1 package org.simantics.g3d.toolbar;
\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
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.State;
\r
15 import org.eclipse.jface.action.Action;
\r
16 import org.eclipse.jface.action.ActionContributionItem;
\r
17 import org.eclipse.jface.action.IContributionItem;
\r
18 import org.eclipse.jface.action.ICoolBarManager;
\r
19 import org.eclipse.jface.action.IToolBarManager;
\r
20 import org.eclipse.jface.action.ToolBarContributionItem;
\r
21 import org.eclipse.jface.resource.ImageDescriptor;
\r
22 import org.eclipse.nebula.widgets.tablecombo.TableCombo;
\r
23 import org.eclipse.swt.SWT;
\r
24 import org.eclipse.swt.events.SelectionEvent;
\r
25 import org.eclipse.swt.events.SelectionListener;
\r
26 import org.eclipse.swt.layout.GridData;
\r
27 import org.eclipse.swt.layout.GridLayout;
\r
28 import org.eclipse.swt.widgets.Composite;
\r
29 import org.eclipse.swt.widgets.Control;
\r
30 import org.eclipse.swt.widgets.TableItem;
\r
31 import org.eclipse.ui.IEditorPart;
\r
32 import org.eclipse.ui.IPartListener;
\r
33 import org.eclipse.ui.IWorkbenchPart;
\r
34 import org.eclipse.ui.PlatformUI;
\r
35 import org.eclipse.ui.commands.ICommandService;
\r
36 import org.eclipse.ui.handlers.HandlerUtil;
\r
37 import org.eclipse.ui.handlers.IHandlerService;
\r
38 import org.eclipse.ui.handlers.RadioState;
\r
39 import org.eclipse.ui.handlers.RegistryToggleState;
\r
40 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
\r
41 import org.eclipse.ui.part.EditorActionBarContributor;
\r
42 import org.simantics.db.common.utils.ErrorLogger;
\r
43 import org.simantics.g3d.Activator;
\r
44 import org.simantics.g3d.toolbar.ToolBarCommandRegistry.ToolbarCommandExtension;
\r
45 import org.simantics.utils.datastructures.MapList;
\r
49 * EditorBarContributor, which tracks toggle states separately for each command.
\r
51 * @see org.simantics.g3d.toolbarCommand Extension Point
\r
53 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
57 * TODO : test radio buttons.
\r
58 * TODO : configuring the position of buttons.
\r
61 public abstract class ToolbarContributor extends EditorActionBarContributor implements ICommandListener, IPartListener {
\r
63 private static final String PLATFORM = "platform:/plugin/";
\r
65 private IEditorPart activePart;
\r
66 private Set<IEditorPart> parts = new HashSet<IEditorPart>();
\r
67 IToolBarManager mgr;
\r
70 ICommandService service;
\r
71 IHandlerService handlerService;
\r
72 List<IContributionItem> items = new ArrayList<IContributionItem>();
\r
73 MapList<String, CommandAction> actions = new MapList<String, ToolbarContributor.CommandAction>();
\r
75 CommandStateRegistry stateRegistry;
\r
77 private Map<String,ComboContribution> menus = new HashMap<String, ComboContribution>();
\r
79 public ToolbarContributor() {
\r
80 service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
\r
81 handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
\r
82 stateRegistry = CommandStateRegistry.getInstance();
\r
85 public abstract String getToolbarId();
\r
87 public void contributeToCoolBar(ICoolBarManager coolBarManager) {
\r
88 IContributionItem toolBar = coolBarManager.find(getToolbarId());
\r
89 if (toolBar instanceof ToolBarContributionItem)
\r
90 mgr = ((ToolBarContributionItem) toolBar).getToolBarManager();
\r
100 private void createCommands() {
\r
101 for (ToolbarCommandExtension ext : ToolBarCommandRegistry.getInstance().getExtensions(getToolbarId())) {
\r
106 private void addCommand(ToolbarCommandExtension ext) {
\r
107 String commandId = ext.commandId;
\r
108 Command command = service.getCommand(commandId);
\r
110 String type = ext.type;
\r
112 State toggleState = command.getState(RegistryToggleState.STATE_ID);
\r
113 State radioState = command.getState(RadioState.STATE_ID);
\r
115 String name = ext.name;
\r
118 ImageDescriptor image = getImage(ext);
\r
120 CommandAction a = null;
\r
121 if (type.equals("toggle") && toggleState != null) {
\r
122 a = new CommandCheckboxAction(command,name,image);
\r
124 stateRegistry.storeDefaultState(commandId);
\r
125 } else if (radioState != null && ext.value != null) {
\r
126 stateRegistry.storeDefaultState(commandId);
\r
127 if (type.equals("radio")) {
\r
128 a = new CommandRadioAction(command,name,ext.value,image);
\r
129 } else if (type.equals("combo")) {
\r
130 a = new CommandRadioAction(command,name,ext.value,image);
\r
131 ComboContribution combo = menus.get(commandId);
\r
132 if (combo == null) {
\r
133 combo = new ComboContribution();
\r
134 menus.put(commandId, combo);
\r
137 a.getCommand().addCommandListener(this);
\r
139 actions.add(commandId,a);
\r
140 combo.addAction(a);
\r
143 } else if (type.equals("push")) {
\r
144 a = new CommandPushAction(command,name,image);
\r
146 ErrorLogger.defaultLogError(ext + " is not valid.");
\r
149 a.getCommand().addCommandListener(this);
\r
150 IContributionItem item = new ActionContributionItem(a);
\r
151 actions.add(commandId,a);
\r
156 private ImageDescriptor getImage(ToolbarCommandExtension ext) {
\r
157 ImageDescriptor image = null;
\r
158 if (ext.image != null) {
\r
159 String plugin = null;
\r
160 String file = null;
\r
161 if (ext.image.startsWith(PLATFORM)) {
\r
162 String s = ext.image.substring(PLATFORM.length());
\r
163 int i = s.indexOf("/");
\r
164 plugin = s.substring(0,i);
\r
165 file = s.substring(i+1);
\r
167 plugin = ext.contributorId;
\r
170 image = Activator.imageDescriptorFromPlugin(plugin, file);
\r
178 public void commandChanged(CommandEvent commandEvent) {
\r
179 if (commandEvent.isHandledChanged()||commandEvent.isEnabledChanged()) {
\r
180 Command command = commandEvent.getCommand();
\r
181 String commandId = command.getId();
\r
182 for (CommandAction a : actions.getValues(commandId)) {
\r
183 a.setEnabled(command.isHandled() && command.isEnabled());
\r
189 public void setActiveEditor(IEditorPart targetEditor) {
\r
190 if (targetEditor == activePart)
\r
192 setContext(targetEditor);
\r
195 private void setContext(IEditorPart part) {
\r
196 this.activePart = part;
\r
197 if (!parts.contains(activePart)) {
\r
198 activePart.getSite().getPage().addPartListener(this);
\r
200 if (part != null) {
\r
201 for (String commandId : actions.getKeys()) {
\r
202 for (CommandAction a : actions.getValues(commandId)) {
\r
203 a.setEnabled(true);
\r
206 updateActionBars(part);
\r
208 for (String commandId : actions.getKeys()) {
\r
209 for (CommandAction a : actions.getValues(commandId)) {
\r
210 a.setEnabled(false);
\r
216 private void updateActionBars(IEditorPart part) {
\r
217 restoreActionStates();
\r
218 part.getEditorSite().getActionBars().updateActionBars();
\r
222 public void dispose() {
\r
224 for (IContributionItem item : items) {
\r
230 if (activePart != null) {
\r
231 activePart.getEditorSite().getActionBars().updateActionBars();
\r
234 for (String commandId : actions.getKeys()) {
\r
235 for (CommandAction a : actions.getValues(commandId)) {
\r
236 a.getCommand().removeCommandListener(this);
\r
247 private void storeRadioActionState(CommandRadioAction action, boolean checked) {
\r
248 if (activePart == null)
\r
250 stateRegistry.setEditorState(activePart, action.getCommandId(), action.getValue());
\r
253 private void storeToggleActionState(CommandAction action, boolean checked) {
\r
254 if (activePart == null)
\r
256 stateRegistry.setEditorState(activePart, action.getCommandId(), checked);
\r
259 private void restoreActionStates() {
\r
260 if (activePart == null)
\r
263 Map<String,Boolean> defaultToggleStates = stateRegistry.getDefaultToggleStates();
\r
264 for (String commandId : defaultToggleStates.keySet()) {
\r
265 for (CommandAction a : actions.getValues(commandId)) {
\r
266 a.setChecked(defaultToggleStates.get(commandId));
\r
269 Map<String,Boolean> editorStates = stateRegistry.getEditorToggleStates(activePart);//toggleStates.get(activePart);
\r
270 if (editorStates != null) {
\r
271 for (String commandId : editorStates.keySet()) {
\r
272 for (CommandAction a : actions.getValues(commandId)) {
\r
273 a.setChecked(editorStates.get(commandId));
\r
278 Map<String,String> defaultRadioStates = stateRegistry.getDefaultRadioStates();
\r
279 for (String commandId : defaultRadioStates.keySet()) {
\r
280 String defaultValue = defaultRadioStates.get(commandId);
\r
281 for (CommandAction a : actions.getValues(commandId)) {
\r
282 CommandRadioAction r = (CommandRadioAction)a;
\r
283 r.setChecked(r.getValue().equals(defaultValue));
\r
287 Map<String,String> editorRadioStates = stateRegistry.getEditorRadioStates(activePart);//radioStates.get(activePart);
\r
288 if (editorRadioStates != null) {
\r
289 for (String commandId : editorRadioStates.keySet()) {
\r
290 String defaultValue = editorRadioStates.get(commandId);
\r
291 for (CommandAction a : actions.getValues(commandId)) {
\r
292 CommandRadioAction r = (CommandRadioAction)a;
\r
293 r.setChecked(r.getValue().equals(defaultValue));
\r
298 for (ComboContribution c : menus.values()) {
\r
299 c.updateSelection();
\r
306 public void partActivated(IWorkbenchPart part) {
\r
311 public void partBroughtToTop(IWorkbenchPart part) {
\r
316 public void partClosed(IWorkbenchPart part) {
\r
317 parts.remove(part);
\r
318 stateRegistry.clearStates(part);
\r
319 part.getSite().getPage().removePartListener(this);
\r
323 public void partDeactivated(IWorkbenchPart part) {
\r
328 public void partOpened(IWorkbenchPart part) {
\r
332 private boolean getToggleState(Command command) {
\r
333 State toggleState = command.getState(RegistryToggleState.STATE_ID);
\r
334 return (Boolean)toggleState.getValue();
\r
337 private abstract class CommandAction extends Action {
\r
338 private Command command;
\r
340 public CommandAction(Command command, String name, ImageDescriptor image, int style) {
\r
342 this.command = command;
\r
344 setImageDescriptor(image);
\r
348 public void run() {
\r
350 handlerService.executeCommand(command.getId(), null);
\r
351 } catch (Exception e) {
\r
352 e.printStackTrace();
\r
356 public Command getCommand() {
\r
360 public String getCommandId() {
\r
361 return command.getId();
\r
365 private class CommandCheckboxAction extends CommandAction {
\r
367 public CommandCheckboxAction(Command command, String name, ImageDescriptor image) {
\r
368 super(command,name,image,Action.AS_CHECK_BOX);
\r
373 public void run() {
\r
374 boolean checked = isChecked();
\r
375 storeToggleActionState(this, checked);
\r
377 if (checked == getToggleState(getCommand()))
\r
378 HandlerUtil.toggleCommandState(getCommand());
\r
379 } catch (ExecutionException e) {
\r
380 e.printStackTrace();
\r
387 private class CommandRadioAction extends CommandAction {
\r
389 private String value;
\r
391 public CommandRadioAction(Command command, String name, String value, ImageDescriptor image) {
\r
392 super(command,name,image,Action.AS_RADIO_BUTTON);
\r
393 this.value = value;
\r
397 public void run() {
\r
398 boolean checked = isChecked();
\r
399 storeRadioActionState(this, checked);
\r
401 HandlerUtil.updateRadioState(getCommand(), value);
\r
402 } catch (ExecutionException e) {
\r
403 e.printStackTrace();
\r
409 public String getValue() {
\r
415 private class CommandPushAction extends CommandAction {
\r
417 public CommandPushAction(Command command, String name, ImageDescriptor image) {
\r
418 super(command,name,image,Action.AS_PUSH_BUTTON);
\r
423 private class ComboContribution extends WorkbenchWindowControlContribution {
\r
424 private TableCombo combo;
\r
426 private List<Action> actions = new ArrayList<Action>();
\r
429 protected Control createControl(Composite parent) {
\r
430 Composite container = new Composite(parent, SWT.NONE);
\r
431 GridLayout glContainer = new GridLayout(1, false);
\r
432 glContainer.marginTop = 0;
\r
433 glContainer.marginHeight = 0;
\r
434 glContainer.marginWidth = 0;
\r
435 container.setLayout(glContainer);
\r
436 GridData glReader = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
\r
437 combo = new TableCombo(container, SWT.BORDER | SWT.READ_ONLY);
\r
438 combo.setLayoutData(glReader);
\r
440 for (Action a : actions) {
\r
441 TableItem item = new TableItem(combo.getTable(), SWT.NONE);
\r
442 item.setText(a.getText());
\r
443 if (a.getImageDescriptor() != null)
\r
444 item.setImage(a.getImageDescriptor().createImage());
\r
447 combo.addSelectionListener(new SelectionListener() {
\r
450 public void widgetSelected(SelectionEvent e) {
\r
451 int index = combo.getSelectionIndex();
\r
454 actions.get(index).run();
\r
458 public void widgetDefaultSelected(SelectionEvent e) {
\r
466 public void addAction(Action a) {
\r
470 void updateSelection() {
\r
473 for (int i = 0; i < actions.size(); i++) {
\r
474 if (actions.get(i).isChecked()) {
\r