+package org.simantics.event.view.handler;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.jface.action.IAction;\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.dnd.Clipboard;\r
+import org.eclipse.swt.dnd.TextTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleTypedParent;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.event.Activator;\r
+import org.simantics.event.ontology.EventResource;\r
+import org.simantics.ui.contribution.DynamicMenuContribution;\r
+import org.simantics.ui.workbench.action.PerformDefaultAction;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class MenuActions extends DynamicMenuContribution {\r
+\r
+ /**\r
+ * The name of the virtual graph the menu actions perform their changes into.\r
+ */\r
+ private static final String VG_EXPERIMENTS = "experiments";\r
+\r
+ @Override\r
+ protected Object[] getSelectedObjects() {\r
+ ISelection sel = getSelection();\r
+ List<Resource> resources = ISelectionUtils.getPossibleKeys(sel, SelectionHints.KEY_MAIN, Resource.class);\r
+ return resources.toArray();\r
+ }\r
+\r
+ List<Resource> toResources(Object[] array) {\r
+ Resource[] a = new Resource[array.length];\r
+ for (int i = 0; i < array.length; ++i)\r
+ a[i] = (Resource) array[i];\r
+ return Arrays.asList(a);\r
+ }\r
+\r
+ @Override\r
+ protected IAction[] getActions(ReadGraph graph, Object[] selection) throws DatabaseException {\r
+ if (selection.length == 0)\r
+ return new IAction[0];\r
+\r
+ List<Resource> input = toResources(selection);\r
+ if (input.isEmpty())\r
+ return new IAction[0];\r
+\r
+ boolean logs = false;\r
+ boolean events = false;\r
+\r
+ EventResource EVENT = EventResource.getInstance(graph);\r
+ int hiddenCount = 0; \r
+ int milestoneCount = 0; \r
+ int hasSourceCount = 0;\r
+ for (Resource r : input) {\r
+ logs |= graph.isInstanceOf(r, EVENT.EventLog);\r
+ events |= graph.isInstanceOf(r, EVENT.Event);\r
+ if (graph.hasStatement(r, EVENT.Hidden))\r
+ ++hiddenCount;\r
+ if (graph.hasStatement(r, EVENT.Milestone))\r
+ ++milestoneCount;\r
+ if (graph.hasStatement(r, EVENT.Event_source))\r
+ ++hasSourceCount;\r
+ }\r
+ boolean allHidden = hiddenCount == selection.length;\r
+ boolean allMilestones= milestoneCount == selection.length;\r
+\r
+ Resource event = null;\r
+ String eventSourceName = null;\r
+ if (input.size() == 1) {\r
+ event = input.get(0);\r
+ if (hasSourceCount == 1) {\r
+ eventSourceName = graph.getPossibleRelatedValue(event, EVENT.Event_sourceName, Bindings.STRING);\r
+ }\r
+ }\r
+\r
+ List<IAction> actions = new ArrayList<IAction>();\r
+\r
+ if (eventSourceName != null && !eventSourceName.isEmpty())\r
+ actions.add(toClipboardAction(eventSourceName, eventSourceName));\r
+ if (!allHidden)\r
+ actions.add(hideAction(input));\r
+ if (hiddenCount > 0 || allHidden)\r
+ actions.add(unhideAction(input));\r
+\r
+ if (!logs && !allMilestones)\r
+ actions.add(markMilestoneAction(input));\r
+ if (!logs && (milestoneCount > 0 || allMilestones)) {\r
+ Resource eventLog = graph.syncRequest(new PossibleTypedParent(input.get(0), EVENT.EventLog));\r
+ actions.add(unmarkMilestoneAction(eventLog, input));\r
+ }\r
+\r
+ if (!logs && events && event != null) {\r
+ Resource eventLog = graph.syncRequest(new PossibleTypedParent(event, EVENT.EventLog));\r
+ if (eventLog != null) {\r
+ boolean isBaseline = graph.hasStatement(eventLog, EVENT.EventLog_HasBaselineEvent, event);\r
+ if (isBaseline && allMilestones)\r
+ actions.add(removeBaseline(Collections.singletonList(eventLog)));\r
+ else\r
+ actions.add(setBaseline(eventLog, event));\r
+ }\r
+ }\r
+ if (logs && !events) {\r
+ actions.add(removeBaseline(input));\r
+ }\r
+\r
+ if (event != null && hasSourceCount == 1) {\r
+ Resource eventSource = graph.getPossibleObject(event, EVENT.Event_source);\r
+ if (eventSource != null)\r
+ actions.add(performDefaultAction(eventSource, null));\r
+ }\r
+\r
+ return actions.toArray(new IAction[actions.size()]);\r
+ }\r
+\r
+ private IAction toClipboardAction(String label, String text) {\r
+ return new ToClipboardAction(label, text);\r
+ }\r
+\r
+ private IAction markMilestoneAction(List<Resource> input) {\r
+ return tagAction("Mark as Milestone", Activator.MARK_MILESTONE_ICON, EventResource.URIs.Milestone, true, input);\r
+ }\r
+\r
+ private IAction unmarkMilestoneAction(Resource eventLog, List<Resource> input) {\r
+ return new UnmarkMilestone(VG_EXPERIMENTS, eventLog, input);\r
+ }\r
+\r
+ private IAction unhideAction(List<Resource> input) {\r
+ return tagAction("Unhide", Activator.UNHIDE_ICON, EventResource.URIs.Hidden, false, input);\r
+ }\r
+\r
+ private IAction hideAction(List<Resource> input) {\r
+ return tagAction("Hide", Activator.HIDE_ICON, EventResource.URIs.Hidden, true, input);\r
+ }\r
+\r
+ private IAction tagAction(String label, ImageDescriptor image, String tagURI, boolean tag, List<Resource> input) {\r
+ return new TagAction(label, image, VG_EXPERIMENTS, tagURI, tag, input);\r
+ }\r
+\r
+ private IAction setBaseline(Resource eventLog, Resource event) {\r
+ return new SetBaseline(VG_EXPERIMENTS, eventLog, event);\r
+ }\r
+\r
+ private IAction removeBaseline(List<Resource> logs) {\r
+ return new DenyAction("Remove Baseline", Activator.REMOVE_BASELINE_ICON, VG_EXPERIMENTS, EventResource.URIs.EventLog_HasBaselineEvent, logs);\r
+ }\r
+\r
+ private IAction performDefaultAction(Resource input, String sourceName) {\r
+ String title = "Show Event Source";\r
+ if (sourceName != null)\r
+ title += " (" + sourceName + ")";\r
+ return new PerformDefaultAction(title, null, input);\r
+ }\r
+\r
+ private static class ToClipboardAction extends Action {\r
+ private String text;\r
+\r
+ public ToClipboardAction(String label, String text) {\r
+ super(label, Activator.CLIPBOARD_ICON);\r
+ this.text = text;\r
+ }\r
+\r
+ @Override\r
+ public void run() {\r
+ Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());\r
+ clipboard.setContents(\r
+ new Object[] { text },\r
+ new Transfer[] { TextTransfer.getInstance() }\r
+ );\r
+ clipboard.dispose();\r
+\r
+ // Show a message in the status line if possible\r
+ IWorkbenchPart part = WorkbenchUtils.getActiveWorkbenchPart();\r
+ if (part != null) {\r
+ IStatusLineManager status = WorkbenchUtils.getStatusLine(part);\r
+ if (status != null) {\r
+ status.setErrorMessage(null);\r
+ status.setMessage("Copied '" + text + "' to clipboard");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private static class UnmarkMilestone extends TagAction {\r
+ private final Resource eventLog;\r
+ private final List<Resource> events;\r
+ public UnmarkMilestone(String virtualGraphId, Resource eventLog, List<Resource> events) {\r
+ super("Unmark Milestone", Activator.UNMARK_MILESTONE_ICON, virtualGraphId, EventResource.URIs.Milestone, false, events);\r
+ this.eventLog = eventLog;\r
+ this.events = events;\r
+ }\r
+ @Override\r
+ public void postTagWrite(WriteGraph graph) throws DatabaseException {\r
+ EventResource EVENT = EventResource.getInstance(graph);\r
+ Resource baselineEvent = graph.getPossibleObject(eventLog, EVENT.EventLog_HasBaselineEvent);\r
+ if (baselineEvent != null) {\r
+ if (events.contains(baselineEvent)) {\r
+ graph.deny(eventLog, EVENT.EventLog_HasBaselineEvent);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private static class SetBaseline extends ClaimAction {\r
+ public SetBaseline(String virtualGraphId, Resource subject, Resource object) {\r
+ super("Set Baseline", Activator.SET_BASELINE_ICON, virtualGraphId, subject, EventResource.URIs.EventLog_HasBaselineEvent, object);\r
+ }\r
+ @Override\r
+ public void claim(WriteGraph graph) throws DatabaseException {\r
+ super.claim(graph);\r
+ EventResource EVENT = EventResource.getInstance(graph);\r
+ if (!graph.hasStatement(object, EVENT.Milestone)) {\r
+ graph.claim(object, EVENT.Milestone, object);\r
+ CorrectMilestoneLabelsAction.correctMilestoneLabels(graph, graph.getProvider(), Collections.singleton(object));\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file