KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.HashMap JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.core.runtime.ListenerList;
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.CoolBar;
21 import org.eclipse.swt.widgets.Menu;
22 import org.eclipse.swt.widgets.ToolBar;
23
24 /**
25  * A <code>SubMenuManager</code> is used to define a set of contribution
26  * items within a parent manager. Once defined, the visibility of the entire set can
27  * be changed as a unit.
28  * <p>
29  * A client may ask for and make additions to a submenu. The visibility of these items
30  * is also controlled by the visibility of the <code>SubMenuManager</code>.
31  * </p>
32  */

33 public class SubMenuManager extends SubContributionManager implements
34         IMenuManager {
35
36     /**
37      * Maps each submenu in the manager to a wrapper. The wrapper is used to
38      * monitor additions and removals. If the visibility of the manager is modified
39      * the visibility of the submenus is also modified.
40      */

41     private Map JavaDoc mapMenuToWrapper;
42
43     /**
44      * List of registered menu listeners (element type: <code>IMenuListener</code>).
45      */

46     private ListenerList menuListeners = new ListenerList();
47
48     /**
49      * The menu listener added to the parent. Lazily initialized
50      * in addMenuListener.
51      */

52     private IMenuListener menuListener;
53
54     /**
55      * Constructs a new manager.
56      *
57      * @param mgr the parent manager. All contributions made to the
58      * <code>SubMenuManager</code> are forwarded and appear in the
59      * parent manager.
60      */

61     public SubMenuManager(IMenuManager mgr) {
62         super(mgr);
63     }
64
65     /* (non-Javadoc)
66      * @see org.eclipse.jface.action.IMenuManager#addMenuListener(org.eclipse.jface.action.IMenuListener)
67      */

68     public void addMenuListener(IMenuListener listener) {
69         menuListeners.add(listener);
70         if (menuListener == null) {
71             menuListener = new IMenuListener() {
72                 public void menuAboutToShow(IMenuManager manager) {
73                     Object JavaDoc[] listeners = menuListeners.getListeners();
74                     for (int i = 0; i < listeners.length; ++i) {
75                         ((IMenuListener) listeners[i])
76                                 .menuAboutToShow(SubMenuManager.this);
77                     }
78                 }
79             };
80         }
81         getParentMenuManager().addMenuListener(menuListener);
82     }
83
84     /**
85      * The default implementation of this <code>IContributionItem</code>
86      * method does nothing. Subclasses may override.
87      */

88     public void dispose() {
89         // do nothing
90
}
91
92     /* (non-Javadoc)
93      * @see org.eclipse.jface.action.SubContributionManager#disposeManager()
94      */

95     public void disposeManager() {
96         if (menuListener != null) {
97             getParentMenuManager().removeMenuListener(menuListener);
98             menuListener = null;
99             clearListenerList(menuListeners);
100         }
101         // Dispose wrapped menus in addition to removing them.
102
// See bugs 64024 and 73715 for details.
103
// important to dispose menu wrappers before call to super,
104
// otherwise super's call to removeAll will remove them
105
// before they can be disposed
106
if (mapMenuToWrapper != null) {
107             Iterator JavaDoc iter = mapMenuToWrapper.values().iterator();
108             while (iter.hasNext()) {
109                 SubMenuManager wrapper = (SubMenuManager) iter.next();
110                 wrapper.disposeManager();
111             }
112             mapMenuToWrapper.clear();
113             mapMenuToWrapper = null;
114         }
115         super.disposeManager();
116     }
117
118     /**
119      * Clears all of the listeners in a listener list. TODO Bug 117519 Remove
120      * this method when fixed.
121      *
122      * @param list
123      * The list to be clear; must not be <code>null</code>.
124      */

125     private final void clearListenerList(final ListenerList list) {
126         final Object JavaDoc[] listeners = list.getListeners();
127         for (int i = 0; i < listeners.length; i++) {
128             list.remove(listeners[i]);
129         }
130     }
131
132     /* (non-Javadoc)
133      * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.Composite)
134      */

135     public void fill(Composite parent) {
136         if (isVisible()) {
137             getParentMenuManager().fill(parent);
138         }
139     }
140
141     /* (non-Javadoc)
142      * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.CoolBar, int)
143      */

144     public void fill(CoolBar parent, int index) {
145         // do nothing
146
}
147
148     /* (non-Javadoc)
149      * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.Menu, int)
150      */

151     public void fill(Menu parent, int index) {
152         if (isVisible()) {
153             getParentMenuManager().fill(parent, index);
154         }
155     }
156
157     /* (non-Javadoc)
158      * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.ToolBar, int)
159      */

160     public void fill(ToolBar parent, int index) {
161         if (isVisible()) {
162             getParentMenuManager().fill(parent, index);
163         }
164     }
165
166     /* (non-Javadoc)
167      * Method declared on IContributionManager.
168      *
169      * Returns the item passed to us, not the wrapper.
170      * In the case of menu's not added by this manager,
171      * ensure that we return a wrapper for the menu.
172      */

173     public IContributionItem find(String JavaDoc id) {
174         IContributionItem item = getParentMenuManager().find(id);
175         if (item instanceof SubContributionItem) {
176             // Return the item passed to us, not the wrapper.
177
item = unwrap(item);
178         }
179
180         if (item instanceof IMenuManager) {
181             // if it is a menu manager wrap it before returning
182
IMenuManager menu = (IMenuManager) item;
183             item = getWrapper(menu);
184         }
185
186         return item;
187     }
188
189     /**
190      * <p>
191      * The menu returned is wrapped within a <code>SubMenuManager</code> to
192      * monitor additions and removals. If the visibility of this menu is modified
193      * the visibility of the submenus is also modified.
194      * </p>
195      */

196     public IMenuManager findMenuUsingPath(String JavaDoc path) {
197         IContributionItem item = findUsingPath(path);
198         if (item instanceof IMenuManager) {
199             return (IMenuManager) item;
200         }
201         return null;
202     }
203
204     /* (non-Javadoc)
205      * Method declared on IMenuManager.
206      *
207      * Returns the item passed to us, not the wrapper.
208      *
209      * We use use the same algorithm as MenuManager.findUsingPath, but unwrap
210      * submenus along so that SubMenuManagers are visible.
211      */

212     public IContributionItem findUsingPath(String JavaDoc path) {
213         String JavaDoc id = path;
214         String JavaDoc rest = null;
215         int separator = path.indexOf('/');
216         if (separator != -1) {
217             id = path.substring(0, separator);
218             rest = path.substring(separator + 1);
219         }
220         IContributionItem item = find(id); // unwraps item
221
if (rest != null && item instanceof IMenuManager) {
222             IMenuManager menu = (IMenuManager) item;
223             item = menu.findUsingPath(rest);
224         }
225         return item;
226     }
227
228     /* (non-Javadoc)
229      * @see org.eclipse.jface.action.IContributionItem#getId()
230      */

231     public String JavaDoc getId() {
232         return getParentMenuManager().getId();
233     }
234
235     /**
236      * @return the parent menu manager that this sub-manager contributes to.
237      */

238     protected final IMenuManager getParentMenuManager() {
239         // Cast is ok because that's the only
240
// thing we accept in the construtor.
241
return (IMenuManager) getParent();
242     }
243
244     /* (non-Javadoc)
245      * @see org.eclipse.jface.action.IMenuManager#getRemoveAllWhenShown()
246      */

247     public boolean getRemoveAllWhenShown() {
248         return false;
249     }
250
251     /**
252      * Returns the menu wrapper for a menu manager.
253      * <p>
254      * The sub menus within this menu are wrapped within a <code>SubMenuManager</code> to
255      * monitor additions and removals. If the visibility of this menu is modified
256      * the visibility of the sub menus is also modified.
257      * <p>
258      * @param mgr the menu manager to be wrapped
259      *
260      * @return the menu wrapper
261      */

262     protected IMenuManager getWrapper(IMenuManager mgr) {
263         if (mapMenuToWrapper == null) {
264             mapMenuToWrapper = new HashMap JavaDoc(4);
265         }
266         SubMenuManager wrapper = (SubMenuManager) mapMenuToWrapper.get(mgr);
267         if (wrapper == null) {
268             wrapper = wrapMenu(mgr);
269             mapMenuToWrapper.put(mgr, wrapper);
270         }
271         return wrapper;
272     }
273
274     /* (non-Javadoc)
275      * @see org.eclipse.jface.action.IContributionItem#isDynamic()
276      */

277     public boolean isDynamic() {
278         return getParentMenuManager().isDynamic();
279     }
280
281     /* (non-Javadoc)
282      * @see org.eclipse.jface.action.IContributionItem#isEnabled()
283      */

284     public boolean isEnabled() {
285         return isVisible() && getParentMenuManager().isEnabled();
286     }
287
288     /* (non-Javadoc)
289      * @see org.eclipse.jface.action.IContributionItem#isGroupMarker()
290      */

291     public boolean isGroupMarker() {
292         return getParentMenuManager().isGroupMarker();
293     }
294
295     /* (non-Javadoc)
296      * @see org.eclipse.jface.action.IContributionItem#isSeparator()
297      */

298     public boolean isSeparator() {
299         return getParentMenuManager().isSeparator();
300     }
301
302     /**
303      * Remove all contribution items.
304      */

305     public void removeAll() {
306         super.removeAll();
307         if (mapMenuToWrapper != null) {
308             Iterator JavaDoc iter = mapMenuToWrapper.values().iterator();
309             while (iter.hasNext()) {
310                 SubMenuManager wrapper = (SubMenuManager) iter.next();
311                 wrapper.removeAll();
312             }
313             mapMenuToWrapper.clear();
314             mapMenuToWrapper = null;
315         }
316     }
317
318     /* (non-Javadoc)
319      * @see org.eclipse.jface.action.IMenuManager#removeMenuListener(org.eclipse.jface.action.IMenuListener)
320      */

321     public void removeMenuListener(IMenuListener listener) {
322         menuListeners.remove(listener);
323     }
324
325     /* (non-Javadoc)
326      * @see org.eclipse.jface.action.IContributionItem#saveWidgetState()
327      */

328     public void saveWidgetState() {
329         // do nothing
330
}
331
332     /* (non-Javadoc)
333      * @see org.eclipse.jface.action.IContributionItem#setParent(org.eclipse.jface.action.IContributionManager)
334      */

335     public void setParent(IContributionManager parent) {
336         // do nothing, our "parent manager's" parent
337
// is set when it is added to a manager
338
}
339
340     /* (non-Javadoc)
341      * @see org.eclipse.jface.action.IMenuManager#setRemoveAllWhenShown(boolean)
342      */

343     public void setRemoveAllWhenShown(boolean removeAll) {
344         Assert.isTrue(false, "Should not be called on submenu manager"); //$NON-NLS-1$
345
}
346
347     /* (non-Javadoc)
348      * @see org.eclipse.jface.action.SubContributionManager#setVisible(boolean)
349      */

350     public void setVisible(boolean visible) {
351         super.setVisible(visible);
352         if (mapMenuToWrapper != null) {
353             Iterator JavaDoc iter = mapMenuToWrapper.values().iterator();
354             while (iter.hasNext()) {
355                 SubMenuManager wrapper = (SubMenuManager) iter.next();
356                 wrapper.setVisible(visible);
357             }
358         }
359     }
360
361     /* (non-Javadoc)
362      * @see org.eclipse.jface.action.IContributionItem#update()
363      */

364     public void update() {
365         // This method is not governed by visibility. The client may
366
// call <code>setVisible</code> and then force an update. At that
367
// point we need to update the parent.
368
getParentMenuManager().update();
369     }
370
371     /* (non-Javadoc)
372      * @see org.eclipse.jface.action.IContributionManager#update(boolean)
373      */

374     public void update(boolean force) {
375         // This method is not governed by visibility. The client may
376
// call <code>setVisible</code> and then force an update. At that
377
// point we need to update the parent.
378
getParentMenuManager().update(force);
379     }
380
381     /* (non-Javadoc)
382      * @see org.eclipse.jface.action.IContributionItem#update(java.lang.String)
383      */

384     public void update(String JavaDoc id) {
385         getParentMenuManager().update(id);
386     }
387
388     /* (non-Javadoc)
389      * @see org.eclipse.jface.action.IMenuManager#updateAll(boolean)
390      */

391     public void updateAll(boolean force) {
392         // This method is not governed by visibility. The client may
393
// call <code>setVisible</code> and then force an update. At that
394
// point we need to update the parent.
395
getParentMenuManager().updateAll(force);
396     }
397
398     /**
399      * Wraps a menu manager in a sub menu manager, and returns the new wrapper.
400      * @param menu the menu manager to wrap
401      * @return the new wrapped menu manager
402      */

403     protected SubMenuManager wrapMenu(IMenuManager menu) {
404         SubMenuManager mgr = new SubMenuManager(menu);
405         mgr.setVisible(isVisible());
406         return mgr;
407     }
408 }
409
Popular Tags