From 2e15b638b07db35a85cc5c4e7a2ddf1cda644053 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Mon, 21 Mar 2011 20:09:41 +0000 Subject: [PATCH] Prevent scrolling beyond the last line of text and scroll to the last line when a prompt is displayed. --- .../BackendBindings/Ruby/RubyBinding.sln | 12 +++++- .../Project/ICSharpCode.Scripting.csproj | 6 +++ .../Project/Src/IScriptingConsole.cs | 2 + .../Src/IScriptingConsoleTextEditor.cs | 2 + .../Scripting/Project/Src/ScriptingConsole.cs | 12 ++++++ .../Project/Src/ScriptingConsolePad.cs | 11 +---- .../Project/Src/ScriptingConsoleTextEditor.cs | 5 +++ .../Project/Src/TextEditorFactory.cs | 28 +++++++++++++ .../Project/Src/ThreadSafeScriptingConsole.cs | 6 +++ .../Console/ScriptingConsoleWriteTests.cs | 41 +++++++++++++++++-- .../ThreadSafeScriptingConsoleTests.cs | 18 ++++++++ .../Test/Utils/FakeConsoleTextEditor.cs | 8 ++++ .../Test/Utils/FakeScriptingConsole.cs | 6 +++ .../Src/Scripting/PackageManagementConsole.cs | 10 +---- 14 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 src/AddIns/BackendBindings/Scripting/Project/Src/TextEditorFactory.cs diff --git a/src/AddIns/BackendBindings/Ruby/RubyBinding.sln b/src/AddIns/BackendBindings/Ruby/RubyBinding.sln index c10342e394..73be1a27ed 100644 --- a/src/AddIns/BackendBindings/Ruby/RubyBinding.sln +++ b/src/AddIns/BackendBindings/Ruby/RubyBinding.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.0.0.6808 +# SharpDevelop 4.1.0.7318-alpha Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RubyBinding", "RubyBinding\Project\RubyBinding.csproj", "{C896FFFF-5B6C-4B0E-B6DF-049865F501B4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RubyBinding.Tests", "RubyBinding\Test\RubyBinding.Tests.csproj", "{01DF0475-0CB2-4E81-971B-BADC60CDE3A5}" @@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting", ".. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Scripting.Tests", "..\Scripting\Test\ICSharpCode.Scripting.Tests.csproj", "{85C09AD8-183B-403A-869A-7226646218A9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.WinForms", "..\..\..\Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj", "{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -98,5 +100,13 @@ Global {85C09AD8-183B-403A-869A-7226646218A9}.Release|Any CPU.ActiveCfg = Release|x86 {85C09AD8-183B-403A-869A-7226646218A9}.Release|x86.Build.0 = Release|x86 {85C09AD8-183B-403A-869A-7226646218A9}.Release|x86.ActiveCfg = Release|x86 + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.Build.0 = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.Build.0 = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.ActiveCfg = Debug|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.Build.0 = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.ActiveCfg = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.Build.0 = Release|Any CPU + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection EndGlobal diff --git a/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj b/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj index 3f4e163dbe..da0c2f11f3 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj +++ b/src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj @@ -106,6 +106,7 @@ + @@ -126,6 +127,11 @@ ICSharpCode.Core False + + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} + ICSharpCode.Core.WinForms + False + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} ICSharpCode.SharpDevelop.Dom diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsole.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsole.cs index 9f11657a09..308bed30f2 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsole.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsole.cs @@ -8,6 +8,8 @@ namespace ICSharpCode.Scripting public interface IScriptingConsole : IDisposable { event EventHandler LineReceived; + + bool ScrollToEndWhenPromptWritten { get; set; } void SendLine(string line); void SendText(string text); diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsoleTextEditor.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsoleTextEditor.cs index 1499a2e469..88c73c8a6d 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsoleTextEditor.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/IScriptingConsoleTextEditor.cs @@ -77,5 +77,7 @@ namespace ICSharpCode.Scripting /// Makes the current text content read only. Text can be entered at the end. /// void MakeCurrentContentReadOnly(); + + void ScrollToEnd(); } } diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsole.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsole.cs index fd952b8437..12236811b3 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsole.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsole.cs @@ -34,6 +34,7 @@ namespace ICSharpCode.Scripting { this.textEditor = textEditor; this.unreadLines = unreadLines; + this.ScrollToEndWhenPromptWritten = true; textEditor.PreviewKeyDown += ProcessPreviewKeyDown; } @@ -77,6 +78,10 @@ namespace ICSharpCode.Scripting WriteFirstLineOfSentText(); textEditor.MakeCurrentContentReadOnly(); + + if (ScrollToEndWhenPromptWritten) { + ScrollToEnd(); + } } } @@ -340,5 +345,12 @@ namespace ICSharpCode.Scripting { return unreadLines.RemoveFirstLine(); } + + public bool ScrollToEndWhenPromptWritten { get; set; } + + void ScrollToEnd() + { + textEditor.ScrollToEnd(); + } } } diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsolePad.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsolePad.cs index 362873c3d3..e7d1c68a8b 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsolePad.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsolePad.cs @@ -3,9 +3,7 @@ using System; using ICSharpCode.AvalonEdit.Highlighting; -using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; -using AvalonEdit = ICSharpCode.AvalonEdit; namespace ICSharpCode.Scripting { @@ -17,19 +15,12 @@ namespace ICSharpCode.Scripting public ScriptingConsolePad() { - textEditor = CreateTextEditor(); + textEditor = TextEditorFactory.CreateTextEditor(); textEditor.SyntaxHighlighting = GetSyntaxHighlighting(); CreateConsoleHost(); host.Run(); } - AvalonEdit.TextEditor CreateTextEditor() - { - object textEditor; - EditorControlService.CreateEditor(out textEditor); - return (AvalonEdit.TextEditor)textEditor; - } - IHighlightingDefinition GetSyntaxHighlighting() { return HighlightingManager.Instance.GetDefinition(SyntaxHighlightingName); diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsoleTextEditor.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsoleTextEditor.cs index 315c83c656..4b616724b9 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsoleTextEditor.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingConsoleTextEditor.cs @@ -147,5 +147,10 @@ namespace ICSharpCode.Scripting completionWindow = null; } } + + public void ScrollToEnd() + { + textEditor.ScrollToEnd(); + } } } diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/TextEditorFactory.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/TextEditorFactory.cs new file mode 100644 index 0000000000..c51f80982a --- /dev/null +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/TextEditorFactory.cs @@ -0,0 +1,28 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Windows.Media; +using ICSharpCode.AvalonEdit; +using ICSharpCode.Core.WinForms; +using ICSharpCode.SharpDevelop.Editor; + +namespace ICSharpCode.Scripting +{ + public static class TextEditorFactory + { + public static TextEditor CreateTextEditor() + { + object control; + EditorControlService.CreateEditor(out control); + var textEditor = (TextEditor)control; + + textEditor.Options = new TextEditorOptions(); + textEditor.Options.AllowScrollBelowDocument = false; + textEditor.FontFamily = new FontFamily(WinFormsResourceService.DefaultMonospacedFont.Name); + textEditor.FontSize = 13.0; + + return textEditor; + } + } +} diff --git a/src/AddIns/BackendBindings/Scripting/Project/Src/ThreadSafeScriptingConsole.cs b/src/AddIns/BackendBindings/Scripting/Project/Src/ThreadSafeScriptingConsole.cs index 0b61c275d4..034805b4aa 100644 --- a/src/AddIns/BackendBindings/Scripting/Project/Src/ThreadSafeScriptingConsole.cs +++ b/src/AddIns/BackendBindings/Scripting/Project/Src/ThreadSafeScriptingConsole.cs @@ -35,6 +35,12 @@ namespace ICSharpCode.Scripting consoleEvents.SetLineReceivedEvent(); } + + public bool ScrollToEndWhenPromptWritten { + get { return nonThreadSafeScriptingConsole.ScrollToEndWhenPromptWritten; } + set { nonThreadSafeScriptingConsole.ScrollToEndWhenPromptWritten = value; } + } + public void WriteLine() { if (dispatcher.CheckAccess()) { diff --git a/src/AddIns/BackendBindings/Scripting/Test/Console/ScriptingConsoleWriteTests.cs b/src/AddIns/BackendBindings/Scripting/Test/Console/ScriptingConsoleWriteTests.cs index f8a94d8a73..9228bfe843 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Console/ScriptingConsoleWriteTests.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Console/ScriptingConsoleWriteTests.cs @@ -23,14 +23,14 @@ namespace ICSharpCode.Scripting.Tests.Console } [Test] - public void WriteLine() + public void WriteLine_WriteLine_NewLineWritten() { TestableScriptingConsole.WriteLine(); Assert.AreEqual(Environment.NewLine, FakeConsoleTextEditor.Text); } [Test] - public void WriteLineWithText() + public void WriteLine_WriteLineWithText_TextPlusNewLineWritten() { TestableScriptingConsole.WriteLine("test", ScriptingStyle.Out); string expectedText = "test" + Environment.NewLine; @@ -38,7 +38,7 @@ namespace ICSharpCode.Scripting.Tests.Console } [Test] - public void TwoWrites() + public void Write_TwoWrites_BothWrittenToTextEditor() { TestableScriptingConsole.Write("a", ScriptingStyle.Out); TestableScriptingConsole.Write("b", ScriptingStyle.Out); @@ -46,9 +46,42 @@ namespace ICSharpCode.Scripting.Tests.Console } [Test] - public void DoesNotHasLinesWaitingToBeRead() + public void Constructor_NewInstance_DoesNotHaveLinesWaitingToBeRead() { Assert.IsFalse(TestableScriptingConsole.IsLineAvailable); } + + [Test] + public void Write_WritePromptWhenScrollToPromptIsTrue_TextEditorIsScrolled() + { + TestableScriptingConsole.ScrollToEndWhenPromptWritten = true; + TestableScriptingConsole.Write("a", ScriptingStyle.Prompt); + + Assert.IsTrue(FakeConsoleTextEditor.IsScrollToEndCalled); + } + + [Test] + public void Write_WritePromptWhenScrollToPromptIsFalse_TextEditorIsNotScrolled() + { + TestableScriptingConsole.ScrollToEndWhenPromptWritten = false; + TestableScriptingConsole.Write("a", ScriptingStyle.Prompt); + + Assert.IsFalse(FakeConsoleTextEditor.IsScrollToEndCalled); + } + + [Test] + public void Write_WriteErrorWhenScrollToPromptIsTrue_TextEditorIsNotScrolled() + { + TestableScriptingConsole.ScrollToEndWhenPromptWritten = true; + TestableScriptingConsole.Write("a", ScriptingStyle.Error); + + Assert.IsFalse(FakeConsoleTextEditor.IsScrollToEndCalled); + } + + [Test] + public void ScrollToEndWhenPromptWritten_NewInstance_IsTrue() + { + Assert.IsTrue(TestableScriptingConsole.ScrollToEndWhenPromptWritten); + } } } diff --git a/src/AddIns/BackendBindings/Scripting/Test/Console/ThreadSafeScriptingConsoleTests.cs b/src/AddIns/BackendBindings/Scripting/Test/Console/ThreadSafeScriptingConsoleTests.cs index 844a21eb48..2c391cf405 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Console/ThreadSafeScriptingConsoleTests.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Console/ThreadSafeScriptingConsoleTests.cs @@ -353,5 +353,23 @@ namespace ICSharpCode.Scripting.Tests.Console string expectedLine = "abc"; Assert.AreEqual(expectedLine, line); } + + [Test] + public void ScrollToEndWhenPromptWritten_NonThreadSafeConsoleScrollToEndWhenPromptWrittenIsTrue_ReturnsTrue() + { + CreateThreadSafeScriptingConsole(); + nonThreadSafeScriptingConsole.ScrollToEndWhenPromptWritten = true; + + Assert.IsTrue(threadSafeConsole.ScrollToEndWhenPromptWritten); + } + + [Test] + public void ScrollToEndWhenPromptWritten_NonThreadSafeConsoleScrollToEndWhenPromptWrittenIsFalse_ReturnsFalse() + { + CreateThreadSafeScriptingConsole(); + nonThreadSafeScriptingConsole.ScrollToEndWhenPromptWritten = false; + + Assert.IsFalse(threadSafeConsole.ScrollToEndWhenPromptWritten); + } } } diff --git a/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeConsoleTextEditor.cs b/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeConsoleTextEditor.cs index 61a1598025..7bcb19dff2 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeConsoleTextEditor.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeConsoleTextEditor.cs @@ -195,5 +195,13 @@ namespace ICSharpCode.Scripting.Tests.Utils LineBuilder.Remove(SelectionStart, SelectionLength); } } + + public bool IsScrollToEndCalled; + public bool ScrollToEndWhenPromptWritten { get; set; } + + public void ScrollToEnd() + { + IsScrollToEndCalled = true; + } } } diff --git a/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeScriptingConsole.cs b/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeScriptingConsole.cs index 8da08a05dc..11df266974 100644 --- a/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeScriptingConsole.cs +++ b/src/AddIns/BackendBindings/Scripting/Test/Utils/FakeScriptingConsole.cs @@ -23,6 +23,7 @@ namespace ICSharpCode.Scripting.Tests.Utils public string TextToReturnFromReadFirstUnreadLine; public bool IsReadLineCalled; public bool IsDisposeCalled; + public bool ScrollToEndWhenPromptWritten { get; set; } public void SendLine(string text) { @@ -75,5 +76,10 @@ namespace ICSharpCode.Scripting.Tests.Utils { IsDisposeCalled = true; } + + public void ScrollToEnd() + { + + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsole.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsole.cs index a5915569aa..a6f6473fd3 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsole.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsole.cs @@ -13,16 +13,10 @@ namespace ICSharpCode.PackageManagement.Scripting TextEditor textEditor; public PackageManagementConsole() - : this(CreateTextEditor()) + : this(TextEditorFactory.CreateTextEditor()) { } - - static TextEditor CreateTextEditor() - { - object textEditor; - EditorControlService.CreateEditor(out textEditor); - return (TextEditor)textEditor; - } + public PackageManagementConsole(TextEditor textEditor) : this(new ScriptingConsoleTextEditor(textEditor), new ControlDispatcher(textEditor))