Mercurial > projects > dwt-addons
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 } |