Merge "Databoard and SCL enchancements."
[simantics/platform.git] / bundles / org.simantics.event / src / org / simantics / event / view / handler / MenuActions.java
1 package org.simantics.event.view.handler;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Arrays;\r
5 import java.util.Collections;\r
6 import java.util.List;\r
7 \r
8 import org.eclipse.jface.action.Action;\r
9 import org.eclipse.jface.action.IAction;\r
10 import org.eclipse.jface.action.IStatusLineManager;\r
11 import org.eclipse.jface.resource.ImageDescriptor;\r
12 import org.eclipse.jface.viewers.ISelection;\r
13 import org.eclipse.swt.dnd.Clipboard;\r
14 import org.eclipse.swt.dnd.TextTransfer;\r
15 import org.eclipse.swt.dnd.Transfer;\r
16 import org.eclipse.ui.IWorkbenchPart;\r
17 import org.eclipse.ui.PlatformUI;\r
18 import org.simantics.databoard.Bindings;\r
19 import org.simantics.db.ReadGraph;\r
20 import org.simantics.db.Resource;\r
21 import org.simantics.db.WriteGraph;\r
22 import org.simantics.db.common.request.PossibleTypedParent;\r
23 import org.simantics.db.exception.DatabaseException;\r
24 import org.simantics.db.layer0.SelectionHints;\r
25 import org.simantics.event.Activator;\r
26 import org.simantics.event.ontology.EventResource;\r
27 import org.simantics.ui.contribution.DynamicMenuContribution;\r
28 import org.simantics.ui.workbench.action.PerformDefaultAction;\r
29 import org.simantics.utils.ui.ISelectionUtils;\r
30 import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
31 \r
32 /**\r
33  * @author Tuukka Lehtonen\r
34  */\r
35 public class MenuActions extends DynamicMenuContribution {\r
36 \r
37     /**\r
38      * The name of the virtual graph the menu actions perform their changes into.\r
39      */\r
40     private static final String VG_EXPERIMENTS = "experiments";\r
41 \r
42     @Override\r
43     protected Object[] getSelectedObjects() {\r
44         ISelection sel = getSelection();\r
45         List<Resource> resources = ISelectionUtils.getPossibleKeys(sel, SelectionHints.KEY_MAIN, Resource.class);\r
46         return resources.toArray();\r
47     }\r
48 \r
49     List<Resource> toResources(Object[] array) {\r
50         Resource[] a = new Resource[array.length];\r
51         for (int i = 0; i < array.length; ++i)\r
52             a[i] = (Resource) array[i];\r
53         return Arrays.asList(a);\r
54     }\r
55 \r
56     @Override\r
57     protected IAction[] getActions(ReadGraph graph, Object[] selection) throws DatabaseException {\r
58         if (selection.length == 0)\r
59             return new IAction[0];\r
60 \r
61         List<Resource> input = toResources(selection);\r
62         if (input.isEmpty())\r
63             return new IAction[0];\r
64 \r
65         boolean logs = false;\r
66         boolean events = false;\r
67 \r
68         EventResource EVENT = EventResource.getInstance(graph);\r
69         int hiddenCount = 0; \r
70         int milestoneCount = 0; \r
71         int hasSourceCount = 0;\r
72         for (Resource r : input) {\r
73             logs |= graph.isInstanceOf(r, EVENT.EventLog);\r
74             events |= graph.isInstanceOf(r, EVENT.Event);\r
75             if (graph.hasStatement(r, EVENT.Hidden))\r
76                 ++hiddenCount;\r
77             if (graph.hasStatement(r, EVENT.Milestone))\r
78                 ++milestoneCount;\r
79             if (graph.hasStatement(r, EVENT.Event_source))\r
80                 ++hasSourceCount;\r
81         }\r
82         boolean allHidden = hiddenCount == selection.length;\r
83         boolean allMilestones= milestoneCount == selection.length;\r
84 \r
85         Resource event = null;\r
86         String eventSourceName = null;\r
87         if (input.size() == 1) {\r
88             event = input.get(0);\r
89             if (hasSourceCount == 1) {\r
90                 eventSourceName = graph.getPossibleRelatedValue(event, EVENT.Event_sourceName, Bindings.STRING);\r
91             }\r
92         }\r
93 \r
94         List<IAction> actions = new ArrayList<IAction>();\r
95 \r
96         if (eventSourceName != null && !eventSourceName.isEmpty())\r
97             actions.add(toClipboardAction(eventSourceName, eventSourceName));\r
98         if (!allHidden)\r
99             actions.add(hideAction(input));\r
100         if (hiddenCount > 0 || allHidden)\r
101             actions.add(unhideAction(input));\r
102 \r
103         if (!logs && !allMilestones)\r
104             actions.add(markMilestoneAction(input));\r
105         if (!logs && (milestoneCount > 0 || allMilestones)) {\r
106             Resource eventLog = graph.syncRequest(new PossibleTypedParent(input.get(0), EVENT.EventLog));\r
107             actions.add(unmarkMilestoneAction(eventLog, input));\r
108         }\r
109 \r
110         if (!logs && events && event != null) {\r
111             Resource eventLog = graph.syncRequest(new PossibleTypedParent(event, EVENT.EventLog));\r
112             if (eventLog != null) {\r
113                 boolean isBaseline = graph.hasStatement(eventLog, EVENT.EventLog_HasBaselineEvent, event);\r
114                 if (isBaseline && allMilestones)\r
115                     actions.add(removeBaseline(Collections.singletonList(eventLog)));\r
116                 else\r
117                     actions.add(setBaseline(eventLog, event));\r
118             }\r
119         }\r
120         if (logs && !events) {\r
121             actions.add(removeBaseline(input));\r
122         }\r
123 \r
124         if (event != null && hasSourceCount == 1) {\r
125             Resource eventSource = graph.getPossibleObject(event, EVENT.Event_source);\r
126             if (eventSource != null)\r
127                 actions.add(performDefaultAction(eventSource, null));\r
128         }\r
129 \r
130         return actions.toArray(new IAction[actions.size()]);\r
131     }\r
132 \r
133     private IAction toClipboardAction(String label, String text) {\r
134         return new ToClipboardAction(label, text);\r
135     }\r
136 \r
137     private IAction markMilestoneAction(List<Resource> input) {\r
138         return tagAction("Mark as Milestone", Activator.MARK_MILESTONE_ICON, EventResource.URIs.Milestone, true, input);\r
139     }\r
140 \r
141     private IAction unmarkMilestoneAction(Resource eventLog, List<Resource> input) {\r
142         return new UnmarkMilestone(VG_EXPERIMENTS, eventLog, input);\r
143     }\r
144 \r
145     private IAction unhideAction(List<Resource> input) {\r
146         return tagAction("Unhide", Activator.UNHIDE_ICON, EventResource.URIs.Hidden, false, input);\r
147     }\r
148 \r
149     private IAction hideAction(List<Resource> input) {\r
150         return tagAction("Hide", Activator.HIDE_ICON, EventResource.URIs.Hidden, true, input);\r
151     }\r
152 \r
153     private IAction tagAction(String label, ImageDescriptor image, String tagURI, boolean tag, List<Resource> input) {\r
154         return new TagAction(label, image, VG_EXPERIMENTS, tagURI, tag, input);\r
155     }\r
156 \r
157     private IAction setBaseline(Resource eventLog, Resource event) {\r
158         return new SetBaseline(VG_EXPERIMENTS, eventLog, event);\r
159     }\r
160 \r
161     private IAction removeBaseline(List<Resource> logs) {\r
162         return new DenyAction("Remove Baseline", Activator.REMOVE_BASELINE_ICON, VG_EXPERIMENTS, EventResource.URIs.EventLog_HasBaselineEvent, logs);\r
163     }\r
164 \r
165     private IAction performDefaultAction(Resource input, String sourceName) {\r
166         String title = "Show Event Source";\r
167         if (sourceName != null)\r
168             title += " (" + sourceName + ")";\r
169         return new PerformDefaultAction(title, null, input);\r
170     }\r
171 \r
172     private static class ToClipboardAction extends Action {\r
173         private String text;\r
174 \r
175         public ToClipboardAction(String label, String text) {\r
176             super(label, Activator.CLIPBOARD_ICON);\r
177             this.text = text;\r
178         }\r
179 \r
180         @Override\r
181         public void run() {\r
182             Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());\r
183             clipboard.setContents(\r
184                     new Object[] { text },\r
185                     new Transfer[] { TextTransfer.getInstance() }\r
186                     );\r
187             clipboard.dispose();\r
188 \r
189             // Show a message in the status line if possible\r
190             IWorkbenchPart part = WorkbenchUtils.getActiveWorkbenchPart();\r
191             if (part != null) {\r
192                 IStatusLineManager status = WorkbenchUtils.getStatusLine(part);\r
193                 if (status != null) {\r
194                     status.setErrorMessage(null);\r
195                     status.setMessage("Copied '" + text + "' to clipboard");\r
196                 }\r
197             }\r
198         }\r
199     }\r
200 \r
201     private static class UnmarkMilestone extends TagAction {\r
202         private final Resource eventLog;\r
203         private final List<Resource> events;\r
204         public UnmarkMilestone(String virtualGraphId, Resource eventLog, List<Resource> events) {\r
205             super("Unmark Milestone", Activator.UNMARK_MILESTONE_ICON, virtualGraphId, EventResource.URIs.Milestone, false, events);\r
206             this.eventLog = eventLog;\r
207             this.events = events;\r
208         }\r
209         @Override\r
210         public void postTagWrite(WriteGraph graph) throws DatabaseException {\r
211             EventResource EVENT = EventResource.getInstance(graph);\r
212             Resource baselineEvent = graph.getPossibleObject(eventLog, EVENT.EventLog_HasBaselineEvent);\r
213             if (baselineEvent != null) {\r
214                 if (events.contains(baselineEvent)) {\r
215                     graph.deny(eventLog, EVENT.EventLog_HasBaselineEvent);\r
216                 }\r
217             }\r
218         }\r
219     }\r
220 \r
221     private static class SetBaseline extends ClaimAction {\r
222         public SetBaseline(String virtualGraphId, Resource subject, Resource object) {\r
223             super("Set Baseline", Activator.SET_BASELINE_ICON, virtualGraphId, subject, EventResource.URIs.EventLog_HasBaselineEvent, object);\r
224         }\r
225         @Override\r
226         public void claim(WriteGraph graph) throws DatabaseException {\r
227             super.claim(graph);\r
228             EventResource EVENT = EventResource.getInstance(graph);\r
229             if (!graph.hasStatement(object, EVENT.Milestone)) {\r
230                 graph.claim(object, EVENT.Milestone, object);\r
231                 CorrectMilestoneLabelsAction.correctMilestoneLabels(graph, graph.getProvider(), Collections.singleton(object));\r
232             }\r
233         }\r
234     }\r
235 }