Index: src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj
===================================================================
diff -u -rc4fb042f3ea7c21852fba8fdc21bdeac96da6419 -r9f1efb36120427350936d48059c87c7e011657a9
--- src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj (.../DeltaShell.Gui.csproj) (revision c4fb042f3ea7c21852fba8fdc21bdeac96da6419)
+++ src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj (.../DeltaShell.Gui.csproj) (revision 9f1efb36120427350936d48059c87c7e011657a9)
@@ -146,6 +146,7 @@
Component
+
SplashScreen.xaml
Index: src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyGridView.cs
===================================================================
diff -u -re0fff25db4ec9d82f4c3a39a4092ba6a30b98572 -r9f1efb36120427350936d48059c87c7e011657a9
--- src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyGridView.cs (.../PropertyGridView.cs) (revision e0fff25db4ec9d82f4c3a39a4092ba6a30b98572)
+++ src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyGridView.cs (.../PropertyGridView.cs) (revision 9f1efb36120427350936d48059c87c7e011657a9)
@@ -1,6 +1,5 @@
using System;
using System.Collections;
-using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Permissions;
@@ -9,9 +8,7 @@
using DelftTools.Shell.Core;
using DelftTools.Shell.Gui;
using DelftTools.Shell.Gui.Forms;
-using DelftTools.Utils.PropertyBag.Dynamic;
using DeltaShell.Gui.Properties;
-using log4net;
namespace DeltaShell.Gui.Forms.PropertyGridView
{
@@ -22,8 +19,6 @@
///
private delegate void ArgumentlessDelegate();
- private static readonly ILog Log = LogManager.GetLogger(typeof(PropertyGridView));
-
///
/// todo: This is still an unwanted dependency. PropertyGrid uses gui to subscribe to the SelectionChanged
/// delegate and in responce queries the gui.Selection
@@ -56,46 +51,6 @@
}
}
- public object GetObjectProperties(object sourceData)
- {
- if (sourceData == null)
- {
- return null;
- }
-
- // Obtain all property information
- var propertyInfos = gui.Plugins.SelectMany(p => p.GetPropertyInfos()).ToList();
-
- // 1. Match property information based on ObjectType and on AdditionalDataCheck
- propertyInfos = propertyInfos.Where(pi => pi.ObjectType.IsInstanceOfType(sourceData) && (pi.AdditionalDataCheck == null || pi.AdditionalDataCheck(sourceData))).ToList();
-
- // 2. Match property information based on object type inheritance
- propertyInfos = FilterPropertyInfoByTypeInheritance(propertyInfos, pi => pi.ObjectType);
-
- // 3. Match property information based on property type inheritance
- propertyInfos = FilterPropertyInfoByTypeInheritance(propertyInfos, pi => pi.PropertyType);
-
- if (propertyInfos.Count == 0)
- {
- // No (or multiple) object properties found: return 'null' so that no object properties are shown in the property grid
- return null;
- }
-
- if (propertyInfos.Count > 1)
- {
- // 4. We assume that the propertyInfos with AdditionalDataCheck are the most specific
- propertyInfos = propertyInfos.Where(pi => pi.AdditionalDataCheck != null).ToList();
- }
-
- if (propertyInfos.Count == 1)
- {
- return CreateObjectProperties(propertyInfos.ElementAt(0), sourceData);
- }
-
- Log.Debug(Resources.PropertyGrid_GetObjectProperties_Multiple_object_property_instances_found_for_the_same_data_object__no_object_properties_are_displayed_in_the_property_grid);
- return null;
- }
-
///
/// Raises the event.
///
@@ -157,56 +112,6 @@
SelectedObject = GetObjectProperties(selection);
}
- private List FilterPropertyInfoByTypeInheritance(List propertyInfo, Func getTypeAction)
- {
- var propertyInfoCount = propertyInfo.Count;
- var propertyInfoWithUnInheritedType = propertyInfo.ToList();
-
- for (var i = 0; i < propertyInfoCount; i++)
- {
- var firstType = getTypeAction(propertyInfo.ElementAt(i));
-
- for (var j = 0; j < propertyInfoCount; j++)
- {
- if (i == j)
- {
- continue;
- }
-
- var secondType = getTypeAction(propertyInfo.ElementAt(j));
-
- if (firstType != secondType && firstType.IsAssignableFrom(secondType))
- {
- propertyInfoWithUnInheritedType.Remove(propertyInfo.ElementAt(i));
-
- break;
- }
- }
- }
-
- return propertyInfoWithUnInheritedType.Any()
- ? propertyInfoWithUnInheritedType.ToList() // One or more specific property information objects found: return the filtered list
- : propertyInfo; // No specific property information found: return the original list
- }
-
- private object CreateObjectProperties(PropertyInfo propertyInfo, object sourceData)
- {
- try
- {
- // Try to create object properties for the source data
- var objectProperties = propertyInfo.CreateObjectProperties(sourceData);
-
- // Return a dynamic property bag containing the created object properties
- return new DynamicPropertyBag(objectProperties);
- }
- catch (Exception)
- {
- Log.Debug(Resources.PropertyGrid_CreateObjectProperties_Could_not_create_object_properties_for_the_data);
-
- return null;
- }
- }
-
#region IPropertyGrid Members
public object Data
@@ -235,6 +140,16 @@
public void EnsureVisible(object item) {}
+ public object GetObjectProperties(object sourceData)
+ {
+ if (gui != null)
+ {
+ PropertyResolver.GetObjectProperties(gui.Plugins.SelectMany(p => p.GetPropertyInfos()).ToList(), sourceData);
+ }
+
+ return null;
+ }
+
public ViewInfo ViewInfo { get; set; }
#endregion
Index: src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyResolver.cs
===================================================================
diff -u
--- src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyResolver.cs (revision 0)
+++ src/DeltaShell/DeltaShell.Gui/Forms/PropertyGridView/PropertyResolver.cs (revision 9f1efb36120427350936d48059c87c7e011657a9)
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DelftTools.Shell.Gui;
+using DelftTools.Utils.PropertyBag.Dynamic;
+
+namespace DeltaShell.Gui.Forms.PropertyGridView
+{
+ ///
+ /// Helper class for resolving objects.
+ ///
+ public static class PropertyResolver
+ {
+ ///
+ /// Returns object properties based on the provided and .
+ ///
+ /// The list of property info objects to obtain the object properties from.
+ /// The source data to get the object properties for.
+ /// An object properties object, or null when no relevant propwrties object is found.
+ public static object GetObjectProperties(List propertyInfos, object sourceData)
+ {
+ if (sourceData == null)
+ {
+ return null;
+ }
+
+ // 1. Match property information based on ObjectType and on AdditionalDataCheck
+ propertyInfos = propertyInfos.Where(pi => pi.ObjectType.IsInstanceOfType(sourceData) && (pi.AdditionalDataCheck == null || pi.AdditionalDataCheck(sourceData))).ToList();
+
+ // 2. Match property information based on object type inheritance
+ propertyInfos = FilterPropertyInfoByTypeInheritance(propertyInfos, pi => pi.ObjectType);
+
+ // 3. Match property information based on property type inheritance
+ propertyInfos = FilterPropertyInfoByTypeInheritance(propertyInfos, pi => pi.PropertyType);
+
+ if (propertyInfos.Count == 0)
+ {
+ // No (or multiple) object properties found: return 'null' so that no object properties are shown in the property grid
+ return null;
+ }
+
+ if (propertyInfos.Count > 1)
+ {
+ // 4. We assume that the propertyInfos with AdditionalDataCheck are the most specific
+ propertyInfos = propertyInfos.Where(pi => pi.AdditionalDataCheck != null).ToList();
+ }
+
+ if (propertyInfos.Count == 1)
+ {
+ return CreateObjectProperties(propertyInfos.ElementAt(0), sourceData);
+ }
+
+ return null;
+ }
+
+ private static List FilterPropertyInfoByTypeInheritance(List propertyInfo, Func getTypeAction)
+ {
+ var propertyInfoCount = propertyInfo.Count;
+ var propertyInfoWithUnInheritedType = propertyInfo.ToList();
+
+ for (var i = 0; i < propertyInfoCount; i++)
+ {
+ var firstType = getTypeAction(propertyInfo.ElementAt(i));
+
+ for (var j = 0; j < propertyInfoCount; j++)
+ {
+ if (i == j)
+ {
+ continue;
+ }
+
+ var secondType = getTypeAction(propertyInfo.ElementAt(j));
+
+ if (firstType != secondType && firstType.IsAssignableFrom(secondType))
+ {
+ propertyInfoWithUnInheritedType.Remove(propertyInfo.ElementAt(i));
+
+ break;
+ }
+ }
+ }
+
+ return propertyInfoWithUnInheritedType.Any()
+ ? propertyInfoWithUnInheritedType.ToList() // One or more specific property information objects found: return the filtered list
+ : propertyInfo; // No specific property information found: return the original list
+ }
+
+ private static object CreateObjectProperties(PropertyInfo propertyInfo, object sourceData)
+ {
+ try
+ {
+ // Try to create object properties for the source data
+ var objectProperties = propertyInfo.CreateObjectProperties(sourceData);
+
+ // Return a dynamic property bag containing the created object properties
+ return new DynamicPropertyBag(objectProperties);
+ return objectProperties is DynamicPropertyBag
+ ? (object)objectProperties
+ : new DynamicPropertyBag(objectProperties);
+ return new DynamicPropertyBag(objectProperties);
+ }
+ catch (Exception)
+ {
+ return sourceData;
+ }
+ }
+ }
+}
Index: test/DeltaShell/DeltaShell.Tests/DeltaShell.Tests.csproj
===================================================================
diff -u -r9e0b372066f8d8be8c231b3be8922d29a1c61e1f -r9f1efb36120427350936d48059c87c7e011657a9
--- test/DeltaShell/DeltaShell.Tests/DeltaShell.Tests.csproj (.../DeltaShell.Tests.csproj) (revision 9e0b372066f8d8be8c231b3be8922d29a1c61e1f)
+++ test/DeltaShell/DeltaShell.Tests/DeltaShell.Tests.csproj (.../DeltaShell.Tests.csproj) (revision 9f1efb36120427350936d48059c87c7e011657a9)
@@ -87,7 +87,7 @@
-
+
Fisheye: Tag 9f1efb36120427350936d48059c87c7e011657a9 refers to a dead (removed) revision in file `test/DeltaShell/DeltaShell.Tests/Gui/Forms/PropertyGrid/PropertyGridTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: test/DeltaShell/DeltaShell.Tests/Gui/Forms/PropertyGrid/PropertyResolverTest.cs
===================================================================
diff -u
--- test/DeltaShell/DeltaShell.Tests/Gui/Forms/PropertyGrid/PropertyResolverTest.cs (revision 0)
+++ test/DeltaShell/DeltaShell.Tests/Gui/Forms/PropertyGrid/PropertyResolverTest.cs (revision 9f1efb36120427350936d48059c87c7e011657a9)
@@ -0,0 +1,317 @@
+using System;
+using System.Collections.Generic;
+using DelftTools.Shell.Gui;
+using DelftTools.TestUtils;
+using DelftTools.Utils.PropertyBag.Dynamic;
+using DeltaShell.Gui;
+using DeltaShell.Gui.Forms.PropertyGridView;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace DeltaShell.Tests.Gui.Forms.PropertyGrid
+{
+ [TestFixture]
+ public class PropertyResolverTest
+ {
+ # region GetObjectProperties tests
+
+ [Test]
+ public void GetObjectProperties_WhenNoPropertyInfoIsFound_ReturnNull()
+ {
+ // Assert
+ Assert.IsNull(PropertyResolver.GetObjectProperties(new List(), 1.0));
+ }
+
+ [Test]
+ public void GetObjectProperties_WhenOnePropertyInfoIsFound_ReturnDynamicPropertyBagContainingOnlyThatPropertiesObject()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new A());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(SimpleProperties), ((DynamicPropertyBag) objectProperties).GetContentType());
+ }
+
+
+ [Test]
+ public void GetObjectProperties_WhenOnePropertyInfoIsFoundButAdditionalChecksFail_ReturnNull()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>()
+ {
+ AdditionalDataCheck = o => false
+ }
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new A());
+
+ // Assert
+ Assert.IsNull(objectProperties);
+ }
+
+ [Test]
+ public void GetObjectProperties_WhenTwoPropertyInfoAreFoundOneWithAdditionalCheckOneWithBetterType_ReturnPropertiesObjectMatchingAdditionCheck()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>()
+ {
+ AdditionalDataCheck = o => false
+ },
+ new PropertyInfo>() // specifically for C
+ };
+
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new C()); //we ask for C
+
+ // Assert
+ Assert.AreSame(typeof(SimpleProperties),
+ ((DynamicPropertyBag)objectProperties).GetContentType(), "we got A, expected C");
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnDirectObjectTypeMatch_ReturnObjectPropertiesMatchingTypeD()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>(),
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new D());
+
+ // Setup
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(SimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnDerivedObjectTypeMatch_ReturnObjectPropertiesForBaseClass()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>(),
+ new PropertyInfo>()
+ };
+
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new D());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(SimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnDerivedObjectTypeMatchAndAdditionalDataCheck_ReturnObjectPropertiesForBaseClassMatchingAdditionCheck()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ },
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new D());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(SimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnMatchingAdditionalDataCheck_ReturnMatchingWithAdditionalDataCheck()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }, // Additional data check which will be matched
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new B());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(SimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnMismatchingAdditionalDataCheck_ReturnFallBackPropertiesObject()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => false
+ }, // Additional data check which will not be matched
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new B());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(OtherSimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnDerivedPropertyTypeMatch_ReturnDerivedObjectPropertiesClass()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>(),
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new B());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(DerivedSimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_BasedOnDerivedPropertyTypeMatchAndAdditionalDataCheck_ReturnDerivedObjectProperties()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ },
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new B());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(DerivedSimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ [Test]
+ public void GetObjectProperties_WhenMultiplePropertyObjectsAreFound_ReturnNull()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>(),
+ new PropertyInfo>()
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new B());
+ Assert.IsNull(objectProperties);
+ }
+
+ [Test]
+ public void GetObjectProperties_TakingAllPropertyInfoPropertiesIntoAccount_ReturnDerivedObjectPropertiesMatchingDataCheck()
+ {
+ // Setup
+ var propertyInfos = new List
+ {
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }, // D is not assignable from C: no candidate
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }, // A is less specific than C: candidate but not the most specific one
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => false
+ }, // Additional data check is false: no candidate
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ }, // SimpleProperties is less specific than DerivedSimpleProperties: candidate but not the most specific one
+ new PropertyInfo>
+ {
+ AdditionalDataCheck = o => true
+ } // Most specific!
+ };
+
+ // Call
+ var objectProperties = PropertyResolver.GetObjectProperties(propertyInfos, new C());
+
+ // Assert
+ Assert.IsTrue(objectProperties is DynamicPropertyBag);
+ Assert.AreSame(typeof(DerivedSimpleProperties), ((DynamicPropertyBag)objectProperties).GetContentType());
+ }
+
+ # endregion
+
+ # region Nested types
+
+ /*
+ * A
+ * ___^___
+ * | |
+ * B C
+ * |
+ * D
+ *
+ *
+ *
+ * SimpleProperties OtherSimpleProperties
+ * ^
+ * |
+ * DerivedSimpleProperties
+ *
+ */
+
+ internal class A {}
+
+ private class B : A {}
+
+ internal class C : A {}
+
+ private class D : C {}
+
+ internal class SimpleProperties : ObjectProperties {}
+
+ private class DerivedSimpleProperties : SimpleProperties {}
+
+ private class OtherSimpleProperties : ObjectProperties {}
+
+ # endregion
+ }
+}
\ No newline at end of file