KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > menus > CommandContributionItem


1 /*******************************************************************************
2  * Copyright (c) 2006, 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.ui.menus;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.core.commands.Command;
18 import org.eclipse.core.commands.CommandEvent;
19 import org.eclipse.core.commands.ExecutionException;
20 import org.eclipse.core.commands.ICommandListener;
21 import org.eclipse.core.commands.IParameter;
22 import org.eclipse.core.commands.NotEnabledException;
23 import org.eclipse.core.commands.NotHandledException;
24 import org.eclipse.core.commands.Parameterization;
25 import org.eclipse.core.commands.ParameterizedCommand;
26 import org.eclipse.core.commands.common.NotDefinedException;
27 import org.eclipse.jface.action.ContributionItem;
28 import org.eclipse.jface.action.IMenuListener;
29 import org.eclipse.jface.action.IMenuManager;
30 import org.eclipse.jface.action.MenuManager;
31 import org.eclipse.jface.bindings.TriggerSequence;
32 import org.eclipse.jface.resource.ImageDescriptor;
33 import org.eclipse.jface.resource.JFaceResources;
34 import org.eclipse.jface.resource.LocalResourceManager;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.graphics.Rectangle;
38 import org.eclipse.swt.widgets.Event;
39 import org.eclipse.swt.widgets.Listener;
40 import org.eclipse.swt.widgets.Menu;
41 import org.eclipse.swt.widgets.MenuItem;
42 import org.eclipse.swt.widgets.ToolBar;
43 import org.eclipse.swt.widgets.ToolItem;
44 import org.eclipse.swt.widgets.Widget;
45 import org.eclipse.ui.IWorkbenchPartSite;
46 import org.eclipse.ui.IWorkbenchWindow;
47 import org.eclipse.ui.commands.ICommandService;
48 import org.eclipse.ui.commands.IElementReference;
49 import org.eclipse.ui.handlers.IHandlerService;
50 import org.eclipse.ui.internal.WorkbenchPlugin;
51 import org.eclipse.ui.internal.commands.ICommandImageService;
52 import org.eclipse.ui.keys.IBindingService;
53 import org.eclipse.ui.services.IServiceLocator;
54
55 /**
56  * A contribution item which delegates to a command. It can be used in
57  * {@link AbstractContributionFactory#createContributionItems(IServiceLocator, IContributionRoot)}.
58  * <p>
59  * It currently supports placement in menus and toolbars.
60  * </p>
61  * <p>
62  * This class may be instantiated; it is not intended to be subclassed.
63  * </p>
64  *
65  * @since 3.3
66  */

67 public final class CommandContributionItem extends ContributionItem {
68     /**
69      * A push button tool item or menu item.
70      */

71     public static final int STYLE_PUSH = SWT.PUSH;
72
73     /**
74      * A checked tool item or menu item.
75      */

76     public static final int STYLE_CHECK = SWT.CHECK;
77
78     /**
79      * A radio-button style menu item.
80      */

81     public static final int STYLE_RADIO = SWT.RADIO;
82
83     /**
84      * A ToolBar pulldown item.
85      */

86     public static final int STYLE_PULLDOWN = SWT.DROP_DOWN;
87
88     private LocalResourceManager localResourceManager;
89
90     private Listener menuItemListener;
91
92     private Widget widget;
93
94     private IMenuService menuService;
95
96     private ICommandService commandService;
97
98     private IHandlerService handlerService;
99     
100     private IBindingService bindingService;
101
102     private ParameterizedCommand command;
103
104     private ImageDescriptor icon;
105
106     private String JavaDoc label;
107
108     private String JavaDoc tooltip;
109
110     private ImageDescriptor disabledIcon;
111
112     private ImageDescriptor hoverIcon;
113
114     private String JavaDoc mnemonic;
115
116     private IElementReference elementRef;
117
118     private boolean checkedState;
119
120     private int style;
121
122     private ICommandListener commandListener;
123
124     private String JavaDoc dropDownMenuOverride;
125
126     /**
127      * Create a CommandContributionItem to place in a ContributionManager.
128      *
129      * @param serviceLocator
130      * a service locator that is most appropriate for this
131      * contribution. Typically the local {@link IWorkbenchWindow} or
132      * {@link IWorkbenchPartSite} will be sufficient.
133      * @param id
134      * The id for this item. May be <code>null</code>. Items
135      * without an id cannot be referenced later.
136      * @param commandId
137      * A command id for a defined command. Must not be
138      * <code>null</code>.
139      * @param parameters
140      * A map of strings to strings which represent parameter names to
141      * values. The parameter names must match those in the command
142      * definition.
143      * @param icon
144      * An icon for this item. May be <code>null</code>.
145      * @param disabledIcon
146      * A disabled icon for this item. May be <code>null</code>.
147      * @param hoverIcon
148      * A hover icon for this item. May be <code>null</code>.
149      * @param label
150      * A label for this item. May be <code>null</code>.
151      * @param mnemonic
152      * A mnemonic for this item to be applied to the label. May be
153      * <code>null</code>.
154      * @param tooltip
155      * A tooltip for this item. May be <code>null</code>. Tooltips
156      * are currently only valid for toolbar contributions.
157      * @param style
158      * The style of this menu contribution. See the STYLE_* contants.
159      */

160     public CommandContributionItem(IServiceLocator serviceLocator, String JavaDoc id,
161             String JavaDoc commandId, Map JavaDoc parameters, ImageDescriptor icon,
162             ImageDescriptor disabledIcon, ImageDescriptor hoverIcon,
163             String JavaDoc label, String JavaDoc mnemonic, String JavaDoc tooltip, int style) {
164         super(id);
165         this.icon = icon;
166         this.disabledIcon = disabledIcon;
167         this.hoverIcon = hoverIcon;
168         this.label = label;
169         this.mnemonic = mnemonic;
170         this.tooltip = tooltip;
171         this.style = style;
172         menuService = (IMenuService) serviceLocator
173                 .getService(IMenuService.class);
174         commandService = (ICommandService) serviceLocator
175                 .getService(ICommandService.class);
176         handlerService = (IHandlerService) serviceLocator
177                 .getService(IHandlerService.class);
178         bindingService = (IBindingService) serviceLocator
179                 .getService(IBindingService.class);
180         createCommand(commandId, parameters);
181
182         if (command != null) {
183             try {
184                 UIElement callback = new UIElement(serviceLocator) {
185
186                     public void setChecked(boolean checked) {
187                         CommandContributionItem.this.setChecked(checked);
188                     }
189
190                     public void setDisabledIcon(ImageDescriptor desc) {
191                         CommandContributionItem.this.setDisabledIcon(desc);
192                     }
193
194                     public void setHoverIcon(ImageDescriptor desc) {
195                         CommandContributionItem.this.setHoverIcon(desc);
196                     }
197
198                     public void setIcon(ImageDescriptor desc) {
199                         CommandContributionItem.this.setIcon(desc);
200                     }
201
202                     public void setText(String JavaDoc text) {
203                         CommandContributionItem.this.setText(text);
204                     }
205
206                     public void setTooltip(String JavaDoc text) {
207                         CommandContributionItem.this.setTooltip(text);
208                     }
209
210                     public void setDropDownId(String JavaDoc id) {
211                         dropDownMenuOverride = id;
212                     }
213                 };
214                 elementRef = commandService.registerElementForCommand(command,
215                         callback);
216                 command.getCommand().addCommandListener(getCommandListener());
217                 setImages(serviceLocator);
218             } catch (NotDefinedException e) {
219                 WorkbenchPlugin.log("Unable to register menu item \"" + getId() //$NON-NLS-1$
220
+ "\", command \"" + commandId + "\" not defined"); //$NON-NLS-1$ //$NON-NLS-2$
221
}
222         }
223     }
224     
225     private void setImages(IServiceLocator locator) {
226         if (icon == null) {
227             ICommandImageService service = (ICommandImageService) locator
228                     .getService(ICommandImageService.class);
229             icon = service.getImageDescriptor(command.getId(),
230                     ICommandImageService.TYPE_DEFAULT);
231             disabledIcon = service.getImageDescriptor(command.getId(),
232                     ICommandImageService.TYPE_DISABLED);
233             hoverIcon = service.getImageDescriptor(command.getId(),
234                     ICommandImageService.TYPE_HOVER);
235         }
236     }
237
238     /**
239      * @return
240      */

241     private ICommandListener getCommandListener() {
242         if (commandListener == null) {
243             commandListener = new ICommandListener() {
244                 public void commandChanged(CommandEvent commandEvent) {
245                     if (commandEvent.isHandledChanged()
246                             || commandEvent.isEnabledChanged()
247                             || commandEvent.isDefinedChanged()) {
248                         if (commandEvent.isHandledChanged()) {
249                             dropDownMenuOverride = null;
250                         }
251                         if (commandEvent.getCommand().isDefined()) {
252                             update(null);
253                         }
254                     }
255                 }
256             };
257         }
258         return commandListener;
259     }
260
261     ParameterizedCommand getCommand() {
262         return command;
263     }
264
265     void createCommand(String JavaDoc commandId, Map JavaDoc parameters) {
266         if (commandId == null) {
267             WorkbenchPlugin.log("Unable to create menu item \"" + getId() //$NON-NLS-1$
268
+ "\", no command id"); //$NON-NLS-1$
269
return;
270         }
271         Command cmd = commandService.getCommand(commandId);
272         if (!cmd.isDefined()) {
273             WorkbenchPlugin.log("Unable to create menu item \"" + getId() //$NON-NLS-1$
274
+ "\", command \"" + commandId + "\" not defined"); //$NON-NLS-1$ //$NON-NLS-2$
275
return;
276         }
277
278         if (parameters == null || parameters.size() == 0) {
279             command = new ParameterizedCommand(cmd, null);
280             return;
281         }
282
283         try {
284             ArrayList JavaDoc parmList = new ArrayList JavaDoc();
285             Iterator JavaDoc i = parameters.entrySet().iterator();
286             while (i.hasNext()) {
287                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
288                 String JavaDoc parmName = (String JavaDoc) entry.getKey();
289                 IParameter parm;
290                 parm = cmd.getParameter(parmName);
291                 if (parm == null) {
292                     WorkbenchPlugin
293                             .log("Unable to create menu item \"" + getId() //$NON-NLS-1$
294
+ "\", parameter \"" + parmName + "\" for command \"" //$NON-NLS-1$ //$NON-NLS-2$
295
+ commandId + "\" is not defined"); //$NON-NLS-1$
296
return;
297                 }
298                 parmList.add(new Parameterization(parm, (String JavaDoc) entry
299                         .getValue()));
300             }
301             command = new ParameterizedCommand(cmd,
302                     (Parameterization[]) parmList
303                             .toArray(new Parameterization[parmList.size()]));
304         } catch (NotDefinedException e) {
305             // this shouldn't happen as we checked for !defined, but we
306
// won't take the chance
307
WorkbenchPlugin.log("Failed to create menu item " //$NON-NLS-1$
308
+ getId(), e);
309         }
310     }
311
312     /*
313      * (non-Javadoc)
314      *
315      * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.Menu,
316      * int)
317      */

318     public void fill(Menu parent, int index) {
319         if (command == null) {
320             return;
321         }
322         if (widget != null || parent == null) {
323             return;
324         }
325
326         // Menus don't support the pulldown style
327
int tmpStyle = style;
328         if (tmpStyle == STYLE_PULLDOWN)
329             tmpStyle = STYLE_PUSH;
330
331         MenuItem item = null;
332         if (index >= 0) {
333             item = new MenuItem(parent, tmpStyle, index);
334         } else {
335             item = new MenuItem(parent, tmpStyle);
336         }
337         item.setData(this);
338
339         item.addListener(SWT.Dispose, getItemListener());
340         item.addListener(SWT.Selection, getItemListener());
341         widget = item;
342
343         update(null);
344     }
345
346     /*
347      * (non-Javadoc)
348      *
349      * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.ToolBar,
350      * int)
351      */

352     public void fill(ToolBar parent, int index) {
353         if (command == null) {
354             return;
355         }
356         if (widget != null || parent == null) {
357             return;
358         }
359
360         ToolItem item = null;
361         if (index >= 0) {
362             item = new ToolItem(parent, style, index);
363         } else {
364             item = new ToolItem(parent, style);
365         }
366
367         item.setData(this);
368
369         item.addListener(SWT.Selection, getItemListener());
370         item.addListener(SWT.Dispose, getItemListener());
371         widget = item;
372
373         update(null);
374     }
375
376     /*
377      * (non-Javadoc)
378      *
379      * @see org.eclipse.jface.action.ContributionItem#update()
380      */

381     public void update() {
382         update(null);
383     }
384
385     /*
386      * (non-Javadoc)
387      *
388      * @see org.eclipse.jface.action.ContributionItem#update(java.lang.String)
389      */

390     public void update(String JavaDoc id) {
391         if (widget != null) {
392             if (widget instanceof MenuItem) {
393                 MenuItem item = (MenuItem) widget;
394
395                 String JavaDoc text = label;
396                 if (text == null) {
397                     if (command != null) {
398                         try {
399                             text = command.getCommand().getName();
400                         } catch (NotDefinedException e) {
401                             WorkbenchPlugin.log("Update item failed " //$NON-NLS-1$
402
+ getId(), e);
403                         }
404                     }
405                 }
406                 text = updateMnemonic(text);
407
408                 String JavaDoc keyBindingText = null;
409                 if (command != null) {
410                     TriggerSequence[] bindings = bindingService
411                             .getActiveBindingsFor(command);
412                     if (bindings.length > 0) {
413                         keyBindingText = bindings[0].format();
414                     }
415                 }
416                 if (text != null) {
417                     if (keyBindingText == null) {
418                         item.setText(text);
419                     } else {
420                         item.setText(text + '\t' + keyBindingText);
421                     }
422                 }
423
424                 updateIcons();
425                 if (item.getSelection() != checkedState) {
426                     item.setSelection(checkedState);
427                 }
428
429                 boolean shouldBeEnabled = isEnabled();
430                 if (item.getEnabled() != shouldBeEnabled) {
431                     item.setEnabled(shouldBeEnabled);
432                 }
433             } else if (widget instanceof ToolItem) {
434                 ToolItem item = (ToolItem) widget;
435
436                 if (icon != null) {
437                     updateIcons();
438                 } else if (label != null) {
439                     item.setText(label);
440                 }
441
442                 if (tooltip != null)
443                     item.setToolTipText(tooltip);
444                 else {
445                     String JavaDoc text = label;
446                     if (text == null) {
447                         if (command != null) {
448                             try {
449                                 text = command.getCommand().getName();
450                             } catch (NotDefinedException e) {
451                                 WorkbenchPlugin.log("Update item failed " //$NON-NLS-1$
452
+ getId(), e);
453                             }
454                         }
455                     }
456                     if (text != null) {
457                         item.setToolTipText(text);
458                     }
459                 }
460
461                 if (item.getSelection() != checkedState) {
462                     item.setSelection(checkedState);
463                 }
464
465                 boolean shouldBeEnabled = isEnabled();
466                 if (item.getEnabled() != shouldBeEnabled) {
467                     item.setEnabled(shouldBeEnabled);
468                 }
469             }
470         }
471     }
472     
473     private String JavaDoc updateMnemonic(String JavaDoc s) {
474         if (mnemonic==null || s==null) {
475             return s;
476         }
477         int idx = s.indexOf(mnemonic);
478         if (idx==-1) {
479             return s;
480         }
481         
482         return s.substring(0, idx) + '&' + s.substring(idx);
483     }
484
485     private void handleWidgetDispose(Event event) {
486         if (event.widget == widget) {
487             widget.removeListener(SWT.Selection, getItemListener());
488             widget.removeListener(SWT.Dispose, getItemListener());
489             widget = null;
490             disposeOldImages();
491         }
492     }
493
494     /*
495      * (non-Javadoc)
496      *
497      * @see org.eclipse.jface.action.ContributionItem#dispose()
498      */

499     public void dispose() {
500         if (elementRef != null) {
501             commandService.unregisterElement(elementRef);
502             elementRef = null;
503         }
504         if (commandListener != null) {
505             command.getCommand().removeCommandListener(commandListener);
506             commandListener = null;
507         }
508         command = null;
509         commandService = null;
510         disposeOldImages();
511         super.dispose();
512     }
513
514     private void disposeOldImages() {
515         if (localResourceManager != null) {
516             localResourceManager.dispose();
517             localResourceManager = null;
518         }
519     }
520
521     private Listener getItemListener() {
522         if (menuItemListener == null) {
523             menuItemListener = new Listener() {
524                 public void handleEvent(Event event) {
525                     switch (event.type) {
526                     case SWT.Dispose:
527                         handleWidgetDispose(event);
528                         break;
529                     case SWT.Selection:
530                         if (event.widget != null) {
531                             handleWidgetSelection(event);
532                         }
533                         break;
534                     }
535                 }
536             };
537         }
538         return menuItemListener;
539     }
540
541     private void handleWidgetSelection(Event event) {
542         // Special check for ToolBar dropdowns...
543
if (openDropDownMenu(event))
544             return;
545
546         if ((style & (SWT.TOGGLE | SWT.CHECK)) != 0) {
547             if (event.widget instanceof ToolItem) {
548                 checkedState = ((ToolItem)event.widget).getSelection();
549             } else if (event.widget instanceof MenuItem) {
550                 checkedState = ((MenuItem)event.widget).getSelection();
551             }
552         }
553         
554         try {
555             handlerService.executeCommand(command, event);
556         } catch (ExecutionException e) {
557             WorkbenchPlugin.log("Failed to execute item " //$NON-NLS-1$
558
+ getId(), e);
559         } catch (NotDefinedException e) {
560             WorkbenchPlugin.log("Failed to execute item " //$NON-NLS-1$
561
+ getId(), e);
562         } catch (NotEnabledException e) {
563             WorkbenchPlugin.log("Failed to execute item " //$NON-NLS-1$
564
+ getId(), e);
565         } catch (NotHandledException e) {
566             WorkbenchPlugin.log("Failed to execute item " //$NON-NLS-1$
567
+ getId(), e);
568         }
569     }
570
571     /**
572      * Determines if the selection was on the dropdown affordance and, if so,
573      * opens the drop down menu (populated using the same id as this item...
574      *
575      * @param event
576      * The <code>SWT.Selection</code> event to be tested
577      *
578      * @return <code>true</code> iff a drop down menu was opened
579      */

580     private boolean openDropDownMenu(Event event) {
581         Widget item = event.widget;
582         if (item != null) {
583             int style = item.getStyle();
584             if ((style & SWT.DROP_DOWN) != 0) {
585                 if (event.detail == 4) { // on drop-down button
586
ToolItem ti = (ToolItem) item;
587
588                     final MenuManager menuManager = new MenuManager();
589                     Menu menu = menuManager.createContextMenu(ti.getParent());
590                     menuManager.addMenuListener(new IMenuListener() {
591                         public void menuAboutToShow(IMenuManager manager) {
592                             String JavaDoc id = getId();
593                             if (dropDownMenuOverride != null) {
594                                 id = dropDownMenuOverride;
595                             }
596                             menuService.populateContributionManager(
597                                     menuManager, "menu:" + id); //$NON-NLS-1$
598
}
599                     });
600                     
601                     // position the menu below the drop down item
602
Rectangle b = ti.getBounds();
603                     Point p = ti.getParent().toDisplay(
604                             new Point(b.x, b.y + b.height));
605                     menu.setLocation(p.x, p.y); // waiting for SWT
606
// 0.42
607
menu.setVisible(true);
608                     return true; // we don't fire the action
609
}
610             }
611         }
612
613         return false;
614     }
615
616     private void setIcon(ImageDescriptor desc) {
617         icon = desc;
618         updateIcons();
619     }
620
621     private void updateIcons() {
622         if (widget instanceof MenuItem) {
623             MenuItem item = (MenuItem) widget;
624             LocalResourceManager m = new LocalResourceManager(JFaceResources
625                     .getResources());
626             item.setImage(icon == null ? null : m.createImage(icon));
627             disposeOldImages();
628             localResourceManager = m;
629         } else if (widget instanceof ToolItem) {
630             ToolItem item = (ToolItem) widget;
631             LocalResourceManager m = new LocalResourceManager(JFaceResources
632                     .getResources());
633             item.setDisabledImage(disabledIcon == null ? null : m
634                     .createImage(disabledIcon));
635             item.setHotImage(hoverIcon == null ? null : m
636                     .createImage(hoverIcon));
637             item.setImage(icon == null ? null : m.createImage(icon));
638             disposeOldImages();
639             localResourceManager = m;
640         }
641     }
642
643     private void setText(String JavaDoc text) {
644         label = text;
645         update(null);
646     }
647
648     private void setChecked(boolean checked) {
649         if (checkedState == checked) {
650             return;
651         }
652         checkedState = checked;
653         if (widget instanceof MenuItem) {
654             ((MenuItem) widget).setSelection(checkedState);
655         } else if (widget instanceof ToolItem) {
656             ((ToolItem) widget).setSelection(checkedState);
657         }
658     }
659
660     private void setTooltip(String JavaDoc text) {
661         tooltip = text;
662         if (widget instanceof ToolItem) {
663             ((ToolItem) widget).setToolTipText(text);
664         }
665     }
666
667     private void setDisabledIcon(ImageDescriptor desc) {
668         disabledIcon = desc;
669         updateIcons();
670     }
671
672     private void setHoverIcon(ImageDescriptor desc) {
673         hoverIcon = desc;
674         updateIcons();
675     }
676
677     /*
678      * (non-Javadoc)
679      *
680      * @see org.eclipse.jface.action.ContributionItem#isEnabled()
681      */

682     public boolean isEnabled() {
683         if (command != null) {
684             return command.getCommand().isEnabled();
685         }
686         return false;
687     }
688 }
689
Popular Tags