-package org.simantics.ui.toolbar;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.commands.Command;\r
-import org.eclipse.core.commands.CommandEvent;\r
-import org.eclipse.core.commands.ExecutionException;\r
-import org.eclipse.core.commands.ICommandListener;\r
-import org.eclipse.core.commands.IParameter;\r
-import org.eclipse.core.commands.Parameterization;\r
-import org.eclipse.core.commands.ParameterizedCommand;\r
-import org.eclipse.core.commands.State;\r
-import org.eclipse.core.runtime.CoreException;\r
-import org.eclipse.core.runtime.IConfigurationElement;\r
-import org.eclipse.core.runtime.IExecutableExtension;\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.ActionContributionItem;\r
-import org.eclipse.jface.action.IContributionItem;\r
-import org.eclipse.jface.action.ICoolBarManager;\r
-import org.eclipse.jface.action.IToolBarManager;\r
-import org.eclipse.jface.action.ToolBarContributionItem;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.nebula.widgets.tablecombo.TableCombo;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.TableItem;\r
-import org.eclipse.ui.IEditorPart;\r
-import org.eclipse.ui.IPartListener;\r
-import org.eclipse.ui.IWorkbenchPart;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.eclipse.ui.commands.ICommandService;\r
-import org.eclipse.ui.handlers.HandlerUtil;\r
-import org.eclipse.ui.handlers.IHandlerService;\r
-import org.eclipse.ui.handlers.RadioState;\r
-import org.eclipse.ui.handlers.RegistryToggleState;\r
-import org.eclipse.ui.menus.WorkbenchWindowControlContribution;\r
-import org.eclipse.ui.part.EditorActionBarContributor;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.ui.internal.Activator;\r
-import org.simantics.ui.toolbar.ToolBarCommandRegistry.Parameter;\r
-import org.simantics.ui.toolbar.ToolBarCommandRegistry.ToolbarCommandExtension;\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-\r
-\r
-/**\r
- * EditorBarContributor, which tracks toggle states separately for each command.\r
- * \r
- * @see org.simantics.g3d.toolbarCommand Extension Point\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- * \r
- * \r
- * \r
- * TODO : configuring the position of buttons. \r
- *\r
- */\r
-public class ToolbarContributor extends EditorActionBarContributor implements ICommandListener, IPartListener, CommandStateListener, IExecutableExtension {\r
-\r
- private static boolean DEBUG = false; // Print debug messages to console\r
- private boolean REUSE = true; // true: Reuse contribution items (leave toolbar in disabled state when editor closes)\r
- // false: delete items on dispose (remove toolbar editor closes) \r
- \r
- private static final String PLATFORM = "platform:/plugin/";\r
-\r
- private String toolbarId;\r
- \r
- private IEditorPart activePart;\r
- private Set<IEditorPart> parts = new HashSet<IEditorPart>();\r
- IToolBarManager mgr;\r
- \r
- \r
- ICommandService service;\r
- IHandlerService handlerService;\r
- List<IContributionItem> items = new ArrayList<IContributionItem>();\r
- MapList<String, CommandAction> actions = new MapList<String, ToolbarContributor.CommandAction>();\r
- \r
- CommandStateRegistry stateRegistry;\r
- \r
- IPartListener partListener;\r
- \r
- private Map<String,ComboContribution> menus = new HashMap<String, ComboContribution>();\r
- \r
- public ToolbarContributor() {\r
- service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); \r
- handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);\r
- stateRegistry = CommandStateRegistry.getInstance();\r
- // we need part listener to be notified for other editor activations (i.e editors that do not use this contributor).\r
- partListener = new IPartListener() {\r
- \r
- @Override\r
- public void partOpened(IWorkbenchPart part) {}\r
- \r
- @Override\r
- public void partDeactivated(IWorkbenchPart part) {}\r
- \r
- @Override\r
- public void partClosed(IWorkbenchPart part) {}\r
- \r
- @Override\r
- public void partBroughtToTop(IWorkbenchPart part) {}\r
- \r
- @Override\r
- public void partActivated(IWorkbenchPart part) {\r
- if (part instanceof IEditorPart)\r
- setContext2((IEditorPart)part);\r
- }\r
- };\r
- PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);\r
- \r
- }\r
- \r
- @Override\r
- public void setInitializationData(IConfigurationElement config,String propertyName, Object data) throws CoreException {\r
- if (data instanceof String) {\r
- String[] parameters = ((String) data).split(";");\r
- for (String parameter : parameters) {\r
- String[] keyValue = parameter.split("=");\r
- if (keyValue.length > 2) {\r
- //ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);\r
- continue;\r
- }\r
- String key = keyValue[0];\r
- String value = keyValue.length > 1 ? keyValue[1] : "";\r
-\r
- if ("toolbar".equals(key)) {\r
- toolbarId = value;\r
- } else if ("hide".equals(key)) {\r
- REUSE = !Boolean.parseBoolean(value);\r
- }\r
- }\r
- }\r
- \r
- }\r
- \r
- public String getToolbarId() {\r
- return toolbarId;\r
- }\r
- \r
- \r
- private ICoolBarManager coolBarManager;\r
- private IContributionItem toolBar;\r
- public void contributeToCoolBar(ICoolBarManager coolBarManager) {\r
- this.coolBarManager = coolBarManager;\r
- toolBar = coolBarManager.find(getToolbarId());\r
- \r
- if (toolBar instanceof ToolBarContributionItem)\r
- mgr = ((ToolBarContributionItem) toolBar).getToolBarManager();\r
- if (mgr == null)\r
- return;\r
- \r
- createCommands();\r
- \r
- mgr.markDirty();\r
- \r
- }\r
- \r
- private void createCommands() {\r
- for (ToolbarCommandExtension ext : ToolBarCommandRegistry.getInstance().getExtensions(getToolbarId())) {\r
- addCommand(ext);\r
- }\r
- }\r
- \r
- private void addCommand(ToolbarCommandExtension ext) {\r
- if (DEBUG) System.out.println("Adding command to toolbar " +getToolbarId() + " " + ext);\r
- String commandId = ext.commandId;\r
- Command command = service.getCommand(commandId);\r
- ICommandWrapper wrapper = new CommandWrapper(command);\r
- \r
- ParameterizedCommand parameterizedCommand = null;\r
- \r
- if (ext.parameters.size() > 0) {\r
- try {\r
- Parameterization parameterizations[] = new Parameterization[ext.parameters.size()];\r
- for (int i = 0; i < ext.parameters.size(); i++) {\r
- Parameter param = ext.parameters.get(i);\r
- IParameter parameter = command.getParameter(param.name);\r
- parameterizations[i] = new Parameterization(parameter, param.value);\r
- }\r
- parameterizedCommand = new ParameterizedCommand(command, parameterizations);\r
- wrapper = new ParameterizedCommandWrapper(parameterizedCommand);\r
- } catch (org.eclipse.core.commands.common.NotDefinedException e) {\r
- e.printStackTrace();\r
- ExceptionUtils.logError(e);\r
- return;\r
- }\r
- }\r
- \r
- String type = ext.type;\r
- \r
- State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
- State radioState = command.getState(RadioState.STATE_ID);\r
- \r
- String name = ext.name;\r
- \r
- \r
- ImageDescriptor image = getImage(ext);\r
- \r
- CommandAction a = null;\r
- if (type.equals("toggle") && toggleState != null) {\r
- a = new CommandCheckboxAction(wrapper,name,image);\r
-\r
- stateRegistry.storeDefaultState(commandId);\r
- } else if (radioState != null && ext.value != null) {\r
- stateRegistry.storeDefaultState(commandId);\r
- if (type.equals("radio")) {\r
- a = new CommandRadioAction(wrapper,name,ext.value,image);\r
- } else if (type.equals("combo")) {\r
- a = new CommandRadioAction(wrapper,name,ext.value,image);\r
- ComboContribution combo = menus.get(commandId);\r
- if (REUSE && combo == null) {\r
- combo = (ComboContribution)mgr.find(commandId);\r
- if (combo != null) {\r
- menus.put(commandId, combo);\r
- items.add(combo);\r
- a.getCommand().addCommandListener(this);\r
- CommandStateRegistry.getInstance().addListener(commandId, this);\r
- }\r
- }\r
- if (combo == null) {\r
- combo = new ComboContribution();\r
- combo.setId(commandId);\r
- menus.put(commandId, combo);\r
- items.add(combo);\r
- mgr.add(combo);\r
- a.getCommand().addCommandListener(this);\r
- CommandStateRegistry.getInstance().addListener(commandId, this);\r
- }\r
- actions.add(commandId,a);\r
- combo.addAction(a);\r
- return;\r
- }\r
- } else if (type.equals("push")) {\r
- a = new CommandPushAction(wrapper,name,image);\r
- } else {\r
- if (DEBUG) System.out.println(ext + " is not valid.");\r
- Logger.defaultLogError(ext + " is not valid.");\r
- return;\r
- }\r
- IContributionItem item = null;\r
- if (REUSE) {\r
- String id = commandId;\r
- if (ext.value != null)\r
- id += "."+ext.value;\r
- item = mgr.find(id);\r
- if (item == null) {\r
- item = new ActionContributionItem(a);\r
- ((ActionContributionItem)item).setId(id);\r
- } else {\r
- if (DEBUG) System.out.println("Reusing " + ext);\r
- a = (CommandAction)((ActionContributionItem)item).getAction();\r
- }\r
- } else {\r
- item = new ActionContributionItem(a);\r
- }\r
- a.getCommand().addCommandListener(this);\r
- actions.add(commandId,a);\r
- items.add(item);\r
- mgr.add(item);\r
- CommandStateRegistry.getInstance().addListener(commandId, this);\r
- }\r
- \r
- private ImageDescriptor getImage(ToolbarCommandExtension ext) {\r
- ImageDescriptor image = null;\r
- if (ext.image != null) {\r
- String plugin = null;\r
- String file = null;\r
- if (ext.image.startsWith(PLATFORM)) {\r
- String s = ext.image.substring(PLATFORM.length());\r
- int i = s.indexOf("/");\r
- plugin = s.substring(0,i);\r
- file = s.substring(i+1);\r
- } else {\r
- plugin = ext.contributorId;\r
- file = ext.image;\r
- }\r
- image = Activator.imageDescriptorFromPlugin(plugin, file);\r
- }\r
- return image;\r
- }\r
- \r
-\r
- \r
- @Override\r
- public void commandChanged(CommandEvent commandEvent) {\r
- if (commandEvent.isHandledChanged()||commandEvent.isEnabledChanged()) {\r
- Command command = commandEvent.getCommand();\r
- String commandId = command.getId();\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- a.setEnabled(command.isHandled() && command.isEnabled());\r
- }\r
- }\r
- }\r
- \r
- @Override\r
- public void setActiveEditor(IEditorPart targetEditor) {\r
- if (targetEditor == activePart)\r
- return;\r
- setContext(targetEditor);\r
- }\r
- \r
- @Override\r
- public void stateChanged(IWorkbenchPart part, String commandId, String state) {\r
- // TODO : update only given command\r
- if (settingState)\r
- return;\r
- if (part instanceof IEditorPart)\r
- setContext((IEditorPart)part);\r
- }\r
- \r
- private void setContext2(IEditorPart part) {\r
- if (REUSE)\r
- return;\r
- if (this.activePart == part)\r
- return;\r
- setContext(null);\r
- }\r
- \r
- private void setContext(IEditorPart part) {\r
- this.activePart = part;\r
- if (activePart != null && !parts.contains(activePart)) {\r
- activePart.getSite().getPage().addPartListener(this);\r
- }\r
- if (part != null) {\r
- for (String commandId : actions.getKeys()) {\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- a.setEnabled(true);\r
- }\r
- ComboContribution menu = menus.get(commandId);\r
- if (menu != null) {\r
- menu.setEnabled(true);\r
- }\r
- }\r
- updateActionBars(part);\r
- } else {\r
- for (String commandId : actions.getKeys()) {\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- a.setEnabled(false);\r
- }\r
- ComboContribution menu = menus.get(commandId);\r
- if (menu != null) {\r
- menu.setEnabled(false);\r
- }\r
- \r
- }\r
- }\r
- }\r
-\r
- private void updateActionBars(IEditorPart part) {\r
- restoreActionStates();\r
- part.getEditorSite().getActionBars().updateActionBars();\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- if (DEBUG) System.out.println("ToolBarContributor.dispose()");\r
- setActiveEditor(null);\r
- if (mgr != null) {\r
- if (!REUSE) {\r
- for (IContributionItem item : items) {\r
- mgr.remove(item);\r
- item.dispose();\r
- }\r
- }\r
- items.clear();\r
- \r
- for (String commandId : actions.getKeys()) {\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- a.getCommand().removeCommandListener(this);\r
- }\r
- \r
- }\r
- actions.clear();\r
- \r
- // without this the contributed toolbar widgets would continue reserve the space even when they are destroyed.\r
- coolBarManager.update(true);\r
- mgr.update(true);\r
- }\r
- CommandStateRegistry.getInstance().removeListener(this);\r
- super.dispose();\r
- activePart = null;\r
- if (partListener != null) {\r
- PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);\r
- partListener = null;\r
- }\r
- }\r
- \r
- boolean settingState = false;\r
- private void storeRadioActionState(CommandRadioAction action, boolean checked) {\r
- if (activePart == null)\r
- return;\r
- settingState = true;\r
- stateRegistry.setEditorState(activePart, action.getCommandId(), action.getValue());\r
- settingState = false;\r
- }\r
- \r
- private void storeToggleActionState(CommandAction action, boolean checked) {\r
- if (activePart == null)\r
- return;\r
- settingState = true;\r
- stateRegistry.setEditorState(activePart, action.getCommandId(), checked);\r
- settingState = false;\r
- }\r
- \r
- \r
- \r
- private void restoreActionStates() {\r
- if (activePart == null)\r
- return;\r
- if (DEBUG)System.out.println("Restore " + activePart);\r
- // toggles\r
- Map<String,Boolean> defaultToggleStates = stateRegistry.getDefaultToggleStates();\r
- for (String commandId : defaultToggleStates.keySet()) {\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- if (DEBUG)System.out.println(commandId + " def " + defaultToggleStates.get(commandId));\r
- a.setChecked(defaultToggleStates.get(commandId));\r
- }\r
- }\r
- Map<String,Boolean> editorStates = stateRegistry.getEditorToggleStates(activePart);//toggleStates.get(activePart);\r
- if (editorStates != null) {\r
- for (String commandId : editorStates.keySet()) {\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- if (DEBUG)System.out.println(commandId + " " + editorStates.get(commandId));\r
- a.setChecked(editorStates.get(commandId));\r
- }\r
- }\r
- }\r
- // radios\r
- Map<String,String> defaultRadioStates = stateRegistry.getDefaultRadioStates();\r
- for (String commandId : defaultRadioStates.keySet()) {\r
- String defaultValue = defaultRadioStates.get(commandId);\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- CommandRadioAction r = (CommandRadioAction)a;\r
- if (DEBUG)System.out.println(commandId + " def " + r.getValue().equals(defaultValue) +" " + r.getValue());\r
- r.setChecked(r.getValue().equals(defaultValue));\r
- }\r
- }\r
- \r
- Map<String,String> editorRadioStates = stateRegistry.getEditorRadioStates(activePart);//radioStates.get(activePart);\r
- if (editorRadioStates != null) {\r
- for (String commandId : editorRadioStates.keySet()) {\r
- String defaultValue = editorRadioStates.get(commandId);\r
- for (CommandAction a : actions.getValues(commandId)) {\r
- CommandRadioAction r = (CommandRadioAction)a;\r
- if (DEBUG)System.out.println(commandId + " " + r.getValue().equals(defaultValue) +" " + r.getValue());\r
- r.setChecked(r.getValue().equals(defaultValue));\r
- }\r
- }\r
- }\r
- \r
- for (ComboContribution c : menus.values()) {\r
- c.updateSelection();\r
- }\r
-\r
- }\r
- \r
- @Override\r
- public void partActivated(IWorkbenchPart part) {\r
-\r
- }\r
- \r
- @Override\r
- public void partBroughtToTop(IWorkbenchPart part) {\r
- \r
- }\r
- \r
- @Override\r
- public void partClosed(IWorkbenchPart part) {\r
- parts.remove(part);\r
- stateRegistry.clearStates(part);\r
- part.getSite().getPage().removePartListener(this);\r
- if (parts.size() == 0) {\r
- \r
- }\r
- if (part instanceof IEditorPart)\r
- ((IEditorPart)part).getEditorSite().getActionBars().updateActionBars();\r
- \r
- }\r
- \r
- @Override\r
- public void partDeactivated(IWorkbenchPart part) {\r
- \r
- }\r
- \r
- @Override\r
- public void partOpened(IWorkbenchPart part) {\r
- \r
- }\r
- \r
- private boolean getToggleState(Command command) {\r
- State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
- return (Boolean)toggleState.getValue();\r
- }\r
- \r
- private interface ICommandWrapper {\r
- \r
- public Command getCommand();\r
- public String getCommandId();\r
- public void run();\r
- }\r
- \r
- private class CommandWrapper implements ICommandWrapper{\r
- private Command command;\r
- \r
- public CommandWrapper(Command command) {\r
- this.command = command;\r
- }\r
- \r
- @Override\r
- public Command getCommand() {\r
- return command;\r
- }\r
- \r
- @Override\r
- public String getCommandId() {\r
- return command.getId();\r
- }\r
- \r
- @Override\r
- public void run() {\r
- try {\r
- handlerService.executeCommand(command.getId(), null);\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- \r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj.getClass() != getClass())\r
- return false;\r
- CommandWrapper other= (CommandWrapper)obj;\r
- return other.getCommandId().equals(getCommandId());\r
- }\r
- }\r
- \r
- private class ParameterizedCommandWrapper implements ICommandWrapper{\r
- private ParameterizedCommand command;\r
- \r
- public ParameterizedCommandWrapper(ParameterizedCommand command) {\r
- this.command = command;\r
- }\r
- \r
- @Override\r
- public Command getCommand() {\r
- return command.getCommand();\r
- }\r
- \r
- @Override\r
- public String getCommandId() {\r
- return command.getId();\r
- }\r
- \r
- @Override\r
- public void run() {\r
- try {\r
- handlerService.executeCommand(command, null);\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- \r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj.getClass() != getClass())\r
- return false;\r
- ParameterizedCommandWrapper other= (ParameterizedCommandWrapper)obj;\r
- return other.command.equals(command);\r
- }\r
- }\r
- \r
- private abstract class CommandAction extends Action {\r
- private ICommandWrapper command;\r
- \r
- public CommandAction(ICommandWrapper command, String name, ImageDescriptor image, int style) {\r
- super(name,style);\r
- this.command = command;\r
- if (image != null)\r
- setImageDescriptor(image);\r
- }\r
- \r
- @Override\r
- public void run() {\r
- command.run();\r
- }\r
- \r
- public Command getCommand() {\r
- return command.getCommand();\r
- }\r
- \r
- public String getCommandId() {\r
- return command.getCommandId();\r
- }\r
- \r
-\r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj.getClass() != getClass())\r
- return false;\r
- CommandAction other= (CommandAction)obj;\r
- return command.equals(other.command);\r
- }\r
-\r
- \r
- @Override\r
- public int hashCode() {\r
- return command.getCommandId().hashCode();\r
- }\r
- }\r
- \r
- \r
- private class CommandCheckboxAction extends CommandAction {\r
- \r
- public CommandCheckboxAction(ICommandWrapper command, String name, ImageDescriptor image) {\r
- super(command,name,image,Action.AS_CHECK_BOX);\r
- \r
- }\r
- \r
- @Override\r
- public void run() {\r
- boolean checked = isChecked(); \r
- storeToggleActionState(this, checked);\r
- try {\r
- if (checked == getToggleState(getCommand()))\r
- HandlerUtil.toggleCommandState(getCommand());\r
- } catch (ExecutionException e) {\r
- e.printStackTrace();\r
- }\r
- super.run();\r
- }\r
- \r
- }\r
- \r
- private class CommandRadioAction extends CommandAction {\r
-\r
- private String value;\r
- \r
- public CommandRadioAction(ICommandWrapper command, String name, String value, ImageDescriptor image) {\r
- super(command,name,image,Action.AS_RADIO_BUTTON);\r
- this.value = value;\r
- }\r
- \r
- @Override\r
- public void run() {\r
- boolean checked = isChecked(); \r
- storeRadioActionState(this, checked);\r
- try {\r
- HandlerUtil.updateRadioState(getCommand(), value);\r
- } catch (ExecutionException e) {\r
- e.printStackTrace();\r
- return;\r
- }\r
- super.run();\r
- }\r
- \r
- public String getValue() {\r
- return value;\r
- }\r
- \r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj.getClass() != getClass())\r
- return false;\r
- CommandRadioAction other= (CommandRadioAction)obj;\r
- if (!other.getCommandId().equals(getCommandId()))\r
- return false;\r
- if (!other.value.equals(value))\r
- return false;\r
- return true;\r
- }\r
- \r
- }\r
-\r
- private class CommandPushAction extends CommandAction {\r
- \r
- public CommandPushAction(ICommandWrapper command, String name, ImageDescriptor image) {\r
- super(command,name,image,Action.AS_PUSH_BUTTON);\r
- }\r
-\r
- }\r
- \r
- private class ComboContribution extends WorkbenchWindowControlContribution {\r
- private TableCombo combo;\r
- \r
- private List<Action> actions = new ArrayList<Action>();\r
- \r
- @Override\r
- protected Control createControl(Composite parent) {\r
- Composite container = new Composite(parent, SWT.NONE);\r
- GridLayout glContainer = new GridLayout(1, false);\r
- glContainer.marginTop = 0;\r
- glContainer.marginHeight = 0;\r
- glContainer.marginWidth = 0;\r
- container.setLayout(glContainer);\r
- GridData glReader = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);\r
- combo = new TableCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
- combo.setLayoutData(glReader);\r
-\r
- for (Action a : actions) {\r
- TableItem item = new TableItem(combo.getTable(), SWT.NONE);\r
- item.setText(a.getText());\r
- if (a.getImageDescriptor() != null)\r
- item.setImage(a.getImageDescriptor().createImage());\r
- }\r
- \r
- combo.addSelectionListener(new SelectionListener() {\r
- \r
- @Override\r
- public void widgetSelected(SelectionEvent e) {\r
- int index = combo.getSelectionIndex();\r
- if (index == -1)\r
- return;\r
- actions.get(index).run();\r
- }\r
- \r
- @Override\r
- public void widgetDefaultSelected(SelectionEvent e) {\r
- \r
- }\r
- });\r
- updateSelection();\r
- return container;\r
- }\r
- \r
- public boolean addAction(Action a) {\r
- // old action must be replaced. (otherwise reused ComboContributor would use different instances to ToolBarContributor.) \r
- actions.remove(a);\r
- actions.add(a);\r
- return true;\r
- \r
- }\r
- \r
- void updateSelection() {\r
- if (combo == null)\r
- return;\r
- for (int i = 0; i < actions.size(); i++) {\r
- if (actions.get(i).isChecked()) {\r
- combo.select(i);\r
- return;\r
- }\r
- }\r
- }\r
- \r
- public void setEnabled(boolean enabled) {\r
- if (combo != null)\r
- combo.setEnabled(enabled);\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- combo.dispose();\r
- super.dispose();\r
- }\r
- }\r
- \r
-}\r
+package org.simantics.ui.toolbar;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.CommandEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.ICommandListener;
+import org.eclipse.core.commands.IParameter;
+import org.eclipse.core.commands.Parameterization;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.State;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.ToolBarContributionItem;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.nebula.widgets.tablecombo.TableCombo;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.handlers.RadioState;
+import org.eclipse.ui.handlers.RegistryToggleState;
+import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
+import org.eclipse.ui.part.EditorActionBarContributor;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.ui.internal.Activator;
+import org.simantics.ui.toolbar.ToolBarCommandRegistry.Parameter;
+import org.simantics.ui.toolbar.ToolBarCommandRegistry.ToolbarCommandExtension;
+import org.simantics.utils.datastructures.MapList;
+import org.simantics.utils.ui.ExceptionUtils;
+
+
+/**
+ * EditorBarContributor, which tracks toggle states separately for each command.
+ *
+ * @see org.simantics.g3d.toolbarCommand Extension Point
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ *
+ *
+ * TODO : configuring the position of buttons.
+ *
+ */
+public class ToolbarContributor extends EditorActionBarContributor implements ICommandListener, IPartListener, CommandStateListener, IExecutableExtension {
+
+ private static boolean DEBUG = false; // Print debug messages to console
+ private boolean REUSE = true; // true: Reuse contribution items (leave toolbar in disabled state when editor closes)
+ // false: delete items on dispose (remove toolbar editor closes)
+
+ private static final String PLATFORM = "platform:/plugin/";
+
+ private String toolbarId;
+
+ private IEditorPart activePart;
+ private Set<IEditorPart> parts = new HashSet<IEditorPart>();
+ IToolBarManager mgr;
+
+
+ ICommandService service;
+ IHandlerService handlerService;
+ List<IContributionItem> items = new ArrayList<IContributionItem>();
+ MapList<String, CommandAction> actions = new MapList<String, ToolbarContributor.CommandAction>();
+
+ CommandStateRegistry stateRegistry;
+
+ IPartListener partListener;
+
+ private Map<String,ComboContribution> menus = new HashMap<String, ComboContribution>();
+
+ public ToolbarContributor() {
+ service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
+ handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
+ stateRegistry = CommandStateRegistry.getInstance();
+ // we need part listener to be notified for other editor activations (i.e editors that do not use this contributor).
+ partListener = new IPartListener() {
+
+ @Override
+ public void partOpened(IWorkbenchPart part) {}
+
+ @Override
+ public void partDeactivated(IWorkbenchPart part) {}
+
+ @Override
+ public void partClosed(IWorkbenchPart part) {}
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPart part) {}
+
+ @Override
+ public void partActivated(IWorkbenchPart part) {
+ if (part instanceof IEditorPart)
+ setContext2((IEditorPart)part);
+ }
+ };
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);
+
+ }
+
+ @Override
+ public void setInitializationData(IConfigurationElement config,String propertyName, Object data) throws CoreException {
+ if (data instanceof String) {
+ String[] parameters = ((String) data).split(";");
+ for (String parameter : parameters) {
+ String[] keyValue = parameter.split("=");
+ if (keyValue.length > 2) {
+ //ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null);
+ continue;
+ }
+ String key = keyValue[0];
+ String value = keyValue.length > 1 ? keyValue[1] : "";
+
+ if ("toolbar".equals(key)) {
+ toolbarId = value;
+ } else if ("hide".equals(key)) {
+ REUSE = !Boolean.parseBoolean(value);
+ }
+ }
+ }
+
+ }
+
+ public String getToolbarId() {
+ return toolbarId;
+ }
+
+
+ private ICoolBarManager coolBarManager;
+ private IContributionItem toolBar;
+ public void contributeToCoolBar(ICoolBarManager coolBarManager) {
+ this.coolBarManager = coolBarManager;
+ toolBar = coolBarManager.find(getToolbarId());
+
+ if (toolBar instanceof ToolBarContributionItem)
+ mgr = ((ToolBarContributionItem) toolBar).getToolBarManager();
+ if (mgr == null)
+ return;
+
+ createCommands();
+
+ mgr.markDirty();
+
+ }
+
+ private void createCommands() {
+ for (ToolbarCommandExtension ext : ToolBarCommandRegistry.getInstance().getExtensions(getToolbarId())) {
+ addCommand(ext);
+ }
+ }
+
+ private void addCommand(ToolbarCommandExtension ext) {
+ if (DEBUG) System.out.println("Adding command to toolbar " +getToolbarId() + " " + ext);
+ String commandId = ext.commandId;
+ Command command = service.getCommand(commandId);
+ ICommandWrapper wrapper = new CommandWrapper(command);
+
+ ParameterizedCommand parameterizedCommand = null;
+
+ if (ext.parameters.size() > 0) {
+ try {
+ Parameterization parameterizations[] = new Parameterization[ext.parameters.size()];
+ for (int i = 0; i < ext.parameters.size(); i++) {
+ Parameter param = ext.parameters.get(i);
+ IParameter parameter = command.getParameter(param.name);
+ parameterizations[i] = new Parameterization(parameter, param.value);
+ }
+ parameterizedCommand = new ParameterizedCommand(command, parameterizations);
+ wrapper = new ParameterizedCommandWrapper(parameterizedCommand);
+ } catch (org.eclipse.core.commands.common.NotDefinedException e) {
+ e.printStackTrace();
+ ExceptionUtils.logError(e);
+ return;
+ }
+ }
+
+ String type = ext.type;
+
+ State toggleState = command.getState(RegistryToggleState.STATE_ID);
+ State radioState = command.getState(RadioState.STATE_ID);
+
+ String name = ext.name;
+
+
+ ImageDescriptor image = getImage(ext);
+
+ CommandAction a = null;
+ if (type.equals("toggle") && toggleState != null) {
+ a = new CommandCheckboxAction(wrapper,name,image);
+
+ stateRegistry.storeDefaultState(commandId);
+ } else if (radioState != null && ext.value != null) {
+ stateRegistry.storeDefaultState(commandId);
+ if (type.equals("radio")) {
+ a = new CommandRadioAction(wrapper,name,ext.value,image);
+ } else if (type.equals("combo")) {
+ a = new CommandRadioAction(wrapper,name,ext.value,image);
+ ComboContribution combo = menus.get(commandId);
+ if (REUSE && combo == null) {
+ combo = (ComboContribution)mgr.find(commandId);
+ if (combo != null) {
+ menus.put(commandId, combo);
+ items.add(combo);
+ a.getCommand().addCommandListener(this);
+ CommandStateRegistry.getInstance().addListener(commandId, this);
+ }
+ }
+ if (combo == null) {
+ combo = new ComboContribution();
+ combo.setId(commandId);
+ menus.put(commandId, combo);
+ items.add(combo);
+ mgr.add(combo);
+ a.getCommand().addCommandListener(this);
+ CommandStateRegistry.getInstance().addListener(commandId, this);
+ }
+ actions.add(commandId,a);
+ combo.addAction(a);
+ return;
+ }
+ } else if (type.equals("push")) {
+ a = new CommandPushAction(wrapper,name,image);
+ } else {
+ if (DEBUG) System.out.println(ext + " is not valid.");
+ Logger.defaultLogError(ext + " is not valid.");
+ return;
+ }
+ IContributionItem item = null;
+ if (REUSE) {
+ String id = commandId;
+ if (ext.value != null)
+ id += "."+ext.value;
+ item = mgr.find(id);
+ if (item == null) {
+ item = new ActionContributionItem(a);
+ ((ActionContributionItem)item).setId(id);
+ } else {
+ if (DEBUG) System.out.println("Reusing " + ext);
+ a = (CommandAction)((ActionContributionItem)item).getAction();
+ }
+ } else {
+ item = new ActionContributionItem(a);
+ }
+ a.getCommand().addCommandListener(this);
+ actions.add(commandId,a);
+ items.add(item);
+ mgr.add(item);
+ CommandStateRegistry.getInstance().addListener(commandId, this);
+ }
+
+ private ImageDescriptor getImage(ToolbarCommandExtension ext) {
+ ImageDescriptor image = null;
+ if (ext.image != null) {
+ String plugin = null;
+ String file = null;
+ if (ext.image.startsWith(PLATFORM)) {
+ String s = ext.image.substring(PLATFORM.length());
+ int i = s.indexOf("/");
+ plugin = s.substring(0,i);
+ file = s.substring(i+1);
+ } else {
+ plugin = ext.contributorId;
+ file = ext.image;
+ }
+ image = Activator.imageDescriptorFromPlugin(plugin, file);
+ }
+ return image;
+ }
+
+
+
+ @Override
+ public void commandChanged(CommandEvent commandEvent) {
+ if (commandEvent.isHandledChanged()||commandEvent.isEnabledChanged()) {
+ Command command = commandEvent.getCommand();
+ String commandId = command.getId();
+ for (CommandAction a : actions.getValues(commandId)) {
+ a.setEnabled(command.isHandled() && command.isEnabled());
+ }
+ }
+ }
+
+ @Override
+ public void setActiveEditor(IEditorPart targetEditor) {
+ if (targetEditor == activePart)
+ return;
+ setContext(targetEditor);
+ }
+
+ @Override
+ public void stateChanged(IWorkbenchPart part, String commandId, String state) {
+ // TODO : update only given command
+ if (settingState)
+ return;
+ if (part instanceof IEditorPart)
+ setContext((IEditorPart)part);
+ }
+
+ private void setContext2(IEditorPart part) {
+ if (REUSE)
+ return;
+ if (this.activePart == part)
+ return;
+ setContext(null);
+ }
+
+ private void setContext(IEditorPart part) {
+ this.activePart = part;
+ if (activePart != null && !parts.contains(activePart)) {
+ activePart.getSite().getPage().addPartListener(this);
+ }
+ if (part != null) {
+ for (String commandId : actions.getKeys()) {
+ for (CommandAction a : actions.getValues(commandId)) {
+ a.setEnabled(true);
+ }
+ ComboContribution menu = menus.get(commandId);
+ if (menu != null) {
+ menu.setEnabled(true);
+ }
+ }
+ updateActionBars(part);
+ } else {
+ for (String commandId : actions.getKeys()) {
+ for (CommandAction a : actions.getValues(commandId)) {
+ a.setEnabled(false);
+ }
+ ComboContribution menu = menus.get(commandId);
+ if (menu != null) {
+ menu.setEnabled(false);
+ }
+
+ }
+ }
+ }
+
+ private void updateActionBars(IEditorPart part) {
+ restoreActionStates();
+ part.getEditorSite().getActionBars().updateActionBars();
+ }
+
+ @Override
+ public void dispose() {
+ if (DEBUG) System.out.println("ToolBarContributor.dispose()");
+ setActiveEditor(null);
+ if (mgr != null) {
+ if (!REUSE) {
+ for (IContributionItem item : items) {
+ mgr.remove(item);
+ item.dispose();
+ }
+ }
+ items.clear();
+
+ for (String commandId : actions.getKeys()) {
+ for (CommandAction a : actions.getValues(commandId)) {
+ a.getCommand().removeCommandListener(this);
+ }
+
+ }
+ actions.clear();
+
+ // without this the contributed toolbar widgets would continue reserve the space even when they are destroyed.
+ coolBarManager.update(true);
+ mgr.update(true);
+ }
+ CommandStateRegistry.getInstance().removeListener(this);
+ super.dispose();
+ activePart = null;
+ if (partListener != null) {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);
+ partListener = null;
+ }
+ }
+
+ boolean settingState = false;
+ private void storeRadioActionState(CommandRadioAction action, boolean checked) {
+ if (activePart == null)
+ return;
+ settingState = true;
+ stateRegistry.setEditorState(activePart, action.getCommandId(), action.getValue());
+ settingState = false;
+ }
+
+ private void storeToggleActionState(CommandAction action, boolean checked) {
+ if (activePart == null)
+ return;
+ settingState = true;
+ stateRegistry.setEditorState(activePart, action.getCommandId(), checked);
+ settingState = false;
+ }
+
+
+
+ private void restoreActionStates() {
+ if (activePart == null)
+ return;
+ if (DEBUG)System.out.println("Restore " + activePart);
+ // toggles
+ Map<String,Boolean> defaultToggleStates = stateRegistry.getDefaultToggleStates();
+ for (String commandId : defaultToggleStates.keySet()) {
+ for (CommandAction a : actions.getValues(commandId)) {
+ if (DEBUG)System.out.println(commandId + " def " + defaultToggleStates.get(commandId));
+ a.setChecked(defaultToggleStates.get(commandId));
+ }
+ }
+ Map<String,Boolean> editorStates = stateRegistry.getEditorToggleStates(activePart);//toggleStates.get(activePart);
+ if (editorStates != null) {
+ for (String commandId : editorStates.keySet()) {
+ for (CommandAction a : actions.getValues(commandId)) {
+ if (DEBUG)System.out.println(commandId + " " + editorStates.get(commandId));
+ a.setChecked(editorStates.get(commandId));
+ }
+ }
+ }
+ // radios
+ Map<String,String> defaultRadioStates = stateRegistry.getDefaultRadioStates();
+ for (String commandId : defaultRadioStates.keySet()) {
+ String defaultValue = defaultRadioStates.get(commandId);
+ for (CommandAction a : actions.getValues(commandId)) {
+ CommandRadioAction r = (CommandRadioAction)a;
+ if (DEBUG)System.out.println(commandId + " def " + r.getValue().equals(defaultValue) +" " + r.getValue());
+ r.setChecked(r.getValue().equals(defaultValue));
+ }
+ }
+
+ Map<String,String> editorRadioStates = stateRegistry.getEditorRadioStates(activePart);//radioStates.get(activePart);
+ if (editorRadioStates != null) {
+ for (String commandId : editorRadioStates.keySet()) {
+ String defaultValue = editorRadioStates.get(commandId);
+ for (CommandAction a : actions.getValues(commandId)) {
+ CommandRadioAction r = (CommandRadioAction)a;
+ if (DEBUG)System.out.println(commandId + " " + r.getValue().equals(defaultValue) +" " + r.getValue());
+ r.setChecked(r.getValue().equals(defaultValue));
+ }
+ }
+ }
+
+ for (ComboContribution c : menus.values()) {
+ c.updateSelection();
+ }
+
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPart part) {
+
+ }
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPart part) {
+
+ }
+
+ @Override
+ public void partClosed(IWorkbenchPart part) {
+ parts.remove(part);
+ stateRegistry.clearStates(part);
+ part.getSite().getPage().removePartListener(this);
+ if (parts.size() == 0) {
+
+ }
+ if (part instanceof IEditorPart)
+ ((IEditorPart)part).getEditorSite().getActionBars().updateActionBars();
+
+ }
+
+ @Override
+ public void partDeactivated(IWorkbenchPart part) {
+
+ }
+
+ @Override
+ public void partOpened(IWorkbenchPart part) {
+
+ }
+
+ private boolean getToggleState(Command command) {
+ State toggleState = command.getState(RegistryToggleState.STATE_ID);
+ return (Boolean)toggleState.getValue();
+ }
+
+ private interface ICommandWrapper {
+
+ public Command getCommand();
+ public String getCommandId();
+ public void run();
+ }
+
+ private class CommandWrapper implements ICommandWrapper{
+ private Command command;
+
+ public CommandWrapper(Command command) {
+ this.command = command;
+ }
+
+ @Override
+ public Command getCommand() {
+ return command;
+ }
+
+ @Override
+ public String getCommandId() {
+ return command.getId();
+ }
+
+ @Override
+ public void run() {
+ try {
+ handlerService.executeCommand(command.getId(), null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj.getClass() != getClass())
+ return false;
+ CommandWrapper other= (CommandWrapper)obj;
+ return other.getCommandId().equals(getCommandId());
+ }
+ }
+
+ private class ParameterizedCommandWrapper implements ICommandWrapper{
+ private ParameterizedCommand command;
+
+ public ParameterizedCommandWrapper(ParameterizedCommand command) {
+ this.command = command;
+ }
+
+ @Override
+ public Command getCommand() {
+ return command.getCommand();
+ }
+
+ @Override
+ public String getCommandId() {
+ return command.getId();
+ }
+
+ @Override
+ public void run() {
+ try {
+ handlerService.executeCommand(command, null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj.getClass() != getClass())
+ return false;
+ ParameterizedCommandWrapper other= (ParameterizedCommandWrapper)obj;
+ return other.command.equals(command);
+ }
+ }
+
+ private abstract class CommandAction extends Action {
+ private ICommandWrapper command;
+
+ public CommandAction(ICommandWrapper command, String name, ImageDescriptor image, int style) {
+ super(name,style);
+ this.command = command;
+ if (image != null)
+ setImageDescriptor(image);
+ }
+
+ @Override
+ public void run() {
+ command.run();
+ }
+
+ public Command getCommand() {
+ return command.getCommand();
+ }
+
+ public String getCommandId() {
+ return command.getCommandId();
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj.getClass() != getClass())
+ return false;
+ CommandAction other= (CommandAction)obj;
+ return command.equals(other.command);
+ }
+
+
+ @Override
+ public int hashCode() {
+ return command.getCommandId().hashCode();
+ }
+ }
+
+
+ private class CommandCheckboxAction extends CommandAction {
+
+ public CommandCheckboxAction(ICommandWrapper command, String name, ImageDescriptor image) {
+ super(command,name,image,Action.AS_CHECK_BOX);
+
+ }
+
+ @Override
+ public void run() {
+ boolean checked = isChecked();
+ storeToggleActionState(this, checked);
+ try {
+ if (checked == getToggleState(getCommand()))
+ HandlerUtil.toggleCommandState(getCommand());
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ super.run();
+ }
+
+ }
+
+ private class CommandRadioAction extends CommandAction {
+
+ private String value;
+
+ public CommandRadioAction(ICommandWrapper command, String name, String value, ImageDescriptor image) {
+ super(command,name,image,Action.AS_RADIO_BUTTON);
+ this.value = value;
+ }
+
+ @Override
+ public void run() {
+ boolean checked = isChecked();
+ storeRadioActionState(this, checked);
+ try {
+ HandlerUtil.updateRadioState(getCommand(), value);
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ return;
+ }
+ super.run();
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj.getClass() != getClass())
+ return false;
+ CommandRadioAction other= (CommandRadioAction)obj;
+ if (!other.getCommandId().equals(getCommandId()))
+ return false;
+ if (!other.value.equals(value))
+ return false;
+ return true;
+ }
+
+ }
+
+ private class CommandPushAction extends CommandAction {
+
+ public CommandPushAction(ICommandWrapper command, String name, ImageDescriptor image) {
+ super(command,name,image,Action.AS_PUSH_BUTTON);
+ }
+
+ }
+
+ private class ComboContribution extends WorkbenchWindowControlContribution {
+ private TableCombo combo;
+
+ private List<Action> actions = new ArrayList<Action>();
+
+ @Override
+ protected Control createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NONE);
+ GridLayout glContainer = new GridLayout(1, false);
+ glContainer.marginTop = 0;
+ glContainer.marginHeight = 0;
+ glContainer.marginWidth = 0;
+ container.setLayout(glContainer);
+ GridData glReader = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
+ combo = new TableCombo(container, SWT.BORDER | SWT.READ_ONLY);
+ combo.setLayoutData(glReader);
+
+ for (Action a : actions) {
+ TableItem item = new TableItem(combo.getTable(), SWT.NONE);
+ item.setText(a.getText());
+ if (a.getImageDescriptor() != null)
+ item.setImage(a.getImageDescriptor().createImage());
+ }
+
+ combo.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int index = combo.getSelectionIndex();
+ if (index == -1)
+ return;
+ actions.get(index).run();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+ updateSelection();
+ return container;
+ }
+
+ public boolean addAction(Action a) {
+ // old action must be replaced. (otherwise reused ComboContributor would use different instances to ToolBarContributor.)
+ actions.remove(a);
+ actions.add(a);
+ return true;
+
+ }
+
+ void updateSelection() {
+ if (combo == null)
+ return;
+ for (int i = 0; i < actions.size(); i++) {
+ if (actions.get(i).isChecked()) {
+ combo.select(i);
+ return;
+ }
+ }
+ }
+
+ public void setEnabled(boolean enabled) {
+ if (combo != null)
+ combo.setEnabled(enabled);
+ }
+
+ @Override
+ public void dispose() {
+ combo.dispose();
+ super.dispose();
+ }
+ }
+
+}