Mercurial > projects > dwt-addons
annotate dwtx/jface/action/CoolBarManager.d @ 192:c3583c6ec027
Added missing default cases for switch statements
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 22:52:26 +0100 |
parents | 04b47443bb01 |
children |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
90 | 2 * Copyright (c) 2003, 2008 IBM Corporation and others. |
25 | 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 module dwtx.jface.action.CoolBarManager; | |
14 | |
15 import dwtx.jface.action.ToolBarContributionItem; | |
16 import dwtx.jface.action.Separator; | |
17 | |
18 import dwtx.jface.action.ContributionManager; | |
19 import dwtx.jface.action.IContributionManager; | |
20 import dwtx.jface.action.IContributionItem; | |
21 import dwtx.jface.action.ICoolBarManager; | |
22 import dwtx.jface.action.IToolBarManager; | |
23 import dwtx.jface.action.IMenuManager; | |
24 import dwtx.jface.action.MenuManager; | |
25 | |
26 import dwt.DWT; | |
27 import dwt.widgets.Composite; | |
28 import dwt.widgets.Control; | |
29 import dwt.widgets.CoolBar; | |
30 import dwt.widgets.CoolItem; | |
31 import dwt.widgets.Menu; | |
32 import dwtx.core.runtime.Assert; | |
33 import dwtx.jface.util.Policy; | |
34 | |
35 import dwt.dwthelper.utils; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
36 import dwtx.dwtxhelper.Collection; |
25 | 37 import tango.io.Stdout; |
38 | |
39 /** | |
40 * A cool bar manager is a contribution manager which realizes itself and its | |
41 * items in a cool bar control. | |
42 * <p> | |
43 * This class may be instantiated; it may also be subclassed. | |
44 * </p> | |
45 * | |
46 * @since 3.0 | |
47 */ | |
48 public class CoolBarManager : ContributionManager, | |
49 ICoolBarManager { | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
40
diff
changeset
|
50 alias ContributionManager.add add; |
25 | 51 |
52 /** | |
53 * A separator created by the end user. | |
54 */ | |
55 public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$ | |
56 | |
57 /** | |
58 * The original creation order of the contribution items. | |
59 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
60 private ArrayList cbItemsCreationOrder; |
25 | 61 |
62 /** | |
63 * MenuManager for cool bar pop-up menu, or null if none. | |
64 */ | |
65 private MenuManager contextMenuManager = null; | |
66 | |
67 /** | |
68 * The cool bar control; <code>null</code> before creation and after | |
69 * disposal. | |
70 */ | |
71 private CoolBar coolBar = null; | |
72 | |
73 /** | |
74 * The cool bar items style; <code>DWT.NONE</code> by default. | |
75 */ | |
76 private int itemStyle = DWT.NONE; | |
77 | |
78 /** | |
79 * Creates a new cool bar manager with the default style. Equivalent to | |
80 * <code>CoolBarManager(DWT.NONE)</code>. | |
81 */ | |
82 public this() { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
83 cbItemsCreationOrder = new ArrayList(); |
25 | 84 // do nothing |
85 } | |
86 | |
87 /** | |
88 * Creates a cool bar manager for an existing cool bar control. This | |
89 * manager becomes responsible for the control, and will dispose of it when | |
90 * the manager is disposed. | |
91 * | |
92 * @param coolBar | |
93 * the cool bar control | |
94 */ | |
95 public this(CoolBar coolBar) { | |
96 this(); | |
97 Assert.isNotNull(coolBar); | |
98 this.coolBar = coolBar; | |
99 itemStyle = coolBar.getStyle(); | |
100 } | |
101 | |
102 /** | |
103 * Creates a cool bar manager with the given DWT style. Calling <code>createControl</code> | |
104 * will create the cool bar control. | |
105 * | |
106 * @param style | |
107 * the cool bar item style; see | |
108 * {@link dwt.widgets.CoolBar CoolBar}for for valid | |
109 * style bits | |
110 */ | |
111 public this(int style) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
112 cbItemsCreationOrder = new ArrayList(); |
25 | 113 itemStyle = style; |
114 } | |
115 | |
116 /* | |
117 * (non-Javadoc) | |
118 * | |
119 * @see dwtx.jface.action.ICoolBarManager#add(dwtx.jface.action.IToolBarManager) | |
120 */ | |
121 public void add(IToolBarManager toolBarManager) { | |
122 Assert.isNotNull(cast(Object)toolBarManager); | |
123 super.add(new ToolBarContributionItem(toolBarManager)); | |
124 } | |
125 | |
126 /** | |
127 * Collapses consecutive separators and removes a separator from the | |
128 * beginning and end of the list. | |
129 * | |
130 * @param contributionList | |
131 * the list of contributions; must not be <code>null</code>. | |
132 * @return The contribution list provided with extraneous separators | |
133 * removed; this value is never <code>null</code>, but may be | |
134 * empty. | |
135 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
136 private ArrayList adjustContributionList(ArrayList contributionList) { |
25 | 137 IContributionItem item; |
138 // Fist remove a separator if it is the first element of the list | |
139 if (contributionList.size() !is 0) { | |
140 item = cast(IContributionItem) contributionList.get(0); | |
141 if (item.isSeparator()) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
142 contributionList.remove(0); |
25 | 143 } |
144 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
145 auto iterator = contributionList.listIterator(); |
25 | 146 // collapse consecutive separators |
147 while (iterator.hasNext()) { | |
148 item = cast(IContributionItem) iterator.next(); | |
149 if (item.isSeparator()) { | |
150 while (iterator.hasNext()) { | |
151 item = cast(IContributionItem) iterator.next(); | |
152 if (item.isSeparator()) { | |
153 iterator.remove(); | |
154 } else { | |
155 break; | |
156 } | |
157 } | |
158 | |
159 } | |
160 } | |
161 // Now check last element to see if there is a separator | |
162 item = cast(IContributionItem) contributionList.get(contributionList | |
163 .size() - 1); | |
164 if (item.isSeparator()) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
165 contributionList.remove(contributionList.size() - 1); |
25 | 166 } |
167 } | |
168 return contributionList; | |
169 | |
170 } | |
171 | |
172 /* (non-Javadoc) | |
173 * @see dwtx.jface.action.ContributionManager#checkDuplication(dwtx.jface.action.IContributionItem) | |
174 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
40
diff
changeset
|
175 protected override bool allowItem(IContributionItem itemToAdd) { |
25 | 176 /* We will allow as many null entries as they like, though there should |
177 * be none. | |
178 */ | |
179 if (itemToAdd is null) { | |
180 return true; | |
181 } | |
182 | |
183 /* Null identifiers can be expected in generic contribution items. | |
184 */ | |
185 String firstId = itemToAdd.getId(); | |
186 if (firstId is null) { | |
187 return true; | |
188 } | |
189 | |
190 // Cycle through the current list looking for duplicates. | |
191 IContributionItem[] currentItems = getItems(); | |
192 for (int i = 0; i < currentItems.length; i++) { | |
193 IContributionItem currentItem = currentItems[i]; | |
194 | |
195 // We ignore null entries. | |
196 if (currentItem is null) { | |
197 continue; | |
198 } | |
199 | |
200 String secondId = currentItem.getId(); | |
201 if (firstId.equals(secondId)) { | |
202 if (Policy.TRACE_TOOLBAR) { | |
203 Stdout.formatln("Trying to add a duplicate item."); //$NON-NLS-1$ | |
204 ExceptionPrintStackTrace(new Exception(null), Stdout ); | |
205 Stdout.formatln("DONE --------------------------"); //$NON-NLS-1$ | |
206 } | |
207 return false; | |
208 } | |
209 } | |
210 | |
211 return true; | |
212 } | |
213 | |
214 /** | |
215 * Positions the list iterator to the end of all the separators. Calling | |
216 * <code>next()</code> the iterator should return the immediate object | |
217 * following the last separator. | |
218 * | |
219 * @param iterator | |
220 * the list iterator. | |
221 */ | |
222 private void collapseSeparators(ListIterator iterator) { | |
223 | |
224 while (iterator.hasNext()) { | |
225 IContributionItem item = cast(IContributionItem) iterator.next(); | |
226 if (!item.isSeparator()) { | |
227 iterator.previous(); | |
228 return; | |
229 } | |
230 } | |
231 } | |
232 | |
233 /** | |
234 * Returns whether the cool bar control has been created and not yet | |
235 * disposed. | |
236 * | |
237 * @return <code>true</code> if the control has been created and not yet | |
238 * disposed, <code>false</code> otherwise | |
239 */ | |
240 private bool coolBarExist() { | |
241 return coolBar !is null && !coolBar.isDisposed(); | |
242 } | |
243 | |
244 /** | |
245 * Creates and returns this manager's cool bar control. Does not create a | |
246 * new control if one already exists. | |
247 * | |
248 * @param parent | |
249 * the parent control | |
250 * @return the cool bar control | |
251 */ | |
252 public CoolBar createControl(Composite parent) { | |
253 Assert.isNotNull(parent); | |
254 if (!coolBarExist()) { | |
255 coolBar = new CoolBar(parent, itemStyle); | |
256 coolBar.setMenu(getContextMenuControl()); | |
257 coolBar.setLocked(false); | |
258 update(false); | |
259 } | |
260 return coolBar; | |
261 } | |
262 | |
263 /** | |
264 * Disposes of this cool bar manager and frees all allocated DWT resources. | |
265 * Notifies all contribution items of the dispose. Note that this method | |
266 * does not clean up references between this cool bar manager and its | |
267 * associated contribution items. Use <code>removeAll</code> for that | |
268 * purpose. | |
269 */ | |
270 public void dispose() { | |
271 if (coolBarExist()) { | |
272 coolBar.dispose(); | |
273 coolBar = null; | |
274 } | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
275 IContributionItem[] items = getItems(); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
276 for (int i = 0; i < items.length; i++) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
277 // Disposes of the contribution item. |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
278 // If Contribution Item is a toolbar then it will dispose of |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
279 // all the nested |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
280 // contribution items. |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
281 items[i].dispose(); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
282 } |
25 | 283 // If a context menu existed then dispose of it. |
284 if (contextMenuManager !is null) { | |
285 contextMenuManager.dispose(); | |
286 contextMenuManager = null; | |
287 } | |
288 | |
289 } | |
290 | |
291 /** | |
292 * Disposes the given cool item. | |
293 * | |
294 * @param item | |
295 * the cool item to dispose | |
296 */ | |
297 private void dispose(CoolItem item) { | |
298 if ((item !is null) && !item.isDisposed()) { | |
299 | |
300 item.setData(null); | |
301 Control control = item.getControl(); | |
302 // if the control is already disposed, setting the coolitem | |
303 // control to null will cause an DWT exception, workaround | |
304 // for 19630 | |
305 if ((control !is null) && !control.isDisposed()) { | |
306 item.setControl(null); | |
307 } | |
308 item.dispose(); | |
309 } | |
310 } | |
311 | |
312 /** | |
313 * Finds the cool item associated with the given contribution item. | |
314 * | |
315 * @param item | |
316 * the contribution item | |
317 * @return the associated cool item, or <code>null</code> if not found | |
318 */ | |
319 private CoolItem findCoolItem(IContributionItem item) { | |
320 CoolItem[] coolItems = (coolBar is null) ? null : coolBar.getItems(); | |
321 return findCoolItem(coolItems, item); | |
322 } | |
323 | |
324 private CoolItem findCoolItem(CoolItem[] items, IContributionItem item) { | |
325 if (items is null) { | |
326 return null; | |
327 } | |
328 | |
329 for (int i = 0; i < items.length; i++) { | |
330 CoolItem coolItem = items[i]; | |
331 IContributionItem data = cast(IContributionItem) coolItem.getData(); | |
332 if (data !is null && (cast(Object)data).opEquals(cast(Object)item)) { | |
333 return coolItem; | |
334 } | |
335 } | |
336 return null; | |
337 } | |
338 | |
339 /** | |
340 * Return a consistent set of wrap indices. The return value will always | |
341 * include at least one entry and the first entry will always be zero. | |
342 * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an | |
343 * index for the first row. | |
344 * | |
345 * @param wraps | |
346 * the wrap indicies from the cool bar widget | |
347 * @return the adjusted wrap indicies. | |
348 */ | |
349 private int[] getAdjustedWrapIndices(int[] wraps) { | |
350 int[] adjustedWrapIndices; | |
351 if (wraps.length is 0) { | |
352 adjustedWrapIndices = [ 0 ]; | |
353 } else { | |
354 if (wraps[0] !is 0) { | |
355 adjustedWrapIndices = new int[wraps.length + 1]; | |
356 adjustedWrapIndices[0] = 0; | |
357 for (int i = 0; i < wraps.length; i++) { | |
358 adjustedWrapIndices[i + 1] = wraps[i]; | |
359 } | |
360 } else { | |
361 adjustedWrapIndices = wraps; | |
362 } | |
363 } | |
364 return adjustedWrapIndices; | |
365 } | |
366 | |
367 /** | |
368 * Returns the control of the Menu Manager. If the menu manager does not | |
369 * have a control then one is created. | |
370 * | |
371 * @return menu control associated with manager, or null if none | |
372 */ | |
373 private Menu getContextMenuControl() { | |
374 if ((contextMenuManager !is null) && (coolBar !is null)) { | |
375 Menu menuWidget = contextMenuManager.getMenu(); | |
376 if ((menuWidget is null) || (menuWidget.isDisposed())) { | |
377 menuWidget = contextMenuManager.createContextMenu(coolBar); | |
378 } | |
379 return menuWidget; | |
380 } | |
381 return null; | |
382 } | |
383 | |
384 /* | |
385 * (non-Javadoc) | |
386 * | |
387 * @see dwtx.jface.action.ICoolBarManager#isLayoutLocked() | |
388 */ | |
389 public IMenuManager getContextMenuManager() { | |
390 return contextMenuManager; | |
391 } | |
392 | |
393 /** | |
394 * Returns the cool bar control for this manager. | |
395 * | |
396 * @return the cool bar control, or <code>null</code> if none | |
397 */ | |
398 public CoolBar getControl() { | |
399 return coolBar; | |
400 } | |
401 | |
402 /** | |
403 * Returns an array list of all the contribution items in the manager. | |
404 * | |
405 * @return an array list of contribution items. | |
406 */ | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
407 private ArrayList getItemList() { |
25 | 408 IContributionItem[] cbItems = getItems(); |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
409 ArrayList list = new ArrayList(cbItems.length); |
25 | 410 for (int i = 0; i < cbItems.length; i++) { |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
411 list.add( cast(Object) cbItems[i]); |
25 | 412 } |
413 return list; | |
414 } | |
415 | |
416 /* | |
417 * (non-Javadoc) | |
418 * | |
419 * @see dwtx.jface.action.ICoolBarManager#isLayoutLocked() | |
420 */ | |
421 public bool getLockLayout() { | |
422 if (!coolBarExist()) { | |
423 return false; | |
424 } | |
425 return coolBar.getLocked(); | |
426 } | |
427 | |
428 /** | |
429 * Returns the number of rows that should be displayed visually. | |
430 * | |
431 * @param items | |
432 * the array of contributin items | |
433 * @return the number of rows | |
434 */ | |
435 private int getNumRows(IContributionItem[] items) { | |
436 int numRows = 1; | |
437 bool separatorFound = false; | |
438 for (int i = 0; i < items.length; i++) { | |
439 if (items[i].isSeparator()) { | |
440 separatorFound = true; | |
441 } | |
442 if ((separatorFound) && (items[i].isVisible()) | |
443 && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) { | |
444 numRows++; | |
445 separatorFound = false; | |
446 } | |
447 } | |
448 return numRows; | |
449 } | |
450 | |
451 /* | |
452 * (non-Javadoc) | |
453 * | |
454 * @see dwtx.jface.action.ICoolBarManager#getStyle() | |
455 */ | |
456 public int getStyle() { | |
457 return itemStyle; | |
458 } | |
459 | |
460 /** | |
461 * Subclasses may extend this <code>ContributionManager</code> method, | |
462 * but must call <code>super.itemAdded</code>. | |
463 * | |
464 * @see dwtx.jface.action.ContributionManager#itemAdded(dwtx.jface.action.IContributionItem) | |
465 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
40
diff
changeset
|
466 protected override void itemAdded(IContributionItem item) { |
25 | 467 Assert.isNotNull(cast(Object)item); |
468 super.itemAdded(item); | |
469 int insertedAt = indexOf(item); | |
470 bool replaced = false; | |
471 final int size = cbItemsCreationOrder.size(); | |
472 for (int i = 0; i < size; i++) { | |
473 IContributionItem created = cast(IContributionItem) cbItemsCreationOrder | |
474 .get(i); | |
475 if (created.getId() !is null && created.getId().equals(item.getId())) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
476 cbItemsCreationOrder.set(i, cast(Object) item); |
25 | 477 replaced = true; |
478 break; | |
479 } | |
480 } | |
481 | |
482 if (!replaced) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
483 cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0), |
25 | 484 cbItemsCreationOrder.size()), cast(Object) item); |
485 } | |
486 } | |
487 | |
488 /** | |
489 * Subclasses may extend this <code>ContributionManager</code> method, | |
490 * but must call <code>super.itemRemoved</code>. | |
491 * | |
492 * @see dwtx.jface.action.ContributionManager#itemRemoved(dwtx.jface.action.IContributionItem) | |
493 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
40
diff
changeset
|
494 protected override void itemRemoved(IContributionItem item) { |
25 | 495 Assert.isNotNull(cast(Object)item); |
496 super.itemRemoved(item); | |
497 CoolItem coolItem = findCoolItem(item); | |
498 if (coolItem !is null) { | |
499 coolItem.setData(null); | |
500 } | |
501 } | |
502 | |
503 /** | |
504 * Positions the list iterator to the starting of the next row. By calling | |
505 * next on the returned iterator, it will return the first element of the | |
506 * next row. | |
507 * | |
508 * @param iterator | |
509 * the list iterator of contribution items | |
510 * @param ignoreCurrentItem | |
511 * Whether the current item in the iterator should be considered | |
512 * (as well as subsequent items). | |
513 */ | |
514 private void nextRow(ListIterator iterator, bool ignoreCurrentItem) { | |
515 | |
516 IContributionItem currentElement = null; | |
517 if (!ignoreCurrentItem && iterator.hasPrevious()) { | |
518 currentElement = cast(IContributionItem) iterator.previous(); | |
519 iterator.next(); | |
520 } | |
521 | |
522 if ((currentElement !is null) && (currentElement.isSeparator())) { | |
523 collapseSeparators(iterator); | |
524 return; | |
525 } | |
526 | |
527 //Find next separator | |
528 while (iterator.hasNext()) { | |
529 IContributionItem item = cast(IContributionItem) iterator.next(); | |
530 if (item.isSeparator()) { | |
531 // we we find a separator, collapse any consecutive | |
532 // separators | |
533 // and return | |
534 collapseSeparators(iterator); | |
535 return; | |
536 } | |
537 } | |
538 } | |
539 | |
540 /* | |
541 * Used for debuging. Prints all the items in the internal structures. | |
542 */ | |
543 // private void printContributions(ArrayList contributionList) { | |
544 // int index = 0; | |
545 // System.out.println("----------------------------------\n"); //$NON-NLS-1$ | |
546 // for (Iterator i = contributionList.iterator(); i.hasNext(); index++) { | |
547 // IContributionItem item = (IContributionItem) i.next(); | |
548 // if (item.isSeparator()) { | |
549 // System.out.println("Separator"); //$NON-NLS-1$ | |
550 // } else { | |
551 // System.out.println(index + ". Item id: " + item.getId() //$NON-NLS-1$ | |
552 // + " - is Visible: " //$NON-NLS-1$ | |
553 // + item.isVisible()); | |
554 // } | |
555 // } | |
556 // } | |
557 /** | |
558 * Synchronizes the visual order of the cool items in the control with this | |
559 * manager's internal data structures. This method should be called before | |
560 * requesting the order of the contribution items to ensure that the order | |
561 * is accurate. | |
562 * <p> | |
563 * Note that <code>update()</code> and <code>refresh()</code> are | |
564 * converses: <code>update()</code> changes the visual order to match the | |
565 * internal structures, and <code>refresh</code> changes the internal | |
566 * structures to match the visual order. | |
567 * </p> | |
568 */ | |
569 public void refresh() { | |
570 if (!coolBarExist()) { | |
571 return; | |
572 } | |
573 | |
574 // Retreives the list of contribution items as an array list | |
575 auto contributionList = getItemList(); | |
576 | |
577 // Check the size of the list | |
578 if (contributionList.size() is 0) { | |
579 return; | |
580 } | |
581 | |
582 // The list of all the cool items in their visual order | |
583 CoolItem[] coolItems = coolBar.getItems(); | |
584 // The wrap indicies of the coolbar | |
585 int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices()); | |
586 | |
587 int row = 0; | |
588 int coolItemIndex = 0; | |
589 | |
590 // Traverse through all cool items in the coolbar add them to a new | |
591 // data structure | |
592 // in the correct order | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
593 auto displayedItems = new ArrayList(coolBar.getItemCount()); |
25 | 594 for (int i = 0; i < coolItems.length; i++) { |
595 CoolItem coolItem = coolItems[i]; | |
596 if ( auto cbItem = cast(IContributionItem) coolItem.getData() ) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
597 displayedItems.add(Math.min(i, displayedItems.size()), cast(Object) cbItem); |
25 | 598 } |
599 } | |
600 | |
601 // Add separators to the displayed Items data structure | |
602 int offset = 0; | |
603 for (int i = 1; i < wrapIndicies.length; i++) { | |
604 int insertAt = wrapIndicies[i] + offset; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
605 displayedItems.add(insertAt, new Separator(USER_SEPARATOR)); |
25 | 606 offset++; |
607 } | |
608 | |
609 // Determine which rows are invisible | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
610 auto existingVisibleRows = new ArrayList(4); |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
611 ListIterator rowIterator = contributionList.listIterator(); |
25 | 612 collapseSeparators(rowIterator); |
613 int numRow = 0; | |
614 while (rowIterator.hasNext()) { | |
615 // Scan row | |
616 while (rowIterator.hasNext()) { | |
617 IContributionItem cbItem = cast(IContributionItem) rowIterator | |
618 .next(); | |
619 if (displayedItems.contains(cast(Object) cbItem)) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
620 existingVisibleRows.add(new Integer(numRow)); |
25 | 621 break; |
622 } | |
623 if (cbItem.isSeparator()) { | |
624 break; | |
625 } | |
626 } | |
627 nextRow(rowIterator, false); | |
628 numRow++; | |
629 } | |
630 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
631 auto existingRows = existingVisibleRows.iterator(); |
25 | 632 // Adjust row number to the first visible |
633 if (existingRows.hasNext()) { | |
634 row = (cast(Integer) existingRows.next()).intValue(); | |
635 } | |
636 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
637 auto itemLocation = new HashMap(); |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
638 for (ListIterator locationIterator = displayedItems.listIterator(); locationIterator |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
639 .hasNext();) { |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
640 IContributionItem item = cast(IContributionItem) locationIterator |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
641 .next(); |
25 | 642 if (item.isSeparator()) { |
643 if (existingRows.hasNext()) { | |
644 Integer value = cast(Integer) existingRows.next(); | |
645 row = value.intValue(); | |
646 } else { | |
647 row++; | |
648 } | |
649 } else { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
650 itemLocation.put(cast(Object)item, new Integer(row)); |
25 | 651 } |
652 | |
653 } | |
654 | |
655 // Insert the contribution items in their correct location | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
656 for (ListIterator iterator = displayedItems.listIterator(); iterator |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
657 .hasNext();) { |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
658 IContributionItem cbItem = cast(IContributionItem) iterator.next(); |
25 | 659 if (cbItem.isSeparator()) { |
660 coolItemIndex = 0; | |
661 } else { | |
662 relocate(cbItem, coolItemIndex, contributionList, itemLocation); | |
663 cbItem.saveWidgetState(); | |
664 coolItemIndex++; | |
665 } | |
666 } | |
667 | |
668 if (contributionList.size() !is 0) { | |
669 contributionList = adjustContributionList(contributionList); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
670 IContributionItem[] array = arraycast!(IContributionItem)( contributionList.toArray()); |
25 | 671 internalSetItems(array); |
672 } | |
673 | |
674 } | |
675 | |
676 /** | |
677 * Relocates the given contribution item to the specified index. | |
678 * | |
679 * @param cbItem | |
680 * the conribution item to relocate | |
681 * @param index | |
682 * the index to locate this item | |
683 * @param contributionList | |
684 * the current list of conrtributions | |
685 * @param itemLocation | |
686 */ | |
687 private void relocate(IContributionItem cbItem, int index, | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
688 ArrayList contributionList, HashMap itemLocation) { |
25 | 689 |
690 if (!(cast(Integer)itemLocation.get(cast(Object)cbItem) )) { | |
691 return; | |
692 } | |
693 int targetRow = (cast(Integer) itemLocation.get(cast(Object)cbItem)).intValue(); | |
694 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
695 int cbInternalIndex = contributionList.indexOf(cast(Object)cbItem); |
25 | 696 |
697 // by default add to end of list | |
698 int insertAt = contributionList.size(); | |
699 // Find the row to place this item in. | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
700 ListIterator iterator = contributionList.listIterator(); |
25 | 701 // bypass any separators at the begining |
702 collapseSeparators(iterator); | |
703 int currentRow = -1; | |
704 while (iterator.hasNext()) { | |
705 | |
706 currentRow++; | |
707 if (currentRow is targetRow) { | |
708 // We found the row to insert the item | |
709 int virtualIndex = 0; | |
710 insertAt = iterator.nextIndex(); | |
711 // first check the position of the current element (item) | |
712 // then get the next element | |
713 while (iterator.hasNext()) { | |
714 IContributionItem item = cast(IContributionItem) iterator | |
715 .next(); | |
716 Integer itemRow = cast(Integer) itemLocation.get( cast(Object) item); | |
717 if (item.isSeparator()) { | |
718 break; | |
719 } | |
720 // if the item has an associate widget | |
721 if ((itemRow !is null) && (itemRow.intValue() is targetRow)) { | |
722 // if the next element is the index we are looking for | |
723 // then break | |
724 if (virtualIndex >= index) { | |
725 break; | |
726 } | |
727 virtualIndex++; | |
728 | |
729 } | |
730 insertAt++; | |
731 } | |
732 // If we don't need to move it then we return | |
733 if (cbInternalIndex is insertAt) { | |
734 return; | |
735 } | |
736 break; | |
737 } | |
738 nextRow(iterator, true); | |
739 } | |
740 contributionList.remove(cast(Object) cbItem); | |
741 | |
742 // Adjust insertAt index | |
743 if (cbInternalIndex < insertAt) { | |
744 insertAt--; | |
745 } | |
746 | |
747 // if we didn't find the row then add a new row | |
748 if (currentRow !is targetRow) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
749 contributionList.add(new Separator(USER_SEPARATOR)); |
25 | 750 insertAt = contributionList.size(); |
751 } | |
752 insertAt = Math.min(insertAt, contributionList.size()); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
753 contributionList.add(insertAt, cast(Object) cbItem); |
25 | 754 |
755 } | |
756 | |
757 /** | |
758 * Restores the canonical order of this cool bar manager. The canonical | |
759 * order is the order in which the contribution items where added. | |
760 */ | |
761 public void resetItemOrder() { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
762 for (ListIterator iterator = cbItemsCreationOrder.listIterator(); iterator |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
763 .hasNext();) { |
25 | 764 IContributionItem item = cast(IContributionItem) iterator.next(); |
765 // if its a user separator then do not include in original order. | |
766 if ((item.getId() !is null) && (item.getId().equals(USER_SEPARATOR))) { | |
767 iterator.remove(); | |
768 } | |
769 } | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
770 IContributionItem[] itemsToSet = arraycast!(IContributionItem)(cbItemsCreationOrder.toArray()); |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
771 setItems(itemsToSet); |
25 | 772 } |
773 | |
774 /* | |
775 * (non-Javadoc) | |
776 * | |
777 * @see dwtx.jface.action.ICoolBarManager#setContextMenuManager(dwtx.jface.action.IMenuManager) | |
778 */ | |
779 public void setContextMenuManager(IMenuManager contextMenuManager) { | |
780 this.contextMenuManager = cast(MenuManager) contextMenuManager; | |
781 if (coolBar !is null) { | |
782 coolBar.setMenu(getContextMenuControl()); | |
783 } | |
784 } | |
785 | |
786 /** | |
787 * Replaces the current items with the given items. | |
788 * Forces an update. | |
789 * | |
790 * @param newItems the items with which to replace the current items | |
791 */ | |
792 public void setItems(IContributionItem[] newItems) { | |
793 // dispose of all the cool items on the cool bar manager | |
794 if (coolBar !is null) { | |
795 CoolItem[] coolItems = coolBar.getItems(); | |
796 for (int i = 0; i < coolItems.length; i++) { | |
797 dispose(coolItems[i]); | |
798 } | |
799 } | |
800 // Set the internal structure to this order | |
801 internalSetItems(newItems); | |
802 // Force and update | |
803 update(true); | |
804 } | |
805 | |
806 /* | |
807 * (non-Javadoc) | |
808 * | |
809 * @see dwtx.jface.action.ICoolBarManager#lockLayout(bool) | |
810 */ | |
811 public void setLockLayout(bool value) { | |
812 if (!coolBarExist()) { | |
813 return; | |
814 } | |
815 coolBar.setLocked(value); | |
816 } | |
817 | |
818 /** | |
819 * Subclasses may extend this <code>IContributionManager</code> method, | |
820 * but must call <code>super.update</code>. | |
821 * | |
822 * @see dwtx.jface.action.IContributionManager#update(bool) | |
823 */ | |
824 public void update(bool force) { | |
825 if ((!isDirty() && !force) || (!coolBarExist())) { | |
826 return; | |
827 } | |
828 | |
829 bool relock = false; | |
830 bool changed = false; | |
831 | |
832 try { | |
833 coolBar.setRedraw(false); | |
834 | |
835 // Refresh the widget data with the internal data structure. | |
836 refresh(); | |
837 | |
838 if (coolBar.getLocked()) { | |
839 coolBar.setLocked(false); | |
840 relock = true; | |
841 } | |
842 | |
843 /* | |
844 * Make a list of items including only those items that are | |
845 * visible. Separators should stay because they mark line breaks in | |
846 * a cool bar. | |
847 */ | |
848 IContributionItem[] items = getItems(); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
849 List visibleItems = new ArrayList(items.length); |
25 | 850 for (int i = 0; i < items.length; i++) { |
851 IContributionItem item = items[i]; | |
852 if (item.isVisible()) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
853 visibleItems.add(cast(Object)item); |
25 | 854 } |
855 } | |
856 | |
857 /* | |
858 * Make a list of CoolItem widgets in the cool bar for which there | |
859 * is no current visible contribution item. These are the widgets | |
860 * to be disposed. Dynamic items are also removed. | |
861 */ | |
862 CoolItem[] coolItems = coolBar.getItems(); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
863 ArrayList coolItemsToRemove = new ArrayList(coolItems.length); |
25 | 864 for (int i = 0; i < coolItems.length; i++) { |
865 Object data = coolItems[i].getData(); | |
866 if ((data is null) | |
867 || (!visibleItems.contains(data)) | |
868 || ((cast(IContributionItem)data ) && (cast(IContributionItem) data) | |
869 .isDynamic())) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
870 coolItemsToRemove.add(coolItems[i]); |
25 | 871 } |
872 } | |
873 | |
874 // Dispose of any items in the list to be removed. | |
875 for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) { | |
876 CoolItem coolItem = cast(CoolItem) coolItemsToRemove.get(i); | |
877 if (!coolItem.isDisposed()) { | |
878 Control control = coolItem.getControl(); | |
879 if (control !is null) { | |
880 coolItem.setControl(null); | |
881 control.dispose(); | |
882 } | |
883 coolItem.dispose(); | |
884 } | |
885 } | |
886 | |
887 // Add any new items by telling them to fill. | |
888 coolItems = coolBar.getItems(); | |
889 IContributionItem sourceItem; | |
890 IContributionItem destinationItem; | |
891 int sourceIndex = 0; | |
892 int destinationIndex = 0; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
893 Iterator visibleItemItr = visibleItems.iterator(); |
25 | 894 while (visibleItemItr.hasNext()) { |
895 sourceItem = cast(IContributionItem) visibleItemItr.next(); | |
896 | |
897 // Retrieve the corresponding contribution item from DWT's | |
898 // data. | |
899 if (sourceIndex < coolItems.length) { | |
900 destinationItem = cast(IContributionItem) coolItems[sourceIndex] | |
901 .getData(); | |
902 } else { | |
903 destinationItem = null; | |
904 } | |
905 | |
906 // The items match is they are equal or both separators. | |
907 if (destinationItem !is null) { | |
908 if ((cast(Object)sourceItem).opEquals(cast(Object)destinationItem)) { | |
909 sourceIndex++; | |
910 destinationIndex++; | |
911 sourceItem.update(); | |
912 continue; | |
913 | |
914 } else if ((destinationItem.isSeparator()) | |
915 && (sourceItem.isSeparator())) { | |
916 coolItems[sourceIndex].setData(cast(Object)sourceItem); | |
917 sourceIndex++; | |
918 destinationIndex++; | |
919 sourceItem.update(); | |
920 continue; | |
921 | |
922 } | |
923 } | |
924 | |
925 // Otherwise, a new item has to be added. | |
926 int start = coolBar.getItemCount(); | |
927 sourceItem.fill(coolBar, destinationIndex); | |
928 int newItems = coolBar.getItemCount() - start; | |
929 for (int i = 0; i < newItems; i++) { | |
930 coolBar.getItem(destinationIndex++).setData(cast(Object)sourceItem); | |
931 } | |
932 changed = true; | |
933 } | |
934 | |
935 // Remove any old widgets not accounted for. | |
936 for (int i = coolItems.length - 1; i >= sourceIndex; i--) { | |
937 final CoolItem item = coolItems[i]; | |
938 if (!item.isDisposed()) { | |
939 Control control = item.getControl(); | |
940 if (control !is null) { | |
941 item.setControl(null); | |
942 control.dispose(); | |
943 } | |
944 item.dispose(); | |
945 changed = true; | |
946 } | |
947 } | |
948 | |
949 // Update wrap indices. | |
950 updateWrapIndices(); | |
951 | |
952 // Update the sizes. | |
953 for (int i = 0; i < items.length; i++) { | |
954 IContributionItem item = items[i]; | |
955 item.update(SIZE); | |
956 } | |
957 | |
958 // if the coolBar was previously locked then lock it | |
959 if (relock) { | |
960 coolBar.setLocked(true); | |
961 } | |
962 | |
963 if (changed) { | |
964 updateTabOrder(); | |
965 } | |
966 | |
967 // We are no longer dirty. | |
968 setDirty(false); | |
969 } finally { | |
970 coolBar.setRedraw(true); | |
971 } | |
972 } | |
973 | |
974 /** | |
975 * Sets the tab order of the coolbar to the visual order of its items. | |
976 */ | |
977 /* package */void updateTabOrder() { | |
978 if (coolBar !is null) { | |
979 CoolItem[] items = coolBar.getItems(); | |
980 if (items !is null) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
981 ArrayList children = new ArrayList(items.length); |
25 | 982 for (int i = 0; i < items.length; i++) { |
983 if ((items[i].getControl() !is null) | |
984 && (!items[i].getControl().isDisposed())) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
985 children.add(items[i].getControl()); |
25 | 986 } |
987 } | |
988 // Convert array | |
989 Control[] childrenArray; | |
990 childrenArray = arraycast!(Control)(children.toArray()); | |
991 | |
992 if (childrenArray !is null) { | |
993 coolBar.setTabList(childrenArray); | |
994 } | |
995 | |
996 } | |
997 } | |
998 } | |
999 | |
1000 /** | |
1001 * Updates the indices at which the cool bar should wrap. | |
1002 */ | |
1003 private void updateWrapIndices() { | |
1004 final IContributionItem[] items = getItems(); | |
1005 final int numRows = getNumRows(items) - 1; | |
1006 | |
1007 // Generate the list of wrap indices. | |
1008 final int[] wrapIndices = new int[numRows]; | |
1009 bool foundSeparator = false; | |
1010 int j = 0; | |
1011 CoolItem[] coolItems = (coolBar is null) ? null : coolBar.getItems(); | |
1012 | |
1013 for (int i = 0; i < items.length; i++) { | |
1014 IContributionItem item = items[i]; | |
1015 CoolItem coolItem = findCoolItem(coolItems, item); | |
1016 if (item.isSeparator()) { | |
1017 foundSeparator = true; | |
1018 } | |
1019 if ((!item.isSeparator()) && (!item.isGroupMarker()) | |
1020 && (item.isVisible()) && (coolItem !is null) | |
1021 && (foundSeparator)) { | |
1022 wrapIndices[j] = coolBar.indexOf(coolItem); | |
1023 j++; | |
1024 foundSeparator = false; | |
1025 } | |
1026 } | |
1027 | |
1028 /* | |
1029 * Check to see if these new wrap indices are different than the old | |
1030 * ones. | |
1031 */ | |
1032 final int[] oldIndices = coolBar.getWrapIndices(); | |
1033 bool shouldUpdate = false; | |
1034 if (oldIndices.length is wrapIndices.length) { | |
1035 for (int i = 0; i < oldIndices.length; i++) { | |
1036 if (oldIndices[i] !is wrapIndices[i]) { | |
1037 shouldUpdate = true; | |
1038 break; | |
1039 } | |
1040 } | |
1041 } else { | |
1042 shouldUpdate = true; | |
1043 } | |
1044 | |
1045 if (shouldUpdate) { | |
1046 coolBar.setWrapIndices(wrapIndices); | |
1047 } | |
1048 } | |
1049 } |