diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
index fbf8798beb..2cf1e3776c 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
@@ -86,7 +86,15 @@
+
+
+
+
+
+
+
+
@@ -102,6 +110,7 @@
+
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoScaleModeProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoScaleModeProperty.cs
new file mode 100644
index 0000000000..adde086cff
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoScaleModeProperty.cs
@@ -0,0 +1,27 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonControlAutoScaleModeProperty : PythonControlProperty
+ {
+ public PythonControlAutoScaleModeProperty()
+ {
+ }
+
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ if (propertyValue is AutoScaleMode) {
+ return (AutoScaleMode)propertyValue == AutoScaleMode.Inherit;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoValidateProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoValidateProperty.cs
new file mode 100644
index 0000000000..bb9064be11
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlAutoValidateProperty.cs
@@ -0,0 +1,30 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ ///
+ /// Represents the AutoValidate property for a Form or ContainerControl.
+ ///
+ public class PythonControlAutoValidateProperty : PythonControlProperty
+ {
+ public PythonControlAutoValidateProperty()
+ {
+ }
+
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ if (propertyValue is AutoValidate) {
+ return (AutoValidate)propertyValue == AutoValidate.EnablePreventFocusChange;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlBooleanProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlBooleanProperty.cs
new file mode 100644
index 0000000000..80970cc8c6
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlBooleanProperty.cs
@@ -0,0 +1,26 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonControlBooleanProperty : PythonControlProperty
+ {
+ bool defaultValue;
+
+ public PythonControlBooleanProperty(bool defaultValue)
+ {
+ this.defaultValue = defaultValue;
+ }
+
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ return (bool)propertyValue == defaultValue;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs
new file mode 100644
index 0000000000..5bfb6425a2
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs
@@ -0,0 +1,135 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ ///
+ /// Contains the default values for all properties on a Control, Form or UserControl.
+ ///
+ public class PythonControlDefaultPropertyValues
+ {
+ Dictionary defaultPropertyValues = new Dictionary();
+
+ public PythonControlDefaultPropertyValues()
+ {
+ defaultPropertyValues.Add("Text", new PythonControlTextProperty());
+ defaultPropertyValues.Add("AutoValidate", new PythonControlAutoValidateProperty());
+ defaultPropertyValues.Add("Enabled", new PythonControlBooleanProperty(true));
+ defaultPropertyValues.Add("AutoScaleMode", new PythonControlAutoScaleModeProperty());
+ defaultPropertyValues.Add("DoubleBuffered", new PythonControlBooleanProperty(false));
+ defaultPropertyValues.Add("ImeMode", new PythonControlImeModeProperty());
+ defaultPropertyValues.Add("RightToLeft", new PythonControlRightToLeftProperty());
+ }
+
+ ///
+ /// Determines if the property value has its default value.
+ ///
+ /// The name of the property.
+ /// The object that has the property.
+ /// False if the property does not exist.
+ public bool IsDefaultValue(string propertyName, object obj)
+ {
+ PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
+ if (propertyInfo != null) {
+ object propertyValue = propertyInfo.GetValue(obj, null);
+ return IsDefaultValue(propertyInfo, propertyValue);
+ }
+ return false;
+ }
+
+ ///
+ /// Determines if the property value is the default value by checking the DefaultValueAttribute.
+ ///
+ /// The property descriptor for the property.
+ /// The object that has the property.
+ ///
+ /// For some properties such as Form.AutoValidate there is no default value specified by the
+ /// DefaultValueAttribute.
+ ///
+ public bool IsDefaultValue(PropertyDescriptor propertyDescriptor, object obj)
+ {
+ PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyDescriptor.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
+ if (propertyInfo != null) {
+ return IsDefaultValue(propertyInfo, propertyDescriptor.GetValue(obj));
+ }
+ return false;
+ }
+
+ ///
+ /// Determines if the property value is the default value by checking the DefaultValueAttribute.
+ ///
+ ///
+ /// For some properties such as Form.AutoValidate there is no default value specified by the
+ /// DefaultValueAttribute.
+ ///
+ public bool IsDefaultValue(PropertyInfo propertyInfo, object propertyValue)
+ {
+ // Check default attribute.
+ DefaultValueAttribute defaultValueAttribute = (DefaultValueAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(DefaultValueAttribute), true);
+ if (defaultValueAttribute != null) {
+ if (defaultValueAttribute.Value != null) {
+ return defaultValueAttribute.Value.Equals(propertyValue);
+ }
+ return defaultValueAttribute.Value == propertyValue;
+ }
+
+ PythonControlProperty controlProperty = null;
+ if (defaultPropertyValues.TryGetValue(propertyInfo.Name, out controlProperty)) {
+ return controlProperty.IsDefaultValue(propertyValue);
+ }
+
+ if (propertyInfo.Name == "BackColor") {
+ // Default is Control.DefaultBackColor
+ return true;
+ } else if (propertyInfo.Name == "Visible") {
+ return true;
+ } else if (propertyInfo.Name == "Icon") {
+ return true;
+ } else if (propertyInfo.Name == "Location") {
+ // 0, 0
+ return true;
+ } else if (propertyInfo.Name == "Margin") {
+ // Padding.DefaultMargin.
+ return true;
+ } else if (propertyInfo.Name == "MinimumSize") {
+ // 0, 0
+ return true;
+ } else if (propertyInfo.Name == "TransparencyKey") {
+ return true;
+ } else if (propertyInfo.Name == "AutoScrollMargin") {
+ return true;
+ } else if (propertyInfo.Name == "AutoScrollMinSize") {
+ return true;
+ } else if (propertyInfo.Name == "HorizontalScroll") {
+ return true;
+ } else if (propertyInfo.Name == "VerticalScroll") {
+ return true;
+ } else if (propertyInfo.Name == "Cursor") {
+ // Cursors.Default
+ return true;
+ } else if (propertyInfo.Name == "Font") {
+ // Default is Control.DefaultFont
+ return true;
+ } else if (propertyInfo.Name == "ForeColor") {
+ // Default is Control.DefaultForeColor
+ return true;
+ } else if (propertyInfo.Name == "Padding") {
+ // Padding.Empty.
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlImeModeProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlImeModeProperty.cs
new file mode 100644
index 0000000000..226ed8ee13
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlImeModeProperty.cs
@@ -0,0 +1,27 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonControlImeModeProperty : PythonControlProperty
+ {
+ public PythonControlImeModeProperty()
+ {
+ }
+
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ if (propertyValue is ImeMode) {
+ return (ImeMode)propertyValue == ImeMode.NoControl;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlProperty.cs
new file mode 100644
index 0000000000..bfa4dcd0f1
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlProperty.cs
@@ -0,0 +1,29 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.PythonBinding
+{
+ ///
+ /// Represents a property on a control or form.
+ ///
+ public abstract class PythonControlProperty
+ {
+ public PythonControlProperty()
+ {
+ }
+
+ ///
+ /// Returns true if the property value matches the default for this control's property.
+ ///
+ public virtual bool IsDefaultValue(object propertyValue)
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlRightToLeftProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlRightToLeftProperty.cs
new file mode 100644
index 0000000000..adb95eb410
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlRightToLeftProperty.cs
@@ -0,0 +1,27 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonControlRightToLeftProperty : PythonControlProperty
+ {
+ public PythonControlRightToLeftProperty()
+ {
+ }
+
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ if (propertyValue is RightToLeft) {
+ return (RightToLeft)propertyValue == RightToLeft.No;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlTextProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlTextProperty.cs
new file mode 100644
index 0000000000..52586b9245
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlTextProperty.cs
@@ -0,0 +1,29 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace ICSharpCode.PythonBinding
+{
+ ///
+ /// Represents a Control's Text Property.
+ ///
+ public class PythonControlTextProperty : PythonControlProperty
+ {
+ public PythonControlTextProperty()
+ {
+ }
+
+ ///
+ /// Returns true if the Text property's value is an empty string.
+ ///
+ public override bool IsDefaultValue(object propertyValue)
+ {
+ return (string)propertyValue == String.Empty;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
index e1fd485171..8f283743ae 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
@@ -7,7 +7,9 @@
using System;
using System.Drawing;
+using System.Collections.Generic;
using System.ComponentModel;
+using System.Reflection;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.PythonBinding;
@@ -16,7 +18,7 @@ using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.PythonBinding
{
///
- /// Represents a form in the designer. Used to generate a form for the forms designer and generate
+ /// Represents a form in the designer. Used to generate
/// Python code after the form has been changed in the designer.
///
public class PythonForm
@@ -24,10 +26,16 @@ namespace ICSharpCode.PythonBinding
StringBuilder codeBuilder;
string indentString = String.Empty;
int indent;
+ PythonControlDefaultPropertyValues defaultPropertyValues = new PythonControlDefaultPropertyValues();
+
+ public PythonForm()
+ : this("\t")
+ {
+ }
public PythonForm(string indentString)
{
- this.indentString = indentString;
+ this.indentString = indentString;
}
///
@@ -58,32 +66,96 @@ namespace ICSharpCode.PythonBinding
return codeBuilder.ToString();
}
+ ///
+ /// Should serialize a property if:
+ ///
+ /// 1) It has a different value to its default.
+ /// 2) DesignerSerializationVisibility is set to Hidden.
+ ///
+ public bool ShouldSerialize(object obj, PropertyDescriptor propertyDescriptor)
+ {
+ if (propertyDescriptor.DesignTimeOnly) {
+ return false;
+ }
+
+ // Is default value?
+ bool serialize = !defaultPropertyValues.IsDefaultValue(propertyDescriptor, obj);
+
+ // Is visible to designer?
+ if (serialize) {
+ serialize = propertyDescriptor.SerializationVisibility == DesignerSerializationVisibility.Visible;
+ if (!serialize) {
+ serialize = (propertyDescriptor.Name == "AutoScaleMode");
+ }
+ }
+
+ // Is browsable?
+ if (serialize) {
+ // Always serialize the Name.
+ if (propertyDescriptor.Name != "Name" && propertyDescriptor.Name != "AutoScaleMode" && propertyDescriptor.Name != "ClientSize") {
+ serialize = propertyDescriptor.IsBrowsable;
+ }
+ }
+ return serialize;
+ }
+
void GenerateInitializeComponentMethodBodyInternal(Form form)
{
// Add method body.
AppendIndentedLine("self.SuspendLayout()");
- AppendControl(form);
+
+ AppendForm(form);
AppendIndentedLine("self.ResumeLayout(False)");
AppendIndentedLine("self.PerformLayout()");
}
- void AppendControl(Control control)
+ ///
+ /// Generates python code for the form's InitializeComponent method.
+ ///
+ ///
+ /// Note that when the form is loaded in the designer the Name property appears twice:
+ ///
+ /// Property.ComponentType: System.Windows.Forms.Design.DesignerExtenders+NameExtenderProvider
+ /// Property.SerializationVisibility: Hidden
+ /// Property.IsBrowsable: True
+ ///
+ /// Property.ComponentType: System.Windows.Forms.Design.ControlDesigner
+ /// Property.SerializationVisibility: Visible
+ /// Property.IsBrowsable: False
+ ///
+ void AppendForm(Form form)
{
- AppendComment(control.Name);
- AppendSize("ClientSize", control.ClientSize);
- AppendIndentedLine("self.Name = \"" + control.Name + "\"");
+ AppendComment(form.Name);
+
+ PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(form);
+ foreach (PropertyDescriptor property in properties) {
+ if (property.SerializationVisibility == DesignerSerializationVisibility.Hidden && property.Name == "Name") {
+ // Skip the duplicate Name property.
+ } else {
+ AppendProperty(form, property);
+ }
+ }
}
- void AppendSize(string name, Size size)
- {
- AppendIndented("self.");
- Append(name + " = ");
- Append(size.GetType().FullName);
- Append("(" + size.Width + ", " + size.Height + ")");
- AppendLine();
+ ///
+ /// Appends a property to the InitializeComponents method.
+ ///
+ void AppendProperty(object obj, PropertyDescriptor propertyDescriptor)
+ {
+ if (propertyDescriptor.Name == "RightToLeft") {
+ Console.WriteLine("ImeMode");
+ }
+ object propertyValue = propertyDescriptor.GetValue(obj);
+ if (propertyValue == null) {
+ return;
+ }
+
+ if (ShouldSerialize(obj, propertyDescriptor)) {
+ AppendIndentedLine("self." + propertyDescriptor.Name + " = " + PythonPropertyValueAssignment.ToString(propertyValue));
+ }
}
-
+
///
/// Appends the comment lines before the control has its properties set.
///
@@ -94,6 +166,9 @@ namespace ICSharpCode.PythonBinding
AppendIndentedLine("# ");
}
+ ///
+ /// Increases the indent of any append lines.
+ ///
void IncreaseIndent()
{
++indent;
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
index aa520dfc67..a0bc969093 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
@@ -27,6 +27,7 @@ namespace ICSharpCode.PythonBinding
IComponentCreator componentCreator;
bool walkingAssignment;
Dictionary createdObjects = new Dictionary();
+ string formName = String.Empty;
public PythonFormWalker(IComponentCreator componentCreator)
{
@@ -52,6 +53,7 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(ClassDefinition node)
{
+ formName = node.Name.ToString();
if (node.Body != null) {
node.Body.Walk(this);
}
@@ -61,7 +63,7 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(FunctionDefinition node)
{
if (IsInitializeComponentMethod(node)) {
- form = (Form)componentCreator.CreateComponent(typeof(Form), "MainForm");
+ form = (Form)componentCreator.CreateComponent(typeof(Form), formName);
node.Body.Walk(this);
}
return false;
@@ -70,13 +72,19 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(AssignmentStatement node)
{
if (node.Left.Count > 0) {
- MemberExpression memberExpression = node.Left[0] as MemberExpression;
- if (memberExpression != null) {
- fieldExpression = PythonControlFieldExpression.Create(memberExpression);
+ MemberExpression lhsMemberExpression = node.Left[0] as MemberExpression;
+ if (lhsMemberExpression != null) {
+ fieldExpression = PythonControlFieldExpression.Create(lhsMemberExpression);
- walkingAssignment = true;
- node.Right.Walk(this);
- walkingAssignment = false;
+ MemberExpression rhsMemberExpression = node.Right as MemberExpression;
+ if (rhsMemberExpression != null) {
+ string name = PythonControlFieldExpression.GetMemberName(rhsMemberExpression);
+ SetPropertyValue(fieldExpression.MemberName, name);
+ } else {
+ walkingAssignment = true;
+ node.Right.Walk(this);
+ walkingAssignment = false;
+ }
}
}
return false;
@@ -84,20 +92,10 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(ConstantExpression node)
{
- Control control = GetCurrentControl();
- SetPropertyValue(control, fieldExpression.MemberName, node.Value);
+ SetPropertyValue(fieldExpression.MemberName, node.Value);
return false;
}
- Control GetCurrentControl()
- {
- string variableName = PythonControlFieldExpression.GetVariableNameFromSelfReference(fieldExpression.FullMemberName);
- if (variableName.Length > 0) {
- return GetControl(variableName);
- }
- return form;
- }
-
public override bool Walk(CallExpression node)
{
MemberExpression memberExpression = node.Target as MemberExpression;
@@ -118,6 +116,12 @@ namespace ICSharpCode.PythonBinding
return false;
}
+ public override bool Walk(NameExpression node)
+ {
+ SetPropertyValue(fieldExpression.MemberName, node.Name.ToString());
+ return false;
+ }
+
///
/// Gets the arguments passed to the call expression.
///
@@ -138,20 +142,44 @@ namespace ICSharpCode.PythonBinding
string name = node.Name.ToString().ToLowerInvariant();
return name == "initializecomponent" || name == "initializecomponents";
}
+
+ ///
+ /// Sets the value of a property on the current control.
+ ///
+ bool SetPropertyValue(string name, object propertyValue)
+ {
+ Control control = GetCurrentControl();
+ return SetPropertyValue(control, name, propertyValue);
+ }
///
- /// Sets the value of a form's property.
+ /// Sets the value of a property on the control.
///
- bool SetPropertyValue(Control control, string name, object @value)
+ bool SetPropertyValue(Control control, string name, object propertyValue)
{
- PropertyInfo propertyInfo = control.GetType().GetProperty(name);
- if (propertyInfo != null) {
- propertyInfo.SetValue(control, @value, null);
+ PropertyDescriptor property = TypeDescriptor.GetProperties(control).Find(name, true);
+ if (property != null) {
+ propertyValue = ConvertPropertyValue(property, propertyValue);
+ property.SetValue(control, propertyValue);
return true;
}
return false;
}
-
+
+ ///
+ /// Converts the value to the property's type if required.
+ ///
+ static object ConvertPropertyValue(PropertyDescriptor propertyDescriptor, object propertyValue)
+ {
+ if (propertyDescriptor.PropertyType != propertyValue.GetType()) {
+ if (propertyDescriptor.PropertyType.IsEnum) {
+ return Enum.Parse(propertyDescriptor.PropertyType, GetUnqualifiedEnumValue(propertyValue as String));
+ }
+ return Convert.ChangeType(propertyValue, propertyDescriptor.PropertyType);
+ }
+ return propertyValue;
+ }
+
Type GetType(string typeName)
{
Type type = componentCreator.GetType(typeName);
@@ -192,5 +220,26 @@ namespace ICSharpCode.PythonBinding
}
return null;
}
+
+ Control GetCurrentControl()
+ {
+ string variableName = PythonControlFieldExpression.GetVariableNameFromSelfReference(fieldExpression.FullMemberName);
+ if (variableName.Length > 0) {
+ return GetControl(variableName);
+ }
+ return form;
+ }
+
+ ///
+ /// Gets the unqualified enum value from a fully qualified value.
+ ///
+ static string GetUnqualifiedEnumValue(string fullyQualifiedEnumValue)
+ {
+ int index = fullyQualifiedEnumValue.LastIndexOf('.');
+ if (index > 0) {
+ return fullyQualifiedEnumValue.Substring(index + 1);
+ }
+ return fullyQualifiedEnumValue;
+ }
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
new file mode 100644
index 0000000000..77eda84b84
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
@@ -0,0 +1,46 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace ICSharpCode.PythonBinding
+{
+ ///
+ /// Represents a property value assignment in a form or control.
+ ///
+ public class PythonPropertyValueAssignment
+ {
+ PythonPropertyValueAssignment()
+ {
+ }
+
+ ///
+ /// Converts the property assignment to the equivalent python string.
+ ///
+ ///
+ /// 1) Strings are returned surrounded by double quotes.
+ /// 2) Objects are returned with their full name (e.g. System.Windows.Forms.Size(100, 200)).
+ /// 3) Enums are returned with their full name (e.g. System.Windows.Forms.AccessibleRole.None).
+ /// 4) By default the ToString method is used on the property value.
+ ///
+ public static string ToString(object propertyValue)
+ {
+ Type propertyType = propertyValue.GetType();
+ if (propertyType == typeof(String)) {
+ return "\"" + propertyValue + "\"";
+ } else if (propertyType == typeof(Size)) {
+ Size size = (Size)propertyValue;
+ return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")";
+ } else if (propertyType.IsEnum) {
+ return propertyType.FullName + "." + propertyValue.ToString();
+ }
+ return propertyValue.ToString();
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EnabledSetUsingPropertyDescriptorTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EnabledSetUsingPropertyDescriptorTestFixture.cs
new file mode 100644
index 0000000000..552ea20e52
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EnabledSetUsingPropertyDescriptorTestFixture.cs
@@ -0,0 +1,69 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// The PythonForm class should be getting the value from the PropertyDescriptor and not
+ /// the PropertyInfo information returned from the form object. If this is not done then when the
+ /// user sets Enabled to false in the designer the value is not generated in the InitializeComponent method.
+ ///
+ [TestFixture]
+ public class EnabledSetUsingPropertyDescriptorTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ Form form = (Form)host.RootComponent;
+ form.ClientSize = new Size(284, 264);
+ form.AllowDrop = false;
+ form.Enabled = false;
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ PropertyDescriptor enabledPropertyDescriptor = descriptors.Find("Enabled", false);
+ enabledPropertyDescriptor.SetValue(form, false);
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.Enabled = False\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAccessibleRoleFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAccessibleRoleFormTestFixture.cs
new file mode 100644
index 0000000000..e586bc0ccb
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAccessibleRoleFormTestFixture.cs
@@ -0,0 +1,53 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TestFixture]
+ public class GenerateAccessibleRoleFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (Form form = new Form()) {
+ form.Name = "MainForm";
+ form.ClientSize = new Size(284, 264);
+ form.AccessibleRole = AccessibleRole.None;
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.AccessibleRole = System.Windows.Forms.AccessibleRole.None\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScaleModeFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScaleModeFormTestFixture.cs
new file mode 100644
index 0000000000..ffae65a190
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScaleModeFormTestFixture.cs
@@ -0,0 +1,65 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// A Form has a base ContainerControl class which has an AutoScaleMode property. This has the following attributes:
+ ///
+ /// Browsable = false
+ /// DesignerSerializationVisibility = Hidden
+ /// EditorBrowsable = EditorBrowsableState.Advanced
+ ///
+ /// However the forms root designer overrides these and shows it in the designer.
+ ///
+ /// This test fixture checks that the AutoScaleMode value will be generated in the form's code
+ /// by the python forms designer.
+ ///
+ [TestFixture]
+ public class GenerateAutoScaleModeFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (Form form = new Form()) {
+ form.Name = "MainForm";
+ form.ClientSize = new Size(284, 264);
+ form.AutoScaleMode = AutoScaleMode.Font;
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScrollFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScrollFormTestFixture.cs
new file mode 100644
index 0000000000..baa1fe274b
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateAutoScrollFormTestFixture.cs
@@ -0,0 +1,53 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TestFixture]
+ public class GenerateAutoScrollFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (Form form = new Form()) {
+ form.Name = "MainForm";
+ form.ClientSize = new Size(284, 264);
+ form.AutoScroll = true;
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.AutoScroll = True\r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateDoubleBufferedFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateDoubleBufferedFormTestFixture.cs
new file mode 100644
index 0000000000..446f6d09e4
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateDoubleBufferedFormTestFixture.cs
@@ -0,0 +1,68 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// The DoubleBuffered property on the Control class is a protected method so using the GetType().GetProperty(...)
+ /// method will not return it. This test checks that this property is generated when creating the python code
+ /// for the form.
+ ///
+ [TestFixture]
+ public class GenerateDoubleBufferedFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ Form form = (Form)host.RootComponent;
+ form.ClientSize = new Size(284, 264);
+ form.AllowDrop = false;
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor doubleBufferedPropertyDescriptor = descriptors.Find("DoubleBuffered", false);
+ doubleBufferedPropertyDescriptor.SetValue(form, true);
+
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.DoubleBuffered = True\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateImeModeFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateImeModeFormTestFixture.cs
new file mode 100644
index 0000000000..79ba98e944
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateImeModeFormTestFixture.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 NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TestFixture]
+ public class GenerateImeModeFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ Form form = (Form)host.RootComponent;
+ form.ClientSize = new Size(284, 264);
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor doubleBufferedPropertyDescriptor = descriptors.Find("ImeMode", false);
+ doubleBufferedPropertyDescriptor.SetValue(form, ImeMode.Alpha);
+
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.ImeMode = System.Windows.Forms.ImeMode.Alpha\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateRightToLeftFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateRightToLeftFormTestFixture.cs
new file mode 100644
index 0000000000..49a1177f2d
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateRightToLeftFormTestFixture.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 NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TestFixture]
+ public class GenerateRightToLeftFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ Form form = (Form)host.RootComponent;
+ form.ClientSize = new Size(284, 264);
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor doubleBufferedPropertyDescriptor = descriptors.Find("RightToLeft", false);
+ doubleBufferedPropertyDescriptor.SetValue(form, RightToLeft.Yes);
+
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ string indentString = " ";
+ PythonForm pythonForm = new PythonForm(indentString);
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.RightToLeft = System.Windows.Forms.RightToLeft.Yes\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ClientSize = System.Drawing.Size(284, 264)\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IgnoreDesignTimePropertiesTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IgnoreDesignTimePropertiesTestFixture.cs
new file mode 100644
index 0000000000..6cd4317fcd
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IgnoreDesignTimePropertiesTestFixture.cs
@@ -0,0 +1,59 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// The python form code generator should ignore any design time properties (e.g. Locked) of the form.
+ /// These are put in the .resx file not the source code.
+ ///
+ [TestFixture]
+ public class IgnoreDesignTimePropertiesTestFixture
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.ClientSize = System.Drawing.Size(200, 300)\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ ///
+ /// Loads a form into a DesignSurface and checks that the PythonForm does not try to
+ /// add design time properties and does not throw a null reference exception.
+ ///
+ [Test]
+ public void DesignTimePropertyIsIgnore()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ Form form = (Form)host.RootComponent;
+ form.AllowDrop = false;
+ form.ClientSize = new Size(200, 300);
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ PythonForm pythonForm = new PythonForm(" ");
+ string code = pythonForm.GenerateInitializeComponentMethod(form);
+
+ Assert.AreEqual(expectedCode, code);
+ }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs
new file mode 100644
index 0000000000..876e957aec
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs
@@ -0,0 +1,114 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Reflection;
+using System.Windows.Forms;
+
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// Tests the PythonControlDefaultPropertyValues.IsDefaultValue method.
+ /// This checks the property and returns true if the value of the property is the same as its default.
+ ///
+ [TestFixture]
+ public class IsDefaultPropertyValueTests
+ {
+ Form form;
+ PythonControlDefaultPropertyValues defaultPropertyValues;
+
+ [TestFixtureSetUp]
+ public void InitFixture()
+ {
+ form = new Form();
+ defaultPropertyValues = new PythonControlDefaultPropertyValues();
+ }
+
+ [TestFixtureTearDown]
+ public void TearDownFixture()
+ {
+ form.Dispose();
+ }
+
+ [Test]
+ public void TextPropertyDefaultIsEmptyString()
+ {
+ form.Text = String.Empty;
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("Text", form));
+ }
+
+ [Test]
+ public void TextPropertyIsNotEmptyString()
+ {
+ form.Text = "abc";
+ Assert.IsFalse(defaultPropertyValues.IsDefaultValue("Text", form));
+ }
+
+ [Test]
+ public void AutoValidatePropertyDefaultIsEnablePreventFocusChange()
+ {
+ form.AutoValidate = AutoValidate.EnablePreventFocusChange;
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("AutoValidate", form));
+ }
+
+ [Test]
+ public void AutoValidatePropertyIsDisable()
+ {
+ form.AutoValidate = AutoValidate.Disable;
+ Assert.IsFalse(defaultPropertyValues.IsDefaultValue("AutoValidate", form));
+ }
+
+ [Test]
+ public void EnabledPropertyDefaultIsTrue()
+ {
+ form.Enabled = true;
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("Enabled", form));
+ }
+
+ [Test]
+ public void EnabledPropertyIsFalse()
+ {
+ form.Enabled = false;
+ Assert.IsFalse(defaultPropertyValues.IsDefaultValue("Enabled", form));
+ }
+
+ [Test]
+ public void AccessibleDescriptionDefaultValueIsNull()
+ {
+ form.AccessibleDescription = null;
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("AccessibleDescription", form));
+ }
+
+ [Test]
+ public void AutoScaleModeDefaultIsInherit()
+ {
+ form.AutoScaleMode = AutoScaleMode.Inherit;
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("AutoScaleMode", form));
+ }
+
+ [Test]
+ public void PropertyDoesNotExist()
+ {
+ Assert.IsFalse(defaultPropertyValues.IsDefaultValue("PropertyDoesNotExist", form));
+ }
+
+ [Test]
+ public void DoubleBufferedDefaultIsFalse()
+ {
+ PropertyInfo property = form.GetType().GetProperty("DoubleBuffered", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
+ property.SetValue(form, false, null);
+
+ Assert.IsTrue(defaultPropertyValues.IsDefaultValue("DoubleBuffered", form));
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs
new file mode 100644
index 0000000000..5a0f688914
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs
@@ -0,0 +1,53 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// Tests that the Form's AccessibleRole property can be loaded into the designer.
+ ///
+ [TestFixture]
+ public class LoadAccessibleRoleTestFixture : LoadFormTestFixtureBase
+ {
+ string pythonCode = "class TestForm(System.Windows.Forms.Form):\r\n" +
+ " def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # TestForm\r\n" +
+ " # \r\n" +
+ " self.AccessibleRole = System.Windows.Forms.AccessibleRole.None\r\n" +
+ " self.Name = \"TestForm\"\r\n" +
+ " self.ResumeLayout(False)\r\n";
+ Form form;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ PythonFormWalker walker = new PythonFormWalker(this);
+ form = walker.CreateForm(pythonCode);
+ }
+
+ [TestFixtureTearDown]
+ public void TearDownFixture()
+ {
+ form.Dispose();
+ }
+
+ [Test]
+ public void AccessibleRoleIsNone()
+ {
+ Assert.AreEqual(AccessibleRole.None, form.AccessibleRole);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs
new file mode 100644
index 0000000000..c2b5f460b8
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs
@@ -0,0 +1,60 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+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 LoadFormWithBooleanPropertiesSetTestFixture : LoadFormTestFixtureBase
+ {
+ string pythonCode = "class TestForm(System.Windows.Forms.Form):\r\n" +
+ " def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # TestForm\r\n" +
+ " # \r\n" +
+ " self.AllowDrop = False\r\n" +
+ " self.Enabled = False\r\n" +
+ " self.Name = \"TestForm\"\r\n" +
+ " self.ResumeLayout(False)\r\n";
+ Form form;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ PythonFormWalker walker = new PythonFormWalker(this);
+ form = walker.CreateForm(pythonCode);
+ }
+
+ [TestFixtureTearDown]
+ public void TearDownFixture()
+ {
+ form.Dispose();
+ }
+
+ [Test]
+ public void FormEnabledIsFalse()
+ {
+ Assert.IsFalse(form.Enabled);
+ }
+
+ [Test]
+ public void FormAllowDropIsFalse()
+ {
+ Assert.IsFalse(form.AllowDrop);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ShouldSerializeTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ShouldSerializeTests.cs
new file mode 100644
index 0000000000..67d0305399
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ShouldSerializeTests.cs
@@ -0,0 +1,76 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Reflection;
+using System.Windows.Forms;
+
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// Tests the PythonForm.ShouldSerialize method which determines whether a form's property
+ /// should be serialized.
+ ///
+ [TestFixture]
+ public class ShouldSerializeTests
+ {
+ PythonForm pythonForm;
+ Form form;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ form = new Form();
+ }
+
+ [TestFixtureTearDown]
+ public void TearDownFixture()
+ {
+ form.Dispose();
+ }
+
+ [SetUp]
+ public void Init()
+ {
+ pythonForm = new PythonForm();
+ }
+
+ [Test]
+ public void ShouldNotSerializePropertyWithFalseBrowseAttribute()
+ {
+ AssertShouldNotSerialize("LayoutEngine", form);
+ }
+
+ [Test]
+ public void ShouldNotSerializeEmptyStringTextProperty()
+ {
+ form.Text = String.Empty;
+ AssertShouldNotSerialize("Text", form);
+ }
+
+ void AssertShouldSerialize(string propertyName, Form form)
+ {
+ AssertShouldSerialize(propertyName, form, true);
+ }
+
+ void AssertShouldNotSerialize(string propertyName, Form form)
+ {
+ AssertShouldSerialize(propertyName, form, false);
+ }
+
+ void AssertShouldSerialize(string propertyName, Form form, bool isTrue)
+ {
+ PropertyDescriptor property = TypeDescriptor.GetProperties(form).Find(propertyName, true);
+ Assert.AreEqual(isTrue, pythonForm.ShouldSerialize(form, property));
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
index 2e18bcd4d4..f998e5efae 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
@@ -145,12 +145,23 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -162,6 +173,7 @@
+