comparison dwtx/jface/bindings/keys/KeySequence.d @ 16:e0f0aaf75edd

PopupDialog, bindings and actions
author Frank Benoit <benoit@tionex.de>
date Tue, 01 Apr 2008 08:00:31 +0200
parents
children e10d9c2648be
comparison
equal deleted inserted replaced
15:db8940420ed8 16:e0f0aaf75edd
1 /*******************************************************************************
2 * Copyright (c) 2004, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13
14 module dwtx.jface.bindings.keys.KeySequence;
15
16 import dwtx.jface.bindings.keys.KeyStroke;
17
18 import tango.util.collection.ArraySeq;
19 import tango.util.collection.model.Seq;
20 import tango.util.collection.model.SeqView;
21
22 import dwtx.jface.bindings.TriggerSequence;
23 import dwtx.jface.bindings.keys.formatting.KeyFormatterFactory;
24
25 import dwtx.jface.util.Util;
26
27 import dwt.dwthelper.utils;
28 static import tango.text.Util;
29 /**
30 * <p>
31 * A <code>KeySequence</code> is defined as a list of zero or more
32 * <code>KeyStrokes</code>, with the stipulation that all
33 * <code>KeyStroke</code> objects must be complete, save for the last one,
34 * whose completeness is optional. A <code>KeySequence</code> is said to be
35 * complete if all of its <code>KeyStroke</code> objects are complete.
36 * </p>
37 * <p>
38 * All <code>KeySequence</code> objects have a formal string representation
39 * available via the <code>toString()</code> method. There are a number of
40 * methods to get instances of <code>KeySequence</code> objects, including one
41 * which can parse this formal string representation.
42 * </p>
43 * <p>
44 * All <code>KeySequence</code> objects, via the <code>format()</code>
45 * method, provide a version of their formal string representation translated by
46 * platform and locale, suitable for display to a user.
47 * </p>
48 * <p>
49 * <code>KeySequence</code> objects are immutable. Clients are not permitted
50 * to extend this class.
51 * </p>
52 *
53 * @since 3.1
54 */
55 public final class KeySequence : TriggerSequence, Comparable {
56
57 /**
58 * An empty key sequence instance for use by everyone.
59 */
60 private const static KeySequence EMPTY_KEY_SEQUENCE;
61
62 static this(){
63 EMPTY_KEY_SEQUENCE = new KeySequence(null);
64 }
65
66 /**
67 * The delimiter between multiple key strokes in a single key sequence --
68 * expressed in the formal key stroke grammar. This is not to be displayed
69 * to the user. It is only intended as an internal representation.
70 */
71 public const static String KEY_STROKE_DELIMITER = "\u0020"; //$NON-NLS-1$
72
73 /**
74 * The set of delimiters for <code>KeyStroke</code> objects allowed during
75 * parsing of the formal string representation.
76 */
77 public const static String KEY_STROKE_DELIMITERS = KEY_STROKE_DELIMITER
78 ~ "\b\r\u007F\u001B\f\n\0\t\u000B"; //$NON-NLS-1$
79
80 /**
81 * Gets an instance of <code>KeySequence</code>.
82 *
83 * @return a key sequence. This key sequence will have no key strokes.
84 * Guaranteed not to be <code>null</code>.
85 */
86 public static final KeySequence getInstance() {
87 return EMPTY_KEY_SEQUENCE;
88 }
89
90 /**
91 * Creates an instance of <code>KeySequence</code> given a key sequence
92 * and a key stroke.
93 *
94 * @param keySequence
95 * a key sequence. Must not be <code>null</code>.
96 * @param keyStroke
97 * a key stroke. Must not be <code>null</code>.
98 * @return a key sequence that is equal to the given key sequence with the
99 * given key stroke appended to the end. Guaranteed not to be
100 * <code>null</code>.
101 */
102 public static final KeySequence getInstance(KeySequence keySequence,
103 KeyStroke keyStroke) {
104 if (keySequence is null || keyStroke is null) {
105 throw new NullPointerException();
106 }
107
108 KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
109 int oldKeyStrokeLength = oldKeyStrokes.length;
110 KeyStroke[] newKeyStrokes = new KeyStroke[oldKeyStrokeLength + 1];
111 System.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
112 oldKeyStrokeLength);
113 newKeyStrokes[oldKeyStrokeLength] = keyStroke;
114 return new KeySequence(newKeyStrokes);
115 }
116
117 /**
118 * Creates an instance of <code>KeySequence</code> given a single key
119 * stroke.
120 *
121 * @param keyStroke
122 * a single key stroke. Must not be <code>null</code>.
123 * @return a key sequence. Guaranteed not to be <code>null</code>.
124 */
125 public static final KeySequence getInstance(KeyStroke keyStroke) {
126 return new KeySequence([ keyStroke ]);
127 }
128
129 /**
130 * Creates an instance of <code>KeySequence</code> given an array of key
131 * strokes.
132 *
133 * @param keyStrokes
134 * the array of key strokes. This array may be empty, but it must
135 * not be <code>null</code>. This array must not contain
136 * <code>null</code> elements.
137 * @return a key sequence. Guaranteed not to be <code>null</code>.
138 */
139 public static final KeySequence getInstance(KeyStroke[] keyStrokes) {
140 return new KeySequence(keyStrokes);
141 }
142
143 /**
144 * Creates an instance of <code>KeySequence</code> given a list of key
145 * strokes.
146 *
147 * @param keyStrokes
148 * the list of key strokes. This list may be empty, but it must
149 * not be <code>null</code>. If this list is not empty, it
150 * must only contain instances of <code>KeyStroke</code>.
151 * @return a key sequence. Guaranteed not to be <code>null</code>.
152 */
153 public static final KeySequence getInstance(SeqView!(KeyStroke) keyStrokes) {
154 return new KeySequence(keyStrokes.toArray());
155 }
156
157 /**
158 * Creates an instance of <code>KeySequence</code> by parsing a given
159 * formal string representation.
160 *
161 * @param string
162 * the formal string representation to parse.
163 * @return a key sequence. Guaranteed not to be <code>null</code>.
164 * @throws ParseException
165 * if the given formal string representation could not be parsed
166 * to a valid key sequence.
167 */
168 public static final KeySequence getInstance(String string) {
169 if (string is null) {
170 throw new NullPointerException();
171 }
172
173 auto keyStrokes = new ArraySeq!(KeyStroke);
174
175 try {
176 auto tokens = tango.text.Util.delimit( string, KEY_STROKE_DELIMITERS );
177 KeyStroke[] keyStrokeArray = new KeyStroke[ tokens.length ];
178 foreach( idx, tok; tokens ){
179 keyStrokeArray[idx] = KeyStroke.getInstance(tok);
180 }
181 return new KeySequence(keyStrokeArray);
182 } catch (IllegalArgumentException e) {
183 throw new ParseException(
184 "Could not construct key sequence with these key strokes: " //$NON-NLS-1$
185 /+~ keyStrokes+/);
186 } catch (NullPointerException e) {
187 throw new ParseException(
188 "Could not construct key sequence with these key strokes: " //$NON-NLS-1$
189 /+~ keyStrokes+/);
190 }
191 }
192
193 /**
194 * Constructs an instance of <code>KeySequence</code> given a list of key
195 * strokes.
196 *
197 * @param keyStrokes
198 * the list of key strokes. This list may be empty, but it must
199 * not be <code>null</code>. If this list is not empty, it
200 * must only contain instances of <code>KeyStroke</code>.
201 */
202 protected this(KeyStroke[] keyStrokes) {
203 super(keyStrokes);
204
205 for (int i = 0; i < triggers.length - 1; i++) {
206 KeyStroke keyStroke = cast(KeyStroke) triggers[i];
207
208 if (!keyStroke.isComplete()) {
209 throw new IllegalArgumentException(null);
210 }
211 }
212 }
213
214 /*
215 * (non-Javadoc)
216 *
217 * @see java.lang.Object#compareTo(java.lang.Object)
218 */
219 public final int compareTo(Object object) {
220 KeySequence castedObject = cast(KeySequence) object;
221 return Util.compare( arraycast!(Comparable)(triggers), arraycast!(Comparable)(castedObject.triggers));
222 }
223
224 /**
225 * Formats this key sequence into the current default look.
226 *
227 * @return A string representation for this key sequence using the default
228 * look; never <code>null</code>.
229 */
230 public final String format() {
231 return KeyFormatterFactory.getDefault().format(this);
232 }
233
234 /**
235 * Returns the list of key strokes for this key sequence.
236 *
237 * @return the list of key strokes keys. This list may be empty, but is
238 * guaranteed not to be <code>null</code>. If this list is not
239 * empty, it is guaranteed to only contain instances of
240 * <code>KeyStroke</code>.
241 */
242 public final KeyStroke[] getKeyStrokes() {
243 int triggerLength = triggers.length;
244 KeyStroke[] keyStrokes = new KeyStroke[triggerLength];
245 System.arraycopy(triggers, 0, keyStrokes, 0, triggerLength);
246 return keyStrokes;
247 }
248
249 /*
250 * (non-Javadoc)
251 *
252 * @see dwtx.jface.bindings.TriggerSequence#getPrefixes()
253 */
254 public final TriggerSequence[] getPrefixes() {
255 int numberOfPrefixes = triggers.length;
256 TriggerSequence[] prefixes = new TriggerSequence[numberOfPrefixes];
257 prefixes[0] = KeySequence.getInstance();
258 for (int i = 0; i < numberOfPrefixes - 1; i++) {
259 final KeyStroke[] prefixKeyStrokes = new KeyStroke[i + 1];
260 System.arraycopy(triggers, 0, prefixKeyStrokes, 0, i + 1);
261 prefixes[i + 1] = KeySequence.getInstance(prefixKeyStrokes);
262 }
263
264 return prefixes;
265 }
266
267 /**
268 * Returns whether or not this key sequence is complete. Key sequences are
269 * complete iff all of their key strokes are complete.
270 *
271 * @return <code>true</code>, iff the key sequence is complete.
272 */
273 public final bool isComplete() {
274 int triggersLength = triggers.length;
275 for (int i = 0; i < triggersLength; i++) {
276 if (!(cast(KeyStroke) triggers[i]).isComplete()) {
277 return false;
278 }
279 }
280
281 return true;
282 }
283
284 /**
285 * Returns the formal string representation for this key sequence.
286 *
287 * @return The formal string representation for this key sequence.
288 * Guaranteed not to be <code>null</code>.
289 * @see java.lang.Object#toString()
290 */
291 public final String toString() {
292 return KeyFormatterFactory.getFormalKeyFormatter().format(this);
293 }
294 }