KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.jface.util.Policy;
18
19 /**
20  * Abstract base class for all contribution managers, and standard
21  * implementation of <code>IContributionManager</code>. This class provides
22  * functionality common across the specific managers defined by this framework.
23  * <p>
24  * This class maintains a list of contribution items and a dirty flag, both as
25  * internal state. In addition to providing implementations of most
26  * <code>IContributionManager</code> methods, this class automatically
27  * coalesces adjacent separators, hides beginning and ending separators, and
28  * deals with dynamically changing sets of contributions. When the set of
29  * contributions does change dynamically, the changes are propagated to the
30  * control via the <code>update</code> method, which subclasses must
31  * implement.
32  * </p>
33  * <p>
34  * Note: A <code>ContributionItem</code> cannot be shared between different
35  * <code>ContributionManager</code>s.
36  * </p>
37  */

38 public abstract class ContributionManager implements IContributionManager {
39
40     // Internal debug flag.
41
// protected static final boolean DEBUG = false;
42

43     /**
44      * The list of contribution items.
45      */

46     private List JavaDoc contributions = new ArrayList JavaDoc();
47
48     /**
49      * Indicates whether the widgets are in sync with the contributions.
50      */

51     private boolean isDirty = true;
52
53     /**
54      * Number of dynamic contribution items.
55      */

56     private int dynamicItems = 0;
57
58     /**
59      * The overrides for items of this manager
60      */

61     private IContributionManagerOverrides overrides;
62
63     /**
64      * Creates a new contribution manager.
65      */

66     protected ContributionManager() {
67         // Do nothing.
68
}
69
70     /*
71      * (non-Javadoc) Method declared on IContributionManager.
72      */

73     public void add(IAction action) {
74         add(new ActionContributionItem(action));
75     }
76
77     /*
78      * (non-Javadoc) Method declared on IContributionManager.
79      */

80     public void add(IContributionItem item) {
81         if (allowItem(item)) {
82             contributions.add(item);
83             itemAdded(item);
84         }
85     }
86
87     /**
88      * Adds a contribution item to the start or end of the group with the given
89      * name.
90      *
91      * @param groupName
92      * the name of the group
93      * @param item
94      * the contribution item
95      * @param append
96      * <code>true</code> to add to the end of the group, and
97      * <code>false</code> to add the beginning of the group
98      * @exception IllegalArgumentException
99      * if there is no group with the given name
100      */

101     private void addToGroup(String JavaDoc groupName, IContributionItem item,
102             boolean append) {
103         int i;
104         Iterator JavaDoc items = contributions.iterator();
105         for (i = 0; items.hasNext(); i++) {
106             IContributionItem o = (IContributionItem) items.next();
107             if (o.isGroupMarker()) {
108                 String JavaDoc id = o.getId();
109                 if (id != null && id.equalsIgnoreCase(groupName)) {
110                     i++;
111                     if (append) {
112                         for (; items.hasNext(); i++) {
113                             IContributionItem ci = (IContributionItem) items
114                                     .next();
115                             if (ci.isGroupMarker()) {
116                                 break;
117                             }
118                         }
119                     }
120                     if (allowItem(item)) {
121                         contributions.add(i, item);
122                         itemAdded(item);
123                     }
124                     return;
125                 }
126             }
127         }
128         throw new IllegalArgumentException JavaDoc("Group not found: " + groupName);//$NON-NLS-1$
129
}
130
131     /*
132      * (non-Javadoc) Method declared on IContributionManager.
133      */

134     public void appendToGroup(String JavaDoc groupName, IAction action) {
135         addToGroup(groupName, new ActionContributionItem(action), true);
136     }
137
138     /*
139      * (non-Javadoc) Method declared on IContributionManager.
140      */

141     public void appendToGroup(String JavaDoc groupName, IContributionItem item) {
142         addToGroup(groupName, item, true);
143     }
144
145     /**
146      * This method allows subclasses of <code>ContributionManager</code> to
147      * prevent certain items in the contributions list.
148      * <code>ContributionManager</code> will either block or allow an addition
149      * based on the result of this method call. This can be used to prevent
150      * duplication, for example.
151      *
152      * @param itemToAdd
153      * The contribution item to be added; may be <code>null</code>.
154      * @return <code>true</code> if the addition should be allowed;
155      * <code>false</code> otherwise. The default implementation allows
156      * all items.
157      * @since 3.0
158      */

159     protected boolean allowItem(IContributionItem itemToAdd) {
160         return true;
161     }
162
163     /**
164      * Internal debug method for printing statistics about this manager to
165      * <code>System.out</code>.
166      */

167     protected void dumpStatistics() {
168         int size = 0;
169         if (contributions != null) {
170             size = contributions.size();
171         }
172
173         System.out.println(this.toString());
174         System.out.println(" Number of elements: " + size);//$NON-NLS-1$
175
int sum = 0;
176         for (int i = 0; i < size; i++) {
177             if (((IContributionItem) contributions.get(i)).isVisible()) {
178                 sum++;
179             }
180         }
181         System.out.println(" Number of visible elements: " + sum);//$NON-NLS-1$
182
System.out.println(" Is dirty: " + isDirty()); //$NON-NLS-1$
183
}
184
185     /*
186      * (non-Javadoc) Method declared on IContributionManager.
187      */

188     public IContributionItem find(String JavaDoc id) {
189         Iterator JavaDoc e = contributions.iterator();
190         while (e.hasNext()) {
191             IContributionItem item = (IContributionItem) e.next();
192             String JavaDoc itemId = item.getId();
193             if (itemId != null && itemId.equalsIgnoreCase(id)) {
194                 return item;
195             }
196         }
197         return null;
198     }
199
200     /*
201      * (non-Javadoc) Method declared on IContributionManager.
202      */

203     public IContributionItem[] getItems() {
204         IContributionItem[] items = new IContributionItem[contributions.size()];
205         contributions.toArray(items);
206         return items;
207     }
208     
209     /**
210      * Return the number of contributions in this manager.
211      *
212      * @return the number of contributions in this manager
213      * @since 3.3
214      */

215     public int getSize() {
216         return contributions.size();
217     }
218
219     /**
220      * The <code>ContributionManager</code> implementation of this method
221      * declared on <code>IContributionManager</code> returns the current
222      * overrides. If there is no overrides it lazily creates one which overrides
223      * no item state.
224      *
225      * @since 2.0
226      */

227     public IContributionManagerOverrides getOverrides() {
228         if (overrides == null) {
229             overrides = new IContributionManagerOverrides() {
230                 public Boolean JavaDoc getEnabled(IContributionItem item) {
231                     return null;
232                 }
233
234                 public Integer JavaDoc getAccelerator(IContributionItem item) {
235                     return null;
236                 }
237
238                 public String JavaDoc getAcceleratorText(IContributionItem item) {
239                     return null;
240                 }
241
242                 public String JavaDoc getText(IContributionItem item) {
243                     return null;
244                 }
245             };
246         }
247         return overrides;
248     }
249
250     /**
251      * Returns whether this contribution manager contains dynamic items. A
252      * dynamic contribution item contributes items conditionally, dependent on
253      * some internal state.
254      *
255      * @return <code>true</code> if this manager contains dynamic items, and
256      * <code>false</code> otherwise
257      */

258     protected boolean hasDynamicItems() {
259         return (dynamicItems > 0);
260     }
261
262     /**
263      * Returns the index of the item with the given id.
264      *
265      * @param id
266      * The id of the item whose index is requested.
267      *
268      * @return <code>int</code> the index or -1 if the item is not found
269      */

270     public int indexOf(String JavaDoc id) {
271         for (int i = 0; i < contributions.size(); i++) {
272             IContributionItem item = (IContributionItem) contributions.get(i);
273             String JavaDoc itemId = item.getId();
274             if (itemId != null && itemId.equalsIgnoreCase(id)) {
275                 return i;
276             }
277         }
278         return -1;
279     }
280
281     /**
282      * Returns the index of the object in the internal structure. This is
283      * different from <code>indexOf(String id)</code> since some contribution
284      * items may not have an id.
285      *
286      * @param item
287      * The contribution item
288      * @return the index, or -1 if the item is not found
289      * @since 3.0
290      */

291     protected int indexOf(IContributionItem item) {
292         return contributions.indexOf(item);
293     }
294
295     /**
296      * Insert the item at the given index.
297      *
298      * @param index
299      * The index to be used for insertion
300      * @param item
301      * The item to be inserted
302      */

303     public void insert(int index, IContributionItem item) {
304         if (index > contributions.size()) {
305             throw new IndexOutOfBoundsException JavaDoc(
306                     "inserting " + item.getId() + " at " + index); //$NON-NLS-1$ //$NON-NLS-2$
307
}
308         if (allowItem(item)) {
309             contributions.add(index, item);
310             itemAdded(item);
311         }
312     }
313
314     /*
315      * (non-Javadoc) Method declared on IContributionManager.
316      */

317     public void insertAfter(String JavaDoc ID, IAction action) {
318         insertAfter(ID, new ActionContributionItem(action));
319     }
320
321     /*
322      * (non-Javadoc) Method declared on IContributionManager.
323      */

324     public void insertAfter(String JavaDoc ID, IContributionItem item) {
325         IContributionItem ci = find(ID);
326         if (ci == null) {
327             throw new IllegalArgumentException JavaDoc("can't find ID" + ID);//$NON-NLS-1$
328
}
329         int ix = contributions.indexOf(ci);
330         if (ix >= 0) {
331             // System.out.println("insert after: " + ix);
332
if (allowItem(item)) {
333                 contributions.add(ix + 1, item);
334                 itemAdded(item);
335             }
336         }
337     }
338
339     /*
340      * (non-Javadoc) Method declared on IContributionManager.
341      */

342     public void insertBefore(String JavaDoc ID, IAction action) {
343         insertBefore(ID, new ActionContributionItem(action));
344     }
345
346     /*
347      * (non-Javadoc) Method declared on IContributionManager.
348      */

349     public void insertBefore(String JavaDoc ID, IContributionItem item) {
350         IContributionItem ci = find(ID);
351         if (ci == null) {
352             throw new IllegalArgumentException JavaDoc("can't find ID " + ID);//$NON-NLS-1$
353
}
354         int ix = contributions.indexOf(ci);
355         if (ix >= 0) {
356             // System.out.println("insert before: " + ix);
357
if (allowItem(item)) {
358                 contributions.add(ix, item);
359                 itemAdded(item);
360             }
361         }
362     }
363
364     /*
365      * (non-Javadoc) Method declared on IContributionManager.
366      */

367     public boolean isDirty() {
368         if (isDirty) {
369             return true;
370         }
371         if (hasDynamicItems()) {
372             for (Iterator JavaDoc iter = contributions.iterator(); iter.hasNext();) {
373                 IContributionItem item = (IContributionItem) iter.next();
374                 if (item.isDirty()) {
375                     return true;
376                 }
377             }
378         }
379         return false;
380     }
381
382     /*
383      * (non-Javadoc) Method declared on IContributionManager.
384      */

385     public boolean isEmpty() {
386         return contributions.isEmpty();
387     }
388
389     /**
390      * The given item was added to the list of contributions. Marks the manager
391      * as dirty and updates the number of dynamic items, and the memento.
392      *
393      * @param item
394      * the item to be added
395      *
396      */

397     protected void itemAdded(IContributionItem item) {
398         item.setParent(this);
399         markDirty();
400         if (item.isDynamic()) {
401             dynamicItems++;
402         }
403     }
404
405     /**
406      * The given item was removed from the list of contributions. Marks the
407      * manager as dirty and updates the number of dynamic items.
408      *
409      * @param item
410      * remove given parent from list of contributions
411      */

412     protected void itemRemoved(IContributionItem item) {
413         item.setParent(null);
414         markDirty();
415         if (item.isDynamic()) {
416             dynamicItems--;
417         }
418     }
419
420     /*
421      * (non-Javadoc) Method declared on IContributionManager.
422      */

423     public void markDirty() {
424         setDirty(true);
425     }
426
427     /*
428      * (non-Javadoc) Method declared on IContributionManager.
429      */

430     public void prependToGroup(String JavaDoc groupName, IAction action) {
431         addToGroup(groupName, new ActionContributionItem(action), false);
432     }
433
434     /*
435      * (non-Javadoc) Method declared on IContributionManager.
436      */

437     public void prependToGroup(String JavaDoc groupName, IContributionItem item) {
438         addToGroup(groupName, item, false);
439     }
440
441     /*
442      * (non-Javadoc) Method declared on IContributionManager.
443      */

444     public IContributionItem remove(String JavaDoc ID) {
445         IContributionItem ci = find(ID);
446         if (ci == null) {
447             return null;
448         }
449         return remove(ci);
450     }
451
452     /*
453      * (non-Javadoc) Method declared on IContributionManager.
454      */

455     public IContributionItem remove(IContributionItem item) {
456         if (contributions.remove(item)) {
457             itemRemoved(item);
458             return item;
459         }
460         return null;
461     }
462
463     /*
464      * (non-Javadoc) Method declared on IContributionManager.
465      */

466     public void removeAll() {
467         IContributionItem[] items = getItems();
468         contributions.clear();
469         for (int i = 0; i < items.length; i++) {
470             IContributionItem item = items[i];
471             itemRemoved(item);
472         }
473         dynamicItems = 0;
474         markDirty();
475     }
476
477     /**
478      * Replaces the item of the given identifier with another contribution item.
479      * This can be used, for example, to replace large contribution items with
480      * placeholders to avoid memory leaks. If the identifier cannot be found in
481      * the current list of items, then this does nothing. If multiple
482      * occurrences are found, then the replacement items is put in the first
483      * position and the other positions are removed.
484      *
485      * @param identifier
486      * The identifier to look for in the list of contributions;
487      * should not be <code>null</code>.
488      * @param replacementItem
489      * The contribution item to replace the old item; must not be
490      * <code>null</code>. Use
491      * {@link org.eclipse.jface.action.ContributionManager#remove(java.lang.String) remove}
492      * if that is what you want to do.
493      * @return <code>true</code> if the given identifier can be; <code>
494      * @since 3.0
495      */

496     public boolean replaceItem(final String JavaDoc identifier,
497             final IContributionItem replacementItem) {
498         if (identifier == null) {
499             return false;
500         }
501
502         final int index = indexOf(identifier);
503         if (index < 0) {
504             return false; // couldn't find the item.
505
}
506
507         // Remove the old item.
508
final IContributionItem oldItem = (IContributionItem) contributions
509                 .get(index);
510         itemRemoved(oldItem);
511
512         // Add the new item.
513
contributions.set(index, replacementItem);
514         itemAdded(replacementItem); // throws NPE if (replacementItem == null)
515

516         // Go through and remove duplicates.
517
for (int i = contributions.size() - 1; i > index; i--) {
518             IContributionItem item = (IContributionItem) contributions.get(i);
519             if ((item != null) && (identifier.equals(item.getId()))) {
520                 if (Policy.TRACE_TOOLBAR) {
521                     System.out
522                             .println("Removing duplicate on replace: " + identifier); //$NON-NLS-1$
523
}
524                 contributions.remove(i);
525                 itemRemoved(item);
526             }
527         }
528
529         return true; // success
530
}
531
532     /**
533      * Sets whether this manager is dirty. When dirty, the list of contributions
534      * is not accurately reflected in the corresponding widgets.
535      *
536      * @param dirty
537      * <code>true</code> if this manager is dirty, and
538      * <code>false</code> if it is up-to-date
539      */

540     protected void setDirty(boolean dirty) {
541         isDirty = dirty;
542     }
543
544     /**
545      * Sets the overrides for this contribution manager
546      *
547      * @param newOverrides
548      * the overrides for the items of this manager
549      * @since 2.0
550      */

551     public void setOverrides(IContributionManagerOverrides newOverrides) {
552         overrides = newOverrides;
553     }
554
555     /**
556      * An internal method for setting the order of the contribution items.
557      *
558      * @param items
559      * the contribution items in the specified order
560      * @since 3.0
561      */

562     protected void internalSetItems(IContributionItem[] items) {
563         contributions.clear();
564         for (int i = 0; i < items.length; i++) {
565             if (allowItem(items[i])) {
566                 contributions.add(items[i]);
567             }
568         }
569     }
570 }
571
Popular Tags