diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
index 3d61f5ab24..6580e9b3ff 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
@@ -87,6 +87,7 @@
+
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
index 7e870544ea..0b92a7980f 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
@@ -1476,25 +1476,7 @@ namespace ICSharpCode.PythonBinding
return (assignmentExpression.Op == AssignmentOperatorType.Subtract) &&
(assignmentExpression.Left is MemberReferenceExpression);
}
-
- ///
- /// Creates an assign statement with the right hand side of the assignment using a binary operator.
- ///
- 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);
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs
index ef24bb2fe6..fafaf81788 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeBuilder.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.ComponentModel;
using System.Text;
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
///
public void AppendIndented(string text)
{
- for (int i = 0; i < indent; ++i) {
- codeBuilder.Append(indentString);
- }
+ codeBuilder.Append(GetIndentString());
codeBuilder.Append(text);
}
+
+ ///
+ /// Inserts a new line at the start of the code before everything else.
+ ///
+ public void InsertIndentedLine(string text)
+ {
+ text = GetIndentString() + text + "\r\n";
+ codeBuilder.Insert(0, text, 1);
+ }
+ ///
+ /// 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.
+ ///
+ public void InsertCreateComponentsContainer()
+ {
+ if (!insertedCreateComponentsContainer) {
+ InsertIndentedLine("self._components = " + typeof(Container).FullName + "()");
+ insertedCreateComponentsContainer = true;
+ }
+ }
+
+ ///
+ /// Inserts the text with a carriage return and newline at the end.
+ ///
public void AppendIndentedLine(string text)
{
AppendIndented(text + "\r\n");
@@ -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();
+ }
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
index 2d95a8f134..fb2d6ad1b0 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
@@ -283,16 +283,7 @@ namespace ICSharpCode.PythonBinding
///
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);
}
///
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonContextMenuComponent.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonContextMenuComponent.cs
new file mode 100644
index 0000000000..59158b931d
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonContextMenuComponent.cs
@@ -0,0 +1,30 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonContextMenuComponent : PythonDesignerComponent
+ {
+ public PythonContextMenuComponent(PythonDesignerComponent parent, IComponent component)
+ : base(parent, component)
+ {
+ }
+
+ ///
+ /// 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.
+ ///
+ protected override bool IgnoreProperty(PropertyDescriptor property)
+ {
+ return property.Name == "OwnerItem";
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs
index 415c6eb6ae..8d260b9315 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControl.cs
@@ -43,15 +43,19 @@ namespace ICSharpCode.PythonBinding
///
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();
}
///
@@ -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);
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs
index cbc77ab830..8a2628f236 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerComponent.cs
@@ -213,13 +213,18 @@ namespace ICSharpCode.PythonBinding
}
return null;
}
-
+
///
/// Appends code that creates an instance of the component.
///
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
AppendCreateChildComponents(codeBuilder, GetChildComponents());
}
+ ///
+ /// Adds all the components that have been added to the design surface container.
+ ///
+ public void AppendCreateContainerComponents(PythonCodeBuilder codeBuilder)
+ {
+ AppendCreateChildComponents(codeBuilder, GetContainerComponents());
+ }
+
+ ///
+ /// Gets all the components added to the design surface container excluding the
+ /// root component.
+ ///
+ public PythonDesignerComponent[] GetContainerComponents()
+ {
+ List components = new List();
+ ComponentCollection containerComponents = Component.Site.Container.Components;
+ for (int i = 1; i < containerComponents.Count; ++i) {
+ components.Add(PythonDesignerComponentFactory.CreateDesignerComponent(this, containerComponents[i]));
+ }
+ return components.ToArray();
+ }
+
///
/// Appends the component's properties.
///
public virtual void AppendComponent(PythonCodeBuilder codeBuilder)
{
AppendComponentProperties(codeBuilder);
- AppendChildComponentProperties(codeBuilder);
}
///
@@ -365,37 +391,15 @@ namespace ICSharpCode.PythonBinding
{
codeBuilder.AppendIndentedLine("self._" + component.Site.Name + " = " + component.GetType().FullName + "(" + parameters + ")");
}
-
+
///
/// Generates the code for the component's properties.
///
public void AppendComponentProperties(PythonCodeBuilder codeBuilder)
{
- AppendComponentProperties(codeBuilder, true, false, true);
+ AppendComponentProperties(codeBuilder, true, true);
}
-
- ///
- /// Appends the properties of any component that is contained in a collection property that is
- /// marked as DesignerSerializationVisibility.Content.
- ///
- 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);
- }
- }
- }
- }
- }
- }
+
///
/// Generates python code for an object's properties when the object is not an IComponent.
///
@@ -443,6 +447,14 @@ namespace ICSharpCode.PythonBinding
return typeName[0].ToString().ToLowerInvariant() + typeName.Substring(1) + count;
}
+ ///
+ /// Appends an array as a parameter and its associated method call.
+ ///
+ public virtual void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor)
+ {
+ AppendMethodCallWithArrayParameter(codeBuilder, propertyOwnerName, propertyOwner, propertyDescriptor, false);
+ }
+
///
/// Appends an array as a parameter and its associated method call.
///
@@ -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.
///
- 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
} 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
///
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
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
///
/// Generates python code for the component.
///
- 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
AppendComment(codeBuilder);
}
codeBuilder.Append(propertiesBuilder.ToString());
-
- if (addChildComponentProperties) {
- AppendChildComponentProperties(codeBuilder);
- }
}
///
@@ -611,6 +620,14 @@ namespace ICSharpCode.PythonBinding
get { return component; }
}
+ ///
+ /// Return true to prevent the property from being added to the generated code.
+ ///
+ 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
foreach (PythonDesignerComponent designerComponent in childComponents) {
if (designerComponent.IsSited) {
designerComponent.AppendCreateInstance(codeBuilder);
- designerComponent.AppendCreateChildComponents(codeBuilder);
}
}
}
@@ -724,5 +740,15 @@ namespace ICSharpCode.PythonBinding
}
return null;
}
+
+ static ICollection ReverseCollection(ICollection collection)
+ {
+ List