/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.ui.workbench.action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.ui.DoubleClickEvent; import org.simantics.ui.DoubleClickExtensionManager; import org.simantics.ui.IDoubleClickExtension; import org.simantics.ui.dialogs.ActionChooserDialog; import org.simantics.ui.utils.ResourceAdaptionUtils; import org.simantics.utils.ui.action.IPriorityAction; /** * @author Tuukka Lehtonen */ public class ChooseActionRequest extends ReadRequest { protected Shell parent; protected Object widget; protected Object input; protected String perspectiveId; protected IPriorityAction[] actions; protected String resourceName; protected boolean rememberAction; protected boolean alwaysAsk; /** * Set to true to never prompt for an action if the selection is ambiguous. */ protected boolean neverPromptForAction; /** * @param parent * @param input * @param forPerspectiveId */ public ChooseActionRequest(Shell parent, Object input, String forPerspectiveId) { this(parent, null, input, forPerspectiveId, true, false); } /** * @param parent * @param input * @param forPerspectiveId */ public ChooseActionRequest(Shell parent, Object widget, Object input, String forPerspectiveId) { this(parent, widget, input, forPerspectiveId, true, false); } /** * @param parent * @param input * @param forPerspectiveId * @param rememberAction * @param alwaysAsk */ public ChooseActionRequest(Shell parent, Object input, String forPerspectiveId, boolean rememberAction, boolean alwaysAsk) { this(parent, null, input, forPerspectiveId, true, false); } /** * @param parent * @param input * @param forPerspectiveId * @param rememberAction * @param alwaysAsk */ public ChooseActionRequest(Shell parent, Object widget, Object input, String forPerspectiveId, boolean rememberAction, boolean alwaysAsk) { this(parent, widget, input, forPerspectiveId, rememberAction, alwaysAsk, false); } /** * @param parent * @param input * @param forPerspectiveId * @param rememberAction * @param alwaysAsk * @param neverPromptForAction true to never prompt/run an action if the * action selection is ambiguous */ public ChooseActionRequest(Shell parent, Object widget, Object input, String forPerspectiveId, boolean rememberAction, boolean alwaysAsk, boolean neverPromptForAction) { if (input == null) throw new NullPointerException("null input"); this.parent = parent; this.widget = widget; this.input = input; this.perspectiveId = forPerspectiveId; this.rememberAction = rememberAction; this.alwaysAsk = alwaysAsk; this.neverPromptForAction = neverPromptForAction; } private String getResourceName(ReadGraph graph, Object resource) throws DatabaseException { Resource r = ResourceAdaptionUtils.toSingleResource(resource); if (r == null) return resource.toString(); return NameUtils.getSafeName(graph, r); } @Override public void run(ReadGraph graph) throws DatabaseException { resourceName = getResourceName(graph, input); actions = findActions(graph, widget, input, perspectiveId, rememberAction, alwaysAsk); if (actions != null) scheduleChooseAction(actions); } // @Override // public void handleException(Throwable e) { // ExceptionUtils.logAndShowError(e); // } public void scheduleChooseAction(final IPriorityAction[] actions) { if(parent == null) { if (actions.length > 0) { actions[0].run(); return; } } else { parent.getDisplay().asyncExec(() -> { if (parent.isDisposed()) return; // System.out.println("ACTIONS: " + Arrays.toString(actions)); IAction action = chooseAction(parent, actions, resourceName, neverPromptForAction); if (action != null) { action.run(); return; } }); } } public static IPriorityAction[] findActions(ReadGraph g, Resource r, String forPerspectiveId) throws DatabaseException { return findActions(g, null, r, forPerspectiveId, true, false); } public static IPriorityAction[] findActions(ReadGraph g, Object widget, Resource r, String forPerspectiveId) throws DatabaseException { return findActions(g, widget, r, forPerspectiveId, true, false); } public static IPriorityAction[] findActions(ReadGraph g, Object r, String forPerspectiveId, boolean rememberAction, boolean alwaysAsk) throws DatabaseException { return findActions(g, null, r, forPerspectiveId, true, false); } public static IPriorityAction[] findActions(ReadGraph g, Object widget, Object r, String forPerspectiveId, boolean rememberAction, boolean alwaysAsk) throws DatabaseException { DoubleClickEvent dbe = new DoubleClickEvent(ChooseActionRequest.class, g, r); dbe.getHintContext().setHint(IWorkbenchActionHints.KEY_CURRENTPERSPECTIVE, forPerspectiveId); dbe.getHintContext().setHint(IWorkbenchActionHints.KEY_REMEMBER, rememberAction); dbe.getHintContext().setHint(IWorkbenchActionHints.KEY_ALWAYS_ASK, alwaysAsk); if (widget != null) dbe.getHintContext().setHint(IWorkbenchActionHints.KEY_WIDGET, widget); for (IDoubleClickExtension ext : DoubleClickExtensionManager.getInstance().getExtensions()) { ext.getAction().doubleClickEvent(dbe); // Found handler? if (dbe.isConsumed()) break; } return dbe.getOrderedActions(); } public static IAction chooseAction(Shell parentShell, IPriorityAction[] actions, String resourceName) { return chooseAction(parentShell, actions, resourceName, false); } public static IAction chooseAction(Shell parentShell, IPriorityAction[] actions, String resourceName, boolean neverPromptForAction) { int len = actions.length; if (len == 1) { // Just use the only action if its priority is >= 0. return actions[0].getPriority() >= 0 ? actions[0] : null; } else if (len > 1) { // If there is a single highest priority action, use // it if its priority is >= 0. if (actions[0].getPriority() > actions[1].getPriority()) { return actions[0].getPriority() >= 0 ? actions[0] : null; } if (neverPromptForAction) return null; // Otherwise give the user a chance to choose from // the available actions. ActionChooserDialog dlg = new ActionChooserDialog(parentShell, actions, "Choose Action", "Choose action for '" + resourceName + "'"); int ret = dlg.open(); if (ret != Window.OK) return null; return dlg.getChosenAction(); } return null; } }