]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java
fb07993ac7894940a6fa522243595470a16837bb
[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.stubs.DiagramResource;
41 import org.simantics.utils.ObjectUtils;
42 import org.simantics.utils.ui.SWTUtils;
43
44 /**
45  * @author Tuukka Lehtonen
46  */
47 public class ActiveRuntimeDiagramInputSource implements WorkbenchSessionContextInputSource, ObservableInputSource, IPartListener2, Disposable {
48
49     protected Display             display;
50     protected IWorkbenchPart      ownerPart;
51     protected IPartService        service;
52     protected IEditorPart         activeEditor;
53     protected Resource            activeRuntimeDiagram;
54     protected InputSourceListener listener;
55     protected boolean             ownerIsVisible = true;
56     protected Resource            lastInputResource;
57
58     @Override
59     public void init(IWorkbenchSite site, IWorkbenchPart part) {
60         this.display = site.getShell().getDisplay();
61         this.ownerPart = part;
62         attachToWorkbench();
63     }
64
65     /**
66      * @thread SWT
67      */
68     protected void attachToWorkbench() {
69         IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
70         if (window == null)
71             return;
72         service = window.getPartService();
73         service.addPartListener(this);
74
75         IWorkbenchPage activePage = window.getActivePage();
76         if (activePage == null)
77             return;
78         
79         IEditorPart activeEditor = activePage.getActiveEditor();
80         if (activeEditor != null)
81             editorActivated(activeEditor);
82     }
83
84     /**
85      * @thread SWT
86      */
87     @Override
88     public void dispose() {
89         if (service != null)
90             service.removePartListener(this);
91         service = null;
92         activeEditor = null;
93         activeRuntimeDiagram = null;
94         listener = null;
95         ownerPart = null;
96         display = null;
97     }
98
99     protected void fireIfInputChanged(Object oldSelection, Object newSelection) {
100         InputSourceListener l = listener;
101         if (l != null)
102             if (!ObjectUtils.objectEquals(oldSelection, newSelection))
103                 l.inputChanged(this);
104     }
105
106     @Override
107     public Object get(ISessionContext ctx) {
108         return activeRuntimeDiagram != null ? activeRuntimeDiagram : GraphExplorer.EMPTY_INPUT;
109     }
110     
111     @Override
112     public IWorkbenchPart getProvider() {
113         return activeEditor;
114     }
115
116     @Override
117     public void setListener(InputSourceListener listener) {
118         this.listener = listener;
119     }
120
121     private static class InputTransformation extends UniqueRead<Resource> {
122
123         private Resource resource;
124         private Resource defaultResult;
125
126         public InputTransformation(Resource input, Resource defaultResult) {
127             this.resource = input;
128             this.defaultResult = defaultResult;
129         }
130
131         @Override
132         public Resource perform(ReadGraph graph) throws DatabaseException {
133             if (graph.isInstanceOf(resource, DiagramResource.getInstance(graph).RuntimeDiagram))
134                 return resource;
135             if (!graph.hasStatement(resource))
136                 return null;
137
138 //            if (defaultResult != null && !graph.hasStatement(defaultResult))
139 //                return null;
140
141             return defaultResult;
142         }
143
144     }
145
146     class InputProcedure implements Procedure<Resource> {
147         @Override
148         public void execute(Resource result) {
149             Display d = display;
150             if (d != null)
151                 SWTUtils.asyncExec(d, () -> changeInput(result));
152         }
153         @Override
154         public void exception(Throwable t) {
155             ErrorLogger.defaultLogError(t);
156         }
157     }
158
159     private InputProcedure inputProcedure = new InputProcedure();
160
161     protected void testAndChangeInput(Resource resource) {
162         Session session = Simantics.peekSession();
163         if (session != null && resource != null) {
164             session.asyncRequest(
165                     new InputTransformation(resource, activeRuntimeDiagram),
166                     inputProcedure);
167         } else {
168             changeInput(null);
169         }
170     }
171
172     protected void editorActivated(IEditorPart part) {
173         Resource resource = part.getAdapter(Resource.class); 
174         lastInputResource = resource;
175         if (ownerIsVisible) {
176             testAndChangeInput(resource);
177         }
178     }
179
180     private boolean allEditorsClosed(IEditorPart forWindowOfPart) {
181         for (IWorkbenchPage page : forWindowOfPart.getEditorSite().getWorkbenchWindow().getPages()) {
182             IEditorReference[] editors = page.getEditorReferences();
183             if (editors.length > 0)
184                 return false;
185         }
186         return true;
187     }
188
189     protected void activeEditorClosed() {
190         if (allEditorsClosed(activeEditor))
191             changeInput(null);
192     }
193
194     private void changeInput(Resource newInput) {
195         Resource oldInput = activeRuntimeDiagram;
196         this.activeRuntimeDiagram = newInput;
197         fireIfInputChanged(oldInput, newInput != null ? newInput : GraphExplorer.EMPTY_INPUT);
198     }
199
200     @Override
201     public void partActivated(IWorkbenchPartReference partRef) {
202         //System.out.println("partActivated1: " + partRef);
203         if (partRef instanceof IEditorReference) {
204             IEditorPart part = ((IEditorReference) partRef).getEditor(false);
205             //System.out.println("partActivated2: " + part);
206             if (part instanceof EditorPart) {
207                 editorActivated((IEditorPart) part);
208             }
209         }
210     }
211
212     @Override
213     public void partBroughtToTop(IWorkbenchPartReference partRef) {
214         //System.out.println("partBroughtToTop: " + partRef);
215     }
216
217     @Override
218     public void partClosed(IWorkbenchPartReference partRef) {
219         //System.out.println("partClosed1: " + partRef);
220         if (partRef instanceof IEditorReference) {
221             IEditorPart part = ((IEditorReference) partRef).getEditor(false);
222             //System.out.println("partClosed2: " + part);
223             if (part == activeEditor) {
224                 activeEditorClosed();
225             }
226         }
227     }
228
229     @Override
230     public void partDeactivated(IWorkbenchPartReference partRef) {
231         //System.out.println("partDeactivated: " + partRef);
232     }
233
234     @Override
235     public void partOpened(IWorkbenchPartReference partRef) {
236         //System.out.println("partOpened: " + partRef);
237     }
238
239     @Override
240     public void partInputChanged(IWorkbenchPartReference partRef) {
241         //System.out.println("partInputChanged: " + partRef);
242     }
243
244     @Override
245     public void partHidden(IWorkbenchPartReference partRef) {
246         //System.out.println("partHidden: " + partRef);
247         IWorkbenchPart part = partRef.getPart(false);
248         if (ownerPart != null && ownerPart.equals(part)) {
249             ownerIsVisible = false;
250         }
251     }
252
253     @Override
254     public void partVisible(IWorkbenchPartReference partRef) {
255         //System.out.println("partVisible: " + partRef);
256         IWorkbenchPart part = partRef.getPart(false);
257         if (ownerPart != null && ownerPart.equals(part)) {
258             ownerIsVisible = true;
259             testAndChangeInput(lastInputResource);
260         }
261     }
262
263 }