Browse Source

Rewritten ICSharpCode.Core.Properties:

- The meaning of "Get" is no longer overloaded, GetList and NestedProperties are now seperate methods.
- "Get" and "GetList" no longer cause the default value to be written into the properties container.
- Use DataContractSerializer instead of XmlSerializer.
newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
7aea1ca75e
  1. 8
      data/options/SharpDevelopProperties.xml
  2. 5
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs
  3. 3
      src/AddIns/BackendBindings/CSharpBinding/Tests/CSharpBinding.Tests.csproj
  4. 6
      src/AddIns/BackendBindings/CSharpBinding/Tests/app.config
  5. 2
      src/AddIns/BackendBindings/CppBinding/CppBinding/CppBinding.csproj
  6. 2
      src/AddIns/BackendBindings/FSharpBinding/FSharpBinding.csproj
  7. 2
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs
  8. 6
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs
  9. 14
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizedHighlightingColor.cs
  10. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
  11. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs
  12. 2
      src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj
  13. 2
      src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/Settings.cs
  14. 8
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XPathQueryControl.cs
  15. 4
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XPathQueryPad.cs
  16. 4
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorOptions.cs
  17. 2
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorService.cs
  18. 2
      src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj
  19. 2
      src/AddIns/Misc/AddInManager/Project/AddInManager.csproj
  20. 2
      src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj
  21. 3
      src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj.user
  22. 2
      src/AddIns/Misc/HelpViewer/HelpViewer.csproj
  23. 2
      src/AddIns/Misc/RegExpTk/Project/RegExpTk.csproj
  24. 3
      src/AddIns/Misc/RegExpTk/Project/RegExpTk.csproj.user
  25. 2
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs
  26. 32
      src/AddIns/Misc/SearchAndReplace/Project/SearchOptions.cs
  27. 6
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/AnalyticsMonitor.cs
  28. 1
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/StartPageMessage.xaml.cs
  29. 2
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/UsageDataCollector.AddIn.csproj
  30. 2
      src/AddIns/VersionControl/SubversionAddIn/Src/AddInOptions.cs
  31. 2
      src/Main/Base/Project/Src/Commands/AutostartCommands.cs
  32. 8
      src/Main/Base/Project/Src/Gui/BrowserDisplayBinding/HtmlViewPane.cs
  33. 5
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/CodeGenerationPanel.cs
  34. 5
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/OutputWindowOptionsPanel.cs
  35. 46
      src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopColorDialog.cs
  36. 7
      src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs
  37. 2
      src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs
  38. 7
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  39. 2
      src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
  40. 2
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  41. 10
      src/Main/Base/Project/Src/Project/Behaviors/DefaultProjectBehavior.cs
  42. 2
      src/Main/Base/Project/Src/Services/AmbienceService/AmbienceService.cs
  43. 8
      src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingService.cs
  44. 4
      src/Main/Base/Project/Src/Services/File/FileService.cs
  45. 14
      src/Main/Base/Project/Src/Services/File/RecentOpen.cs
  46. 4
      src/Main/Base/Project/Src/Services/ParserService/CodeCompletionOptions.cs
  47. 9
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
  48. 23
      src/Main/Base/Project/Src/Util/ExtensionMethods.cs
  49. 1
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  50. 78
      src/Main/Base/Test/SharpDevelopColorDialogTests.cs
  51. 2
      src/Main/Base/Test/Utils/MockTextMarker.cs
  52. 10
      src/Main/Core/Project/ICSharpCode.Core.csproj
  53. 1
      src/Main/Core/Project/Src/AddInTree/CoreStartup.cs
  54. 748
      src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
  55. 61
      src/Main/Core/Project/Src/Services/PropertyService/PropertyChangedEvent.cs
  56. 169
      src/Main/Core/Project/Src/Services/PropertyService/PropertyService.cs
  57. 5
      src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs
  58. 13
      src/Main/Core/Project/Src/Services/StringParser/StringParser.cs
  59. 3
      src/Main/Core/Test/ICSharpCode.Core.Tests.csproj
  60. 3
      src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
  61. 3
      src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj
  62. 3
      src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ICSharpCode.SharpDevelop.Widgets.csproj

8
data/options/SharpDevelopProperties.xml

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
<SharpDevelopProperties>
<ShowTipsAtStartup value="True" />
<Properties name="WorkbenchMemento">
<bounds value="10,10,780,560" />
<windowstate value="Maximized" />
<defaultstate value="Maximized" />
</Properties>
</SharpDevelopProperties>

5
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs

@ -70,7 +70,7 @@ namespace CSharpBinding.Refactoring @@ -70,7 +70,7 @@ namespace CSharpBinding.Refactoring
{
// TODO: cache the result
var dict = new Dictionary<Type, Severity>();
var prop = PropertyService.Get("CSharpIssueSeveritySettings", new Properties());
var prop = PropertyService.NestedProperties("CSharpIssueSeveritySettings");
foreach (var provider in issueProviders.Value) {
dict[provider.ProviderType] = prop.Get(provider.ProviderType.FullName, provider.DefaultSeverity);
}
@ -79,11 +79,10 @@ namespace CSharpBinding.Refactoring @@ -79,11 +79,10 @@ namespace CSharpBinding.Refactoring
public static void SetIssueSeveritySettings(IReadOnlyDictionary<Type, Severity> dict)
{
var prop = new Properties();
var prop = PropertyService.NestedProperties("CSharpIssueSeveritySettings");
foreach (var pair in dict) {
prop.Set(pair.Key.FullName, pair.Value);
}
PropertyService.Set("CSharpIssueSeveritySettings", prop);
}
readonly ITextEditor editor;

3
src/AddIns/BackendBindings/CSharpBinding/Tests/CSharpBinding.Tests.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>CSharpBinding.Tests</RootNamespace>
<AssemblyName>CSharpBinding.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SourceAnalysisOverrideSettingsFile>C:\Users\daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<OutputPath>..\..\..\..\..\bin\UnitTests\</OutputPath>
@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>

6
src/AddIns/BackendBindings/CSharpBinding/Tests/app.config

@ -1,9 +1,11 @@ @@ -1,9 +1,11 @@
<configuration>
<?xml version="1.0" encoding="utf-8"?><configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler" />
</sectionGroup>
</configSections>
</configSections><startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<NUnit>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->

2
src/AddIns/BackendBindings/CppBinding/CppBinding/CppBinding.csproj

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AssemblyName>CppBinding</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<SourceAnalysisOverrideSettingsFile>C:\Users\trecio\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<TargetFrameworkSubset>
</TargetFrameworkSubset>

2
src/AddIns/BackendBindings/FSharpBinding/FSharpBinding.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>FSharpBinding</RootNamespace>
<AssemblyName>FSharpBinding</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>

2
src/AddIns/BackendBindings/XamlBinding/XamlBinding/Options/XamlBindingOptions.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.XamlBinding @@ -16,7 +16,7 @@ namespace ICSharpCode.XamlBinding
static XamlBindingOptions()
{
properties = PropertyService.Get("XamlBinding.Options", new Properties());
properties = PropertyService.NestedProperties("XamlBinding.Options");
}
static Properties Properties {

6
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs

@ -26,8 +26,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions @@ -26,8 +26,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
internal static void LoadProviderVisibilities(IEnumerable<IContextActionProvider> providers)
{
var list = PropertyService.Get(PropertyServiceKey, new List<string>());
var disabledActions = new HashSet<string>(list);
var disabledActions = new HashSet<string>(PropertyService.GetList<string>(PropertyServiceKey));
foreach (var provider in providers) {
provider.IsVisible = !(provider.AllowHiding && disabledActions.Contains(provider.ID));
}
@ -35,8 +34,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions @@ -35,8 +34,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
internal static void SaveProviderVisibilities(IEnumerable<IContextActionProvider> providers)
{
List<string> disabledProviders = providers.Where(p => !p.IsVisible).Select(p => p.ID).ToList();
PropertyService.Set(PropertyServiceKey, disabledProviders);
PropertyService.SetList(PropertyServiceKey, providers.Where(p => !p.IsVisible).Select(p => p.ID));
}
readonly IList<IContextActionProvider> providers;

14
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizedHighlightingColor.cs

@ -29,11 +29,9 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -29,11 +29,9 @@ namespace ICSharpCode.AvalonEdit.AddIn
public bool Bold, Italic;
public Color? Foreground, Background;
public static List<CustomizedHighlightingColor> LoadColors()
public static IReadOnlyList<CustomizedHighlightingColor> LoadColors()
{
var list = PropertyService.Get("CustomizedHighlightingRules", new List<CustomizedHighlightingColor>());
// Always make a copy of the list so that the original list cannot be modified without using SaveColors().
return new List<CustomizedHighlightingColor>(list);
return PropertyService.GetList<CustomizedHighlightingColor>("CustomizedHighlightingRules");
}
/// <summary>
@ -43,21 +41,21 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -43,21 +41,21 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
lock (staticLockObj) {
activeColors = null;
PropertyService.Set("CustomizedHighlightingRules", colors.ToList());
PropertyService.SetList("CustomizedHighlightingRules", colors);
}
EventHandler e = ActiveColorsChanged;
if (e != null)
e(null, EventArgs.Empty);
}
static ReadOnlyCollection<CustomizedHighlightingColor> activeColors;
static IReadOnlyList<CustomizedHighlightingColor> activeColors;
static readonly object staticLockObj = new object();
public static ReadOnlyCollection<CustomizedHighlightingColor> ActiveColors {
public static IReadOnlyList<CustomizedHighlightingColor> ActiveColors {
get {
lock (staticLockObj) {
if (activeColors == null)
activeColors = LoadColors().AsReadOnly();
activeColors = LoadColors();
return activeColors;
}
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options @@ -128,7 +128,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
.OrderBy(def => def.Name)
.ToList();
}
customizationList = CustomizedHighlightingColor.LoadColors();
customizationList = new List<CustomizedHighlightingColor>(CustomizedHighlightingColor.LoadColors());
languageComboBox.Items.Clear();
languageComboBox.Items.Add(new XshdSyntaxDefinition { Name = "All languages" });

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs

@ -312,7 +312,7 @@ End Property${Caret}", @@ -312,7 +312,7 @@ End Property${Caret}",
/// </summary>
public List<CodeSnippetGroup> LoadGroups()
{
var savedSnippets = PropertyService.Get("CodeSnippets", new List<CodeSnippetGroup>());
var savedSnippets = new List<CodeSnippetGroup>(PropertyService.GetList<CodeSnippetGroup>("CodeSnippets"));
foreach (var group in savedSnippets) {
var defaultGroup = defaultSnippets.FirstOrDefault(i => i.Extensions == group.Extensions);
@ -382,7 +382,7 @@ End Property${Caret}", @@ -382,7 +382,7 @@ End Property${Caret}",
modifiedGroups.Add(copy);
}
PropertyService.Set("CodeSnippets", modifiedGroups);
PropertyService.SetList("CodeSnippets", modifiedGroups);
}
}

2
src/AddIns/DisplayBindings/HexEditor/Project/HexEditor.csproj

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
<DelaySign>False</DelaySign>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<RunCodeAnalysis>False</RunCodeAnalysis>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>

2
src/AddIns/DisplayBindings/HexEditor/Project/Src/Util/Settings.cs

@ -15,7 +15,7 @@ namespace HexEditor.Util @@ -15,7 +15,7 @@ namespace HexEditor.Util
/// </summary>
public class Settings
{
static Properties properties = PropertyService.Get("HexEditorOptions", new Properties());
static Properties properties = PropertyService.NestedProperties("HexEditorOptions");
public static Properties Properties {
get {

8
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XPathQueryControl.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.XmlEditor @@ -111,7 +111,7 @@ namespace ICSharpCode.XmlEditor
void SaveNamespaces(Properties properties)
{
properties.Set(NamespacesProperty, GetNamespaceStringArray());
properties.SetList(NamespacesProperty, GetNamespaceStringArray());
}
void SaveNamespaceDataGridColumnWidths(Properties properties)
@ -128,7 +128,7 @@ namespace ICSharpCode.XmlEditor @@ -128,7 +128,7 @@ namespace ICSharpCode.XmlEditor
void SaveXPathQueryHistory(Properties properties)
{
properties.Set(XPathComboBoxTextProperty, XPathComboBox.Text);
properties.Set(XPathComboBoxItemsProperty, GetXPathHistory());
properties.SetList(XPathComboBoxItemsProperty, GetXPathHistory());
}
/// <summary>
@ -150,7 +150,7 @@ namespace ICSharpCode.XmlEditor @@ -150,7 +150,7 @@ namespace ICSharpCode.XmlEditor
void LoadNamespaces(Properties properties)
{
string[] namespaces = properties.Get(NamespacesProperty, new string[0]);
string[] namespaces = properties.GetList<string>(NamespacesProperty);
foreach (string ns in namespaces) {
XmlNamespace xmlNamespace = XmlNamespace.FromString(ns);
AddNamespace(xmlNamespace.Prefix, xmlNamespace.Name);
@ -171,7 +171,7 @@ namespace ICSharpCode.XmlEditor @@ -171,7 +171,7 @@ namespace ICSharpCode.XmlEditor
void LoadXPathQueryHistory(Properties properties)
{
XPathComboBox.Text = properties.Get(XPathComboBoxTextProperty, string.Empty);
string[] xpaths = properties.Get(XPathComboBoxItemsProperty, new string[0]);
string[] xpaths = properties.GetList<string>(XPathComboBoxItemsProperty);
foreach (string xpath in xpaths) {
xpathComboBox.Items.Add(xpath);
}

4
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XPathQueryPad.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.XmlEditor @@ -20,7 +20,7 @@ namespace ICSharpCode.XmlEditor
{
xpathQueryControl = new XPathQueryControl();
WorkbenchSingleton.Workbench.ActiveViewContentChanged += ActiveViewContentChanged;
Properties properties = PropertyService.Get(XPathQueryControlProperties, new Properties());
Properties properties = PropertyService.NestedProperties(XPathQueryControlProperties);
xpathQueryControl.SetMemento(properties);
instance = this;
}
@ -42,7 +42,7 @@ namespace ICSharpCode.XmlEditor @@ -42,7 +42,7 @@ namespace ICSharpCode.XmlEditor
disposed = true;
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= ActiveViewContentChanged;
Properties properties = xpathQueryControl.CreateMemento();
PropertyService.Set(XPathQueryControlProperties, properties);
PropertyService.PropertiesContainer.SetNestedProperties(XPathQueryControlProperties, properties);
xpathQueryControl.Dispose();
}
}

4
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorOptions.cs

@ -2,10 +2,12 @@ @@ -2,10 +2,12 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using ICSharpCode.Core;
using System.Globalization;
namespace ICSharpCode.XmlEditor
{

2
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorService.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.XmlEditor @@ -37,7 +37,7 @@ namespace ICSharpCode.XmlEditor
static void CreateXmlEditorProperties()
{
xmlEditorProperties = PropertyService.Get(XmlEditorOptions.OptionsProperty, new Properties());
xmlEditorProperties = PropertyService.NestedProperties(XmlEditorOptions.OptionsProperty);
}
public static bool ShowAttributesWhenFolded {

2
src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>ICSharpCode.XmlEditor</RootNamespace>
<AssemblyName>XmlEditor</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>

2
src/AddIns/Misc/AddInManager/Project/AddInManager.csproj

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
<FileAlignment>4096</FileAlignment>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>

2
src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj

@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>

3
src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj.user

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<LastOpenVersion>8.0.41115</LastOpenVersion>
<ProjectView>ShowAllFiles</ProjectView>

2
src/AddIns/Misc/HelpViewer/HelpViewer.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>MSHelpSystem</RootNamespace>
<AssemblyName>HelpViewer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>

2
src/AddIns/Misc/RegExpTk/Project/RegExpTk.csproj

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
<BaseAddress>122683392</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>

3
src/AddIns/Misc/RegExpTk/Project/RegExpTk.csproj.user

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<LastOpenVersion>8.0.41115</LastOpenVersion>
<ProjectView>ShowAllFiles</ProjectView>

2
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs

@ -286,7 +286,7 @@ namespace SearchAndReplace @@ -286,7 +286,7 @@ namespace SearchAndReplace
var editor = GetActiveTextEditor();
if (editor == null)
return -1;
return files.FindIndex(file => editor.FileName.Equals(file));
return Array.IndexOf(files, editor.FileName);
}
public static SearchRegion CreateSearchRegion(FileName[] files, ISearchStrategy strategy, SearchLocation location)

32
src/AddIns/Misc/SearchAndReplace/Project/SearchOptions.cs

@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.Core;
@ -29,11 +31,9 @@ namespace SearchAndReplace @@ -29,11 +31,9 @@ namespace SearchAndReplace
set {
if (value != FindPattern) {
findPattern = value;
string[] oldPatterns = FindPatterns;
string[] newPatterns = new string[oldPatterns.Length + 1];
oldPatterns.CopyTo(newPatterns, 1);
newPatterns[0] = value;
FindPatterns = newPatterns;
List<string> patterns = FindPatterns.ToList();
patterns.Insert(0, value);
FindPatterns = patterns;
}
}
}
@ -47,12 +47,12 @@ namespace SearchAndReplace @@ -47,12 +47,12 @@ namespace SearchAndReplace
}
}
public static string[] FindPatterns {
public static IReadOnlyList<string> FindPatterns {
get {
return properties.Get("FindPatterns", new string[0]);
return properties.GetList<string>("FindPatterns");
}
set {
properties.Set("FindPatterns", value);
properties.SetList("FindPatterns", value);
}
}
@ -65,22 +65,20 @@ namespace SearchAndReplace @@ -65,22 +65,20 @@ namespace SearchAndReplace
}
set {
if (value != ReplacePattern) {
string[] oldPatterns = ReplacePatterns;
string[] newPatterns = new string[oldPatterns.Length + 1];
oldPatterns.CopyTo(newPatterns, 1);
newPatterns[0] = value;
ReplacePatterns = newPatterns;
List<string> patterns = ReplacePatterns.ToList();
patterns.Insert(0, value);
ReplacePatterns = patterns;
replacePattern = value;
}
}
}
public static string[] ReplacePatterns {
public static IReadOnlyList<string> ReplacePatterns {
get {
return properties.Get("ReplacePatterns", new string[0]);
return properties.GetList<string>("ReplacePatterns");
}
set {
properties.Set("ReplacePatterns", value);
properties.SetList("ReplacePatterns", value);
}
}
@ -150,7 +148,7 @@ namespace SearchAndReplace @@ -150,7 +148,7 @@ namespace SearchAndReplace
static SearchOptions()
{
properties = PropertyService.Get(searchPropertyKey, new Properties());
properties = PropertyService.NestedProperties(searchPropertyKey);
}
}
}

6
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/AnalyticsMonitor.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.UsageDataCollector @@ -28,7 +28,7 @@ namespace ICSharpCode.UsageDataCollector
public static bool EnabledIsUndecided {
get {
return string.IsNullOrEmpty(PropertyService.Get("ICSharpCode.UsageDataCollector.Enabled"));
return PropertyService.Contains("ICSharpCode.UsageDataCollector.Enabled");
}
}
@ -37,10 +37,10 @@ namespace ICSharpCode.UsageDataCollector @@ -37,10 +37,10 @@ namespace ICSharpCode.UsageDataCollector
/// </summary>
public static bool Enabled {
get {
return string.Equals(PropertyService.Get("ICSharpCode.UsageDataCollector.Enabled"), bool.TrueString, StringComparison.OrdinalIgnoreCase);
return PropertyService.Get("ICSharpCode.UsageDataCollector.Enabled", false);
}
set {
PropertyService.Set("ICSharpCode.UsageDataCollector.Enabled", value.ToString());
PropertyService.Set("ICSharpCode.UsageDataCollector.Enabled", value);
// Initially opening the session takes some time; which is bad for the startpage
// because the animation would start with a delay. We solve this by calling Open/CloseSession
// on a background thread.

1
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/StartPageMessage.xaml.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.UsageDataCollector @@ -38,6 +38,7 @@ namespace ICSharpCode.UsageDataCollector
mainPanel.IsCollapsed = true;
acceptedMessage.IsCollapsed = !accepted;
declinedMessage.IsCollapsed = accepted;
Core.PropertyService.Save();
}
public static readonly DependencyProperty HeaderProperty = HeaderedContentControl.HeaderProperty.AddOwner(typeof(StartPageMessage));

2
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/UsageDataCollector.AddIn.csproj

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>ICSharpCode.UsageDataCollector</RootNamespace>
<AssemblyName>UsageDataCollector.AddIn</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<OutputPath>..\..\..\..\..\AddIns\Misc\UsageDataCollector\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>

2
src/AddIns/VersionControl/SubversionAddIn/Src/AddInOptions.cs

@ -14,7 +14,7 @@ namespace ICSharpCode.Svn @@ -14,7 +14,7 @@ namespace ICSharpCode.Svn
static AddInOptions()
{
properties = PropertyService.Get(OptionsProperty, new Properties());
properties = PropertyService.NestedProperties(OptionsProperty);
}
#region Properties

2
src/Main/Base/Project/Src/Commands/AutostartCommands.cs

@ -87,7 +87,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -87,7 +87,7 @@ namespace ICSharpCode.SharpDevelop.Commands
// save the workbench memento in the ide properties
try {
PropertyService.Set(workbenchMemento, WorkbenchSingleton.Workbench.CreateMemento());
PropertyService.SetNestedProperties(workbenchMemento, WorkbenchSingleton.Workbench.CreateMemento());
} catch (Exception e) {
MessageService.ShowException(e, "Exception while saving workbench state.");
}

8
src/Main/Base/Project/Src/Gui/BrowserDisplayBinding/HtmlViewPane.cs

@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.SharpDevelop.Gui;
@ -244,7 +244,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding @@ -244,7 +244,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding
SetUrlBox(comboBox);
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
comboBox.Items.Clear();
comboBox.Items.AddRange(PropertyService.Get("Browser.URLBoxHistory", new string[0]));
comboBox.Items.AddRange(PropertyService.GetList<string>("Browser.URLBoxHistory"));
comboBox.AutoCompleteMode = AutoCompleteMode.Suggest;
comboBox.AutoCompleteSource = AutoCompleteSource.HistoryList;
}
@ -276,7 +276,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding @@ -276,7 +276,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding
comboBox.Items.Remove(text);
comboBox.Items.Insert(0, text);
// Add to URLBoxHistory:
string[] history = PropertyService.Get("Browser.URLBoxHistory", new string[0]);
string[] history = PropertyService.GetList<string>("Browser.URLBoxHistory").ToArray();
int pos = Array.IndexOf(history, text);
if (pos < 0 && history.Length >= 20) {
pos = history.Length - 1; // remove last entry and insert new at the beginning
@ -292,7 +292,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding @@ -292,7 +292,7 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding
}
}
history[0] = text;
PropertyService.Set("Browser.URLBoxHistory", history);
PropertyService.SetList("Browser.URLBoxHistory", history);
}
}

5
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/CodeGenerationPanel.cs

@ -15,7 +15,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -15,7 +15,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
SetupFromXmlStream(this.GetType().Assembly.GetManifestResourceStream("Resources.CodeGenerationOptionsPanel.xfrm"));
Properties p = (Properties)PropertyService.Get(codeGenerationProperty, new Properties());
Properties p = PropertyService.NestedProperties(codeGenerationProperty);
((CheckBox)ControlDictionary["generateAdditonalCommentsCheckBox"]).Checked = p.Get("GenerateAdditionalComments", true);
((CheckBox)ControlDictionary["generateDocCommentsCheckBox"]).Checked = p.Get("GenerateDocumentComments", true);
@ -28,14 +28,13 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -28,14 +28,13 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
public override bool StorePanelContents()
{
Properties p = (Properties)PropertyService.Get(codeGenerationProperty, new Properties());
Properties p = PropertyService.NestedProperties(codeGenerationProperty);
p.Set("GenerateAdditionalComments", ((CheckBox)ControlDictionary["generateAdditonalCommentsCheckBox"]).Checked);
p.Set("GenerateDocumentComments", ((CheckBox)ControlDictionary["generateDocCommentsCheckBox"]).Checked);
p.Set("UseFullyQualifiedNames", ((CheckBox)ControlDictionary["useFullTypeNamesCheckBox"]).Checked);
p.Set("BlankLinesBetweenMembers", ((CheckBox)ControlDictionary["blankLinesBetweenMemberCheckBox"]).Checked);
p.Set("ElseOnClosing", ((CheckBox)ControlDictionary["elseOnClosingCheckbox"]).Checked);
p.Set("StartBlockOnSameLine", ((CheckBox)ControlDictionary["startBlockOnTheSameLineCheckBox"]).Checked);
PropertyService.Set(codeGenerationProperty, p);
return true;
}
}

5
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/OutputWindowOptionsPanel.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
SetupFromXmlStream(this.GetType().Assembly.GetManifestResourceStream("Resources.OutputWindowOptionsPanel.xfrm"));
Properties properties = (Properties)PropertyService.Get(OutputWindowsProperty, new Properties());
Properties properties = PropertyService.NestedProperties(OutputWindowsProperty);
fontSelectionPanel = new FontSelectionPanel();
fontSelectionPanel.Dock = DockStyle.Fill;
ControlDictionary["FontGroupBox"].Controls.Add(fontSelectionPanel);
@ -35,13 +35,12 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -35,13 +35,12 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
public override bool StorePanelContents()
{
Properties properties = (Properties)PropertyService.Get(OutputWindowsProperty, new Properties());
Properties properties = PropertyService.NestedProperties(OutputWindowsProperty);
properties.Set("WordWrap", ((CheckBox)ControlDictionary["wordWrapCheckBox"]).Checked);
string currentFontString = fontSelectionPanel.CurrentFontString;
if (currentFontString != null)
properties.Set("DefaultFont", currentFontString);
PropertyService.Set(OutputWindowsProperty, properties);
return true;
}
}

46
src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopColorDialog.cs

@ -3,9 +3,9 @@ @@ -3,9 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Gui
@ -22,46 +22,6 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -22,46 +22,6 @@ namespace ICSharpCode.SharpDevelop.Gui
LoadCustomColors();
}
/// <summary>
/// Converts a string of colors separated by the '|' character
/// into an array of colors.
/// </summary>
public static int[] CustomColorsFromString(string s)
{
if (String.IsNullOrEmpty(s)) {
return null;
}
string[] items = s.Split('|');
List<int> colors = new List<int>();
foreach (string item in items) {
int color;
if (Int32.TryParse(item, out color)) {
colors.Add(color);
}
}
return colors.ToArray();
}
/// <summary>
/// Converts an integer array of colors into a string.
/// </summary>
public static string CustomColorsToString(int[] colors)
{
if (colors == null) {
return String.Empty;
}
StringBuilder s = new StringBuilder();
for (int i = 0; i < colors.Length; ++i) {
if (i != 0) {
s.Append('|');
}
s.Append(colors[i]);
}
return s.ToString();
}
protected override bool RunDialog(IntPtr hwndOwner)
{
bool result = base.RunDialog(hwndOwner);
@ -71,12 +31,12 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -71,12 +31,12 @@ namespace ICSharpCode.SharpDevelop.Gui
void LoadCustomColors()
{
CustomColors = CustomColorsFromString(PropertyService.Get(CustomColorsPropertyName));
CustomColors = PropertyService.GetList<int>(CustomColorsPropertyName).ToArray();
}
void SaveCustomColors()
{
PropertyService.Set(CustomColorsPropertyName, CustomColorsToString(CustomColors));
PropertyService.SetList(CustomColorsPropertyName, CustomColors);
}
public bool? ShowWpfDialog()

7
src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
@ -204,7 +205,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -204,7 +205,7 @@ namespace ICSharpCode.SharpDevelop.Gui
textEditor.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/CompilerMessageView/ContextMenu");
properties = (Properties)PropertyService.Get(OutputWindowOptionsPanel.OutputWindowsProperty, new Properties());
properties = PropertyService.NestedProperties(OutputWindowOptionsPanel.OutputWindowsProperty);
var font = FontSelectionPanel.ParseFont(properties.Get("DefaultFont", Core.WinForms.WinFormsResourceService.DefaultMonospacedFont.ToString()).ToString());
@ -396,11 +397,11 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -396,11 +397,11 @@ namespace ICSharpCode.SharpDevelop.Gui
/// </summary>
void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.Key == "WordWrap") {
if (e.PropertyName == "WordWrap") {
SetWordWrap();
ToolBarService.UpdateStatus(toolStrip.Items);
}
if (e.Key == "DefaultFont") {
if (e.PropertyName == "DefaultFont") {
var font = FontSelectionPanel.ParseFont(properties.Get("DefaultFont", Core.WinForms.WinFormsResourceService.DefaultMonospacedFont.ToString()).ToString());
textEditor.FontFamily = new FontFamily(font.FontFamily.Name);

2
src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -74,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.Gui
public ErrorListPad()
{
instance = this;
properties = PropertyService.Get("ErrorListPad", new Properties());
properties = PropertyService.NestedProperties("ErrorListPad");
RedrawContent();
ResourceService.LanguageChanged += delegate { RedrawContent(); };

7
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -517,7 +517,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -517,7 +517,7 @@ namespace ICSharpCode.SharpDevelop.Gui
Properties memento = mementoCapable.CreateMemento();
Properties p = this.LoadOrCreateViewContentMementos();
p.Set(key, memento);
p.SetNestedProperties(key, memento);
FileUtility.ObservedSave(new NamedFileOperationDelegate(p.Save), this.ViewContentMementosFileName, FileErrorPolicy.Inform);
}
}
@ -533,10 +533,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -533,10 +533,7 @@ namespace ICSharpCode.SharpDevelop.Gui
string key = GetMementoKeyName(viewContent);
LoggingService.Debug("Trying to restore memento of '" + viewContent.ToString() + "' from key '" + key + "'");
Properties memento = this.LoadOrCreateViewContentMementos().Get<Properties>(key, null);
if (memento != null) {
mementoCapable.SetMemento(memento);
}
mementoCapable.SetMemento(this.LoadOrCreateViewContentMementos().NestedProperties(key));
} catch (Exception e) {
MessageService.ShowException(e, "Can't get/set memento");
}

2
src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -83,7 +83,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
workbench.Initialize();
workbench.SetMemento(PropertyService.Get(workbenchMemento, new Properties()));
workbench.SetMemento(PropertyService.NestedProperties(workbenchMemento));
workbench.WorkbenchLayout = layout;
ApplicationStateInfoService.RegisterStateGetter(activeContentState, delegate { return WorkbenchSingleton.Workbench.ActiveContent; });

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

@ -76,7 +76,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -76,7 +76,7 @@ namespace ICSharpCode.SharpDevelop.Project
public void SetMemento(Properties memento)
{
// other project data
this.ProjectSpecificProperties = memento.Get("projectSavedData", new Properties());
this.ProjectSpecificProperties = memento.NestedProperties("projectSavedData");
GetOrCreateBehavior().SetMemento(memento);
}
#endregion

10
src/Main/Base/Project/Src/Project/Behaviors/DefaultProjectBehavior.cs

@ -93,17 +93,17 @@ namespace ICSharpCode.SharpDevelop.Project @@ -93,17 +93,17 @@ namespace ICSharpCode.SharpDevelop.Project
// breakpoints and files
Properties properties = new Properties();
properties.Set("bookmarks", ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.GetProjectBookmarks(Project).ToArray());
properties.SetList("bookmarks", ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.GetProjectBookmarks(Project));
List<string> files = new List<string>();
foreach (string fileName in FileService.GetOpenFiles()) {
if (fileName != null && Project.IsFileInProject(fileName)) {
files.Add(fileName);
}
}
properties.Set("files", files.ToArray());
properties.SetList("files", files);
// other project data
properties.Set("projectSavedData", Project.ProjectSpecificProperties ?? new Properties());
properties.SetNestedProperties("projectSavedData", Project.ProjectSpecificProperties.Clone());
return properties;
}
@ -112,11 +112,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -112,11 +112,11 @@ namespace ICSharpCode.SharpDevelop.Project
{
WorkbenchSingleton.AssertMainThread();
foreach (ICSharpCode.SharpDevelop.Bookmarks.SDBookmark mark in memento.Get("bookmarks", new ICSharpCode.SharpDevelop.Bookmarks.SDBookmark[0])) {
foreach (var mark in memento.GetList<ICSharpCode.SharpDevelop.Bookmarks.SDBookmark>("bookmarks")) {
ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.AddMark(mark);
}
List<string> filesToOpen = new List<string>();
foreach (string fileName in memento.Get("files", new string[0])) {
foreach (string fileName in memento.GetList<string>("files")) {
if (File.Exists(fileName)) {
filesToOpen.Add(fileName);
}

2
src/Main/Base/Project/Src/Services/AmbienceService/AmbienceService.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop
public static Properties CodeGenerationProperties {
get {
return PropertyService.Get(codeGenerationProperty, new Properties());
return PropertyService.NestedProperties(codeGenerationProperty);
}
}

8
src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingService.cs

@ -25,8 +25,8 @@ namespace ICSharpCode.SharpDevelop @@ -25,8 +25,8 @@ namespace ICSharpCode.SharpDevelop
internal static void InitializeService()
{
bindings = AddInTree.BuildItems<DisplayBindingDescriptor>(displayBindingPath, null, true);
displayBindingServiceProperties = PropertyService.Get("DisplayBindingService", new Properties());
foreach (ExternalProcessDisplayBinding binding in displayBindingServiceProperties.Get("ExternalProcesses", new ExternalProcessDisplayBinding[0])) {
displayBindingServiceProperties = PropertyService.NestedProperties("DisplayBindingService");
foreach (var binding in displayBindingServiceProperties.GetList<ExternalProcessDisplayBinding>("ExternalProcesses")) {
if (binding != null) {
AddExternalProcessDisplayBindingInternal(binding);
}
@ -45,7 +45,7 @@ namespace ICSharpCode.SharpDevelop @@ -45,7 +45,7 @@ namespace ICSharpCode.SharpDevelop
static void SaveExternalProcessDisplayBindings()
{
displayBindingServiceProperties.Set("ExternalProcesses", externalProcessDisplayBindings.ToArray());
displayBindingServiceProperties.SetList("ExternalProcesses", externalProcessDisplayBindings);
}
static DisplayBindingDescriptor AddExternalProcessDisplayBindingInternal(ExternalProcessDisplayBinding binding)
@ -98,7 +98,7 @@ namespace ICSharpCode.SharpDevelop @@ -98,7 +98,7 @@ namespace ICSharpCode.SharpDevelop
{
WorkbenchSingleton.AssertMainThread();
string defaultCommandID = displayBindingServiceProperties.Get("Default" + Path.GetExtension(filename).ToLowerInvariant()) as string;
string defaultCommandID = displayBindingServiceProperties.Get("Default" + Path.GetExtension(filename).ToLowerInvariant(), string.Empty);
if (!string.IsNullOrEmpty(defaultCommandID)) {
foreach (DisplayBindingDescriptor binding in bindings) {
if (binding.Id == defaultCommandID) {

4
src/Main/Base/Project/Src/Services/File/FileService.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.SharpDevelop @@ -26,7 +26,7 @@ namespace ICSharpCode.SharpDevelop
public static RecentOpen RecentOpen {
get {
if (recentOpen == null) {
recentOpen = RecentOpen.FromXmlElement(PropertyService.Get("RecentOpen", new Properties()));
recentOpen = RecentOpen.FromXmlElement(PropertyService.NestedProperties("RecentOpen"));
}
return recentOpen;
}
@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop @@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop
internal static void Unload()
{
if (recentOpen != null) {
PropertyService.Set("RecentOpen", recentOpen.ToProperties());
PropertyService.SetNestedProperties("RecentOpen", recentOpen.ToProperties());
}
ProjectService.SolutionLoaded -= ProjectServiceSolutionLoaded;
ParserService.LoadSolutionProjectsThreadEnded -= ParserServiceLoadSolutionProjectsThreadEnded;

14
src/Main/Base/Project/Src/Services/File/RecentOpen.cs

@ -48,14 +48,8 @@ namespace ICSharpCode.SharpDevelop @@ -48,14 +48,8 @@ namespace ICSharpCode.SharpDevelop
// don't check whether files exist because that might be slow (e.g. if file is on network
// drive that's unavailable)
// if one of these entries is a string, then it's from a previous SharpDevelop version - don't try loading it
if (p.Contains("Files") && !(p.Get("Files") is string)) {
lastfile.AddRange(p.Get("Files", new string[0]));
}
if (p.Contains("Projects") && !(p.Get("Files") is string)) {
lastproject.AddRange(p.Get("Projects", new string[0]));
}
lastfile.AddRange(p.GetList<string>("Files"));
lastproject.AddRange(p.GetList<string>("Projects"));
}
public void AddLastFile(string name)
@ -107,8 +101,8 @@ namespace ICSharpCode.SharpDevelop @@ -107,8 +101,8 @@ namespace ICSharpCode.SharpDevelop
public Properties ToProperties()
{
Properties p = new Properties();
p.Set("Files", lastfile.ToArray());
p.Set("Projects", lastproject.ToArray());
p.SetList("Files", lastfile);
p.SetList("Projects", lastproject);
return p;
}

4
src/Main/Base/Project/Src/Services/ParserService/CodeCompletionOptions.cs

@ -6,14 +6,12 @@ using ICSharpCode.Core; @@ -6,14 +6,12 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop
{
// TODO: what is this class doing in the ParserService ??
/// <summary>
/// Class containing static properties for the code completion options.
/// </summary>
public static class CodeCompletionOptions
{
static Properties properties = PropertyService.Get("CodeCompletionOptions", new Properties());
static Properties properties = PropertyService.NestedProperties("CodeCompletionOptions");
public static Properties Properties {
get {

9
src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

@ -170,8 +170,13 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -170,8 +170,13 @@ namespace ICSharpCode.SharpDevelop.Parser
/// This property is thread-safe.
/// </summary>
public static string[] TaskListTokens {
get { return PropertyService.Get("SharpDevelop.TaskListTokens", DefaultTaskListTokens); }
set { PropertyService.Set("SharpDevelop.TaskListTokens", value); }
get {
if (PropertyService.Contains("SharpDevelop.TaskListTokens"))
return PropertyService.GetList<string>("SharpDevelop.TaskListTokens").ToArray();
else
return DefaultTaskListTokens;
}
set { PropertyService.SetList("SharpDevelop.TaskListTokens", value); }
}
/// <summary>

23
src/Main/Base/Project/Src/Util/ExtensionMethods.cs

@ -110,6 +110,15 @@ namespace ICSharpCode.SharpDevelop @@ -110,6 +110,15 @@ namespace ICSharpCode.SharpDevelop
list.Add(o);
}
/// <summary>
/// Adds all <paramref name="elements"/> to <paramref name="list"/>.
/// </summary>
public static void AddRange(this WinForms.ComboBox.ObjectCollection list, IEnumerable elements)
{
foreach (var o in elements)
list.Add(o);
}
public static ReadOnlyCollection<T> AsReadOnly<T>(this IList<T> arr)
{
return new ReadOnlyCollection<T>(arr);
@ -471,6 +480,20 @@ namespace ICSharpCode.SharpDevelop @@ -471,6 +480,20 @@ namespace ICSharpCode.SharpDevelop
return -1;
}
/// <summary>
/// Returns the index of the first element for which <paramref name="predicate"/> returns true.
/// If none of the items in the list fits the <paramref name="predicate"/>, -1 is returned.
/// </summary>
public static int FindIndex<T>(this IReadOnlyList<T> list, Func<T, bool> predicate)
{
for (int i = 0; i < list.Count; i++) {
if (predicate(list[i]))
return i;
}
return -1;
}
/// <summary>
/// Adds item to the list if the item is not null.
/// </summary>

1
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -155,7 +155,6 @@ @@ -155,7 +155,6 @@
<Compile Include="NavigationServiceTests\INavigationPointTextFixture.cs" />
<Compile Include="NavigationServiceTests\TestNavigationPoint.cs" />
<Compile Include="NavigationServiceTests\NavigationServiceTestFixture.cs" />
<Compile Include="SharpDevelopColorDialogTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">

78
src/Main/Base/Test/SharpDevelopColorDialogTests.cs

@ -1,78 +0,0 @@ @@ -1,78 +0,0 @@
// 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 ICSharpCode.SharpDevelop.Gui;
using NUnit.Framework;
using System;
namespace ICSharpCode.SharpDevelop.Tests
{
[TestFixture]
public class SharpDevelopColorDialogTests
{
[Test]
public void NullString()
{
Assert.IsNull(SharpDevelopColorDialog.CustomColorsFromString(null));
}
[Test]
public void EmptyString()
{
Assert.IsNull(SharpDevelopColorDialog.CustomColorsFromString(String.Empty));
}
[Test]
public void OneColorInString()
{
int[] colors = SharpDevelopColorDialog.CustomColorsFromString("34");
Assert.AreEqual(1, colors.Length);
Assert.AreEqual(34, colors[0]);
}
[Test]
public void TwoColorsInString()
{
int[] colors = SharpDevelopColorDialog.CustomColorsFromString("20|30");
Assert.AreEqual(2, colors.Length);
Assert.AreEqual(20, colors[0]);
Assert.AreEqual(30, colors[1]);
}
[Test]
public void SecondColorIsInvalid()
{
int[] colors = SharpDevelopColorDialog.CustomColorsFromString("20|Test");
Assert.AreEqual(1, colors.Length);
Assert.AreEqual(20, colors[0]);
}
[Test]
public void FirstColorIsInvalid()
{
int[] colors = SharpDevelopColorDialog.CustomColorsFromString("Test|20");
Assert.AreEqual(1, colors.Length);
Assert.AreEqual(20, colors[0]);
}
[Test]
public void NullIntColorsArray()
{
Assert.AreEqual(String.Empty, SharpDevelopColorDialog.CustomColorsToString(null));
}
[Test]
public void OneCustomColor()
{
int[] colors = new int[] { 10 };
Assert.AreEqual("10", SharpDevelopColorDialog.CustomColorsToString(colors));
}
[Test]
public void TwoCustomColors()
{
int[] colors = new int[] { 10, 20 };
Assert.AreEqual("10|20", SharpDevelopColorDialog.CustomColorsToString(colors));
}
}
}

2
src/Main/Base/Test/Utils/MockTextMarker.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils @@ -49,7 +49,7 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils
public Nullable<Color> BackgroundColor { get; set; }
public Nullable<Color> ForegroundColor { get; set; }
public TextMarkerType MarkerType { get; set; }
public TextMarkerTypes MarkerTypes { get; set; }
public Color MarkerColor { get; set; }
public object Tag { get; set; }
public object ToolTip { get; set; }

10
src/Main/Core/Project/ICSharpCode.Core.csproj

@ -22,7 +22,8 @@ @@ -22,7 +22,8 @@
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<SourceAnalysisOverrideSettingsFile>C:\Users\daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -56,7 +57,13 @@ @@ -56,7 +57,13 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Runtime.Serialization">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\AssemblyInfo.cs" />
@ -107,7 +114,6 @@ @@ -107,7 +114,6 @@
<Compile Include="Src\Services\MessageService\IMessageService.cs" />
<Compile Include="Src\Services\MessageService\MessageService.cs" />
<Compile Include="Src\Services\PropertyService\Properties.cs" />
<Compile Include="Src\Services\PropertyService\PropertyChangedEvent.cs" />
<Compile Include="Src\Services\PropertyService\PropertyService.cs" />
<Compile Include="Src\Services\RegistryService\RegistryService.cs" />
<Compile Include="Src\Services\ResourceService\ResourceNotFoundException.cs" />

1
src/Main/Core/Project/Src/AddInTree/CoreStartup.cs

@ -200,7 +200,6 @@ namespace ICSharpCode.Core @@ -200,7 +200,6 @@ namespace ICSharpCode.Core
PropertyService.InitializeService(configDirectory,
dataDirectory ?? Path.Combine(FileUtility.ApplicationRootPath, "data"),
propertiesName);
PropertyService.Load();
ResourceService.InitializeService(Path.Combine(PropertyService.DataDirectory, "resources"));
StringParser.RegisterStringTagProvider(new AppNameProvider { appName = applicationName });
}

748
src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

@ -5,11 +5,15 @@ using System; @@ -5,11 +5,15 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace ICSharpCode.Core
@ -34,116 +38,462 @@ namespace ICSharpCode.Core @@ -34,116 +38,462 @@ namespace ICSharpCode.Core
}
/// <summary>
/// Description of PropertyGroup.
/// A container for settings - key/value pairs where keys are strings, and values are arbitrary objects.
/// Instances of this class are thread-safe.
/// </summary>
public class Properties
public sealed class Properties : INotifyPropertyChanged, ICloneable
{
/// <summary> Needed for support of late deserialization </summary>
class SerializedValue {
string content;
public string Content {
get { return content; }
// Properties instances form a tree due to the nested properties containers.
// All nodes in such a tree share the same syncRoot in order to simplify synchronization.
// When an existing node is added to a tree, its syncRoot needs to change.
object syncRoot;
Properties parent;
// Objects in the dictionary are one of:
// - string: value stored using TypeConverter
// - XElement: serialized object
// - object[]: a stored list (array elements are null, string or XElement)
// - Properties: nested properties container
Dictionary<string, object> dict = new Dictionary<string, object>();
#region Constructor
public Properties()
{
this.syncRoot = new object();
}
private Properties(Properties parent)
{
this.parent = parent;
this.syncRoot = parent.syncRoot;
}
#endregion
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string key)
{
var handler = Volatile.Read(ref PropertyChanged);
if (handler != null)
handler(this, new PropertyChangedEventArgs("key"));
}
#endregion
#region IsDirty
bool isDirty;
/// <summary>
/// Gets/Sets whether this properties container is dirty.
/// IsDirty automatically gets set to <c>true</c> when a property in this container (or a nested container)
/// changes.
/// </summary>
public bool IsDirty {
get { return isDirty; }
set {
lock (syncRoot) {
if (value)
MakeDirty();
else
CleanDirty();
}
}
public T Deserialize<T>()
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(content));
}
void MakeDirty()
{
// called within syncroot
if (!isDirty) {
isDirty = true;
if (parent != null)
parent.MakeDirty();
}
public SerializedValue(string content)
{
this.content = content;
}
void CleanDirty()
{
if (isDirty) {
isDirty = false;
foreach (var properties in dict.Values.OfType<Properties>()) {
properties.CleanDirty();
}
}
}
#endregion
Dictionary<string, object> properties = new Dictionary<string, object>();
#region Keys/Contains
public IReadOnlyList<string> Keys {
get {
lock (syncRoot) {
return dict.Keys.ToArray();
}
}
}
public string this[string property] {
/// <summary>
/// Gets whether this properties instance contains any entry (value, list, or nested container)
/// with the specified key.
/// </summary>
public bool Contains(string key)
{
lock (syncRoot) {
return dict.ContainsKey(key);
}
}
#endregion
#region Get and Set
/// <summary>
/// Retrieves a string value from this Properties-container.
/// Using this indexer is equivalent to calling <c>Get(key, string.Empty)</c>.
/// </summary>
public string this[string key] {
get {
return Convert.ToString(Get(property), CultureInfo.InvariantCulture);
lock (syncRoot) {
object val;
dict.TryGetValue(key, out val);
return val as string ?? string.Empty;
}
}
set {
Set(property, value);
Set(key, value);
}
}
public string[] Elements
/// <summary>
/// Retrieves a single element from this Properties-container.
/// </summary>
/// <param name="key">Key of the item to retrieve</param>
/// <param name="defaultValue">Default value to be returned if the key is not present.</param>
public T Get<T>(string key, T defaultValue)
{
get {
lock (properties) {
return properties.Keys.ToArray();
lock (syncRoot) {
object val;
if (dict.TryGetValue(key, out val)) {
return (T)Deserialize(val, typeof(T));
} else {
return defaultValue;
}
}
}
/// <summary>
/// Sets a single element in this Properties-container.
/// The element will be serialized using a TypeConverter if possible, or DataContractSerializer otherwise.
/// </summary>
/// <remarks>Setting a key to <c>null</c> has the same effect as calling <see cref="Remove"/>.</remarks>
public void Set<T>(string key, T value)
{
object serializedValue = Serialize(value, typeof(T), key);
SetSerializedValue(key, serializedValue);
}
void SetSerializedValue(string key, object serializedValue)
{
if (serializedValue == null) {
Remove(key);
return;
}
lock (syncRoot) {
object oldValue;
if (dict.TryGetValue(key, out oldValue)) {
if (object.Equals(serializedValue, oldValue))
return;
HandleOldValue(oldValue);
}
dict[key] = serializedValue;
}
OnPropertyChanged(key);
}
#endregion
public object Get(string property)
#region GetList/SetList
/// <summary>
/// Retrieves the list of items stored with the specified key.
/// If no entry with the specified key exists, this method returns an empty list.
/// </summary>
/// <remarks>
/// This method returns a copy of the list used internally; you need to call
/// <see cref="SetList"/> if you want to store the changed list.
/// </remarks>
public IReadOnlyList<T> GetList<T>(string key)
{
lock (properties) {
lock (syncRoot) {
object val;
properties.TryGetValue(property, out val);
return val;
if (dict.TryGetValue(key, out val)) {
object[] serializedArray = val as object[];
if (serializedArray != null) {
T[] array = new T[serializedArray.Length];
for (int i = 0; i < array.Length; i++) {
array[i] = (T)Deserialize(serializedArray[i], typeof(T));
}
return array;
} else {
LoggingService.Warn("Properties.GetList(" + key + ") - this entry is not a list");
}
}
return new T[0];
}
}
public void Set<T>(string property, T value)
/// <summary>
/// Sets a list of elements in this Properties-container.
/// The elements will be serialized using a TypeConverter if possible, or DataContractSerializer otherwise.
/// </summary>
/// <remarks>Passing <c>null</c> or an empty list as value has the same effect as calling <see cref="Remove"/>.</remarks>
public void SetList<T>(string key, IEnumerable<T> value)
{
if (value == null) {
Remove(key);
return;
}
T[] array = value.ToArray();
if (array.Length == 0) {
Remove(key);
return;
}
object[] serializedArray = new object[array.Length];
for (int i = 0; i < array.Length; i++) {
serializedArray[i] = Serialize(array[i], typeof(T), null);
}
SetSerializedValue(key, serializedArray);
}
[Obsolete("Use the GetList method instead", true)]
public T[] Get<T>(string key, T[] defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public void Set<T>(string key, T[] value)
{
throw new InvalidOperationException();
}
[Obsolete("Use the GetList method instead", true)]
public List<T> Get<T>(string key, List<T> defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public void Set<T>(string key, List<T> value)
{
throw new InvalidOperationException();
}
[Obsolete("Use the GetList method instead", true)]
public ArrayList Get<T>(string key, ArrayList defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public void Set<T>(string key, ArrayList value)
{
throw new InvalidOperationException();
}
#endregion
#region Serialization
object Serialize(object value, Type sourceType, string key)
{
if (property == null)
throw new ArgumentNullException("property");
if (value == null)
throw new ArgumentNullException("value");
T oldValue = default(T);
lock (properties) {
if (!properties.ContainsKey(property)) {
properties.Add(property, value);
} else {
oldValue = Get<T>(property, value);
properties[property] = value;
return null;
TypeConverter c = TypeDescriptor.GetConverter(sourceType);
if (c != null && c.CanConvertTo(typeof(string)) && c.CanConvertFrom(typeof(string))) {
return c.ConvertToInvariantString(value);
}
var element = new XElement("SerializedObject");
if (key != null) {
element.Add(new XAttribute("key", key));
}
var s = new DataContractSerializer(sourceType);
using (var xmlWriter = element.CreateWriter()) {
s.WriteObject(xmlWriter, value);
}
return element;
}
object Deserialize(object serializedVal, Type targetType)
{
if (serializedVal == null)
return null;
XElement element = serializedVal as XElement;
if (element != null) {
var s = new DataContractSerializer(targetType);
using (var xmlReader = element.CreateReader()) {
xmlReader.MoveToContent();
xmlReader.Read(); // skip <SerializedObject>
xmlReader.MoveToContent();
return s.ReadObject(xmlReader);
}
} else {
string text = serializedVal as string;
if (text == null)
throw new InvalidOperationException("Cannot read a properties container as a single value");
TypeConverter c = TypeDescriptor.GetConverter(targetType);
return c.ConvertFromInvariantString(text);
}
OnPropertyChanged(new PropertyChangedEventArgs(this, property, oldValue, value));
}
#endregion
public bool Contains(string property)
#region Remove
/// <summary>
/// Removes the entry (value, list, or nested container) with the specified key.
/// </summary>
public bool Remove(string key)
{
lock (properties) {
return properties.ContainsKey(property);
bool removed = false;
lock (syncRoot) {
object oldValue;
if (dict.TryGetValue(key, out oldValue)) {
removed = true;
HandleOldValue(oldValue);
MakeDirty();
}
}
if (removed)
OnPropertyChanged(key);
return removed;
}
public int Count {
#endregion
#region Nested Properties
/// <summary>
/// Gets the parent property container.
/// </summary>
public Properties Parent {
get {
lock (properties) {
return properties.Count;
lock (syncRoot) {
return parent;
}
}
}
[Obsolete("Use the NestedProperties method instead", true)]
public Properties Get(string key, Properties defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetNestedProperties method instead", true)]
public void Set(string key, Properties value)
{
throw new InvalidOperationException();
}
/// <summary>
/// Retrieves a nested property container; creating a new one on demand.
/// Multiple calls to this method will return the same instance (unless the entry at this key
/// is overwritten by one of the Set-methods).
/// Changes performed on the nested container will be persisted together with the parent container.
/// </summary>
public Properties NestedProperties(string key)
{
bool isNewContainer = false;
Properties result;
lock (syncRoot) {
object oldValue;
dict.TryGetValue(key, out oldValue);
result = oldValue as Properties;
if (result == null) {
result = new Properties(this);
dict[key] = result;
result.MakeDirty();
}
}
if (isNewContainer)
OnPropertyChanged(key);
return result;
}
public bool Remove(string property)
void HandleOldValue(object oldValue)
{
lock (properties) {
return properties.Remove(property);
Properties p = oldValue as Properties;
if (p != null) {
Debug.Assert(p.parent == this);
p.parent = null;
}
}
public override string ToString()
/// <summary>
/// Attaches the specified properties container as nested properties.
///
/// This method is intended to be used in conjunction with the <see cref="IMementoCapable"/> pattern
/// where a new unattached properties container is created and then later attached to a parent container.
/// </summary>
public void SetNestedProperties(string key, Properties properties)
{
lock (properties) {
StringBuilder sb = new StringBuilder();
sb.Append("[Properties:{");
foreach (KeyValuePair<string, object> entry in properties) {
sb.Append(entry.Key);
sb.Append("=");
sb.Append(entry.Value);
sb.Append(",");
if (properties == null) {
Remove(key);
return;
}
lock (syncRoot) {
for (Properties ancestor = this; ancestor != null; ancestor = ancestor.parent) {
if (ancestor == properties)
throw new InvalidOperationException("Cannot add a properties container to itself.");
}
object oldValue;
if (dict.TryGetValue(key, out oldValue)) {
if (oldValue == properties)
return;
HandleOldValue(oldValue);
}
lock (properties.syncRoot) {
if (properties.parent != null)
throw new InvalidOperationException("Cannot attach nested properties that already have a parent.");
MakeDirty();
properties.SetSyncRoot(syncRoot);
properties.parent = this;
dict[key] = properties;
}
sb.Append("}]");
return sb.ToString();
}
OnPropertyChanged(key);
}
public static Properties ReadFromAttributes(XmlReader reader)
void SetSyncRoot(object newSyncRoot)
{
this.syncRoot = newSyncRoot;
foreach (var properties in dict.Values.OfType<Properties>()) {
properties.SetSyncRoot(newSyncRoot);
}
}
#endregion
#region Clone
/// <summary>
/// Creates a deep clone of this Properties container.
/// </summary>
public Properties Clone()
{
lock (syncRoot) {
return CloneWithParent(null);
}
}
Properties CloneWithParent(Properties parent)
{
Properties copy = parent != null ? new Properties(parent) : new Properties();
foreach (var pair in dict) {
Properties child = pair.Value as Properties;
if (child != null)
copy.dict.Add(pair.Key, child.CloneWithParent(copy));
else
copy.dict.Add(pair.Key, pair.Value);
}
return copy;
}
object ICloneable.Clone()
{
return Clone();
}
#endregion
#region ReadFromAttributes
internal static Properties ReadFromAttributes(XmlReader reader)
{
Properties properties = new Properties();
if (reader.HasAttributes) {
@ -159,231 +509,109 @@ namespace ICSharpCode.Core @@ -159,231 +509,109 @@ namespace ICSharpCode.Core
}
return properties;
}
#endregion
internal void ReadProperties(XmlReader reader, string endElement)
#region Load/Save
public static Properties Load(string fileName)
{
if (reader.IsEmptyElement) {
return;
}
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.EndElement:
if (reader.LocalName == endElement) {
return;
}
break;
case XmlNodeType.Element:
string propertyName = reader.LocalName;
if (propertyName == "Properties") {
propertyName = reader.GetAttribute(0);
Properties p = new Properties();
p.ReadProperties(reader, "Properties");
properties[propertyName] = p;
} else if (propertyName == "Array") {
propertyName = reader.GetAttribute(0);
properties[propertyName] = ReadArray(reader);
} else if (propertyName == "SerializedValue") {
propertyName = reader.GetAttribute(0);
properties[propertyName] = new SerializedValue(reader.ReadInnerXml());
} else {
properties[propertyName] = reader.HasAttributes ? reader.GetAttribute(0) : null;
}
break;
}
}
return Load(XDocument.Load(fileName).Root);
}
ArrayList ReadArray(XmlReader reader)
public static Properties Load(XElement element)
{
if (reader.IsEmptyElement)
return new ArrayList(0);
ArrayList l = new ArrayList();
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.EndElement:
if (reader.LocalName == "Array") {
return l;
}
Properties properties = new Properties();
properties.LoadContents(element.Elements());
return properties;
}
void LoadContents(IEnumerable<XElement> elements)
{
foreach (var element in elements) {
string key = (string)element.Attribute("key");
if (key == null)
continue;
switch (element.Name.LocalName) {
case "Property":
dict[key] = element.Value;
break;
case XmlNodeType.Element:
l.Add(reader.HasAttributes ? reader.GetAttribute(0) : null);
case "Array":
dict[key] = LoadArray(element.Elements());
break;
case "SerializedObject":
dict[key] = new XElement(element);
break;
case "Properties":
Properties child = new Properties(this);
child.LoadContents(element.Elements());
dict[key] = child;
break;
}
}
return l;
}
public void WriteProperties(XmlWriter writer)
{
lock (properties) {
List<KeyValuePair<string, object>> sortedProperties = new List<KeyValuePair<string, object>>(properties);
sortedProperties.Sort((a, b) => StringComparer.OrdinalIgnoreCase.Compare(a.Key, b.Key));
foreach (KeyValuePair<string, object> entry in sortedProperties) {
object val = entry.Value;
if (val is Properties) {
writer.WriteStartElement("Properties");
writer.WriteAttributeString("name", entry.Key);
((Properties)val).WriteProperties(writer);
writer.WriteEndElement();
} else if (val is Array || val is ArrayList) {
writer.WriteStartElement("Array");
writer.WriteAttributeString("name", entry.Key);
foreach (object o in (IEnumerable)val) {
writer.WriteStartElement("Element");
WriteValue(writer, o);
writer.WriteEndElement();
}
writer.WriteEndElement();
} else if (TypeDescriptor.GetConverter(val).CanConvertFrom(typeof(string))) {
writer.WriteStartElement(entry.Key);
WriteValue(writer, val);
writer.WriteEndElement();
} else if (val is SerializedValue) {
writer.WriteStartElement("SerializedValue");
writer.WriteAttributeString("name", entry.Key);
writer.WriteRaw(((SerializedValue)val).Content);
writer.WriteEndElement();
} else {
writer.WriteStartElement("SerializedValue");
writer.WriteAttributeString("name", entry.Key);
XmlSerializer serializer = new XmlSerializer(val.GetType());
serializer.Serialize(writer, val, null);
writer.WriteEndElement();
}
}
}
}
void WriteValue(XmlWriter writer, object val)
static object[] LoadArray(IEnumerable<XElement> elements)
{
if (val != null) {
if (val is string) {
writer.WriteAttributeString("value", val.ToString());
} else {
TypeConverter c = TypeDescriptor.GetConverter(val.GetType());
writer.WriteAttributeString("value", c.ConvertToInvariantString(val));
List<object> result = new List<object>();
foreach (var element in elements) {
switch (element.Name.LocalName) {
case "Null":
result.Add(null);
break;
case "Element":
result.Add(element.Value);
break;
case "SerializedObject":
result.Add(new XElement(element));
break;
}
}
return result.ToArray();
}
public void Save(string fileName)
{
XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
Save(writer);
}
public void Save(XmlWriter writer)
{
using (writer) {
writer.WriteStartElement("Properties");
WriteProperties(writer);
writer.WriteEndElement();
}
new XDocument(Save()).Save(fileName);
}
// public void BinarySerialize(BinaryWriter writer)
// {
// writer.Write((byte)properties.Count);
// foreach (KeyValuePair<string, object> entry in properties) {
// writer.Write(AddInTree.GetNameOffset(entry.Key));
// writer.Write(AddInTree.GetNameOffset(entry.Value.ToString()));
// }
// }
public static Properties Load(string fileName)
public XElement Save()
{
if (!File.Exists(fileName)) {
return null;
lock (syncRoot) {
return new XElement("Properties", SaveContents());
}
XmlTextReader reader = new XmlTextReader(fileName);
return Load(reader);
}
public static Properties Load(XmlReader reader)
IReadOnlyList<XElement> SaveContents()
{
using (reader) {
while (reader.Read()){
if (reader.IsStartElement()) {
switch (reader.LocalName) {
case "Properties":
Properties properties = new Properties();
properties.ReadProperties(reader, "Properties");
return properties;
}
}
}
}
return null;
}
public T Get<T>(string property, T defaultValue)
{
lock (properties) {
object o;
if (!properties.TryGetValue(property, out o)) {
properties.Add(property, defaultValue);
return defaultValue;
}
if (o is string && typeof(T) != typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
try {
o = c.ConvertFromInvariantString(o.ToString());
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
} else if (o is ArrayList && typeof(T).IsArray) {
ArrayList list = (ArrayList)o;
Type elementType = typeof(T).GetElementType();
Array arr = System.Array.CreateInstance(elementType, list.Count);
TypeConverter c = TypeDescriptor.GetConverter(elementType);
try {
for (int i = 0; i < arr.Length; ++i) {
if (list[i] != null) {
arr.SetValue(c.ConvertFromInvariantString(list[i].ToString()), i);
}
List<XElement> result = new List<XElement>();
foreach (var pair in dict) {
XAttribute key = new XAttribute("key", pair.Key);
Properties child = pair.Value as Properties;
if (child != null) {
var contents = child.SaveContents();
if (contents.Count > 0)
result.Add(new XElement("Properties", key, contents));
} else if (pair.Value is object[]) {
object[] array = (object[])pair.Value;
XElement[] elements = new XElement[array.Length];
for (int i = 0; i < array.Length; i++) {
XElement obj = array[i] as XElement;
if (obj != null) {
elements[i] = new XElement(obj);
} else if (array[i] == null) {
elements[i] = new XElement("Null");
} else {
elements[i] = new XElement("Element", (string)array[i]);
}
o = arr;
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
} else if (!(o is string) && typeof(T) == typeof(string)) {
TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
if (c.CanConvertTo(typeof(string))) {
o = c.ConvertToInvariantString(o);
} else {
o = o.ToString();
}
} else if (o is SerializedValue) {
try {
o = ((SerializedValue)o).Deserialize<T>();
} catch (Exception ex) {
MessageService.ShowWarning("Error loading property '" + property + "': " + ex.Message);
o = defaultValue;
}
properties[property] = o; // store for future look up
}
try {
return (T)o;
} catch (NullReferenceException) {
// can happen when configuration is invalid -> o is null and a value type is expected
return defaultValue;
result.Add(new XElement("Array", key, elements));
} else if (pair.Value is XElement) {
result.Add(new XElement((XElement)pair.Value));
} else {
result.Add(new XElement("Property", key, (string)pair.Value));
}
}
return result;
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) {
PropertyChanged(this, e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}

61
src/Main/Core/Project/Src/Services/PropertyService/PropertyChangedEvent.cs

@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
// 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;
namespace ICSharpCode.Core
{
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
public class PropertyChangedEventArgs : EventArgs
{
Properties properties;
string key;
object newValue;
object oldValue;
/// <returns>
/// returns the changed property object
/// </returns>
public Properties Properties {
get {
return properties;
}
}
/// <returns>
/// The key of the changed property
/// </returns>
public string Key {
get {
return key;
}
}
/// <returns>
/// The new value of the property
/// </returns>
public object NewValue {
get {
return newValue;
}
}
/// <returns>
/// The new value of the property
/// </returns>
public object OldValue {
get {
return oldValue;
}
}
public PropertyChangedEventArgs(Properties properties, string key, object oldValue, object newValue)
{
this.properties = properties;
this.key = key;
this.oldValue = oldValue;
this.newValue = newValue;
}
}
}

169
src/Main/Core/Project/Src/Services/PropertyService/PropertyService.cs

@ -2,6 +2,9 @@ @@ -2,6 +2,9 @@
// 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.ComponentModel;
using System.IO;
using System.Text;
using System.Threading;
@ -12,7 +15,6 @@ namespace ICSharpCode.Core @@ -12,7 +15,6 @@ namespace ICSharpCode.Core
public static class PropertyService
{
static string propertyFileName;
static string propertyXmlRootNodeName;
static string configDirectory;
static string dataDirectory;
@ -26,19 +28,20 @@ namespace ICSharpCode.Core @@ -26,19 +28,20 @@ namespace ICSharpCode.Core
public static void InitializeServiceForUnitTests()
{
properties = null;
InitializeService(null, null, null);
configDirectory = null;
dataDirectory = null;
propertyFileName = null;
properties = new Properties();
}
public static void InitializeService(string configDirectory, string dataDirectory, string propertiesName)
{
if (properties != null)
throw new InvalidOperationException("Service is already initialized.");
properties = new Properties();
PropertyService.configDirectory = configDirectory;
PropertyService.dataDirectory = dataDirectory;
propertyXmlRootNodeName = propertiesName;
propertyFileName = propertiesName + ".xml";
properties.PropertyChanged += new PropertyChangedEventHandler(PropertiesPropertyChanged);
LoadPropertiesFromStream(Path.Combine(configDirectory, propertyFileName));
}
public static string ConfigDirectory {
@ -53,79 +56,135 @@ namespace ICSharpCode.Core @@ -53,79 +56,135 @@ namespace ICSharpCode.Core
}
}
public static string Get(string property)
/// <inheritdoc cref="Properties.Get{T}(string, T)"/>
public static T Get<T>(string key, T defaultValue)
{
return properties[property];
return properties.Get(key, defaultValue);
}
public static T Get<T>(string property, T defaultValue)
[Obsolete("Use the NestedProperties method instead", true)]
public static Properties Get(string key, Properties defaultValue)
{
return properties.Get(property, defaultValue);
return properties.Get(key, defaultValue);
}
public static void Set<T>(string property, T value)
/// <inheritdoc cref="Properties.NestedProperties"/>
public static Properties NestedProperties(string key)
{
properties.Set(property, value);
return properties.NestedProperties(key);
}
public static void Load()
/// <inheritdoc cref="Properties.SetNestedProperties"/>
public static void SetNestedProperties(string key, Properties nestedProperties)
{
if (properties == null)
throw new InvalidOperationException("Service is not initialized.");
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyXmlRootNodeName))
throw new InvalidOperationException("No file name was specified on service creation");
if (!Directory.Exists(configDirectory)) {
Directory.CreateDirectory(configDirectory);
}
if (!LoadPropertiesFromStream(Path.Combine(configDirectory, propertyFileName))) {
LoadPropertiesFromStream(Path.Combine(DataDirectory, "options", propertyFileName));
}
properties.SetNestedProperties(key, nestedProperties);
}
/// <inheritdoc cref="Properties.Contains"/>
public static bool Contains(string key)
{
return properties.Contains(key);
}
public static bool LoadPropertiesFromStream(string fileName)
/// <summary>
/// Gets the main property container.
/// </summary>
internal static Properties PropertiesContainer {
get { return properties; }
}
/// <inheritdoc cref="Properties.Set{T}(string, T)"/>
public static void Set<T>(string key, T value)
{
properties.Set(key, value);
}
[Obsolete("Use the SetNestedProperties method instead", true)]
public static void Set(string key, Properties value)
{
properties.Set(key, value);
}
/// <inheritdoc cref="Properties.GetList"/>
public static IReadOnlyList<T> GetList<T>(string key)
{
return properties.GetList<T>(key);
}
/// <inheritdoc cref="Properties.SetList"/>
public static void SetList<T>(string key, IEnumerable<T> value)
{
properties.SetList(key, value);
}
[Obsolete("Use the GetList method instead", true)]
public static T[] Get<T>(string key, T[] defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public static void Set<T>(string key, T[] value)
{
throw new InvalidOperationException();
}
[Obsolete("Use the GetList method instead", true)]
public static List<T> Get<T>(string key, List<T> defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public static void Set<T>(string key, List<T> value)
{
throw new InvalidOperationException();
}
[Obsolete("Use the GetList method instead", true)]
public static ArrayList Get<T>(string key, ArrayList defaultValue)
{
throw new InvalidOperationException();
}
[Obsolete("Use the SetList method instead", true)]
public static void Set<T>(string key, ArrayList value)
{
throw new InvalidOperationException();
}
/// <inheritdoc cref="Properties.Remove"/>
public static void Remove(string key)
{
properties.Remove(key);
}
static bool LoadPropertiesFromStream(string fileName)
{
if (!File.Exists(fileName)) {
properties = new Properties();
return false;
}
try {
using (LockPropertyFile()) {
using (XmlTextReader reader = new XmlTextReader(fileName)) {
while (reader.Read()){
if (reader.IsStartElement()) {
if (reader.LocalName == propertyXmlRootNodeName) {
properties.ReadProperties(reader, propertyXmlRootNodeName);
return true;
}
}
}
}
properties = Properties.Load(fileName);
return true;
}
} catch (XmlException ex) {
MessageService.ShowError("Error loading properties: " + ex.Message + "\nSettings have been restored to default values.");
}
properties = new Properties();
return false;
}
public static void Save()
{
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyXmlRootNodeName))
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyFileName))
throw new InvalidOperationException("No file name was specified on service creation");
using (MemoryStream ms = new MemoryStream()) {
XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.WriteStartElement(propertyXmlRootNodeName);
properties.WriteProperties(writer);
writer.WriteEndElement();
writer.Flush();
ms.Position = 0;
string fileName = Path.Combine(configDirectory, propertyFileName);
using (LockPropertyFile()) {
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) {
ms.WriteTo(fs);
}
}
string fileName = Path.Combine(configDirectory, propertyFileName);
using (LockPropertyFile()) {
properties.Save(fileName);
}
}
@ -143,13 +202,9 @@ namespace ICSharpCode.Core @@ -143,13 +202,9 @@ namespace ICSharpCode.Core
});
}
static void PropertiesPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (PropertyChanged != null) {
PropertyChanged(null, e);
}
public static event PropertyChangedEventHandler PropertyChanged {
add { properties.PropertyChanged += value; }
remove { properties.PropertyChanged -= value; }
}
public static event PropertyChangedEventHandler PropertyChanged;
}
}

5
src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Resources;
@ -164,8 +165,8 @@ namespace ICSharpCode.Core @@ -164,8 +165,8 @@ namespace ICSharpCode.Core
static void OnPropertyChange(object sender, PropertyChangedEventArgs e)
{
if (e.Key == uiLanguageProperty && e.NewValue != e.OldValue) {
LoadLanguageResources((string)e.NewValue);
if (e.PropertyName == uiLanguageProperty) {
LoadLanguageResources(Language);
EventHandler handler = LanguageChanged;
if (handler != null)
handler(null, e);

13
src/Main/Core/Project/Src/Services/StringParser/StringParser.cs

@ -241,19 +241,14 @@ namespace ICSharpCode.Core @@ -241,19 +241,14 @@ namespace ICSharpCode.Core
defaultValue = propertyName.Substring(pos + 2);
propertyName = propertyName.Substring(0, pos);
}
Properties properties = PropertyService.PropertiesContainer;
pos = propertyName.IndexOf('/');
if (pos >= 0) {
Properties properties = PropertyService.Get(propertyName.Substring(0, pos), new Properties());
while (pos >= 0) {
properties = properties.NestedProperties(propertyName.Substring(0, pos));
propertyName = propertyName.Substring(pos + 1);
pos = propertyName.IndexOf('/');
while (pos >= 0) {
properties = properties.Get(propertyName.Substring(0, pos), new Properties());
propertyName = propertyName.Substring(pos + 1);
}
return properties.Get(propertyName, defaultValue);
} else {
return PropertyService.Get(propertyName, defaultValue);
}
return properties.Get(propertyName, defaultValue);
}
}

3
src/Main/Core/Test/ICSharpCode.Core.Tests.csproj

@ -28,7 +28,8 @@ @@ -28,7 +28,8 @@
<DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<DebugSymbols>true</DebugSymbols>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>DEBUG</DefineConstants>

3
src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj

@ -21,7 +21,8 @@ @@ -21,7 +21,8 @@
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<RunCodeAnalysis>False</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Performance#CA1810</CodeAnalysisRules>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>

3
src/Main/ICSharpCode.Core.WinForms/ICSharpCode.Core.WinForms.csproj

@ -18,7 +18,8 @@ @@ -18,7 +18,8 @@
<AssemblyOriginatorKeyFile>..\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>

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

@ -17,7 +17,8 @@ @@ -17,7 +17,8 @@
<DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<Optimize>False</Optimize>

Loading…
Cancel
Save