20 changed files with 558 additions and 115 deletions
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using ICSharpCode.Build.Tasks; |
||||
using ICSharpCode.SharpDevelop.Project.Converter; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project.PortableLibrary |
||||
{ |
||||
/// <summary>
|
||||
/// Project behavior attached to all non-portable C# and VB projects.
|
||||
/// </summary>
|
||||
public class ConvertToPortableLibraryProjectBehavior : ProjectBehavior |
||||
{ |
||||
public override IEnumerable<TargetFramework> GetAvailableTargetFrameworks() |
||||
{ |
||||
return base.GetAvailableTargetFrameworks().Concat(new [] { new PickPortableTargetFramework() }); |
||||
} |
||||
|
||||
public override void UpgradeProject(CompilerVersion newVersion, TargetFramework newFramework) |
||||
{ |
||||
PortableTargetFramework newFx = newFramework as PortableTargetFramework; |
||||
if (newFx != null) { |
||||
// Convert to portable library
|
||||
Core.AnalyticsMonitorService.TrackFeature(GetType(), "ConvertToPortableLibrary"); |
||||
var project = (CompilableProject)Project; |
||||
lock (project.SyncRoot) { |
||||
if (newVersion != null && GetAvailableCompilerVersions().Contains(newVersion)) { |
||||
project.SetToolsVersion(newVersion.MSBuildVersion.Major + "." + newVersion.MSBuildVersion.Minor); |
||||
} |
||||
project.SetProperty(null, null, "TargetFrameworkProfile", newFx.TargetFrameworkProfile, PropertyStorageLocations.Base, true); |
||||
project.SetProperty(null, null, "TargetFrameworkVersion", newFx.TargetFrameworkVersion, PropertyStorageLocations.Base, true); |
||||
// Convert <Imports>
|
||||
project.PerformUpdateOnProjectFile( |
||||
delegate { |
||||
foreach (var import in project.MSBuildProjectFile.Imports) { |
||||
if (import.Project.EndsWith(PortableLibraryProjectBehavior.NormalCSharpTargets, StringComparison.OrdinalIgnoreCase)) { |
||||
import.Project = PortableLibraryProjectBehavior.PortableTargetsPath + PortableLibraryProjectBehavior.PortableCSharpTargets; |
||||
break; |
||||
} else if (import.Project.EndsWith(PortableLibraryProjectBehavior.NormalVBTargets, StringComparison.OrdinalIgnoreCase)) { |
||||
import.Project = PortableLibraryProjectBehavior.PortableTargetsPath + PortableLibraryProjectBehavior.PortableVBTargets; |
||||
break; |
||||
} |
||||
} |
||||
}); |
||||
// Remove references
|
||||
foreach (var referenceItem in project.GetItemsOfType(ItemType.Reference).ToArray()) { |
||||
// get short assembly name:
|
||||
string assemblyName = referenceItem.Include; |
||||
if (assemblyName.IndexOf(',') >= 0) |
||||
assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(',')); |
||||
assemblyName += ","; |
||||
if (KnownFrameworkAssemblies.FullAssemblyNames.Any(fullName => fullName.StartsWith(assemblyName, StringComparison.OrdinalIgnoreCase))) { |
||||
// If it's a framework assembly, remove the reference
|
||||
// (portable libraries automatically reference all available framework assemblies)
|
||||
ProjectService.RemoveProjectItem(project, referenceItem); |
||||
} |
||||
} |
||||
project.AddProjectType(ProjectTypeGuids.PortableLibrary); |
||||
project.Save(); |
||||
ProjectBrowserPad.RefreshViewAsync(); |
||||
} |
||||
} else { |
||||
base.UpgradeProject(newVersion, newFramework); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project.Converter; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project.PortableLibrary |
||||
{ |
||||
/// <summary>
|
||||
/// Dummy TargetFramework that displays the SelectProfileDialog.
|
||||
/// </summary>
|
||||
sealed class PickPortableTargetFramework : TargetFramework |
||||
{ |
||||
public PickPortableTargetFramework() |
||||
: base("PickPortableTargetFramework", ".NET Portable Subset (choose target frameworks)") |
||||
{ |
||||
this.MinimumMSBuildVersion = new Version(4, 0); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return obj is PickPortableTargetFramework; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
public override TargetFramework PickFramework(IEnumerable<IUpgradableProject> selectedProjects) |
||||
{ |
||||
if (ProfileList.IsPortableLibraryInstalled()) { |
||||
SelectProfileDialog dlg = new SelectProfileDialog(ProfileList.Instance); |
||||
dlg.Owner = WorkbenchSingleton.MainWindow; |
||||
if (selectedProjects != null) { |
||||
var project = selectedProjects.FirstOrDefault() as CompilableProject; |
||||
if (project != null) { |
||||
Profile profile = Profile.LoadProfile(project.TargetFrameworkVersion, project.TargetFrameworkProfile); |
||||
if (profile != null) |
||||
dlg.SelectedProfile = profile; |
||||
} |
||||
} |
||||
if (dlg.ShowDialog() == true && dlg.SelectedProfile != null) { |
||||
return new PortableTargetFramework(dlg.SelectedProfile); |
||||
} |
||||
} else { |
||||
new CheckPortableLibraryInstalled().Run(); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
<Window x:Class="ICSharpCode.SharpDevelop.Project.PortableLibrary.SelectProfileDialog" x:ClassModifier="internal" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Project.PortableLibrary" |
||||
xmlns:core="http://icsharpcode.net/sharpdevelop/core" xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets" |
||||
Title="Select Portable Library Profile" MinWidth="300" MinHeight="200" Height="350" Width="400" WindowStartupLocation="CenterOwner" |
||||
Style="{x:Static core:GlobalStyles.DialogWindowStyle}"> |
||||
<Grid> |
||||
<Grid.Resources> |
||||
<widgets:BoolToVisibilityConverter x:Key="showWhenTrue" TrueValue="Visible" FalseValue="Collapsed" /> |
||||
<widgets:BoolToVisibilityConverter x:Key="showWhenFalse" TrueValue="Collapsed" FalseValue="Visible" /> |
||||
</Grid.Resources> |
||||
<Grid.RowDefinitions> |
||||
<RowDefinition |
||||
Height="1*" /> |
||||
<RowDefinition |
||||
Height="Auto" MinHeight="50" /> |
||||
<RowDefinition |
||||
Height="Auto" /> |
||||
</Grid.RowDefinitions> |
||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> |
||||
<ItemsControl ItemsSource="{Binding SupportedFrameworkGroups}" Margin="8"> |
||||
<ItemsControl.ItemsPanel> |
||||
<ItemsPanelTemplate> |
||||
<widgets:StackPanelWithSpacing Orientation="Vertical" SpaceBetweenItems="10"/> |
||||
</ItemsPanelTemplate> |
||||
</ItemsControl.ItemsPanel> |
||||
<ItemsControl.ItemTemplate> |
||||
<DataTemplate DataType="{x:Type local:SupportedFrameworkGroup}"> |
||||
<StackPanel Orientation="Vertical"> |
||||
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding DisplayName}" FontWeight="Bold" /> |
||||
<ComboBox Name="comboBox" ItemsSource="{Binding AvailableVersions}" SelectedItem="{Binding SelectedVersion}" |
||||
Margin="20,0,0,0" IsEnabled="{Binding IsChecked}" /> |
||||
</StackPanel> |
||||
<DataTemplate.Triggers> |
||||
<DataTrigger Binding="{Binding AvailableVersions.Count}" Value="1"> |
||||
<DataTrigger.Setters> |
||||
<Setter TargetName="comboBox" Property="Visibility" Value="Collapsed" /> |
||||
</DataTrigger.Setters> |
||||
</DataTrigger> |
||||
</DataTemplate.Triggers> |
||||
</DataTemplate> |
||||
</ItemsControl.ItemTemplate> |
||||
</ItemsControl> |
||||
</ScrollViewer> |
||||
<TextBlock Grid.Row="1" TextWrapping="WrapWithOverflow" Visibility="{Binding HasTwoOrMoreFrameworksSelected, Converter={StaticResource showWhenTrue}}"> |
||||
<Bold>Selected profile:</Bold> <Run Text="{Binding SelectedProfile.DisplayName, Mode=OneWay}"/> |
||||
</TextBlock> |
||||
<TextBlock Grid.Row="1" TextWrapping="WrapWithOverflow" Visibility="{Binding HasTwoOrMoreFrameworksSelected, Converter={StaticResource showWhenFalse}}"> |
||||
<Bold>Two or more frameworks must be selected.</Bold> |
||||
</TextBlock> |
||||
<widgets:UniformGridWithSpacing Columns="2" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,4,12,12"> |
||||
<Button |
||||
Content="{core:Localize Global.OKButtonText}" |
||||
IsDefault="True" |
||||
Click="okButton_Click" |
||||
IsEnabled="{Binding HasTwoOrMoreFrameworksSelected}" |
||||
Style="{x:Static core:GlobalStyles.ButtonStyle}" /> |
||||
<Button |
||||
Content="{core:Localize Global.CancelButtonText}" |
||||
IsCancel="True" |
||||
Style="{x:Static core:GlobalStyles.ButtonStyle}" /> |
||||
</widgets:UniformGridWithSpacing> |
||||
</Grid> |
||||
</Window> |
||||
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.Diagnostics; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project.PortableLibrary |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for SelectProfileDialog.xaml
|
||||
/// </summary>
|
||||
internal partial class SelectProfileDialog : Window, INotifyPropertyChanged |
||||
{ |
||||
readonly ProfileList profileList; |
||||
readonly List<SupportedFrameworkGroup> viewModels; |
||||
|
||||
public IEnumerable<SupportedFrameworkGroup> SupportedFrameworkGroups { |
||||
get { return viewModels; } |
||||
} |
||||
|
||||
public SelectProfileDialog(ProfileList profileList) |
||||
{ |
||||
if (profileList == null) |
||||
throw new ArgumentNullException("profileList"); |
||||
InitializeComponent(); |
||||
this.profileList = profileList; |
||||
Debug.WriteLine(string.Join(Environment.NewLine, profileList.AllProfiles.Select(p => p.DisplayName))); |
||||
viewModels = profileList.AllFrameworks.GroupBy(fx => fx.DisplayName, (key, group) => new SupportedFrameworkGroup(group)).ToList(); |
||||
this.DataContext = this; |
||||
foreach (var vm in viewModels) { |
||||
vm.PropertyChanged += delegate { UpdateSelectedProfile(); }; |
||||
} |
||||
UpdateSelectedProfile(); |
||||
} |
||||
|
||||
void okButton_Click(object sender, RoutedEventArgs e) |
||||
{ |
||||
this.DialogResult = true; |
||||
Close(); |
||||
} |
||||
|
||||
Profile selectedProfile; |
||||
bool isSettingProfile; |
||||
|
||||
public Profile SelectedProfile { |
||||
get { return selectedProfile; } |
||||
set { |
||||
selectedProfile = value; |
||||
isSettingProfile = true; |
||||
foreach (var g in viewModels) { |
||||
if (value == null) { |
||||
g.IsChecked = false; |
||||
} else { |
||||
SupportedFramework version = g.AvailableVersions.Intersect(value.SupportedFrameworks).FirstOrDefault(); |
||||
if (version != null) { |
||||
g.IsChecked = true; |
||||
g.SelectedVersion = version; |
||||
} else { |
||||
g.IsChecked = false; |
||||
} |
||||
} |
||||
} |
||||
isSettingProfile = false; |
||||
PropertyChanged(this, new PropertyChangedEventArgs("SelectedProfile")); |
||||
} |
||||
} |
||||
|
||||
public bool HasTwoOrMoreFrameworksSelected { |
||||
get { return viewModels.Count(vm => vm.IsChecked) >= 2; } |
||||
} |
||||
|
||||
void UpdateSelectedProfile() |
||||
{ |
||||
PropertyChanged(this, new PropertyChangedEventArgs("HasTwoOrMoreFrameworksSelected")); |
||||
if (isSettingProfile) |
||||
return; |
||||
var requestedFrameworks = (from g in viewModels where g.IsChecked select g.SelectedVersion).ToList(); |
||||
var bestProfile = profileList.GetBestProfile(requestedFrameworks); |
||||
if (bestProfile != selectedProfile) { |
||||
selectedProfile = bestProfile; |
||||
PropertyChanged(this, new PropertyChangedEventArgs("SelectedProfile")); |
||||
} |
||||
} |
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged = delegate {}; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// View model used in SelectProfileDialog
|
||||
/// </summary>
|
||||
sealed class SupportedFrameworkGroup : INotifyPropertyChanged |
||||
{ |
||||
readonly IList<SupportedFramework> availableVersions; |
||||
bool isChecked; |
||||
SupportedFramework selectedVersion; |
||||
|
||||
public SupportedFrameworkGroup(IEnumerable<SupportedFramework> availableVersions) |
||||
{ |
||||
this.availableVersions = availableVersions.OrderBy(v => v.MinimumVersion).ToList(); |
||||
this.isChecked = true; |
||||
this.selectedVersion = this.availableVersions.First(); |
||||
} |
||||
|
||||
public IList<SupportedFramework> AvailableVersions { |
||||
get { return availableVersions; } |
||||
} |
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged; |
||||
|
||||
private void OnPropertyChanged(string propertyName) |
||||
{ |
||||
if (PropertyChanged != null) { |
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); |
||||
} |
||||
} |
||||
|
||||
public string DisplayName { |
||||
get { return availableVersions[0].DisplayName; } |
||||
} |
||||
|
||||
public bool IsChecked { |
||||
get { return isChecked; } |
||||
set { |
||||
if (isChecked != value) { |
||||
isChecked = value; |
||||
OnPropertyChanged("IsChecked"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public SupportedFramework SelectedVersion { |
||||
get { return selectedVersion; } |
||||
set { |
||||
if (selectedVersion != value) { |
||||
selectedVersion = value; |
||||
OnPropertyChanged("SelectedVersion"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Globalization; |
||||
using System.Windows; |
||||
using System.Windows.Data; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Widgets |
||||
{ |
||||
[ValueConversion(typeof(bool), typeof(Visibility))] |
||||
public class BoolToVisibilityConverter : IValueConverter |
||||
{ |
||||
public Visibility TrueValue { get; set; } |
||||
public Visibility FalseValue { get; set; } |
||||
|
||||
public BoolToVisibilityConverter() |
||||
{ |
||||
this.TrueValue = Visibility.Visible; |
||||
this.FalseValue = Visibility.Collapsed; |
||||
} |
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
||||
{ |
||||
if ((value as bool?) == true) |
||||
return TrueValue; |
||||
else |
||||
return FalseValue; |
||||
} |
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
||||
{ |
||||
return value is Visibility && (Visibility)value == TrueValue; |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue