KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > action > CoolBarManager


1 /*******************************************************************************
2  * Copyright (c) 2003, 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  *******************************************************************************/

11 package org.eclipse.jface.action;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.ListIterator JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.jface.util.Policy;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.CoolBar;
25 import org.eclipse.swt.widgets.CoolItem;
26 import org.eclipse.swt.widgets.Menu;
27
28 /**
29  * A cool bar manager is a contribution manager which realizes itself and its
30  * items in a cool bar control.
31  * <p>
32  * This class may be instantiated; it may also be subclassed.
33  * </p>
34  *
35  * @since 3.0
36  */

37 public class CoolBarManager extends ContributionManager implements
38         ICoolBarManager {
39
40     /**
41      * A separator created by the end user.
42      */

43     public final static String JavaDoc USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$
44

45     /**
46      * The original creation order of the contribution items.
47      */

48     private ArrayList JavaDoc cbItemsCreationOrder = new ArrayList JavaDoc();
49
50     /**
51      * MenuManager for cool bar pop-up menu, or null if none.
52      */

53     private MenuManager contextMenuManager = null;
54
55     /**
56      * The cool bar control; <code>null</code> before creation and after
57      * disposal.
58      */

59     private CoolBar coolBar = null;
60
61     /**
62      * The cool bar items style; <code>SWT.NONE</code> by default.
63      */

64     private int itemStyle = SWT.NONE;
65
66     /**
67      * Creates a new cool bar manager with the default style. Equivalent to
68      * <code>CoolBarManager(SWT.NONE)</code>.
69      */

70     public CoolBarManager() {
71         // do nothing
72
}
73
74     /**
75      * Creates a cool bar manager for an existing cool bar control. This
76      * manager becomes responsible for the control, and will dispose of it when
77      * the manager is disposed.
78      *
79      * @param coolBar
80      * the cool bar control
81      */

82     public CoolBarManager(CoolBar coolBar) {
83         this();
84         Assert.isNotNull(coolBar);
85         this.coolBar = coolBar;
86         itemStyle = coolBar.getStyle();
87     }
88
89     /**
90      * Creates a cool bar manager with the given SWT style. Calling <code>createControl</code>
91      * will create the cool bar control.
92      *
93      * @param style
94      * the cool bar item style; see
95      * {@link org.eclipse.swt.widgets.CoolBar CoolBar}for for valid
96      * style bits
97      */

98     public CoolBarManager(int style) {
99         itemStyle = style;
100     }
101
102     /*
103      * (non-Javadoc)
104      *
105      * @see org.eclipse.jface.action.ICoolBarManager#add(org.eclipse.jface.action.IToolBarManager)
106      */

107     public void add(IToolBarManager toolBarManager) {
108         Assert.isNotNull(toolBarManager);
109         super.add(new ToolBarContributionItem(toolBarManager));
110     }
111
112     /**
113      * Collapses consecutive separators and removes a separator from the
114      * beginning and end of the list.
115      *
116      * @param contributionList
117      * the list of contributions; must not be <code>null</code>.
118      * @return The contribution list provided with extraneous separators
119      * removed; this value is never <code>null</code>, but may be
120      * empty.
121      */

122     private ArrayList JavaDoc adjustContributionList(ArrayList JavaDoc contributionList) {
123         IContributionItem item;
124         // Fist remove a separator if it is the first element of the list
125
if (contributionList.size() != 0) {
126             item = (IContributionItem) contributionList.get(0);
127             if (item.isSeparator()) {
128                 contributionList.remove(0);
129             }
130
131             ListIterator JavaDoc iterator = contributionList.listIterator();
132             // collapse consecutive separators
133
while (iterator.hasNext()) {
134                 item = (IContributionItem) iterator.next();
135                 if (item.isSeparator()) {
136                     while (iterator.hasNext()) {
137                         item = (IContributionItem) iterator.next();
138                         if (item.isSeparator()) {
139                             iterator.remove();
140                         } else {
141                             break;
142                         }
143                     }
144
145                 }
146             }
147             // Now check last element to see if there is a separator
148
item = (IContributionItem) contributionList.get(contributionList
149                     .size() - 1);
150             if (item.isSeparator()) {
151                 contributionList.remove(contributionList.size() - 1);
152             }
153         }
154         return contributionList;
155
156     }
157
158     /* (non-Javadoc)
159      * @see org.eclipse.jface.action.ContributionManager#checkDuplication(org.eclipse.jface.action.IContributionItem)
160      */

161     protected boolean allowItem(IContributionItem itemToAdd) {
162         /* We will allow as many null entries as they like, though there should
163          * be none.
164          */

165         if (itemToAdd == null) {
166             return true;
167         }
168
169         /* Null identifiers can be expected in generic contribution items.
170          */

171         String JavaDoc firstId = itemToAdd.getId();
172         if (firstId == null) {
173             return true;
174         }
175
176         // Cycle through the current list looking for duplicates.
177
IContributionItem[] currentItems = getItems();
178         for (int i = 0; i < currentItems.length; i++) {
179             IContributionItem currentItem = currentItems[i];
180
181             // We ignore null entries.
182
if (currentItem == null) {
183                 continue;
184             }
185
186             String JavaDoc secondId = currentItem.getId();
187             if (firstId.equals(secondId)) {
188                 if (Policy.TRACE_TOOLBAR) {
189                     System.out.println("Trying to add a duplicate item."); //$NON-NLS-1$
190
new Exception JavaDoc().printStackTrace(System.out);
191                     System.out.println("DONE --------------------------"); //$NON-NLS-1$
192
}
193                 return false;
194             }
195         }
196
197         return true;
198     }
199
200     /**
201      * Positions the list iterator to the end of all the separators. Calling
202      * <code>next()</code> the iterator should return the immediate object
203      * following the last separator.
204      *
205      * @param iterator
206      * the list iterator.
207      */

208     private void collapseSeparators(ListIterator JavaDoc iterator) {
209
210         while (iterator.hasNext()) {
211             IContributionItem item = (IContributionItem) iterator.next();
212             if (!item.isSeparator()) {
213                 iterator.previous();
214                 return;
215             }
216         }
217     }
218
219     /**
220      * Returns whether the cool bar control has been created and not yet
221      * disposed.
222      *
223      * @return <code>true</code> if the control has been created and not yet
224      * disposed, <code>false</code> otherwise
225      */

226     private boolean coolBarExist() {
227         return coolBar != null && !coolBar.isDisposed();
228     }
229
230     /**
231      * Creates and returns this manager's cool bar control. Does not create a
232      * new control if one already exists.
233      *
234      * @param parent
235      * the parent control
236      * @return the cool bar control
237      */

238     public CoolBar createControl(Composite parent) {
239         Assert.isNotNull(parent);
240         if (!coolBarExist()) {
241             coolBar = new CoolBar(parent, itemStyle);
242             coolBar.setMenu(getContextMenuControl());
243             coolBar.setLocked(false);
244             update(false);
245         }
246         return coolBar;
247     }
248
249     /**
250      * Disposes of this cool bar manager and frees all allocated SWT resources.
251      * Notifies all contribution items of the dispose. Note that this method
252      * does not clean up references between this cool bar manager and its
253      * associated contribution items. Use <code>removeAll</code> for that
254      * purpose.
255      */

256     public void dispose() {
257         if (coolBarExist()) {
258             IContributionItem[] items = getItems();
259             for (int i = 0; i < items.length; i++) {
260                 // Disposes of the contribution item.
261
// If Contribution Item is a toolbar then it will dispose of
262
// all the nested
263
// contribution items.
264
items[i].dispose();
265             }
266             coolBar.dispose();
267             coolBar = null;
268         }
269         // If a context menu existed then dispose of it.
270
if (contextMenuManager != null) {
271             contextMenuManager.dispose();
272             contextMenuManager = null;
273         }
274
275     }
276
277     /**
278      * Disposes the given cool item.
279      *
280      * @param item
281      * the cool item to dispose
282      */

283     private void dispose(CoolItem item) {
284         if ((item != null) && !item.isDisposed()) {
285
286             item.setData(null);
287             Control control = item.getControl();
288             // if the control is already disposed, setting the coolitem
289
// control to null will cause an SWT exception, workaround
290
// for 19630
291
if ((control != null) && !control.isDisposed()) {
292                 item.setControl(null);
293             }
294             item.dispose();
295         }
296     }
297
298     /**
299      * Finds the cool item associated with the given contribution item.
300      *
301      * @param item
302      * the contribution item
303      * @return the associated cool item, or <code>null</code> if not found
304      */

305     private CoolItem findCoolItem(IContributionItem item) {
306         CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems();
307         return findCoolItem(coolItems, item);
308     }
309     
310     private CoolItem findCoolItem(CoolItem[] items, IContributionItem item) {
311         if (items == null) {
312             return null;
313         }
314
315         for (int i = 0; i < items.length; i++) {
316             CoolItem coolItem = items[i];
317             IContributionItem data = (IContributionItem) coolItem.getData();
318             if (data != null && data.equals(item)) {
319                 return coolItem;
320             }
321         }
322         return null;
323     }
324
325     /**
326      * Return a consistent set of wrap indices. The return value will always
327      * include at least one entry and the first entry will always be zero.
328      * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
329      * index for the first row.
330      *
331      * @param wraps
332      * the wrap indicies from the cool bar widget
333      * @return the adjusted wrap indicies.
334      */

335     private int[] getAdjustedWrapIndices(int[] wraps) {
336         int[] adjustedWrapIndices;
337         if (wraps.length == 0) {
338             adjustedWrapIndices = new int[] { 0 };
339         } else {
340             if (wraps[0] != 0) {
341                 adjustedWrapIndices = new int[wraps.length + 1];
342                 adjustedWrapIndices[0] = 0;
343                 for (int i = 0; i < wraps.length; i++) {
344                     adjustedWrapIndices[i + 1] = wraps[i];
345                 }
346             } else {
347                 adjustedWrapIndices = wraps;
348             }
349         }
350         return adjustedWrapIndices;
351     }
352
353     /**
354      * Returns the control of the Menu Manager. If the menu manager does not
355      * have a control then one is created.
356      *
357      * @return menu control associated with manager, or null if none
358      */

359     private Menu getContextMenuControl() {
360         if ((contextMenuManager != null) && (coolBar != null)) {
361             Menu menuWidget = contextMenuManager.getMenu();
362             if ((menuWidget == null) || (menuWidget.isDisposed())) {
363                 menuWidget = contextMenuManager.createContextMenu(coolBar);
364             }
365             return menuWidget;
366         }
367         return null;
368     }
369
370     /*
371      * (non-Javadoc)
372      *
373      * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
374      */

375     public IMenuManager getContextMenuManager() {
376         return contextMenuManager;
377     }
378
379     /**
380      * Returns the cool bar control for this manager.
381      *
382      * @return the cool bar control, or <code>null</code> if none
383      */

384     public CoolBar getControl() {
385         return coolBar;
386     }
387
388     /**
389      * Returns an array list of all the contribution items in the manager.
390      *
391      * @return an array list of contribution items.
392      */

393     private ArrayList JavaDoc getItemList() {
394         IContributionItem[] cbItems = getItems();
395         ArrayList JavaDoc list = new ArrayList JavaDoc(cbItems.length);
396         for (int i = 0; i < cbItems.length; i++) {
397             list.add(cbItems[i]);
398         }
399         return list;
400     }
401
402     /*
403      * (non-Javadoc)
404      *
405      * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
406      */

407     public boolean getLockLayout() {
408         if (!coolBarExist()) {
409             return false;
410         }
411         return coolBar.getLocked();
412     }
413
414     /**
415      * Returns the number of rows that should be displayed visually.
416      *
417      * @param items
418      * the array of contributin items
419      * @return the number of rows
420      */

421     private int getNumRows(IContributionItem[] items) {
422         int numRows = 1;
423         boolean separatorFound = false;
424         for (int i = 0; i < items.length; i++) {
425             if (items[i].isSeparator()) {
426                 separatorFound = true;
427             }
428             if ((separatorFound) && (items[i].isVisible())
429                     && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) {
430                 numRows++;
431                 separatorFound = false;
432             }
433         }
434         return numRows;
435     }
436
437     /*
438      * (non-Javadoc)
439      *
440      * @see org.eclipse.jface.action.ICoolBarManager#getStyle()
441      */

442     public int getStyle() {
443         return itemStyle;
444     }
445
446     /**
447      * Subclasses may extend this <code>ContributionManager</code> method,
448      * but must call <code>super.itemAdded</code>.
449      *
450      * @see org.eclipse.jface.action.ContributionManager#itemAdded(org.eclipse.jface.action.IContributionItem)
451      */

452     protected void itemAdded(IContributionItem item) {
453         Assert.isNotNull(item);
454         super.itemAdded(item);
455         int insertedAt = indexOf(item);
456         boolean replaced = false;
457         final int size = cbItemsCreationOrder.size();
458         for (int i = 0; i < size; i++) {
459             IContributionItem created = (IContributionItem) cbItemsCreationOrder
460                     .get(i);
461             if (created.getId() != null && created.getId().equals(item.getId())) {
462                 cbItemsCreationOrder.set(i, item);
463                 replaced = true;
464                 break;
465             }
466         }
467
468         if (!replaced) {
469             cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0),
470                     cbItemsCreationOrder.size()), item);
471         }
472     }
473
474     /**
475      * Subclasses may extend this <code>ContributionManager</code> method,
476      * but must call <code>super.itemRemoved</code>.
477      *
478      * @see org.eclipse.jface.action.ContributionManager#itemRemoved(org.eclipse.jface.action.IContributionItem)
479      */

480     protected void itemRemoved(IContributionItem item) {
481         Assert.isNotNull(item);
482         super.itemRemoved(item);
483         CoolItem coolItem = findCoolItem(item);
484         if (coolItem != null) {
485             coolItem.setData(null);
486         }
487     }
488
489     /**
490      * Positions the list iterator to the starting of the next row. By calling
491      * next on the returned iterator, it will return the first element of the
492      * next row.
493      *
494      * @param iterator
495      * the list iterator of contribution items
496      * @param ignoreCurrentItem
497      * Whether the current item in the iterator should be considered
498      * (as well as subsequent items).
499      */

500     private void nextRow(ListIterator JavaDoc iterator, boolean ignoreCurrentItem) {
501
502         IContributionItem currentElement = null;
503         if (!ignoreCurrentItem && iterator.hasPrevious()) {
504             currentElement = (IContributionItem) iterator.previous();
505             iterator.next();
506         }
507
508         if ((currentElement != null) && (currentElement.isSeparator())) {
509             collapseSeparators(iterator);
510             return;
511         }
512
513         //Find next separator
514
while (iterator.hasNext()) {
515             IContributionItem item = (IContributionItem) iterator.next();
516             if (item.isSeparator()) {
517                 // we we find a separator, collapse any consecutive
518
// separators
519
// and return
520
collapseSeparators(iterator);
521                 return;
522             }
523         }
524     }
525
526     /*
527      * Used for debuging. Prints all the items in the internal structures.
528      */

529     // private void printContributions(ArrayList contributionList) {
530
// int index = 0;
531
// System.out.println("----------------------------------\n"); //$NON-NLS-1$
532
// for (Iterator i = contributionList.iterator(); i.hasNext(); index++) {
533
// IContributionItem item = (IContributionItem) i.next();
534
// if (item.isSeparator()) {
535
// System.out.println("Separator"); //$NON-NLS-1$
536
// } else {
537
// System.out.println(index + ". Item id: " + item.getId() //$NON-NLS-1$
538
// + " - is Visible: " //$NON-NLS-1$
539
// + item.isVisible());
540
// }
541
// }
542
// }
543
/**
544      * Synchronizes the visual order of the cool items in the control with this
545      * manager's internal data structures. This method should be called before
546      * requesting the order of the contribution items to ensure that the order
547      * is accurate.
548      * <p>
549      * Note that <code>update()</code> and <code>refresh()</code> are
550      * converses: <code>update()</code> changes the visual order to match the
551      * internal structures, and <code>refresh</code> changes the internal
552      * structures to match the visual order.
553      * </p>
554      */

555     public void refresh() {
556         if (!coolBarExist()) {
557             return;
558         }
559
560         // Retreives the list of contribution items as an array list
561
ArrayList JavaDoc contributionList = getItemList();
562
563         // Check the size of the list
564
if (contributionList.size() == 0) {
565             return;
566         }
567
568         // The list of all the cool items in their visual order
569
CoolItem[] coolItems = coolBar.getItems();
570         // The wrap indicies of the coolbar
571
int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
572
573         int row = 0;
574         int coolItemIndex = 0;
575
576         // Traverse through all cool items in the coolbar add them to a new
577
// data structure
578
// in the correct order
579
ArrayList JavaDoc displayedItems = new ArrayList JavaDoc(coolBar.getItemCount());
580         for (int i = 0; i < coolItems.length; i++) {
581             CoolItem coolItem = coolItems[i];
582             if (coolItem.getData() instanceof IContributionItem) {
583                 IContributionItem cbItem = (IContributionItem) coolItem
584                         .getData();
585                 displayedItems.add(Math.min(i, displayedItems.size()), cbItem);
586             }
587         }
588
589         // Add separators to the displayed Items data structure
590
int offset = 0;
591         for (int i = 1; i < wrapIndicies.length; i++) {
592             int insertAt = wrapIndicies[i] + offset;
593             displayedItems.add(insertAt, new Separator(USER_SEPARATOR));
594             offset++;
595         }
596
597         // Determine which rows are invisible
598
ArrayList JavaDoc existingVisibleRows = new ArrayList JavaDoc(4);
599         ListIterator JavaDoc rowIterator = contributionList.listIterator();
600         collapseSeparators(rowIterator);
601         int numRow = 0;
602         while (rowIterator.hasNext()) {
603             // Scan row
604
while (rowIterator.hasNext()) {
605                 IContributionItem cbItem = (IContributionItem) rowIterator
606                         .next();
607                 if (displayedItems.contains(cbItem)) {
608                     existingVisibleRows.add(new Integer JavaDoc(numRow));
609                     break;
610                 }
611                 if (cbItem.isSeparator()) {
612                     break;
613                 }
614             }
615             nextRow(rowIterator, false);
616             numRow++;
617         }
618
619         Iterator JavaDoc existingRows = existingVisibleRows.iterator();
620         // Adjust row number to the first visible
621
if (existingRows.hasNext()) {
622             row = ((Integer JavaDoc) existingRows.next()).intValue();
623         }
624
625         HashMap JavaDoc itemLocation = new HashMap JavaDoc();
626         for (ListIterator JavaDoc locationIterator = displayedItems.listIterator(); locationIterator
627                 .hasNext();) {
628             IContributionItem item = (IContributionItem) locationIterator
629                     .next();
630             if (item.isSeparator()) {
631                 if (existingRows.hasNext()) {
632                     Integer JavaDoc value = (Integer JavaDoc) existingRows.next();
633                     row = value.intValue();
634                 } else {
635                     row++;
636                 }
637             } else {
638                 itemLocation.put(item, new Integer JavaDoc(row));
639             }
640
641         }
642
643         // Insert the contribution items in their correct location
644
for (ListIterator JavaDoc iterator = displayedItems.listIterator(); iterator
645                 .hasNext();) {
646             IContributionItem cbItem = (IContributionItem) iterator.next();
647             if (cbItem.isSeparator()) {
648                 coolItemIndex = 0;
649             } else {
650                 relocate(cbItem, coolItemIndex, contributionList, itemLocation);
651                 cbItem.saveWidgetState();
652                 coolItemIndex++;
653             }
654         }
655
656         if (contributionList.size() != 0) {
657             contributionList = adjustContributionList(contributionList);
658             IContributionItem[] array = new IContributionItem[contributionList
659                     .size() - 1];
660             array = (IContributionItem[]) contributionList.toArray(array);
661             internalSetItems(array);
662         }
663
664     }
665
666     /**
667      * Relocates the given contribution item to the specified index.
668      *
669      * @param cbItem
670      * the conribution item to relocate
671      * @param index
672      * the index to locate this item
673      * @param contributionList
674      * the current list of conrtributions
675      * @param itemLocation
676      */

677     private void relocate(IContributionItem cbItem, int index,
678             ArrayList JavaDoc contributionList, HashMap JavaDoc itemLocation) {
679
680         if (!(itemLocation.get(cbItem) instanceof Integer JavaDoc)) {
681             return;
682         }
683         int targetRow = ((Integer JavaDoc) itemLocation.get(cbItem)).intValue();
684
685         int cbInternalIndex = contributionList.indexOf(cbItem);
686
687         // by default add to end of list
688
int insertAt = contributionList.size();
689         // Find the row to place this item in.
690
ListIterator JavaDoc iterator = contributionList.listIterator();
691         // bypass any separators at the begining
692
collapseSeparators(iterator);
693         int currentRow = -1;
694         while (iterator.hasNext()) {
695
696             currentRow++;
697             if (currentRow == targetRow) {
698                 // We found the row to insert the item
699
int virtualIndex = 0;
700                 insertAt = iterator.nextIndex();
701                 // first check the position of the current element (item)
702
// then get the next element
703
while (iterator.hasNext()) {
704                     IContributionItem item = (IContributionItem) iterator
705                             .next();
706                     Integer JavaDoc itemRow = (Integer JavaDoc) itemLocation.get(item);
707                     if (item.isSeparator()) {
708                         break;
709                     }
710                     // if the item has an associate widget
711
if ((itemRow != null) && (itemRow.intValue() == targetRow)) {
712                         // if the next element is the index we are looking for
713
// then break
714
if (virtualIndex >= index) {
715                             break;
716                         }
717                         virtualIndex++;
718
719                     }
720                     insertAt++;
721                 }
722                 // If we don't need to move it then we return
723
if (cbInternalIndex == insertAt) {
724                     return;
725                 }
726                 break;
727             }
728             nextRow(iterator, true);
729         }
730         contributionList.remove(cbItem);
731
732         // Adjust insertAt index
733
if (cbInternalIndex < insertAt) {
734             insertAt--;
735         }
736
737         // if we didn't find the row then add a new row
738
if (currentRow != targetRow) {
739             contributionList.add(new Separator(USER_SEPARATOR));
740             insertAt = contributionList.size();
741         }
742         insertAt = Math.min(insertAt, contributionList.size());
743         contributionList.add(insertAt, cbItem);
744
745     }
746
747     /**
748      * Restores the canonical order of this cool bar manager. The canonical
749      * order is the order in which the contribution items where added.
750      */

751     public void resetItemOrder() {
752         for (ListIterator JavaDoc iterator = cbItemsCreationOrder.listIterator(); iterator
753                 .hasNext();) {
754             IContributionItem item = (IContributionItem) iterator.next();
755             // if its a user separator then do not include in original order.
756
if ((item.getId() != null) && (item.getId().equals(USER_SEPARATOR))) {
757                 iterator.remove();
758             }
759         }
760         IContributionItem[] itemsToSet = new IContributionItem[cbItemsCreationOrder
761                 .size()];
762         cbItemsCreationOrder.toArray(itemsToSet);
763         setItems(itemsToSet);
764     }
765
766     /*
767      * (non-Javadoc)
768      *
769      * @see org.eclipse.jface.action.ICoolBarManager#setContextMenuManager(org.eclipse.jface.action.IMenuManager)
770      */

771     public void setContextMenuManager(IMenuManager contextMenuManager) {
772         this.contextMenuManager = (MenuManager) contextMenuManager;
773         if (coolBar != null) {
774             coolBar.setMenu(getContextMenuControl());
775         }
776     }
777
778     /**
779      * Replaces the current items with the given items.
780      * Forces an update.
781      *
782      * @param newItems the items with which to replace the current items
783      */

784     public void setItems(IContributionItem[] newItems) {
785         // dispose of all the cool items on the cool bar manager
786
if (coolBar != null) {
787             CoolItem[] coolItems = coolBar.getItems();
788             for (int i = 0; i < coolItems.length; i++) {
789                 dispose(coolItems[i]);
790             }
791         }
792         // Set the internal structure to this order
793
internalSetItems(newItems);
794         // Force and update
795
update(true);
796     }
797
798     /*
799      * (non-Javadoc)
800      *
801      * @see org.eclipse.jface.action.ICoolBarManager#lockLayout(boolean)
802      */

803     public void setLockLayout(boolean value) {
804         if (!coolBarExist()) {
805             return;
806         }
807         coolBar.setLocked(value);
808     }
809
810     /**
811      * Subclasses may extend this <code>IContributionManager</code> method,
812      * but must call <code>super.update</code>.
813      *
814      * @see org.eclipse.jface.action.IContributionManager#update(boolean)
815      */

816     public void update(boolean force) {
817         if ((!isDirty() && !force) || (!coolBarExist())) {
818             return;
819         }
820
821         boolean relock = false;
822         boolean changed = false;
823
824         try {
825             coolBar.setRedraw(false);
826
827             // Refresh the widget data with the internal data structure.
828
refresh();
829
830             if (coolBar.getLocked()) {
831                 coolBar.setLocked(false);
832                 relock = true;
833             }
834
835             /*
836              * Make a list of items including only those items that are
837              * visible. Separators should stay because they mark line breaks in
838              * a cool bar.
839              */

840             final IContributionItem[] items = getItems();
841             final List JavaDoc visibleItems = new ArrayList JavaDoc(items.length);
842             for (int i = 0; i < items.length; i++) {
843                 final IContributionItem item = items[i];
844                 if (item.isVisible()) {
845                     visibleItems.add(item);
846                 }
847             }
848
849             /*
850              * Make a list of CoolItem widgets in the cool bar for which there
851              * is no current visible contribution item. These are the widgets
852              * to be disposed. Dynamic items are also removed.
853              */

854             CoolItem[] coolItems = coolBar.getItems();
855             final ArrayList JavaDoc coolItemsToRemove = new ArrayList JavaDoc(coolItems.length);
856             for (int i = 0; i < coolItems.length; i++) {
857                 final Object JavaDoc data = coolItems[i].getData();
858                 if ((data == null)
859                         || (!visibleItems.contains(data))
860                         || ((data instanceof IContributionItem) && ((IContributionItem) data)
861                                 .isDynamic())) {
862                     coolItemsToRemove.add(coolItems[i]);
863                 }
864             }
865
866             // Dispose of any items in the list to be removed.
867
for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) {
868                 CoolItem coolItem = (CoolItem) coolItemsToRemove.get(i);
869                 if (!coolItem.isDisposed()) {
870                     Control control = coolItem.getControl();
871                     if (control != null) {
872                         coolItem.setControl(null);
873                         control.dispose();
874                     }
875                     coolItem.dispose();
876                 }
877             }
878
879             // Add any new items by telling them to fill.
880
coolItems = coolBar.getItems();
881             IContributionItem sourceItem;
882             IContributionItem destinationItem;
883             int sourceIndex = 0;
884             int destinationIndex = 0;
885             final Iterator JavaDoc visibleItemItr = visibleItems.iterator();
886             while (visibleItemItr.hasNext()) {
887                 sourceItem = (IContributionItem) visibleItemItr.next();
888
889                 // Retrieve the corresponding contribution item from SWT's
890
// data.
891
if (sourceIndex < coolItems.length) {
892                     destinationItem = (IContributionItem) coolItems[sourceIndex]
893                             .getData();
894                 } else {
895                     destinationItem = null;
896                 }
897
898                 // The items match is they are equal or both separators.
899
if (destinationItem != null) {
900                     if (sourceItem.equals(destinationItem)) {
901                         sourceIndex++;
902                         destinationIndex++;
903                         sourceItem.update();
904                         continue;
905
906                     } else if ((destinationItem.isSeparator())
907                             && (sourceItem.isSeparator())) {
908                         coolItems[sourceIndex].setData(sourceItem);
909                         sourceIndex++;
910                         destinationIndex++;
911                         sourceItem.update();
912                         continue;
913
914                     }
915                 }
916
917                 // Otherwise, a new item has to be added.
918
final int start = coolBar.getItemCount();
919                 sourceItem.fill(coolBar, destinationIndex);
920                 final int newItems = coolBar.getItemCount() - start;
921                 for (int i = 0; i < newItems; i++) {
922                     coolBar.getItem(destinationIndex++).setData(sourceItem);
923                 }
924                 changed = true;
925             }
926
927             // Remove any old widgets not accounted for.
928
for (int i = coolItems.length - 1; i >= sourceIndex; i--) {
929                 final CoolItem item = coolItems[i];
930                 if (!item.isDisposed()) {
931                     Control control = item.getControl();
932                     if (control != null) {
933                         item.setControl(null);
934                         control.dispose();
935                     }
936                     item.dispose();
937                     changed = true;
938                 }
939             }
940
941             // Update wrap indices.
942
updateWrapIndices();
943
944             // Update the sizes.
945
for (int i = 0; i < items.length; i++) {
946                 IContributionItem item = items[i];
947                 item.update(SIZE);
948             }
949
950             // if the coolBar was previously locked then lock it
951
if (relock) {
952                 coolBar.setLocked(true);
953             }
954
955             if (changed) {
956                 updateTabOrder();
957             }
958
959             // We are no longer dirty.
960
setDirty(false);
961         } finally {
962             coolBar.setRedraw(true);
963         }
964     }
965
966     /**
967      * Sets the tab order of the coolbar to the visual order of its items.
968      */

969     /* package */void updateTabOrder() {
970         if (coolBar != null) {
971             CoolItem[] items = coolBar.getItems();
972             if (items != null) {
973                 ArrayList JavaDoc children = new ArrayList JavaDoc(items.length);
974                 for (int i = 0; i < items.length; i++) {
975                     if ((items[i].getControl() != null)
976                             && (!items[i].getControl().isDisposed())) {
977                         children.add(items[i].getControl());
978                     }
979                 }
980                 // Convert array
981
Control[] childrenArray = new Control[0];
982                 childrenArray = (Control[]) children.toArray(childrenArray);
983
984                 if (childrenArray != null) {
985                     coolBar.setTabList(childrenArray);
986                 }
987
988             }
989         }
990     }
991
992     /**
993      * Updates the indices at which the cool bar should wrap.
994      */

995     private void updateWrapIndices() {
996         final IContributionItem[] items = getItems();
997         final int numRows = getNumRows(items) - 1;
998
999         // Generate the list of wrap indices.
1000
final int[] wrapIndices = new int[numRows];
1001        boolean foundSeparator = false;
1002        int j = 0;
1003        CoolItem[] coolItems = (coolBar == null) ? null : coolBar.getItems();
1004
1005        for (int i = 0; i < items.length; i++) {
1006            IContributionItem item = items[i];
1007            CoolItem coolItem = findCoolItem(coolItems, item);
1008            if (item.isSeparator()) {
1009                foundSeparator = true;
1010            }
1011            if ((!item.isSeparator()) && (!item.isGroupMarker())
1012                    && (item.isVisible()) && (coolItem != null)
1013                    && (foundSeparator)) {
1014                wrapIndices[j] = coolBar.indexOf(coolItem);
1015                j++;
1016                foundSeparator = false;
1017            }
1018        }
1019
1020        /*
1021         * Check to see if these new wrap indices are different than the old
1022         * ones.
1023         */

1024        final int[] oldIndices = coolBar.getWrapIndices();
1025        boolean shouldUpdate = false;
1026        if (oldIndices.length == wrapIndices.length) {
1027            for (int i = 0; i < oldIndices.length; i++) {
1028                if (oldIndices[i] != wrapIndices[i]) {
1029                    shouldUpdate = true;
1030                    break;
1031                }
1032            }
1033        } else {
1034            shouldUpdate = true;
1035        }
1036
1037        if (shouldUpdate) {
1038            coolBar.setWrapIndices(wrapIndices);
1039        }
1040    }
1041}
1042
Popular Tags