// 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.Linq; using System.Windows; using System.Windows.Input; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Search; namespace ICSharpCode.AvalonEdit.Editing { /// /// Contains the predefined input handlers. /// public class TextAreaDefaultInputHandler : TextAreaInputHandler { /// /// Gets the caret navigation input handler. /// public TextAreaInputHandler CaretNavigation { get; private set; } /// /// Gets the editing input handler. /// public TextAreaInputHandler Editing { get; private set; } /// /// Gets the mouse selection input handler. /// public ITextAreaInputHandler MouseSelection { get; private set; } /// /// Creates a new TextAreaDefaultInputHandler instance. /// public TextAreaDefaultInputHandler(TextArea textArea) : base(textArea) { this.NestedInputHandlers.Add(CaretNavigation = CaretNavigationCommandHandler.Create(textArea)); this.NestedInputHandlers.Add(Editing = EditingCommandHandler.Create(textArea)); this.NestedInputHandlers.Add(MouseSelection = new SelectionMouseHandler(textArea)); this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, ExecuteUndo, CanExecuteUndo)); this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, ExecuteRedo, CanExecuteRedo)); this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Find, ExecuteFind)); this.CommandBindings.Add(new CommandBinding(SearchCommands.FindNext, ExecuteFindNext)); this.CommandBindings.Add(new CommandBinding(SearchCommands.FindPrevious, ExecuteFindPrevious)); } internal static KeyBinding CreateFrozenKeyBinding(ICommand command, ModifierKeys modifiers, Key key) { KeyBinding kb = new KeyBinding(command, key, modifiers); // Mark KeyBindings as frozen because they're shared between multiple editor instances. // KeyBinding derives from Freezable only in .NET 4, so we have to use this little trick: Freezable f = ((object)kb) as Freezable; if (f != null) f.Freeze(); return kb; } #region Undo / Redo UndoStack GetUndoStack() { TextDocument document = this.TextArea.Document; if (document != null) return document.UndoStack; else return null; } void ExecuteUndo(object sender, ExecutedRoutedEventArgs e) { var undoStack = GetUndoStack(); if (undoStack != null) { if (undoStack.CanUndo) { undoStack.Undo(); this.TextArea.Caret.BringCaretToView(); } e.Handled = true; } } void CanExecuteUndo(object sender, CanExecuteRoutedEventArgs e) { var undoStack = GetUndoStack(); if (undoStack != null) { e.Handled = true; e.CanExecute = undoStack.CanUndo; } } void ExecuteRedo(object sender, ExecutedRoutedEventArgs e) { var undoStack = GetUndoStack(); if (undoStack != null) { if (undoStack.CanRedo) { undoStack.Redo(); this.TextArea.Caret.BringCaretToView(); } e.Handled = true; } } void CanExecuteRedo(object sender, CanExecuteRoutedEventArgs e) { var undoStack = GetUndoStack(); if (undoStack != null) { e.Handled = true; e.CanExecute = undoStack.CanRedo; } } #endregion void ExecuteFind(object sender, ExecutedRoutedEventArgs e) { var panel = TextArea.TextView.Layers.OfType().FirstOrDefault(); if (panel == null) new SearchPanel(TextArea); else panel.Reactivate(); } void ExecuteFindNext(object sender, ExecutedRoutedEventArgs e) { var panel = TextArea.TextView.Layers.OfType().FirstOrDefault(); if (panel != null) panel.FindNext(); } void ExecuteFindPrevious(object sender, ExecutedRoutedEventArgs e) { var panel = TextArea.TextView.Layers.OfType().FirstOrDefault(); if (panel != null) panel.FindPrevious(); } } }