22 changed files with 38 additions and 614 deletions
@ -1,29 +0,0 @@
@@ -1,29 +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.Input; |
||||
using ICSharpCode.Scripting; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class PythonConsoleTextEditorKeyEventArgs : ConsoleTextEditorKeyEventArgs |
||||
{ |
||||
KeyEventArgs e; |
||||
|
||||
public PythonConsoleTextEditorKeyEventArgs(KeyEventArgs e) |
||||
: base(e.Key) |
||||
{ |
||||
this.e = e; |
||||
} |
||||
|
||||
public override bool Handled { |
||||
get { return e.Handled; } |
||||
set { e.Handled = value; } |
||||
} |
||||
} |
||||
} |
||||
@ -1,118 +0,0 @@
@@ -1,118 +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 ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.Scripting; |
||||
|
||||
namespace ICSharpCode.PythonBinding |
||||
{ |
||||
public class ThreadSafePythonConsoleTextEditor : IScriptingConsoleTextEditor |
||||
{ |
||||
delegate string GetLineInvoker(int index); |
||||
|
||||
IScriptingConsoleTextEditor consoleTextEditor; |
||||
IControlDispatcher dispatcher; |
||||
|
||||
public ThreadSafePythonConsoleTextEditor(TextEditor textEditor) |
||||
: this(new PythonConsoleTextEditor(textEditor), new ControlDispatcher(textEditor)) |
||||
{ |
||||
} |
||||
|
||||
public ThreadSafePythonConsoleTextEditor(IScriptingConsoleTextEditor consoleTextEditor, IControlDispatcher dispatcher) |
||||
{ |
||||
this.consoleTextEditor = consoleTextEditor; |
||||
this.dispatcher = dispatcher; |
||||
} |
||||
|
||||
public event ConsoleTextEditorKeyEventHandler PreviewKeyDown { |
||||
add { consoleTextEditor.PreviewKeyDown += value; } |
||||
remove { consoleTextEditor.PreviewKeyDown -= value; } |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
consoleTextEditor.Dispose(); |
||||
} |
||||
|
||||
public int Column { |
||||
get { return consoleTextEditor.Column; } |
||||
set { consoleTextEditor.Column = value; } |
||||
} |
||||
|
||||
public int SelectionLength { |
||||
get { return consoleTextEditor.SelectionLength; } |
||||
} |
||||
|
||||
public int SelectionStart { |
||||
get { return consoleTextEditor.SelectionStart; } |
||||
} |
||||
|
||||
public int Line { |
||||
get { return consoleTextEditor.Line; } |
||||
set { consoleTextEditor.Line = value; } |
||||
} |
||||
|
||||
public int TotalLines { |
||||
get { return consoleTextEditor.TotalLines; } |
||||
} |
||||
|
||||
public bool IsCompletionWindowDisplayed { |
||||
get { return consoleTextEditor.IsCompletionWindowDisplayed; } |
||||
} |
||||
|
||||
public void Write(string text) |
||||
{ |
||||
if (dispatcher.CheckAccess()) { |
||||
consoleTextEditor.Write(text); |
||||
} else { |
||||
Action<string> action = Write; |
||||
dispatcher.Invoke(action, text); |
||||
} |
||||
} |
||||
|
||||
public void Replace(int index, int length, string text) |
||||
{ |
||||
if (dispatcher.CheckAccess()) { |
||||
consoleTextEditor.Replace(index, length, text); |
||||
} else { |
||||
Action<int, int, string> action = Replace; |
||||
dispatcher.Invoke(action, index, length, text); |
||||
} |
||||
} |
||||
|
||||
public string GetLine(int index) |
||||
{ |
||||
if (dispatcher.CheckAccess()) { |
||||
return consoleTextEditor.GetLine(index); |
||||
} else { |
||||
GetLineInvoker invoker = new GetLineInvoker(GetLine); |
||||
return (string)dispatcher.Invoke(invoker, index); |
||||
} |
||||
} |
||||
|
||||
public void ShowCompletionWindow(ScriptingConsoleCompletionDataProvider completionDataProvider) |
||||
{ |
||||
if (dispatcher.CheckAccess()) { |
||||
consoleTextEditor.ShowCompletionWindow(completionDataProvider); |
||||
} else { |
||||
Action<ScriptingConsoleCompletionDataProvider> action = ShowCompletionWindow; |
||||
dispatcher.Invoke(action, completionDataProvider); |
||||
} |
||||
} |
||||
|
||||
public void MakeCurrentContentReadOnly() |
||||
{ |
||||
if (dispatcher.CheckAccess()) { |
||||
consoleTextEditor.MakeCurrentContentReadOnly(); |
||||
} else { |
||||
Action action = MakeCurrentContentReadOnly; |
||||
dispatcher.Invoke(action); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,157 +0,0 @@
@@ -1,157 +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.Windows; |
||||
using System.Windows.Input; |
||||
using System.Windows.Threading; |
||||
|
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.CodeCompletion; |
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.Scripting; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.RubyBinding |
||||
{ |
||||
public class RubyConsoleTextEditor : IScriptingConsoleTextEditor |
||||
{ |
||||
TextEditor textEditor; |
||||
Color customLineColour = Color.LightGray; |
||||
BeginReadOnlySectionProvider readOnlyRegion; |
||||
CompletionWindow completionWindow; |
||||
|
||||
public RubyConsoleTextEditor(TextEditor textEditor) |
||||
{ |
||||
this.textEditor = textEditor; |
||||
readOnlyRegion = new BeginReadOnlySectionProvider(); |
||||
textEditor.TextArea.ReadOnlySectionProvider = readOnlyRegion; |
||||
textEditor.PreviewKeyDown += OnTextEditorPreviewKeyDown; |
||||
} |
||||
|
||||
void OnTextEditorPreviewKeyDown(object source, KeyEventArgs e) |
||||
{ |
||||
if (PreviewKeyDown != null) { |
||||
PreviewKeyDown(this, new RubyConsoleTextEditorKeyEventArgs(e)); |
||||
} |
||||
} |
||||
|
||||
public event ConsoleTextEditorKeyEventHandler PreviewKeyDown; |
||||
|
||||
public void Dispose() |
||||
{ |
||||
textEditor.PreviewKeyDown -= OnTextEditorPreviewKeyDown; |
||||
} |
||||
|
||||
public Color CustomLineColour { |
||||
get { return customLineColour; } |
||||
} |
||||
|
||||
public void Write(string text) |
||||
{ |
||||
TextLocation location = GetCurrentCursorLocation(); |
||||
int offset = textEditor.Document.GetOffset(location); |
||||
textEditor.Document.Insert(offset, text); |
||||
} |
||||
|
||||
TextLocation GetCurrentCursorLocation() |
||||
{ |
||||
return new TextLocation(Line + 1, Column + 1); |
||||
} |
||||
|
||||
public int Column { |
||||
get { return textEditor.TextArea.Caret.Column - 1; } |
||||
set { textEditor.TextArea.Caret.Column = value + 1; } |
||||
} |
||||
|
||||
public int SelectionStart { |
||||
get { return textEditor.SelectionStart; } |
||||
} |
||||
|
||||
public int SelectionLength { |
||||
get { return textEditor.SelectionLength; } |
||||
} |
||||
|
||||
public int Line { |
||||
get { return textEditor.TextArea.Caret.Line - 1; } |
||||
set { textEditor.TextArea.Caret.Line = value + 1; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of lines in the text editor.
|
||||
/// </summary>
|
||||
public int TotalLines { |
||||
get { return textEditor.Document.LineCount; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the text for the specified line.
|
||||
/// </summary>
|
||||
public string GetLine(int index) |
||||
{ |
||||
DocumentLine line = textEditor.Document.GetLineByNumber(index + 1); |
||||
return textEditor.Document.GetText(line); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Replaces the text at the specified index on the current line with the specified text.
|
||||
/// </summary>
|
||||
public void Replace(int index, int length, string text) |
||||
{ |
||||
DocumentLine line = textEditor.Document.GetLineByNumber(textEditor.TextArea.Caret.Line); |
||||
int offset = line.Offset + index; |
||||
textEditor.Document.Replace(offset, length, text); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Makes the current text read only. Text can still be entered at the end.
|
||||
/// </summary>
|
||||
public void MakeCurrentContentReadOnly() |
||||
{ |
||||
readOnlyRegion.EndOffset = textEditor.Document.TextLength; |
||||
} |
||||
|
||||
public void ShowCompletionWindow(ScriptingConsoleCompletionDataProvider completionDataProvider) |
||||
{ |
||||
ICompletionData[] items = completionDataProvider.GenerateCompletionData(this); |
||||
if (items.Length > 0) { |
||||
ShowCompletionWindow(items); |
||||
} |
||||
} |
||||
|
||||
void ShowCompletionWindow(ICompletionData[] items) |
||||
{ |
||||
completionWindow = new CompletionWindow(textEditor.TextArea); |
||||
completionWindow.Closed += CompletionWindowClosed; |
||||
foreach (ICompletionData item in items) { |
||||
completionWindow.CompletionList.CompletionData.Add(item); |
||||
} |
||||
completionWindow.ExpectInsertionBeforeStart = true; |
||||
completionWindow.Show(); |
||||
} |
||||
|
||||
void ShowCompletionWindow(CompletionWindow window) |
||||
{ |
||||
if (completionWindow == window) { |
||||
window.Show(); |
||||
} |
||||
} |
||||
|
||||
public bool IsCompletionWindowDisplayed { |
||||
get { return completionWindow != null; } |
||||
} |
||||
|
||||
void CompletionWindowClosed(object source, EventArgs e) |
||||
{ |
||||
if (completionWindow != null) { |
||||
completionWindow.Closed -= CompletionWindowClosed; |
||||
completionWindow = null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,147 +0,0 @@
@@ -1,147 +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.Threading; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
using ICSharpCode.RubyBinding; |
||||
using ICSharpCode.Scripting; |
||||
using NUnit.Framework; |
||||
using RubyBinding.Tests.Utils; |
||||
|
||||
namespace RubyBinding.Tests.Console |
||||
{ |
||||
[TestFixture] |
||||
public class RubyConsoleTextEditorTests |
||||
{ |
||||
RubyConsoleTextEditor consoleTextEditor; |
||||
TextEditor avalonEditTextEditor; |
||||
|
||||
[TestFixtureSetUp] |
||||
public void SetUpFixture() |
||||
{ |
||||
avalonEditTextEditor = new TextEditor(); |
||||
consoleTextEditor = new RubyConsoleTextEditor(avalonEditTextEditor); |
||||
} |
||||
|
||||
[Test] |
||||
public void RubyConsoleTextEditorImplementsIScriptingConsoleTextEditorInterface() |
||||
{ |
||||
Assert.IsNotNull(consoleTextEditor as IScriptingConsoleTextEditor); |
||||
} |
||||
|
||||
[Test] |
||||
public void MakeCurrentTextEditorContentReadOnlyExtendsReadOnlyRegionToEntireDocument() |
||||
{ |
||||
avalonEditTextEditor.Text = String.Empty; |
||||
consoleTextEditor.Write("abc" + Environment.NewLine); |
||||
consoleTextEditor.MakeCurrentContentReadOnly(); |
||||
|
||||
IReadOnlySectionProvider readOnlySection = avalonEditTextEditor.TextArea.ReadOnlySectionProvider; |
||||
Assert.IsFalse(readOnlySection.CanInsert(2)); |
||||
} |
||||
|
||||
[Test] |
||||
public void WriteMethodUpdatesTextEditor() |
||||
{ |
||||
avalonEditTextEditor.Text = String.Empty; |
||||
consoleTextEditor.Write("abc"); |
||||
Assert.AreEqual("abc", avalonEditTextEditor.Text); |
||||
} |
||||
|
||||
[Test] |
||||
public void ZeroBasedConsoleTextEditorColumnPositionIsOneLessThanAvalonTextEditorColumnPositionWhichIsOneBased() |
||||
{ |
||||
avalonEditTextEditor.Text = "test"; |
||||
avalonEditTextEditor.TextArea.Caret.Column = 3; |
||||
|
||||
Assert.AreEqual(2, consoleTextEditor.Column); |
||||
} |
||||
|
||||
[Test] |
||||
public void SettingConsoleTextEditorColumnPositionUpdatesAvalonTextEditorColumnPosition() |
||||
{ |
||||
avalonEditTextEditor.Text = "test"; |
||||
avalonEditTextEditor.TextArea.Caret.Column = 0; |
||||
|
||||
consoleTextEditor.Column = 1; |
||||
Assert.AreEqual(2, avalonEditTextEditor.TextArea.Caret.Column); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetSelectionStartAndLengthWhenThreeCharactersSelected() |
||||
{ |
||||
avalonEditTextEditor.Text = "te000xt"; |
||||
int startOffset = 2; |
||||
int endOffset = 5; |
||||
SimpleSelection expectedSelection = new SimpleSelection(startOffset, endOffset); |
||||
avalonEditTextEditor.SelectionStart = expectedSelection.StartOffset; |
||||
avalonEditTextEditor.SelectionLength = expectedSelection.Length; |
||||
|
||||
// Sanity check.
|
||||
Assert.AreEqual("000", avalonEditTextEditor.SelectedText); |
||||
|
||||
AssertSelectionsAreEqual(expectedSelection, consoleTextEditor); |
||||
} |
||||
|
||||
void AssertSelectionsAreEqual(SimpleSelection expectedSelection, IScriptingConsoleTextEditor consoleTextEditor) |
||||
{ |
||||
int selectionLength = consoleTextEditor.SelectionStart + consoleTextEditor.SelectionLength; |
||||
SimpleSelection actualSelection = new SimpleSelection(consoleTextEditor.SelectionStart, selectionLength); |
||||
Assert.AreEqual(expectedSelection, actualSelection); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetSelectionStartAndLengthWhenNothingSelected() |
||||
{ |
||||
avalonEditTextEditor.Text = "text"; |
||||
avalonEditTextEditor.TextArea.Caret.Column = 1; |
||||
avalonEditTextEditor.SelectionLength = 0; |
||||
|
||||
SimpleSelection expectedSelection = new SimpleSelection(1, 1); |
||||
AssertSelectionsAreEqual(expectedSelection, consoleTextEditor); |
||||
} |
||||
|
||||
[Test] |
||||
public void ConsoleTextEditorLineEqualsOneLessThanAvalonTextEditorCaretLine() |
||||
{ |
||||
avalonEditTextEditor.Text = "abc\r\ndef"; |
||||
avalonEditTextEditor.TextArea.Caret.Line = 2; |
||||
Assert.AreEqual(1, consoleTextEditor.Line); |
||||
} |
||||
|
||||
[Test] |
||||
public void ConsoleTextEditorTotalLinesEqualsAvalonTextEditorTotalLines() |
||||
{ |
||||
avalonEditTextEditor.Text = "abc\r\ndef\r\nghi"; |
||||
Assert.AreEqual(3, consoleTextEditor.TotalLines); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetLineForZerothLineReturnsFirstLineInAvalonTextEditor() |
||||
{ |
||||
avalonEditTextEditor.Text = "abc\r\ndef\r\nghi"; |
||||
Assert.AreEqual("abc", consoleTextEditor.GetLine(0)); |
||||
} |
||||
|
||||
[Test] |
||||
public void ReplaceTextReplacesTextInAvalonEditTextEditor() |
||||
{ |
||||
avalonEditTextEditor.Text = "abc\r\ndef"; |
||||
avalonEditTextEditor.TextArea.Caret.Line = 2; |
||||
|
||||
int lineOffset = 1; |
||||
int length = 1; |
||||
consoleTextEditor.Replace(lineOffset, length, "test"); |
||||
Assert.AreEqual("abc\r\ndtestf", avalonEditTextEditor.Text); |
||||
} |
||||
} |
||||
} |
||||
@ -1,114 +0,0 @@
@@ -1,114 +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.Threading; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
using ICSharpCode.RubyBinding; |
||||
using ICSharpCode.Scripting.Tests.Utils; |
||||
using ICSharpCode.Scripting.Tests.Utils.Tests; |
||||
using NUnit.Framework; |
||||
using RubyBinding.Tests.Utils; |
||||
using RubyBinding.Tests.Utils.Tests; |
||||
|
||||
namespace RubyBinding.Tests.Console |
||||
{ |
||||
[TestFixture] |
||||
public class ThreadSafeRubyConsoleTextEditorTests |
||||
{ |
||||
ThreadSafeRubyConsoleTextEditor consoleTextEditor; |
||||
MockConsoleTextEditor textEditor; |
||||
MockControlDispatcher dispatcher; |
||||
|
||||
[TestFixtureSetUp] |
||||
public void SetUpFixture() |
||||
{ |
||||
textEditor = new MockConsoleTextEditor(); |
||||
dispatcher = new MockControlDispatcher(); |
||||
consoleTextEditor = new ThreadSafeRubyConsoleTextEditor(textEditor, dispatcher); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseWriteMethodIsInvoked() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvoked = null; |
||||
|
||||
consoleTextEditor.Write("abc"); |
||||
Assert.IsNotNull(dispatcher.MethodInvoked); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseWriteMethodIsInvokedWithTextAsArg() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvokedArgs = null; |
||||
|
||||
consoleTextEditor.Write("abc"); |
||||
object[] expectedArgs = new object[] { "abc" }; |
||||
Assert.AreEqual(expectedArgs, dispatcher.MethodInvokedArgs); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseGetLineMethodIsInvoked() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvoked = null; |
||||
|
||||
consoleTextEditor.GetLine(0); |
||||
Assert.IsNotNull(dispatcher.MethodInvoked); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseGetLineMethodIsInvokedWithLineNumberAsArg() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvokedArgs = null; |
||||
|
||||
consoleTextEditor.GetLine(0); |
||||
object[] expectedArgs = new object[] { 0 }; |
||||
Assert.AreEqual(expectedArgs, dispatcher.MethodInvokedArgs); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseReplaceMethodIsInvoked() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvoked = null; |
||||
textEditor.Text = "abcd"; |
||||
|
||||
consoleTextEditor.Replace(0, 2, "12"); |
||||
Assert.IsNotNull(dispatcher.MethodInvoked); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseReplaceethodIsInvokedWithThreeArgs() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvokedArgs = null; |
||||
textEditor.Text = "abcd"; |
||||
|
||||
consoleTextEditor.Replace(0, 2, "12"); |
||||
object[] expectedArgs = new object[] { 0, 2, "12" }; |
||||
Assert.AreEqual(expectedArgs, dispatcher.MethodInvokedArgs); |
||||
} |
||||
|
||||
[Test] |
||||
public void IfDispatcherCheckAccessReturnsFalseMakeCurrentContentReadOnlyIsInvoked() |
||||
{ |
||||
dispatcher.CheckAccessReturnValue = false; |
||||
dispatcher.MethodInvoked = null; |
||||
|
||||
consoleTextEditor.MakeCurrentContentReadOnly(); |
||||
Assert.IsNotNull(dispatcher.MethodInvoked); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue