Browse Source

Added support for ContextMenuStrips in the python forms designer.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4145 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 17 years ago
parent
commit
bbe48609ab
  1. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
  2. 20
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
  3. 43
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs
  4. 11
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
  5. 30
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonContextMenuComponent.cs
  6. 23
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs
  7. 108
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs
  8. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponentFactory.cs
  9. 72
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerRootComponent.cs
  10. 3
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonListViewComponent.cs
  11. 17
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateBackgroundWorkerTestFixture.cs
  12. 105
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateContextMenuStripTestFixture.cs
  13. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateEventLogTestFixture.cs
  14. 10
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateListViewItemTestFixture.cs
  15. 8
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs
  16. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs
  17. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs
  18. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateSimpleFormTestFixture.cs
  19. 17
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateTimerTestFixture.cs
  20. 18
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratedControlOrderingTestFixture.cs
  21. 16
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs
  22. 28
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs
  23. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs
  24. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  25. 7
      src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt
  26. 19
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedToolStripMenuItem.cs

1
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj

@ -87,6 +87,7 @@ @@ -87,6 +87,7 @@
<Compile Include="Src\PythonConsoleCompletionDataProvider.cs" />
<Compile Include="Src\PythonConsoleHost.cs" />
<Compile Include="Src\PythonConsolePad.cs" />
<Compile Include="Src\PythonContextMenuComponent.cs" />
<Compile Include="Src\PythonControlFieldExpression.cs" />
<Compile Include="Src\PythonDesignerComponent.cs" />
<Compile Include="Src\PythonDesignerComponentFactory.cs" />

20
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs

@ -1476,25 +1476,7 @@ namespace ICSharpCode.PythonBinding @@ -1476,25 +1476,7 @@ namespace ICSharpCode.PythonBinding
return (assignmentExpression.Op == AssignmentOperatorType.Subtract) &&
(assignmentExpression.Left is MemberReferenceExpression);
}
/// <summary>
/// Creates an assign statement with the right hand side of the assignment using a binary operator.
/// </summary>
object CreateAssignmentStatementWithBinaryOperatorExpression(AssignmentExpression assignmentExpression, string binaryOperatorType)
{
// Create the left hand side of the assignment.
assignmentExpression.Left.AcceptVisitor(this, null);
Append(" = ");
// Create the right hand side of the assignment.
assignmentExpression.Left.AcceptVisitor(this, null);
Append(" " + binaryOperatorType + " ");
assignmentExpression.Right.AcceptVisitor(this, null);
return null;
}
void Append(string code)
{
codeBuilder.Append(code);

43
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.ComponentModel;
using System.Text;
namespace ICSharpCode.PythonBinding
@ -15,6 +16,7 @@ namespace ICSharpCode.PythonBinding @@ -15,6 +16,7 @@ namespace ICSharpCode.PythonBinding
StringBuilder codeBuilder = new StringBuilder();
string indentString = "\t";
int indent;
bool insertedCreateComponentsContainer;
public PythonCodeBuilder()
{
@ -62,12 +64,38 @@ namespace ICSharpCode.PythonBinding @@ -62,12 +64,38 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public void AppendIndented(string text)
{
for (int i = 0; i < indent; ++i) {
codeBuilder.Append(indentString);
}
codeBuilder.Append(GetIndentString());
codeBuilder.Append(text);
}
/// <summary>
/// Inserts a new line at the start of the code before everything else.
/// </summary>
public void InsertIndentedLine(string text)
{
text = GetIndentString() + text + "\r\n";
codeBuilder.Insert(0, text, 1);
}
/// <summary>
/// Inserts the following line of code before all the other lines of code:
///
/// "self._components = System.ComponentModel.Container()"
///
/// This line will only be inserted once. Multiple calls to this method will only result in one
/// line of code being inserted.
/// </summary>
public void InsertCreateComponentsContainer()
{
if (!insertedCreateComponentsContainer) {
InsertIndentedLine("self._components = " + typeof(Container).FullName + "()");
insertedCreateComponentsContainer = true;
}
}
/// <summary>
/// Inserts the text with a carriage return and newline at the end.
/// </summary>
public void AppendIndentedLine(string text)
{
AppendIndented(text + "\r\n");
@ -93,5 +121,14 @@ namespace ICSharpCode.PythonBinding @@ -93,5 +121,14 @@ namespace ICSharpCode.PythonBinding
public int Length {
get { return codeBuilder.Length; }
}
string GetIndentString()
{
StringBuilder currentIndentString = new StringBuilder();
for (int i = 0; i < indent; ++i) {
currentIndentString.Append(indentString);
}
return currentIndentString.ToString();
}
}
}

11
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs

@ -283,16 +283,7 @@ namespace ICSharpCode.PythonBinding @@ -283,16 +283,7 @@ namespace ICSharpCode.PythonBinding
/// </summary>
object GetPropertyValueFromAssignmentRhs(MemberExpression memberExpression)
{
object propertyValue = deserializer.Deserialize(memberExpression);
if (propertyValue == null) {
PythonControlFieldExpression field = PythonControlFieldExpression.Create(memberExpression);
if (field.MemberName.Length > 0) {
propertyValue = GetComponent(PythonControlFieldExpression.GetVariableName(field.MemberName));
} else {
propertyValue = field.FullMemberName;
}
}
return propertyValue;
return deserializer.Deserialize(memberExpression);
}
/// <summary>

30
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonContextMenuComponent.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
// <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.ComponentModel;
namespace ICSharpCode.PythonBinding
{
public class PythonContextMenuComponent : PythonDesignerComponent
{
public PythonContextMenuComponent(PythonDesignerComponent parent, IComponent component)
: base(parent, component)
{
}
/// <summary>
/// Always ignore the OwnerItem property. This is set if the context menu is open and displayed in
/// the designer when the user switches to the source tab. This method works around the problem by
/// ignoring the OwnerItem property when generating the form designer code.
/// </summary>
protected override bool IgnoreProperty(PropertyDescriptor property)
{
return property.Name == "OwnerItem";
}
}
}

23
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs

@ -43,15 +43,19 @@ namespace ICSharpCode.PythonBinding @@ -43,15 +43,19 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public string GenerateInitializeComponentMethod(Control control)
{
PythonCodeBuilder methodCodeBuilder = new PythonCodeBuilder();
methodCodeBuilder.IndentString = indentString;
methodCodeBuilder.AppendIndentedLine("def InitializeComponent(self):");
codeBuilder = new PythonCodeBuilder();
codeBuilder.IndentString = indentString;
codeBuilder.AppendIndentedLine("def InitializeComponent(self):");
codeBuilder.IncreaseIndent();
GenerateInitializeComponentMethodBodyInternal(control);
return codeBuilder.ToString();
methodCodeBuilder.Append(codeBuilder.ToString());
return methodCodeBuilder.ToString();
}
/// <summary>
@ -73,20 +77,13 @@ namespace ICSharpCode.PythonBinding @@ -73,20 +77,13 @@ namespace ICSharpCode.PythonBinding
void GenerateInitializeComponentMethodBodyInternal(Control control)
{
PythonDesignerRootComponent rootDesignerComponent = PythonDesignerComponentFactory.CreateDesignerRootComponent(control);
if (rootDesignerComponent.HasNonVisualChildComponents()) {
rootDesignerComponent.AppendCreateComponentsContainer(codeBuilder);
rootDesignerComponent.AppendCreateNonVisualComponents(codeBuilder);
rootDesignerComponent.AppendNonVisualComponentsBeginInit(codeBuilder);
}
rootDesignerComponent.AppendCreateChildComponents(codeBuilder);
rootDesignerComponent.AppendCreateContainerComponents(codeBuilder);
rootDesignerComponent.AppendNonVisualComponentsBeginInit(codeBuilder);
rootDesignerComponent.AppendChildComponentsSuspendLayout(codeBuilder);
rootDesignerComponent.AppendSuspendLayout(codeBuilder);
rootDesignerComponent.AppendNonVisualComponents(codeBuilder);
rootDesignerComponent.AppendComponent(codeBuilder);
rootDesignerComponent.AppendChildComponentsResumeLayout(codeBuilder);
if (rootDesignerComponent.HasNonVisualChildComponents()) {
rootDesignerComponent.AppendNonVisualComponentsEndInit(codeBuilder);
}
rootDesignerComponent.AppendNonVisualComponentsEndInit(codeBuilder);
rootDesignerComponent.AppendResumeLayout(codeBuilder);
}
}

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

@ -213,13 +213,18 @@ namespace ICSharpCode.PythonBinding @@ -213,13 +213,18 @@ namespace ICSharpCode.PythonBinding
}
return null;
}
/// <summary>
/// Appends code that creates an instance of the component.
/// </summary>
public virtual void AppendCreateInstance(PythonCodeBuilder codeBuilder)
{
AppendComponentCreation(codeBuilder, component);
if (HasIContainerConstructor()) {
codeBuilder.InsertCreateComponentsContainer();
AppendCreateInstance(codeBuilder, "self._components");
} else {
AppendComponentCreation(codeBuilder, component);
}
}
public void AppendCreateInstance(PythonCodeBuilder codeBuilder, string parameters)
@ -235,13 +240,34 @@ namespace ICSharpCode.PythonBinding @@ -235,13 +240,34 @@ namespace ICSharpCode.PythonBinding
AppendCreateChildComponents(codeBuilder, GetChildComponents());
}
/// <summary>
/// Adds all the components that have been added to the design surface container.
/// </summary>
public void AppendCreateContainerComponents(PythonCodeBuilder codeBuilder)
{
AppendCreateChildComponents(codeBuilder, GetContainerComponents());
}
/// <summary>
/// Gets all the components added to the design surface container excluding the
/// root component.
/// </summary>
public PythonDesignerComponent[] GetContainerComponents()
{
List<PythonDesignerComponent> components = new List<PythonDesignerComponent>();
ComponentCollection containerComponents = Component.Site.Container.Components;
for (int i = 1; i < containerComponents.Count; ++i) {
components.Add(PythonDesignerComponentFactory.CreateDesignerComponent(this, containerComponents[i]));
}
return components.ToArray();
}
/// <summary>
/// Appends the component's properties.
/// </summary>
public virtual void AppendComponent(PythonCodeBuilder codeBuilder)
{
AppendComponentProperties(codeBuilder);
AppendChildComponentProperties(codeBuilder);
}
/// <summary>
@ -365,37 +391,15 @@ namespace ICSharpCode.PythonBinding @@ -365,37 +391,15 @@ namespace ICSharpCode.PythonBinding
{
codeBuilder.AppendIndentedLine("self._" + component.Site.Name + " = " + component.GetType().FullName + "(" + parameters + ")");
}
/// <summary>
/// Generates the code for the component's properties.
/// </summary>
public void AppendComponentProperties(PythonCodeBuilder codeBuilder)
{
AppendComponentProperties(codeBuilder, true, false, true);
AppendComponentProperties(codeBuilder, true, true);
}
/// <summary>
/// Appends the properties of any component that is contained in a collection property that is
/// marked as DesignerSerializationVisibility.Content.
/// </summary>
public void AppendChildComponentProperties(PythonCodeBuilder codeBuilder)
{
foreach (PropertyDescriptor property in PythonDesignerComponent.GetSerializableContentProperties(component)) {
object propertyCollection = property.GetValue(component);
ICollection collection = propertyCollection as ICollection;
if (collection != null) {
foreach (object childObject in collection) {
IComponent childComponent = childObject as IComponent;
if (childComponent != null) {
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(this, childComponent);
if (designerComponent.IsSited) {
designerComponent.AppendComponentProperties(codeBuilder, true, true, true);
}
}
}
}
}
}
/// <summary>
/// Generates python code for an object's properties when the object is not an IComponent.
/// </summary>
@ -443,6 +447,14 @@ namespace ICSharpCode.PythonBinding @@ -443,6 +447,14 @@ namespace ICSharpCode.PythonBinding
return typeName[0].ToString().ToLowerInvariant() + typeName.Substring(1) + count;
}
/// <summary>
/// Appends an array as a parameter and its associated method call.
/// </summary>
public virtual void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor)
{
AppendMethodCallWithArrayParameter(codeBuilder, propertyOwnerName, propertyOwner, propertyDescriptor, false);
}
/// <summary>
/// Appends an array as a parameter and its associated method call.
/// </summary>
@ -450,7 +462,7 @@ namespace ICSharpCode.PythonBinding @@ -450,7 +462,7 @@ namespace ICSharpCode.PythonBinding
/// Looks for the AddRange method first. If that does not exist or is hidden from the designer the
/// Add method is looked for.
/// </remarks>
public static void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor)
public static void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor, bool reverse)
{
IComponent component = propertyOwner as IComponent;
ICollection collectionProperty = propertyDescriptor.GetValue(propertyOwner) as ICollection;
@ -462,6 +474,9 @@ namespace ICSharpCode.PythonBinding @@ -462,6 +474,9 @@ namespace ICSharpCode.PythonBinding
} else {
MethodInfo addMethod = GetAddSerializationMethod(collectionProperty);
ParameterInfo[] parameters = addMethod.GetParameters();
if (reverse) {
collectionProperty = ReverseCollection(collectionProperty);
}
foreach (object item in collectionProperty) {
IComponent collectionComponent = item as IComponent;
if (PythonDesignerComponent.IsSitedComponent(collectionComponent)) {
@ -477,11 +492,7 @@ namespace ICSharpCode.PythonBinding @@ -477,11 +492,7 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public void AppendProperty(PythonCodeBuilder codeBuilder, string propertyOwnerName, object obj, PropertyDescriptor propertyDescriptor)
{
object propertyValue = propertyDescriptor.GetValue(obj);
if (propertyValue == null) {
return;
}
object propertyValue = propertyDescriptor.GetValue(obj);
ExtenderProvidedPropertyAttribute extender = GetExtenderAttribute(propertyDescriptor);
if (extender != null) {
AppendExtenderProperty(codeBuilder, propertyOwnerName, extender, propertyDescriptor, propertyValue);
@ -521,7 +532,9 @@ namespace ICSharpCode.PythonBinding @@ -521,7 +532,9 @@ namespace ICSharpCode.PythonBinding
public void AppendProperties(PythonCodeBuilder codeBuilder, string propertyOwnerName, object obj)
{
foreach (PropertyDescriptor property in GetSerializableProperties(obj)) {
AppendProperty(codeBuilder, propertyOwnerName, obj, property);
if (!IgnoreProperty(property)) {
AppendProperty(codeBuilder, propertyOwnerName, obj, property);
}
}
}
@ -536,7 +549,7 @@ namespace ICSharpCode.PythonBinding @@ -536,7 +549,7 @@ namespace ICSharpCode.PythonBinding
/// <summary>
/// Generates python code for the component.
/// </summary>
public void AppendComponentProperties(PythonCodeBuilder codeBuilder, bool addComponentNameToProperty, bool addChildComponentProperties, bool addComment)
public void AppendComponentProperties(PythonCodeBuilder codeBuilder, bool addComponentNameToProperty, bool addComment)
{
PythonCodeBuilder propertiesBuilder = new PythonCodeBuilder(codeBuilder.Indent);
propertiesBuilder.IndentString = codeBuilder.IndentString;
@ -549,10 +562,6 @@ namespace ICSharpCode.PythonBinding @@ -549,10 +562,6 @@ namespace ICSharpCode.PythonBinding
AppendComment(codeBuilder);
}
codeBuilder.Append(propertiesBuilder.ToString());
if (addChildComponentProperties) {
AppendChildComponentProperties(codeBuilder);
}
}
/// <summary>
@ -611,6 +620,14 @@ namespace ICSharpCode.PythonBinding @@ -611,6 +620,14 @@ namespace ICSharpCode.PythonBinding
get { return component; }
}
/// <summary>
/// Return true to prevent the property from being added to the generated code.
/// </summary>
protected virtual bool IgnoreProperty(PropertyDescriptor property)
{
return false;
}
static bool HasSitedComponents(PythonDesignerComponent[] components)
{
foreach (PythonDesignerComponent component in components) {
@ -626,7 +643,6 @@ namespace ICSharpCode.PythonBinding @@ -626,7 +643,6 @@ namespace ICSharpCode.PythonBinding
foreach (PythonDesignerComponent designerComponent in childComponents) {
if (designerComponent.IsSited) {
designerComponent.AppendCreateInstance(codeBuilder);
designerComponent.AppendCreateChildComponents(codeBuilder);
}
}
}
@ -724,5 +740,15 @@ namespace ICSharpCode.PythonBinding @@ -724,5 +740,15 @@ namespace ICSharpCode.PythonBinding
}
return null;
}
static ICollection ReverseCollection(ICollection collection)
{
List<object> reversedCollection = new List<object>();
foreach (object item in collection) {
reversedCollection.Add(item);
}
reversedCollection.Reverse();
return reversedCollection;
}
}
}

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponentFactory.cs

@ -31,7 +31,9 @@ namespace ICSharpCode.PythonBinding @@ -31,7 +31,9 @@ namespace ICSharpCode.PythonBinding
public static PythonDesignerComponent CreateDesignerComponent(PythonDesignerComponent parent, IComponent component)
{
if (component is ListView) {
return new PythonListViewComponent(parent,component);
return new PythonListViewComponent(parent, component);
} else if (component is ContextMenuStrip) {
return new PythonContextMenuComponent(parent, component);
}
return new PythonDesignerComponent(parent, component);
}

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

@ -41,37 +41,14 @@ namespace ICSharpCode.PythonBinding @@ -41,37 +41,14 @@ namespace ICSharpCode.PythonBinding
public override void AppendComponent(PythonCodeBuilder codeBuilder)
{
// Add the child components first.
foreach (PythonDesignerComponent component in GetChildComponents()) {
foreach (PythonDesignerComponent component in GetContainerComponents()) {
component.AppendComponent(codeBuilder);
}
// Add root component
AppendComponentProperties(codeBuilder, false, false, true);
AppendComponentProperties(codeBuilder, false, true);
}
/// <summary>
/// Gets the child components in reverse order since the forms designer has them reversed.
/// </summary>
public override PythonDesignerComponent[] GetChildComponents()
{
PythonDesignerComponent[] components = base.GetChildComponents();
Array.Reverse(components);
return components;
}
/// <summary>
/// Returns true if non-visual components (e.g. Timer) are associated with this root component.
/// </summary>
public bool HasNonVisualChildComponents()
{
foreach (IComponent containerComponent in Component.Site.Container.Components) {
if (IsNonVisualComponent(containerComponent)) {
return true;
}
}
return false;
}
public PythonDesignerComponent[] GetNonVisualChildComponents()
{
List<PythonDesignerComponent> components = new List<PythonDesignerComponent>();
@ -83,39 +60,7 @@ namespace ICSharpCode.PythonBinding @@ -83,39 +60,7 @@ namespace ICSharpCode.PythonBinding
}
return components.ToArray();
}
/// <summary>
/// Appends an expression that creates an instance of the Container to hold non-visual components
/// </summary>
public void AppendCreateComponentsContainer(PythonCodeBuilder codeBuilder)
{
codeBuilder.AppendIndentedLine("self._components = " + typeof(Container).FullName + "()");
}
/// <summary>
/// Appends code to create all the non-visual component.
/// </summary>
public void AppendCreateNonVisualComponents(PythonCodeBuilder codeBuilder)
{
foreach (PythonDesignerComponent component in GetNonVisualChildComponents()) {
if (component.HasIContainerConstructor()) {
component.AppendCreateInstance(codeBuilder, "self._components");
} else {
component.AppendCreateInstance(codeBuilder);
}
}
}
/// <summary>
/// Appends code to set all the non-visual component properties.
/// </summary>
public void AppendNonVisualComponents(PythonCodeBuilder codeBuilder)
{
foreach (PythonDesignerComponent component in GetNonVisualChildComponents()) {
component.AppendComponent(codeBuilder);
}
}
/// <summary>
/// Adds BeginInit method call for any non-visual components that implement the
/// System.ComponentModel.ISupportInitialize interface.
@ -142,5 +87,14 @@ namespace ICSharpCode.PythonBinding @@ -142,5 +87,14 @@ namespace ICSharpCode.PythonBinding
}
}
}
/// <summary>
/// Reverses the ordering when adding items to the Controls collection.
/// </summary>
public override void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor)
{
bool reverse = propertyDescriptor.Name == "Controls";
AppendMethodCallWithArrayParameter(codeBuilder, propertyOwnerName, propertyOwner, propertyDescriptor, reverse);
}
}
}

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

@ -48,8 +48,7 @@ namespace ICSharpCode.PythonBinding @@ -48,8 +48,7 @@ namespace ICSharpCode.PythonBinding
{
AppendComment(codeBuilder);
AppendListViewItemProperties(codeBuilder);
AppendComponentProperties(codeBuilder, true, false, false);
AppendChildComponentProperties(codeBuilder);
AppendComponentProperties(codeBuilder, true, false);
}
/// <summary>

17
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateBackgroundWorkerTestFixture.cs

@ -20,7 +20,6 @@ namespace PythonBinding.Tests.Designer @@ -20,7 +20,6 @@ namespace PythonBinding.Tests.Designer
public class GenerateBackgroundWorkerTestFixture
{
string generatedPythonCode;
bool hasNonVisualChildComponents;
bool hasIContainerConstructor;
[TestFixtureSetUp]
@ -40,29 +39,19 @@ namespace PythonBinding.Tests.Designer @@ -40,29 +39,19 @@ namespace PythonBinding.Tests.Designer
propertyDescriptor = descriptors.Find("WorkerReportsProgress", false);
propertyDescriptor.SetValue(worker, true);
string indentString = " ";
PythonDesignerRootComponent designerRootComponent = new PythonDesignerRootComponent(form);
hasNonVisualChildComponents = designerRootComponent.HasNonVisualChildComponents();
PythonDesignerComponent component = new PythonDesignerComponent(worker);
hasIContainerConstructor = component.HasIContainerConstructor();
string indentString = " ";
PythonControl pythonControl = new PythonControl(indentString);
generatedPythonCode = pythonControl.GenerateInitializeComponentMethod(form);
}
}
[Test]
public void HasNonVisualChildComponents()
{
Assert.IsTrue(hasNonVisualChildComponents);
}
[Test]
public void GeneratedCode()
{
string expectedCode = "def InitializeComponent(self):\r\n" +
" self._components = System.ComponentModel.Container()\r\n" +
" self._backgroundWorker1 = System.ComponentModel.BackgroundWorker()\r\n" +
" self.SuspendLayout()\r\n" +
" # \r\n" +

105
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateContextMenuStripTestFixture.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// <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 GenerateContextMenuStripTestFixture
{
string generatedPythonCode;
string createContextMenuStripCode;
Size menuStripSize;
PythonDesignerComponent contextMenuDesignerComponent;
[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 timer. This checks that the components Container is only created once in the
// generated code.
Timer timer = (Timer)host.CreateComponent(typeof(Timer), "timer1");
// Add menu strip.
ContextMenuStrip menuStrip = (ContextMenuStrip)host.CreateComponent(typeof(ContextMenuStrip), "contextMenuStrip1");
// Set the context menu strip OwnerItem to simulate leaving the context menu
// open in the designer before generating the source code. We do not want the
// OwnerItem to be serialized.
menuStrip.OwnerItem = new DerivedToolStripMenuItem();
menuStrip.RightToLeft = RightToLeft.No;
menuStripSize = menuStrip.Size;
PythonControl pythonForm = new PythonControl(" ");
generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
PythonCodeBuilder codeBuilder = new PythonCodeBuilder();
contextMenuDesignerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(menuStrip);
contextMenuDesignerComponent.AppendCreateInstance(codeBuilder);
createContextMenuStripCode = codeBuilder.ToString();
}
}
[Test]
public void GeneratedCode()
{
string expectedCode = "def InitializeComponent(self):\r\n" +
" self._components = System.ComponentModel.Container()\r\n" +
" self._timer1 = System.Windows.Forms.Timer(self._components)\r\n" +
" self._contextMenuStrip1 = System.Windows.Forms.ContextMenuStrip(self._components)\r\n" +
" self.SuspendLayout()\r\n" +
" # \r\n" +
" # contextMenuStrip1\r\n" +
" # \r\n" +
" self._contextMenuStrip1.Name = \"contextMenuStrip1\"\r\n" +
" self._contextMenuStrip1.Size = " + PythonPropertyValueAssignment.ToString(menuStripSize) + "\r\n" +
" # \r\n" +
" # MainForm\r\n" +
" # \r\n" +
" self.ClientSize = System.Drawing.Size(200, 300)\r\n" +
" self.Name = \"MainForm\"\r\n" +
" self.ResumeLayout(False)\r\n" +
" self.PerformLayout()\r\n";
Assert.AreEqual(expectedCode, generatedPythonCode, generatedPythonCode);
}
[Test]
public void CreateContextMenuStripCodeUsesIContainerConstructor()
{
string expectedCode = "self._components = System.ComponentModel.Container()\r\n" +
"self._contextMenuStrip1 = System.Windows.Forms.ContextMenuStrip(self._components)\r\n";
Assert.AreEqual(expectedCode, createContextMenuStripCode);
}
[Test]
public void ContextMenuDesignerComponentCreatedFromFactory()
{
Assert.IsInstanceOf(typeof(PythonContextMenuComponent), contextMenuDesignerComponent);
}
}
}

1
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateEventLogTestFixture.cs

@ -47,7 +47,6 @@ namespace PythonBinding.Tests.Designer @@ -47,7 +47,6 @@ namespace PythonBinding.Tests.Designer
public void GeneratedCode()
{
string expectedCode = "def InitializeComponent(self):\r\n" +
" self._components = System.ComponentModel.Container()\r\n" +
" self._eventLog1 = System.Diagnostics.EventLog()\r\n" +
" self._eventLog1.BeginInit()\r\n" +
" self.SuspendLayout()\r\n" +

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

@ -228,15 +228,7 @@ namespace PythonBinding.Tests.Designer @@ -228,15 +228,7 @@ namespace PythonBinding.Tests.Designer
" self._listView1.Name = \"listView1\"\r\n" +
" self._listView1.Size = System.Drawing.Size(204, 104)\r\n" +
" self._listView1.TabIndex = 0\r\n" +
" self._listView1.View = System.Windows.Forms.View.Details\r\n" +
" # \r\n" +
" # columnHeader1\r\n" +
" # \r\n" +
" self._columnHeader1.Text = \"columnHeader1\"\r\n" +
" # \r\n" +
" # columnHeader2\r\n" +
" # \r\n" +
" self._columnHeader2.Text = \"columnHeader2\"\r\n";
" self._listView1.View = System.Windows.Forms.View.Details\r\n";
Assert.AreEqual(expectedCode, listViewPropertiesCode);
}

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

@ -26,7 +26,6 @@ namespace PythonBinding.Tests.Designer @@ -26,7 +26,6 @@ namespace PythonBinding.Tests.Designer
Size openMenuItemSize;
Size exitMenuItemSize;
Size editMenuItemSize;
bool nonVisualComponents;
[TestFixtureSetUp]
public void SetUpFixture()
@ -77,7 +76,6 @@ namespace PythonBinding.Tests.Designer @@ -77,7 +76,6 @@ namespace PythonBinding.Tests.Designer
editMenuItemSize = editMenuItem.Size;
PythonDesignerRootComponent rootComponent = new PythonDesignerRootComponent(form);
nonVisualComponents = rootComponent.HasNonVisualChildComponents();
PythonControl pythonForm = new PythonControl(" ");
generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
@ -146,12 +144,6 @@ namespace PythonBinding.Tests.Designer @@ -146,12 +144,6 @@ namespace PythonBinding.Tests.Designer
Assert.AreEqual(expectedCode, generatedPythonCode, generatedPythonCode);
}
[Test]
public void NoNonVisualComponents()
{
Assert.IsFalse(nonVisualComponents);
}
string SizeToString(Size size)
{

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs

@ -107,7 +107,7 @@ namespace PythonBinding.Tests.Designer @@ -107,7 +107,7 @@ namespace PythonBinding.Tests.Designer
" self.ResumeLayout(False)\r\n" +
" self.PerformLayout()\r\n";
Assert.AreEqual(expectedCode, generatedPythonCode);
Assert.AreEqual(expectedCode, generatedPythonCode, generatedPythonCode);
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs

@ -94,7 +94,7 @@ namespace PythonBinding.Tests.Designer @@ -94,7 +94,7 @@ namespace PythonBinding.Tests.Designer
" self.ResumeLayout(False)\r\n" +
" self.PerformLayout()\r\n";
Assert.AreEqual(expectedCode, generatedPythonCode);
Assert.AreEqual(expectedCode, generatedPythonCode, generatedPythonCode);
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateSimpleFormTestFixture.cs

@ -44,7 +44,7 @@ namespace PythonBinding.Tests.Designer @@ -44,7 +44,7 @@ namespace PythonBinding.Tests.Designer
codeBuilder.IncreaseIndent();
PythonDesignerRootComponent designerRootComponent = new PythonDesignerRootComponent(form);
propertyOwnerName = designerRootComponent.GetPropertyOwnerName();
designerRootComponent.AppendComponentProperties(codeBuilder, true, false, false);
designerRootComponent.AppendComponentProperties(codeBuilder, true, false);
formPropertiesCode = codeBuilder.ToString();
}
}

17
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateTimerTestFixture.cs

@ -20,8 +20,8 @@ namespace PythonBinding.Tests.Designer @@ -20,8 +20,8 @@ namespace PythonBinding.Tests.Designer
public class GenerateTimerTestFixture
{
string generatedPythonCode;
bool hasNonVisualChildComponents;
bool hasIContainerConstructor;
[TestFixtureSetUp]
public void SetUpFixture()
{
@ -38,25 +38,16 @@ namespace PythonBinding.Tests.Designer @@ -38,25 +38,16 @@ namespace PythonBinding.Tests.Designer
descriptors = TypeDescriptor.GetProperties(timer);
namePropertyDescriptor = descriptors.Find("Interval", false);
namePropertyDescriptor.SetValue(timer, 1000);
string indentString = " ";
PythonDesignerRootComponent designerRootComponent = new PythonDesignerRootComponent(form);
hasNonVisualChildComponents = designerRootComponent.HasNonVisualChildComponents();
PythonDesignerComponent component = new PythonDesignerComponent(timer);
hasIContainerConstructor = component.HasIContainerConstructor();
string indentString = " ";
PythonControl pythonControl = new PythonControl(indentString);
generatedPythonCode = pythonControl.GenerateInitializeComponentMethod(form);
}
}
[Test]
public void HasNonVisualChildComponents()
{
Assert.IsTrue(hasNonVisualChildComponents);
}
[Test]
public void GeneratedCode()
{

18
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratedControlOrderingTestFixture.cs

@ -36,17 +36,7 @@ namespace PythonBinding.Tests.Designer @@ -36,17 +36,7 @@ namespace PythonBinding.Tests.Designer
PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
namePropertyDescriptor.SetValue(form, "MainForm");
RadioButton radioButton = (RadioButton)host.CreateComponent(typeof(RadioButton), "radioButton1");
radioButton.Location = new Point(20, 0);
radioButton.Size = new Size(10, 10);
radioButton.Text = "radioButton1";
radioButton.TabIndex = 1;
radioButton.UseCompatibleTextRendering = false;
form.Controls.Add(radioButton);
// Add button after radio button to simulate the forms designer
// behaviour of adding the controls in reverse order to the Controls collection.
Button button = (Button)host.CreateComponent(typeof(Button), "button1");
button.Location = new Point(0, 0);
button.Size = new Size(10, 10);
@ -54,6 +44,14 @@ namespace PythonBinding.Tests.Designer @@ -54,6 +44,14 @@ namespace PythonBinding.Tests.Designer
button.TabIndex = 0;
button.UseCompatibleTextRendering = false;
form.Controls.Add(button);
RadioButton radioButton = (RadioButton)host.CreateComponent(typeof(RadioButton), "radioButton1");
radioButton.Location = new Point(20, 0);
radioButton.Size = new Size(10, 10);
radioButton.Text = "radioButton1";
radioButton.TabIndex = 1;
radioButton.UseCompatibleTextRendering = false;
form.Controls.Add(radioButton);
string indentString = " ";
PythonControl pythonForm = new PythonControl(indentString);

16
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetInstanceFromDesignerLoaderTestFixture.cs

@ -25,6 +25,8 @@ namespace PythonBinding.Tests.Designer @@ -25,6 +25,8 @@ namespace PythonBinding.Tests.Designer
MockDesignerLoaderHost host;
ListViewItem listViewItem1;
object instance;
Type type;
string typeName;
[SetUp]
public void Init()
@ -37,6 +39,8 @@ namespace PythonBinding.Tests.Designer @@ -37,6 +39,8 @@ namespace PythonBinding.Tests.Designer
using (designerSerializationManager.CreateSession()) {
listViewItem1 = (ListViewItem)loader.CreateInstance(typeof(ListViewItem), new object[0], "listViewItem1", false);
instance = loader.GetInstance("listViewItem1");
typeName = typeof(Int32).FullName;
type = loader.GetType(typeName);
}
}
@ -46,5 +50,17 @@ namespace PythonBinding.Tests.Designer @@ -46,5 +50,17 @@ namespace PythonBinding.Tests.Designer
{
Assert.AreEqual(listViewItem1, instance);
}
[Test]
public void GetTypeFromLoader()
{
Assert.AreEqual(typeof(Int32), type);
}
[Test]
public void TypeNameUsed()
{
Assert.AreEqual(typeName, host.TypeResolutionService.LastTypeNameResolved);
}
}
}

28
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeBuilderTests.cs

@ -100,5 +100,33 @@ namespace PythonBinding.Tests.Designer @@ -100,5 +100,33 @@ namespace PythonBinding.Tests.Designer
codeBuilder.AppendIndented("abc");
Assert.AreEqual("\t\tabc", codeBuilder.ToString());
}
[Test]
public void InsertIndentedLine()
{
codeBuilder.IncreaseIndent();
codeBuilder.AppendIndentedLine("def");
codeBuilder.InsertIndentedLine("abc");
Assert.AreEqual("\tabc\r\n\tdef\r\n", codeBuilder.ToString());
}
/// <summary>
/// Check that the "self._components = System.ComponentModel.Container()" line is generated
/// the once and before any other lines of code.
/// </summary>
[Test]
public void AppendCreateComponentsContainerTwice()
{
codeBuilder.IndentString = " ";
codeBuilder.IncreaseIndent();
codeBuilder.AppendIndentedLine("self._listView = System.Windows.Forms.ListView()");
codeBuilder.InsertCreateComponentsContainer();
codeBuilder.InsertCreateComponentsContainer();
string expectedCode = " self._components = System.ComponentModel.Container()\r\n" +
" self._listView = System.Windows.Forms.ListView()\r\n";
Assert.AreEqual(expectedCode, codeBuilder.ToString());
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs

@ -142,7 +142,7 @@ namespace PythonBinding.Tests.Designer @@ -142,7 +142,7 @@ namespace PythonBinding.Tests.Designer
{
Assert.AreEqual(designedForm, loader.RootComponent);
}
/// <summary>
/// The code that the designer loader will parse.
/// </summary>

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

@ -170,6 +170,7 @@ @@ -170,6 +170,7 @@
<Compile Include="Designer\GenerateAutoScrollFormTestFixture.cs" />
<Compile Include="Designer\GenerateBackgroundWorkerTestFixture.cs" />
<Compile Include="Designer\GenerateComboBoxItemsTestFixture.cs" />
<Compile Include="Designer\GenerateContextMenuStripTestFixture.cs" />
<Compile Include="Designer\GenerateCursorFormTestFixture.cs" />
<Compile Include="Designer\GeneratedControlOrderingTestFixture.cs" />
<Compile Include="Designer\GenerateDoubleBufferedFormTestFixture.cs" />
@ -291,6 +292,7 @@ @@ -291,6 +292,7 @@
<Compile Include="Utils\DerivedPythonDesignerGenerator.cs" />
<Compile Include="Utils\DerivedPythonDesignerLoader.cs" />
<Compile Include="Utils\DerivedPythonFormsDesignerDisplayBinding.cs" />
<Compile Include="Utils\DerivedToolStripMenuItem.cs" />
<Compile Include="Utils\MockClass.cs" />
<Compile Include="Utils\MockComponentCreator.cs" />
<Compile Include="Utils\MockDesignerGenerator.cs" />

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

@ -88,7 +88,12 @@ def main(args): @@ -88,7 +88,12 @@ def main(args):
Handle invalid event name.
Check that += operator used.
* ContextMenuStrip - designer does not generate the correct code.
* ContextMenuStrip
If the context menu is added for the first time and left open and displayed on the form when
switching to the source code you see an OwnerItem property added to the context menu variable:
self._contextMenuStrip1.OwnerItem = ContextMenuStrip
* Look at fixing the compiled exe so it can be run from a different folder.

19
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedToolStripMenuItem.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
// <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.Windows.Forms;
namespace PythonBinding.Tests.Utils
{
public class DerivedToolStripMenuItem : ToolStripMenuItem
{
public DerivedToolStripMenuItem() : base()
{
}
}
}
Loading…
Cancel
Save