Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2877_HiveImprovements/HeuristicLab.ExtLibs/HeuristicLab.AvalonEdit/5.0.1/AvalonEdit-5.0.1/Editing/TextAreaDefaultInputHandlers.cs @ 16755

Last change on this file since 16755 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 4.5 KB
Line 
1// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19using System;
20using System.Collections.Generic;
21using System.Windows;
22using System.Windows.Input;
23
24using ICSharpCode.AvalonEdit.Document;
25
26namespace ICSharpCode.AvalonEdit.Editing
27{
28  /// <summary>
29  /// Contains the predefined input handlers.
30  /// </summary>
31  public class TextAreaDefaultInputHandler : TextAreaInputHandler
32  {
33    /// <summary>
34    /// Gets the caret navigation input handler.
35    /// </summary>
36    public TextAreaInputHandler CaretNavigation { get; private set; }
37   
38    /// <summary>
39    /// Gets the editing input handler.
40    /// </summary>
41    public TextAreaInputHandler Editing { get; private set; }
42   
43    /// <summary>
44    /// Gets the mouse selection input handler.
45    /// </summary>
46    public ITextAreaInputHandler MouseSelection { get; private set; }
47   
48    /// <summary>
49    /// Creates a new TextAreaDefaultInputHandler instance.
50    /// </summary>
51    public TextAreaDefaultInputHandler(TextArea textArea) : base(textArea)
52    {
53      this.NestedInputHandlers.Add(CaretNavigation = CaretNavigationCommandHandler.Create(textArea));
54      this.NestedInputHandlers.Add(Editing = EditingCommandHandler.Create(textArea));
55      this.NestedInputHandlers.Add(MouseSelection = new SelectionMouseHandler(textArea));
56     
57      this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, ExecuteUndo, CanExecuteUndo));
58      this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, ExecuteRedo, CanExecuteRedo));
59    }
60   
61    internal static KeyBinding CreateFrozenKeyBinding(ICommand command, ModifierKeys modifiers, Key key)
62    {
63      KeyBinding kb = new KeyBinding(command, key, modifiers);
64      // Mark KeyBindings as frozen because they're shared between multiple editor instances.
65      // KeyBinding derives from Freezable only in .NET 4, so we have to use this little trick:
66      Freezable f = ((object)kb) as Freezable;
67      if (f != null)
68        f.Freeze();
69      return kb;
70    }
71   
72    internal static void WorkaroundWPFMemoryLeak(List<InputBinding> inputBindings)
73    {
74      // Work around WPF memory leak:
75      // KeyBinding retains a reference to whichever UIElement it is used in first.
76      // Using a dummy element for this purpose ensures that we don't leak
77      // a real text editor (with a potentially large document).
78      UIElement dummyElement = new UIElement();
79      dummyElement.InputBindings.AddRange(inputBindings);
80    }
81   
82    #region Undo / Redo
83    UndoStack GetUndoStack()
84    {
85      TextDocument document = this.TextArea.Document;
86      if (document != null)
87        return document.UndoStack;
88      else
89        return null;
90    }
91   
92    void ExecuteUndo(object sender, ExecutedRoutedEventArgs e)
93    {
94      var undoStack = GetUndoStack();
95      if (undoStack != null) {
96        if (undoStack.CanUndo) {
97          undoStack.Undo();
98          this.TextArea.Caret.BringCaretToView();
99        }
100        e.Handled = true;
101      }
102    }
103   
104    void CanExecuteUndo(object sender, CanExecuteRoutedEventArgs e)
105    {
106      var undoStack = GetUndoStack();
107      if (undoStack != null) {
108        e.Handled = true;
109        e.CanExecute = undoStack.CanUndo;
110      }
111    }
112   
113    void ExecuteRedo(object sender, ExecutedRoutedEventArgs e)
114    {
115      var undoStack = GetUndoStack();
116      if (undoStack != null) {
117        if (undoStack.CanRedo) {
118          undoStack.Redo();
119          this.TextArea.Caret.BringCaretToView();
120        }
121        e.Handled = true;
122      }
123    }
124   
125    void CanExecuteRedo(object sender, CanExecuteRoutedEventArgs e)
126    {
127      var undoStack = GetUndoStack();
128      if (undoStack != null) {
129        e.Handled = true;
130        e.CanExecute = undoStack.CanRedo;
131      }
132    }
133    #endregion
134  }
135}
Note: See TracBrowser for help on using the repository browser.