--- /dev/null
+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.State;\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.IHandlerService;\r
+import org.eclipse.ui.handlers.RadioState;\r
+import org.eclipse.ui.handlers.RegistryToggleState;\r
+import org.simantics.utils.datastructures.MapList;\r
+\r
+/**\r
+ * Registry for storing command states separately for each IEditorPart\r
+ * \r
+ * TODO : cleaning editor states and listeners is now implemented through ToolBarContributor. Is this OK?\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class CommandStateRegistry {\r
+\r
+ \r
+ private static CommandStateRegistry instance;\r
+ \r
+ \r
+ public static CommandStateRegistry getInstance() {\r
+ if (instance == null)\r
+ instance = new CommandStateRegistry();\r
+ return instance;\r
+ }\r
+ \r
+ \r
+ \r
+ private Map<IWorkbenchPart,Map<String,Boolean>> toggleStates = new HashMap<IWorkbenchPart, Map<String,Boolean>>();\r
+ private Map<String,Boolean> defaultToggleStates = new HashMap<String, Boolean>();\r
+ \r
+ private Map<String,String> defaultRadioStates = new HashMap<String, String>();\r
+ private Map<IWorkbenchPart,Map<String,String>> radioStates = new HashMap<IWorkbenchPart, Map<String,String>>();\r
+\r
+ private ICommandService service;\r
+ private IHandlerService handlerService;\r
+ \r
+ private CommandStateRegistry() {\r
+ service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);\r
+ }\r
+ \r
+ /**\r
+ * Stores default state for a command.\r
+ * \r
+ * Note: uses current state as default. \r
+ * \r
+ * @param commandId\r
+ */\r
+ public void storeDefaultState(String commandId) {\r
+ Command command = service.getCommand(commandId);\r
+ State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
+ State radioState = command.getState(RadioState.STATE_ID);\r
+ if (toggleState != null) {\r
+ if (!defaultToggleStates.containsKey(commandId))\r
+ defaultToggleStates.put(commandId, getToggleState(command));\r
+ } else if (radioState != null) {\r
+ String value = (String) radioState.getValue();\r
+ if (!defaultRadioStates.containsKey(commandId))\r
+ defaultRadioStates.put(commandId, value);\r
+ } else {\r
+ throw new IllegalArgumentException("Command " + commandId + " does not have a state");\r
+ }\r
+ }\r
+ /**\r
+ * Stores toggle state of a command.\r
+ * @param part\r
+ * @param commandId\r
+ * @param checked\r
+ */\r
+ public void setEditorState(IWorkbenchPart part, String commandId, boolean checked) {\r
+ Map<String,Boolean> editorStates = toggleStates.get(part);\r
+ if (editorStates == null) {\r
+ editorStates = new HashMap<String, Boolean>();\r
+ toggleStates.put(part, editorStates);\r
+ }\r
+ editorStates.put(commandId, checked);\r
+ fireStateChange(part, commandId, Boolean.toString(checked));\r
+ }\r
+ \r
+ /**\r
+ * Stores radio state of a command.\r
+ * @param part\r
+ * @param commandId\r
+ * @param value\r
+ */\r
+ public void setEditorState(IWorkbenchPart part, String commandId, String value) {\r
+ Map<String,String> editorStates = radioStates.get(part);\r
+ if (editorStates == null) {\r
+ editorStates = new HashMap<String, String>();\r
+ radioStates.put(part, editorStates);\r
+ }\r
+ editorStates.put(commandId, value);\r
+ fireStateChange(part, commandId, value);\r
+ }\r
+ \r
+ \r
+ \r
+ public Map<String, Boolean> getDefaultToggleStates() {\r
+ return defaultToggleStates;\r
+ }\r
+ \r
+ public Map<String, String> getDefaultRadioStates() {\r
+ return defaultRadioStates;\r
+ }\r
+ \r
+ public Map<String, Boolean> getEditorToggleStates(IWorkbenchPart part) {\r
+ return toggleStates.get(part);\r
+ }\r
+ \r
+ public Map<String, String> getEditorRadioStates(IWorkbenchPart part) {\r
+ return radioStates.get(part);\r
+ }\r
+ \r
+ public Boolean getToggleState(IWorkbenchPart part, String commandId) {\r
+ if (part == null)\r
+ return defaultToggleStates.get(commandId);\r
+ Map<String,Boolean> editorStates = toggleStates.get(part);\r
+ if (editorStates == null) {\r
+ return defaultToggleStates.get(commandId);\r
+ }\r
+ return editorStates.get(commandId);\r
+ }\r
+ \r
+ public String getRadioState(IWorkbenchPart part, String commandId) {\r
+ if (part == null)\r
+ return defaultRadioStates.get(commandId);\r
+ Map<String,String> editorStates = radioStates.get(part);\r
+ if (editorStates == null) {\r
+ return defaultRadioStates.get(commandId);\r
+ }\r
+ return editorStates.get(commandId);\r
+ }\r
+ \r
+ public void clearStates(IWorkbenchPart part) {\r
+ toggleStates.remove(part);\r
+ radioStates.remove(part);\r
+ listenerWithPart.remove(part);\r
+ }\r
+ \r
+ private boolean getToggleState(Command command) {\r
+ State toggleState = command.getState(RegistryToggleState.STATE_ID);\r
+ return (Boolean)toggleState.getValue();\r
+ }\r
+ \r
+ \r
+ private List<CommandStateListener> listeners = new ArrayList<CommandStateListener>();\r
+ private MapList<String, CommandStateListener> listenerWithCommandId = new MapList<String, CommandStateListener>();\r
+ private MapList<IWorkbenchPart, CommandStateListener> listenerWithPart = new MapList<IWorkbenchPart, CommandStateListener>();\r
+ \r
+ /**\r
+ * Attaches a listener that receives all state changes of all commands and all workbench parts.\r
+ * @param listener\r
+ */\r
+ public void addListener(CommandStateListener listener) {\r
+ if (!listeners.contains(listener))\r
+ listeners.add(listener);\r
+ }\r
+ \r
+ /**\r
+ * Attaches a listener to receive state changes of specific workbench part.\r
+ * @param part\r
+ * @param listener\r
+ */\r
+ public void addListener(IWorkbenchPart part, CommandStateListener listener) {\r
+ if (!listenerWithPart.contains(part,listener))\r
+ listenerWithPart.add(part,listener);\r
+ }\r
+ \r
+ /**\r
+ * Attaches a listener to receive state changes of specific command.\r
+ * @param part\r
+ * @param listener\r
+ */\r
+ public void addListener(String commandId, CommandStateListener listener) {\r
+ if (!listenerWithCommandId.contains(commandId,listener))\r
+ listenerWithCommandId.add(commandId, listener);\r
+ }\r
+ \r
+ /**\r
+ * Removes the listener from the registry.\r
+ * @param listener\r
+ */\r
+ public void removeListener(CommandStateListener listener) {\r
+ listeners.remove(listener);\r
+ Set<String> commandIds = new HashSet<String>();\r
+ commandIds.addAll(listenerWithCommandId.getKeys());\r
+ for (String commandId : commandIds) {\r
+ listenerWithCommandId.remove(commandId, listener);\r
+ }\r
+ commandIds.clear();\r
+ Set<IWorkbenchPart> parts = new HashSet<IWorkbenchPart>();\r
+ parts.addAll(listenerWithPart.getKeys());\r
+ for (IWorkbenchPart part : parts) {\r
+ listenerWithPart.remove(part, listener);\r
+ }\r
+ parts.clear();\r
+ }\r
+ \r
+ private List<CommandStateListener> fireList = new ArrayList<CommandStateListener>();\r
+ \r
+ private void fireStateChange(IWorkbenchPart part, String commandId, String state) {\r
+ fireList.clear();\r
+ fireList.addAll(listeners);\r
+ List<CommandStateListener> list = listenerWithCommandId.getValues(commandId);\r
+ if (list != null) {\r
+ fireList.addAll(list);\r
+ \r
+ }\r
+ list = listenerWithPart.getValues(part);\r
+ if (list != null) {\r
+ fireList.addAll(list);\r
+ \r
+ } \r
+ for (CommandStateListener l : fireList) {\r
+ l.stateChanged(part, commandId, state);\r
+ }\r
+\r
+ }\r
+ \r
+}\r