1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.xnap.gui.component;
20
21 import java.awt.event.InputEvent;
22 import java.awt.event.KeyAdapter;
23 import java.awt.event.KeyEvent;
24 import java.awt.event.KeyListener;
25
26 import javax.swing.KeyStroke;
27 import javax.swing.text.JTextComponent;
28
29 import org.apache.log4j.Logger;
30 import org.xnap.XNap;
31 import org.xnap.gui.shortcut.DefaultShortcut;
32 import org.xnap.gui.shortcut.ShortcutManager;
33
34
35 /***
36 *
37 */
38 public class EmacsCompletionMode extends CompletionMode
39 {
40
41 private static DefaultShortcut forward = new DefaultShortcut
42 (KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_MASK),
43 XNap.tr("Completion"), XNap.tr("Emacs Cycle Forward"),
44 "emacsCycleForward");
45
46 private static DefaultShortcut backward = new DefaultShortcut
47 (KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK),
48 XNap.tr("Completion"), XNap.tr("Emacs Cycle Backward"),
49 "emacsCycleBackward");
50
51 static {
52 ShortcutManager.getInstance().add(forward);
53 ShortcutManager.getInstance().add(backward);
54 }
55
56 private static Logger logger = Logger.getLogger(EmacsCompletionMode.class);
57 /***
58 * Holds the key listener used for receiving the mode's trigger key events.
59 */
60 private KeyListener listener = new KeyHandler();
61 /***
62 * The current set of possible completions for the input which can be
63 * traversed.
64 */
65 private Object[] matches = null;
66 /***
67 * The index of the currently shown completion.
68 */
69 private int index = 0;
70 /***
71 * The original string which triggered the completion.
72 */
73 private String orig = null;
74
75 /***
76 * @param textComponent
77 * @param model
78 * @param wholeText
79 */
80 public EmacsCompletionMode(JTextComponent textComponent,
81 CompletionModel model, boolean wholeText)
82 {
83 super(textComponent, model, wholeText);
84 }
85
86 /***
87 * @param textComponent
88 * @param wholeText
89 */
90 public EmacsCompletionMode(JTextComponent textComponent, boolean wholeText)
91 {
92 super(textComponent, wholeText);
93 }
94
95 /***
96 * @param textComponent
97 * @param model
98 */
99 public EmacsCompletionMode(JTextComponent textComponent,
100 CompletionModel model)
101 {
102 super(textComponent, model);
103 }
104
105 /***
106 * @param textComponent
107 */
108 public EmacsCompletionMode(JTextComponent textComponent)
109 {
110 super(textComponent);
111 }
112
113
114
115
116 public String getName()
117 {
118 return XNap.tr("Emacs Completion");
119 }
120
121 protected void disable()
122 {
123 getTextComponent().removeKeyListener(listener);
124 }
125
126 protected void enable()
127 {
128 getTextComponent().addKeyListener(listener);
129 }
130
131 private Object[] getMatches()
132 {
133 int size = getModel().getSize();
134 Object[] matches = new Object[size];
135
136 for (int i = 0; i < size; i++) {
137 matches[i] = getModel().getElementAt(i);
138 }
139
140 return matches;
141 }
142
143 private class KeyHandler extends KeyAdapter
144 {
145 public void keyPressed(KeyEvent e)
146 {
147 if (forward.getKeyStroke() != null
148 && forward.getKeyStroke().equals
149 (KeyStroke.getKeyStrokeForEvent(e))) {
150
151 if (matches != null) {
152 if ((index + 1) == matches.length) {
153 setText(orig);
154 getTextComponent().getToolkit().beep();
155 matches = null;
156 }
157 else {
158 setText(matches[++index].toString());
159 }
160 }
161 else if (getModel().complete(getText())) {
162 orig = getText();
163 matches = getMatches();
164 index = 0;
165 setText(matches[0].toString());
166 }
167 e.consume();
168 }
169 else if (backward.getKeyStroke() != null
170 && backward.getKeyStroke().equals
171 (KeyStroke.getKeyStrokeForEvent(e))) {
172
173 if (matches != null) {
174 if (index > 0) {
175 setText(matches[--index].toString());
176 }
177 else {
178 setText(orig);
179 matches = null;
180 }
181 }
182 e.consume();
183 }
184 else if (e.getKeyCode() != KeyEvent.VK_ALT
185 && e.getKeyCode() != KeyEvent.VK_CONTROL
186 && e.getKeyCode() != KeyEvent.VK_SHIFT
187 && e.getKeyCode() != KeyEvent.VK_META) {
188 matches = null;
189 }
190 }
191 }
192 }