X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Ftoolbar%2FToolbarContributor.java;h=036574fb3825f61e75c7636c982977b28f14b6c9;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=0f7d3e26d26f90b2aef60cfcbecb396d4b2ec557;hpb=d11239c402eec37ba28edcfa7ea6ca7c1f01147f;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/toolbar/ToolbarContributor.java b/bundles/org.simantics.ui/src/org/simantics/ui/toolbar/ToolbarContributor.java index 0f7d3e26d..036574fb3 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/toolbar/ToolbarContributor.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/toolbar/ToolbarContributor.java @@ -1,766 +1,766 @@ -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 - * - * - * - * 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 parts = new HashSet(); - IToolBarManager mgr; - - - ICommandService service; - IHandlerService handlerService; - List items = new ArrayList(); - MapList actions = new MapList(); - - CommandStateRegistry stateRegistry; - - IPartListener partListener; - - private Map menus = new HashMap(); - - 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 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 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 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 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 actions = new ArrayList(); - - @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(); - } - } - -} +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 + * + * + * + * 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 parts = new HashSet(); + IToolBarManager mgr; + + + ICommandService service; + IHandlerService handlerService; + List items = new ArrayList(); + MapList actions = new MapList(); + + CommandStateRegistry stateRegistry; + + IPartListener partListener; + + private Map menus = new HashMap(); + + 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 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 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 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 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 actions = new ArrayList(); + + @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(); + } + } + +}