Index: Core/Common/src/Core.Common.Gui/Attributes/PropertyOrderAttribute.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/Attributes/PropertyOrderAttribute.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/Attributes/PropertyOrderAttribute.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,35 @@ +using System; + +namespace Core.Common.Gui.Attributes +{ + /// + /// Attribute that allows for controlling the order that properties appear in . + /// Ordering should occur on ascending order. Not having this attribute defined means + /// an order value of . + /// + [AttributeUsage(AttributeTargets.Property)] + public sealed class PropertyOrderAttribute : Attribute + { + private readonly int order; + + /// + /// Initializes a new instance of the class. + /// + /// The ordering value. + public PropertyOrderAttribute(int order) + { + this.order = order; + } + + /// + /// Gets the ordering value. + /// + public int Order + { + get + { + return order; + } + } + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/Core.Common.Gui.csproj =================================================================== diff -u -r00c8bc7fed580b4a9820a7d85b3b6d2346599f65 -rcd9655d356bdff388c7058eeff1cdbed076c407b --- Core/Common/src/Core.Common.Gui/Core.Common.Gui.csproj (.../Core.Common.Gui.csproj) (revision 00c8bc7fed580b4a9820a7d85b3b6d2346599f65) +++ Core/Common/src/Core.Common.Gui/Core.Common.Gui.csproj (.../Core.Common.Gui.csproj) (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -114,6 +114,7 @@ + Form @@ -124,6 +125,11 @@ + + + + + Index: Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyResolver.cs =================================================================== diff -u -re95dbee6ea6b002476a7827a03f6584b779ad594 -rcd9655d356bdff388c7058eeff1cdbed076c407b --- Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyResolver.cs (.../PropertyResolver.cs) (revision e95dbee6ea6b002476a7827a03f6584b779ad594) +++ Core/Common/src/Core.Common.Gui/Forms/PropertyGridView/PropertyResolver.cs (.../PropertyResolver.cs) (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Core.Common.Gui.Properties; -using Core.Common.Utils.PropertyBag; +using Core.Common.Gui.PropertyBag; namespace Core.Common.Gui.Forms.PropertyGridView { Index: Core/Common/src/Core.Common.Gui/IGui.cs =================================================================== diff -u -ra70fac40e34e16bed007b1d0d4e437d91c89d0cb -rcd9655d356bdff388c7058eeff1cdbed076c407b --- Core/Common/src/Core.Common.Gui/IGui.cs (.../IGui.cs) (revision a70fac40e34e16bed007b1d0d4e437d91c89d0cb) +++ Core/Common/src/Core.Common.Gui/IGui.cs (.../IGui.cs) (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -14,7 +14,7 @@ using Core.Common.Controls.Views; using Core.Common.Gui.Forms.MainWindow; using Core.Common.Gui.Forms.PropertyGridView; -using Core.Common.Utils.PropertyBag; +using Core.Common.Gui.PropertyBag; namespace Core.Common.Gui { Index: Core/Common/src/Core.Common.Gui/PropertyBag/DynamicPropertyBag.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/PropertyBag/DynamicPropertyBag.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/PropertyBag/DynamicPropertyBag.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,251 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +using Core.Common.Gui.Attributes; +using Core.Common.Utils.Attributes; + +namespace Core.Common.Gui.PropertyBag +{ + /// + /// Creates a custom type descriptor for an object using reflection as a property bag. Used for Property Grid. + /// Additionally it scans the object for any dynamic attributes and processes those, eg checks their condition + /// at runtime and if met, adds them as static attribute. + /// + public class DynamicPropertyBag : ICustomTypeDescriptor + { + public DynamicPropertyBag(object propertyObject) + { + Properties = new PropertySpecCollection(); + Initialize(propertyObject); + } + + /// + /// Gets the collection of properties contained within this PropertyBag. + /// + public PropertySpecCollection Properties { get; private set; } + + public object WrappedObject { get; private set; } + + public Type GetContentType() + { + return WrappedObject.GetType(); + } + + public override string ToString() + { + return WrappedObject.ToString(); + } + + /// + /// Raises the GetValue event. + /// + /// A PropertySpecEventArgs that contains the event data. + /// + internal void OnGetValue(PropertySpecEventArgs e, PropertySpec propertySpec) + { + var attributeList = new List(); + attributeList.AddRange(propertySpec.Attributes.ToList()); + + //check all of the attributes: if we find a dynamic one, evaluate it and possibly add/overwrite a static attribute + foreach (Attribute customAttribute in propertySpec.Attributes) + { + if (customAttribute is DynamicReadOnlyAttribute) + { + attributeList.RemoveAll(x => x is ReadOnlyAttribute); + + if (DynamicReadOnlyAttribute.IsReadOnly(WrappedObject, propertySpec.Name)) + { + //condition is true: the dynamic attribute should be applied (as static attribute) + attributeList.Add(new ReadOnlyAttribute(true)); //add static read only attribute + } + } + + if (customAttribute is DynamicVisibleAttribute) + { + attributeList.RemoveAll(x => x is BrowsableAttribute); + + if (!DynamicVisibleAttribute.IsVisible(WrappedObject, propertySpec.Name)) + { + attributeList.Add(new BrowsableAttribute(false)); + } + } + } + + propertySpec.Attributes = attributeList.ToArray(); + + var propertyInfo = WrappedObject.GetType().GetProperty(propertySpec.Name); + var value = propertyInfo.GetValue(WrappedObject, null); + + var isNestedPropertiesObject = IsNestedExpandablePropertiesObject(propertyInfo); + + // if nested properties object, wrap in DynamicPropertyBag to provide support for things like DynamicReadOnly + e.Value = isNestedPropertiesObject ? new DynamicPropertyBag(value) : value; + } + + /// + /// Raises the SetValue event. + /// + /// + /// + internal void OnSetValue(string propertyName, object propertyValue) + { + WrappedObject.GetType().GetProperty(propertyName).SetValue(WrappedObject, propertyValue, null); + } + + private void Initialize(object propertyObject) + { + WrappedObject = propertyObject; + + foreach (var propertyInfo in propertyObject.GetType().GetProperties().OrderBy(x => x.MetadataToken).ToArray()) + { + Properties.Add(new PropertySpec(propertyInfo)); + } + } + + /// + /// Determines if the property represents nested object properties, by checking for an ExpandableObjectConverter type converter. + /// + /// + /// + private bool IsNestedExpandablePropertiesObject(System.Reflection.PropertyInfo propertyInfo) + { + try + { + var typeConverterAttributes = propertyInfo.GetCustomAttributes(typeof(TypeConverterAttribute), false); + foreach (TypeConverterAttribute typeConverterAttribute in typeConverterAttributes) + { + var typeString = typeConverterAttribute.ConverterTypeName; + var type = Type.GetType(typeString); + if (type != null) + { + if (typeof(ExpandableObjectConverter) == type) + { + return true; + } + } + } + } + catch (Exception) + { + //gulp + } + return false; + } + + #region ICustomTypeDescriptor explicit interface definitions + + #region Implementations delegated to System.ComponentModel.TypeDescriptor + + public AttributeCollection GetAttributes() + { + return TypeDescriptor.GetAttributes(this, true); + } + + public string GetClassName() + { + return TypeDescriptor.GetClassName(this, true); + } + + public string GetComponentName() + { + return TypeDescriptor.GetComponentName(this, true); + } + + public System.ComponentModel.TypeConverter GetConverter() + { + return TypeDescriptor.GetConverter(this, true); + } + + public EventDescriptor GetDefaultEvent() + { + return TypeDescriptor.GetDefaultEvent(this, true); + } + + public object GetEditor(Type editorBaseType) + { + return TypeDescriptor.GetEditor(this, editorBaseType, true); + } + + public EventDescriptorCollection GetEvents() + { + return TypeDescriptor.GetEvents(this, true); + } + + public EventDescriptorCollection GetEvents(Attribute[] attributes) + { + return TypeDescriptor.GetEvents(this, attributes, true); + } + + public PropertyDescriptorCollection GetProperties() + { + return GetProperties(new Attribute[0]); + } + + #endregion + + public PropertyDescriptor GetDefaultProperty() + { + return Properties.Count > 0 ? new PropertySpecDescriptor(Properties[0], this, Properties[0].Name, null) : null; + } + + public PropertyDescriptorCollection GetProperties(Attribute[] attributes) + { + // Rather than passing this function on to the default TypeDescriptor, + // which would return the actual properties of PropertyBag, I construct + // a list here that contains property descriptors for the elements of the + // Properties list in the bag. + var props = new List(); + var propsToOrder = new List>(); + + foreach (PropertySpec property in Properties) + { + var attrs = new ArrayList(); + + // Additionally, append the custom attributes associated with the + // PropertySpec, if any. + if (property.Attributes != null) + { + attrs.AddRange(property.Attributes); + } + + Attribute[] attrArray = (Attribute[])attrs.ToArray(typeof(Attribute)); + + // Create a new property descriptor for the property item, and add + // it to the list. + var pd = new PropertySpecDescriptor(property, this, property.Name, attrArray); + + var propertyOrderAttribute = property.Attributes != null ? property.Attributes.OfType().FirstOrDefault() : null; + if (propertyOrderAttribute != null) + { + propsToOrder.Add(new Tuple(propertyOrderAttribute.Order, pd)); + } + else + { + props.Add(pd); + } + } + + var orderedProperties = propsToOrder.OrderBy(p => p.Item1).Select(p => p.Item2).ToList(); + + // Convert the list of PropertyDescriptors to a collection that the + // ICustomTypeDescriptor can use, and return it. + var browsableAttribute = attributes.OfType().FirstOrDefault(); + + var propertySpecDescriptors = (browsableAttribute != null) + ? orderedProperties.Concat(props).Where(p => p.IsBrowsable == browsableAttribute.Browsable) + : orderedProperties.Concat(props); + + return new PropertyDescriptorCollection(propertySpecDescriptors.ToArray()); + } + + public object GetPropertyOwner(PropertyDescriptor pd) + { + return this; + } + + #endregion + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpec.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpec.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpec.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,48 @@ +using System; +using System.ComponentModel; +using System.Linq; + +namespace Core.Common.Gui.PropertyBag +{ + /// + /// This class represents a single property. + /// + public class PropertySpec + { + /// + /// Initializes a new instance of the class for a given + /// property meta-data object. + /// + /// The property information. + public PropertySpec(System.Reflection.PropertyInfo propertyInfo) + { + Name = propertyInfo.Name; + TypeName = propertyInfo.PropertyType.AssemblyQualifiedName; + + var attributeList = propertyInfo.GetCustomAttributes(true).OfType().Select(attrib => attrib).ToList(); + if (propertyInfo.GetSetMethod() == null) + { + attributeList.Add(new ReadOnlyAttribute(true)); + } + Attributes = attributeList.ToArray(); + } + + /// + /// Gets or sets a collection of additional s for this property. + /// This can be used to specify attributes beyond those supported intrinsically by the + /// class, such as + /// and . + /// + public Attribute[] Attributes { get; set; } + + /// + /// Gets the name of the property. + /// + public string Name { get; private set; } + + /// + /// Gets the fully qualified name of the type of this property. + /// + public string TypeName { get; private set; } + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecCollection.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecCollection.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecCollection.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,349 @@ +using System; +using System.Collections; + +namespace Core.Common.Gui.PropertyBag +{ + /// + /// Encapsulates a collection of PropertySpec objects. + /// + [Serializable] + public class PropertySpecCollection : IList + { + private readonly ArrayList innerArray; + + /// + /// Initializes a new instance of the PropertySpecCollection class. + /// + public PropertySpecCollection() + { + innerArray = new ArrayList(); + } + + /// + /// Gets or sets the element at the specified index. + /// In C#, this property is the indexer for the PropertySpecCollection class. + /// + /// The zero-based index of the element to get or set. + /// + /// The element at the specified index. + /// + public PropertySpec this[int index] + { + get + { + return (PropertySpec) innerArray[index]; + } + set + { + innerArray[index] = value; + } + } + + /// + /// Gets the number of elements in the PropertySpecCollection. + /// + /// + /// The number of elements contained in the PropertySpecCollection. + /// + public int Count + { + get + { + return innerArray.Count; + } + } + + /// + /// Gets a value indicating whether the PropertySpecCollection has a fixed size. + /// + /// + /// true if the PropertySpecCollection has a fixed size; otherwise, false. + /// + public bool IsFixedSize + { + get + { + return false; + } + } + + /// + /// Gets a value indicating whether the PropertySpecCollection is read-only. + /// + public bool IsReadOnly + { + get + { + return false; + } + } + + /// + /// Gets a value indicating whether access to the collection is synchronized (thread-safe). + /// + /// + /// true if access to the PropertySpecCollection is synchronized (thread-safe); otherwise, false. + /// + public bool IsSynchronized + { + get + { + return false; + } + } + + /// + /// Gets an object that can be used to synchronize access to the collection. + /// + /// + /// An object that can be used to synchronize access to the collection. + /// + object ICollection.SyncRoot + { + get + { + return null; + } + } + + /// + /// Adds a PropertySpec to the end of the PropertySpecCollection. + /// + /// The PropertySpec to be added to the end of the PropertySpecCollection. + /// The PropertySpecCollection index at which the value has been added. + public int Add(PropertySpec value) + { + int index = innerArray.Add(value); + + return index; + } + + /// + /// Adds the elements of an array of PropertySpec objects to the end of the PropertySpecCollection. + /// + /// The PropertySpec array whose elements should be added to the end of the + /// PropertySpecCollection. + public void AddRange(PropertySpec[] array) + { + innerArray.AddRange(array); + } + + /// + /// Determines whether a PropertySpec is in the PropertySpecCollection. + /// + /// The PropertySpec to locate in the PropertySpecCollection. The element to locate + /// can be a null reference (Nothing in Visual Basic). + /// true if item is found in the PropertySpecCollection; otherwise, false. + public bool Contains(PropertySpec item) + { + return innerArray.Contains(item); + } + + /// + /// Determines whether a PropertySpec with the specified name is in the PropertySpecCollection. + /// + /// The name of the PropertySpec to locate in the PropertySpecCollection. + /// true if item is found in the PropertySpecCollection; otherwise, false. + public bool Contains(string name) + { + foreach (PropertySpec spec in innerArray) + { + if (spec.Name == name) + { + return true; + } + } + + return false; + } + + /// + /// Copies the entire PropertySpecCollection to a compatible one-dimensional Array, starting at the + /// beginning of the target array. + /// + /// The one-dimensional Array that is the destination of the elements copied + /// fromPropertySpecCollection. The Array must have zero-based indexing. + public void CopyTo(PropertySpec[] array) + { + innerArray.CopyTo(array); + } + + /// + /// Copies the PropertySpecCollection or a portion of it to a one-dimensional array. + /// + /// The one-dimensional Array that is the destination of the elements copied + /// from the collection. + /// The zero-based index in array at which copying begins. + public void CopyTo(PropertySpec[] array, int index) + { + innerArray.CopyTo(array, index); + } + + /// + /// Searches for the specified PropertySpec and returns the zero-based index of the first + /// occurrence within the entire PropertySpecCollection. + /// + /// The PropertySpec to locate in the PropertySpecCollection. + /// The zero-based index of the first occurrence of value within the entire PropertySpecCollection, + /// if found; otherwise, -1. + public int IndexOf(PropertySpec value) + { + return innerArray.IndexOf(value); + } + + /// + /// Searches for the PropertySpec with the specified name and returns the zero-based index of + /// the first occurrence within the entire PropertySpecCollection. + /// + /// The name of the PropertySpec to locate in the PropertySpecCollection. + /// The zero-based index of the first occurrence of value within the entire PropertySpecCollection, + /// if found; otherwise, -1. + public int IndexOf(string name) + { + int i = 0; + + foreach (PropertySpec spec in innerArray) + { + if (spec.Name == name) + { + return i; + } + + i++; + } + + return -1; + } + + /// + /// Inserts a PropertySpec object into the PropertySpecCollection at the specified index. + /// + /// The zero-based index at which value should be inserted. + /// The PropertySpec to insert. + public void Insert(int index, PropertySpec value) + { + innerArray.Insert(index, value); + } + + /// + /// Removes the first occurrence of a specific object from the PropertySpecCollection. + /// + /// The PropertySpec to remove from the PropertySpecCollection. + public void Remove(PropertySpec obj) + { + innerArray.Remove(obj); + } + + /// + /// Removes the property with the specified name from the PropertySpecCollection. + /// + /// The name of the PropertySpec to remove from the PropertySpecCollection. + public void Remove(string name) + { + int index = IndexOf(name); + RemoveAt(index); + } + + /// + /// Copies the elements of the PropertySpecCollection to a new PropertySpec array. + /// + /// A PropertySpec array containing copies of the elements of the PropertySpecCollection. + public PropertySpec[] ToArray() + { + return (PropertySpec[]) innerArray.ToArray(typeof(PropertySpec)); + } + + /// + /// Removes all elements from the PropertySpecCollection. + /// + public void Clear() + { + innerArray.Clear(); + } + + /// + /// Returns an enumerator that can iterate through the PropertySpecCollection. + /// + /// An IEnumerator for the entire PropertySpecCollection. + public IEnumerator GetEnumerator() + { + return innerArray.GetEnumerator(); + } + + /// + /// Removes the object at the specified index of the PropertySpecCollection. + /// + /// The zero-based index of the element to remove. + public void RemoveAt(int index) + { + innerArray.RemoveAt(index); + } + + #region Explicit interface implementations for ICollection and IList + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + void ICollection.CopyTo(Array array, int index) + { + CopyTo((PropertySpec[]) array, index); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + int IList.Add(object value) + { + return Add((PropertySpec) value); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + bool IList.Contains(object obj) + { + return Contains((PropertySpec) obj); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + object IList.this[int index] + { + get + { + return ((PropertySpecCollection) this)[index]; + } + set + { + ((PropertySpecCollection) this)[index] = (PropertySpec) value; + } + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + int IList.IndexOf(object obj) + { + return IndexOf((PropertySpec) obj); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + void IList.Insert(int index, object value) + { + Insert(index, (PropertySpec) value); + } + + /// + /// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code. + /// + void IList.Remove(object value) + { + Remove((PropertySpec) value); + } + + #endregion + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecDescriptor.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecDescriptor.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecDescriptor.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,91 @@ +using System; +using System.ComponentModel; + +namespace Core.Common.Gui.PropertyBag +{ + public class PropertySpecDescriptor : PropertyDescriptor + { + private readonly DynamicPropertyBag bag; + private readonly PropertySpec item; + + public PropertySpecDescriptor(PropertySpec item, DynamicPropertyBag bag, string name, Attribute[] attrs) + : + base(name, attrs) + { + this.bag = bag; + this.item = item; + } + + public override Type ComponentType + { + get + { + return item.GetType(); + } + } + + public override bool IsReadOnly + { + get + { + return (Attributes.Matches(ReadOnlyAttribute.Yes)); + } + } + + public override bool IsBrowsable + { + get + { + ReEvaluateAttributes(); + return base.IsBrowsable; + } + } + + public override Type PropertyType + { + get + { + return Type.GetType(item.TypeName); + } + } + + public override bool CanResetValue(object component) + { + return false; + } + + public override object GetValue(object component) + { + return ReEvaluateAttributes().Value; + } + + public override void ResetValue(object component) + { + + } + + public override void SetValue(object component, object value) + { + // Have the property bag raise an event to set the current value + // of the property. + + PropertySpecEventArgs e = new PropertySpecEventArgs(item, value); + bag.OnSetValue(e.Property.Name, e.Value); + } + + public override bool ShouldSerializeValue(object component) + { + return false; + } + + private PropertySpecEventArgs ReEvaluateAttributes() + { + // Have the property bag raise an event to get the current value + // of the property and evaluate the dynamic attributes + var e = new PropertySpecEventArgs(item, null); + bag.OnGetValue(e, e.Property); + AttributeArray = e.Property.Attributes; + return e; + } + } +} \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecEventArgs.cs =================================================================== diff -u --- Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecEventArgs.cs (revision 0) +++ Core/Common/src/Core.Common.Gui/PropertyBag/PropertySpecEventArgs.cs (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -0,0 +1,33 @@ +using System; + +namespace Core.Common.Gui.PropertyBag +{ + /// + /// Provides data for the GetValue and SetValue events of the PropertyBag class. + /// + public class PropertySpecEventArgs : EventArgs + { + /// + /// Initializes a new instance of the PropertySpecEventArgs class. + /// + /// The PropertySpec that represents the property whose + /// value is being requested or set. + /// The current value of the property. + public PropertySpecEventArgs(PropertySpec property, object val) + { + Property = property; + Value = val; + } + + /// + /// Gets the PropertySpec that represents the property whose value is being + /// requested or set. + /// + public PropertySpec Property { get; private set; } + + /// + /// Gets or sets the current value of the property. + /// + public object Value { get; set; } + } +} \ No newline at end of file Fisheye: Tag cd9655d356bdff388c7058eeff1cdbed076c407b refers to a dead (removed) revision in file `Core/Common/src/Core.Common.Utils/Attributes/PropertyOrderAttribute.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Common/src/Core.Common.Utils/Core.Common.Utils.csproj =================================================================== diff -u -r2a1dc72ed9a202b720c26828e5d53cecc5a0e6c8 -rcd9655d356bdff388c7058eeff1cdbed076c407b --- Core/Common/src/Core.Common.Utils/Core.Common.Utils.csproj (.../Core.Common.Utils.csproj) (revision 2a1dc72ed9a202b720c26828e5d53cecc5a0e6c8) +++ Core/Common/src/Core.Common.Utils/Core.Common.Utils.csproj (.../Core.Common.Utils.csproj) (revision cd9655d356bdff388c7058eeff1cdbed076c407b) @@ -91,7 +91,6 @@ - @@ -110,14 +109,9 @@ True Resource.resx - - - - - @@ -176,9 +170,7 @@ False - - - +