From 95a74afdb70894317fc3868a731ced07c9038276 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sun, 19 Apr 2009 15:04:03 +0000 Subject: [PATCH] Added limited support for ListView items in the python forms designer. No support for sub items nor the ListViewItem.Text property. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4001 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/IComponentCreator.cs | 6 + .../Project/Src/PythonCodeDeserializer.cs | 3 + .../Project/Src/PythonComponentWalker.cs | 40 ++++-- .../Project/Src/PythonControl.cs | 84 ++++++++---- .../Src/PythonControlFieldExpression.cs | 42 ++++-- .../Project/Src/PythonDesignerLoader.cs | 8 ++ .../DeserializeLocalVariableTestFixture.cs | 62 +++++++++ .../GenerateAcceptButtonFormTestFixture.cs | 4 +- .../GenerateListViewItemTestFixture.cs | 125 ++++++++++++++++++ .../GenerateMenuStripItemsTestFixture.cs | 4 +- ...tComponentFromDesignerLoaderTestFixture.cs | 8 +- ...etInstanceFromDesignerLoaderTestFixture.cs | 50 +++++++ .../Designer/LoadListViewFormTestFixture.cs | 85 ++++++++++++ ...ingInitializeComponentMethodTestFixture.cs | 5 + .../PythonControlFieldExpressionTests.cs | 26 ++++ .../Test/PythonBinding.Tests.csproj | 4 + .../Python/PythonBinding/Test/TODO.txt | 7 +- .../Test/Utils/MockComponentCreator.cs | 11 +- 18 files changed, 519 insertions(+), 55 deletions(-) create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeLocalVariableTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadListViewFormTestFixture.cs diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs index 47a1c6a96f..b3a9cf2bbe 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs @@ -48,6 +48,12 @@ namespace ICSharpCode.PythonBinding /// Name of the object. /// If set to true then the is added to the design container. object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer); + + /// + /// Gets the created instance. + /// + /// Instance name. + object GetInstance(string name); /// /// Gets the type given its name. diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs index fe0fbf9c32..d27f1a9fa6 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs @@ -144,11 +144,14 @@ namespace ICSharpCode.PythonBinding Expression listItemExpression = list.Items[i]; ConstantExpression constantExpression = listItemExpression as ConstantExpression; MemberExpression memberExpression = listItemExpression as MemberExpression; + NameExpression nameExpression = listItemExpression as NameExpression; if (constantExpression != null) { array.SetValue(constantExpression.Value, i); } else if (memberExpression != null) { string name = PythonControlFieldExpression.GetVariableName(memberExpression.Name.ToString()); array.SetValue(componentCreator.GetComponent(name), i); + } else if (nameExpression != null) { + array.SetValue(componentCreator.GetInstance(nameExpression.Name.ToString()), i); } } return array; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs index f261c38986..57f26654d4 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs @@ -94,6 +94,7 @@ namespace ICSharpCode.PythonBinding { if (node.Left.Count > 0) { MemberExpression lhsMemberExpression = node.Left[0] as MemberExpression; + NameExpression lhsNameExpression = node.Left[0] as NameExpression; if (lhsMemberExpression != null) { fieldExpression = PythonControlFieldExpression.Create(lhsMemberExpression); MemberExpression rhsMemberExpression = node.Right as MemberExpression; @@ -110,14 +111,23 @@ namespace ICSharpCode.PythonBinding } walkingAssignment = false; } - } + } else if (lhsNameExpression != null) { + CallExpression callExpression = node.Right as CallExpression; + if (callExpression != null) { + CreateInstance(lhsNameExpression.Name.ToString(), callExpression); + } + } } return false; } public override bool Walk(ConstantExpression node) { - SetPropertyValue(fieldExpression.MemberName, node.Value); + if (fieldExpression.IsSelfReference) { + SetPropertyValue(fieldExpression.MemberName, node.Value); + } else { + SetPropertyValue(componentCreator.GetInstance(fieldExpression.VariableName), fieldExpression.MemberName, node.Value); + } return false; } @@ -279,11 +289,8 @@ namespace ICSharpCode.PythonBinding { MemberExpression memberExpression = node.Target as MemberExpression; if (memberExpression != null) { - string name = PythonControlFieldExpression.GetMemberName(memberExpression); - Type type = componentCreator.GetType(name); - if (type != null) { - List args = deserializer.GetArguments(node); - object instance = componentCreator.CreateInstance(type, args, null, false); + object instance = CreateInstance(null, node); + if (instance != null) { if (!SetPropertyValue(fieldExpression.MemberName, instance)) { AddComponent(fieldExpression.MemberName, instance); } @@ -292,7 +299,7 @@ namespace ICSharpCode.PythonBinding if (obj != null) { SetPropertyValue(component, fieldExpression.MemberName, obj); } else { - throw new PythonComponentWalkerException(String.Format("Could not find type '{0}'.", name)); + throw new PythonComponentWalkerException(String.Format("Could not find type '{0}'.", PythonControlFieldExpression.GetMemberName(memberExpression))); } } } @@ -326,5 +333,22 @@ namespace ICSharpCode.PythonBinding member.GetType().InvokeMember(field.MethodName, BindingFlags.InvokeMethod, Type.DefaultBinder, member, new object[] {parameter}); } } + + /// + /// Creates a new instance with the specified name. + /// + object CreateInstance(string name, CallExpression node) + { + MemberExpression memberExpression = node.Target as MemberExpression; + if (memberExpression != null) { + string typeName = PythonControlFieldExpression.GetMemberName(memberExpression); + Type type = componentCreator.GetType(typeName); + if (type != null) { + List args = deserializer.GetArguments(node); + return componentCreator.CreateInstance(type, args, name, false); + } + } + return null; + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs index 126e2565f3..ada249bcaf 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs @@ -221,28 +221,31 @@ namespace ICSharpCode.PythonBinding } /// - /// Gets the child components that are sited on the specified object. + /// Gets the child objects that need to be stored in the generated designer code on the specified object. /// /// /// For a MenuStrip the child components include the MenuStrip.Items. /// For a Control the child components include the Control.Controls. /// - public static IComponent[] GetChildComponents(object obj) + public static object[] GetChildComponents(object obj) { - List childComponents = new List(); + List childComponents = new List(); foreach (PropertyDescriptor property in GetSerializableContentProperties(obj)) { ICollection collection = property.GetValue(obj) as ICollection; if (collection != null) { - foreach (object component in collection) { - if (IsSitedComponent(component)) { - childComponents.Add(component as IComponent); + foreach (object childObject in collection) { + // Add only those IComponents which are sited and any other objects + // which are not IComponents. + IComponent component = childObject as IComponent; + if ((component == null) || IsSitedComponent(component)) { + childComponents.Add(childObject); } } } } return childComponents.ToArray(); } - + void GenerateInitializeComponentMethodBodyInternal(Control control) { AppendChildControlCreation(control); @@ -289,6 +292,14 @@ namespace ICSharpCode.PythonBinding } } + /// + /// Generates python code for an object's properties which is not an IComponent. + /// + void AppendObject(object obj, int count) + { + AppendProperties(GetVariableName(obj, count), obj); + } + /// /// Appends a property to the InitializeComponents method. /// @@ -300,7 +311,7 @@ namespace ICSharpCode.PythonBinding } if (propertyDescriptor.SerializationVisibility == DesignerSerializationVisibility.Visible) { - string propertyName = GetPropertyName(propertyOwnerName, propertyDescriptor.Name); + string propertyName = propertyOwnerName + "." + propertyDescriptor.Name; Control control = propertyValue as Control; if (control != null) { AppendIndentedLine(propertyName + " = self._" + control.Name); @@ -312,15 +323,7 @@ namespace ICSharpCode.PythonBinding AppendMethodCallWithArrayParameter(propertyOwnerName, obj, propertyDescriptor); } } - - static string GetPropertyName(string propertyOwnerName, string propertyName) - { - if (String.IsNullOrEmpty(propertyOwnerName)) { - return "self." + propertyName; - } - return "self._" + propertyOwnerName + "." + propertyName; - } - + /// /// Appends the comment lines before the control has its properties set. /// @@ -374,11 +377,15 @@ namespace ICSharpCode.PythonBinding void AppendChildComponentCreation(ICollection components) { + int count = 1; foreach (object obj in components) { IComponent component = obj as IComponent; if (IsSitedComponent(component)) { AppendComponentCreation(component); AppendChildComponentCreation(GetChildComponents(component)); + } else if (component == null) { + AppendChildObjectCreation(obj, count); + count++; } } } @@ -393,6 +400,15 @@ namespace ICSharpCode.PythonBinding AppendIndentedLine("self._" + name + " = " + obj.GetType().FullName + "()"); } + void AppendChildObjectCreation(object obj, int count) + { + if (obj is String) { + // Do nothing. + } else { + AppendIndentedLine(GetVariableName(obj, count) + " = " + obj.GetType().FullName + "()"); + } + } + void AppendChildControlSuspendLayout(Control.ControlCollection controls) { AppendChildControlLayoutMethodCalls(controls, new string[] {"SuspendLayout()"}); @@ -439,7 +455,7 @@ namespace ICSharpCode.PythonBinding PropertyDescriptor propertyDescriptor = eventBindingService.GetEventProperty(eventDescriptor); if (propertyDescriptor.ShouldSerializeValue(component)) { string methodName = (string)propertyDescriptor.GetValue(component); - AppendIndentedLine(GetPropertyName(propertyOwnerName, eventDescriptor.Name) + " += self." + methodName); + AppendIndentedLine(propertyOwnerName + "." + eventDescriptor.Name + " += self." + methodName); } } @@ -474,8 +490,10 @@ namespace ICSharpCode.PythonBinding } if (component is IComponent) { Append("self._" + ((IComponent)component).Site.Name); - } else { + } else if (component is String) { Append(PythonPropertyValueAssignment.ToString(component)); + } else { + Append(GetVariableName(component, i + 1)); } ++i; } @@ -495,9 +513,9 @@ namespace ICSharpCode.PythonBinding string GetPropertyOwnerName(IComponent component, bool addComponentNameToProperty) { if (addComponentNameToProperty) { - return component.Site.Name; + return "self._" + component.Site.Name; } - return String.Empty; + return "self"; } /// @@ -510,9 +528,14 @@ namespace ICSharpCode.PythonBinding object propertyCollection = property.GetValue(component); ICollection collection = propertyCollection as ICollection; if (collection != null) { - foreach (object childComponent in collection) { + int count = 1; + foreach (object childObject in collection) { + IComponent childComponent = childObject as IComponent; if (IsSitedComponent(childComponent)) { - AppendComponent(childComponent as IComponent , true, true); + AppendComponent(childComponent, true, true); + } else if (childComponent == null) { + AppendObject(childObject, count); + ++count; } } } @@ -557,11 +580,24 @@ namespace ICSharpCode.PythonBinding foreach (object item in collectionProperty) { IComponent collectionComponent = item as IComponent; if (IsSitedComponent(collectionComponent)) { - AppendIndentedLine(GetPropertyName(propertyOwnerName, propertyDescriptor.Name) + "." + addMethod.Name + "(self._" + collectionComponent.Site.Name + ")"); + AppendIndentedLine(propertyOwnerName + "." + propertyDescriptor.Name + "." + addMethod.Name + "(self._" + collectionComponent.Site.Name + ")"); } } } } } + + /// + /// Gets the variable name for the specified type. + /// + /// + /// The variable name is simply the type name with the first character in lower case followed by the + /// count. + /// + static string GetVariableName(object obj, int count) + { + string typeName = obj.GetType().Name; + return typeName[0].ToString().ToLowerInvariant() + typeName.Substring(1) + count; + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs index 5bc6cad614..0a29979aef 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs @@ -26,13 +26,15 @@ namespace ICSharpCode.PythonBinding string fullMemberName = String.Empty; string variableName = String.Empty; string methodName = String.Empty; + bool selfReference; - PythonControlFieldExpression(string memberName, string variableName, string methodName, string fullMemberName) + public PythonControlFieldExpression(string memberName, string variableName, string methodName, string fullMemberName) { this.memberName = memberName; this.variableName = variableName; this.methodName = methodName; this.fullMemberName = fullMemberName; + selfReference = ContainsSelfReference(fullMemberName); } /// @@ -63,16 +65,23 @@ namespace ICSharpCode.PythonBinding get { return methodName; } } + /// + /// Returns whether the variable is for a field or not. + /// + public bool IsSelfReference { + get { return selfReference; } + } + public override string ToString() { - return fullMemberName; + return "[VariableName: " + variableName + " FullMemberName: " + fullMemberName + "]"; } public override bool Equals(object obj) { PythonControlFieldExpression rhs = obj as PythonControlFieldExpression; if (rhs != null) { - return rhs.fullMemberName == fullMemberName; + return rhs.fullMemberName == fullMemberName && rhs.variableName == variableName; } return false; } @@ -240,18 +249,20 @@ namespace ICSharpCode.PythonBinding /// /// Returns "textBox1" /// + /// + /// If there is no self part then the variable name is the first part of the name. + /// static string GetVariableNameFromSelfReference(string name) { - int startIndex = name.IndexOf('.'); - if (startIndex > 0) { - name = name.Substring(startIndex + 1); - int endIndex = name.IndexOf('.'); - if (endIndex > 0) { - return GetVariableName(name.Substring(0, endIndex)); - } - return String.Empty; + if (ContainsSelfReference(name)) { + name = name.Substring(5); } - return name; + + int endIndex = name.IndexOf('.'); + if (endIndex > 0) { + return GetVariableName(name.Substring(0, endIndex)); + } + return String.Empty; } static PythonControlFieldExpression Create(string[] memberNames) @@ -261,7 +272,12 @@ namespace ICSharpCode.PythonBinding memberName = memberNames[memberNames.Length - 1]; } string fullMemberName = PythonControlFieldExpression.GetMemberName(memberNames); - return new PythonControlFieldExpression(memberName, GetVariableNameFromSelfReference(fullMemberName), String.Empty, fullMemberName); + return new PythonControlFieldExpression(memberName, GetVariableNameFromSelfReference(fullMemberName), String.Empty, fullMemberName); + } + + static bool ContainsSelfReference(string name) + { + return name.StartsWith("self.", StringComparison.InvariantCultureIgnoreCase); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs index f534912107..87344533d1 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs @@ -84,6 +84,14 @@ namespace ICSharpCode.PythonBinding { return serializationManager.CreateInstance(type, arguments, name, addToContainer); } + + /// + /// Gets an instance by name. + /// + public object GetInstance(string name) + { + return serializationManager.GetInstance(name); + } /// /// Gets the type given its name. diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeLocalVariableTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeLocalVariableTestFixture.cs new file mode 100644 index 0000000000..15b3115dfd --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeLocalVariableTestFixture.cs @@ -0,0 +1,62 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + /// + /// Tests that a local variable can be deserialized. Local variables are used when adding + /// ListViewItems to a ListView. + /// + [TestFixture] + public class DeserializeLocalVariableTestFixture + { + string pythonCode = "self.Items.AddRange(System.Array[System.Windows.Forms.ListViewItem]([listViewItem1]))"; + + MockDesignerLoaderHost mockDesignerLoaderHost; + MockTypeResolutionService typeResolutionService; + MockComponentCreator componentCreator; + ListViewItem listViewItem1; + object deserializedObject; + + [TestFixtureSetUp] + public void SetUpFixture() + { + componentCreator = new MockComponentCreator(); + listViewItem1 = (ListViewItem)componentCreator.CreateInstance(typeof(ListViewItem), new object[0], "listViewItem1", false); + + CallExpression callExpression = PythonParserHelper.GetCallExpression(pythonCode); + + mockDesignerLoaderHost = new MockDesignerLoaderHost(); + typeResolutionService = mockDesignerLoaderHost.TypeResolutionService; + PythonCodeDeserializer deserializer = new PythonCodeDeserializer(componentCreator); + deserializedObject = deserializer.Deserialize(callExpression.Args[0].Expression); + } + + [Test] + public void ListViewItemDeserialized() + { + ListViewItem[] array = (ListViewItem[])deserializedObject; + Assert.AreSame(listViewItem1, array[0]); + } + + [Test] + public void ListViewItemIsNotNull() + { + Assert.IsNotNull(deserializedObject); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs index 94e6823e2e..b2b46fc08f 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs @@ -22,8 +22,8 @@ namespace PythonBinding.Tests.Designer public class GenerateAcceptButtonFormTestFixture { string generatedPythonCode; - IComponent[] formChildComponents; - IComponent[] buttonChildComponents; + object[] formChildComponents; + object[] buttonChildComponents; [TestFixtureSetUp] public void SetUpFixture() diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs new file mode 100644 index 0000000000..3817acfbfe --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs @@ -0,0 +1,125 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Serialization; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class GenerateListViewItemsFormTestFixture + { + string generatedPythonCode; + object[] listViewChildren; + ListViewItem listViewItem1; + ListViewItem listViewItem2; + + [TestFixtureSetUp] + public void SetUpFixture() + { + using (DesignSurface designSurface = new DesignSurface(typeof(Form))) { + IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost)); + IEventBindingService eventBindingService = new MockEventBindingService(host); + Form form = (Form)host.RootComponent; + form.ClientSize = new Size(200, 300); + + PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form); + PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false); + namePropertyDescriptor.SetValue(form, "MainForm"); + + // Add list view. + ListView listView = (ListView)host.CreateComponent(typeof(ListView), "listView1"); + listView.TabIndex = 0; + listView.Location = new Point(0, 0); + listView.ClientSize = new Size(200, 100); + descriptors = TypeDescriptor.GetProperties(listView); + PropertyDescriptor descriptor = descriptors.Find("UseCompatibleStateImageBehavior", false); + descriptor.SetValue(listView, true); + form.Controls.Add(listView); + + ListViewItem item = new ListViewItem("aaa"); + item.ToolTipText = "tooltip"; + listView.Items.Add(item); + + ListViewItem item2 = new ListViewItem("bbb"); + listView.Items.Add(item2); + + PythonControl pythonForm = new PythonControl(" "); + generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form); + + listViewChildren = PythonControl.GetChildComponents(listView); + if (listViewChildren != null && listViewChildren.Length > 1) { + listViewItem1 = listViewChildren[0] as ListViewItem; + listViewItem2 = listViewChildren[1] as ListViewItem; + } + } + } + + [Test] + public void GeneratedCode() + { + string expectedCode = "def InitializeComponent(self):\r\n" + + " self._listView1 = System.Windows.Forms.ListView()\r\n" + + " listViewItem1 = System.Windows.Forms.ListViewItem()\r\n" + + " listViewItem2 = System.Windows.Forms.ListViewItem()\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # listView1\r\n" + + " # \r\n" + + " self._listView1.Items.AddRange(System.Array[System.Windows.Forms.ListViewItem](\r\n" + + " [listViewItem1,\r\n" + + " listViewItem2]))\r\n" + + " self._listView1.Location = System.Drawing.Point(0, 0)\r\n" + + " self._listView1.Name = \"listView1\"\r\n" + + " self._listView1.Size = System.Drawing.Size(204, 104)\r\n" + + " self._listView1.TabIndex = 0\r\n" + + " listViewItem1.ToolTipText = \"tooltip\"\r\n" + + " # \r\n" + + " # MainForm\r\n" + + " # \r\n" + + " self.ClientSize = System.Drawing.Size(200, 300)\r\n" + + " self.Controls.Add(self._listView1)\r\n" + + " self.Name = \"MainForm\"\r\n" + + " self.ResumeLayout(False)\r\n" + + " self.PerformLayout()\r\n"; + + Assert.AreEqual(expectedCode, generatedPythonCode); + } + + [Test] + public void TwoListViewChildren() + { + Assert.AreEqual(2, listViewChildren.Length); + } + + [Test] + public void ListViewItem1Text() + { + Assert.AreEqual("aaa", listViewItem1.Text); + } + + [Test] + public void ListViewItem1TooltipText() + { + Assert.AreEqual("tooltip", listViewItem1.ToolTipText); + } + + [Test] + public void ListViewItem2Text() + { + Assert.AreEqual("bbb", listViewItem2.Text); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs index 2b4bf6bef1..a04e424346 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs @@ -26,8 +26,8 @@ namespace PythonBinding.Tests.Designer Size openMenuItemSize; Size exitMenuItemSize; Size editMenuItemSize; - IComponent[] menuStripChildComponents; - IComponent[] fileMenuItemChildComponents; + object[] menuStripChildComponents; + object[] fileMenuItemChildComponents; [TestFixtureSetUp] public void SetUpFixture() diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs index 65c91beaa7..93f1ed6e54 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs @@ -35,7 +35,7 @@ namespace PythonBinding.Tests.Designer textBox = (TextBox)loader.CreateComponent(typeof(TextBox), "textBox1"); label = (Label)loader.CreateComponent(typeof(Label), "label1"); - loader.Add(label, "label1"); + loader.Add(label, "label1"); } [TearDown] @@ -44,6 +44,12 @@ namespace PythonBinding.Tests.Designer if (textBox != null) { textBox.Dispose(); } + if (label != null) { + label.Dispose(); + } + if (loader != null) { + loader.Dispose(); + } } [Test] diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs new file mode 100644 index 0000000000..0841692169 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs @@ -0,0 +1,50 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + /// + /// Tests the GetInstance method of the PythonDesignerLoader. + /// + [TestFixture] + public class GetInstanceFromDesignerLoaderTestFixture + { + PythonDesignerLoader loader; + MockDesignerLoaderHost host; + ListViewItem listViewItem1; + object instance; + + [SetUp] + public void Init() + { + host = new MockDesignerLoaderHost(); + loader = new PythonDesignerLoader(new MockDesignerGenerator()); + loader.BeginLoad(host); + + DesignerSerializationManager designerSerializationManager = (DesignerSerializationManager)host.GetService(typeof(IDesignerSerializationManager)); + using (designerSerializationManager.CreateSession()) { + listViewItem1 = (ListViewItem)loader.CreateInstance(typeof(ListViewItem), new object[0], "listViewItem1", false); + instance = loader.GetInstance("listViewItem1"); + } + } + + + [Test] + public void GetListViewInstance() + { + Assert.AreEqual(listViewItem1, instance); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadListViewFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadListViewFormTestFixture.cs new file mode 100644 index 0000000000..88d83d3a85 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadListViewFormTestFixture.cs @@ -0,0 +1,85 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class LoadListViewFormTestFixture : LoadFormTestFixtureBase + { + public override string PythonCode { + get { + return "class MainForm(System.Windows.Forms.Form):\r\n" + + " def InitializeComponent(self):\r\n" + + " self._listView1 = System.Windows.Forms.ListView()\r\n" + + " listViewItem1 = System.Windows.Forms.ListViewItem()\r\n" + + " listViewItem2 = System.Windows.Forms.ListViewItem()\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # listView1\r\n" + + " # \r\n" + + " self._listView1.Items.AddRange(System.Array[System.Windows.Forms.ListViewItem](\r\n" + + " [listViewItem1,\r\n" + + " listViewItem2]))\r\n" + + " self._listView1.Location = System.Drawing.Point(0, 0)\r\n" + + " self._listView1.Name = \"listView1\"\r\n" + + " self._listView1.Size = System.Drawing.Size(204, 104)\r\n" + + " self._listView1.TabIndex = 0\r\n" + + " listViewItem1.ToolTipText = \"tooltip1\"\r\n" + + " listViewItem2.ToolTipText = \"tooltip2\"\r\n" + + " # \r\n" + + " # MainForm\r\n" + + " # \r\n" + + " self.ClientSize = System.Drawing.Size(200, 300)\r\n" + + " self.Controls.Add(self._listView1)\r\n" + + " self.Name = \"MainForm\"\r\n" + + " self.ResumeLayout(False)\r\n" + + " self.PerformLayout()\r\n"; + } + } + + public ListView ListView { + get { return Form.Controls[0] as ListView; } + } + + public ListViewItem ListViewItem1 { + get { return ListView.Items[0]; } + } + + public ListViewItem ListViewItem2 { + get { return ListView.Items[1]; } + } + + [Test] + public void ListViewAddedToForm() + { + Assert.IsNotNull(ListView); + } + + [Test] + public void ListViewHasTwoItems() + { + Assert.AreEqual(2, ListView.Items.Count); + } + + [Test] + public void ListViewItem1TooltipText() + { + Assert.AreEqual("tooltip1", ListViewItem1.ToolTipText); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs index b703545a2f..6b59d54122 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs @@ -98,5 +98,10 @@ namespace PythonBinding.Tests.Designer { return null; } + + public object GetInstance(string name) + { + return null; + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs index f15a23c50f..8d83374e07 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs @@ -152,6 +152,32 @@ namespace PythonBinding.Tests.Designer } } + [Test] + public void LocalVariable() + { + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("listViewItem1.TooltipText = \"abc\""); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + + PythonControlFieldExpression expectedField = new PythonControlFieldExpression("TooltipText", "listViewItem1", String.Empty, "listViewItem1.TooltipText"); + Assert.AreEqual(expectedField, field); + } + + [Test] + public void LocalVariableIsNotSelfReference() + { + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("listViewItem1.TooltipText = \"abc\""); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + Assert.IsFalse(field.IsSelfReference); + } + + [Test] + public void FieldIsNotSelfReference() + { + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self.listView1.TooltipText = \"abc\""); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + Assert.IsTrue(field.IsSelfReference); + } + void AssertAreEqual(PythonControlFieldExpression field, string variableName, string memberName, string methodName, string fullMemberName) { string expected = "Variable: " + variableName + " Member: " + memberName + " Method: " + methodName + " FullMemberName: " + fullMemberName; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index 14968eaddd..32020d4b6b 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -149,6 +149,7 @@ + @@ -166,6 +167,7 @@ + @@ -176,6 +178,7 @@ + @@ -192,6 +195,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt b/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt index db94446496..83bab5104a 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt @@ -98,8 +98,7 @@ def main(args): * ContextMenuStrip - designer does not generate the correct code. -* MenuStrip - adds a design time only control to the generated code. - self._menuStrip1.Items.AddRange(System.Array[System.Windows.Forms.ToolStripItem]((self._fileToolStripMenuItem, ))) - System.Array[System.Windows.Forms.ToolStripItem([self._fileToolStripMenuItem,self._exitToolStripMenuItem]) +* Look at fixing the compiled exe so it can be run from a different folder. - \ No newline at end of file + See http://lists.ironpython.com/pipermail/users-ironpython.com/2009-April/009993.html + \ No newline at end of file diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs index 2a5b77dae8..5b200d69a7 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs @@ -147,6 +147,15 @@ namespace PythonBinding.Tests.Utils } } return null; - } + } + + public object GetInstance(string name) + { + CreatedInstance instance = GetCreatedInstance(name); + if (instance != null) { + return instance.Object; + } + return null; + } } }