/src/Base/PropertySystem/PropertyCollection.cs
C# | 280 lines | 225 code | 47 blank | 8 comment | 11 complexity | 9945cf130860284b3e6da8952a98eac1 MD5 | raw file
Possible License(s): Unlicense
- /////////////////////////////////////////////////////////////////////////////////
- // Paint.NET //
- // Copyright (C) Rick Brewster, Tom Jackson, and past contributors. //
- // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
- // See src/Resources/Files/License.txt for full licensing and attribution //
- // details. //
- // . //
- /////////////////////////////////////////////////////////////////////////////////
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Runtime.Serialization;
- using System.Text;
-
- namespace PaintDotNet.PropertySystem
- {
- public sealed class PropertyCollection
- : INotifyPropertyChanged,
- IEnumerable<Property>,
- ICloneable<PropertyCollection>
- {
- private bool eventAddAllowed = true;
- private Dictionary<string, Property> properties = new Dictionary<string, Property>();
- private List<PropertyCollectionRule> rules = new List<PropertyCollectionRule>();
-
- public static PropertyCollection CreateEmpty()
- {
- return new PropertyCollection(new Property[0]);
- }
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- private void OnPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- public Property this[object propertyName]
- {
- get
- {
- string propertyNameString = propertyName.ToString();
- Property theProperty;
- this.properties.TryGetValue(propertyNameString, out theProperty);
- return theProperty;
- }
- }
-
- public int Count
- {
- get
- {
- return this.properties.Count;
- }
- }
-
- public IEnumerable<Property> Properties
- {
- get
- {
- return this.properties.Values;
- }
- }
-
- public IEnumerable<PropertyCollectionRule> Rules
- {
- get
- {
- return this.rules;
- }
- }
-
- public IEnumerable<string> PropertyNames
- {
- get
- {
- return this.properties.Keys;
- }
- }
-
- public PropertyCollection(IEnumerable<Property> properties)
- {
- Initialize(properties, new PropertyCollectionRule[0]);
- }
-
- public PropertyCollection(
- IEnumerable<Property> properties,
- IEnumerable<PropertyCollectionRule> rules)
- {
- Initialize(properties, rules);
- }
-
- public IDisposable __Internal_BeginEventAddMoratorium()
- {
- if (!this.eventAddAllowed)
- {
- throw new InvalidOperationException("An event add moratorium is already in effect");
- }
-
- List<IDisposable> propUndoFns = new List<IDisposable>(this.properties.Count);
-
- foreach (Property property in this.properties.Values)
- {
- IDisposable propUndoFn = property.BeginEventAddMoratorium();
- propUndoFns.Add(propUndoFn);
- }
-
- IDisposable undoFn = new CallbackOnDispose(() =>
- {
- this.eventAddAllowed = true;
-
- foreach (IDisposable propUndoFn in propUndoFns)
- {
- propUndoFn.Dispose();
- }
- });
-
- this.eventAddAllowed = false;
-
- return undoFn;
- }
-
- private void Initialize(
- IEnumerable<Property> properties,
- IEnumerable<PropertyCollectionRule> rules)
- {
- foreach (Property property in properties)
- {
- Property propertyClone = property.Clone();
- this.properties.Add(propertyClone.Name, propertyClone);
- }
-
- foreach (PropertyCollectionRule rule in rules)
- {
- PropertyCollectionRule ruleClone = rule.Clone();
- this.rules.Add(ruleClone);
- }
-
- foreach (PropertyCollectionRule rule in this.rules)
- {
- rule.Initialize(this);
- }
-
- HookUpEvents();
- }
-
- private void Property_ValueChanged(object sender, EventArgs e)
- {
- OnPropertyChanged((sender as Property).Name);
- }
-
- private void Property_ReadOnlyChanged(object sender, EventArgs e)
- {
- OnPropertyChanged((sender as Property).Name);
- }
-
- private void HookUpEvents()
- {
- foreach (Property property in this.properties.Values)
- {
- property.ValueChanged -= Property_ValueChanged;
- property.ValueChanged += Property_ValueChanged;
-
- property.ReadOnlyChanged -= Property_ReadOnlyChanged;
- property.ReadOnlyChanged += Property_ReadOnlyChanged;
- }
- }
-
- public void CopyCompatibleValuesFrom(PropertyCollection srcProps)
- {
- CopyCompatibleValuesFrom(srcProps, false);
- }
-
- public void CopyCompatibleValuesFrom(PropertyCollection srcProps, bool ignoreReadOnlyFlags)
- {
- foreach (Property srcProp in srcProps)
- {
- Property dstProp = this[srcProp.Name];
-
- if (dstProp != null && dstProp.ValueType == srcProp.ValueType)
- {
- if (dstProp.ReadOnly && ignoreReadOnlyFlags)
- {
- dstProp.ReadOnly = false;
- dstProp.Value = srcProp.Value;
- dstProp.ReadOnly = true;
- }
- else
- {
- dstProp.Value = srcProp.Value;
- }
- }
- }
- }
-
- public static PropertyCollection CreateMerged(PropertyCollection pc1, PropertyCollection pc2)
- {
- foreach (Property p1 in pc1.Properties)
- {
- Property p2 = pc2[p1.Name];
-
- if (p2 != null)
- {
- throw new ArgumentException("pc1 must not have any properties with the same name as in pc2");
- }
- }
-
- Property[] allProps = new Property[pc1.Count + pc2.Count];
- int index = 0;
-
- foreach (Property p1 in pc1)
- {
- allProps[index] = p1.Clone();
- ++index;
- }
-
- foreach (Property p2 in pc2)
- {
- allProps[index] = p2.Clone();
- ++index;
- }
-
- List<PropertyCollectionRule> allRules = new List<PropertyCollectionRule>();
-
- foreach (PropertyCollectionRule pcr1 in pc1.Rules)
- {
- allRules.Add(pcr1);
- }
-
- foreach (PropertyCollectionRule pcr2 in pc2.Rules)
- {
- allRules.Add(pcr2);
- }
-
- PropertyCollection mergedPC = new PropertyCollection(allProps, allRules);
- return mergedPC;
- }
-
- public PropertyCollection Clone()
- {
- List<Property> clonedProperties = new List<Property>();
-
- foreach (Property property in this.Properties)
- {
- Property clonedProperty = property.Clone();
- clonedProperties.Add(clonedProperty);
- }
-
- List<PropertyCollectionRule> clonedRules = new List<PropertyCollectionRule>();
-
- foreach (PropertyCollectionRule rule in this.rules)
- {
- PropertyCollectionRule clonedRule = rule.Clone();
- clonedRules.Add(clonedRule);
- }
-
- return new PropertyCollection(clonedProperties, clonedRules);
- }
-
- object ICloneable.Clone()
- {
- return Clone();
- }
-
- public IEnumerator<Property> GetEnumerator()
- {
- return Properties.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- }