]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.ui/src/org/simantics/ui/toolbar/ToolbarContributor.java
Sync git svn branch with SVN repository r33198.
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / toolbar / ToolbarContributor.java
1 package org.simantics.ui.toolbar;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.HashMap;\r
5 import java.util.HashSet;\r
6 import java.util.List;\r
7 import java.util.Map;\r
8 import java.util.Set;\r
9 \r
10 import org.eclipse.core.commands.Command;\r
11 import org.eclipse.core.commands.CommandEvent;\r
12 import org.eclipse.core.commands.ExecutionException;\r
13 import org.eclipse.core.commands.ICommandListener;\r
14 import org.eclipse.core.commands.IParameter;\r
15 import org.eclipse.core.commands.Parameterization;\r
16 import org.eclipse.core.commands.ParameterizedCommand;\r
17 import org.eclipse.core.commands.State;\r
18 import org.eclipse.core.runtime.CoreException;\r
19 import org.eclipse.core.runtime.IConfigurationElement;\r
20 import org.eclipse.core.runtime.IExecutableExtension;\r
21 import org.eclipse.jface.action.Action;\r
22 import org.eclipse.jface.action.ActionContributionItem;\r
23 import org.eclipse.jface.action.IContributionItem;\r
24 import org.eclipse.jface.action.ICoolBarManager;\r
25 import org.eclipse.jface.action.IToolBarManager;\r
26 import org.eclipse.jface.action.ToolBarContributionItem;\r
27 import org.eclipse.jface.resource.ImageDescriptor;\r
28 import org.eclipse.nebula.widgets.tablecombo.TableCombo;\r
29 import org.eclipse.swt.SWT;\r
30 import org.eclipse.swt.events.SelectionEvent;\r
31 import org.eclipse.swt.events.SelectionListener;\r
32 import org.eclipse.swt.layout.GridData;\r
33 import org.eclipse.swt.layout.GridLayout;\r
34 import org.eclipse.swt.widgets.Composite;\r
35 import org.eclipse.swt.widgets.Control;\r
36 import org.eclipse.swt.widgets.TableItem;\r
37 import org.eclipse.ui.IEditorPart;\r
38 import org.eclipse.ui.IPartListener;\r
39 import org.eclipse.ui.IWorkbenchPart;\r
40 import org.eclipse.ui.PlatformUI;\r
41 import org.eclipse.ui.commands.ICommandService;\r
42 import org.eclipse.ui.handlers.HandlerUtil;\r
43 import org.eclipse.ui.handlers.IHandlerService;\r
44 import org.eclipse.ui.handlers.RadioState;\r
45 import org.eclipse.ui.handlers.RegistryToggleState;\r
46 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;\r
47 import org.eclipse.ui.part.EditorActionBarContributor;\r
48 import org.simantics.db.common.utils.Logger;\r
49 import org.simantics.ui.internal.Activator;\r
50 import org.simantics.ui.toolbar.ToolBarCommandRegistry.Parameter;\r
51 import org.simantics.ui.toolbar.ToolBarCommandRegistry.ToolbarCommandExtension;\r
52 import org.simantics.utils.datastructures.MapList;\r
53 import org.simantics.utils.ui.ExceptionUtils;\r
54 \r
55 \r
56 /**\r
57  * EditorBarContributor, which tracks toggle states separately for each command.\r
58  * \r
59  * @see org.simantics.g3d.toolbarCommand Extension Point\r
60  * \r
61  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
62  * \r
63  * \r
64  * \r
65  * TODO : configuring the position of buttons. \r
66  *\r
67  */\r
68 public class ToolbarContributor extends EditorActionBarContributor implements ICommandListener, IPartListener, CommandStateListener, IExecutableExtension {\r
69 \r
70         private static boolean DEBUG = false;                   // Print debug messages to console\r
71         private boolean REUSE = true;                           // true: Reuse contribution items (leave toolbar in disabled state when editor closes)\r
72                                                         // false: delete items on dispose (remove toolbar editor closes) \r
73         \r
74         private static final String PLATFORM = "platform:/plugin/";\r
75 \r
76         private String toolbarId;\r
77         \r
78         private IEditorPart    activePart;\r
79         private Set<IEditorPart> parts = new HashSet<IEditorPart>();\r
80     IToolBarManager        mgr;\r
81     \r
82     \r
83     ICommandService service;\r
84     IHandlerService handlerService;\r
85     List<IContributionItem> items = new ArrayList<IContributionItem>();\r
86     MapList<String, CommandAction> actions = new MapList<String, ToolbarContributor.CommandAction>();\r
87     \r
88     CommandStateRegistry stateRegistry;\r
89     \r
90     IPartListener partListener;\r
91         \r
92         private Map<String,ComboContribution> menus = new HashMap<String, ComboContribution>();\r
93         \r
94         public ToolbarContributor() {\r
95                 service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); \r
96                 handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);\r
97                 stateRegistry = CommandStateRegistry.getInstance();\r
98                 // we need part listener to be notified for other editor activations (i.e editors that do not use this contributor).\r
99                 partListener = new IPartListener() {\r
100                         \r
101                         @Override\r
102                         public void partOpened(IWorkbenchPart part) {}\r
103                         \r
104                         @Override\r
105                         public void partDeactivated(IWorkbenchPart part) {}\r
106                         \r
107                         @Override\r
108                         public void partClosed(IWorkbenchPart part) {}\r
109                         \r
110                         @Override\r
111                         public void partBroughtToTop(IWorkbenchPart part) {}\r
112                         \r
113                         @Override\r
114                         public void partActivated(IWorkbenchPart part) {\r
115                                 if (part instanceof IEditorPart)\r
116                                         setContext2((IEditorPart)part);\r
117                         }\r
118                 };\r
119                 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);\r
120                 \r
121         }\r
122         \r
123         @Override\r
124         public void setInitializationData(IConfigurationElement config,String propertyName, Object data) throws CoreException {\r
125                 if (data instanceof String) {\r
126                          String[] parameters = ((String) data).split(";");\r
127                          for (String parameter : parameters) {\r
128                         String[] keyValue = parameter.split("=");\r
129                         if (keyValue.length > 2) {\r
130                             //ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);\r
131                             continue;\r
132                         }\r
133                         String key = keyValue[0];\r
134                         String value = keyValue.length > 1 ? keyValue[1] : "";\r
135 \r
136                         if ("toolbar".equals(key)) {\r
137                             toolbarId = value;\r
138                         }  else if ("hide".equals(key)) {\r
139                                 REUSE = !Boolean.parseBoolean(value);\r
140                         }\r
141                     }\r
142                 }\r
143                 \r
144         }\r
145         \r
146         public String getToolbarId() {\r
147                 return toolbarId;\r
148         }\r
149         \r
150         \r
151         private ICoolBarManager coolBarManager;\r
152         private IContributionItem toolBar;\r
153         public void contributeToCoolBar(ICoolBarManager coolBarManager) {\r
154                 this.coolBarManager = coolBarManager;\r
155                 toolBar = coolBarManager.find(getToolbarId());\r
156                 \r
157                  if (toolBar instanceof ToolBarContributionItem)\r
158                  mgr = ((ToolBarContributionItem) toolBar).getToolBarManager();\r
159              if (mgr == null)\r
160                     return;\r
161              \r
162              createCommands();\r
163              \r
164              mgr.markDirty();\r
165              \r
166         }\r
167         \r
168         private void createCommands() {\r
169                 for (ToolbarCommandExtension ext : ToolBarCommandRegistry.getInstance().getExtensions(getToolbarId())) {\r
170                         addCommand(ext);\r
171                 }\r
172         }\r
173         \r
174         private void addCommand(ToolbarCommandExtension ext) {\r
175                 if (DEBUG) System.out.println("Adding command to toolbar " +getToolbarId()  + " " + ext);\r
176                 String commandId = ext.commandId;\r
177                 Command command = service.getCommand(commandId);\r
178                 ICommandWrapper wrapper = new CommandWrapper(command);\r
179                 \r
180                 ParameterizedCommand parameterizedCommand = null;\r
181                 \r
182                 if (ext.parameters.size() > 0) {\r
183                         try {\r
184                                 Parameterization parameterizations[] = new Parameterization[ext.parameters.size()];\r
185                                 for (int i = 0; i < ext.parameters.size(); i++) {\r
186                                         Parameter param = ext.parameters.get(i);\r
187                                         IParameter parameter = command.getParameter(param.name);\r
188                                         parameterizations[i] = new Parameterization(parameter, param.value);\r
189                                 }\r
190                                 parameterizedCommand = new ParameterizedCommand(command, parameterizations);\r
191                                 wrapper = new ParameterizedCommandWrapper(parameterizedCommand);\r
192                         } catch (org.eclipse.core.commands.common.NotDefinedException e) {\r
193                                 e.printStackTrace();\r
194                                 ExceptionUtils.logError(e);\r
195                                 return;\r
196                         }\r
197                 }\r
198                 \r
199                 String type = ext.type;\r
200                 \r
201                 State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
202                 State radioState = command.getState(RadioState.STATE_ID);\r
203                 \r
204                 String name = ext.name;\r
205                 \r
206                 \r
207                 ImageDescriptor image = getImage(ext);\r
208                 \r
209                 CommandAction a = null;\r
210                 if (type.equals("toggle") && toggleState != null) {\r
211                         a = new CommandCheckboxAction(wrapper,name,image);\r
212 \r
213                         stateRegistry.storeDefaultState(commandId);\r
214                 } else if (radioState != null && ext.value != null) {\r
215                         stateRegistry.storeDefaultState(commandId);\r
216                         if (type.equals("radio")) {\r
217                                 a = new CommandRadioAction(wrapper,name,ext.value,image);\r
218                         } else if (type.equals("combo")) {\r
219                                 a = new CommandRadioAction(wrapper,name,ext.value,image);\r
220                                 ComboContribution combo = menus.get(commandId);\r
221                                 if (REUSE && combo == null) {\r
222                                         combo = (ComboContribution)mgr.find(commandId);\r
223                                         if (combo != null) {\r
224                                                 menus.put(commandId, combo);\r
225                                                 items.add(combo);\r
226                                                 a.getCommand().addCommandListener(this);\r
227                                                 CommandStateRegistry.getInstance().addListener(commandId, this);\r
228                                         }\r
229                                 }\r
230                                 if (combo == null) {\r
231                                         combo = new ComboContribution();\r
232                                         combo.setId(commandId);\r
233                                         menus.put(commandId, combo);\r
234                                         items.add(combo);\r
235                                         mgr.add(combo);\r
236                                         a.getCommand().addCommandListener(this);\r
237                                         CommandStateRegistry.getInstance().addListener(commandId, this);\r
238                                 }\r
239                                 actions.add(commandId,a);\r
240                                 combo.addAction(a);\r
241                                 return;\r
242                         }\r
243                 } else if (type.equals("push")) {\r
244                         a = new CommandPushAction(wrapper,name,image);\r
245                 } else {\r
246                         if (DEBUG) System.out.println(ext + " is not valid.");\r
247                         Logger.defaultLogError(ext + " is not valid.");\r
248                         return;\r
249                 }\r
250                 IContributionItem item = null;\r
251                 if (REUSE) {\r
252                         String id = commandId;\r
253                         if (ext.value != null)\r
254                                 id += "."+ext.value;\r
255                         item = mgr.find(id);\r
256                         if (item == null) {\r
257                                 item =  new ActionContributionItem(a);\r
258                                 ((ActionContributionItem)item).setId(id);\r
259                         } else {\r
260                                 if (DEBUG) System.out.println("Reusing " + ext);\r
261                                 a = (CommandAction)((ActionContributionItem)item).getAction();\r
262                         }\r
263                 } else {\r
264                         item =  new ActionContributionItem(a);\r
265                 }\r
266                 a.getCommand().addCommandListener(this);\r
267                 actions.add(commandId,a);\r
268                 items.add(item);\r
269                 mgr.add(item);\r
270                 CommandStateRegistry.getInstance().addListener(commandId, this);\r
271         }\r
272         \r
273         private ImageDescriptor getImage(ToolbarCommandExtension ext) {\r
274                 ImageDescriptor image = null;\r
275                 if (ext.image != null) {\r
276                         String plugin = null;\r
277                         String file = null;\r
278                         if (ext.image.startsWith(PLATFORM)) {\r
279                                 String s = ext.image.substring(PLATFORM.length());\r
280                                 int i = s.indexOf("/");\r
281                                 plugin = s.substring(0,i);\r
282                                 file = s.substring(i+1);\r
283                         } else {\r
284                                 plugin = ext.contributorId;\r
285                                 file = ext.image;\r
286                         }\r
287                         image = Activator.imageDescriptorFromPlugin(plugin, file);\r
288                 }\r
289                 return image;\r
290         }\r
291         \r
292 \r
293         \r
294         @Override\r
295         public void commandChanged(CommandEvent commandEvent) {\r
296                 if (commandEvent.isHandledChanged()||commandEvent.isEnabledChanged()) {\r
297                         Command command = commandEvent.getCommand();\r
298                         String commandId = command.getId();\r
299                         for (CommandAction a : actions.getValues(commandId)) {\r
300                                 a.setEnabled(command.isHandled() && command.isEnabled());\r
301                         }\r
302                 }\r
303         }\r
304         \r
305         @Override\r
306         public void setActiveEditor(IEditorPart targetEditor) {\r
307                 if (targetEditor == activePart)\r
308                         return;\r
309                 setContext(targetEditor);\r
310         }\r
311         \r
312         @Override\r
313         public void stateChanged(IWorkbenchPart part, String commandId, String state) {\r
314                 // TODO : update only given command\r
315                 if (settingState)\r
316                         return;\r
317                 if (part instanceof IEditorPart)\r
318                         setContext((IEditorPart)part);\r
319         }\r
320         \r
321         private void setContext2(IEditorPart part) {\r
322                 if (REUSE)\r
323                         return;\r
324                 if (this.activePart == part)\r
325                         return;\r
326                 setContext(null);\r
327         }\r
328         \r
329         private void setContext(IEditorPart part) {\r
330                 this.activePart = part;\r
331         if (activePart != null && !parts.contains(activePart)) {\r
332                 activePart.getSite().getPage().addPartListener(this);\r
333         }\r
334         if (part != null) {\r
335                 for (String commandId : actions.getKeys()) {\r
336                                 for (CommandAction a : actions.getValues(commandId)) {\r
337                                         a.setEnabled(true);\r
338                                 }\r
339                                 ComboContribution menu = menus.get(commandId);\r
340                                 if (menu != null) {\r
341                                         menu.setEnabled(true);\r
342                                 }\r
343                         }\r
344             updateActionBars(part);\r
345         } else {\r
346                         for (String commandId : actions.getKeys()) {\r
347                                 for (CommandAction a : actions.getValues(commandId)) {\r
348                                         a.setEnabled(false);\r
349                                 }\r
350                                 ComboContribution menu = menus.get(commandId);\r
351                                 if (menu != null) {\r
352                                         menu.setEnabled(false);\r
353                                 }\r
354                                 \r
355                         }\r
356         }\r
357     }\r
358 \r
359     private void updateActionBars(IEditorPart part) {\r
360         restoreActionStates();\r
361         part.getEditorSite().getActionBars().updateActionBars();\r
362     }\r
363         \r
364         @Override\r
365         public void dispose() {\r
366                 if (DEBUG) System.out.println("ToolBarContributor.dispose()");\r
367                 setActiveEditor(null);\r
368                 if (mgr != null) {\r
369                         if (!REUSE) {\r
370                                 for (IContributionItem item : items) {\r
371                                         mgr.remove(item);\r
372                                         item.dispose();\r
373                                 }\r
374                         }\r
375                         items.clear();\r
376                         \r
377                         for (String commandId : actions.getKeys()) {\r
378                                 for (CommandAction a : actions.getValues(commandId)) {\r
379                                         a.getCommand().removeCommandListener(this);\r
380                                 }\r
381                                 \r
382                         }\r
383                         actions.clear();\r
384                         \r
385                         // without this the contributed toolbar widgets would continue reserve the space even when they are destroyed.\r
386                         coolBarManager.update(true);\r
387                         mgr.update(true);\r
388                 }\r
389                 CommandStateRegistry.getInstance().removeListener(this);\r
390                 super.dispose();\r
391                 activePart = null;\r
392                 if (partListener != null) {\r
393                         PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);\r
394                         partListener = null;\r
395                 }\r
396         }\r
397         \r
398         boolean settingState = false;\r
399         private void storeRadioActionState(CommandRadioAction action, boolean checked) {\r
400                 if (activePart == null)\r
401                         return;\r
402                 settingState = true;\r
403                 stateRegistry.setEditorState(activePart, action.getCommandId(), action.getValue());\r
404                 settingState = false;\r
405         }\r
406         \r
407         private void storeToggleActionState(CommandAction action, boolean checked) {\r
408                 if (activePart == null)\r
409                         return;\r
410                 settingState = true;\r
411                 stateRegistry.setEditorState(activePart, action.getCommandId(), checked);\r
412                 settingState = false;\r
413         }\r
414         \r
415         \r
416         \r
417         private void restoreActionStates() {\r
418                 if (activePart == null)\r
419                         return;\r
420                 if (DEBUG)System.out.println("Restore " + activePart);\r
421                 // toggles\r
422                 Map<String,Boolean> defaultToggleStates = stateRegistry.getDefaultToggleStates();\r
423                 for (String commandId : defaultToggleStates.keySet()) {\r
424                         for (CommandAction a : actions.getValues(commandId)) {\r
425                                 if (DEBUG)System.out.println(commandId + " def " + defaultToggleStates.get(commandId));\r
426                                 a.setChecked(defaultToggleStates.get(commandId));\r
427                         }\r
428                 }\r
429                 Map<String,Boolean> editorStates = stateRegistry.getEditorToggleStates(activePart);//toggleStates.get(activePart);\r
430                 if (editorStates != null) {\r
431                         for (String commandId : editorStates.keySet()) {\r
432                                 for (CommandAction a : actions.getValues(commandId)) {\r
433                                         if (DEBUG)System.out.println(commandId + " " + editorStates.get(commandId));\r
434                                         a.setChecked(editorStates.get(commandId));\r
435                                 }\r
436                         }\r
437                 }\r
438                 // radios\r
439                 Map<String,String> defaultRadioStates = stateRegistry.getDefaultRadioStates();\r
440                 for (String commandId : defaultRadioStates.keySet()) {\r
441                         String defaultValue = defaultRadioStates.get(commandId);\r
442                         for (CommandAction a : actions.getValues(commandId)) {\r
443                                 CommandRadioAction r = (CommandRadioAction)a;\r
444                                 if (DEBUG)System.out.println(commandId + " def " + r.getValue().equals(defaultValue) +" " + r.getValue());\r
445                                 r.setChecked(r.getValue().equals(defaultValue));\r
446                         }\r
447                 }\r
448                 \r
449                 Map<String,String> editorRadioStates = stateRegistry.getEditorRadioStates(activePart);//radioStates.get(activePart);\r
450                 if (editorRadioStates != null) {\r
451                         for (String commandId : editorRadioStates.keySet()) {\r
452                                 String defaultValue = editorRadioStates.get(commandId);\r
453                                 for (CommandAction a : actions.getValues(commandId)) {\r
454                                         CommandRadioAction r = (CommandRadioAction)a;\r
455                                         if (DEBUG)System.out.println(commandId + " " + r.getValue().equals(defaultValue) +" " + r.getValue());\r
456                                         r.setChecked(r.getValue().equals(defaultValue));\r
457                                 }\r
458                         }\r
459                 }\r
460                 \r
461                 for (ComboContribution c : menus.values()) {\r
462                         c.updateSelection();\r
463                 }\r
464 \r
465         }\r
466         \r
467         @Override\r
468         public void partActivated(IWorkbenchPart part) {\r
469 \r
470         }\r
471         \r
472         @Override\r
473         public void partBroughtToTop(IWorkbenchPart part) {\r
474                 \r
475         }\r
476         \r
477         @Override\r
478         public void partClosed(IWorkbenchPart part) {\r
479                 parts.remove(part);\r
480                 stateRegistry.clearStates(part);\r
481                 part.getSite().getPage().removePartListener(this);\r
482                 if (parts.size() == 0) {\r
483                         \r
484                 }\r
485                 if (part instanceof IEditorPart)\r
486                         ((IEditorPart)part).getEditorSite().getActionBars().updateActionBars();\r
487                 \r
488         }\r
489         \r
490         @Override\r
491         public void partDeactivated(IWorkbenchPart part) {\r
492                 \r
493         }\r
494         \r
495         @Override\r
496         public void partOpened(IWorkbenchPart part) {\r
497                 \r
498         }\r
499         \r
500         private boolean getToggleState(Command command) {\r
501                 State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
502                 return (Boolean)toggleState.getValue();\r
503         }\r
504         \r
505         private interface ICommandWrapper {\r
506                 \r
507                 public Command getCommand();\r
508                 public String getCommandId();\r
509                 public void run();\r
510         }\r
511         \r
512         private class CommandWrapper implements ICommandWrapper{\r
513                 private Command command;\r
514                 \r
515                 public CommandWrapper(Command command) {\r
516                         this.command = command;\r
517                 }\r
518                 \r
519                 @Override\r
520                 public Command getCommand() {\r
521                         return command;\r
522                 }\r
523                 \r
524                 @Override\r
525                 public String getCommandId() {\r
526                         return command.getId();\r
527                 }\r
528                 \r
529                 @Override\r
530                 public void run() {\r
531                         try {\r
532                                 handlerService.executeCommand(command.getId(), null);\r
533                         } catch (Exception e) {\r
534                                 e.printStackTrace();\r
535                         }\r
536                 }\r
537                 \r
538                 @Override\r
539                 public boolean equals(Object obj) {\r
540                         if (obj.getClass() != getClass())\r
541                                 return false;\r
542                         CommandWrapper other= (CommandWrapper)obj;\r
543                         return other.getCommandId().equals(getCommandId());\r
544                 }\r
545         }\r
546         \r
547         private class ParameterizedCommandWrapper implements ICommandWrapper{\r
548                 private ParameterizedCommand command;\r
549                 \r
550                 public ParameterizedCommandWrapper(ParameterizedCommand command) {\r
551                         this.command = command;\r
552                 }\r
553                 \r
554                 @Override\r
555                 public Command getCommand() {\r
556                         return command.getCommand();\r
557                 }\r
558                 \r
559                 @Override\r
560                 public String getCommandId() {\r
561                         return command.getId();\r
562                 }\r
563                 \r
564                 @Override\r
565                 public void run() {\r
566                         try {\r
567                                 handlerService.executeCommand(command, null);\r
568                         } catch (Exception e) {\r
569                                 e.printStackTrace();\r
570                         }\r
571                 }\r
572                 \r
573                 @Override\r
574                 public boolean equals(Object obj) {\r
575                         if (obj.getClass() != getClass())\r
576                                 return false;\r
577                         ParameterizedCommandWrapper other= (ParameterizedCommandWrapper)obj;\r
578                         return other.command.equals(command);\r
579                 }\r
580         }\r
581         \r
582         private abstract class CommandAction extends Action {\r
583                 private ICommandWrapper command;\r
584                 \r
585                 public CommandAction(ICommandWrapper command, String name, ImageDescriptor image, int style) {\r
586                         super(name,style);\r
587                         this.command = command;\r
588                         if (image != null)\r
589                                 setImageDescriptor(image);\r
590                 }\r
591                 \r
592                 @Override\r
593                 public void run() {\r
594                         command.run();\r
595                 }\r
596                 \r
597                 public Command getCommand() {\r
598                         return command.getCommand();\r
599                 }\r
600                 \r
601                 public String getCommandId() {\r
602                         return command.getCommandId();\r
603                 }\r
604                 \r
605 \r
606                 @Override\r
607                 public boolean equals(Object obj) {\r
608                         if (obj.getClass() != getClass())\r
609                                 return false;\r
610                         CommandAction other= (CommandAction)obj;\r
611                         return command.equals(other.command);\r
612                 }\r
613 \r
614                 \r
615                 @Override\r
616                 public int hashCode() {\r
617                         return command.getCommandId().hashCode();\r
618                 }\r
619         }\r
620         \r
621         \r
622         private class CommandCheckboxAction extends CommandAction {\r
623                 \r
624                 public CommandCheckboxAction(ICommandWrapper command, String name, ImageDescriptor image) {\r
625                         super(command,name,image,Action.AS_CHECK_BOX);\r
626                         \r
627                 }\r
628                 \r
629                 @Override\r
630                 public void run() {\r
631                         boolean checked = isChecked(); \r
632                         storeToggleActionState(this, checked);\r
633                         try {\r
634                                 if (checked == getToggleState(getCommand()))\r
635                                         HandlerUtil.toggleCommandState(getCommand());\r
636                         } catch (ExecutionException e) {\r
637                                 e.printStackTrace();\r
638                         }\r
639                         super.run();\r
640                 }\r
641                 \r
642         }\r
643         \r
644         private class CommandRadioAction extends CommandAction {\r
645 \r
646                 private String value;\r
647                 \r
648                 public CommandRadioAction(ICommandWrapper command, String name, String value, ImageDescriptor image) {\r
649                         super(command,name,image,Action.AS_RADIO_BUTTON);\r
650                         this.value = value;\r
651                 }\r
652                 \r
653                 @Override\r
654                 public void run() {\r
655                         boolean checked = isChecked(); \r
656                         storeRadioActionState(this, checked);\r
657                         try {\r
658                                 HandlerUtil.updateRadioState(getCommand(), value);\r
659                         } catch (ExecutionException e) {\r
660                                 e.printStackTrace();\r
661                                 return;\r
662                         }\r
663                         super.run();\r
664                 }\r
665                 \r
666                 public String getValue() {\r
667                         return value;\r
668                 }\r
669                 \r
670                 @Override\r
671                 public boolean equals(Object obj) {\r
672                         if (obj.getClass() != getClass())\r
673                                 return false;\r
674                         CommandRadioAction other= (CommandRadioAction)obj;\r
675                         if (!other.getCommandId().equals(getCommandId()))\r
676                                 return false;\r
677                         if (!other.value.equals(value))\r
678                                 return false;\r
679                         return true;\r
680                 }\r
681                 \r
682         }\r
683 \r
684         private class CommandPushAction extends CommandAction {\r
685                 \r
686                 public CommandPushAction(ICommandWrapper command, String name, ImageDescriptor image) {\r
687                         super(command,name,image,Action.AS_PUSH_BUTTON);\r
688                 }\r
689 \r
690         }\r
691         \r
692         private class ComboContribution extends WorkbenchWindowControlContribution {\r
693                 private TableCombo combo;\r
694                 \r
695                 private List<Action> actions = new ArrayList<Action>();\r
696                 \r
697                 @Override\r
698                 protected Control createControl(Composite parent) {\r
699                         Composite container = new Composite(parent, SWT.NONE);\r
700                         GridLayout glContainer = new GridLayout(1, false);\r
701                         glContainer.marginTop = 0;\r
702                         glContainer.marginHeight = 0;\r
703                         glContainer.marginWidth = 0;\r
704                         container.setLayout(glContainer);\r
705                         GridData glReader = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);\r
706                         combo = new TableCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
707                         combo.setLayoutData(glReader);\r
708 \r
709                         for (Action a : actions) {\r
710                                 TableItem item = new TableItem(combo.getTable(), SWT.NONE);\r
711                                 item.setText(a.getText());\r
712                                 if (a.getImageDescriptor() != null)\r
713                                         item.setImage(a.getImageDescriptor().createImage());\r
714                         }\r
715                         \r
716                         combo.addSelectionListener(new SelectionListener() {\r
717                                 \r
718                                 @Override\r
719                                 public void widgetSelected(SelectionEvent e) {\r
720                                         int index = combo.getSelectionIndex();\r
721                                         if (index == -1)\r
722                                                 return;\r
723                                         actions.get(index).run();\r
724                                 }\r
725                                 \r
726                                 @Override\r
727                                 public void widgetDefaultSelected(SelectionEvent e) {\r
728                                         \r
729                                 }\r
730                         });\r
731                         updateSelection();\r
732                         return container;\r
733                 }\r
734                 \r
735                 public boolean addAction(Action a) {\r
736                         // old action must be replaced. (otherwise reused ComboContributor would use different instances to ToolBarContributor.) \r
737                         actions.remove(a);\r
738                         actions.add(a);\r
739                         return true;\r
740                         \r
741                 }\r
742                 \r
743                 void updateSelection() {\r
744                         if (combo == null)\r
745                                 return;\r
746                         for (int i = 0; i < actions.size(); i++) {\r
747                                 if (actions.get(i).isChecked()) {\r
748                                         combo.select(i);\r
749                                         return;\r
750                                 }\r
751                         }\r
752                 }\r
753                 \r
754                 public void setEnabled(boolean enabled) {\r
755                         if (combo != null)\r
756                                 combo.setEnabled(enabled);\r
757                 }\r
758                 \r
759                 @Override\r
760                 public void dispose() {\r
761                         combo.dispose();\r
762                         super.dispose();\r
763                 }\r
764         }\r
765         \r
766 }\r