Browse Source

Allow switching between normal .NET framework and portable library in existing projects.

Add dialog for picking portable target framework.
pull/24/merge
Daniel Grunwald 14 years ago
parent
commit
2906487bf3
  1. 41
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs
  2. 40
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs
  3. 12
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  4. 7
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  5. 7
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  6. 1
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  7. 12
      src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
  8. 26
      src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
  9. 72
      src/Main/Base/Project/Src/Project/PortableLibrary/ConvertToPortableLibraryProjectBehavior.cs
  10. 57
      src/Main/Base/Project/Src/Project/PortableLibrary/PickPortableTargetFramework.cs
  11. 57
      src/Main/Base/Project/Src/Project/PortableLibrary/PortableLibraryProjectBehavior.cs
  12. 11
      src/Main/Base/Project/Src/Project/PortableLibrary/Profile.cs
  13. 65
      src/Main/Base/Project/Src/Project/PortableLibrary/SelectProfileDialog.xaml
  14. 151
      src/Main/Base/Project/Src/Project/PortableLibrary/SelectProfileDialog.xaml.cs
  15. 59
      src/Main/Base/Project/Src/Project/PortableLibrary/SupportedFramework.cs
  16. 10
      src/Main/Base/Project/Src/Project/TargetFramework.cs
  17. 1
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/BoolToVisibilityConverter.cs
  18. 3
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml
  19. 36
      src/Main/ICSharpCode.SharpDevelop.Widgets/Project/BoolToVisibilityConverter.cs
  20. 1
      src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ICSharpCode.SharpDevelop.Widgets.csproj

41
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs

@ -46,8 +46,7 @@ namespace CSharpBinding @@ -46,8 +46,7 @@ namespace CSharpBinding
Init();
}
public const string DefaultTargetsFile = @"$(MSBuildBinPath)\Microsoft.CSharp.Targets";
public const string ExtendedTargetsFile = @"$(SharpDevelopBinPath)\SharpDevelop.Build.CSharp.targets";
public const string DefaultTargetsFile = @"$(MSBuildToolsPath)\Microsoft.CSharp.targets";
public CSharpProject(ProjectCreateInformation info)
: base(info)
@ -80,44 +79,6 @@ namespace CSharpBinding @@ -80,44 +79,6 @@ namespace CSharpBinding
}
}
/*
protected override void AddOrRemoveExtensions()
{
// Test if SharpDevelop-Build extensions are required
bool needExtensions = false;
foreach (var p in GetAllProperties("TargetFrameworkVersion")) {
if (p.IsImported == false) {
if (p.Value.StartsWith("CF")) {
needExtensions = true;
}
}
}
foreach (Microsoft.Build.BuildEngine.Import import in MSBuildProject.Imports) {
if (needExtensions) {
if (DefaultTargetsFile.Equals(import.ProjectPath, StringComparison.OrdinalIgnoreCase)) {
//import.ProjectPath = extendedTargets;
MSBuildInternals.SetImportProjectPath(this, import, ExtendedTargetsFile);
// Workaround for SD2-1490. It would be better if the project browser could refresh itself
// when necessary.
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
break;
}
} else {
if (ExtendedTargetsFile.Equals(import.ProjectPath, StringComparison.OrdinalIgnoreCase)) {
//import.ProjectPath = defaultTargets;
MSBuildInternals.SetImportProjectPath(this, import, DefaultTargetsFile);
// Workaround for SD2-1490. It would be better if the project browser could refresh itself
// when necessary.
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
break;
}
}
}
}
*/
protected override ProjectBehavior CreateDefaultBehavior()
{
return new CSharpProjectBehavior(this, base.CreateDefaultBehavior());

40
src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs

@ -49,8 +49,7 @@ namespace ICSharpCode.VBNetBinding @@ -49,8 +49,7 @@ namespace ICSharpCode.VBNetBinding
InitVB();
}
public const string DefaultTargetsFile = @"$(MSBuildBinPath)\Microsoft.VisualBasic.Targets";
public const string ExtendedTargetsFile = @"$(SharpDevelopBinPath)\SharpDevelop.Build.VisualBasic.targets";
public const string DefaultTargetsFile = @"$(MSBuildToolsPath)\Microsoft.VisualBasic.targets";
public VBNetProject(ProjectCreateInformation info)
: base(info)
@ -108,43 +107,6 @@ namespace ICSharpCode.VBNetBinding @@ -108,43 +107,6 @@ namespace ICSharpCode.VBNetBinding
}
}
/*
protected override void AddOrRemoveExtensions()
{
// Test if SharpDevelop-Build extensions are required
bool needExtensions = false;
foreach (var p in GetAllProperties("TargetFrameworkVersion")) {
if (p.IsImported == false) {
if (p.Value.StartsWith("CF")) {
needExtensions = true;
}
}
}
foreach (Microsoft.Build.BuildEngine.Import import in MSBuildProject.Imports) {
if (needExtensions) {
if (DefaultTargetsFile.Equals(import.ProjectPath, StringComparison.OrdinalIgnoreCase)) {
//import.ProjectPath = extendedTargets;
MSBuildInternals.SetImportProjectPath(this, import, ExtendedTargetsFile);
// Workaround for SD2-1490. It would be better if the project browser could refresh itself
// when necessary.
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
break;
}
} else {
if (ExtendedTargetsFile.Equals(import.ProjectPath, StringComparison.OrdinalIgnoreCase)) {
//import.ProjectPath = defaultTargets;
MSBuildInternals.SetImportProjectPath(this, import, DefaultTargetsFile);
// Workaround for SD2-1490. It would be better if the project browser could refresh itself
// when necessary.
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
break;
}
}
}
}*/
public Nullable<bool> OptionInfer {
get { return GetValue("OptionInfer", false); }
}

12
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -2365,5 +2365,17 @@ @@ -2365,5 +2365,17 @@
<Condition name="ProjectBehaviorSupported" guid="{786C830F-07A1-408B-BD7F-6EE04809D6DB}">
<Class id="PortableLibraryBehavior" class="ICSharpCode.SharpDevelop.Project.PortableLibrary.PortableLibraryProjectBehavior" />
</Condition>
<ComplexCondition>
<And>
<Not> <!-- not already portable -->
<Condition name="ProjectBehaviorSupported" guid="{786C830F-07A1-408B-BD7F-6EE04809D6DB}" />
</Not>
<Or> <!-- and either a C# or VB project -->
<Condition name = "ProjectActive" activeproject="C#" />
<Condition name = "ProjectActive" activeproject="VBNet" />
</Or>
</And>
<Class id="ConvertToPortableLibraryBehavior" class="ICSharpCode.SharpDevelop.Project.PortableLibrary.ConvertToPortableLibraryProjectBehavior" />
</ComplexCondition>
</Path>
</AddIn>

7
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -380,10 +380,16 @@ @@ -380,10 +380,16 @@
<Compile Include="Src\Project\MSBuildFileProject.cs" />
<Compile Include="Src\Project\MSBuildItemWrapper.cs" />
<Compile Include="Src\Project\PortableLibrary\CheckPortableLibraryInstalled.cs" />
<Compile Include="Src\Project\PortableLibrary\ConvertToPortableLibraryProjectBehavior.cs" />
<Compile Include="Src\Project\PortableLibrary\PickPortableTargetFramework.cs" />
<Compile Include="Src\Project\PortableLibrary\PortableLibraryProjectBehavior.cs" />
<Compile Include="Src\Project\PortableLibrary\PortableTargetFramework.cs" />
<Compile Include="Src\Project\PortableLibrary\Profile.cs" />
<Compile Include="Src\Project\PortableLibrary\ProfileList.cs" />
<Compile Include="Src\Project\PortableLibrary\SelectProfileDialog.xaml.cs">
<DependentUpon>SelectProfileDialog.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Project\PortableLibrary\SupportedFramework.cs" />
<Compile Include="Src\Project\ProjectChangeWatcher.cs" />
<Compile Include="Src\Project\ProjectLoadInformation.cs" />
@ -905,6 +911,7 @@ @@ -905,6 +911,7 @@
<Page Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\AddServiceReferenceDialog.xaml" />
<Page Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\AdvancedServiceDialog.xaml" />
<Page Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceOptionsPanel..xaml" />
<Page Include="Src\Project\PortableLibrary\SelectProfileDialog.xaml" />
<Page Include="Src\Services\RefactoringService\ContextActions\ContextActionsBulbControl.xaml" />
<Page Include="Src\Services\RefactoringService\ContextActions\ContextActionsControl.xaml" />
<Page Include="Src\Services\RefactoringService\ContextActions\ContextActionsHeaderedControl.xaml" />

7
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -598,6 +598,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -598,6 +598,13 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
protected virtual void InvalidateBehavior()
{
lock (SyncRoot) {
projectBehavior = null;
}
}
public virtual bool HasProjectType(Guid projectTypeGuid)
{
Guid myGuid;

1
src/Main/Base/Project/Src/Project/CompilableProject.cs

@ -296,6 +296,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -296,6 +296,7 @@ namespace ICSharpCode.SharpDevelop.Project
public virtual void UpgradeProject(CompilerVersion newVersion, TargetFramework newFramework)
{
if (!ReadOnly)
GetOrCreateBehavior().UpgradeProject(newVersion, newFramework);
}

12
src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs

@ -221,8 +221,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -221,8 +221,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
TargetFramework selectedFramework = newFrameworkComboBox.SelectedValue as TargetFramework;
if (selectedCompiler is UnchangedCompilerVersion)
selectedCompiler = null;
if (selectedFramework is UnchangedTargetFramework)
selectedFramework = null;
if (selectedFramework != null) {
// Show dialog for picking target frameworks for portable library.
// This also handles UnchangedTargetFramework
selectedFramework = selectedFramework.PickFramework(listView.SelectedItems.Cast<Entry>().Select(entry => entry.Project).ToList());
}
foreach (Entry entry in listView.SelectedItems) {
@ -261,6 +264,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -261,6 +264,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
{
}
public override TargetFramework PickFramework(IEnumerable<IUpgradableProject> selectedProjects)
{
return null;
}
public override bool Equals(object obj)
{
return obj is UnchangedTargetFramework;

26
src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs

@ -1630,6 +1630,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1630,6 +1630,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
#endregion
#region HasProjectType
public override bool HasProjectType(Guid projectTypeGuid)
{
string guidList = GetEvaluatedProperty("ProjectTypeGuids");
@ -1642,5 +1643,30 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1642,5 +1643,30 @@ namespace ICSharpCode.SharpDevelop.Project
}
return false;
}
public void AddProjectType(Guid projectTypeGuid)
{
string guidList = GetEvaluatedProperty("ProjectTypeGuids");
if (string.IsNullOrEmpty(guidList))
guidList = this.TypeGuid;
SetProperty("ProjectTypeGuids", guidList + ";" + projectTypeGuid.ToString("B").ToUpperInvariant(), false);
InvalidateBehavior();
}
public void RemoveProjectType(Guid projectTypeGuid)
{
string guidList = GetEvaluatedProperty("ProjectTypeGuids");
if (!string.IsNullOrEmpty(guidList)) {
List<string> remainingGuids = new List<string>();
foreach (string guid in guidList.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) {
Guid result;
if (!(Guid.TryParse(guid, out result) && projectTypeGuid == result))
remainingGuids.Add(guid);
}
SetProperty("ProjectTypeGuids", string.Join(";", remainingGuids), false);
InvalidateBehavior();
}
}
#endregion
}
}

72
src/Main/Base/Project/Src/Project/PortableLibrary/ConvertToPortableLibraryProjectBehavior.cs

@ -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);
}
}
}
}

57
src/Main/Base/Project/Src/Project/PortableLibrary/PickPortableTargetFramework.cs

@ -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;
}
}
}

57
src/Main/Base/Project/Src/Project/PortableLibrary/PortableLibraryProjectBehavior.cs

@ -10,16 +10,28 @@ using ICSharpCode.SharpDevelop.Project.Converter; @@ -10,16 +10,28 @@ using ICSharpCode.SharpDevelop.Project.Converter;
namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
{
/// <summary>
/// Project behavior for portable library projects.
/// </summary>
public class PortableLibraryProjectBehavior : ProjectBehavior
{
public override IEnumerable<CompilerVersion> GetAvailableCompilerVersions()
{
return base.GetAvailableCompilerVersions().Where(c => c.MSBuildVersion == new Version(4, 0));
}
internal const string PortableTargetsPath = @"$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\";
internal const string NormalTargetsPath = @"$(MSBuildToolsPath)\";
internal const string PortableCSharpTargets = "Microsoft.Portable.CSharp.targets";
internal const string NormalCSharpTargets = "Microsoft.CSharp.targets";
internal const string PortableVBTargets = "Microsoft.Portable.VisualBasic.targets";
internal const string NormalVBTargets = "Microsoft.VisualBasic.targets";
public override IEnumerable<TargetFramework> GetAvailableTargetFrameworks()
{
return ProfileList.Instance.AllProfiles.Select(p => new PortableTargetFramework(p)).Union(new[] { this.CurrentTargetFramework });
TargetFramework[] portableTargets = { this.CurrentTargetFramework, new PickPortableTargetFramework() };
if (Project.Language == "C#" || Project.Language == "VBNet") {
// we support converting back to regular projects
return base.GetAvailableTargetFrameworks().Union(portableTargets);
} else {
// project must stay portable
return portableTargets;
}
}
public override TargetFramework CurrentTargetFramework {
@ -37,21 +49,48 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary @@ -37,21 +49,48 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
public override void UpgradeProject(CompilerVersion newVersion, TargetFramework newFramework)
{
var project = (CompilableProject)Project;
if (project.ReadOnly)
var newFx = newFramework as PortableTargetFramework;
if (newFramework != null && newFx == null) {
// convert to normal .NET project (not portable)
Core.AnalyticsMonitorService.TrackFeature(GetType(), "DowngradePortableLibrary");
project.PerformUpdateOnProjectFile(
delegate {
foreach (var import in project.MSBuildProjectFile.Imports) {
if (import.Project.EndsWith(PortableCSharpTargets, StringComparison.OrdinalIgnoreCase)) {
import.Project = NormalTargetsPath + NormalCSharpTargets;
break;
} else if (import.Project.EndsWith(PortableVBTargets, StringComparison.OrdinalIgnoreCase)) {
import.Project = NormalTargetsPath + NormalVBTargets;
break;
}
}
});
project.RemoveProjectType(ProjectTypeGuids.PortableLibrary);
AddReferenceIfNotExists("System");
AddReferenceIfNotExists("System.Xml");
if (newFramework.IsBasedOn(TargetFramework.Net35) || newFramework.IsBasedOn(TargetFramework.Net35Client))
AddReferenceIfNotExists("System.Core");
base.UpgradeProject(newVersion, newFramework);
return;
}
lock (project.SyncRoot) {
if (newVersion != null && GetAvailableCompilerVersions().Contains(newVersion)) {
project.SetToolsVersion(newVersion.MSBuildVersion.Major + "." + newVersion.MSBuildVersion.Minor);
}
var newFx = newFramework as PortableTargetFramework;
if (newFx != null) {
project.SetProperty(null, null, "TargetFrameworkProfile", newFx.TargetFrameworkProfile, PropertyStorageLocations.Base, true);
project.SetProperty(null, null, "TargetFrameworkVersion", newFx.TargetFrameworkVersion, PropertyStorageLocations.Base, true);
}
Project.Save();
ResXConverter.UpdateResourceFiles(project);
project.Save();
ProjectBrowserPad.RefreshViewAsync();
}
}
void AddReferenceIfNotExists(string name)
{
if (!(Project.GetItemsOfType(ItemType.Reference).Any(r => string.Equals(r.Include, name, StringComparison.OrdinalIgnoreCase)))) {
ProjectService.AddProjectItem(Project, new ReferenceProjectItem(Project, name));
}
}
}
}

11
src/Main/Base/Project/Src/Project/PortableLibrary/Profile.cs

@ -44,10 +44,11 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary @@ -44,10 +44,11 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
}
}
public readonly string TargetFrameworkVersion;
public readonly string TargetFrameworkProfile;
public readonly string DisplayName;
public readonly IList<SupportedFramework> SupportedFrameworks;
// These must be properties for WPF data binding
public string TargetFrameworkVersion { get; private set; }
public string TargetFrameworkProfile { get; private set; }
public string DisplayName { get; private set; }
public IList<SupportedFramework> SupportedFrameworks { get; private set; }
public Profile(string targetFrameworkVersion, string targetFrameworkProfile, IList<SupportedFramework> supportedFrameworks)
{
@ -61,7 +62,7 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary @@ -61,7 +62,7 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
public bool Supports(IList<SupportedFramework> frameworks)
{
return frameworks.All(
requiredFx => SupportedFrameworks.Any(fx => fx.Identifier == requiredFx.Identifier && fx.MinimumVersion >= requiredFx.MinimumVersion)
requiredFx => SupportedFrameworks.Any(fx => fx.IsMoreGeneralThan(requiredFx))
);
}
}

65
src/Main/Base/Project/Src/Project/PortableLibrary/SelectProfileDialog.xaml

@ -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>

151
src/Main/Base/Project/Src/Project/PortableLibrary/SelectProfileDialog.xaml.cs

@ -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");
}
}
}
}
}

59
src/Main/Base/Project/Src/Project/PortableLibrary/SupportedFramework.cs

@ -7,38 +7,47 @@ using System.Xml.Linq; @@ -7,38 +7,47 @@ using System.Xml.Linq;
namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
{
/// <summary>
/// A supported framework.
/// A supported framework for portable libraries.
/// </summary>
public class SupportedFramework
{
public readonly string Identifier;
public readonly string Profile;
public readonly Version MinimumVersion;
public readonly string DisplayName;
// These are properties for WPF data binding
public string Identifier { get; private set; }
public string Profile { get; private set; }
public Version MinimumVersion { get; private set; }
public string DisplayName { get; private set; }
public string MinimumVersionDisplayName { get; private set; }
public SupportedFramework(string identifier, Version minimumVersion, string profile = null, string displayName = null)
public SupportedFramework(string identifier, Version minimumVersion = null, string profile = "*", string displayName = null, string minimumVersionDisplayName = null)
{
if (identifier == null)
throw new ArgumentNullException("identifier");
if (profile == null)
throw new ArgumentNullException("profile");
this.Identifier = identifier;
this.MinimumVersion = minimumVersion;
this.Profile = profile;
this.DisplayName = displayName ?? identifier;
this.MinimumVersionDisplayName = minimumVersionDisplayName ?? (minimumVersion != null ? minimumVersion.ToString() : null);
}
internal SupportedFramework(XElement framework)
{
this.Identifier = (string)framework.Attribute("Identifier");
this.Profile = (string)framework.Attribute("Profile");
Version.TryParse((string)framework.Attribute("MinimumVersion"), out MinimumVersion);
string displayName = (string)framework.Attribute("DisplayName");
string minimumVersionDisplayName = (string)framework.Attribute("MinimumVersionDisplayName");
if (!string.IsNullOrEmpty(minimumVersionDisplayName))
displayName += " " + minimumVersionDisplayName;
this.DisplayName = displayName;
this.Identifier = (string)framework.Attribute("Identifier") ?? string.Empty;
this.Profile = (string)framework.Attribute("Profile") ?? "*";
Version minimumVersion;
if (Version.TryParse((string)framework.Attribute("MinimumVersion"), out minimumVersion))
this.MinimumVersion = minimumVersion;
this.DisplayName = (string)framework.Attribute("DisplayName");
this.MinimumVersionDisplayName = (string)framework.Attribute("MinimumVersionDisplayName");
}
public override string ToString()
{
if (string.IsNullOrEmpty(this.MinimumVersionDisplayName))
return this.DisplayName;
else
return this.DisplayName + " " + this.MinimumVersionDisplayName;
}
public override bool Equals(object obj)
@ -46,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary @@ -46,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
SupportedFramework other = obj as SupportedFramework;
if (other == null)
return false;
return this.Identifier == other.Identifier && this.Profile == other.Profile && object.Equals(this.MinimumVersion, other.MinimumVersion) && this.DisplayName == other.DisplayName;
return this.Identifier == other.Identifier && this.Profile == other.Profile && object.Equals(this.MinimumVersion, other.MinimumVersion) && this.DisplayName == other.DisplayName && this.MinimumVersionDisplayName == other.MinimumVersionDisplayName;
}
public override int GetHashCode()
@ -59,10 +68,26 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary @@ -59,10 +68,26 @@ namespace ICSharpCode.SharpDevelop.Project.PortableLibrary
hashCode += 1000000009 * Profile.GetHashCode();
if (MinimumVersion != null)
hashCode += 1000000021 * MinimumVersion.GetHashCode();
if (DisplayName != null)
hashCode += 1000000033 * DisplayName.GetHashCode();
}
return hashCode;
}
/// <summary>
/// Gets whether this supported framework is a more general version of the specified framework.
/// </summary>
public bool IsMoreGeneralThan(SupportedFramework fx)
{
if (this.Identifier != fx.Identifier)
return false;
if (this.Profile.EndsWith("*", StringComparison.OrdinalIgnoreCase)) {
string prefix = this.Profile.Substring(0, this.Profile.Length - 1);
if (!fx.Profile.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
return false;
} else {
if (!this.Profile.Equals(fx.Profile, StringComparison.OrdinalIgnoreCase))
return false;
}
return this.MinimumVersion <= fx.MinimumVersion;
}
}
}

10
src/Main/Base/Project/Src/Project/TargetFramework.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Project.Converter;
namespace ICSharpCode.SharpDevelop.Project
@ -137,6 +138,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -137,6 +138,15 @@ namespace ICSharpCode.SharpDevelop.Project
{
return DisplayName;
}
/// <summary>
/// Shows a dialog to pick the target framework.
/// This method is called by the UpgradeView 'convert' button to retrieve the actual target framework
/// </summary>
public virtual TargetFramework PickFramework(IEnumerable<IUpgradableProject> selectedProjects)
{
return this;
}
}
public class ClientProfileTargetFramework : TargetFramework

1
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/BoolToVisibilityConverter.cs

@ -9,6 +9,7 @@ using System.Windows.Data; @@ -9,6 +9,7 @@ using System.Windows.Data;
namespace ICSharpCode.SharpDevelop.Refactoring
{
[ValueConversion(typeof(bool), typeof(Visibility))]
[Obsolete]
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

3
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Refactoring"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<UserControl.Resources>
@ -9,7 +10,7 @@ @@ -9,7 +10,7 @@
<SolidColorBrush x:Key="OuterBorderBrush" Color="#436C82"></SolidColorBrush>
<BitmapImage x:Key="PencilImage" UriSource="pencil.png" />
<Geometry x:Key="DownArrowGeometry">M 0 0 L 2 3 L 4 0 Z</Geometry>
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<widgets:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" TrueValue="Visible" FalseValue="Hidden" />
<!-- Expander -->

36
src/Main/ICSharpCode.SharpDevelop.Widgets/Project/BoolToVisibilityConverter.cs

@ -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;
}
}
}

1
src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ICSharpCode.SharpDevelop.Widgets.csproj

@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
<Compile Include="..\..\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="BoolToVisibilityConverter.cs" />
<Compile Include="CollapsiblePanel.cs" />
<Compile Include="ColorHelper.cs" />
<Compile Include="ColorPicker.xaml.cs">

Loading…
Cancel
Save