diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin index 8f20aeb189..f08bc138af 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin @@ -118,10 +118,13 @@ class = "CSharpBinding.CSharpProjectBinding" /> - + + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index 03f2fbe10a..e92fc5c4c7 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -66,8 +66,13 @@ + + IssueOptions.xaml + Code + + @@ -129,15 +134,28 @@ ICSharpCode.Core False + + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} + ICSharpCode.Core.Presentation + False + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} ICSharpCode.Core.WinForms False + + {8035765F-D51F-4A0C-A746-2FD100E19419} + ICSharpCode.SharpDevelop.Widgets + False + + + + \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeActionProviderDoozer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeActionProviderDoozer.cs index 92ac010efe..7444db1d73 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeActionProviderDoozer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeActionProviderDoozer.cs @@ -76,8 +76,7 @@ namespace CSharpBinding.Refactoring } public string Category { - get { return string.IsNullOrEmpty(attribute.Category) ? attribute.Title[0].ToString() : attribute.Category; } - // get { return attribute.Category ?? string.Empty; } + get { return attribute.Category ?? string.Empty; } } public bool AllowHiding { diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs index 4b0154ebf5..130ab1d8a7 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueManager.cs @@ -7,10 +7,12 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Windows; using System.Windows.Media; using CSharpBinding.Parser; using ICSharpCode.Core; using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.Editor; using ICSharpCode.SharpDevelop.Editor; @@ -25,8 +27,65 @@ namespace CSharpBinding.Refactoring /// public class IssueManager : IDisposable, IContextActionProvider { - static readonly Lazy> issueProviders = new Lazy>( - () => AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/IssueProviders", null, false)); + static readonly Lazy> issueProviders = new Lazy>( + () => AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/IssueProviders", null, false) + .Select(p => new IssueProvider(p)).ToList()); + + internal static IReadOnlyList IssueProviders { + get { return issueProviders.Value; } + } + + internal class IssueProvider + { + readonly ICodeIssueProvider provider; + public readonly Type ProviderType; + public readonly IssueDescriptionAttribute Attribute; + + public IssueProvider(ICodeIssueProvider provider) + { + if (provider == null) + throw new ArgumentNullException("provider"); + this.provider = provider; + this.ProviderType = provider.GetType(); + var attributes = ProviderType.GetCustomAttributes(typeof(IssueDescriptionAttribute), true); + if (attributes.Length == 1) + this.Attribute = (IssueDescriptionAttribute)attributes[0]; + } + + public Severity DefaultSeverity { + get { return Attribute != null ? Attribute.Severity : Severity.Hint; } + } + + public IssueMarker DefaultMarker { + get { return Attribute != null ? Attribute.IssueMarker : IssueMarker.Underline; } + } + + public IEnumerable GetIssues(BaseRefactoringContext context) + { + return provider.GetIssues(context); + } + } + + public static IReadOnlyDictionary GetIssueSeveritySettings() + { + // TODO: cache the result + var dict = new Dictionary(); + var prop = PropertyService.Get("CSharpIssueSeveritySettings", new Properties()); + foreach (var provider in issueProviders.Value) { + dict[provider.ProviderType] = prop.Get(provider.ProviderType.FullName, provider.DefaultSeverity); + } + return dict; + } + + public static void SetIssueSeveritySettings(IReadOnlyDictionary dict) + { + var prop = new Properties(); + foreach (var pair in dict) { + prop.Set(pair.Key.FullName, pair.Value); + } + PropertyService.Set("CSharpIssueSeveritySettings", prop); + } + readonly ITextEditor editor; readonly ITextMarkerService markerService; @@ -50,14 +109,15 @@ namespace CSharpBinding.Refactoring sealed class InspectionTag { readonly IssueManager manager; - public readonly ICodeIssueProvider Provider; + public readonly IssueProvider Provider; public readonly ITextSourceVersion InspectedVersion; public readonly string Description; public readonly int StartOffset; public readonly int EndOffset; public readonly IReadOnlyList Actions; + public readonly Severity Severity; - public InspectionTag(IssueManager manager, ICodeIssueProvider provider, ITextSourceVersion inspectedVersion, string description, int startOffset, int endOffset, IEnumerable actions) + public InspectionTag(IssueManager manager, IssueProvider provider, ITextSourceVersion inspectedVersion, string description, int startOffset, int endOffset, Severity severity, IEnumerable actions) { this.manager = manager; this.Provider = provider; @@ -65,6 +125,7 @@ namespace CSharpBinding.Refactoring this.Description = description; this.StartOffset = startOffset; this.EndOffset = endOffset; + this.Severity = severity; this.Actions = actions.Select(Wrap).ToList(); } @@ -105,11 +166,34 @@ namespace CSharpBinding.Refactoring return; marker = markerService.Create(startOffset, endOffset - startOffset); marker.ToolTip = this.Description; - marker.MarkerType = TextMarkerType.SquigglyUnderline; - marker.MarkerColor = Colors.Blue; + switch (Provider.DefaultMarker) { + case IssueMarker.Underline: + Color underlineColor = GetColor(this.Severity); + underlineColor.A = 186; + marker.MarkerType = TextMarkerType.SquigglyUnderline; + marker.MarkerColor = underlineColor; + break; + case IssueMarker.GrayOut: + marker.ForegroundColor = SystemColors.GrayTextColor; + break; + } marker.Tag = this; } + static Color GetColor(Severity severity) + { + switch (severity) { + case Severity.Error: + return Colors.Red; + case Severity.Warning: + return Colors.Orange; + case Severity.Suggestion: + return Colors.Green; + default: + return Colors.Blue; + } + } + public void RemoveMarker() { if (marker != null) { @@ -163,7 +247,14 @@ namespace CSharpBinding.Refactoring var compilation = ParserService.GetCompilationForFile(parseInfo.FileName); var resolver = parseInfo.GetResolver(compilation); var context = new SDRefactoringContext(textSource, resolver, new TextLocation(0, 0), 0, 0, cancellationToken); + var settings = GetIssueSeveritySettings(); foreach (var issueProvider in issueProviders.Value) { + Severity severity; + if (!settings.TryGetValue(issueProvider.ProviderType, out severity)) + severity = Severity.Hint; + if (severity == Severity.None) + continue; + foreach (var issue in issueProvider.GetIssues(context)) { results.Add(new InspectionTag( this, @@ -172,6 +263,7 @@ namespace CSharpBinding.Refactoring issue.Desription, context.GetOffset(issue.Start), context.GetOffset(issue.End), + severity, issue.Action != null ? new [] { issue.Action } : new CodeAction[0])); } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml new file mode 100644 index 0000000000..e50d67fb15 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml.cs new file mode 100644 index 0000000000..ff30e38725 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptions.xaml.cs @@ -0,0 +1,64 @@ +// 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.Collections.ObjectModel; +using System.ComponentModel; +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; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace CSharpBinding.Refactoring +{ + /// + /// Interaction logic for IssueOptions.xaml + /// + public partial class IssueOptions : OptionPanel + { + ObservableCollection viewModels; + + public IssueOptions() + { + InitializeComponent(); + viewModels = new ObservableCollection( + from p in IssueManager.IssueProviders + where p.Attribute != null + select new IssueOptionsViewModel(p.ProviderType, p.Attribute) + ); + ICollectionView view = CollectionViewSource.GetDefaultView(viewModels); + if (viewModels.Any(p => !string.IsNullOrEmpty(p.Category))) + view.GroupDescriptions.Add(new PropertyGroupDescription("Category")); + listBox.ItemsSource = view; + } + + public override void LoadOptions() + { + base.LoadOptions(); + var settings = IssueManager.GetIssueSeveritySettings(); + foreach (var m in viewModels) { + Severity severity; + if (settings.TryGetValue(m.ProviderType, out severity)) + m.Severity = severity; + } + } + + public override bool SaveOptions() + { + Dictionary dict = new Dictionary(); + foreach (var m in viewModels) { + dict[m.ProviderType] = m.Severity; + } + IssueManager.SetIssueSeveritySettings(dict); + return base.SaveOptions(); + } + } +} \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptionsViewModel.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptionsViewModel.cs new file mode 100644 index 0000000000..2ad0fd48cb --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/IssueOptionsViewModel.cs @@ -0,0 +1,47 @@ +// 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.ComponentModel; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.SharpDevelop.Widgets; + +namespace CSharpBinding.Refactoring +{ + public class IssueOptionsViewModel : ViewModelBase + { + readonly Type providerType; + readonly IssueDescriptionAttribute attribute; + + public IssueOptionsViewModel(Type providerType, IssueDescriptionAttribute attribute) + { + this.providerType = providerType; + this.attribute = attribute; + this.Severity = attribute.Severity; + } + + public Type ProviderType { + get { return providerType; } + } + + // TODO: Translate + public string DisplayName { + get { return attribute.Title; } + } + + public string ToolTip { + get { return attribute.Description; } + } + + public string Category { + get { return attribute.Category; } + } + + Severity severity; + + public Severity Severity { + get { return severity; } + set { SetAndNotifyPropertyChanged(ref severity, value); } + } + } +} diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml index db24cbdec8..4c211c24aa 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml @@ -6,18 +6,28 @@ - + + + + + + + + + diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml.cs index af838b5706..f98216c57c 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionOptions.xaml.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Windows; @@ -27,7 +28,10 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions { InitializeComponent(); this.providers = providers.ToArray(); - listBox.ItemsSource = this.providers; + ICollectionView view = CollectionViewSource.GetDefaultView(this.providers); + if (this.providers.Any(p => !string.IsNullOrEmpty(p.Category))) + view.GroupDescriptions.Add(new PropertyGroupDescription("Category")); + listBox.ItemsSource = view; } public override void LoadOptions() diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs index 560f9e1720..a36649d03f 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs @@ -256,7 +256,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return title; } set { title = value; - base.RaisePropertyChanged(() => Title); + OnPropertyChanged(); } } @@ -268,7 +268,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return discoverButtonContent; } set { discoverButtonContent = value; - base.RaisePropertyChanged(() => DiscoverButtonContent); + OnPropertyChanged(); + OnPropertyChanged(); } } @@ -276,7 +277,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return mruServices; } set { mruServices = value; - base.RaisePropertyChanged(() => MruServices); + OnPropertyChanged(); } } @@ -284,7 +285,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return selectedService; } set { selectedService = value; - base.RaisePropertyChanged(() => SelectedService); + OnPropertyChanged(); } } @@ -292,7 +293,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return items; } set { items = value; - base.RaisePropertyChanged(() => ServiceItems); + OnPropertyChanged(); } } @@ -301,7 +302,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference set { myItem = value; UpdateListView(); - base.RaisePropertyChanged(() => ServiceItem); + OnPropertyChanged(); } } @@ -309,7 +310,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return serviceDescriptionMessage; } set { serviceDescriptionMessage = value; - base.RaisePropertyChanged(() => ServiceDescriptionMessage); + OnPropertyChanged(); } } @@ -317,7 +318,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return defaultNameSpace; } set { defaultNameSpace = value; - base.RaisePropertyChanged(() => DefaultNameSpace); + OnPropertyChanged(); } } @@ -325,7 +326,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return twoValues; } set { twoValues = value; - base.RaisePropertyChanged(() => TwoValues); + OnPropertyChanged(); } } diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AdvancedServiceViewModel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AdvancedServiceViewModel.cs index 7230ec09da..c275f78159 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AdvancedServiceViewModel.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AdvancedServiceViewModel.cs @@ -85,7 +85,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return selectedModifier; } set { selectedModifier = value; - base.RaisePropertyChanged(() => SelectedModifier); + OnPropertyChanged(); } } @@ -95,7 +95,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return generateAsyncOperations; } set { generateAsyncOperations = value; - base.RaisePropertyChanged(() => GenerateAsyncOperations); + OnPropertyChanged(); } } @@ -105,7 +105,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return generateMessageContract; } set { generateMessageContract = value; - base.RaisePropertyChanged(() => GenerateMessageContract); + OnPropertyChanged(); } } @@ -115,7 +115,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return collectionType; } set { collectionType = value; - base.RaisePropertyChanged(() => CollectionType); + OnPropertyChanged(); } } @@ -125,7 +125,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return dictionaryCollectionType; } set { dictionaryCollectionType = value; - base.RaisePropertyChanged(() => DictionaryCollectionType); + OnPropertyChanged(); } } @@ -136,7 +136,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference set { useReferencedAssemblies = value; ReuseTypes = useReferencedAssemblies; - base.RaisePropertyChanged(() => UseReferencedAssemblies); + OnPropertyChanged(); } } @@ -146,7 +146,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return reuseTypes; } set { reuseTypes = value; - base.RaisePropertyChanged(() => ReuseTypes); + OnPropertyChanged(); } } @@ -157,7 +157,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference set { reuseReferencedTypes = value; ListViewEnable = value; - base.RaisePropertyChanged(() => ReuseReferencedTypes); + OnPropertyChanged(); } } @@ -167,7 +167,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference get { return listViewEnable; } set { listViewEnable = value; - base.RaisePropertyChanged(() => ListViewEnable); + OnPropertyChanged(); } } diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/TabbedOptions.cs b/src/Main/Base/Project/Src/Gui/Dialogs/TabbedOptions.cs index acf91942f2..86dc2da173 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/TabbedOptions.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/TabbedOptions.cs @@ -28,9 +28,7 @@ namespace ICSharpCode.SharpDevelop.Gui if (descriptor.HasOptionPanel) { this.Items.Add(new OptionTabPage(this, descriptor)); } - if (descriptor.ChildOptionPanelDescriptors != null) { - AddOptionPanels(descriptor.ChildOptionPanelDescriptors); - } + AddOptionPanels(descriptor.ChildOptionPanelDescriptors); } } OnIsDirtyChanged(null, null); diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/TreeViewOptionsDialog.xaml.cs b/src/Main/Base/Project/Src/Gui/Dialogs/TreeViewOptionsDialog.xaml.cs index e85f02c99f..48e3a5089e 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/TreeViewOptionsDialog.xaml.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/TreeViewOptionsDialog.xaml.cs @@ -136,7 +136,7 @@ namespace ICSharpCode.SharpDevelop.Gui get { if (IsActive) return PresentationResourceService.GetBitmapSource("Icons.16x16.SelectionArrow"); - if (OptionPanelDescriptor.ChildOptionPanelDescriptors != null) { + if (OptionPanelDescriptor.ChildOptionPanelDescriptors.Any()) { if (IsExpanded) return PresentationResourceService.GetBitmapSource("Icons.16x16.OpenFolderBitmap"); else @@ -152,12 +152,8 @@ namespace ICSharpCode.SharpDevelop.Gui public List Children { get { if (children == null) { - if (OptionPanelDescriptor.ChildOptionPanelDescriptors != null) { - children = OptionPanelDescriptor.ChildOptionPanelDescriptors - .Select(op => new OptionPanelNode(op, this)).ToList(); - } else { - children = new List(); - } + children = OptionPanelDescriptor.ChildOptionPanelDescriptors + .Select(op => new OptionPanelNode(op, this)).ToList(); } return children; } diff --git a/src/Main/Base/Project/Src/Internal/Doozers/DefaultOptionPanelDescriptor.cs b/src/Main/Base/Project/Src/Internal/Doozers/DefaultOptionPanelDescriptor.cs index 9cb5c1b28d..92cb200eef 100644 --- a/src/Main/Base/Project/Src/Internal/Doozers/DefaultOptionPanelDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Doozers/DefaultOptionPanelDescriptor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop @@ -23,7 +24,7 @@ namespace ICSharpCode.SharpDevelop public IEnumerable ChildOptionPanelDescriptors { get { - return optionPanelDescriptors; + return optionPanelDescriptors ?? Enumerable.Empty(); } } diff --git a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs index 497bcd0051..ffb2ac1a8c 100644 --- a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs +++ b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; @@ -72,10 +73,7 @@ namespace ICSharpCode.Core { get { lock (properties) { - List ret = new List(); - foreach (KeyValuePair property in properties) - ret.Add(property.Key); - return ret.ToArray(); + return properties.Keys.ToArray(); } } } diff --git a/src/Main/ICSharpCode.Core.Presentation/RestrictDesiredSize.cs b/src/Main/ICSharpCode.Core.Presentation/RestrictDesiredSize.cs index 4950e20f42..2de996fadb 100644 --- a/src/Main/ICSharpCode.Core.Presentation/RestrictDesiredSize.cs +++ b/src/Main/ICSharpCode.Core.Presentation/RestrictDesiredSize.cs @@ -14,19 +14,48 @@ namespace ICSharpCode.Core.Presentation /// public class RestrictDesiredSize : Decorator { - Size lastArrangeSize = new Size(double.NaN, double.NaN); + public static readonly DependencyProperty RestrictWidthProperty = + DependencyProperty.Register("RestrictWidth", typeof(bool), typeof(RestrictDesiredSize), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange)); + public bool RestrictWidth { + get { return (bool)GetValue(RestrictWidthProperty); } + set { SetValue(RestrictWidthProperty, value); } + } + + public static readonly DependencyProperty RestrictHeightProperty = + DependencyProperty.Register("RestrictHeight", typeof(bool), typeof(RestrictDesiredSize), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange)); + + public bool RestrictHeight { + get { return (bool)GetValue(RestrictHeightProperty); } + set { SetValue(RestrictHeightProperty, value); } + } + + Size lastArrangeSize = new Size(double.PositiveInfinity, double.PositiveInfinity); + Size lastMeasureSize = new Size(double.NaN, double.NaN); + protected override Size MeasureOverride(Size constraint) { - return new Size(0, 0); + if (RestrictWidth && RestrictHeight) + return new Size(0, 0); + + if (RestrictWidth && constraint.Width > lastArrangeSize.Width) + constraint.Width = lastArrangeSize.Width; + if (RestrictHeight && constraint.Height > lastArrangeSize.Height) + constraint.Height = lastArrangeSize.Height; + lastMeasureSize = constraint; + Size baseSize = base.MeasureOverride(constraint); + return new Size(RestrictWidth ? 0 : baseSize.Width, RestrictHeight ? 0 : baseSize.Height); } protected override Size ArrangeOverride(Size arrangeSize) { - if (lastArrangeSize != arrangeSize) { - lastArrangeSize = arrangeSize; + if (lastMeasureSize != arrangeSize) { + lastMeasureSize = arrangeSize; base.MeasureOverride(arrangeSize); } + lastArrangeSize = arrangeSize; return base.ArrangeOverride(arrangeSize); } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ViewModelBase.cs b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ViewModelBase.cs index 032c8a2cbf..4ab992352c 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ViewModelBase.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Widgets/Project/ViewModelBase.cs @@ -2,73 +2,35 @@ // 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.Linq.Expressions; using System.Reflection; +using System.Runtime.CompilerServices; namespace ICSharpCode.SharpDevelop.Widgets { /// - /// Description of ViewModelBase. + /// Base class for view models; implements INotifyPropertyChanged. /// - public class ViewModelBase:INotifyPropertyChanged + public class ViewModelBase : INotifyPropertyChanged { - public ViewModelBase() - { - } - - public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; - protected virtual void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs e) + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { var handler = this.PropertyChanged; - if (handler != null) - { - handler(this, e); + if (handler != null) { + handler(this, new PropertyChangedEventArgs(propertyName)); } } - - protected void RaisePropertyChanged(Expression> propertyExpresssion) - { - var propertyName = ExtractPropertyName(propertyExpresssion); - this.RaisePropertyChanged(propertyName); - } - - - protected void RaisePropertyChanged(String propertyName) - { - OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); - } - - - private static String ExtractPropertyName(Expression> propertyExpresssion) + protected void SetAndNotifyPropertyChanged(ref T field, T newValue, [CallerMemberName] string propertyName = null) { - if (propertyExpresssion == null) - { - throw new ArgumentNullException("propertyExpresssion"); - } - - var memberExpression = propertyExpresssion.Body as MemberExpression; - if (memberExpression == null) - { - throw new ArgumentException("The expression is not a member access expression.", "propertyExpresssion"); + if (!EqualityComparer.Default.Equals(field, newValue)) { + field = newValue; + OnPropertyChanged(propertyName); } - - var property = memberExpression.Member as PropertyInfo; - if (property == null) - { - throw new ArgumentException("The member access expression does not access a property.", "propertyExpresssion"); - } - - var getMethod = property.GetGetMethod(true); - if (getMethod.IsStatic) - { - throw new ArgumentException("The referenced property is a static property.", "propertyExpresssion"); - } - - return memberExpression.Member.Name; } } }