comparison dwtx/jface/action/SubMenuManager.d @ 28:50b0163e18f8

Sub...
author Frank Benoit <benoit@tionex.de>
date Thu, 03 Apr 2008 05:38:04 +0200
parents
children ea8ff534f622
comparison
equal deleted inserted replaced
27:7ec2fd279c28 28:50b0163e18f8
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 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.jface.action.SubMenuManager;
14
15 import dwtx.jface.action.SubContributionManager;
16 import dwtx.jface.action.IMenuManager;
17 import dwtx.jface.action.IMenuListener;
18 import dwtx.jface.action.IContributionItem;
19 import dwtx.jface.action.IContributionManager;
20 import dwtx.jface.action.SubContributionItem;
21
22 import tango.util.collection.HashMap;
23 import tango.util.collection.model.Map;
24
25 import dwt.widgets.Composite;
26 import dwt.widgets.CoolBar;
27 import dwt.widgets.Menu;
28 import dwt.widgets.ToolBar;
29 import dwtx.core.runtime.Assert;
30 import dwtx.core.runtime.ListenerList;
31
32 import dwt.dwthelper.utils;
33
34 /**
35 * A <code>SubMenuManager</code> is used to define a set of contribution
36 * items within a parent manager. Once defined, the visibility of the entire set can
37 * be changed as a unit.
38 * <p>
39 * A client may ask for and make additions to a submenu. The visibility of these items
40 * is also controlled by the visibility of the <code>SubMenuManager</code>.
41 * </p>
42 */
43 public class SubMenuManager : SubContributionManager,
44 IMenuManager {
45
46 public bool isDirty() {
47 return super.isDirty();
48 }
49 public bool isVisible() {
50 return super.isVisible();
51 }
52
53 /**
54 * Maps each submenu in the manager to a wrapper. The wrapper is used to
55 * monitor additions and removals. If the visibility of the manager is modified
56 * the visibility of the submenus is also modified.
57 */
58 private Map!(Object,Object) mapMenuToWrapper;
59
60 /**
61 * List of registered menu listeners (element type: <code>IMenuListener</code>).
62 */
63 private ListenerList menuListeners;
64
65 /**
66 * The menu listener added to the parent. Lazily initialized
67 * in addMenuListener.
68 */
69 private IMenuListener menuListener;
70
71 /**
72 * Constructs a new manager.
73 *
74 * @param mgr the parent manager. All contributions made to the
75 * <code>SubMenuManager</code> are forwarded and appear in the
76 * parent manager.
77 */
78 public this(IMenuManager mgr) {
79 menuListeners = new ListenerList();
80 super(mgr);
81 }
82
83 /* (non-Javadoc)
84 * @see dwtx.jface.action.IMenuManager#addMenuListener(dwtx.jface.action.IMenuListener)
85 */
86 public void addMenuListener(IMenuListener listener) {
87 menuListeners.add(cast(Object)listener);
88 if (menuListener is null) {
89 menuListener = new class IMenuListener {
90 public void menuAboutToShow(IMenuManager manager) {
91 Object[] listeners = menuListeners.getListeners();
92 for (int i = 0; i < listeners.length; ++i) {
93 (cast(IMenuListener) listeners[i])
94 .menuAboutToShow(this.outer);
95 }
96 }
97 };
98 }
99 getParentMenuManager().addMenuListener(menuListener);
100 }
101
102 /**
103 * The default implementation of this <code>IContributionItem</code>
104 * method does nothing. Subclasses may override.
105 */
106 public void dispose() {
107 // do nothing
108 }
109
110 /* (non-Javadoc)
111 * @see dwtx.jface.action.SubContributionManager#disposeManager()
112 */
113 public void disposeManager() {
114 if (menuListener !is null) {
115 getParentMenuManager().removeMenuListener(menuListener);
116 menuListener = null;
117 clearListenerList(menuListeners);
118 }
119 // Dispose wrapped menus in addition to removing them.
120 // See bugs 64024 and 73715 for details.
121 // important to dispose menu wrappers before call to super,
122 // otherwise super's call to removeAll will remove them
123 // before they can be disposed
124 if (mapMenuToWrapper !is null) {
125 foreach( v; mapMenuToWrapper.elements() ){
126 SubMenuManager wrapper = cast(SubMenuManager) v;
127 wrapper.disposeManager();
128 }
129 mapMenuToWrapper.clear();
130 mapMenuToWrapper = null;
131 }
132 super.disposeManager();
133 }
134
135 /**
136 * Clears all of the listeners in a listener list. TODO Bug 117519 Remove
137 * this method when fixed.
138 *
139 * @param list
140 * The list to be clear; must not be <code>null</code>.
141 */
142 private final void clearListenerList(ListenerList list) {
143 Object[] listeners = list.getListeners();
144 for (int i = 0; i < listeners.length; i++) {
145 list.remove(cast(Object)listeners[i]);
146 }
147 }
148
149 /* (non-Javadoc)
150 * @see dwtx.jface.action.IContributionItem#fill(dwt.widgets.Composite)
151 */
152 public void fill(Composite parent) {
153 if (isVisible()) {
154 getParentMenuManager().fill(parent);
155 }
156 }
157
158 /* (non-Javadoc)
159 * @see dwtx.jface.action.IContributionItem#fill(dwt.widgets.CoolBar, int)
160 */
161 public void fill(CoolBar parent, int index) {
162 // do nothing
163 }
164
165 /* (non-Javadoc)
166 * @see dwtx.jface.action.IContributionItem#fill(dwt.widgets.Menu, int)
167 */
168 public void fill(Menu parent, int index) {
169 if (isVisible()) {
170 getParentMenuManager().fill(parent, index);
171 }
172 }
173
174 /* (non-Javadoc)
175 * @see dwtx.jface.action.IContributionItem#fill(dwt.widgets.ToolBar, int)
176 */
177 public void fill(ToolBar parent, int index) {
178 if (isVisible()) {
179 getParentMenuManager().fill(parent, index);
180 }
181 }
182
183 /* (non-Javadoc)
184 * Method declared on IContributionManager.
185 *
186 * Returns the item passed to us, not the wrapper.
187 * In the case of menu's not added by this manager,
188 * ensure that we return a wrapper for the menu.
189 */
190 public IContributionItem find(String id) {
191 IContributionItem item = getParentMenuManager().find(id);
192 if (cast(SubContributionItem)item ) {
193 // Return the item passed to us, not the wrapper.
194 item = unwrap(item);
195 }
196
197 if (cast(IMenuManager)item ) {
198 // if it is a menu manager wrap it before returning
199 IMenuManager menu = cast(IMenuManager) item;
200 item = getWrapper(menu);
201 }
202
203 return item;
204 }
205
206 /**
207 * <p>
208 * The menu returned is wrapped within a <code>SubMenuManager</code> to
209 * monitor additions and removals. If the visibility of this menu is modified
210 * the visibility of the submenus is also modified.
211 * </p>
212 */
213 public IMenuManager findMenuUsingPath(String path) {
214 IContributionItem item = findUsingPath(path);
215 if (cast(IMenuManager)item ) {
216 return cast(IMenuManager) item;
217 }
218 return null;
219 }
220
221 /* (non-Javadoc)
222 * Method declared on IMenuManager.
223 *
224 * Returns the item passed to us, not the wrapper.
225 *
226 * We use use the same algorithm as MenuManager.findUsingPath, but unwrap
227 * submenus along so that SubMenuManagers are visible.
228 */
229 public IContributionItem findUsingPath(String path) {
230 String id = path;
231 String rest = null;
232 int separator = path.indexOf('/');
233 if (separator !is -1) {
234 id = path.substring(0, separator);
235 rest = path.substring(separator + 1);
236 }
237 IContributionItem item = find(id); // unwraps item
238 if (rest !is null && cast(IMenuManager)item ) {
239 IMenuManager menu = cast(IMenuManager) item;
240 item = menu.findUsingPath(rest);
241 }
242 return item;
243 }
244
245 /* (non-Javadoc)
246 * @see dwtx.jface.action.IContributionItem#getId()
247 */
248 public String getId() {
249 return getParentMenuManager().getId();
250 }
251
252 /**
253 * @return the parent menu manager that this sub-manager contributes to.
254 */
255 protected final IMenuManager getParentMenuManager() {
256 // Cast is ok because that's the only
257 // thing we accept in the construtor.
258 return cast(IMenuManager) getParent();
259 }
260
261 /* (non-Javadoc)
262 * @see dwtx.jface.action.IMenuManager#getRemoveAllWhenShown()
263 */
264 public bool getRemoveAllWhenShown() {
265 return false;
266 }
267
268 /**
269 * Returns the menu wrapper for a menu manager.
270 * <p>
271 * The sub menus within this menu are wrapped within a <code>SubMenuManager</code> to
272 * monitor additions and removals. If the visibility of this menu is modified
273 * the visibility of the sub menus is also modified.
274 * <p>
275 * @param mgr the menu manager to be wrapped
276 *
277 * @return the menu wrapper
278 */
279 protected IMenuManager getWrapper(IMenuManager mgr) {
280 if (mapMenuToWrapper is null) {
281 mapMenuToWrapper = new HashMap!(Object,Object);
282 }
283 SubMenuManager wrapper = cast(SubMenuManager) mapMenuToWrapper.get(cast(Object)mgr);
284 if (wrapper is null) {
285 wrapper = wrapMenu(mgr);
286 mapMenuToWrapper.add(cast(Object)mgr, wrapper);
287 }
288 return wrapper;
289 }
290
291 /* (non-Javadoc)
292 * @see dwtx.jface.action.IContributionItem#isDynamic()
293 */
294 public bool isDynamic() {
295 return getParentMenuManager().isDynamic();
296 }
297
298 /* (non-Javadoc)
299 * @see dwtx.jface.action.IContributionItem#isEnabled()
300 */
301 public bool isEnabled() {
302 return isVisible() && getParentMenuManager().isEnabled();
303 }
304
305 /* (non-Javadoc)
306 * @see dwtx.jface.action.IContributionItem#isGroupMarker()
307 */
308 public bool isGroupMarker() {
309 return getParentMenuManager().isGroupMarker();
310 }
311
312 /* (non-Javadoc)
313 * @see dwtx.jface.action.IContributionItem#isSeparator()
314 */
315 public bool isSeparator() {
316 return getParentMenuManager().isSeparator();
317 }
318
319 /**
320 * Remove all contribution items.
321 */
322 public void removeAll() {
323 super.removeAll();
324 if (mapMenuToWrapper !is null) {
325 foreach( v; mapMenuToWrapper.elements() ){
326 SubMenuManager wrapper = cast(SubMenuManager) v;
327 wrapper.removeAll();
328 }
329 mapMenuToWrapper.clear();
330 mapMenuToWrapper = null;
331 }
332 }
333
334 /* (non-Javadoc)
335 * @see dwtx.jface.action.IMenuManager#removeMenuListener(dwtx.jface.action.IMenuListener)
336 */
337 public void removeMenuListener(IMenuListener listener) {
338 menuListeners.remove(cast(Object)listener);
339 }
340
341 /* (non-Javadoc)
342 * @see dwtx.jface.action.IContributionItem#saveWidgetState()
343 */
344 public void saveWidgetState() {
345 // do nothing
346 }
347
348 /* (non-Javadoc)
349 * @see dwtx.jface.action.IContributionItem#setParent(dwtx.jface.action.IContributionManager)
350 */
351 public void setParent(IContributionManager parent) {
352 // do nothing, our "parent manager's" parent
353 // is set when it is added to a manager
354 }
355
356 /* (non-Javadoc)
357 * @see dwtx.jface.action.IMenuManager#setRemoveAllWhenShown(bool)
358 */
359 public void setRemoveAllWhenShown(bool removeAll) {
360 Assert.isTrue(false, "Should not be called on submenu manager"); //$NON-NLS-1$
361 }
362
363 /* (non-Javadoc)
364 * @see dwtx.jface.action.SubContributionManager#setVisible(bool)
365 */
366 public void setVisible(bool visible) {
367 super.setVisible(visible);
368 if (mapMenuToWrapper !is null) {
369 foreach( v; mapMenuToWrapper.elements() ){
370 SubMenuManager wrapper = cast(SubMenuManager) v;
371 wrapper.setVisible(visible);
372 }
373 }
374 }
375
376 /* (non-Javadoc)
377 * @see dwtx.jface.action.IContributionItem#update()
378 */
379 public void update() {
380 // This method is not governed by visibility. The client may
381 // call <code>setVisible</code> and then force an update. At that
382 // point we need to update the parent.
383 getParentMenuManager().update();
384 }
385
386 /* (non-Javadoc)
387 * @see dwtx.jface.action.IContributionManager#update(bool)
388 */
389 public void update(bool force) {
390 // This method is not governed by visibility. The client may
391 // call <code>setVisible</code> and then force an update. At that
392 // point we need to update the parent.
393 getParentMenuManager().update(force);
394 }
395
396 /* (non-Javadoc)
397 * @see dwtx.jface.action.IContributionItem#update(java.lang.String)
398 */
399 public void update(String id) {
400 getParentMenuManager().update(id);
401 }
402
403 /* (non-Javadoc)
404 * @see dwtx.jface.action.IMenuManager#updateAll(bool)
405 */
406 public void updateAll(bool force) {
407 // This method is not governed by visibility. The client may
408 // call <code>setVisible</code> and then force an update. At that
409 // point we need to update the parent.
410 getParentMenuManager().updateAll(force);
411 }
412
413 /**
414 * Wraps a menu manager in a sub menu manager, and returns the new wrapper.
415 * @param menu the menu manager to wrap
416 * @return the new wrapped menu manager
417 */
418 protected SubMenuManager wrapMenu(IMenuManager menu) {
419 SubMenuManager mgr = new SubMenuManager(menu);
420 mgr.setVisible(isVisible());
421 return mgr;
422 }
423 }