]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java
Allow Issues and Profiles to be used on non standard diagram viewers
[simantics/platform.git] / bundles / org.simantics.diagram.profile / src / org / simantics / diagram / profile / view / ActiveRuntimeDiagramInputSource.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.profile.view;
13
14 import org.eclipse.swt.widgets.Display;
15 import org.eclipse.ui.IEditorPart;
16 import org.eclipse.ui.IEditorReference;
17 import org.eclipse.ui.IPartListener2;
18 import org.eclipse.ui.IPartService;
19 import org.eclipse.ui.IWorkbenchPage;
20 import org.eclipse.ui.IWorkbenchPart;
21 import org.eclipse.ui.IWorkbenchPartReference;
22 import org.eclipse.ui.IWorkbenchSite;
23 import org.eclipse.ui.IWorkbenchWindow;
24 import org.eclipse.ui.PlatformUI;
25 import org.eclipse.ui.part.EditorPart;
26 import org.simantics.Simantics;
27 import org.simantics.browsing.ui.GraphExplorer;
28 import org.simantics.browsing.ui.common.ErrorLogger;
29 import org.simantics.browsing.ui.graph.impl.InputSourceListener;
30 import org.simantics.browsing.ui.graph.impl.ObservableInputSource;
31 import org.simantics.browsing.ui.graph.impl.WorkbenchSessionContextInputSource;
32 import org.simantics.db.Disposable;
33 import org.simantics.db.ReadGraph;
34 import org.simantics.db.Resource;
35 import org.simantics.db.Session;
36 import org.simantics.db.common.request.UniqueRead;
37 import org.simantics.db.exception.DatabaseException;
38 import org.simantics.db.management.ISessionContext;
39 import org.simantics.db.procedure.Procedure;
40 import org.simantics.diagram.runtime.RuntimeDiagramManager;
41 import org.simantics.diagram.stubs.DiagramResource;
42 import org.simantics.utils.ObjectUtils;
43 import org.simantics.utils.ui.SWTUtils;
44
45 /**
46  * @author Tuukka Lehtonen
47  */
48 public class ActiveRuntimeDiagramInputSource implements WorkbenchSessionContextInputSource, ObservableInputSource, IPartListener2, Disposable {
49
50     protected Display             display;
51     protected IWorkbenchPart      ownerPart;
52     protected IPartService        service;
53     protected IEditorPart         activeEditor;
54     protected Resource            activeRuntimeDiagram;
55     protected InputSourceListener listener;
56     protected boolean             ownerIsVisible = true;
57     protected Resource            lastInputResource;
58
59     @Override
60     public void init(IWorkbenchSite site, IWorkbenchPart part) {
61         this.display = site.getShell().getDisplay();
62         this.ownerPart = part;
63         attachToWorkbench();
64     }
65
66     /**
67      * @thread SWT
68      */
69     protected void attachToWorkbench() {
70         IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
71         if (window == null)
72             return;
73         service = window.getPartService();
74         service.addPartListener(this);
75
76         IWorkbenchPage activePage = window.getActivePage();
77         if (activePage == null)
78             return;
79         
80         IEditorPart activeEditor = activePage.getActiveEditor();
81         if (activeEditor != null)
82             editorActivated(activeEditor);
83     }
84
85     /**
86      * @thread SWT
87      */
88     @Override
89     public void dispose() {
90         if (service != null)
91             service.removePartListener(this);
92         service = null;
93         activeEditor = null;
94         activeRuntimeDiagram = null;
95         listener = null;
96         ownerPart = null;
97         display = null;
98     }
99
100     protected void fireIfInputChanged(Object oldSelection, Object newSelection) {
101         InputSourceListener l = listener;
102         if (l != null)
103             if (!ObjectUtils.objectEquals(oldSelection, newSelection))
104                 l.inputChanged(this);
105     }
106
107     @Override
108     public Object get(ISessionContext ctx) {
109         return activeRuntimeDiagram != null ? activeRuntimeDiagram : GraphExplorer.EMPTY_INPUT;
110     }
111     
112     @Override
113     public IWorkbenchPart getProvider() {
114         return activeEditor;
115     }
116
117     @Override
118     public void setListener(InputSourceListener listener) {
119         this.listener = listener;
120     }
121
122     private static class InputTransformation extends UniqueRead<Resource> {
123
124         private Resource resource;
125         private Resource defaultResult;
126
127         public InputTransformation(Resource input, Resource defaultResult) {
128             this.resource = input;
129             this.defaultResult = defaultResult;
130         }
131
132         @Override
133         public Resource perform(ReadGraph graph) throws DatabaseException {
134             if (graph.isInstanceOf(resource, DiagramResource.getInstance(graph).RuntimeDiagram))
135                 return resource;
136             if (!graph.hasStatement(resource))
137                 return null;
138
139 //            if (defaultResult != null && !graph.hasStatement(defaultResult))
140 //                return null;
141
142             return defaultResult;
143         }
144
145     }
146
147     class InputProcedure implements Procedure<Resource> {
148         @Override
149         public void execute(Resource result) {
150             Display d = display;
151             if (d != null)
152                 SWTUtils.asyncExec(d, () -> changeInput(result));
153         }
154         @Override
155         public void exception(Throwable t) {
156             ErrorLogger.defaultLogError(t);
157         }
158     }
159
160     private InputProcedure inputProcedure = new InputProcedure();
161
162     protected void testAndChangeInput(Resource resource) {
163         Session session = Simantics.peekSession();
164         if (session != null && resource != null) {
165             session.asyncRequest(
166                     new InputTransformation(resource, activeRuntimeDiagram),
167                     inputProcedure);
168         } else {
169             changeInput(null);
170         }
171     }
172
173     protected void editorActivated(IEditorPart part) {
174         RuntimeDiagramManager rdm = part.getAdapter(RuntimeDiagramManager.class);
175         Resource resource = null;
176         if (rdm != null)
177             resource = rdm.getRuntimeDiagram();
178         if (resource == null)
179             resource = part.getAdapter(Resource.class); 
180         lastInputResource = resource;
181         if (ownerIsVisible) {
182             testAndChangeInput(resource);
183         }
184     }
185
186     private boolean allEditorsClosed(IEditorPart forWindowOfPart) {
187         for (IWorkbenchPage page : forWindowOfPart.getEditorSite().getWorkbenchWindow().getPages()) {
188             IEditorReference[] editors = page.getEditorReferences();
189             if (editors.length > 0)
190                 return false;
191         }
192         return true;
193     }
194
195     protected void activeEditorClosed() {
196         if (allEditorsClosed(activeEditor))
197             changeInput(null);
198     }
199
200     private void changeInput(Resource newInput) {
201         Resource oldInput = activeRuntimeDiagram;
202         this.activeRuntimeDiagram = newInput;
203         fireIfInputChanged(oldInput, newInput != null ? newInput : GraphExplorer.EMPTY_INPUT);
204     }
205
206     @Override
207     public void partActivated(IWorkbenchPartReference partRef) {
208         //System.out.println("partActivated1: " + partRef);
209         if (partRef instanceof IEditorReference) {
210             IEditorPart part = ((IEditorReference) partRef).getEditor(false);
211             //System.out.println("partActivated2: " + part);
212             if (part instanceof EditorPart) {
213                 editorActivated((IEditorPart) part);
214             }
215         }
216     }
217
218     @Override
219     public void partBroughtToTop(IWorkbenchPartReference partRef) {
220         //System.out.println("partBroughtToTop: " + partRef);
221     }
222
223     @Override
224     public void partClosed(IWorkbenchPartReference partRef) {
225         //System.out.println("partClosed1: " + partRef);
226         if (partRef instanceof IEditorReference) {
227             IEditorPart part = ((IEditorReference) partRef).getEditor(false);
228             //System.out.println("partClosed2: " + part);
229             if (part == activeEditor) {
230                 activeEditorClosed();
231             }
232         }
233     }
234
235     @Override
236     public void partDeactivated(IWorkbenchPartReference partRef) {
237         //System.out.println("partDeactivated: " + partRef);
238     }
239
240     @Override
241     public void partOpened(IWorkbenchPartReference partRef) {
242         //System.out.println("partOpened: " + partRef);
243     }
244
245     @Override
246     public void partInputChanged(IWorkbenchPartReference partRef) {
247         //System.out.println("partInputChanged: " + partRef);
248     }
249
250     @Override
251     public void partHidden(IWorkbenchPartReference partRef) {
252         //System.out.println("partHidden: " + partRef);
253         IWorkbenchPart part = partRef.getPart(false);
254         if (ownerPart != null && ownerPart.equals(part)) {
255             ownerIsVisible = false;
256         }
257     }
258
259     @Override
260     public void partVisible(IWorkbenchPartReference partRef) {
261         //System.out.println("partVisible: " + partRef);
262         IWorkbenchPart part = partRef.getPart(false);
263         if (ownerPart != null && ownerPart.equals(part)) {
264             ownerIsVisible = true;
265             testAndChangeInput(lastInputResource);
266         }
267     }
268
269 }