1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.ui.contribution;
\r
14 import org.eclipse.jface.action.ActionContributionItem;
\r
15 import org.eclipse.jface.action.IAction;
\r
16 import org.eclipse.jface.action.IContributionItem;
\r
17 import org.eclipse.jface.viewers.ISelection;
\r
18 import org.eclipse.jface.viewers.IStructuredSelection;
\r
19 import org.eclipse.ui.ISelectionService;
\r
20 import org.eclipse.ui.IWorkbenchWindow;
\r
21 import org.eclipse.ui.PlatformUI;
\r
22 import org.eclipse.ui.actions.CompoundContributionItem;
\r
23 import org.simantics.DatabaseJob;
\r
24 import org.simantics.Simantics;
\r
25 import org.simantics.db.ReadGraph;
\r
26 import org.simantics.db.common.request.UniqueRead;
\r
27 import org.simantics.db.common.utils.RequestUtil;
\r
28 import org.simantics.db.exception.DatabaseException;
\r
29 import org.simantics.db.management.ISessionContext;
\r
30 import org.simantics.ui.SimanticsUI;
\r
31 import org.simantics.utils.ui.ErrorLogger;
\r
34 * A more or less carbon copy of CompoundContributionItem with the exception of
\r
35 * adding Simantics Graph database traits to the menu filling process.
\r
38 * The simplest way to use this class is to override the
\r
39 * {@link #getActions(ReadGraph, Object[])} method which should return any
\r
40 * actions that you want to be performed on the specified selection. Another way
\r
41 * is to override {@link #getContributionItems(ReadGraph, Object[])} that by
\r
42 * default simply invokes the simplest method
\r
43 * {@link #getActions(ReadGraph, Object[])}. Overriding it allows you to create
\r
44 * e.g. submenus, which you cannot do with actions.
\r
48 * To customize what gets passed to either
\r
49 * {@link #getActions(ReadGraph, Object[])} or
\r
50 * {@link #getContributionItems(ReadGraph, Object[])} as the selection
\r
51 * parameter, override {@link #getSelectedObjects()}
\r
54 * @author Tuukka Lehtonen
\r
56 public abstract class DynamicMenuContribution extends CompoundContributionItem {
\r
58 protected static final Object[] NO_OBJECTS = {};
\r
59 protected static final IAction[] NO_ACTIONS = {};
\r
60 protected static final IContributionItem[] NONE = {};
\r
63 * Creates a contribution item with a <code>null</code> id.
\r
65 protected DynamicMenuContribution() {
\r
70 * Creates a contribution item with the given (optional) id.
\r
72 * @param id the contribution item identifier, or <code>null</code>
\r
74 protected DynamicMenuContribution(String id) {
\r
79 * @see org.eclipse.ui.actions.CompoundContributionItem#getContributionItems()
\r
82 protected final IContributionItem[] getContributionItems() {
\r
83 if (DatabaseJob.inProgress())
\r
85 ISessionContext ctx = SimanticsUI.getSessionContext();
\r
87 final Object[] selection = getSelectedObjects();
\r
88 //System.out.println(getClass().getSimpleName() + "@" + System.identityHashCode(this) + "( " + System.identityHashCode(selection) + ": " + Arrays.toString(selection) + " )");
\r
89 if (!preAcceptSelection(selection))
\r
92 return RequestUtil.trySyncRequest(
\r
93 Simantics.getSession(),
\r
94 SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
\r
95 SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT_LONG,
\r
97 new UniqueRead<IContributionItem[]>() {
\r
99 public IContributionItem[] perform(ReadGraph graph) throws DatabaseException {
\r
100 return getContributionItems(graph, selection);
\r
103 public String toString() {
\r
104 return DynamicMenuContribution.this.toString();
\r
107 } catch (DatabaseException | InterruptedException e) {
\r
108 ErrorLogger.defaultLogError(e);
\r
115 * @see org.eclipse.ui.actions.CompoundContributionItem#isDynamic()
\r
118 public boolean isDynamic() {
\r
122 //////////////////////////////////////////////////////////////////////////
\r
124 protected ISelection getSelection() {
\r
125 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
\r
126 ISelectionService service = window.getSelectionService();
\r
127 return service.getSelection();
\r
130 protected Object[] getSelectedObjects() {
\r
131 ISelection sel = getSelection();
\r
132 if (!(sel instanceof IStructuredSelection))
\r
134 return ((IStructuredSelection) sel).toArray();
\r
137 protected Object getSingleSelectedObject() {
\r
138 Object[] resources = getSelectedObjects();
\r
139 return resources.length == 1 ? resources[0] : null;
\r
142 protected IContributionItem[] toContributionItems(IAction... actions) {
\r
143 if (actions == null)
\r
146 IContributionItem[] ret = new IContributionItem[actions.length];
\r
147 for (int i = 0; i < actions.length; ++i)
\r
148 ret[i] = new ActionContributionItem(actions[i]);
\r
153 //////////////////////////////////////////////////////////////////////////
\r
154 // Override these where needed
\r
157 * Tests the input selection for whether it can produce any meaningful
\r
158 * contribution items in the first place. This is a filter that is invoked
\r
159 * before performing a database request to find out more about the possible
\r
163 * The default implementation checks that the input selection is not empty.
\r
164 * To be able to provide contributions for empty selection, you must
\r
165 * override this method.
\r
170 protected boolean preAcceptSelection(Object[] selection) {
\r
171 return selection != null && selection.length > 0;
\r
174 protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {
\r
175 return toContributionItems( getActions(graph, selection) );
\r
178 protected IAction[] getActions(ReadGraph graph, Object[] selection) throws DatabaseException {
\r
179 return new IAction[0];
\r