Browse Source

Python forms designer now uses InstanceDescriptor to generate code for object creation.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4588 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 16 years ago
parent
commit
80f9ad772d
  1. 108
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
  2. 76
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ConvertCustomClassUsingTypeConverterTestFixture.cs
  3. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

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

@ -6,7 +6,10 @@
// </file> // </file>
using System; using System;
using System.Collections;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Windows.Forms; using System.Windows.Forms;
@ -42,70 +45,13 @@ namespace ICSharpCode.PythonBinding
Type propertyType = propertyValue.GetType(); Type propertyType = propertyValue.GetType();
if (propertyType == typeof(String)) { if (propertyType == typeof(String)) {
return GetQuotedString((string)propertyValue); return GetQuotedString((string)propertyValue);
} else if (propertyType == typeof(Size)) {
Size size = (Size)propertyValue;
return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")";
} else if (propertyType == typeof(SizeF)) {
SizeF size = (SizeF)propertyValue;
return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")";
} else if (propertyType == typeof(Cursor)) {
return GetCursorAsString(propertyValue as Cursor);
} else if (propertyType == typeof(Point)) {
Point point = (Point)propertyValue;
return point.GetType().FullName + "(" + point.X + ", " + point.Y + ")";
} else if (propertyType == typeof(Padding)) {
Padding padding = (Padding)propertyValue;
return padding.GetType().FullName + "(" + padding.Left + ", " + padding.Top + ", " + padding.Right + ", " + padding.Bottom + ")";
} else if (propertyType == typeof(Color)) {
Color color = (Color)propertyValue;
return GetColorAsString(color);
} else if (propertyType == typeof(Font)) {
Font font = (Font)propertyValue;
return GetFontAsString(font);
} else if (propertyType == typeof(AnchorStyles)) { } else if (propertyType == typeof(AnchorStyles)) {
AnchorStyles anchor = (AnchorStyles)propertyValue; AnchorStyles anchor = (AnchorStyles)propertyValue;
return GetAnchorStyleAsString(anchor); return GetAnchorStyleAsString(anchor);
} else if (propertyType.IsEnum) {
return propertyType.FullName.Replace('+', '.') + "." + propertyValue.ToString();
} }
return propertyValue.ToString(); return ConvertTypeToString(propertyValue);
} }
static string GetCursorAsString(Cursor cursor)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(Cursor));
string cursorName = converter.ConvertToString(null, CultureInfo.InvariantCulture, cursor);
return typeof(Cursors).FullName + "." + cursorName;
}
static string GetColorAsString(Color color)
{
if (color.IsSystemColor) {
return GetColorAsString(color, typeof(SystemColors));
} else if (color.IsNamedColor) {
return GetColorAsString(color, typeof(Color));
}
// Custom color.
return color.GetType().FullName + ".FromArgb(" + color.R + ", " + color.G + ", " + color.B + ")";
}
static string GetColorAsString(Color color, Type type)
{
foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Static)) {
Color standardColor = (Color)property.GetValue(null, null);
if (color == standardColor) {
return type.FullName + "." + standardColor.Name;
}
}
return String.Empty;
}
static string GetFontAsString(Font font)
{
return String.Concat(font.GetType().FullName, "(\"", font.Name, "\", ", font.Size.ToString(CultureInfo.InvariantCulture), ", ", typeof(FontStyle).FullName, ".", font.Style, ", ", typeof(GraphicsUnit).FullName, ".", font.Unit, ", ", font.GdiCharSet, ")");
}
static string GetAnchorStyleAsString(AnchorStyles anchorStyles) static string GetAnchorStyleAsString(AnchorStyles anchorStyles)
{ {
if (anchorStyles == AnchorStyles.None) { if (anchorStyles == AnchorStyles.None) {
@ -139,5 +85,49 @@ namespace ICSharpCode.PythonBinding
{ {
return "\"" + text.Replace(@"\", @"\\").Replace("\"", "\\\"") + "\""; return "\"" + text.Replace(@"\", @"\\").Replace("\"", "\\\"") + "\"";
} }
/// <summary>
/// Looks for an instance descriptor for the property value's type and then tries to convert
/// the object creation using this instance descriptor.
/// </summary>
static string ConvertTypeToString(object propertyValue)
{
TypeConverter converter = TypeDescriptor.GetConverter(propertyValue);
if (converter.CanConvertTo(typeof(InstanceDescriptor))) {
InstanceDescriptor instanceDescriptor = converter.ConvertTo(propertyValue, typeof(InstanceDescriptor)) as InstanceDescriptor;
if (instanceDescriptor != null) {
StringBuilder text = new StringBuilder();
MemberInfo memberInfo = instanceDescriptor.MemberInfo;
string fullName = memberInfo.DeclaringType.FullName.Replace('+', '.'); // Remove any + chars from enums.
text.Append(fullName);
if (memberInfo.MemberType != MemberTypes.Constructor) {
text.Append('.');
text.Append(memberInfo.Name);
}
// Append arguments.
AppendArguments(text, instanceDescriptor.Arguments);
return text.ToString();
}
}
return converter.ConvertToString(null, CultureInfo.InvariantCulture, propertyValue);
}
static void AppendArguments(StringBuilder text, ICollection args)
{
if (args.Count > 0) {
int i = 0;
text.Append('(');
foreach (object arg in args) {
if (i > 0) {
text.Append(", ");
}
text.Append(ToString(arg));
++i;
}
text.Append(')');
}
}
} }
} }

76
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ConvertCustomClassUsingTypeConverterTestFixture.cs

@ -0,0 +1,76 @@
// <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;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Windows.Forms;
using ICSharpCode.PythonBinding;
using NUnit.Framework;
namespace PythonBinding.Tests.Designer
{
[TypeConverter(typeof(CustomClassTypeConverter))]
class CustomClass
{
public string Name { get; set; }
public string Category { get; set; }
public CustomClass()
{
}
public CustomClass(string name, string category)
{
this.Name = name;
this.Category = category;
}
}
class CustomClassTypeConverter : TypeConverter
{
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor)) {
CustomClass c = value as CustomClass;
if (c != null) {
ConstructorInfo info = typeof(CustomClass).GetConstructor(new Type[] {typeof(String), typeof(String)});
return new InstanceDescriptor(info, new object[] {c.Name, c.Category});
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor)) {
return true;
}
return base.CanConvertTo(context, destinationType);
}
}
/// <summary>
/// Converts a custom class that has a custom TypeConverter defined.
/// This type converter implements an InstanceDescriptor which is used to generate the
/// code to create an instance of the class.
/// </summary>
[TestFixture]
public class ConvertCustomClassUsingTypeConverterTestFixture
{
[Test]
public void ConvertCustomClass()
{
CustomClass customClass = new CustomClass("Test", "Category");
Assert.AreEqual("PythonBinding.Tests.Designer.CustomClass(\"Test\", \"Category\")", PythonPropertyValueAssignment.ToString(customClass));
}
}
}

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

@ -161,6 +161,7 @@
<Compile Include="Converter\WhileLoopConversionTestFixture.cs" /> <Compile Include="Converter\WhileLoopConversionTestFixture.cs" />
<Compile Include="Converter\XmlDocCommentConversionTestFixture.cs" /> <Compile Include="Converter\XmlDocCommentConversionTestFixture.cs" />
<Compile Include="DebugPythonCommandTestFixture.cs" /> <Compile Include="DebugPythonCommandTestFixture.cs" />
<Compile Include="Designer\ConvertCustomClassUsingTypeConverterTestFixture.cs" />
<Compile Include="Designer\CreateDesignerComponentTests.cs" /> <Compile Include="Designer\CreateDesignerComponentTests.cs" />
<Compile Include="Designer\CursorTypeResolutionTestFixture.cs" /> <Compile Include="Designer\CursorTypeResolutionTestFixture.cs" />
<Compile Include="Designer\DeserializeAssignmentTestFixtureBase.cs" /> <Compile Include="Designer\DeserializeAssignmentTestFixtureBase.cs" />

Loading…
Cancel
Save