Browse Source

Python forms designer now supports loading and generating code for the text in a ListViewSubItem.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4046 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 16 years ago
parent
commit
97eff32314
  1. 3
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs
  2. 69
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs
  3. 10
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerRootComponent.cs
  4. 7
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonListViewComponent.cs
  5. 57
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializerConstructorStringArrayTestFixture.cs
  6. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs
  7. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs
  8. 98
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewSubItemsTestFixture.cs
  9. 33
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs
  10. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  11. 3
      src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt

3
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs

@ -35,10 +35,13 @@ namespace ICSharpCode.PythonBinding @@ -35,10 +35,13 @@ namespace ICSharpCode.PythonBinding
foreach (Arg a in expression.Args) {
ConstantExpression constantExpression = a.Expression as ConstantExpression;
MemberExpression memberExpression = a.Expression as MemberExpression;
CallExpression callExpression = a.Expression as CallExpression;
if (constantExpression != null) {
args.Add(constantExpression.Value);
} else if (memberExpression != null) {
args.Add(Deserialize(memberExpression));
} else if(callExpression != null) {
args.Add(Deserialize(callExpression));
}
}
return args;

69
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs

@ -144,6 +144,14 @@ namespace ICSharpCode.PythonBinding @@ -144,6 +144,14 @@ namespace ICSharpCode.PythonBinding
return null;
}
/// <summary>
/// Gets the component type.
/// </summary>
public Type GetComponentType()
{
return component.GetType();
}
/// <summary>
/// Gets the Add serialization method that is not hidden from the designer.
/// </summary>
@ -216,7 +224,7 @@ namespace ICSharpCode.PythonBinding @@ -216,7 +224,7 @@ namespace ICSharpCode.PythonBinding
public bool IsSited {
get { return IsSitedComponent(component); }
}
/// <summary>
/// Gets the child objects that need to be stored in the generated designer code on the specified object.
/// </summary>
@ -224,21 +232,24 @@ namespace ICSharpCode.PythonBinding @@ -224,21 +232,24 @@ namespace ICSharpCode.PythonBinding
/// For a MenuStrip the child components include the MenuStrip.Items.
/// For a Control the child components include the Control.Controls.
/// </remarks>
public virtual object[] GetChildComponents()
public virtual PythonDesignerComponent[] GetChildComponents()
{
List<object> childComponents = new List<object>();
List<PythonDesignerComponent> components = new List<PythonDesignerComponent>();
foreach (PropertyDescriptor property in GetSerializableContentProperties(component)) {
ICollection collection = property.GetValue(component) as ICollection;
if (collection != null) {
foreach (object childObject in collection) {
IComponent childComponent = childObject as IComponent;
if (IsSitedComponent(childComponent)) {
childComponents.Add(childObject);
if (childComponent != null) {
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(childComponent);
if (designerComponent.IsSited) {
components.Add(designerComponent);
}
}
}
}
}
return childComponents.ToArray();
}
return components.ToArray();
}
/// <summary>
@ -274,9 +285,8 @@ namespace ICSharpCode.PythonBinding @@ -274,9 +285,8 @@ namespace ICSharpCode.PythonBinding
void AppendChildComponentsMethodCalls(PythonCodeBuilder codeBuilder, string[] methods)
{
foreach (IComponent component in GetChildComponents()) {
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(component);
if (designerComponent.component is Control) {
foreach (PythonDesignerComponent designerComponent in GetChildComponents()) {
if (typeof(Control).IsAssignableFrom(designerComponent.GetComponentType())) {
if (designerComponent.HasSitedChildComponents()) {
designerComponent.AppendMethodCalls(codeBuilder, methods);
}
@ -301,7 +311,14 @@ namespace ICSharpCode.PythonBinding @@ -301,7 +311,14 @@ namespace ICSharpCode.PythonBinding
if (i > 0) {
codeBuilder.Append(", ");
}
codeBuilder.Append(PythonPropertyValueAssignment.ToString(parameters[i]));
object currentParameter = parameters[i];
Array array = currentParameter as Array;
if (array != null) {
AppendSystemArray(codeBuilder, array.GetValue(0).GetType().FullName, currentParameter as ICollection);
codeBuilder.DecreaseIndent();
} else {
codeBuilder.Append(PythonPropertyValueAssignment.ToString(currentParameter));
}
}
codeBuilder.Append(")");
codeBuilder.AppendLine();
@ -520,21 +537,19 @@ namespace ICSharpCode.PythonBinding @@ -520,21 +537,19 @@ namespace ICSharpCode.PythonBinding
get { return component; }
}
static bool HasSitedComponents(ICollection items)
static bool HasSitedComponents(PythonDesignerComponent[] components)
{
foreach (object item in items) {
if (IsSitedComponent(item)) {
foreach (PythonDesignerComponent component in components) {
if (component.IsSited) {
return true;
}
}
return false;
}
void AppendCreateChildComponents(PythonCodeBuilder codeBuilder, ICollection childComponents)
void AppendCreateChildComponents(PythonCodeBuilder codeBuilder, PythonDesignerComponent[] childComponents)
{
foreach (object obj in childComponents) {
IComponent component = obj as IComponent;
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(component);
foreach (PythonDesignerComponent designerComponent in childComponents) {
if (designerComponent.IsSited) {
designerComponent.AppendCreateInstance(codeBuilder);
designerComponent.AppendCreateChildComponents(codeBuilder);
@ -561,7 +576,19 @@ namespace ICSharpCode.PythonBinding @@ -561,7 +576,19 @@ namespace ICSharpCode.PythonBinding
static void AppendSystemArray(PythonCodeBuilder codeBuilder, string componentName, string methodName, string typeName, ICollection components)
{
if (components.Count > 0) {
codeBuilder.AppendIndentedLine("self._" + componentName + "." + methodName + "(System.Array[" + typeName + "](");
codeBuilder.AppendIndented("self._" + componentName + "." + methodName + "(");
AppendSystemArray(codeBuilder, typeName, components);
codeBuilder.Append(")");
codeBuilder.AppendLine();
codeBuilder.DecreaseIndent();
}
}
static void AppendSystemArray(PythonCodeBuilder codeBuilder, string typeName, ICollection components)
{
if (components.Count > 0) {
codeBuilder.Append("System.Array[" + typeName + "](");
codeBuilder.AppendLine();
codeBuilder.IncreaseIndent();
int i = 0;
foreach (object component in components) {
@ -581,9 +608,7 @@ namespace ICSharpCode.PythonBinding @@ -581,9 +608,7 @@ namespace ICSharpCode.PythonBinding
}
++i;
}
codeBuilder.Append("]))");
codeBuilder.AppendLine();
codeBuilder.DecreaseIndent();
codeBuilder.Append("])");
}
}
}

10
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerRootComponent.cs

@ -38,8 +38,8 @@ namespace ICSharpCode.PythonBinding @@ -38,8 +38,8 @@ namespace ICSharpCode.PythonBinding
public override void AppendComponent(PythonCodeBuilder codeBuilder)
{
// Add the child components first.
foreach (IComponent component in GetChildComponents()) {
PythonDesignerComponentFactory.CreateDesignerComponent(component).AppendComponent(codeBuilder);
foreach (PythonDesignerComponent component in GetChildComponents()) {
component.AppendComponent(codeBuilder);
}
// Add root component
@ -49,11 +49,11 @@ namespace ICSharpCode.PythonBinding @@ -49,11 +49,11 @@ namespace ICSharpCode.PythonBinding
/// <summary>
/// Gets the child components in reverse order since the forms designer has them reversed.
/// </summary>
public override object[] GetChildComponents()
public override PythonDesignerComponent[] GetChildComponents()
{
object[] components = base.GetChildComponents();
PythonDesignerComponent[] components = base.GetChildComponents();
Array.Reverse(components);
return components;
}
}
}
}

7
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonListViewComponent.cs

@ -58,6 +58,13 @@ namespace ICSharpCode.PythonBinding @@ -58,6 +58,13 @@ namespace ICSharpCode.PythonBinding
/// </remarks>
object[] GetConstructorParameters(ListViewItem item)
{
if (item.SubItems.Count > 1) {
string[] subItems = new string[item.SubItems.Count];
for (int i = 0; i < item.SubItems.Count; ++i) {
subItems[i] = item.SubItems[i].Text;
}
return new object[] {subItems};
}
if (String.IsNullOrEmpty(item.Text)) {
return new object[0];
}

57
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializerConstructorStringArrayTestFixture.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
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
{
/// <summary>
/// Tests that the constructor arguments are returned when the first argument is
/// an array.
/// </summary>
[TestFixture]
public class DeserializeConstructorStringArrayTestFixture
{
string code = "System.Windows.Forms.ListViewItem(System.Array[System.String](\r\n" +
" [\"a\",\r\n" +
" \"sa\",\r\n" +
" \"sa2\"]))\r\n";
List<object> args;
[TestFixtureSetUp]
public void SetUpFixture()
{
MockComponentCreator componentCreator = new MockComponentCreator();
CallExpression callExpression = PythonParserHelper.GetCallExpression(code);
PythonCodeDeserializer deserializer = new PythonCodeDeserializer(componentCreator);
args = deserializer.GetArguments(callExpression);
}
[Test]
public void OneArgument()
{
Assert.AreEqual(1, args.Count);
}
[Test]
public void ArgumentIsStringArray()
{
string[] array = new string[0];
Assert.IsInstanceOfType(array.GetType(), args[0]);
}
}
}

6
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAcceptButtonFormTestFixture.cs

@ -22,8 +22,8 @@ namespace PythonBinding.Tests.Designer @@ -22,8 +22,8 @@ namespace PythonBinding.Tests.Designer
public class GenerateAcceptButtonFormTestFixture
{
string generatedPythonCode;
object[] formChildComponents;
object[] buttonChildComponents;
PythonDesignerComponent[] formChildComponents;
PythonDesignerComponent[] buttonChildComponents;
[TestFixtureSetUp]
public void SetUpFixture()
@ -92,7 +92,7 @@ namespace PythonBinding.Tests.Designer @@ -92,7 +92,7 @@ namespace PythonBinding.Tests.Designer
[Test]
public void FormChildComponentIsButton()
{
Assert.IsInstanceOfType(typeof(Button), formChildComponents[0]);
Assert.AreEqual(typeof(Button), formChildComponents[0].GetComponentType());
}
[Test]

6
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs

@ -27,7 +27,7 @@ namespace PythonBinding.Tests.Designer @@ -27,7 +27,7 @@ namespace PythonBinding.Tests.Designer
string suspendLayoutCode;
string resumeLayoutCode;
string listViewPropertiesCode;
object[] listViewChildComponents;
PythonDesignerComponent[] listViewChildComponents;
ColumnHeader columnHeader1;
ColumnHeader columnHeader2;
@ -191,8 +191,8 @@ namespace PythonBinding.Tests.Designer @@ -191,8 +191,8 @@ namespace PythonBinding.Tests.Designer
[Test]
public void ListViewChildComponentAreColumnHeaders()
{
object[] expectedChildComponents = new object[] {columnHeader1, columnHeader2};
Assert.AreEqual(expectedChildComponents, listViewChildComponents);
Assert.AreEqual(typeof(ColumnHeader), listViewChildComponents[0].GetComponentType());
Assert.AreEqual(typeof(ColumnHeader), listViewChildComponents[1].GetComponentType());
}
[Test]

98
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewSubItemsTestFixture.cs

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
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 GenerateListViewSubItemsTestFixture
{
string createListViewCode;
ColumnHeader columnHeader1;
ColumnHeader columnHeader2;
[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);
descriptor = descriptors.Find("View", false);
descriptor.SetValue(listView, View.Details);
form.Controls.Add(listView);
// Add column headers.
columnHeader1 = (ColumnHeader)host.CreateComponent(typeof(ColumnHeader), "columnHeader1");
descriptors = TypeDescriptor.GetProperties(columnHeader1);
descriptor = descriptors.Find("Text", false);
descriptor.SetValue(columnHeader1, "columnHeader1");
listView.Columns.Add(columnHeader1);
columnHeader2 = (ColumnHeader)host.CreateComponent(typeof(ColumnHeader), "columnHeader2");
descriptors = TypeDescriptor.GetProperties(columnHeader2);
descriptor = descriptors.Find("Text", false);
descriptor.SetValue(columnHeader2, "columnHeader2");
listView.Columns.Add(columnHeader2);
// Add list view item with 3 sub items.
ListViewItem item = new ListViewItem("listItem1");
item.SubItems.Add("subItem1");
item.SubItems.Add("subItem2");
item.SubItems.Add("subItem3");
listView.Items.Add(item);
// Get list view creation code.
PythonCodeBuilder codeBuilder = new PythonCodeBuilder();
codeBuilder.IndentString = " ";
PythonListViewComponent listViewComponent = new PythonListViewComponent(listView);
listViewComponent.AppendCreateInstance(codeBuilder);
createListViewCode = codeBuilder.ToString();
}
}
/// <summary>
/// Should include the column header and list view item creation.
/// </summary>
[Test]
public void ListViewCreationCode()
{
string expectedCode = "listViewItem1 = System.Windows.Forms.ListViewItem(System.Array[System.String](\r\n" +
" [\"listItem1\",\r\n" +
" \"subItem1\",\r\n" +
" \"subItem2\",\r\n" +
" \"subItem3\"]))\r\n" +
"self._listView1 = System.Windows.Forms.ListView()\r\n";
Assert.AreEqual(expectedCode, createListViewCode, createListViewCode);
}
}
}

33
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs

@ -26,8 +26,6 @@ namespace PythonBinding.Tests.Designer @@ -26,8 +26,6 @@ namespace PythonBinding.Tests.Designer
Size openMenuItemSize;
Size exitMenuItemSize;
Size editMenuItemSize;
object[] menuStripChildComponents;
object[] fileMenuItemChildComponents;
[TestFixtureSetUp]
public void SetUpFixture()
@ -79,9 +77,6 @@ namespace PythonBinding.Tests.Designer @@ -79,9 +77,6 @@ namespace PythonBinding.Tests.Designer
PythonControl pythonForm = new PythonControl(" ");
generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
menuStripChildComponents = PythonDesignerComponentFactory.CreateDesignerComponent(menuStrip).GetChildComponents();
fileMenuItemChildComponents = PythonDesignerComponentFactory.CreateDesignerComponent(fileMenuItem).GetChildComponents();
}
}
@ -147,33 +142,7 @@ namespace PythonBinding.Tests.Designer @@ -147,33 +142,7 @@ namespace PythonBinding.Tests.Designer
Assert.AreEqual(expectedCode, generatedPythonCode, generatedPythonCode);
}
[Test]
public void MenuStripHasTwoChildComponents()
{
Assert.AreEqual(2, menuStripChildComponents.Length);
}
[Test]
public void MenuStripFirstChildIsFileMenuItem()
{
ToolStripMenuItem fileMenuItem = menuStripChildComponents[0] as ToolStripMenuItem;
Assert.AreEqual("&File", fileMenuItem.Text);
}
[Test]
public void FileMenuItemHasTwoChildComponents()
{
Assert.AreEqual(2, fileMenuItemChildComponents.Length);
}
[Test]
public void FileMenuItemFirstChildIsOpenFileMenuItem()
{
ToolStripMenuItem openMenuItem = fileMenuItemChildComponents[0] as ToolStripMenuItem;
Assert.AreEqual("&Open", openMenuItem.Text);
}
string SizeToString(Size size)
{
return PythonPropertyValueAssignment.ToString(size);

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

@ -151,6 +151,7 @@ @@ -151,6 +151,7 @@
<Compile Include="Designer\DeserializeColorFromArgbTestFixture.cs" />
<Compile Include="Designer\DeserializeComponentAssignmentTestFixture.cs" />
<Compile Include="Designer\DeserializeLocalVariableTestFixture.cs" />
<Compile Include="Designer\DeserializerConstructorStringArrayTestFixture.cs" />
<Compile Include="Designer\DeserializeStringArrayTestFixture.cs" />
<Compile Include="Designer\DeserializeToolStripItemArrayTestFixture.cs" />
<Compile Include="Designer\EnabledSetUsingPropertyDescriptorTestFixture.cs" />
@ -172,6 +173,7 @@ @@ -172,6 +173,7 @@
<Compile Include="Designer\GenerateFormPaddingTestFixture.cs" />
<Compile Include="Designer\GenerateImeModeFormTestFixture.cs" />
<Compile Include="Designer\GenerateListViewItemTestFixture.cs" />
<Compile Include="Designer\GenerateListViewSubItemsTestFixture.cs" />
<Compile Include="Designer\GenerateMenuStripFormTestFixture.cs" />
<Compile Include="Designer\GenerateMenuStripItemsTestFixture.cs" />
<Compile Include="Designer\GenerateMinSizeFormTestFixture.cs" />

3
src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt

@ -93,4 +93,5 @@ def main(args): @@ -93,4 +93,5 @@ def main(args):
* Look at fixing the compiled exe so it can be run from a different folder.
See http://lists.ironpython.com/pipermail/users-ironpython.com/2009-April/009993.html
* Support for ListViewSubItems - Font, Colors.
Loading…
Cancel
Save