Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4743 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
126 changed files with 2872 additions and 4041 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 235 B |
@ -1,19 +0,0 @@
@@ -1,19 +0,0 @@
|
||||
// <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; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a named item in an array.
|
||||
/// </summary>
|
||||
public interface IArrayItem |
||||
{ |
||||
string Name { get; } |
||||
} |
||||
} |
@ -0,0 +1,376 @@
@@ -0,0 +1,376 @@
|
||||
// <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.CodeDom; |
||||
using System.ComponentModel; |
||||
using System.ComponentModel.Design; |
||||
using System.ComponentModel.Design.Serialization; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Used to generate Python code after the form has been changed in the designer.
|
||||
/// </summary>
|
||||
public class PythonCodeDomSerializer |
||||
{ |
||||
PythonCodeBuilder codeBuilder; |
||||
string indentString = String.Empty; |
||||
string rootResourceName = String.Empty; |
||||
IDesignerSerializationManager serializationManager; |
||||
|
||||
public PythonCodeDomSerializer() |
||||
: this("\t") |
||||
{ |
||||
} |
||||
|
||||
public PythonCodeDomSerializer(string indentString) |
||||
{ |
||||
this.indentString = indentString; |
||||
} |
||||
|
||||
// public string GenerateInitializeComponentMethod(IDesignerHost host, IDesignerSerializationManager serializationManager)
|
||||
// {
|
||||
// return GenerateInitializeComponentMethod(host, serializationManager, String.Empty);
|
||||
// }
|
||||
//
|
||||
// public string GenerateInitializeComponentMethod(IDesignerHost host, IDesignerSerializationManager serializationManager, string rootNamespace)
|
||||
// {
|
||||
// CodeMemberMethod method = FindInitializeComponentMethod(host, serializationManager);
|
||||
//
|
||||
// codeBuilder = new PythonCodeBuilder();
|
||||
// codeBuilder.IndentString = indentString;
|
||||
// codeBuilder.AppendIndentedLine("def " + method.Name + "(self):");
|
||||
// codeBuilder.IncreaseIndent();
|
||||
//
|
||||
// GetResourceRootName(rootNamespace, host.RootComponent);
|
||||
// AppendStatements(method.Statements);
|
||||
//
|
||||
// return codeBuilder.ToString();
|
||||
// }
|
||||
|
||||
public string GenerateInitializeComponentMethodBody(IDesignerHost host, IDesignerSerializationManager serializationManager) |
||||
{ |
||||
return GenerateInitializeComponentMethodBody(host, serializationManager, String.Empty); |
||||
} |
||||
|
||||
public string GenerateInitializeComponentMethodBody(IDesignerHost host, IDesignerSerializationManager serializationManager, string rootNamespace) |
||||
{ |
||||
return GenerateInitializeComponentMethodBody(host, serializationManager, rootResourceName, 0); |
||||
} |
||||
|
||||
public string GenerateInitializeComponentMethodBody(IDesignerHost host, IDesignerSerializationManager serializationManager, string rootNamespace, int initialIndent) |
||||
{ |
||||
codeBuilder = new PythonCodeBuilder(initialIndent); |
||||
codeBuilder.IndentString = indentString; |
||||
|
||||
CodeMemberMethod method = FindInitializeComponentMethod(host, serializationManager); |
||||
GetResourceRootName(rootNamespace, host.RootComponent); |
||||
AppendStatements(method.Statements); |
||||
|
||||
return codeBuilder.ToString(); |
||||
} |
||||
|
||||
CodeMemberMethod FindInitializeComponentMethod(IDesignerHost host, IDesignerSerializationManager serializationManager) |
||||
{ |
||||
this.serializationManager = serializationManager; |
||||
object rootComponent = host.RootComponent; |
||||
TypeCodeDomSerializer serializer = serializationManager.GetSerializer(rootComponent.GetType(), typeof(TypeCodeDomSerializer)) as TypeCodeDomSerializer; |
||||
CodeTypeDeclaration typeDec = serializer.Serialize(serializationManager, rootComponent, host.Container.Components) as CodeTypeDeclaration; |
||||
foreach (CodeTypeMember member in typeDec.Members) { |
||||
CodeMemberMethod method = member as CodeMemberMethod; |
||||
if (method != null) { |
||||
if (method.Name == "InitializeComponent") { |
||||
return method; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void AppendStatements(CodeStatementCollection statements) |
||||
{ |
||||
foreach (CodeStatement statement in statements) { |
||||
AppendStatement(statement); |
||||
} |
||||
} |
||||
|
||||
void AppendStatement(CodeStatement statement) |
||||
{ |
||||
if (statement is CodeExpressionStatement) { |
||||
AppendExpressionStatement((CodeExpressionStatement)statement); |
||||
} else if (statement is CodeCommentStatement) { |
||||
AppendCommentStatement((CodeCommentStatement)statement); |
||||
} else if (statement is CodeAssignStatement) { |
||||
AppendAssignStatement((CodeAssignStatement)statement); |
||||
} else if (statement is CodeVariableDeclarationStatement) { |
||||
AppendVariableDeclarationStatement((CodeVariableDeclarationStatement)statement); |
||||
} else if (statement is CodeAttachEventStatement) { |
||||
AppendAttachEventStatement((CodeAttachEventStatement)statement); |
||||
} else { |
||||
Console.WriteLine("AppendStatement: " + statement.GetType().Name); |
||||
} |
||||
} |
||||
|
||||
void AppendExpressionStatement(CodeExpressionStatement statement) |
||||
{ |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
AppendExpression(statement.Expression); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
void AppendCommentStatement(CodeCommentStatement statement) |
||||
{ |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
codeBuilder.Append("# "); |
||||
codeBuilder.Append(statement.Comment.Text); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
void AppendExpression(CodeExpression expression) |
||||
{ |
||||
if (expression is CodeMethodInvokeExpression) { |
||||
AppendMethodInvokeExpression((CodeMethodInvokeExpression)expression); |
||||
} else if (expression is CodePropertyReferenceExpression) { |
||||
AppendPropertyReferenceExpression((CodePropertyReferenceExpression)expression); |
||||
} else if (expression is CodeObjectCreateExpression) { |
||||
AppendObjectCreateExpression((CodeObjectCreateExpression)expression); |
||||
} else if (expression is CodePrimitiveExpression) { |
||||
AppendPrimitiveExpression((CodePrimitiveExpression)expression); |
||||
} else if (expression is CodeFieldReferenceExpression) { |
||||
AppendFieldReferenceExpression((CodeFieldReferenceExpression)expression); |
||||
} else if (expression is CodeThisReferenceExpression) { |
||||
AppendThisReferenceExpression(); |
||||
} else if (expression is CodeTypeReferenceExpression) { |
||||
AppendTypeReferenceExpression((CodeTypeReferenceExpression)expression); |
||||
} else if (expression is CodeArrayCreateExpression) { |
||||
AppendArrayCreateExpression((CodeArrayCreateExpression)expression); |
||||
} else if (expression is CodeVariableReferenceExpression) { |
||||
AppendVariableReferenceExpression((CodeVariableReferenceExpression)expression); |
||||
} else if (expression is CodeDelegateCreateExpression) { |
||||
AppendDelegateCreateExpression((CodeDelegateCreateExpression)expression); |
||||
} else if (expression is CodeCastExpression) { |
||||
AppendCastExpression((CodeCastExpression)expression); |
||||
} else { |
||||
Console.WriteLine("AppendExpression: " + expression.GetType().Name); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a method call (e.g. "self.SuspendLayout()");
|
||||
/// </summary>
|
||||
void AppendMethodInvokeExpression(CodeMethodInvokeExpression expression) |
||||
{ |
||||
AppendMethodReferenceExpression(expression.Method); |
||||
AppendParameters(expression.Parameters); |
||||
} |
||||
|
||||
void AppendMethodReferenceExpression(CodeMethodReferenceExpression expression) |
||||
{ |
||||
AppendExpression(expression.TargetObject); |
||||
codeBuilder.Append("."); |
||||
codeBuilder.Append(expression.MethodName); |
||||
} |
||||
|
||||
void AppendParameters(CodeExpressionCollection parameters) |
||||
{ |
||||
codeBuilder.Append("("); |
||||
bool firstParameter = true; |
||||
foreach (CodeExpression expression in parameters) { |
||||
if (firstParameter) { |
||||
firstParameter = false; |
||||
} else { |
||||
codeBuilder.Append(", "); |
||||
} |
||||
AppendExpression(expression); |
||||
} |
||||
codeBuilder.Append(")"); |
||||
} |
||||
|
||||
void AppendAssignStatement(CodeAssignStatement statement) |
||||
{ |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
AppendExpression(statement.Left); |
||||
codeBuilder.Append(" = "); |
||||
AppendExpression(statement.Right); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
void AppendPropertyReferenceExpression(CodePropertyReferenceExpression expression) |
||||
{ |
||||
AppendExpression(expression.TargetObject); |
||||
codeBuilder.Append("."); |
||||
codeBuilder.Append(expression.PropertyName); |
||||
} |
||||
|
||||
void AppendObjectCreateExpression(CodeObjectCreateExpression expression) |
||||
{ |
||||
AppendTypeReference(expression.CreateType); |
||||
AppendParameters(expression.Parameters); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a constant (e.g. string or int).
|
||||
/// </summary>
|
||||
void AppendPrimitiveExpression(CodePrimitiveExpression expression) |
||||
{ |
||||
codeBuilder.Append(PythonPropertyValueAssignment.ToString(expression.Value)); |
||||
} |
||||
|
||||
void AppendFieldReferenceExpression(CodeFieldReferenceExpression expression) |
||||
{ |
||||
AppendExpression(expression.TargetObject); |
||||
codeBuilder.Append("."); |
||||
if (expression.FieldName != null) { |
||||
if (expression.TargetObject is CodeThisReferenceExpression) { |
||||
if (!IsInherited(expression.FieldName)) { |
||||
codeBuilder.Append("_"); |
||||
} |
||||
} |
||||
codeBuilder.Append(expression.FieldName); |
||||
} |
||||
} |
||||
|
||||
void AppendThisReferenceExpression() |
||||
{ |
||||
codeBuilder.Append("self"); |
||||
} |
||||
|
||||
void AppendTypeReferenceExpression(CodeTypeReferenceExpression expression) |
||||
{ |
||||
AppendTypeReference(expression.Type); |
||||
} |
||||
|
||||
void AppendTypeReference(CodeTypeReference typeRef) |
||||
{ |
||||
codeBuilder.Append(typeRef.BaseType); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates an array expression:
|
||||
///
|
||||
/// (System.Array[System.Object](\r\n" +
|
||||
/// ["aaa",
|
||||
/// "bbb",
|
||||
/// "ccc\"]))
|
||||
/// </summary>
|
||||
void AppendArrayCreateExpression(CodeArrayCreateExpression expression) |
||||
{ |
||||
codeBuilder.Append("System.Array["); |
||||
AppendTypeReference(expression.CreateType); |
||||
codeBuilder.Append("]"); |
||||
|
||||
AppendInitializers(expression.Initializers); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends initializers for an array.
|
||||
/// </summary>
|
||||
void AppendInitializers(CodeExpressionCollection initalizers) |
||||
{ |
||||
codeBuilder.Append("("); |
||||
codeBuilder.AppendLine(); |
||||
codeBuilder.IncreaseIndent(); |
||||
codeBuilder.AppendIndented("["); |
||||
|
||||
bool firstInitializer = true; |
||||
foreach (CodeExpression expression in initalizers) { |
||||
if (firstInitializer) { |
||||
firstInitializer = false; |
||||
} else { |
||||
codeBuilder.Append(","); |
||||
codeBuilder.AppendLine(); |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
} |
||||
AppendExpression(expression); |
||||
} |
||||
|
||||
codeBuilder.Append("])"); |
||||
codeBuilder.DecreaseIndent(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a local variable declaration.
|
||||
/// </summary>
|
||||
void AppendVariableDeclarationStatement(CodeVariableDeclarationStatement statement) |
||||
{ |
||||
if (statement.Name == "resources") { |
||||
codeBuilder.AppendIndented("resources = System.Resources.ResourceManager(\""); |
||||
codeBuilder.Append(rootResourceName); |
||||
codeBuilder.Append("\", System.Reflection.Assembly.GetEntryAssembly())"); |
||||
codeBuilder.AppendLine(); |
||||
} else { |
||||
codeBuilder.AppendIndented(statement.Name); |
||||
codeBuilder.Append(" = "); |
||||
AppendExpression(statement.InitExpression); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
} |
||||
|
||||
void AppendVariableReferenceExpression(CodeVariableReferenceExpression expression) |
||||
{ |
||||
codeBuilder.Append(expression.VariableName); |
||||
} |
||||
|
||||
void AppendAttachEventStatement(CodeAttachEventStatement statement) |
||||
{ |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
AppendExpression(statement.Event.TargetObject); |
||||
codeBuilder.Append("."); |
||||
codeBuilder.Append(statement.Event.EventName); |
||||
|
||||
codeBuilder.Append(" += "); |
||||
|
||||
AppendExpression(statement.Listener); |
||||
|
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
void AppendDelegateCreateExpression(CodeDelegateCreateExpression expression) |
||||
{ |
||||
AppendExpression(expression.TargetObject); |
||||
codeBuilder.Append("."); |
||||
codeBuilder.Append(expression.MethodName); |
||||
} |
||||
|
||||
void GetResourceRootName(string rootNamespace, IComponent component) |
||||
{ |
||||
rootResourceName = component.Site.Name; |
||||
if (!String.IsNullOrEmpty(rootNamespace)) { |
||||
rootResourceName = rootNamespace + "." + rootResourceName; |
||||
} |
||||
} |
||||
|
||||
void AppendCastExpression(CodeCastExpression expression) |
||||
{ |
||||
AppendExpression(expression.Expression); |
||||
} |
||||
|
||||
bool IsInherited(string componentName) |
||||
{ |
||||
return IsInherited(serializationManager.GetInstance(componentName)); |
||||
} |
||||
|
||||
static bool IsInherited(object component) |
||||
{ |
||||
InheritanceAttribute attribute = GetInheritanceAttribute(component); |
||||
if (attribute != null) { |
||||
return attribute.InheritanceLevel != InheritanceLevel.NotInherited; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static InheritanceAttribute GetInheritanceAttribute(object component) |
||||
{ |
||||
if (component != null) { |
||||
AttributeCollection attributes = TypeDescriptor.GetAttributes(component); |
||||
return attributes[typeof(InheritanceAttribute)] as InheritanceAttribute; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -1,30 +0,0 @@
@@ -1,30 +0,0 @@
|
||||
// <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"; |
||||
} |
||||
} |
||||
} |
@ -1,119 +0,0 @@
@@ -1,119 +0,0 @@
|
||||
// <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.Drawing; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.ComponentModel.Design; |
||||
using System.Globalization; |
||||
using System.Reflection; |
||||
using System.Resources; |
||||
using System.Text; |
||||
using System.Windows.Forms; |
||||
using ICSharpCode.PythonBinding; |
||||
using ICSharpCode.TextEditor.Document; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a form or user control in the designer. Used to generate
|
||||
/// Python code after the form has been changed in the designer.
|
||||
/// </summary>
|
||||
public class PythonControl |
||||
{ |
||||
PythonCodeBuilder codeBuilder; |
||||
string indentString = String.Empty; |
||||
IResourceService resourceService; |
||||
|
||||
public PythonControl() |
||||
: this("\t") |
||||
{ |
||||
} |
||||
|
||||
public PythonControl(string indentString) |
||||
: this(indentString, null) |
||||
{ |
||||
this.indentString = indentString; |
||||
} |
||||
|
||||
public PythonControl(string indentString, IResourceService resourceService) |
||||
{ |
||||
this.indentString = indentString; |
||||
this.resourceService = resourceService; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates python code for the InitializeComponent method based on the controls added to the form.
|
||||
/// </summary>
|
||||
public string GenerateInitializeComponentMethod(Control control) |
||||
{ |
||||
return GenerateInitializeComponentMethod(control, String.Empty); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates python code for the InitializeComponent method based on the controls added to the form.
|
||||
/// </summary>
|
||||
public string GenerateInitializeComponentMethod(Control control, string rootNamespace) |
||||
{ |
||||
PythonCodeBuilder methodCodeBuilder = new PythonCodeBuilder(); |
||||
methodCodeBuilder.IndentString = indentString; |
||||
|
||||
methodCodeBuilder.AppendIndentedLine("def InitializeComponent(self):"); |
||||
|
||||
codeBuilder = new PythonCodeBuilder(); |
||||
codeBuilder.IndentString = indentString; |
||||
codeBuilder.IncreaseIndent(); |
||||
|
||||
PythonDesignerRootComponent rootComponent = GenerateInitializeComponentMethodBodyInternal(control, rootNamespace); |
||||
rootComponent.GenerateResources(resourceService); |
||||
|
||||
methodCodeBuilder.Append(codeBuilder.ToString()); |
||||
return methodCodeBuilder.ToString(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates the InitializeComponent method body.
|
||||
/// </summary>
|
||||
public string GenerateInitializeComponentMethodBody(Control control, int initialIndent) |
||||
{ |
||||
return GenerateInitializeComponentMethodBody(control, String.Empty, initialIndent); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates the InitializeComponent method body.
|
||||
/// </summary>
|
||||
public string GenerateInitializeComponentMethodBody(Control control, string rootNamespace, int initialIndent) |
||||
{ |
||||
codeBuilder = new PythonCodeBuilder(); |
||||
codeBuilder.IndentString = indentString; |
||||
|
||||
for (int i = 0; i < initialIndent; ++i) { |
||||
codeBuilder.IncreaseIndent(); |
||||
} |
||||
PythonDesignerRootComponent rootComponent = GenerateInitializeComponentMethodBodyInternal(control, rootNamespace); |
||||
rootComponent.GenerateResources(resourceService); |
||||
|
||||
return codeBuilder.ToString(); |
||||
} |
||||
|
||||
PythonDesignerRootComponent GenerateInitializeComponentMethodBodyInternal(Control control, string rootNamespace) |
||||
{ |
||||
PythonDesignerRootComponent rootDesignerComponent = PythonDesignerComponentFactory.CreateDesignerRootComponent(control, rootNamespace); |
||||
rootDesignerComponent.AppendCreateContainerComponents(codeBuilder); |
||||
rootDesignerComponent.AppendSupportInitializeComponentsBeginInit(codeBuilder); |
||||
rootDesignerComponent.AppendChildComponentsSuspendLayout(codeBuilder); |
||||
rootDesignerComponent.AppendSuspendLayout(codeBuilder); |
||||
rootDesignerComponent.AppendComponent(codeBuilder); |
||||
rootDesignerComponent.AppendChildComponentsResumeLayout(codeBuilder); |
||||
rootDesignerComponent.AppendSupportInitializeComponentsEndInit(codeBuilder); |
||||
rootDesignerComponent.AppendResumeLayout(codeBuilder); |
||||
return rootDesignerComponent; |
||||
} |
||||
} |
||||
} |
@ -1,954 +0,0 @@
@@ -1,954 +0,0 @@
|
||||
// <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; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.ComponentModel.Design; |
||||
using System.Globalization; |
||||
using System.Drawing; |
||||
using System.Reflection; |
||||
using System.Resources; |
||||
using System.Text; |
||||
using System.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Represents an IComponent in the designer.
|
||||
/// </summary>
|
||||
public class PythonDesignerComponent |
||||
{ |
||||
delegate void AppendCollectionContent(PythonCodeBuilder codeBuilder, object item, int count); |
||||
|
||||
IComponent component; |
||||
static readonly Attribute[] notDesignOnlyFilter = new Attribute[] { DesignOnlyAttribute.No }; |
||||
static readonly DesignerSerializationVisibility[] notHiddenDesignerVisibility = new DesignerSerializationVisibility[] { DesignerSerializationVisibility.Content, DesignerSerializationVisibility.Visible }; |
||||
static readonly DesignerSerializationVisibility[] contentDesignerVisibility = new DesignerSerializationVisibility[] { DesignerSerializationVisibility.Content }; |
||||
IEventBindingService eventBindingService; |
||||
PythonDesignerComponent parent; |
||||
Dictionary<string, object> resources = new Dictionary<string, object>(); |
||||
List<PythonDesignerComponent> designerContainerComponents; |
||||
|
||||
protected static readonly string[] suspendLayoutMethods = new string[] {"SuspendLayout()"}; |
||||
protected static readonly string[] resumeLayoutMethods = new string[] {"ResumeLayout(False)", "PerformLayout()"}; |
||||
|
||||
/// <summary>
|
||||
/// Used so the EventBindingService.GetEventProperty method can be called to get the property descriptor
|
||||
/// for an event.
|
||||
/// </summary>
|
||||
class PythonEventBindingService : EventBindingService |
||||
{ |
||||
public PythonEventBindingService() |
||||
: base(new ServiceContainer()) |
||||
{ |
||||
} |
||||
|
||||
protected override string CreateUniqueMethodName(IComponent component, EventDescriptor e) |
||||
{ |
||||
return String.Empty; |
||||
} |
||||
|
||||
protected override ICollection GetCompatibleMethods(EventDescriptor e) |
||||
{ |
||||
return new ArrayList(); |
||||
} |
||||
|
||||
protected override bool ShowCode() |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
protected override bool ShowCode(int lineNumber) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
protected override bool ShowCode(IComponent component, EventDescriptor e, string methodName) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public PythonDesignerComponent(IComponent component) |
||||
: this(null, component) |
||||
{ |
||||
} |
||||
|
||||
public PythonDesignerComponent(PythonDesignerComponent parent, IComponent component) |
||||
: this(parent, component, new PythonEventBindingService()) |
||||
{ |
||||
} |
||||
|
||||
PythonDesignerComponent(PythonDesignerComponent parent, IComponent component, IEventBindingService eventBindingService) |
||||
{ |
||||
this.parent = parent; |
||||
this.component = component; |
||||
this.eventBindingService = eventBindingService; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets a list of properties that should be serialized for the specified form.
|
||||
/// </summary>
|
||||
public static PropertyDescriptorCollection GetSerializableProperties(object obj) |
||||
{ |
||||
return GetSerializableProperties(obj, notHiddenDesignerVisibility); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets a list of properties that should have their content serialized for the specified form.
|
||||
/// </summary>
|
||||
public static PropertyDescriptorCollection GetSerializableContentProperties(object obj) |
||||
{ |
||||
return GetSerializableProperties(obj, contentDesignerVisibility); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the serializable properties with the specified designer serialization visibility.
|
||||
/// </summary>
|
||||
public static PropertyDescriptorCollection GetSerializableProperties(object obj, DesignerSerializationVisibility[] visibility) |
||||
{ |
||||
List<DesignerSerializationVisibility> requiredVisibility = new List<DesignerSerializationVisibility>(visibility); |
||||
List<PropertyDescriptor> properties = new List<PropertyDescriptor>(); |
||||
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(obj, notDesignOnlyFilter).Sort()) { |
||||
if (requiredVisibility.Contains(property.SerializationVisibility)) { |
||||
if (property.ShouldSerializeValue(obj)) { |
||||
properties.Add(property); |
||||
} |
||||
} |
||||
} |
||||
return new PropertyDescriptorCollection(properties.ToArray()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Checks whether the method is marked with the DesignerSerializationVisibility.Hidden attribute.
|
||||
/// </summary>
|
||||
public static bool IsHiddenFromDesignerSerializer(MethodInfo methodInfo) |
||||
{ |
||||
foreach (DesignerSerializationVisibilityAttribute attribute in methodInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true)) { |
||||
if (attribute.Visibility == DesignerSerializationVisibility.Hidden) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if the component has the DesignTimeVisible attribute set to false.
|
||||
/// </summary>
|
||||
public static bool IsHiddenFromDesigner(IComponent component) |
||||
{ |
||||
foreach (DesignTimeVisibleAttribute attribute in component.GetType().GetCustomAttributes(typeof(DesignTimeVisibleAttribute), true)) { |
||||
return !attribute.Visible; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the AddRange method on the object that is not hidden from the designer.
|
||||
/// </summary>
|
||||
public static MethodInfo GetAddRangeSerializationMethod(object obj) |
||||
{ |
||||
foreach (MethodInfo methodInfo in obj.GetType().GetMethods()) { |
||||
if (methodInfo.Name == "AddRange") { |
||||
ParameterInfo[] parameters = methodInfo.GetParameters(); |
||||
if (parameters.Length == 1) { |
||||
if (parameters[0].ParameterType.IsArray) { |
||||
if (!IsHiddenFromDesignerSerializer(methodInfo)) { |
||||
return methodInfo; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the component type.
|
||||
/// </summary>
|
||||
public Type GetComponentType() |
||||
{ |
||||
return component.GetType(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the Add serialization method that is not hidden from the designer.
|
||||
/// </summary>
|
||||
public static MethodInfo GetAddSerializationMethod(object obj) |
||||
{ |
||||
foreach (MethodInfo methodInfo in obj.GetType().GetMethods()) { |
||||
if (methodInfo.Name == "Add") { |
||||
return methodInfo; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the type used in the array for the first parameter to the method.
|
||||
/// </summary>
|
||||
public static Type GetArrayParameterType(MethodInfo methodInfo) |
||||
{ |
||||
if (methodInfo != null) { |
||||
ParameterInfo[] parameters = methodInfo.GetParameters(); |
||||
if (parameters.Length > 0) { |
||||
Type arrayType = parameters[0].ParameterType; |
||||
return arrayType.GetElementType(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends code that creates an instance of the component.
|
||||
/// </summary>
|
||||
public virtual void AppendCreateInstance(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
string parameters = String.Empty; |
||||
if (HasIContainerConstructor()) { |
||||
codeBuilder.InsertCreateComponentsContainer(); |
||||
parameters = "self._components"; |
||||
} |
||||
AppendComponentCreation(codeBuilder, component, parameters); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the code to create the child components.
|
||||
/// </summary>
|
||||
public void AppendCreateChildComponents(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
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() |
||||
{ |
||||
if (designerContainerComponents == null) { |
||||
designerContainerComponents = new List<PythonDesignerComponent>(); |
||||
ComponentCollection components = Component.Site.Container.Components; |
||||
for (int i = 1; i < components.Count; ++i) { |
||||
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(this, components[i]); |
||||
if (!designerComponent.IsInheritedReadOnly) { |
||||
designerContainerComponents.Add(designerComponent); |
||||
} |
||||
} |
||||
} |
||||
return designerContainerComponents.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the component's properties.
|
||||
/// </summary>
|
||||
public virtual void AppendComponent(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendComponentProperties(codeBuilder); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the object is an IComponent and has a non-null ISite.
|
||||
/// </summary>
|
||||
public static bool IsSitedComponent(object obj) |
||||
{ |
||||
IComponent component = obj as IComponent; |
||||
if (component != null) { |
||||
return component.Site != null; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether this designer component is sited.
|
||||
/// </summary>
|
||||
public bool IsSited { |
||||
get { return IsSitedComponent(component); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if the component has an InheritanceAttribute set to InheritanceLevel.Inherited or
|
||||
/// InheritanceLevel.InheritedReadOnly
|
||||
/// </summary>
|
||||
public static bool IsInheritedComponent(object component) |
||||
{ |
||||
if (component != null) { |
||||
InheritanceAttribute attribute = GetInheritanceAttribute(component); |
||||
return attribute.InheritanceLevel != InheritanceLevel.NotInherited; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if the component has an InheritanceAttribute set to InheritanceLevel.Inherited or
|
||||
/// InheritanceLevel.InheritedReadOnly
|
||||
/// </summary>
|
||||
public bool IsInherited { |
||||
get { return IsInheritedComponent(component); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if the component has an InheritanceAttribute set to InheritanceLevel.InheritedReadOnly
|
||||
/// </summary>
|
||||
public bool IsInheritedReadOnly { |
||||
get { |
||||
InheritanceAttribute attribute = GetInheritanceAttribute(component); |
||||
if (attribute != null) { |
||||
return attribute.InheritanceLevel == InheritanceLevel.InheritedReadOnly; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public static InheritanceAttribute GetInheritanceAttribute(object component) |
||||
{ |
||||
if (component != null) { |
||||
AttributeCollection attributes = TypeDescriptor.GetAttributes(component); |
||||
return attributes[typeof(InheritanceAttribute)] as InheritanceAttribute; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the child objects that need to be stored in the generated designer code on the specified object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For a MenuStrip the child components include the MenuStrip.Items.
|
||||
/// For a Control the child components include the Control.Controls.
|
||||
/// </remarks>
|
||||
public virtual PythonDesignerComponent[] GetChildComponents() |
||||
{ |
||||
List<PythonDesignerComponent> components = new List<PythonDesignerComponent>(); |
||||
foreach (PropertyDescriptor property in GetSerializableContentProperties(component)) { |
||||
ICollection collection = property.GetValue(component) as ICollection; |
||||
if (collection != null) { |
||||
foreach (object childObject in collection) { |
||||
IComponent childComponent = childObject as IComponent; |
||||
if (childComponent != null) { |
||||
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(this, childComponent); |
||||
if (designerComponent.IsSited) { |
||||
components.Add(designerComponent); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return components.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends SuspendLayout method call if the component has any sited child components.
|
||||
/// </summary>
|
||||
public virtual void AppendSuspendLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
if (HasSitedChildComponents()) { |
||||
AppendMethodCalls(codeBuilder, suspendLayoutMethods); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the ResumeLayout and PerformLayout method calls if the component has any sited
|
||||
/// child components.
|
||||
/// </summary>
|
||||
public virtual void AppendResumeLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
if (HasSitedChildComponents()) { |
||||
AppendMethodCalls(codeBuilder, resumeLayoutMethods); |
||||
} |
||||
} |
||||
|
||||
public void AppendChildComponentsSuspendLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendChildComponentsMethodCalls(codeBuilder, suspendLayoutMethods); |
||||
} |
||||
|
||||
public void AppendChildComponentsResumeLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendChildComponentsMethodCalls(codeBuilder, resumeLayoutMethods); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the code to create the specified object.
|
||||
/// </summary>
|
||||
public void AppendCreateInstance(PythonCodeBuilder codeBuilder, object obj, int count, object[] parameters) |
||||
{ |
||||
if (obj is String) { |
||||
// Do nothing.
|
||||
} else { |
||||
codeBuilder.AppendIndented(GetVariableName(obj, count) + " = " + obj.GetType().FullName); |
||||
|
||||
codeBuilder.Append("("); |
||||
for (int i = 0; i < parameters.Length; ++i) { |
||||
if (i > 0) { |
||||
codeBuilder.Append(", "); |
||||
} |
||||
object currentParameter = parameters[i]; |
||||
Array array = currentParameter as Array; |
||||
if (array != null) { |
||||
AppendSystemArray(codeBuilder, array.GetValue(0).GetType().FullName, currentParameter as ICollection); |
||||
codeBuilder.DecreaseIndent(); |
||||
} else { |
||||
codeBuilder.Append(PythonPropertyValueAssignment.ToString(currentParameter)); |
||||
} |
||||
} |
||||
codeBuilder.Append(")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the code to create the specified IComponent
|
||||
/// </summary>
|
||||
public void AppendComponentCreation(PythonCodeBuilder codeBuilder, IComponent component) |
||||
{ |
||||
AppendComponentCreation(codeBuilder, component, String.Empty); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the code to create the specified IComponent
|
||||
/// </summary>
|
||||
public void AppendComponentCreation(PythonCodeBuilder codeBuilder, IComponent component, string parameters) |
||||
{ |
||||
if (ShouldAppendCollectionContent) { |
||||
AppendForEachCollectionContent(codeBuilder, component, AppendCollectionContentCreation); |
||||
} |
||||
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, true); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates python code for an object's properties when the object is not an IComponent.
|
||||
/// </summary>
|
||||
public void AppendObjectProperties(PythonCodeBuilder codeBuilder, object obj, int count) |
||||
{ |
||||
AppendProperties(codeBuilder, PythonDesignerComponent.GetVariableName(obj, count), obj); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the comment lines containing the component name before the component has its properties set.
|
||||
/// </summary>
|
||||
///
|
||||
public void AppendComment(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
codeBuilder.AppendIndentedLine("# "); |
||||
codeBuilder.AppendIndentedLine("# " + component.Site.Name); |
||||
codeBuilder.AppendIndentedLine("# "); |
||||
} |
||||
|
||||
public bool HasSitedChildComponents() |
||||
{ |
||||
return HasSitedComponents(GetChildComponents()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the method calls for this component.
|
||||
/// </summary>
|
||||
public void AppendMethodCalls(PythonCodeBuilder codeBuilder, string[] methods) |
||||
{ |
||||
foreach (string method in methods) { |
||||
codeBuilder.AppendIndentedLine(GetPropertyOwnerName() + "." + method); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Looks for any collections that have objects that should be created as local variables
|
||||
/// in the InitializeComponent method.
|
||||
/// </summary>
|
||||
public void AppendCollectionContentCreation(PythonCodeBuilder codeBuilder, object item, int count) |
||||
{ |
||||
AppendCreateInstance(codeBuilder, item, count, new object[0]); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Looks for any collections that have objects that will have been added as local variables
|
||||
/// and appends their property values.
|
||||
/// </summary>
|
||||
public void AppendCollectionContentProperties(PythonCodeBuilder codeBuilder, object item, int count) |
||||
{ |
||||
AppendProperties(codeBuilder, GetVariableName(item, count), item); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the variable name for the specified type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The variable name is simply the type name with the first character in lower case followed by the
|
||||
/// count.
|
||||
/// </remarks>
|
||||
public static string GetVariableName(object obj, int count) |
||||
{ |
||||
string typeName = obj.GetType().Name; |
||||
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>
|
||||
/// <remarks>
|
||||
/// 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, bool reverse) |
||||
{ |
||||
ICollection collectionProperty = propertyDescriptor.GetValue(propertyOwner) as ICollection; |
||||
if (collectionProperty != null) { |
||||
MethodInfo addRangeMethod = GetAddRangeSerializationMethod(collectionProperty); |
||||
if (addRangeMethod != null) { |
||||
Type arrayElementType = GetArrayParameterType(addRangeMethod); |
||||
AppendSystemArray(codeBuilder, propertyOwnerName, propertyDescriptor.Name + "." + addRangeMethod.Name, arrayElementType.FullName, GetSitedComponentsAndNonComponents(collectionProperty)); |
||||
} 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) && !PythonDesignerComponent.IsInheritedComponent(collectionComponent)) { |
||||
codeBuilder.AppendIndentedLine(propertyOwnerName + "." + propertyDescriptor.Name + "." + addMethod.Name + "(self._" + collectionComponent.Site.Name + ")"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a property.
|
||||
/// </summary>
|
||||
public void AppendProperty(PythonCodeBuilder codeBuilder, string propertyOwnerName, object obj, PropertyDescriptor propertyDescriptor) |
||||
{ |
||||
object propertyValue = propertyDescriptor.GetValue(obj); |
||||
ExtenderProvidedPropertyAttribute extender = GetExtenderAttribute(propertyDescriptor); |
||||
if (extender != null) { |
||||
AppendExtenderProperty(codeBuilder, propertyOwnerName, extender, propertyDescriptor, propertyValue); |
||||
} else if (propertyDescriptor.SerializationVisibility == DesignerSerializationVisibility.Visible) { |
||||
string propertyName = propertyOwnerName + "." + propertyDescriptor.Name; |
||||
IComponent component = propertyValue as IComponent; |
||||
if (component != null) { |
||||
string componentRef = GetComponentReference(component); |
||||
if (componentRef != null) { |
||||
codeBuilder.AppendIndentedLine(propertyName + " = " + componentRef); |
||||
} |
||||
} else if (IsResourcePropertyValue(propertyValue)) { |
||||
AppendResourceProperty(codeBuilder, propertyName, propertyValue); |
||||
} else if (IsArray(propertyValue)) { |
||||
codeBuilder.AppendIndented(propertyName + " = "); |
||||
AppendSystemArray(codeBuilder, GetArrayType(propertyValue).FullName, propertyValue as ICollection, false); |
||||
codeBuilder.AppendLine(); |
||||
} else { |
||||
codeBuilder.AppendIndentedLine(propertyName + " = " + PythonPropertyValueAssignment.ToString(propertyValue)); |
||||
} |
||||
} else { |
||||
// DesignerSerializationVisibility.Content
|
||||
AppendPropertyContents(codeBuilder, propertyOwnerName, obj, propertyDescriptor); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends an extender provider property.
|
||||
/// </summary>
|
||||
public void AppendExtenderProperty(PythonCodeBuilder codeBuilder, string propertyOwnerName, ExtenderProvidedPropertyAttribute extender, PropertyDescriptor propertyDescriptor, object propertyValue) |
||||
{ |
||||
PythonDesignerComponent designerComponent = PythonDesignerComponentFactory.CreateDesignerComponent(extender.Provider as IComponent); |
||||
codeBuilder.AppendIndented(designerComponent.GetPropertyOwnerName()); |
||||
codeBuilder.Append(".Set" + propertyDescriptor.Name); |
||||
codeBuilder.Append("("); |
||||
codeBuilder.Append(propertyOwnerName); |
||||
codeBuilder.Append(", "); |
||||
codeBuilder.Append(PythonPropertyValueAssignment.ToString(propertyValue)); |
||||
codeBuilder.Append(")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a property whose value is a resource.
|
||||
/// </summary>
|
||||
public void AppendResourceProperty(PythonCodeBuilder codeBuilder, string propertyName, object propertyValue) |
||||
{ |
||||
string resourceName = propertyName.Replace("self._", String.Empty); |
||||
resourceName = resourceName.Replace("self.", "$this."); |
||||
codeBuilder.AppendIndented(propertyName); |
||||
codeBuilder.Append(" = resources.GetObject(\""); |
||||
codeBuilder.Append(resourceName); |
||||
codeBuilder.Append("\")"); |
||||
codeBuilder.AppendLine(); |
||||
|
||||
resources.Add(resourceName, propertyValue); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if the property value will be obtained from a resource.
|
||||
/// </summary>
|
||||
public static bool IsResourcePropertyValue(object propertyValue) |
||||
{ |
||||
return (propertyValue is Image) || (propertyValue is Icon) || (propertyValue is ImageListStreamer); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the properties of the object to the code builder.
|
||||
/// </summary>
|
||||
public void AppendProperties(PythonCodeBuilder codeBuilder, string propertyOwnerName, object obj) |
||||
{ |
||||
foreach (PropertyDescriptor property in GetSerializableProperties(obj)) { |
||||
if (!IgnoreProperty(property)) { |
||||
AppendProperty(codeBuilder, propertyOwnerName, obj, property); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the properties of the component.
|
||||
/// </summary>
|
||||
public void AppendProperties(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
if (ShouldAppendCollectionContent) { |
||||
AppendForEachCollectionContent(codeBuilder, component, AppendCollectionContentProperties); |
||||
} |
||||
|
||||
AppendProperties(codeBuilder, GetPropertyOwnerName(), component); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates python code for the component.
|
||||
/// </summary>
|
||||
public void AppendComponentProperties(PythonCodeBuilder codeBuilder, bool addComponentNameToProperty, bool addComment) |
||||
{ |
||||
PythonCodeBuilder propertiesBuilder = new PythonCodeBuilder(codeBuilder.Indent); |
||||
propertiesBuilder.IndentString = codeBuilder.IndentString; |
||||
|
||||
AppendProperties(propertiesBuilder); |
||||
AppendEventHandlers(propertiesBuilder, eventBindingService); |
||||
|
||||
// Add comment if we have added some properties or event handlers.
|
||||
if (addComment && propertiesBuilder.Length > 0) { |
||||
AppendComment(codeBuilder); |
||||
} |
||||
codeBuilder.Append(propertiesBuilder.ToString()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Generates code that wires an event to an event handler.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that the EventDescriptorCollection.Sort method does not work if the
|
||||
/// enumerator is called first. Sorting will only occur if an item is retrieved after calling
|
||||
/// Sort or CopyTo is called. The PropertyDescriptorCollection class does not behave
|
||||
/// in the same way.</remarks>
|
||||
public void AppendEventHandlers(PythonCodeBuilder codeBuilder, IEventBindingService eventBindingService) |
||||
{ |
||||
EventDescriptorCollection events = TypeDescriptor.GetEvents(component, notDesignOnlyFilter).Sort(); |
||||
if (events.Count > 0) { |
||||
EventDescriptor dummyEventDescriptor = events[0]; |
||||
} |
||||
foreach (EventDescriptor eventDescriptor in events) { |
||||
AppendEventHandler(codeBuilder, component, eventDescriptor, eventBindingService); |
||||
} |
||||
} |
||||
|
||||
void AppendEventHandler(PythonCodeBuilder codeBuilder, object component, EventDescriptor eventDescriptor, IEventBindingService eventBindingService) |
||||
{ |
||||
PropertyDescriptor propertyDescriptor = eventBindingService.GetEventProperty(eventDescriptor); |
||||
if (propertyDescriptor.ShouldSerializeValue(component)) { |
||||
string methodName = (string)propertyDescriptor.GetValue(component); |
||||
codeBuilder.AppendIndentedLine(GetPropertyOwnerName() + "." + eventDescriptor.Name + " += self." + methodName); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the owner of any properties generated (e.g. "self._textBox1").
|
||||
/// For an inherited component the actual component name is used without any underscore prefix.
|
||||
/// </summary>
|
||||
public virtual string GetPropertyOwnerName() |
||||
{ |
||||
string componentName = component.Site.Name; |
||||
if (IsInherited) { |
||||
return "self." + componentName; |
||||
} |
||||
return "self._" + componentName; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the component has a constructor that takes a single IContainer parameter.
|
||||
/// </summary>
|
||||
public bool HasIContainerConstructor() |
||||
{ |
||||
foreach (ConstructorInfo constructor in GetComponentType().GetConstructors()) { |
||||
ParameterInfo[] parameters = constructor.GetParameters(); |
||||
if (parameters.Length == 1) { |
||||
ParameterInfo parameter = parameters[0]; |
||||
if (parameter.ParameterType.IsAssignableFrom(typeof(IContainer))) { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Writes resources for this component to the resource writer.
|
||||
/// </summary>
|
||||
public void GenerateResources(IResourceWriter writer) |
||||
{ |
||||
foreach (KeyValuePair<string, object> entry in resources) { |
||||
writer.AddResource(entry.Key, entry.Value); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if this component has any properties that are resources.
|
||||
/// </summary>
|
||||
public bool HasResources { |
||||
get { return resources.Count > 0; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of this component.
|
||||
/// </summary>
|
||||
public PythonDesignerComponent Parent { |
||||
get { return parent; } |
||||
} |
||||
|
||||
public static void AppendSystemArray(PythonCodeBuilder codeBuilder, string propertyName, string methodName, string typeName, ICollection components) |
||||
{ |
||||
if (components.Count > 0) { |
||||
codeBuilder.AppendIndented(propertyName + "." + methodName + "("); |
||||
AppendSystemArray(codeBuilder, typeName, components); |
||||
codeBuilder.Append(")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
} |
||||
|
||||
public static void AppendSystemArray(PythonCodeBuilder codeBuilder, string typeName, ICollection components) |
||||
{ |
||||
AppendSystemArray(codeBuilder, typeName, components, true); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends an array.
|
||||
/// </summary>
|
||||
/// <param name="localVariables">Indicates that the array is for an AddRange method that
|
||||
/// requires the code to reference local variables.</param>
|
||||
public static void AppendSystemArray(PythonCodeBuilder codeBuilder, string typeName, ICollection components, bool localVariables) |
||||
{ |
||||
if (components.Count > 0) { |
||||
codeBuilder.Append("System.Array[" + typeName + "]("); |
||||
codeBuilder.AppendLine(); |
||||
codeBuilder.IncreaseIndent(); |
||||
int i = 0; |
||||
foreach (object component in components) { |
||||
if (i == 0) { |
||||
codeBuilder.AppendIndented("["); |
||||
} else { |
||||
codeBuilder.Append(","); |
||||
codeBuilder.AppendLine(); |
||||
codeBuilder.AppendIndented(String.Empty); |
||||
} |
||||
if (component is IComponent) { |
||||
codeBuilder.Append("self._" + ((IComponent)component).Site.Name); |
||||
} else if (component is String) { |
||||
codeBuilder.Append(PythonPropertyValueAssignment.ToString(component)); |
||||
} else if (component is IArrayItem) { |
||||
codeBuilder.Append(((IArrayItem)component).Name); |
||||
} else if (localVariables) { |
||||
codeBuilder.Append(GetVariableName(component, i + 1)); |
||||
} else { |
||||
codeBuilder.Append(PythonPropertyValueAssignment.ToString(component)); |
||||
} |
||||
++i; |
||||
} |
||||
codeBuilder.Append("])"); |
||||
} |
||||
codeBuilder.DecreaseIndent(); |
||||
} |
||||
|
||||
protected IComponent Component { |
||||
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; |
||||
} |
||||
|
||||
protected virtual bool ShouldAppendCollectionContent { |
||||
get { return true; } |
||||
} |
||||
|
||||
static bool HasSitedComponents(PythonDesignerComponent[] components) |
||||
{ |
||||
foreach (PythonDesignerComponent component in components) { |
||||
if (component.IsSited && !component.IsInherited) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void AppendCreateChildComponents(PythonCodeBuilder codeBuilder, PythonDesignerComponent[] childComponents) |
||||
{ |
||||
foreach (PythonDesignerComponent designerComponent in childComponents) { |
||||
if (designerComponent.IsSited && !designerComponent.IsInherited) { |
||||
designerComponent.AppendCreateInstance(codeBuilder); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the sited components in the collection. If an object in the collection is not
|
||||
/// an IComponent then this is added to the collection.
|
||||
/// </summary>
|
||||
static ICollection GetSitedComponentsAndNonComponents(ICollection components) |
||||
{ |
||||
List<object> sitedComponents = new List<object>(); |
||||
foreach (object obj in components) { |
||||
IComponent component = obj as IComponent; |
||||
if (component == null || IsSitedComponent(component)) { |
||||
sitedComponents.Add(obj); |
||||
} |
||||
} |
||||
return sitedComponents.ToArray(); |
||||
} |
||||
|
||||
void AppendChildComponentsMethodCalls(PythonCodeBuilder codeBuilder, string[] methods) |
||||
{ |
||||
foreach (PythonDesignerComponent designerComponent in GetChildComponents()) { |
||||
if (typeof(Control).IsAssignableFrom(designerComponent.GetComponentType())) { |
||||
if (designerComponent.HasSitedChildComponents()) { |
||||
designerComponent.AppendMethodCalls(codeBuilder, methods); |
||||
} |
||||
} |
||||
designerComponent.AppendChildComponentsMethodCalls(codeBuilder, methods); |
||||
} |
||||
} |
||||
|
||||
bool IsRootComponent(IComponent component) |
||||
{ |
||||
if (parent == null) { |
||||
return this.component == component; |
||||
} |
||||
return parent.IsRootComponent(component); |
||||
} |
||||
|
||||
string GetComponentReference(IComponent component) |
||||
{ |
||||
if (IsRootComponent(component)) { |
||||
return "self"; |
||||
} else { |
||||
foreach (PythonDesignerComponent designerComponent in GetContainerComponents()) { |
||||
string name = component.Site.Name; |
||||
if ((designerComponent.component == component) && (!String.IsNullOrEmpty(name))) { |
||||
return "self._" + name; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static ExtenderProvidedPropertyAttribute GetExtenderAttribute(PropertyDescriptor property) |
||||
{ |
||||
foreach (Attribute attribute in property.Attributes) { |
||||
ExtenderProvidedPropertyAttribute extenderAttribute = attribute as ExtenderProvidedPropertyAttribute; |
||||
if (extenderAttribute != null) { |
||||
return extenderAttribute; |
||||
} |
||||
} |
||||
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; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends a property that needs its contents serialized.
|
||||
/// </summary>
|
||||
void AppendPropertyContents(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor) |
||||
{ |
||||
object propertyValue = propertyDescriptor.GetValue(propertyOwner); |
||||
if (propertyValue is ICollection) { |
||||
AppendMethodCallWithArrayParameter(codeBuilder, propertyOwnerName, propertyOwner, propertyDescriptor); |
||||
} else { |
||||
propertyOwnerName += "." + propertyDescriptor.Name; |
||||
AppendProperties(codeBuilder, propertyOwnerName, propertyValue); |
||||
} |
||||
} |
||||
|
||||
static Type GetArrayType(object obj) |
||||
{ |
||||
Type type = obj.GetType(); |
||||
return obj.GetType().GetElementType(); |
||||
} |
||||
|
||||
static bool IsArray(object obj) |
||||
{ |
||||
if (obj != null) { |
||||
return obj.GetType().IsArray; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Calls the AppendCollectionContent method for every item in all collections that need their content
|
||||
/// serialized.
|
||||
/// </summary>
|
||||
void AppendForEachCollectionContent(PythonCodeBuilder codeBuilder, object component, AppendCollectionContent appendCollectionContent) |
||||
{ |
||||
foreach (PropertyDescriptor propertyDescriptor in GetSerializableContentProperties(component)) { |
||||
object propertyValue = propertyDescriptor.GetValue(component); |
||||
ICollection collection = propertyValue as ICollection; |
||||
if (collection != null) { |
||||
int count = 1; |
||||
foreach (object item in collection) { |
||||
if (item is IComponent) { |
||||
// Ignore.
|
||||
} else { |
||||
appendCollectionContent(codeBuilder, item, count); |
||||
} |
||||
++count; |
||||
} |
||||
} else { |
||||
// Try child collections.
|
||||
AppendForEachCollectionContent(codeBuilder, propertyValue, appendCollectionContent); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,57 +0,0 @@
@@ -1,57 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonDesignerComponentFactory |
||||
{ |
||||
PythonDesignerComponentFactory() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a PythonDesignerComponent class for the specified component.
|
||||
/// </summary>
|
||||
public static PythonDesignerComponent CreateDesignerComponent(IComponent component) |
||||
{ |
||||
return CreateDesignerComponent(null, component); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a PythonDesignerComponent class for the specified component.
|
||||
/// </summary>
|
||||
public static PythonDesignerComponent CreateDesignerComponent(PythonDesignerComponent parent, IComponent component) |
||||
{ |
||||
if (component is ListView) { |
||||
return new PythonListViewComponent(parent, component); |
||||
} else if (component is ContextMenuStrip) { |
||||
return new PythonContextMenuComponent(parent, component); |
||||
} else if (component is ImageList) { |
||||
return new PythonImageListComponent(parent, component); |
||||
} else if (component is TreeView) { |
||||
return new PythonTreeViewComponent(parent, component); |
||||
} else if (component is TableLayoutPanel) { |
||||
return new PythonTableLayoutPanelComponent(parent, component); |
||||
} |
||||
return new PythonDesignerComponent(parent, component); |
||||
} |
||||
|
||||
public static PythonDesignerRootComponent CreateDesignerRootComponent(IComponent component) |
||||
{ |
||||
return CreateDesignerRootComponent(component, String.Empty); |
||||
} |
||||
|
||||
public static PythonDesignerRootComponent CreateDesignerRootComponent(IComponent component, string rootNamespace) |
||||
{ |
||||
return new PythonDesignerRootComponent(component, rootNamespace); |
||||
} |
||||
} |
||||
} |
@ -1,169 +0,0 @@
@@ -1,169 +0,0 @@
|
||||
// <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.Globalization; |
||||
using System.Reflection; |
||||
using System.Resources; |
||||
using System.Text; |
||||
using System.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a root component in the designer.
|
||||
/// </summary>
|
||||
public class PythonDesignerRootComponent : PythonDesignerComponent |
||||
{ |
||||
string rootNamespace = String.Empty; |
||||
|
||||
public PythonDesignerRootComponent(IComponent component) |
||||
: this(component, String.Empty) |
||||
{ |
||||
} |
||||
|
||||
public PythonDesignerRootComponent(IComponent component, string rootNamespace) |
||||
: base(null, component) |
||||
{ |
||||
this.rootNamespace = rootNamespace; |
||||
} |
||||
|
||||
public override string GetPropertyOwnerName() |
||||
{ |
||||
return "self"; |
||||
} |
||||
|
||||
public override void AppendSuspendLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendMethodCalls(codeBuilder, suspendLayoutMethods); |
||||
} |
||||
|
||||
public override void AppendResumeLayout(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendMethodCalls(codeBuilder, resumeLayoutMethods); |
||||
} |
||||
|
||||
public override void AppendComponent(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
// Add the child components first.
|
||||
foreach (PythonDesignerComponent component in GetContainerComponents()) { |
||||
component.AppendComponent(codeBuilder); |
||||
} |
||||
|
||||
// Add root component
|
||||
AppendComponentProperties(codeBuilder, false, true); |
||||
if (HasAddedResources()) { |
||||
InsertCreateResourceManagerLine(codeBuilder); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds BeginInit method call for any components that implement the
|
||||
/// System.ComponentModel.ISupportInitialize interface.
|
||||
/// </summary>
|
||||
public void AppendSupportInitializeComponentsBeginInit(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendSupportInitializeMethodCalls(codeBuilder, new string[] {"BeginInit()"}); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds EndInit method call for any that implement the
|
||||
/// System.ComponentModel.ISupportInitialize interface.
|
||||
/// </summary>
|
||||
public void AppendSupportInitializeComponentsEndInit(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendSupportInitializeMethodCalls(codeBuilder, new string[] {"EndInit()"}); |
||||
} |
||||
|
||||
public void AppendSupportInitializeMethodCalls(PythonCodeBuilder codeBuilder, string[] methods) |
||||
{ |
||||
foreach (PythonDesignerComponent component in GetContainerComponents()) { |
||||
if (typeof(ISupportInitialize).IsAssignableFrom(component.GetComponentType())) { |
||||
component.AppendMethodCalls(codeBuilder, methods); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <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); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Writes resources to file.
|
||||
/// </summary>
|
||||
public void GenerateResources(IResourceService resourceService) |
||||
{ |
||||
if (resourceService == null) { |
||||
return; |
||||
} |
||||
|
||||
using (IResourceWriter writer = resourceService.GetResourceWriter(CultureInfo.InvariantCulture)) { |
||||
foreach (PythonDesignerComponent component in GetContainerComponents()) { |
||||
component.GenerateResources(writer); |
||||
} |
||||
GenerateResources(writer); |
||||
} |
||||
} |
||||
|
||||
public string GetResourceRootName() |
||||
{ |
||||
string componentName = Component.Site.Name; |
||||
if (!String.IsNullOrEmpty(rootNamespace)) { |
||||
return rootNamespace + "." + componentName; |
||||
} |
||||
return componentName; |
||||
} |
||||
|
||||
void InsertCreateResourceManagerLine(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
StringBuilder line = new StringBuilder(); |
||||
line.Append("resources = System.Resources.ResourceManager(\""); |
||||
line.Append(GetRootComponentRootResourceName()); |
||||
line.Append("\", System.Reflection.Assembly.GetEntryAssembly())"); |
||||
codeBuilder.InsertIndentedLine(line.ToString()); |
||||
} |
||||
|
||||
string GetRootComponentRootResourceName() |
||||
{ |
||||
PythonDesignerComponent component = this; |
||||
while (component != null) { |
||||
if (component.Parent == null) { |
||||
PythonDesignerRootComponent rootComponent = component as PythonDesignerRootComponent; |
||||
return rootComponent.GetResourceRootName(); |
||||
} |
||||
component = component.Parent; |
||||
} |
||||
return String.Empty; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns true if a resource has been added to any of the form components.
|
||||
/// </summary>
|
||||
bool HasAddedResources() |
||||
{ |
||||
if (HasResources) { |
||||
return true; |
||||
} |
||||
|
||||
foreach (PythonDesignerComponent component in GetContainerComponents()) { |
||||
if (component.HasResources) { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonDesignerTreeNode : IArrayItem |
||||
{ |
||||
TreeNode node; |
||||
int num; |
||||
List<PythonDesignerTreeNode> childNodes = new List<PythonDesignerTreeNode>(); |
||||
|
||||
public PythonDesignerTreeNode(TreeNode node, int num) |
||||
{ |
||||
this.node = node; |
||||
this.num = num; |
||||
} |
||||
|
||||
public TreeNode TreeNode { |
||||
get { return node; } |
||||
} |
||||
|
||||
public int Number { |
||||
get { return num; } |
||||
} |
||||
|
||||
public string Name { |
||||
get { return "treeNode" + num.ToString(); } |
||||
} |
||||
|
||||
public List<PythonDesignerTreeNode> ChildNodes { |
||||
get { return childNodes; } |
||||
} |
||||
} |
||||
} |
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonImageListComponent : PythonDesignerComponent |
||||
{ |
||||
public PythonImageListComponent(IComponent component) : this(null, component) |
||||
{ |
||||
} |
||||
|
||||
public PythonImageListComponent(PythonDesignerComponent parent, IComponent component) |
||||
: base(parent, component) |
||||
{ |
||||
} |
||||
|
||||
public override void AppendComponent(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
base.AppendComponent(codeBuilder); |
||||
|
||||
// Add image list keys.
|
||||
ImageList imageList = (ImageList)Component; |
||||
for (int i = 0; i < imageList.Images.Keys.Count; ++i) { |
||||
codeBuilder.AppendIndented(GetPropertyOwnerName()); |
||||
codeBuilder.Append(".Images.SetKeyName("); |
||||
codeBuilder.Append(i.ToString()); |
||||
codeBuilder.Append(", \""); |
||||
codeBuilder.Append(imageList.Images.Keys[i]); |
||||
codeBuilder.Append("\")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,144 +0,0 @@
@@ -1,144 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Used to generate code for a ListView component currently being designed.
|
||||
/// </summary>
|
||||
public class PythonListViewComponent : PythonDesignerComponent |
||||
{ |
||||
public PythonListViewComponent(IComponent component) : this(null, component) |
||||
{ |
||||
} |
||||
|
||||
public PythonListViewComponent(PythonDesignerComponent parent, IComponent component) |
||||
: base(parent, component) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends code that creates an instance of the list view.
|
||||
/// </summary>
|
||||
public override void AppendCreateInstance(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
// Append list view item creation first.
|
||||
int count = 1; |
||||
foreach (ListViewItem item in GetListViewItems(Component)) { |
||||
AppendCreateInstance(codeBuilder, item, count, GetConstructorParameters(item)); |
||||
++count; |
||||
} |
||||
|
||||
// Append list view group creation.
|
||||
count = 1; |
||||
foreach (ListViewGroup group in GetListViewGroups(Component)) { |
||||
AppendCreateInstance(codeBuilder, group, count, new object[0]); |
||||
++count; |
||||
} |
||||
|
||||
// Append list view creation.
|
||||
base.AppendCreateInstance(codeBuilder); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the component's properties.
|
||||
/// </summary>
|
||||
public override void AppendComponent(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendComment(codeBuilder); |
||||
AppendListViewItemProperties(codeBuilder); |
||||
AppendListViewGroupProperties(codeBuilder); |
||||
AppendComponentProperties(codeBuilder, true, false); |
||||
} |
||||
|
||||
protected override bool ShouldAppendCollectionContent { |
||||
get { return false; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the parameters to the ListViewItem constructor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The constructors that are used:
|
||||
/// ListViewItem()
|
||||
/// ListViewItem(string text)
|
||||
/// ListViewItem(string[] subItems)
|
||||
/// ListViewItem(string text, int imageIndex)
|
||||
/// ListViewItem(string text, string imageKey)
|
||||
/// </remarks>
|
||||
object[] GetConstructorParameters(ListViewItem item) |
||||
{ |
||||
if (item.SubItems.Count > 1) { |
||||
string[] subItems = new string[item.SubItems.Count]; |
||||
for (int i = 0; i < item.SubItems.Count; ++i) { |
||||
subItems[i] = item.SubItems[i].Text; |
||||
} |
||||
return new object[] {subItems}; |
||||
} |
||||
|
||||
if (item.ImageIndex != -1) { |
||||
return GetConstructorParameters(item.Text, item.ImageIndex); |
||||
} |
||||
|
||||
if (!String.IsNullOrEmpty(item.ImageKey)) { |
||||
return GetConstructorParameters(item.Text, item.ImageKey); |
||||
} |
||||
|
||||
if (String.IsNullOrEmpty(item.Text)) { |
||||
return new object[0]; |
||||
} |
||||
return new object[] {item.Text}; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates an object array:
|
||||
/// [0] = text.
|
||||
/// [1] = obj.
|
||||
/// </summary>
|
||||
object[] GetConstructorParameters(string text, object obj) |
||||
{ |
||||
if (String.IsNullOrEmpty(text)) { |
||||
text = String.Empty; |
||||
} |
||||
return new object[] {text, obj}; |
||||
} |
||||
|
||||
static ListView.ListViewItemCollection GetListViewItems(IComponent component) |
||||
{ |
||||
ListView listView = (ListView)component; |
||||
return listView.Items; |
||||
} |
||||
|
||||
static ListViewGroupCollection GetListViewGroups(IComponent component) |
||||
{ |
||||
ListView listView = (ListView)component; |
||||
return listView.Groups; |
||||
} |
||||
|
||||
void AppendListViewItemProperties(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
int count = 1; |
||||
foreach (ListViewItem item in GetListViewItems(Component)) { |
||||
AppendObjectProperties(codeBuilder, item, count); |
||||
++count; |
||||
} |
||||
} |
||||
|
||||
void AppendListViewGroupProperties(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
int count = 1; |
||||
foreach (ListViewGroup item in GetListViewGroups(Component)) { |
||||
AppendObjectProperties(codeBuilder, item, count); |
||||
++count; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,75 +0,0 @@
@@ -1,75 +0,0 @@
|
||||
// <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; |
||||
using System.ComponentModel; |
||||
using System.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonTableLayoutPanelComponent : PythonDesignerComponent |
||||
{ |
||||
public PythonTableLayoutPanelComponent(PythonDesignerComponent parent, IComponent component) |
||||
: base(parent, component) |
||||
{ |
||||
} |
||||
|
||||
public override void AppendMethodCallWithArrayParameter(PythonCodeBuilder codeBuilder, string propertyOwnerName, object propertyOwner, PropertyDescriptor propertyDescriptor) |
||||
{ |
||||
if (IsStylesProperty(propertyDescriptor.Name)) { |
||||
ICollection collection = propertyDescriptor.GetValue(propertyOwner) as ICollection; |
||||
if (collection != null) { |
||||
AppendStylesCollection(codeBuilder, collection, propertyOwnerName); |
||||
} |
||||
} else { |
||||
base.AppendMethodCallWithArrayParameter(codeBuilder, propertyOwnerName, propertyOwner, propertyDescriptor); |
||||
} |
||||
} |
||||
|
||||
protected override bool ShouldAppendCollectionContent { |
||||
get { return false; } |
||||
} |
||||
|
||||
bool IsStylesProperty(string name) |
||||
{ |
||||
return "ColumnStyles".Equals(name, StringComparison.InvariantCultureIgnoreCase) || "RowStyles".Equals(name, StringComparison.InvariantCultureIgnoreCase); |
||||
} |
||||
|
||||
void AppendStylesCollection(PythonCodeBuilder codeBuilder, ICollection collection, string propertyOwnerName) |
||||
{ |
||||
string newPropertyOwnerName = propertyOwnerName; |
||||
SizeType sizeType = SizeType.Absolute; |
||||
float width = 0; |
||||
foreach (object item in collection) { |
||||
ColumnStyle columnStyle = item as ColumnStyle; |
||||
RowStyle rowStyle = item as RowStyle; |
||||
if (columnStyle != null) { |
||||
sizeType = columnStyle.SizeType; |
||||
width = columnStyle.Width; |
||||
newPropertyOwnerName = propertyOwnerName + ".ColumnStyles"; |
||||
} |
||||
if (rowStyle != null) { |
||||
sizeType = rowStyle.SizeType; |
||||
width = rowStyle.Height; |
||||
newPropertyOwnerName = propertyOwnerName + ".RowStyles"; |
||||
} |
||||
AppendStyle(codeBuilder, newPropertyOwnerName, item.GetType(), sizeType, width); |
||||
} |
||||
} |
||||
|
||||
void AppendStyle(PythonCodeBuilder codeBuilder, string propertyOwnerName, Type type, SizeType sizeType, float value) |
||||
{ |
||||
codeBuilder.AppendIndented(propertyOwnerName + ".Add("); |
||||
codeBuilder.Append(type.FullName + "("); |
||||
codeBuilder.Append(typeof(SizeType).FullName + "." + sizeType + ", "); |
||||
codeBuilder.Append(value + ")"); |
||||
codeBuilder.Append(")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
} |
||||
} |
@ -1,109 +0,0 @@
@@ -1,109 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Used to generate code for a TreeView component currently being designed.
|
||||
/// </summary>
|
||||
public class PythonTreeViewComponent : PythonDesignerComponent |
||||
{ |
||||
List<PythonDesignerTreeNode> rootTreeNodes; |
||||
int treeNodeCount = 1; |
||||
|
||||
public PythonTreeViewComponent(IComponent component) : this(null, component) |
||||
{ |
||||
} |
||||
|
||||
public PythonTreeViewComponent(PythonDesignerComponent parent, IComponent component) |
||||
: base(parent, component) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends code that creates an instance of the tree view.
|
||||
/// </summary>
|
||||
public override void AppendCreateInstance(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
// Append tree node creation first.
|
||||
AppendCreateInstance(codeBuilder, GetRootTreeNodes(Component)); |
||||
|
||||
// Append tree view creation.
|
||||
base.AppendCreateInstance(codeBuilder); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Appends the component's properties.
|
||||
/// </summary>
|
||||
public override void AppendComponent(PythonCodeBuilder codeBuilder) |
||||
{ |
||||
AppendComment(codeBuilder); |
||||
AppendTreeNodeProperties(codeBuilder, GetRootTreeNodes(Component)); |
||||
AppendComponentProperties(codeBuilder, true, false); |
||||
} |
||||
|
||||
protected override bool ShouldAppendCollectionContent { |
||||
get { return false; } |
||||
} |
||||
|
||||
void AppendCreateInstance(PythonCodeBuilder codeBuilder, List<PythonDesignerTreeNode> nodes) |
||||
{ |
||||
object[] parameters = new object[0]; |
||||
foreach (PythonDesignerTreeNode node in nodes) { |
||||
AppendCreateInstance(codeBuilder, node.TreeNode, node.Number, parameters); |
||||
AppendCreateInstance(codeBuilder, node.ChildNodes); |
||||
} |
||||
} |
||||
|
||||
List<PythonDesignerTreeNode> GetRootTreeNodes(IComponent component) |
||||
{ |
||||
if (rootTreeNodes == null) { |
||||
rootTreeNodes = new List<PythonDesignerTreeNode>(); |
||||
|
||||
TreeView treeView = (TreeView)component; |
||||
AddTreeNodes(rootTreeNodes, treeView.Nodes); |
||||
} |
||||
return rootTreeNodes; |
||||
} |
||||
|
||||
void AddTreeNodes(List<PythonDesignerTreeNode> designerNodes, TreeNodeCollection nodes) |
||||
{ |
||||
foreach (TreeNode node in nodes) { |
||||
PythonDesignerTreeNode designerNode = new PythonDesignerTreeNode(node, treeNodeCount); |
||||
designerNodes.Add(designerNode); |
||||
++treeNodeCount; |
||||
|
||||
// Add child nodes.
|
||||
AddTreeNodes(designerNode.ChildNodes, node.Nodes); |
||||
} |
||||
} |
||||
|
||||
void AppendTreeNodeProperties(PythonCodeBuilder codeBuilder, List<PythonDesignerTreeNode> nodes) |
||||
{ |
||||
foreach (PythonDesignerTreeNode node in nodes) { |
||||
AppendObjectProperties(codeBuilder, node.TreeNode, node.Number); |
||||
|
||||
// Append child nodes to parent tree node.
|
||||
if (node.ChildNodes.Count > 0) { |
||||
codeBuilder.AppendIndented(node.Name); |
||||
codeBuilder.Append(".Nodes.AddRange("); |
||||
AppendSystemArray(codeBuilder, typeof(TreeNode).FullName, node.ChildNodes); |
||||
codeBuilder.Append(")"); |
||||
codeBuilder.AppendLine(); |
||||
} |
||||
|
||||
// Append child node properties.
|
||||
AppendTreeNodeProperties(codeBuilder, node.ChildNodes); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
// <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.Drawing; |
||||
using System.Windows.Forms; |
||||
using ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
/// <summary>
|
||||
/// Tests that the control's BeginInit and EndInit methods are called.
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class CallBeginInitOnLoadTestFixture : LoadFormTestFixtureBase |
||||
{ |
||||
public override string PythonCode { |
||||
get { |
||||
ComponentCreator.AddType("PythonBinding.Tests.Utils.SupportInitCustomControl", typeof(SupportInitCustomControl)); |
||||
|
||||
return "class TestForm(System.Windows.Forms.Form):\r\n" + |
||||
" def InitializeComponent(self):\r\n" + |
||||
" self._control = PythonBinding.Tests.Utils.SupportInitCustomControl()\r\n" + |
||||
" self._control.BeginInit()\r\n" + |
||||
" localVariable = PythonBinding.Tests.Utils.SupportInitCustomControl()\r\n" + |
||||
" localVariable.BeginInit()\r\n" + |
||||
" self.SuspendLayout()\r\n" + |
||||
" # \r\n" + |
||||
" # TestForm\r\n" + |
||||
" # \r\n" + |
||||
" self.AccessibleRole = System.Windows.Forms.AccessibleRole.None\r\n" + |
||||
" self.Controls.Add(self._control)\r\n" + |
||||
" self.Name = \"TestForm\"\r\n" + |
||||
" self._control.EndInit()\r\n" + |
||||
" localVariable.EndInit()\r\n" + |
||||
" self.ResumeLayout(False)\r\n"; |
||||
} |
||||
} |
||||
|
||||
public SupportInitCustomControl Control { |
||||
get { return Form.Controls[0] as SupportInitCustomControl; } |
||||
} |
||||
|
||||
public SupportInitCustomControl LocalControl { |
||||
get { return base.ComponentCreator.GetInstance("localVariable") as SupportInitCustomControl; } |
||||
} |
||||
|
||||
[Test] |
||||
public void BeginInitCalled() |
||||
{ |
||||
Assert.IsTrue(Control.IsBeginInitCalled); |
||||
} |
||||
|
||||
[Test] |
||||
public void EndInitCalled() |
||||
{ |
||||
Assert.IsTrue(Control.IsEndInitCalled); |
||||
} |
||||
|
||||
[Test] |
||||
public void BeginInitCalledOnLocalVariable() |
||||
{ |
||||
Assert.IsTrue(LocalControl.IsBeginInitCalled); |
||||
} |
||||
|
||||
[Test] |
||||
public void EndInitCalledOnLocalVariable() |
||||
{ |
||||
Assert.IsTrue(LocalControl.IsEndInitCalled); |
||||
} |
||||
} |
||||
} |
@ -1,61 +0,0 @@
@@ -1,61 +0,0 @@
|
||||
// <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; |
||||
using ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
/// <summary>
|
||||
/// Tests the PythonControl's CreateDesignerComponent method.
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class CreateDesignerComponentTests |
||||
{ |
||||
[Test] |
||||
public void ListViewComponent() |
||||
{ |
||||
using (ListView listView = new ListView()) { |
||||
Assert.IsInstanceOf(typeof(PythonListViewComponent), PythonDesignerComponentFactory.CreateDesignerComponent(listView)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void TextBoxComponent() |
||||
{ |
||||
using (TextBox textBox = new TextBox()) { |
||||
Assert.IsInstanceOf(typeof(PythonDesignerComponent), PythonDesignerComponentFactory.CreateDesignerComponent(textBox)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void CreateRootDesigner() |
||||
{ |
||||
using (TextBox textBox = new TextBox()) { |
||||
Assert.IsInstanceOf(typeof(PythonDesignerRootComponent), PythonDesignerComponentFactory.CreateDesignerRootComponent(textBox)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void ImageListComponent() |
||||
{ |
||||
using (ImageList imageList = new ImageList()) { |
||||
Assert.IsInstanceOf(typeof(PythonImageListComponent), PythonDesignerComponentFactory.CreateDesignerComponent(imageList)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void TreeViewComponent() |
||||
{ |
||||
using (TreeView treeView = new TreeView()) { |
||||
Assert.IsInstanceOf(typeof(PythonTreeViewComponent), PythonDesignerComponentFactory.CreateDesignerComponent(treeView)); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel; |
||||
using System.ComponentModel.Design; |
||||
using System.Drawing; |
||||
using System.Windows.Forms; |
||||
using ICSharpCode.PythonBinding; |
||||
using IronPython.Compiler.Ast; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
[TestFixture] |
||||
public class DeserializeCallParametersTestFixture |
||||
{ |
||||
PythonCodeDeserializer deserializer; |
||||
MockComponentCreator componentCreator; |
||||
|
||||
[SetUp] |
||||
public void Init() |
||||
{ |
||||
componentCreator = new MockComponentCreator(); |
||||
MockDesignerLoaderHost mockDesignerLoaderHost = new MockDesignerLoaderHost(); |
||||
deserializer = new PythonCodeDeserializer(componentCreator); |
||||
} |
||||
|
||||
[Test] |
||||
public void NegativeIntegerParameter() |
||||
{ |
||||
List<object> expectedArgs = new List<object>(); |
||||
expectedArgs.Add(-1); |
||||
|
||||
string code = "TestClass(-1)"; |
||||
CallExpression callExpression = PythonParserHelper.GetCallExpression(code); |
||||
List<object> args = deserializer.GetArguments(callExpression); |
||||
|
||||
Assert.AreEqual(expectedArgs, args); |
||||
} |
||||
|
||||
[Test] |
||||
public void EnumParameter() |
||||
{ |
||||
List<object> expectedArgs = new List<object>(); |
||||
expectedArgs.Add(AnchorStyles.Top); |
||||
|
||||
string code = "TestClass(System.Windows.Forms.AnchorStyles.Top)"; |
||||
CallExpression callExpression = PythonParserHelper.GetCallExpression(code); |
||||
List<object> args = deserializer.GetArguments(callExpression); |
||||
|
||||
Assert.AreEqual(expectedArgs, args); |
||||
} |
||||
|
||||
[Test] |
||||
public void BooleanParameter() |
||||
{ |
||||
List<object> expectedArgs = new List<object>(); |
||||
expectedArgs.Add(true); |
||||
|
||||
string code = "TestClass(True)"; |
||||
CallExpression callExpression = PythonParserHelper.GetCallExpression(code); |
||||
List<object> args = deserializer.GetArguments(callExpression); |
||||
|
||||
Assert.AreEqual(expectedArgs, args); |
||||
} |
||||
|
||||
[Test] |
||||
public void LocalVariableInstance() |
||||
{ |
||||
string s = "abc"; |
||||
CreatedInstance instance = new CreatedInstance(typeof(string), new object[0], "localVariable", false); |
||||
instance.Object = s; |
||||
componentCreator.CreatedInstances.Add(instance); |
||||
List<object> expectedArgs = new List<object>(); |
||||
expectedArgs.Add(s); |
||||
|
||||
string code = "TestClass(localVariable)"; |
||||
CallExpression callExpression = PythonParserHelper.GetCallExpression(code); |
||||
List<object> args = deserializer.GetArguments(callExpression); |
||||
|
||||
Assert.AreEqual(expectedArgs, args); |
||||
} |
||||
|
||||
} |
||||
} |
@ -1,95 +0,0 @@
@@ -1,95 +0,0 @@
|
||||
// <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.Reflection; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
/// <summary>
|
||||
/// Tests that the AddRange or Add method that takes an array of items can be determined.
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class FindAddRangeMethodTests |
||||
{ |
||||
[Test] |
||||
public void MenuStripItemsAddRangeMethod() |
||||
{ |
||||
using (MenuStrip menuStrip = new MenuStrip()) { |
||||
MethodInfo expectedMethodInfo = FindMethod(menuStrip.Items, "AddRange", typeof(ToolStripItem[])); |
||||
Assert.IsNotNull(expectedMethodInfo); |
||||
|
||||
Assert.AreSame(expectedMethodInfo, PythonDesignerComponent.GetAddRangeSerializationMethod(menuStrip.Items)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void GetArrayParameterType() |
||||
{ |
||||
using (MenuStrip menuStrip = new MenuStrip()) { |
||||
MethodInfo methodInfo = FindMethod(menuStrip.Items, "AddRange", typeof(ToolStripItem[])); |
||||
Assert.AreEqual(typeof(ToolStripItem), PythonDesignerComponent.GetArrayParameterType(methodInfo)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void GetArrayParameterTypeFromMethodWithNoParameters() |
||||
{ |
||||
MethodInfo methodInfo = typeof(String).GetMethod("Clone"); |
||||
Assert.IsNull(PythonDesignerComponent.GetArrayParameterType(methodInfo)); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetArrayParameterTypeWithNullMethodInfo() |
||||
{ |
||||
Assert.IsNull(PythonDesignerComponent.GetArrayParameterType(null)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Form.Controls.AddRange() method should not be returned since it is marked with
|
||||
/// DesignerSerializationVisibility.Hidden.
|
||||
/// </summary>
|
||||
[Test] |
||||
public void FormControlsAddRangeMethodNotFound() |
||||
{ |
||||
using (Form form = new Form()) { |
||||
Assert.IsNull(PythonDesignerComponent.GetAddRangeSerializationMethod(form.Controls)); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void FormControlsAddMethod() |
||||
{ |
||||
using (Form form = new Form()) { |
||||
MethodInfo expectedMethodInfo = FindMethod(form.Controls, "Add", typeof(Control)); |
||||
Assert.IsNotNull(expectedMethodInfo); |
||||
|
||||
Assert.AreSame(expectedMethodInfo, PythonDesignerComponent.GetAddSerializationMethod(form.Controls)); |
||||
} |
||||
} |
||||
|
||||
static MethodInfo FindMethod(object obj, string methodName, Type parameterType) |
||||
{ |
||||
foreach (MethodInfo methodInfo in obj.GetType().GetMethods()) { |
||||
if (methodInfo.Name == methodName) { |
||||
ParameterInfo[] parameters = methodInfo.GetParameters(); |
||||
if (parameters.Length == 1) { |
||||
ParameterInfo param = parameters[0]; |
||||
if (param.ParameterType == parameterType) { |
||||
return methodInfo; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -1,77 +0,0 @@
@@ -1,77 +0,0 @@
|
||||
// <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; |
||||
using System.Collections.Generic; |
||||
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 |
||||
{ |
||||
class NonComponentToolbar |
||||
{ |
||||
NonComponentToolbarToolsCollection tools = new NonComponentToolbarToolsCollection(); |
||||
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] |
||||
public NonComponentToolbarToolsCollection Tools { |
||||
get { return tools; } |
||||
} |
||||
} |
||||
|
||||
class NonComponentToolbarToolsCollection : CollectionBase |
||||
{ |
||||
public void Add(string s) |
||||
{ |
||||
InnerList.Add(s); |
||||
} |
||||
|
||||
public void AddRange(string[] strings) |
||||
{ |
||||
InnerList.AddRange(strings); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tests that we can generate python code for a property which is not an IComponent and one of
|
||||
/// its properties is a collection that needs its content generated as code.
|
||||
///
|
||||
/// class Toolbar : IDisposable
|
||||
/// {
|
||||
/// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
/// public ToolsCollection Tools { get; }
|
||||
/// }
|
||||
///
|
||||
/// class ToolsCollection : CollectionBase
|
||||
/// {
|
||||
/// }
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class GenerateAddRangeForNonComponentTestFixture |
||||
{ |
||||
[Test] |
||||
public void GenerateAddRangeCode() |
||||
{ |
||||
NonComponentToolbar toolbar = new NonComponentToolbar(); |
||||
toolbar.Tools.Add("One"); |
||||
PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(toolbar).Find("Tools", true); |
||||
PythonCodeBuilder codeBuilder = new PythonCodeBuilder(); |
||||
codeBuilder.IndentString = " "; |
||||
PythonDesignerComponent.AppendMethodCallWithArrayParameter(codeBuilder, "self.ReportViewer.Toolbar", toolbar, propertyDescriptor, false); |
||||
|
||||
string expectedCode = "self.ReportViewer.Toolbar.Tools.AddRange(System.Array[System.String](\r\n" + |
||||
" [\"One\"]))\r\n"; |
||||
|
||||
Assert.AreEqual(expectedCode, codeBuilder.ToString(), codeBuilder.ToString()); |
||||
} |
||||
} |
||||
} |
@ -1,46 +0,0 @@
@@ -1,46 +0,0 @@
|
||||
// <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.Windows.Forms; |
||||
using ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
/// <summary>
|
||||
/// Gets properties that are marked as DesignerSerializationVisibility.Content
|
||||
/// </summary>
|
||||
[TestFixture] |
||||
public class GetSerializableContentPropertiesTestFixture |
||||
{ |
||||
PropertyDescriptorCollection properties; |
||||
|
||||
[TestFixtureSetUp] |
||||
public void SetUpFixture() |
||||
{ |
||||
using (Form form = new Form()) { |
||||
// Modify Form.Text so it is identified as needing serialization.
|
||||
form.Text = "abc"; |
||||
properties = PythonDesignerComponent.GetSerializableContentProperties(form); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void FormControlsPropertyReturned() |
||||
{ |
||||
Assert.IsNotNull(properties.Find("Controls", false), "Property not found: Controls"); |
||||
} |
||||
|
||||
[Test] |
||||
public void FormTextPropertyIsNotReturned() |
||||
{ |
||||
Assert.IsNull(properties.Find("Text", false), "Property should not be found: Text"); |
||||
} |
||||
} |
||||
} |
@ -1,86 +0,0 @@
@@ -1,86 +0,0 @@
|
||||
// <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 ICSharpCode.PythonBinding; |
||||
using NUnit.Framework; |
||||
using PythonBinding.Tests.Utils; |
||||
|
||||
namespace PythonBinding.Tests.Designer |
||||
{ |
||||
[TestFixture] |
||||
public class IsSitedComponentTests : ISite |
||||
{ |
||||
[Test] |
||||
public void NullComponent() |
||||
{ |
||||
Assert.IsFalse(PythonDesignerComponent.IsSitedComponent(null)); |
||||
} |
||||
|
||||
[Test] |
||||
public void ComponentNotSited() |
||||
{ |
||||
Assert.IsFalse(PythonDesignerComponent.IsSitedComponent(new Component())); |
||||
} |
||||
|
||||
[Test] |
||||
public void SitedComponent() |
||||
{ |
||||
Component component = new Component(); |
||||
component.Site = this; |
||||
Assert.IsTrue(PythonDesignerComponent.IsSitedComponent(component)); |
||||
} |
||||
|
||||
[Test] |
||||
public void SitedDesignerComponent() |
||||
{ |
||||
Component component = new Component(); |
||||
component.Site = this; |
||||
PythonDesignerComponent designerComponent = new PythonDesignerComponent(component); |
||||
Assert.IsTrue(designerComponent.IsSited); |
||||
} |
||||
|
||||
[Test] |
||||
public void NonComponent() |
||||
{ |
||||
Assert.IsFalse(PythonDesignerComponent.IsSitedComponent(String.Empty)); |
||||
} |
||||
|
||||
public IComponent Component { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IContainer Container { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public bool DesignMode { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
set { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public object GetService(Type serviceType) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
// <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.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 LoadLocalVariablePropertyAssignmentTestFixture : LoadFormTestFixtureBase |
||||
{ |
||||
public override string PythonCode { |
||||
get { |
||||
return "class MainForm(System.Windows.Forms.Form):\r\n" + |
||||
" def InitializeComponent(self):\r\n" + |
||||
" button1 = System.Windows.Forms.Button()\r\n" + |
||||
" self.SuspendLayout()\r\n" + |
||||
" # \r\n" + |
||||
" # MainForm\r\n" + |
||||
" # \r\n" + |
||||
" self.AcceptButton = button1\r\n" + |
||||
" self.ClientSize = System.Drawing.Size(300, 400)\r\n" + |
||||
" self.Name = \"MainForm\"\r\n" + |
||||
" self.ResumeLayout(False)\r\n"; |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void OneComponentCreated() |
||||
{ |
||||
Assert.AreEqual(1, ComponentCreator.CreatedComponents.Count); |
||||
} |
||||
|
||||
[Test] |
||||
public void TwoObjectsCreated() |
||||
{ |
||||
Assert.AreEqual(2, ComponentCreator.CreatedInstances.Count); |
||||
} |
||||
|
||||
[Test] |
||||
public void ButtonInstance() |
||||
{ |
||||
CreatedInstance expectedInstance = new CreatedInstance(typeof(Button), new object[0], "button1", false); |
||||
Assert.AreEqual(expectedInstance, ComponentCreator.CreatedInstances[0]); |
||||
} |
||||
|
||||
[Test] |
||||
public void AcceptButtonPropertyIsNotNull() |
||||
{ |
||||
Assert.IsNotNull(Form.AcceptButton); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<root> |
||||
<!-- |
||||
Microsoft ResX Schema |
||||
|
||||
Version 2.0 |
||||
|
||||
The primary goals of this format is to allow a simple XML format |
||||
that is mostly human readable. The generation and parsing of the |
||||
various data types are done through the TypeConverter classes |
||||
associated with the data types. |
||||
|
||||
Example: |
||||
|
||||
... ado.net/XML headers & schema ... |
||||
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
<resheader name="version">2.0</resheader> |
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
</data> |
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
<comment>This is a comment</comment> |
||||
</data> |
||||
|
||||
There are any number of "resheader" rows that contain simple |
||||
name/value pairs. |
||||
|
||||
Each data row contains a name, and value. The row also contains a |
||||
type or mimetype. Type corresponds to a .NET class that support |
||||
text/value conversion through the TypeConverter architecture. |
||||
Classes that don't support this are serialized and stored with the |
||||
mimetype set. |
||||
|
||||
The mimetype is used for serialized objects, and tells the |
||||
ResXResourceReader how to depersist the object. This is currently not |
||||
extensible. For a given mimetype the value must be set accordingly: |
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
that the ResXResourceWriter will generate, however the reader can |
||||
read any of the formats listed below. |
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
value : The object must be serialized with |
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
: and then encoded with base64 encoding. |
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
value : The object must be serialized with |
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
: and then encoded with base64 encoding. |
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
value : The object must be serialized into a byte array |
||||
: using a System.ComponentModel.TypeConverter |
||||
: and then encoded with base64 encoding. |
||||
--> |
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
<xsd:complexType> |
||||
<xsd:choice maxOccurs="unbounded"> |
||||
<xsd:element name="metadata"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
<xsd:attribute name="type" type="xsd:string" /> |
||||
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
<xsd:attribute ref="xml:space" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="assembly"> |
||||
<xsd:complexType> |
||||
<xsd:attribute name="alias" type="xsd:string" /> |
||||
<xsd:attribute name="name" type="xsd:string" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="data"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
<xsd:attribute ref="xml:space" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="resheader"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
</xsd:choice> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
</xsd:schema> |
||||
<resheader name="resmimetype"> |
||||
<value>text/microsoft-resx</value> |
||||
</resheader> |
||||
<resheader name="version"> |
||||
<value>2.0</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<data name="ICSharpCode.PythonBinding.UnknownTypeName" xml:space="preserve"> |
||||
<value>Could not find type '{0}'. Are you missing an assembly reference?</value> |
||||
</data> |
||||
</root> |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <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 NullPropertyUserControl : UserControl |
||||
{ |
||||
string fooBar; |
||||
|
||||
public string FooBar { |
||||
get { return fooBar; } |
||||
set { fooBar = value; } |
||||
} |
||||
|
||||
public NullPropertyUserControl() |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <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.Windows.Forms; |
||||
|
||||
namespace PythonBinding.Tests.Utils |
||||
{ |
||||
public class SupportInitCustomControl : UserControl, ISupportInitialize |
||||
{ |
||||
bool beginInitCalled; |
||||
bool endInitCalled; |
||||
|
||||
public SupportInitCustomControl() |
||||
{ |
||||
} |
||||
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] |
||||
[Browsable(false)] |
||||
public bool IsBeginInitCalled { |
||||
get { return beginInitCalled; } |
||||
} |
||||
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] |
||||
[Browsable(false)] |
||||
public bool IsEndInitCalled { |
||||
get { return endInitCalled; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Deliberately making the interface explicit for the BeginInit method but not the EndInit method.
|
||||
/// </summary>
|
||||
void ISupportInitialize.BeginInit() |
||||
{ |
||||
beginInitCalled = true; |
||||
} |
||||
|
||||
public void EndInit() |
||||
{ |
||||
endInitCalled = true; |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue