]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.ui/src/org/simantics/ui/contribution/DynamicMenuContribution.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / contribution / DynamicMenuContribution.java
diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/contribution/DynamicMenuContribution.java b/bundles/org.simantics.ui/src/org/simantics/ui/contribution/DynamicMenuContribution.java
new file mode 100644 (file)
index 0000000..728375b
--- /dev/null
@@ -0,0 +1,182 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.ui.contribution;\r
+\r
+import org.eclipse.jface.action.ActionContributionItem;\r
+import org.eclipse.jface.action.IAction;\r
+import org.eclipse.jface.action.IContributionItem;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.ui.ISelectionService;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.actions.CompoundContributionItem;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.utils.RequestUtil;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+/**\r
+ * A more or less carbon copy of CompoundContributionItem with the exception of\r
+ * adding Simantics Graph database traits to the menu filling process.\r
+ * \r
+ * <p>\r
+ * The simplest way to use this class is to override the\r
+ * {@link #getActions(ReadGraph, Object[])} method which should return any\r
+ * actions that you want to be performed on the specified selection. Another way\r
+ * is to override {@link #getContributionItems(ReadGraph, Object[])} that by\r
+ * default simply invokes the simplest method\r
+ * {@link #getActions(ReadGraph, Object[])}. Overriding it allows you to create\r
+ * e.g. submenus, which you cannot do with actions.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * To customize what gets passed to either\r
+ * {@link #getActions(ReadGraph, Object[])} or\r
+ * {@link #getContributionItems(ReadGraph, Object[])} as the selection\r
+ * parameter, override {@link #getSelectedObjects()}\r
+ * </p>\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public abstract class DynamicMenuContribution extends CompoundContributionItem {\r
+\r
+    protected static final Object[] NO_OBJECTS = {};\r
+    protected static final IAction[] NO_ACTIONS = {};\r
+    protected static final IContributionItem[] NONE = {};\r
+\r
+    /**\r
+     * Creates a contribution item with a <code>null</code> id.\r
+     */\r
+    protected DynamicMenuContribution() {\r
+        super();\r
+    }\r
+\r
+    /**\r
+     * Creates a contribution item with the given (optional) id.\r
+     *\r
+     * @param id the contribution item identifier, or <code>null</code>\r
+     */\r
+    protected DynamicMenuContribution(String id) {\r
+        super(id);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.actions.CompoundContributionItem#getContributionItems()\r
+     */\r
+    @Override\r
+    protected final IContributionItem[] getContributionItems() {\r
+        if (DatabaseJob.inProgress())\r
+            return NONE;\r
+        ISessionContext ctx = SimanticsUI.getSessionContext();\r
+        if (ctx != null) {\r
+            final Object[] selection = getSelectedObjects();\r
+            //System.out.println(getClass().getSimpleName() + "@" + System.identityHashCode(this) + "( " + System.identityHashCode(selection) + ": " + Arrays.toString(selection) + " )");\r
+            if (!preAcceptSelection(selection))\r
+                return NONE;\r
+            try {\r
+                return RequestUtil.trySyncRequest(\r
+                        Simantics.getSession(),\r
+                        SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,\r
+                        SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG,\r
+                        NONE,\r
+                        new UniqueRead<IContributionItem[]>() {\r
+                    @Override\r
+                    public IContributionItem[] perform(ReadGraph graph) throws DatabaseException {\r
+                        return getContributionItems(graph, selection);\r
+                    }\r
+                    @Override\r
+                    public String toString() {\r
+                        return DynamicMenuContribution.this.toString();\r
+                    }\r
+                });\r
+            } catch (DatabaseException | InterruptedException e) {\r
+                ErrorLogger.defaultLogError(e);\r
+            }\r
+        }\r
+        return NONE;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.actions.CompoundContributionItem#isDynamic()\r
+     */\r
+    @Override\r
+    public boolean isDynamic() {\r
+        return true;\r
+    }\r
+\r
+    //////////////////////////////////////////////////////////////////////////\r
+\r
+    protected ISelection getSelection() {\r
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();\r
+        ISelectionService service = window.getSelectionService();\r
+        return service.getSelection();\r
+    }\r
+\r
+    protected Object[] getSelectedObjects() {\r
+        ISelection sel = getSelection();\r
+        if (!(sel instanceof IStructuredSelection))\r
+            return NO_OBJECTS;\r
+        return ((IStructuredSelection) sel).toArray();\r
+    }\r
+\r
+    protected Object getSingleSelectedObject() {\r
+        Object[] resources = getSelectedObjects();\r
+        return resources.length == 1 ? resources[0] : null;\r
+    }\r
+\r
+    protected IContributionItem[] toContributionItems(IAction... actions) {\r
+        if (actions == null)\r
+            return NONE;\r
+\r
+        IContributionItem[] ret = new IContributionItem[actions.length];\r
+        for (int i = 0; i < actions.length; ++i)\r
+            ret[i] = new ActionContributionItem(actions[i]);\r
+\r
+        return ret;\r
+    }\r
+\r
+    //////////////////////////////////////////////////////////////////////////\r
+    // Override these where needed\r
+\r
+    /**\r
+     * Tests the input selection for whether it can produce any meaningful\r
+     * contribution items in the first place. This is a filter that is invoked\r
+     * before performing a database request to find out more about the possible\r
+     * contributions.\r
+     * \r
+     * <p>\r
+     * The default implementation checks that the input selection is not empty.\r
+     * To be able to provide contributions for empty selection, you must\r
+     * override this method.\r
+     * \r
+     * @param selection\r
+     * @return\r
+     */\r
+    protected boolean preAcceptSelection(Object[] selection) {\r
+        return selection != null && selection.length > 0;\r
+    }\r
+\r
+    protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {\r
+        return toContributionItems( getActions(graph, selection) );\r
+    }\r
+\r
+    protected IAction[] getActions(ReadGraph graph, Object[] selection) throws DatabaseException {\r
+        return new IAction[0];\r
+    }\r
+\r
+}\r