diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index 15db22a072..c3cf1cdae1 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -2160,6 +2160,23 @@ class = "ICSharpCode.SharpDevelop.Gui.SelectScopeCommand" type = "ComboBox"/> + + + + + + + diff --git a/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.DeleteHistory.png b/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.DeleteHistory.png new file mode 100644 index 0000000000..ca252ae5e3 Binary files /dev/null and b/data/resources/image/BitmapResources/BitmapResources-data/Icons.16x16.DeleteHistory.png differ diff --git a/data/resources/image/BitmapResources/BitmapResources.res b/data/resources/image/BitmapResources/BitmapResources.res index 15a2749cc7..bdbd26b684 100644 --- a/data/resources/image/BitmapResources/BitmapResources.res +++ b/data/resources/image/BitmapResources/BitmapResources.res @@ -225,6 +225,7 @@ Icons.16x16.CloseFileIcon = BitmapResources-data\Icons.1 Icons.16x16.OpenFileIcon = BitmapResources-data\Icons.16x16.OpenFileIcon.png Icons.16x16.HtmlElements.FieldSetElement = BitmapResources-data\Icons.16x16.HtmlElements.FieldSetElement.png Icons.16x16.SplitWindow = BitmapResources-data\Icons.16x16.SplitWindow.png +Icons.16x16.DeleteHistory = BitmapResources-data\Icons.16x16.DeleteHistory.png #pad icons PadIcons.ErrorList = PadIcons\ErrorList.png diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/InteractiveInterpreter.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/InteractiveInterpreter.cs index 9f7225a323..66a3f007f1 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/InteractiveInterpreter.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/InteractiveInterpreter.cs @@ -19,44 +19,21 @@ namespace Grunwald.BooBinding /// /// Interactive Boo interpreter. /// - public class InteractiveInterpreterPad : TextEditorBasedPad + public class InteractiveInterpreterPad : AbstractConsolePad { - InteractiveInterpreterControl ctl = new InteractiveInterpreterControl(); + InteractiveInterpreter interpreter; - public override ICSharpCode.TextEditor.TextEditorControl TextEditorControl { + protected override string Prompt { get { - return ctl; + return ">>> "; } } - } - - sealed class InteractiveInterpreterControl : CommandPromptControl - { - InteractiveInterpreter interpreter; - public InteractiveInterpreterControl() + protected override void InitializeConsole() { + base.InitializeConsole(); + SetHighlighting("Boo"); - PrintPrompt(); - } - - void PrintLine(object text) - { - if (text == null) - return; - if (WorkbenchSingleton.InvokeRequired) { - WorkbenchSingleton.SafeThreadAsyncCall(PrintLine, text); - } else { - if (processing) - Append(Environment.NewLine + text.ToString()); - else - InsertLineBeforePrompt(text.ToString()); - } - } - - protected override void PrintPromptInternal() - { - Append(">>> "); } protected override void AcceptCommand(string command) @@ -66,8 +43,7 @@ namespace Grunwald.BooBinding } else if (!command.Contains("\n") && !command.EndsWith(":")) { ProcessCommand(command); } else { - Append(Environment.NewLine); - ActiveTextAreaControl.Caret.Position = this.Document.OffsetToPosition(this.Document.TextLength); + TextEditor.Caret.Position = TextEditor.Document.OffsetToPosition(TextEditor.Document.TextLength); } } @@ -105,10 +81,22 @@ namespace Grunwald.BooBinding PrintLine(ex.InnerException); } processing = false; - if (this.Document.TextLength != 0) { - Append(Environment.NewLine); + + Append(Environment.NewLine); + } + + void PrintLine(object text) + { + if (text == null) + return; + if (WorkbenchSingleton.InvokeRequired) { + WorkbenchSingleton.SafeThreadAsyncCall(PrintLine, text); + } else { + if (processing) + Append(text.ToString()); + else + InsertLineBeforePrompt(text.ToString()); } - PrintPrompt(); } protected override void Clear() diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs index a4bc985494..d2b6a62c1c 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ConsolePad.cs @@ -16,56 +16,15 @@ using ICSharpCode.TextEditor; namespace ICSharpCode.SharpDevelop.Gui.Pads { - public class ConsolePad : TextEditorBasedPad + public class ConsolePad : AbstractConsolePad { - ConsoleControl editor = new ConsoleControl(); - - public override TextEditorControl TextEditorControl { - get { - return editor; - } - } - - public ConsolePad() - { - WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger; - - debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) { - editor.Process = e.Process; - }; - editor.Process = debugger.DebuggedProcess; - } - } - - class ConsoleControl : CommandPromptControl - { - Process process; - - public Process Process { - get { return process; } - set { process = value; } - } - - public ConsoleControl() - { - SetHighlighting("C#"); - PrintPrompt(); - } - - protected override void PrintPromptInternal() - { - Append("> "); - } - protected override void AcceptCommand(string command) { if (!string.IsNullOrEmpty(command)) { string result = Evaluate(command); - Append(Environment.NewLine); if (!string.IsNullOrEmpty(result)) { Append(result + Environment.NewLine); } - PrintPrompt(); } } @@ -84,5 +43,35 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads return e.Message; } } + + Process process; + + public Process Process { + get { return process; } + set { process = value; } + } + + protected override string Prompt { + get { + return "> "; + } + } + + protected override void InitializeConsole() + { + base.InitializeConsole(); + + SetHighlighting("C#"); + } + + public ConsolePad() + { + WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger; + + debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) { + this.Process = e.Process; + }; + this.Process = debugger.DebuggedProcess; + } } } diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 3d7c44a3b7..0b645a0807 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -183,6 +183,7 @@ Code + @@ -611,7 +612,6 @@ UserControl - UserControl diff --git a/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs b/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs new file mode 100644 index 0000000000..afb54e7bf9 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Pads/AbstractConsolePad.cs @@ -0,0 +1,351 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.Core.Presentation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Editing; +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.AvalonEdit; + +namespace ICSharpCode.SharpDevelop.Gui +{ + public abstract class AbstractConsolePad : AbstractPadContent, IEditable, IPositionable, ITextEditorProvider, IToolsHost + { + const string toolBarTreePath = "/SharpDevelop/Pads/CommonConsole/ToolBar"; + + DockPanel panel; + ConsoleControl console; + ToolBar toolbar; + + bool cleared; + IList history; + int historyPointer; + + protected AbstractConsolePad() + { + this.panel = new DockPanel(); + + this.toolbar = ToolBarService.CreateToolBar(this, toolBarTreePath); + this.toolbar.SetValue(DockPanel.DockProperty, Dock.Top); + + this.console = new ConsoleControl(); + + this.panel.Children.Add(toolbar); + this.panel.Children.Add(console); + + this.history = new List(); + + this.console.editor.TextArea.PreviewKeyDown += (sender, e) => { + e.Handled = HandleInput(e.Key); + }; + + this.InitializeConsole(); + } + + public virtual ITextEditor TextEditor { + get { + return console.TextEditor; + } + } + + public override object Control { + get { return panel; } + } + + string GetText() + { + return this.TextEditor.Document.Text; + } + + /// + /// Creates a snapshot of the editor content. + /// This method is thread-safe. + /// + public ITextBuffer CreateSnapshot() + { + return new StringTextBuffer(GetText()); + } + + string IEditable.Text { + get { + return GetText(); + } + } + + public virtual ICSharpCode.SharpDevelop.Editor.IDocument GetDocumentForFile(OpenedFile file) + { + return null; + } + + #region IPositionable implementation + void IPositionable.JumpTo(int line, int column) + { + this.TextEditor.JumpTo(line, column); + } + + int IPositionable.Line { + get { + return this.TextEditor.Caret.Line; + } + } + + int IPositionable.Column { + get { + return this.TextEditor.Caret.Column; + } + } + #endregion + + object IToolsHost.ToolsContent { + get { return TextEditorSideBar.Instance; } + } + + protected virtual bool HandleInput(Key key) { + switch (key) { + case Key.Down: + this.historyPointer = Math.Min(this.historyPointer + 1, this.history.Count); + if (this.historyPointer == this.history.Count) + console.CommandText = ""; + else + console.CommandText = this.history[this.historyPointer]; + console.editor.ScrollToEnd(); + return true; + case Key.Up: + this.historyPointer = Math.Max(this.historyPointer - 1, 0); + if (this.historyPointer == this.history.Count) + console.CommandText = ""; + else + console.CommandText = this.history[this.historyPointer]; + console.editor.ScrollToEnd(); + return true; + case Key.Return: + if (Keyboard.Modifiers == ModifierKeys.Shift) + return false; + string commandText = console.CommandText; + this.console.TextEditor.Document.Insert(this.console.TextEditor.Document.TextLength, "\n"); + if (!string.IsNullOrEmpty(commandText)) + AcceptCommand(commandText); + if (!cleared) + AppendPrompt(); + else + console.CommandText = ""; + cleared = false; + this.history.Add(commandText); + this.historyPointer = this.history.Count; + console.editor.ScrollToEnd(); + return true; + } + + return false; + } + + /// + /// Deletes the content of the console and prints a new prompt. + /// + public void ClearConsole() + { + this.console.editor.Document.Text = ""; + cleared = true; + AppendPrompt(); + } + + /// + /// Deletes the console history. + /// + public void DeleteHistory() + { + this.history.Clear(); + this.historyPointer = 0; + } + + public void SetHighlighting(string language) + { + this.console.SetHighlighting(language); + } + + public bool WordWrap { + get { return this.console.editor.WordWrap; } + set { this.console.editor.WordWrap = value; } + } + + protected abstract string Prompt { + get; + } + + protected abstract void AcceptCommand(string command); + + protected virtual void InitializeConsole() + { + AppendPrompt(); + } + + protected virtual void AppendPrompt() + { + console.Append(Prompt); + console.SetReadonly(); + console.editor.Document.UndoStack.ClearAll(); + } + + protected void Append(string text) + { + console.Append(text); + } + + protected void InsertLineBeforePrompt(string text) + { + text += Environment.NewLine; + this.console.editor.Document.Insert(this.console.readOnlyRegion.EndOffset - Prompt.Length, text); + this.console.SetReadonly(this.console.readOnlyRegion.EndOffset + text.Length); + } + + protected virtual void Clear() + { + this.ClearConsole(); + } + } + + class ConsoleControl : Grid + { + internal AvalonEdit.TextEditor editor; + internal BeginReadOnlySectionProvider readOnlyRegion; + + public ConsoleControl() + { + this.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); + this.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); + + this.editor = new ICSharpCode.AvalonEdit.TextEditor(); + this.editor.SetValue(Grid.ColumnProperty, 0); + this.editor.SetValue(Grid.RowProperty, 0); + + this.editor.Background = Brushes.White; + this.editor.FontFamily = new FontFamily("Consolas"); + this.editor.FontSize = 13; + this.Children.Add(editor); + + editor.TextArea.ReadOnlySectionProvider = readOnlyRegion = new BeginReadOnlySectionProvider(); + } + + public ITextEditor TextEditor { + get { + return new AvalonEditTextEditorAdapter(editor); + } + } + + public void SetHighlighting(string language) + { + editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition(language); + } + + public void Append(string text) + { + editor.AppendText(text); + } + + /// + /// Sets the readonly region to a specified offset. + /// + public void SetReadonly(int offset) + { + readOnlyRegion.EndOffset = offset; + } + + /// + /// Sets the readonly region to the end of the document. + /// + public void SetReadonly() + { + readOnlyRegion.EndOffset = editor.Document.TextLength; + } + + /// + /// Gets/sets the command text displayed at the command prompt. + /// + public string CommandText { + get { + return editor.Document.GetText(new TextSegment() { StartOffset = readOnlyRegion.EndOffset, EndOffset = editor.Document.TextLength }); + } + set { + editor.Document.Replace(new TextSegment() { StartOffset = readOnlyRegion.EndOffset, EndOffset = editor.Document.TextLength }, value); + } + } + } + + class BeginReadOnlySectionProvider : IReadOnlySectionProvider + { + public int EndOffset { get; set; } + + public bool CanInsert(int offset) + { + return offset >= EndOffset; + } + + public IEnumerable GetDeletableSegments(ISegment segment) + { + return new[] { + new TextSegment() { + StartOffset = Math.Max(this.EndOffset, segment.Offset), + EndOffset = segment.EndOffset + } + }; + } + } + + class ClearConsoleCommand : AbstractMenuCommand + { + public override void Run() + { + var pad = this.Owner as AbstractConsolePad; + if (pad != null) + pad.ClearConsole(); + } + } + + class DeleteHistoryCommand : AbstractMenuCommand + { + public override void Run() + { + var pad = this.Owner as AbstractConsolePad; + if (pad != null) + pad.DeleteHistory(); + } + } + + class ToggleConsoleWordWrapCommand : AbstractCheckableMenuCommand + { + AbstractConsolePad pad; + + public override object Owner { + get { return base.Owner; } + set { + if (!(value is AbstractConsolePad)) + throw new Exception("Owner has to be a AbstractConsolePad"); + pad = value as AbstractConsolePad; + base.Owner = value; + } + } + + public override bool IsChecked { + get { return pad.WordWrap; } + set { pad.WordWrap = value; } + } + + public override void Run() + { + IsChecked = !IsChecked; + } + } +} diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorBasedPad.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorBasedPad.cs deleted file mode 100644 index 1d08192e98..0000000000 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorBasedPad.cs +++ /dev/null @@ -1,186 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using ICSharpCode.SharpDevelop.Editor; -using System; -using System.Drawing.Printing; -using System.Windows.Forms; -using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Document; - -namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor -{ - /// - /// Description of TextEditorBasedPad. - /// - public abstract class TextEditorBasedPad : AbstractPadContent, IEditable, IUndoHandler, IPositionable, ITextEditorControlProvider, IPrintable, IToolsHost, IClipboardHandler - { - public abstract TextEditorControl TextEditorControl { - get; - } - - public virtual ICSharpCode.SharpDevelop.Editor.ITextEditor TextEditor { - get { - return new TextEditorAdapter(this.TextEditorControl); - } - } - - public override object Control { - get { return this.TextEditorControl; } - } - - bool IUndoHandler.EnableUndo { - get { - return this.TextEditorControl.EnableUndo; - } - } - - bool IUndoHandler.EnableRedo { - get { - return this.TextEditorControl.EnableRedo; - } - } - - string GetText() - { - return this.TextEditorControl.Document.TextContent; - } - - void SetText(string value) - { - this.TextEditorControl.Document.Replace(0, this.TextEditorControl.Document.TextLength, value); - } - - /// - /// Creates a snapshot of the editor content. - /// This method is thread-safe. - /// - public ITextBuffer CreateSnapshot() - { - string content = WorkbenchSingleton.SafeThreadFunction(GetText); - return new StringTextBuffer(content); - } - - string IEditable.Text { - get { - if (WorkbenchSingleton.InvokeRequired) - return WorkbenchSingleton.SafeThreadFunction(GetText); - else - return GetText(); - } - } - - public virtual ICSharpCode.SharpDevelop.Editor.IDocument GetDocumentForFile(OpenedFile file) - { - return null; - } - - PrintDocument IPrintable.PrintDocument { - get { - return this.TextEditorControl.PrintDocument; - } - } - - void IUndoHandler.Undo() - { - this.TextEditorControl.Undo(); - } - - void IUndoHandler.Redo() - { - this.TextEditorControl.Redo(); - } - - #region IPositionable implementation - void IPositionable.JumpTo(int line, int column) - { - this.TextEditorControl.ActiveTextAreaControl.JumpTo(line - 1, column - 1); - - // we need to delay this call here because the text editor does not know its height if it was just created - WorkbenchSingleton.SafeThreadAsyncCall( - delegate { - this.TextEditorControl.ActiveTextAreaControl.CenterViewOn( - line - 1, (int)(0.3 * this.TextEditorControl.ActiveTextAreaControl.TextArea.TextView.VisibleLineCount)); - }); - } - - int IPositionable.Line { - get { - return this.TextEditorControl.ActiveTextAreaControl.Caret.Line + 1; - } - } - - int IPositionable.Column { - get { - return this.TextEditorControl.ActiveTextAreaControl.Caret.Column + 1; - } - } - #endregion - - object IToolsHost.ToolsContent { - get { return TextEditorSideBar.Instance; } - } - - #region ICSharpCode.SharpDevelop.Gui.IClipboardHandler interface implementation - public bool EnableCut { - get { - return this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.EnableCut; - } - } - - public bool EnableCopy { - get { - return this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.EnableCopy; - } - } - - public bool EnablePaste { - get { - return this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.EnablePaste; - } - } - - public bool EnableDelete { - get { - return this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.EnableDelete; - } - } - - public bool EnableSelectAll { - get { - return this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.EnableSelectAll; - } - } - - public void SelectAll() - { - this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.SelectAll(null, null); - } - - public void Delete() - { - this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.Delete(null, null); - } - - public void Paste() - { - this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(null, null); - } - - public void Copy() - { - this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(null, null); - } - - public void Cut() - { - this.TextEditorControl.ActiveTextAreaControl.TextArea.ClipboardHandler.Cut(null, null); - } - #endregion - } -} diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs index b320ee44a9..b49be6c568 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs +++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs @@ -56,4 +56,46 @@ namespace ICSharpCode.Core.Presentation this.Visibility = Visibility.Visible; } } + + sealed class ToolBarCheckBox : CheckBox, IStatusUpdate + { + readonly Codon codon; + readonly object caller; + + public ToolBarCheckBox(Codon codon, object caller, bool createCommand) + { + ToolTipService.SetShowOnDisabled(this, true); + + this.codon = codon; + this.caller = caller; + this.Command = CommandWrapper.GetCommand(codon, caller, createCommand); + + if (codon.Properties.Contains("icon")) { + var image = PresentationResourceService.GetImage(StringParser.Parse(codon.Properties["icon"])); + image.Height = 16; + image.SetResourceReference(StyleProperty, ToolBarService.ImageStyleKey); + this.Content = new PixelSnapper(image); + } else { + this.Content = codon.Id; + } + UpdateText(); + + SetResourceReference(FrameworkElement.StyleProperty, ToolBar.ButtonStyleKey); + } + + public void UpdateText() + { + if (codon.Properties.Contains("tooltip")) { + this.ToolTip = StringParser.Parse(codon.Properties["tooltip"]); + } + } + + public void UpdateStatus() + { + if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude) + this.Visibility = Visibility.Collapsed; + else + this.Visibility = Visibility.Visible; + } + } } diff --git a/src/Main/StartUp/Project/Resources/BitmapResources.resources b/src/Main/StartUp/Project/Resources/BitmapResources.resources index 50ce7ca6c5..f6f756de59 100644 Binary files a/src/Main/StartUp/Project/Resources/BitmapResources.resources and b/src/Main/StartUp/Project/Resources/BitmapResources.resources differ