Combination of Simantics-platform related changes and fixes for district
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / workbench / e4 / E4WorkbenchUtils.java
1 package org.simantics.ui.workbench.e4;
2
3 import java.util.List;
4 import java.util.Map;
5
6 import org.eclipse.e4.core.contexts.IEclipseContext;
7 import org.eclipse.e4.ui.model.application.MApplication;
8 import org.eclipse.e4.ui.model.application.commands.MCommand;
9 import org.eclipse.e4.ui.model.application.ui.MUIElement;
10 import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
11 import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
12 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
13 import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
14 import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
15 import org.eclipse.e4.ui.workbench.modeling.EModelService;
16 import org.eclipse.e4.ui.workbench.modeling.EPartService;
17 import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
18 import org.eclipse.ui.IEditorPart;
19 import org.eclipse.ui.PlatformUI;
20 import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
21 import org.simantics.db.Resource;
22 import org.simantics.utils.datastructures.ArrayMap;
23 import org.simantics.utils.ui.workbench.WorkbenchUtils;
24
25 /**
26  * @author Tuukka Lehtonen
27  *
28  */
29 public class E4WorkbenchUtils {
30
31     private static final String[] KEYS_RESOURCE = { E4ResourceEditorConstants.KEY_RESOURCE };
32
33     /**
34      * 
35      */
36     private static final String TAG_EDITOR = "Editor";
37
38     /**
39      * The Legacy IDE application ID for the "editor area" partstack. In E3
40      * compatibility mode legacy application the {@link MPartStack} lies under
41      * the shared {@link MArea} (org.eclipse.ui.editorss).
42      * 
43      * <p>
44      * In a pure E4 application this needs to be changed.
45      */
46     public static final String EDITOR_PART_STACK_ID = "org.eclipse.e4.primaryDataStack";
47
48     public static final String EDITOR_AREA_ID = "org.eclipse.ui.editorss";
49
50     /**
51      * @param editorId
52      * @param contributionURI
53      * @param iconURI
54      * @param inputId
55      * @param inputMap
56      */
57     public static MPart openEditor(String editorId, String contributionURI, String iconURI, String inputId, Map<String, Object> inputMap) {
58         if (editorId == null)
59             throw new NullPointerException("null editor ID");
60         if (contributionURI == null)
61             throw new NullPointerException("null contributionURI");
62         if (inputId == null)
63             throw new NullPointerException("null input ID");
64         if (inputMap == null)
65             throw new NullPointerException("null input map");
66
67         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
68         EModelService modelService = context.get(EModelService.class);
69         EPartService partService = context.get(EPartService.class);
70         MApplication app = context.get(MApplication.class);
71
72         String editorID = editorId + "_" + inputId;
73
74         List<MPart> parts = modelService.findElements(app, editorID, MPart.class, null);
75         MPart editor = null;
76         if (parts == null || parts.isEmpty()) {
77             editor = modelService.createModelElement(MPart.class);
78             editor.setElementId(editorID);
79             editor.setContributionURI(contributionURI);
80             if (iconURI != null)
81                 editor.setIconURI(iconURI);
82             editor.setCloseable(true);
83             editor.getTags().add(TAG_EDITOR);
84             editor.getTransientData().putAll(inputMap);
85
86             MPartStack stack = getEditorPartStack(modelService, app);
87             stack.getChildren().add(editor);
88         } else {
89             editor = parts.get(0);
90         }
91
92         partService.showPart(editor, PartState.ACTIVATE);
93         return editor;
94     }
95
96     /**
97      * @param editorId
98      * @param contributionURI
99      * @param iconURI
100      * @param input
101      */
102     public static MPart openEditor(String editorId, String contributionURI, String iconURI, Resource input) {
103         String inputId = Long.toString(input.getResourceId());
104         Map<String, Object> inputMap = ArrayMap.make(KEYS_RESOURCE, input);
105         return openEditor(editorId, contributionURI, iconURI, inputId, inputMap);
106     }
107
108     /**
109      * @param editorElementId the unique element ID of the part (editor)
110      */
111     public static void closeEditor(String editorElementId) {
112         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
113         EModelService modelService = context.get(EModelService.class);
114         MApplication app = context.get(MApplication.class);
115         modelService
116         .findElements(app, editorElementId, MPart.class, null)
117         .forEach(p -> p.getContext().get(EPartService.class).hidePart(p));
118     }
119
120     public static void activatePart(MPart part) {
121         EPartService partService = part.getContext().get(EPartService.class);
122         partService.activate(part);
123     }
124
125     public static MPartStack getEditorPartStack(EModelService modelService, MApplication app) {
126         MPartStack stack = (MPartStack) modelService.find(E4WorkbenchUtils.EDITOR_PART_STACK_ID, app);
127         if (stack == null) {
128             MArea editorArea = null;
129             MUIElement area = modelService.find(E4WorkbenchUtils.EDITOR_AREA_ID, app);
130             if (area instanceof MPlaceholder) {
131                 editorArea = (MArea) ((MPlaceholder) area).getRef();
132             } else if (area instanceof MArea) {
133                 editorArea = (MArea) area;
134             }
135             if (editorArea == null)
136                 throw new IllegalStateException("Shared editor area (" + E4WorkbenchUtils.EDITOR_AREA_ID + ") not found in application model");
137             for (MPartSashContainerElement container : editorArea.getChildren()) {
138                 if (container instanceof MPartStack) {
139                     stack = (MPartStack) container;
140                     break;
141                 }
142             }
143         }
144         if (stack == null)
145             throw new IllegalStateException("Could not find part stack under editor area.");
146         return stack;
147     }
148
149     public static void openAndShowPart(MPart part) {
150         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
151         EPartService partService = context.get(EPartService.class);
152         if (!partService.isPartVisible(part))
153             partService.showPart(part, PartState.ACTIVATE);
154         else
155             partService.activate(part);
156     }
157
158     
159     public static void openAndShowPart(String partId) {
160         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
161         EPartService partService = context.get(EPartService.class);
162         partService.showPart(partId, PartState.ACTIVATE);
163     }
164
165     public static MPart getMPartById(String partId) {
166         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
167         EPartService partService = context.get(EPartService.class);
168         MPart part = partService.findPart(partId);
169         if (part == null)
170             part = partService.createPart(partId);
171         return part;
172     }
173     
174     public static MCommand getMCommandById(String id) {
175         IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
176         MApplication application = context.get(MApplication.class);
177         for (MCommand command : application.getCommands()) {
178             if (id.equals(command.getElementId())) {
179                 return command;
180             }
181         }
182         return null;
183     }
184
185     @SuppressWarnings("restriction")
186     public static IEditorPart getActiveIEditorPart(MPart mActiveEditorPart) {
187         // TODO: Fix this when we get rid of CompatibilityEditors
188         IEditorPart activeEditor = null;
189         if (mActiveEditorPart != null) {
190             Object editor = mActiveEditorPart.getObject();
191             if (editor instanceof CompatibilityEditor) {
192                 CompatibilityEditor compEditor = (CompatibilityEditor) editor;
193                 activeEditor = compEditor.getEditor();
194             } else {
195                 // TODO: This is not good practice with E4 but an OK fallback for now
196                 activeEditor = WorkbenchUtils.getActiveEditor();
197             }
198         }
199         return activeEditor;
200     }
201 }