Browse Source

Python forms designer no longer generates event handlers if they already exist.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4016 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 16 years ago
parent
commit
426aec5809
  1. 75
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs
  2. 85
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EventHandlerAlreadyExistsTestFixture.cs
  3. 57
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EventHandlerExistsWithIncorrectParameterCountTestFixture.cs
  4. 63
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerTestFixtureBase.cs
  5. 19
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertNewEventHandlerTestFixture.cs
  6. 21
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertSecondEventHandlerTestFixture.cs
  7. 3
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

75
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.PythonBinding @@ -80,7 +80,7 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public void MergeRootComponentChanges(IComponent component)
{
ParseInformation parseInfo = ParseFile(this.ViewContent.DesignerCodeFile.FileName, this.ViewContent.DesignerCodeFileContent);
ParseInformation parseInfo = ParseFile();
Merge(component, ViewContent.DesignerCodeFileDocument, parseInfo.BestCompilationUnit, textEditorProperties);
}
@ -113,32 +113,35 @@ namespace ICSharpCode.PythonBinding @@ -113,32 +113,35 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public bool InsertComponentEvent(IComponent component, EventDescriptor edesc, string eventMethodName, string body, out string file, out int position)
{
// Ensure the text editor has the latest version
// of the source code before we insert any new code.
viewContent.MergeFormChanges();
// Insert the event handler at the end of the class with an extra
// new line before it.
IDocument doc = viewContent.DesignerCodeFileDocument;
string eventHandler = CreateEventHandler(eventMethodName, body, "\t");
int line = doc.LineSegmentCollection.Count;
LineSegment lastLineSegment = doc.GetLineSegment(line - 1);
int offset = lastLineSegment.Offset + lastLineSegment.Length;
string newContent = "\r\n" + eventHandler;
if (lastLineSegment.Length > 0) {
// Add an extra new line between the last line and the event handler.
newContent = "\r\n" + newContent;
position = GetExistingEventHandler(eventMethodName);
if (position == -1) {
// Ensure the text editor has the latest version
// of the source code before we insert any new code.
viewContent.MergeFormChanges();
// Insert the event handler at the end of the class with an extra
// new line before it.
IDocument doc = viewContent.DesignerCodeFileDocument;
string eventHandler = CreateEventHandler(eventMethodName, body, "\t");
int line = doc.LineSegmentCollection.Count;
LineSegment lastLineSegment = doc.GetLineSegment(line - 1);
int offset = lastLineSegment.Offset + lastLineSegment.Length;
string newContent = "\r\n" + eventHandler;
if (lastLineSegment.Length > 0) {
// Add an extra new line between the last line and the event handler.
newContent = "\r\n" + newContent;
}
doc.Insert(offset, newContent);
// Set position so it points to the line
// where the event handler was inserted.
position = line + 1;
}
doc.Insert(offset, newContent);
// Set position so it points to the line
// where the event handler was inserted.
position = line + 1;
// Set the filename so it refers to the form being designed.
file = viewContent.DesignerCodeFile.FileName;
return true;
}
@ -149,7 +152,7 @@ namespace ICSharpCode.PythonBinding @@ -149,7 +152,7 @@ namespace ICSharpCode.PythonBinding
public ICollection GetCompatibleMethods(EventDescriptor edesc)
{
// Get the form or user control class.
ParseInformation parseInfo = ParseFile(this.ViewContent.DesignerCodeFile.FileName, this.ViewContent.DesignerCodeFileContent);
ParseInformation parseInfo = ParseFile();
// Look at the form's methods and see which are compatible.
ArrayList methods = new ArrayList();
@ -264,5 +267,29 @@ namespace ICSharpCode.PythonBinding @@ -264,5 +267,29 @@ namespace ICSharpCode.PythonBinding
}
return document.PositionToOffset(endLocation);
}
/// <summary>
/// Checks if the event handler already exists.
/// </summary>
/// <returns>The line position of the first line of the existing event handler.</returns>
int GetExistingEventHandler(string methodName)
{
ParseInformation parseInfo = ParseFile();
IClass c = GetClass(parseInfo.BestCompilationUnit);
foreach (IMethod method in c.Methods) {
if ((method.Name == methodName) && (method.Parameters.Count == 2)) {
return method.Region.BeginLine;
}
}
return -1;
}
/// <summary>
/// Parses the form or user control being designed.
/// </summary>
ParseInformation ParseFile()
{
return ParseFile(this.ViewContent.DesignerCodeFile.FileName, this.ViewContent.DesignerCodeFileContent);
}
}
}

85
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EventHandlerAlreadyExistsTestFixture.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
// <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 ICSharpCode.PythonBinding;
using ICSharpCode.FormsDesigner;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Designer
{
/// <summary>
/// Tests the PythonDesignerGenerator does not insert an event handler if a method already exists with the same
/// name.
/// </summary>
[TestFixture]
public class EventHandlerAlreadyExistsTestFixture : InsertEventHandlerTestFixtureBase
{
public override void AfterSetUpFixture()
{
MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
generator.InsertComponentEvent(null, mockEventDescriptor, "mybuttonclick", String.Empty, out file, out position);
insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "mybuttonclick", String.Empty, out file, out position);
}
[Test]
public void CodeAfterInsertComponentEventMethodCalledIsNotChanged()
{
string expectedCode = GetTextEditorCode();
Assert.AreEqual(expectedCode, viewContent.DesignerCodeFileContent);
}
[Test]
public void InsertComponentEventMethodReturnsTrue()
{
Assert.IsTrue(insertedEventHandler);
}
[Test]
public void FileIsForm()
{
Assert.AreEqual(fileName, file);
}
[Test]
public void PositionOfEventHandlerIsLine12()
{
Assert.AreEqual(12, position);
}
[Test]
public void TextPassedToParseFileMethod()
{
Assert.AreEqual(GetTextEditorCode(), generator.TextContentPassedToParseFileMethod);
}
[Test]
public void FileNamePassedToParseFileMethod()
{
Assert.AreEqual(fileName, generator.FileNamePassedToParseFileMethod);
}
protected override string GetTextEditorCode()
{
return "from System.Windows.Forms import Form\r\n" +
"\r\n" +
"class MainForm(Form):\r\n" +
"\tdef __init__(self):\r\n" +
"\t\tself.InitializeComponents()\r\n" +
"\t\r\n" +
"\tdef InitializeComponents(self):\r\n" +
"\t\tself._button1 = System.Windows.Forms.Button()\r\n" +
"\t\tself._button1.Click += mybuttonclick\r\n" +
"\t\tself.Controls.Add(self._button1)\r\n" +
"\t\r\n" +
"\tdef mybuttonclick(self, sender, e)\r\n" +
"\t\tpass\r\n";
}
}
}

57
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/EventHandlerExistsWithIncorrectParameterCountTestFixture.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// <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 ICSharpCode.PythonBinding;
using ICSharpCode.FormsDesigner;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Designer
{
/// <summary>
/// An event handler should be inserted if a method exists in the form's class but has the incorrect
/// number of parameters.
/// </summary>
[TestFixture]
public class EventHandlerExistsWithIncorrectParameterCountTestFixture : InsertEventHandlerTestFixtureBase
{
public override void AfterSetUpFixture()
{
MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "mybuttonclick", String.Empty, out file, out position);
}
[Test]
public void ExpectedCodeAfterEventHandlerInserted()
{
string expectedCode = GetTextEditorCode();
string eventHandler = "\tdef mybuttonclick(self, sender, e):\r\n" +
"\t\tpass";
expectedCode = expectedCode + "\r\n" + eventHandler;
Assert.AreEqual(expectedCode, viewContent.DesignerCodeFileContent);
}
protected override string GetTextEditorCode()
{
return "from System.Windows.Forms import Form\r\n" +
"\r\n" +
"class MainForm(Form):\r\n" +
"\tdef __init__(self):\r\n" +
"\t\tself.InitializeComponents()\r\n" +
"\t\r\n" +
"\tdef InitializeComponents(self):\r\n" +
"\t\tself._button1 = System.Windows.Forms.Button()\r\n" +
"\t\tself._button1.Click += mybuttonclick\r\n" +
"\t\r\n" +
"\tdef mybuttonclick(self)\r\n" +
"\t\tpass\r\n";
}
}
}

63
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerTestFixtureBase.cs

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// <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 ICSharpCode.PythonBinding;
using ICSharpCode.FormsDesigner;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Designer
{
/// <summary>
/// Base class that tests the PythonDesignerGenerator.InsertEventComponent method.
/// </summary>
public class InsertEventHandlerTestFixtureBase
{
protected string file;
protected int position;
protected bool insertedEventHandler;
protected MockTextEditorViewContent mockViewContent;
protected DerivedFormDesignerViewContent viewContent;
protected string fileName = @"C:\Projects\Python\mainform.py";
protected DerivedPythonDesignerGenerator generator;
[TestFixtureSetUp]
public void SetUpFixture()
{
generator = new DerivedPythonDesignerGenerator();
mockViewContent = new MockTextEditorViewContent();
viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(fileName));
generator.Attach(viewContent);
viewContent.DesignerCodeFileContent = GetTextEditorCode();
ParseInformation parseInfo = new ParseInformation();
PythonParser parser = new PythonParser();
ICompilationUnit parserCompilationUnit = parser.Parse(new DefaultProjectContent(), fileName, GetTextEditorCode());
parseInfo.SetCompilationUnit(parserCompilationUnit);
generator.ParseInfoToReturnFromParseFileMethod = parseInfo;
AfterSetUpFixture();
}
/// <summary>
/// Called at the end of the SetUpFixture method.
/// </summary>
public virtual void AfterSetUpFixture()
{
}
/// <summary>
/// Gets the form's code.
/// </summary>
protected virtual string GetTextEditorCode()
{
return String.Empty;
}
}
}

19
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertNewEventHandlerTestFixture.cs

@ -19,23 +19,10 @@ namespace PythonBinding.Tests.Designer @@ -19,23 +19,10 @@ namespace PythonBinding.Tests.Designer
/// into the document correctly.
/// </summary>
[TestFixture]
public class InsertNewEventHandlerTestFixture
public class InsertNewEventHandlerTestFixture : InsertEventHandlerTestFixtureBase
{
string file;
int position;
bool insertedEventHandler;
MockTextEditorViewContent mockViewContent;
DerivedFormDesignerViewContent viewContent;
[TestFixtureSetUp]
public void SetUpFixture()
public override void AfterSetUpFixture()
{
DerivedPythonDesignerGenerator generator = new DerivedPythonDesignerGenerator();
mockViewContent = new MockTextEditorViewContent();
viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(@"C:\Projects\Python\mainform.py"));
generator.Attach(viewContent);
viewContent.DesignerCodeFileContent = GetTextEditorCode();
MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "button1_click", String.Empty, out file, out position);
}
@ -60,7 +47,7 @@ namespace PythonBinding.Tests.Designer @@ -60,7 +47,7 @@ namespace PythonBinding.Tests.Designer
/// This is generated by the form designer framework and not
/// by the designer generator.
/// </summary>
string GetTextEditorCode()
protected override string GetTextEditorCode()
{
return "from System.Windows.Forms import Form\r\n" +
"\r\n" +

21
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertSecondEventHandlerTestFixture.cs

@ -19,23 +19,10 @@ namespace PythonBinding.Tests.Designer @@ -19,23 +19,10 @@ namespace PythonBinding.Tests.Designer
/// and the new one inserted.
/// </summary>
[TestFixture]
public class InsertSecondEventHandlerTestFixture
public class InsertSecondEventHandlerTestFixture : InsertEventHandlerTestFixtureBase
{
string file;
int position;
bool insertedEventHandler;
MockTextEditorViewContent mockViewContent;
DerivedFormDesignerViewContent viewContent;
[TestFixtureSetUp]
public void SetUpFixture()
{
DerivedPythonDesignerGenerator generator = new DerivedPythonDesignerGenerator();
mockViewContent = new MockTextEditorViewContent();
viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(@"C:\Projects\Python\mainform.py"));
generator.Attach(viewContent);
viewContent.DesignerCodeFileContent = GetTextEditorCode();
public override void AfterSetUpFixture()
{
MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
generator.InsertComponentEvent(null, mockEventDescriptor, "button1_click", String.Empty, out file, out position);
insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "button2_click", String.Empty, out file, out position);
@ -55,7 +42,7 @@ namespace PythonBinding.Tests.Designer @@ -55,7 +42,7 @@ namespace PythonBinding.Tests.Designer
Assert.AreEqual(expectedCode, viewContent.DesignerCodeFileContent);
}
string GetTextEditorCode()
protected override string GetTextEditorCode()
{
return "from System.Windows.Forms import Form\r\n" +
"\r\n" +

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

@ -153,6 +153,8 @@ @@ -153,6 +153,8 @@
<Compile Include="Designer\DeserializeStringArrayTestFixture.cs" />
<Compile Include="Designer\DeserializeToolStripItemArrayTestFixture.cs" />
<Compile Include="Designer\EnabledSetUsingPropertyDescriptorTestFixture.cs" />
<Compile Include="Designer\EventHandlerAlreadyExistsTestFixture.cs" />
<Compile Include="Designer\EventHandlerExistsWithIncorrectParameterCountTestFixture.cs" />
<Compile Include="Designer\FindAddRangeMethodTests.cs" />
<Compile Include="Designer\FindInitializeComponentMethodTestFixture.cs" />
<Compile Include="Designer\GenerateAcceptButtonFormTestFixture.cs" />
@ -181,6 +183,7 @@ @@ -181,6 +183,7 @@
<Compile Include="Designer\GetInstanceFromDesignerLoaderTestFixture.cs" />
<Compile Include="Designer\GetSerializableContentPropertiesTestFixture.cs" />
<Compile Include="Designer\IgnoreDesignTimePropertiesTestFixture.cs" />
<Compile Include="Designer\InsertEventHandlerTestFixtureBase.cs" />
<Compile Include="Designer\InsertNewEventHandlerTestFixture.cs" />
<Compile Include="Designer\InsertSecondEventHandlerTestFixture.cs" />
<Compile Include="Designer\IsFullyQualifiedBaseClassFormDesignableTestFixture.cs" />

Loading…
Cancel
Save