1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2013 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 * Semantum Oy - issue #4384
\r
12 *******************************************************************************/
\r
13 package org.simantics.modeling.ui.diagramEditor;
\r
15 import java.awt.Color;
\r
16 import java.awt.dnd.DnDConstants;
\r
17 import java.util.Collections;
\r
18 import java.util.Set;
\r
19 import java.util.concurrent.TimeUnit;
\r
20 import java.util.function.Supplier;
\r
22 import org.eclipse.core.runtime.Assert;
\r
23 import org.eclipse.core.runtime.IAdaptable;
\r
24 import org.eclipse.core.runtime.IProgressMonitor;
\r
25 import org.eclipse.core.runtime.SubMonitor;
\r
26 import org.eclipse.core.runtime.jobs.Job;
\r
27 import org.eclipse.jface.action.IStatusLineManager;
\r
28 import org.eclipse.jface.resource.JFaceResources;
\r
29 import org.eclipse.jface.resource.LocalResourceManager;
\r
30 import org.eclipse.swt.widgets.Composite;
\r
31 import org.eclipse.swt.widgets.Display;
\r
32 import org.eclipse.ui.IEditorInput;
\r
33 import org.eclipse.ui.IEditorSite;
\r
34 import org.eclipse.ui.IWorkbenchPartSite;
\r
35 import org.eclipse.ui.contexts.IContextService;
\r
36 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
\r
37 import org.simantics.Simantics;
\r
38 import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;
\r
39 import org.simantics.db.ReadGraph;
\r
40 import org.simantics.db.Resource;
\r
41 import org.simantics.db.Session;
\r
42 import org.simantics.db.WriteGraph;
\r
43 import org.simantics.db.common.primitiverequest.PossibleAdapter;
\r
44 import org.simantics.db.common.procedure.adapter.ListenerDelegate;
\r
45 import org.simantics.db.common.procedure.adapter.ListenerSupport;
\r
46 import org.simantics.db.common.request.ParametrizedRead;
\r
47 import org.simantics.db.common.request.WriteRequest;
\r
48 import org.simantics.db.common.utils.CommonDBUtils;
\r
49 import org.simantics.db.common.utils.TagUtil;
\r
50 import org.simantics.db.exception.DatabaseException;
\r
51 import org.simantics.db.layer0.request.combinations.Combinators;
\r
52 import org.simantics.db.management.ISessionContext;
\r
53 import org.simantics.db.management.ISessionContextProvider;
\r
54 import org.simantics.db.request.Read;
\r
55 import org.simantics.diagram.DiagramTypeUtils;
\r
56 import org.simantics.diagram.adapter.FlagClassFactory;
\r
57 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
\r
58 import org.simantics.diagram.adapter.IDiagramLoader;
\r
59 import org.simantics.diagram.connection.ModelledConnectionAdvisor;
\r
60 import org.simantics.diagram.handler.ConnectionCommandHandler;
\r
61 import org.simantics.diagram.handler.CopyPasteHandler;
\r
62 import org.simantics.diagram.handler.CopyPasteStrategy;
\r
63 import org.simantics.diagram.handler.DefaultCopyPasteStrategy;
\r
64 import org.simantics.diagram.handler.DeleteHandler;
\r
65 import org.simantics.diagram.handler.ExpandSelectionHandler;
\r
66 import org.simantics.diagram.handler.SimpleElementTransformHandler;
\r
67 import org.simantics.diagram.layer.ILayersViewPage;
\r
68 import org.simantics.diagram.participant.ContextUtil;
\r
69 import org.simantics.diagram.participant.PointerInteractor2;
\r
70 import org.simantics.diagram.participant.SGFocusParticipant;
\r
71 import org.simantics.diagram.query.DiagramRequests;
\r
72 import org.simantics.diagram.runtime.RuntimeDiagramManager;
\r
73 import org.simantics.diagram.stubs.DiagramResource;
\r
74 import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;
\r
75 import org.simantics.diagram.synchronization.CopyAdvisor;
\r
76 import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;
\r
77 import org.simantics.diagram.synchronization.SynchronizationHints;
\r
78 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
\r
79 import org.simantics.diagram.ui.DiagramModelHints;
\r
80 import org.simantics.diagram.ui.SWTPopupMenuParticipant;
\r
81 import org.simantics.diagram.ui.SWTPopupMenuParticipantAwt;
\r
82 import org.simantics.diagram.ui.WorkbenchSelectionProvider;
\r
83 import org.simantics.g2d.canvas.Hints;
\r
84 import org.simantics.g2d.canvas.ICanvasContext;
\r
85 import org.simantics.g2d.canvas.ICanvasParticipant;
\r
86 import org.simantics.g2d.canvas.impl.CanvasContext;
\r
87 import org.simantics.g2d.chassis.AWTChassis;
\r
88 import org.simantics.g2d.chassis.ICanvasChassis;
\r
89 import org.simantics.g2d.chassis.IChassisListener;
\r
90 import org.simantics.g2d.chassis.SWTChassis;
\r
91 import org.simantics.g2d.connection.IConnectionAdvisor;
\r
92 import org.simantics.g2d.diagram.DiagramClass;
\r
93 import org.simantics.g2d.diagram.DiagramHints;
\r
94 import org.simantics.g2d.diagram.IDiagram;
\r
95 import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;
\r
96 import org.simantics.g2d.diagram.impl.Diagram;
\r
97 import org.simantics.g2d.diagram.participant.DelayedBatchElementPainter;
\r
98 import org.simantics.g2d.diagram.participant.DiagramParticipant;
\r
99 import org.simantics.g2d.diagram.participant.ElementInteractor;
\r
100 import org.simantics.g2d.diagram.participant.ElementPainter;
\r
101 import org.simantics.g2d.diagram.participant.Selection;
\r
102 import org.simantics.g2d.diagram.participant.TerminalPainter;
\r
103 import org.simantics.g2d.diagram.participant.ZOrderHandler;
\r
104 import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
\r
105 import org.simantics.g2d.element.ElementClassProviders;
\r
106 import org.simantics.g2d.element.ElementClasses;
\r
107 import org.simantics.g2d.element.IElement;
\r
108 import org.simantics.g2d.element.IElementClassProvider;
\r
109 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
\r
110 import org.simantics.g2d.elementclass.connection.ConnectionClass;
\r
111 import org.simantics.g2d.page.DiagramDesc;
\r
112 import org.simantics.g2d.participant.BackgroundPainter;
\r
113 import org.simantics.g2d.participant.CanvasBoundsParticipant;
\r
114 import org.simantics.g2d.participant.CanvasGrab;
\r
115 import org.simantics.g2d.participant.GridPainter;
\r
116 import org.simantics.g2d.participant.KeyUtil;
\r
117 import org.simantics.g2d.participant.MouseUtil;
\r
118 import org.simantics.g2d.participant.Notifications;
\r
119 import org.simantics.g2d.participant.PageBorderParticipant;
\r
120 import org.simantics.g2d.participant.PanZoomRotateHandler;
\r
121 import org.simantics.g2d.participant.PointerPainter;
\r
122 import org.simantics.g2d.participant.RenderingQualityInteractor;
\r
123 import org.simantics.g2d.participant.RulerPainter;
\r
124 import org.simantics.g2d.participant.SymbolUtil;
\r
125 import org.simantics.g2d.participant.TimeParticipant;
\r
126 import org.simantics.g2d.participant.TransformUtil;
\r
127 import org.simantics.g2d.participant.WorkbenchStatusLine;
\r
128 import org.simantics.g2d.participant.ZoomToAreaHandler;
\r
129 import org.simantics.g2d.tooltip.TerminalTooltipParticipant;
\r
130 import org.simantics.g2d.utils.CanvasUtils;
\r
131 import org.simantics.layer0.utils.triggers.IActivation;
\r
132 import org.simantics.layer0.utils.triggers.IActivationManager;
\r
133 import org.simantics.modeling.ModelingResources;
\r
134 import org.simantics.modeling.mapping.ComponentCopyAdvisor;
\r
135 import org.simantics.modeling.mapping.ElementCopyAdvisor;
\r
136 import org.simantics.modeling.mapping.MappedElementCopyAdvisor;
\r
137 import org.simantics.modeling.mapping.ModelingSynchronizationHints;
\r
138 import org.simantics.modeling.ui.diagramEditor.handlers.LinkBrowsingHandler;
\r
139 import org.simantics.modeling.ui.diagramEditor.handlers.StructuralBrowsingHandler;
\r
140 import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;
\r
141 import org.simantics.modeling.ui.preferences.DiagramPreferences;
\r
142 import org.simantics.project.ontology.ProjectResource;
\r
143 import org.simantics.scenegraph.INode;
\r
144 import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor;
\r
145 import org.simantics.scenegraph.utils.NodeUtil;
\r
146 import org.simantics.selectionview.StandardPropertyPage;
\r
147 import org.simantics.structural.stubs.StructuralResource2;
\r
148 import org.simantics.structural2.modelingRules.IModelingRules;
\r
149 import org.simantics.ui.SimanticsUI;
\r
150 import org.simantics.ui.jobs.SessionGarbageCollectorJob;
\r
151 import org.simantics.ui.workbench.IPropertyPage;
\r
152 import org.simantics.ui.workbench.IResourceEditorInput;
\r
153 import org.simantics.ui.workbench.IResourceEditorInput2;
\r
154 import org.simantics.ui.workbench.TitleRequest;
\r
155 import org.simantics.ui.workbench.TitleUpdater;
\r
156 import org.simantics.ui.workbench.ToolTipRequest;
\r
157 import org.simantics.ui.workbench.editor.input.InputValidationCombinators;
\r
158 import org.simantics.utils.DataContainer;
\r
159 import org.simantics.utils.datastructures.Callback;
\r
160 import org.simantics.utils.datastructures.hints.HintContext;
\r
161 import org.simantics.utils.datastructures.hints.HintListenerAdapter;
\r
162 import org.simantics.utils.datastructures.hints.IHintContext;
\r
163 import org.simantics.utils.datastructures.hints.IHintContext.Key;
\r
164 import org.simantics.utils.datastructures.hints.IHintListener;
\r
165 import org.simantics.utils.datastructures.hints.IHintObservable;
\r
166 import org.simantics.utils.threads.AWTThread;
\r
167 import org.simantics.utils.threads.IThreadWorkQueue;
\r
168 import org.simantics.utils.threads.SWTThread;
\r
169 import org.simantics.utils.threads.ThreadUtils;
\r
170 import org.simantics.utils.ui.ErrorLogger;
\r
171 import org.simantics.utils.ui.ExceptionUtils;
\r
173 import com.kitfox.svg.SVGCache;
\r
176 * @author Toni Kalajainen
\r
177 * @author Tuukka Lehtonen
\r
179 public class DiagramViewer
\r
180 //extends EditorPart implements IResourceEditorPart2,
\r
181 implements ListenerSupport, IAdaptable {
\r
183 public interface DiagramViewerHost {
\r
184 void doSetPartName(String name);
\r
185 void doSetTitleToolTip(String name);
\r
188 public static final String DIAGRAMMING_CONTEXT = "org.simantics.modeling.ui.diagramming";
\r
189 private static final String PREFERENCE_VIRTUAL_GRAPH = "preferences";
\r
191 private static final boolean PROFILE = false;
\r
193 ParametrizedRead<IResourceEditorInput, Boolean> INPUT_VALIDATOR =
\r
194 Combinators.compose(
\r
195 InputValidationCombinators.or(
\r
196 // Normal configuration diagrams of a model
\r
197 Combinators.compose(
\r
198 InputValidationCombinators.hasURI(),
\r
199 InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)
\r
201 // Configuration diagrams of a component type
\r
202 Combinators.compose(
\r
203 InputValidationCombinators.hasURI(),
\r
204 Combinators.compose(
\r
205 InputValidationCombinators.partialFunction(StructuralResource2.URIs.Defines),
\r
206 InputValidationCombinators.partialFunction(ModelingResources.URIs.DiagramToComposite)
\r
210 InputValidationCombinators.extractInputResource()
\r
213 protected EditorState editorState;
\r
215 protected boolean disposed = false;
\r
216 protected IThreadWorkQueue swt;
\r
217 protected IStatusLineManager statusLineManager;
\r
218 protected Display display;
\r
219 protected LocalResourceManager resourceManager;
\r
220 protected SWTChassis c;
\r
221 protected IDiagram sourceDiagram;
\r
222 protected DataContainer<IDiagram> sourceDiagramContainer;
\r
223 protected CanvasContext canvasContext;
\r
224 protected ISessionContextProvider sessionContextProvider;
\r
225 protected ISessionContext sessionContext;
\r
226 protected Resource diagramResource;
\r
227 protected GraphToDiagramSynchronizer synchronizer;
\r
228 protected IActivation activation;
\r
229 protected ContextUtil contextUtil;
\r
230 protected SWTPopupMenuParticipant popupMenuParticipant;
\r
232 protected DiagramPreferences diagramPreferences;
\r
233 protected DiagramDesc diagramDesc;
\r
234 protected GridSnapAdvisor snapAdvisor;
\r
236 private RuntimeDiagramManager runtimeDiagramManager;
\r
239 * Set externally in
\r
240 * {@link #init(DiagramViewerHost, IEditorSite, IEditorInput, DataContainer, WorkbenchSelectionProvider)}
\r
243 protected WorkbenchSelectionProvider selectionProvider;
\r
245 public Resource getRuntime() {
\r
246 RuntimeDiagramManager rtdm = runtimeDiagramManager;
\r
247 return (rtdm == null) ? null : rtdm.getRuntimeDiagram();
\r
250 public ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {
\r
251 return INPUT_VALIDATOR;
\r
254 protected void addDropParticipants(ICanvasContext ctx) {
\r
255 ctx.getDefaultHintContext().setHint(Hints.KEY_ALLOWED_DRAG_ACTIONS, DnDConstants.ACTION_COPY);
\r
257 ctx.add(new PopulateElementDropParticipant(synchronizer, getSite()));
\r
258 ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));
\r
261 protected CopyPasteStrategy getCopyPasteStrategy() {
\r
263 CopyPasteStrategy cpStrategy = Simantics.getSession().syncRequest(new PossibleAdapter<CopyPasteStrategy>(getInputResource(), CopyPasteStrategy.class));
\r
264 if(cpStrategy != null) return cpStrategy;
\r
265 } catch (DatabaseException e) {
\r
267 return getDefaultCopyPasteStrategy();
\r
270 protected CopyPasteStrategy getDefaultCopyPasteStrategy() {
\r
271 return new DefaultCopyPasteStrategy();
\r
274 protected CopyAdvisor getCopyAdvisor() {
\r
276 CopyAdvisor advisor = Simantics.getSession().syncRequest(new PossibleAdapter<CopyAdvisor>(getInputResource(), CopyAdvisor.class));
\r
277 if(advisor != null) return advisor;
\r
278 } catch (DatabaseException e) {
\r
280 return new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new ComponentCopyAdvisor());
\r
285 * TODO: change argument from CanvasContext to ICanvasContext
\r
287 protected void addKeyBindingParticipants(CanvasContext ctx) {
\r
288 //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );
\r
289 ctx.add(new DeleteHandler(statusLineManager));
\r
290 ctx.add(new CopyPasteHandler(getCopyPasteStrategy(), statusLineManager).setWorkbenchSite(getEditorSite()));
\r
291 ctx.add(new ConnectionCommandHandler());
\r
294 protected void addPopupmenu(ICanvasContext ctx) {
\r
295 ctx.add(popupMenuParticipant);
\r
298 protected void addWorkbenchSelectionProvider(ICanvasContext ctx) {
\r
299 if (selectionProvider != null)
\r
300 ctx.add(selectionProvider);
\r
303 protected void addViewManipulationParticipants(CanvasContext ctx) {
\r
304 ctx.add(new PanZoomRotateHandler());
\r
305 //ctx.add(new MousePanZoomInteractor());
\r
306 //ctx.add(new MultitouchPanZoomRotateInteractor());
\r
307 // ctx.add( new OrientationRestorer() );
\r
308 ctx.add(new ZoomToAreaHandler());
\r
311 protected void addDiagramParticipants(ICanvasContext ctx) {
\r
312 ctx.add(new ZOrderHandler());
\r
313 ctx.add(getPointerInteractor());
\r
314 ctx.add(new ElementInteractor());
\r
315 ctx.add(new Selection());
\r
316 ctx.add(new DiagramParticipant());
\r
317 ctx.add(new ElementPainter());
\r
318 //ctx.add(new ElementHeartbeater());
\r
319 //ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));
\r
320 //ctx.add(new TooltipParticipant());
\r
321 ctx.add(new TerminalTooltipParticipant());
\r
324 protected void addPainterParticipants(ICanvasContext ctx) {
\r
325 ctx.add(new RenderingQualityInteractor());
\r
326 ctx.add(new TerminalPainter(true, true, false, true));
\r
327 ctx.add(new DelayedBatchElementPainter(PickFilter.FILTER_MONITORS, 500, TimeUnit.MILLISECONDS));
\r
330 protected void addStructureParticipants(ICanvasContext ctx) {
\r
331 addWorkbenchSelectionProvider(ctx);
\r
332 // Add visual browsing capabilities for structural models
\r
333 ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, getResourceInput2()));
\r
334 ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));
\r
338 * Override to add any diagram/canvas participants to the canvas context
\r
339 * initialized for the editor.
\r
343 protected void addOtherParticipants(CanvasContext ctx) {
\r
346 public static Set<String> defaultPropertyBrowseContexts = Collections.singleton(ProjectResource.URIs.ProjectBrowseContext);
\r
348 protected Set<String> getPropertyPageContexts() {
\r
350 return BrowseContext.getBrowseContextClosure(SimanticsUI.getSession(), defaultPropertyBrowseContexts);
\r
351 } catch (DatabaseException e) {
\r
352 ExceptionUtils.logAndShowError("Failed to load modeled browse contexts for property page, see exception for details.", e);
\r
353 return defaultPropertyBrowseContexts;
\r
357 protected IPropertyPage createPropertyPage(IWorkbenchPartSite site, Set<String> contexts) {
\r
358 return new StandardPropertyPage(site, contexts);
\r
361 protected String getPopupId() {
\r
362 return "#ModelingDiagramPopup";
\r
365 protected void getPreferences() {
\r
366 this.diagramPreferences = DiagramPreferenceUtil.getPreferences();
\r
369 protected void initSession() {
\r
370 sessionContextProvider = SimanticsUI.getSessionContextProvider();
\r
371 sessionContext = sessionContextProvider.getSessionContext();
\r
374 protected void readNames() {
\r
375 String name = getEditorInput().getName();
\r
376 host.doSetPartName(name);
\r
377 host.doSetTitleToolTip(name);
\r
380 class ChassisListener implements IChassisListener {
\r
382 public void chassisClosed(ICanvasChassis sender) {
\r
383 // Prevent deadlock while disposing which using syncExec would result in.
\r
384 final ICanvasContext ctx = canvasContext;
\r
385 ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
\r
387 public void run() {
\r
389 saveEditorState(ctx);
\r
390 ctx.getHintStack().removeKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);
\r
391 ctx.getHintStack().removeKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);
\r
392 final AWTChassis awtChassis = c.getAWTComponent();
\r
393 if (awtChassis != null)
\r
394 awtChassis.setCanvasContext(null);
\r
398 if (sourceDiagramContainer != null) {
\r
399 sourceDiagramContainer.set(null);
\r
400 sourceDiagramContainer = null;
\r
403 if (sourceDiagram != null)
\r
404 sourceDiagram.dispose();
\r
406 if(synchronizer != null) {
\r
407 synchronizer.dispose();
\r
409 synchronizer = null;
\r
412 if (runtimeDiagramManager != null) {
\r
413 runtimeDiagramManager.dispose();
\r
414 runtimeDiagramManager = null;
\r
418 c.removeChassisListener(ChassisListener.this);
\r
422 protected void createChassis(Composite parent) {
\r
423 resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
\r
424 c = new SWTChassis(parent, 0);
\r
426 Object task = BEGIN("DV.precreateParticipants");
\r
427 createCustomParticipants();
\r
430 c.populate(component -> {
\r
432 c.addChassisListener(new ChassisListener());
\r
433 initializeCanvas();
\r
438 protected void beforeSetCanvasContext(ICanvasContext canvasContext2) {
\r
442 * Invoke this only from the AWT thread.
\r
445 protected void setCanvasContext(ICanvasContext context) {
\r
446 // Cannot directly invoke SWTChassis.setCanvasContext only because it
\r
447 // needs to be invoked in the SWT thread and AWTChassis.setCanvasContext in the
\r
448 // AWT thread, but directly invoking SWTChassis.setCanvasContext would call both
\r
449 // in the SWT thread which would cause synchronous scheduling of AWT
\r
450 // runnables which is always a potential source of deadlocks.
\r
451 c.getAWTComponent().setCanvasContext(canvasContext);
\r
452 swt.asyncExec(new Runnable() {
\r
454 public void run() {
\r
455 if (!c.isDisposed())
\r
456 // For AWT, this is a no-operation.
\r
457 c.setCanvasContext(canvasContext);
\r
462 public void createPartControl(Composite parent) {
\r
463 //ProfileObserver.begin = System.nanoTime();
\r
464 display = parent.getDisplay();
\r
465 swt = SWTThread.getThreadAccess(display);
\r
466 statusLineManager = getEditorSite().getActionBars().getStatusLineManager();
\r
468 Object task = BEGIN("DV.initSession");
\r
472 diagramResource = getInputResource();
\r
477 this.runtimeDiagramManager = RuntimeDiagramManager.track(sessionContext.getSession(), diagramResource, getEditorInput(), this);
\r
479 // Create the canvas context here before finishing createPartControl
\r
480 // to give DiagramViewerActionContributor a chance to work.
\r
481 // The context can be created in SWT thread without scheduling
\r
482 // to the context thread and having potential deadlocks.
\r
483 IThreadWorkQueue thread = AWTThread.getThreadAccess();
\r
484 this.canvasContext = new CanvasContext(thread);
\r
485 this.canvasContext.setLocked(true);
\r
487 task = BEGIN("DV.createChassis");
\r
488 createChassis(parent);
\r
490 } catch (DatabaseException e) {
\r
491 ErrorLogger.defaultLogError(e);
\r
497 * A method invoked before chassis construction for creating such
\r
498 * {@link ICanvasParticipant}s that need to be constructed in the SWT
\r
501 * Use it for creating any such canvas participants during the viewer
\r
502 * construction and add them to the {@link ICanvasContext} later on from
\r
505 protected void createCustomParticipants() {
\r
506 if (SimanticsUI.isLinuxGTK()) {
\r
507 popupMenuParticipant = new SWTPopupMenuParticipantAwt(getSite(), c, display, getPopupId());
\r
509 popupMenuParticipant = new SWTPopupMenuParticipant(getSite(), c, display, getPopupId());
\r
514 * Invoke this only from the AWT thread.
\r
516 protected void initializeCanvas() {
\r
517 Object canvasInit = BEGIN("DV.canvasInitialization");
\r
519 Object task = BEGIN("DV.createViewerCanvas");
\r
520 initializeCanvasContext(canvasContext);
\r
523 beforeSetCanvasContext(canvasContext);
\r
524 //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);
\r
526 // Without this all diagram participants will crash like there's no tomorrow.
\r
527 // Just trying to keep the behavior a bit more sane in case of
\r
528 // errors instead of flooding the console with exceptions.
\r
529 canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT));
\r
531 // Changes in ruler/grid activity shall be written as
\r
532 // workspace-persistent diagram-specific preferences.
\r
533 canvasContext.getHintStack().addKeyHintListener(GridPainter.KEY_GRID_ENABLED, canvasHintListener);
\r
534 canvasContext.getHintStack().addKeyHintListener(RulerPainter.KEY_RULER_ENABLED, canvasHintListener);
\r
536 task = BEGIN("DV.setCanvasContext");
\r
537 setCanvasContext(canvasContext);
\r
540 // Finish loading in a worker thread because it may be a time consuming
\r
541 // process to load a large diagram and we don't want unnecessary AWT
\r
542 // thread contention.
\r
543 Job loadJob = new DiagramViewerLoadJob(this);
\r
544 loadJob.schedule();
\r
549 protected void activateUiContexts(ContextUtil util) {
\r
550 util.activate(DIAGRAMMING_CONTEXT);
\r
554 * @param monitor the progress monitor to use for reporting progress to the
\r
555 * user. It is the caller's responsibility to call done() on the
\r
556 * given monitor. Accepts <code>null</code>, indicating that no
\r
557 * progress should be reported and that the operation cannot be
\r
560 protected void performActivation(IProgressMonitor monitor) {
\r
561 SubMonitor progress = SubMonitor.convert(monitor, "Activate Mapping", 100);
\r
562 IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);
\r
563 if (activationManager != null) {
\r
564 activation = activationManager.activate(diagramResource);
\r
566 progress.worked(100);
\r
569 protected void onCreated() {
\r
575 protected void scheduleZoomToFit(IDiagram diagram) {
\r
576 if (diagram == null)
\r
577 throw new IllegalStateException("diagram is null");
\r
579 CanvasUtils.scheduleZoomToFit(swt, () -> disposed, canvasContext, diagram);
\r
583 * Subclasses may override but should always invoke super.
\r
586 * @param initialHints
\r
587 * @throws DatabaseException
\r
589 protected void fillInitialDiagramHints(Resource diagram, IHintContext initialHints) throws DatabaseException {
\r
590 IModelingRules modelingRules = sessionContext.getSession().syncRequest(
\r
591 DiagramRequests.getModelingRules(diagram, null));
\r
592 if (modelingRules != null) {
\r
593 initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules);
\r
594 initialHints.setHint(DiagramHints.CONNECTION_ADVISOR,
\r
595 getConnectionAdvisor(modelingRules, sessionContext.getSession()));
\r
598 initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor());
\r
599 initialHints.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.TRUE);
\r
600 initialHints.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.TRUE);
\r
601 initialHints.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.TRUE);
\r
605 * @param monitor the progress monitor to use for reporting progress to the
\r
606 * user. It is the caller's responsibility to call done() on the
\r
607 * given monitor. Accepts <code>null</code>, indicating that no
\r
608 * progress should be reported and that the operation cannot be
\r
612 * @throws DatabaseException
\r
614 protected IDiagram loadDiagram(IProgressMonitor monitor, final Resource r) throws DatabaseException {
\r
615 // Pre-load modeling rules and possibly other hints too since they are
\r
616 // needed already while loading the diagram contents.
\r
617 IHintContext initialHints = new HintContext();
\r
618 fillInitialDiagramHints(r, initialHints);
\r
619 IDiagram d = loadDiagram(monitor, r, initialHints);
\r
624 * @param monitor the progress monitor to use for reporting progress to the
\r
625 * user. It is the caller's responsibility to call done() on the
\r
626 * given monitor. Accepts <code>null</code>, indicating that no
\r
627 * progress should be reported and that the operation cannot be
\r
630 * @param initialHints
\r
632 * @throws DatabaseException
\r
634 protected IDiagram loadDiagram(IProgressMonitor monitor, Resource diagram, IHintContext initialHints) throws DatabaseException {
\r
635 RuntimeDiagramManager rtdm = runtimeDiagramManager;
\r
636 Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;
\r
637 IDiagramLoader loader = synchronizer;
\r
638 if (rtdm == null || runtimeDiagram == null || loader == null)
\r
640 IDiagram d = sessionContext.getSession().syncRequest(
\r
641 DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,
\r
642 runtimeDiagram, null, loader, initialHints));
\r
646 protected void beforeSetDiagram(IDiagram diagram) {
\r
649 protected PointerInteractor getPointerInteractor() {
\r
650 return new PointerInteractor2(true, true, true, false, true, false, synchronizer.getElementClassProvider());
\r
653 protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) {
\r
654 return new ModelledConnectionAdvisor(modelingRules, sessionContext.getSession());
\r
657 protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) {
\r
659 return sessionContext.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {
\r
661 public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException {
\r
662 GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph));
\r
663 initializeSynchronizationContext(graph, sync);
\r
667 } catch (DatabaseException e) {
\r
668 throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);
\r
672 protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {
\r
673 context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));
\r
676 protected IElementClassProvider createElementClassProvider(ReadGraph graph) {
\r
677 DiagramResource dr = DiagramResource.getInstance(graph);
\r
678 return ElementClassProviders.mappedProvider(
\r
679 ElementClasses.CONNECTION, ConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(dr.RouteGraphConnection)),
\r
680 ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)
\r
684 protected SimpleElementTransformHandler getTransformHandler() {
\r
685 return new SimpleElementTransformHandler(true, true, true);
\r
688 public void initializeCanvasContext(CanvasContext ctx) {
\r
689 IHintContext h = ctx.getDefaultHintContext();
\r
691 // The canvas context should not be painted until it is ready to avoid
\r
692 // unnecessary visual glitches.
\r
693 h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
\r
695 Object task = BEGIN("createSynchronizer");
\r
696 this.synchronizer = createSynchronizer(ctx, sessionContext);
\r
699 IContextService contextService = (IContextService) getSite().getService(IContextService.class);
\r
700 contextUtil = new ContextUtil(contextService, swt);
\r
702 // Support & Util Participants
\r
703 ctx.add(new TransformUtil());
\r
704 ctx.add(new MouseUtil());
\r
705 ctx.add(new KeyUtil());
\r
706 ctx.add(contextUtil);
\r
707 ctx.add(new WorkbenchStatusLine(statusLineManager));
\r
708 ctx.add(new CanvasGrab());
\r
709 ctx.add(new SymbolUtil());
\r
710 ctx.add(new TimeParticipant());
\r
711 ctx.add(new CanvasBoundsParticipant());
\r
712 ctx.add(new Notifications());
\r
714 ctx.add(new SGFocusParticipant(c, DIAGRAMMING_CONTEXT));
\r
716 // Debug participant(s)
\r
717 // ctx.add( new PointerPainter() );
\r
718 // ctx.add( new HandPainter() );
\r
719 h.setHint(PointerPainter.KEY_PAINT_POINTER, true);
\r
721 // Pan & Zoom & Rotate
\r
722 addViewManipulationParticipants(ctx);
\r
724 ctx.add(getTransformHandler());
\r
725 ctx.add(new ExpandSelectionHandler(getEditorSite().getActionBars().getStatusLineManager()));
\r
728 addKeyBindingParticipants(ctx);
\r
730 // Grid & Ruler & Background
\r
731 ctx.add(new GridPainter());
\r
732 ctx.add(new RulerPainter());
\r
733 ctx.add(new BackgroundPainter());
\r
735 h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));
\r
736 h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));
\r
737 ctx.add(new PageBorderParticipant());
\r
739 // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));
\r
740 // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY);
\r
741 h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));
\r
742 h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);
\r
743 h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));
\r
744 h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);
\r
746 ////// Diagram Participants //////
\r
747 addDiagramParticipants(ctx);
\r
748 addPainterParticipants(ctx);
\r
750 /////// D'n'D ///////
\r
751 addDropParticipants(ctx);
\r
753 h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA);
\r
754 h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
\r
756 h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0);
\r
757 h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);
\r
759 Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE);
\r
760 this.snapAdvisor = new GridSnapAdvisor(snapResolution);
\r
761 h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor);
\r
762 h.setHint(GridPainter.KEY_GRID_SIZE, snapResolution);
\r
763 h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE);
\r
765 // Workbench selection provider
\r
766 addStructureParticipants(ctx);
\r
771 // Load page frame description settings
\r
772 loadPageSettings(ctx);
\r
774 addOtherParticipants(ctx);
\r
776 ctx.assertParticipantDependencies();
\r
777 ctx.setLocked(false);
\r
780 protected void loadPageSettings(ICanvasContext ctx) {
\r
781 DiagramDesc diagramDesc = null;
\r
783 // load diagram page configuration
\r
784 if (diagramResource != null) {
\r
786 diagramDesc = sessionContext.getSession().syncRequest(DiagramRequests.getDiagramDesc(diagramResource));
\r
787 } catch (DatabaseException e) {
\r
788 ErrorLogger.defaultLogError(e);
\r
792 if (diagramDesc == null) {
\r
793 // Take page description from the preferences if nothing else is available.
\r
794 final DiagramDesc desc = diagramDesc = diagramPreferences.getDiagramDesc();
\r
796 // Write page configuration to graph
\r
797 sessionContext.getSession().asyncRequest(new WriteRequest() {
\r
799 public void perform(WriteGraph graph) throws DatabaseException {
\r
800 CommonDBUtils.selectClusterSet(graph, diagramResource);
\r
801 DiagramGraphUtil.setDiagramDesc(graph, diagramResource, desc);
\r
803 }, new Callback<DatabaseException>() {
\r
805 public void run(DatabaseException parameter) {
\r
806 if (parameter != null)
\r
807 ErrorLogger.defaultLogError("Failed to write default diagram page description to database, see exception for details", parameter);
\r
812 setDiagramDesc(ctx, diagramDesc);
\r
814 // Create a listener to react to page setting changes.
\r
815 sessionContext.getSession().asyncRequest(DiagramRequests.getDiagramDesc(diagramResource),
\r
816 new ListenerDelegate<DiagramDesc>(this) {
\r
818 public void execute(final DiagramDesc result) {
\r
819 if (result != null && canvasContext != null) {
\r
820 ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {
\r
822 public void run() {
\r
824 setDiagramDesc(canvasContext, result);
\r
832 protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) {
\r
833 if (diagramDesc == null)
\r
834 throw new NullPointerException("null diagram desc");
\r
836 if (diagramDesc.equals(this.diagramDesc))
\r
839 this.diagramDesc = diagramDesc;
\r
840 IHintContext hints = ctx.getDefaultHintContext();
\r
841 hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc());
\r
842 hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible());
\r
843 hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible());
\r
844 hints.setHint(GridPainter.KEY_GRID_ENABLED, diagramDesc.isGridVisible());
\r
845 hints.setHint(RulerPainter.KEY_RULER_ENABLED, diagramDesc.isRulerVisible());
\r
846 snapAdvisor.setResolution(diagramDesc.getGridSize());
\r
847 hints.setHint(GridPainter.KEY_GRID_SIZE, diagramDesc.getGridSize());
\r
851 * Must be invoked from the AWT thread only.
\r
856 protected void applyEditorState(final EditorState state, final ICanvasContext ctx) {
\r
857 final IDiagram diagram = ctx.getHintStack().getHint(DiagramHints.KEY_DIAGRAM);
\r
859 if (state.viewTransform != null && state.viewTransform.getDeterminant() != 0) {
\r
860 for (PanZoomRotateHandler h : ctx.getItemsByClass(PanZoomRotateHandler.class)) {
\r
861 h.setTransform(state.viewTransform);
\r
865 if (diagram != null) {
\r
866 if (state.viewTransform != null)
\r
867 diagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);
\r
869 if (state.toolMode != null)
\r
870 ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, state.toToolMode());
\r
872 ctx.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
\r
874 final Set<IElement> selected = DiagramEditorStates.toElements(state.selection, diagram);
\r
875 if (!selected.isEmpty()) {
\r
876 for (Selection s : ctx.getItemsByClass(Selection.class)) {
\r
877 s.setSelection(0, selected);
\r
883 protected EditorState getSavedEditorState(ICanvasContext ctx) {
\r
884 return DiagramEditorStates.toEditorState(ctx, true, true, true);
\r
887 protected void saveEditorState(ICanvasContext ctx) {
\r
888 DiagramEditorStates.saveEditorState(PREFERENCE_VIRTUAL_GRAPH, diagramResource, getSavedEditorState(ctx) , DiagramViewer.this);
\r
891 private boolean firstFocus = true;
\r
893 public void setFocus() {
\r
899 // This is a workaround for using the symbol viewer in multi-page
\r
900 // editors which causes the first zoom-to-fit scheduling to happen
\r
901 // already before the controls have been laid out properly.
\r
902 firstFocus = false;
\r
903 firstTimeSetFocus();
\r
910 protected void firstTimeSetFocus() {
\r
911 // [Tuukka@2010-02-11]
\r
912 // Removed since this is actually a workaround for multi-page editors.
\r
913 //scheduleZoomToFit();
\r
916 public void dispose() {
\r
917 // Deactivate all contexts here because after this the context service
\r
918 // in question will not be available.
\r
919 if (contextUtil != null) {
\r
920 contextUtil.deactivateAll();
\r
924 if (activation != null) {
\r
925 activation.deactivate();
\r
929 if (resourceManager != null) {
\r
930 resourceManager.dispose();
\r
931 resourceManager = null;
\r
936 protected Resource getInputResource() {
\r
937 return getResourceInput().getResource();
\r
940 public IResourceEditorInput getResourceInput() {
\r
941 return (IResourceEditorInput) getEditorInput();
\r
944 public IResourceEditorInput2 getResourceInput2() {
\r
945 return (IResourceEditorInput2) getEditorInput();
\r
948 public void init(DiagramViewerHost _host, IEditorSite site, IEditorInput input, DataContainer<IDiagram> diagramContainer, WorkbenchSelectionProvider selectionProvider) {
\r
949 if (!(input instanceof IResourceEditorInput))
\r
950 throw new RuntimeException("Invalid input: must be IResourceEditorInput");
\r
955 this.sourceDiagramContainer = diagramContainer;
\r
956 this.selectionProvider = selectionProvider;
\r
958 // Set initial part name according to the name given by IEditorInput
\r
959 host.doSetPartName(getEditorInput().getName());
\r
961 Session session = SimanticsUI.peekSession();
\r
962 if (session != null) {
\r
963 Supplier<Boolean> disposedCallback = () -> disposed;
\r
964 session.asyncRequest(
\r
965 new TitleRequest(site.getId(), getResourceInput()),
\r
966 new TitleUpdater(site.getShell().getDisplay(), host::doSetPartName, disposedCallback));
\r
967 session.asyncRequest(
\r
968 new ToolTipRequest(site.getId(), getResourceInput()),
\r
969 new TitleUpdater(site.getShell().getDisplay(), host::doSetTitleToolTip, disposedCallback));
\r
973 // Read previous editor state from the database
\r
974 editorState = DiagramEditorStates.readEditorState(getInputResource());
\r
975 } catch (DatabaseException e) {
\r
980 @SuppressWarnings("unchecked")
\r
982 public <T> T getAdapter(Class<T> adapter) {
\r
983 // System.out.println("diagramViewer getAdapter " + adapter);
\r
984 // Property view support
\r
985 if (adapter == IPropertyPage.class)
\r
986 return (T) createPropertyPage(getSite(), getPropertyPageContexts());
\r
987 // Provide symbols for the editor
\r
988 if (adapter == SymbolProviderFactory.class) {
\r
990 return (T) DiagramTypeUtils.readSymbolProviderFactory(sessionContext.getSession(), diagramResource);
\r
991 } catch (DatabaseException e) {
\r
992 ErrorLogger.defaultLogError(getClass() + " failed to adapt to SymbolProviderFactory, see exception for details.", e);
\r
996 // Outline view support
\r
997 if (adapter == IContentOutlinePage.class)
\r
998 return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2());
\r
999 // Role view support
\r
1000 if (adapter == ILayersViewPage.class)
\r
1001 return (T) new DiagramLayersPage(sourceDiagram, canvasContext);
\r
1002 // Support external steering of the diagram canvas, zooming etc.
\r
1003 if (adapter == ICanvasContext.class)
\r
1004 return (T) canvasContext;
\r
1005 // Support scene graph debugger view
\r
1006 if (adapter == INode.class) {
\r
1007 if (canvasContext != null) {
\r
1008 INode node = canvasContext.getCanvasNode();
\r
1010 return (T) NodeUtil.getRootNode(node);
\r
1014 // Support retrieval of the current diagram.
\r
1015 if (adapter == IDiagram.class)
\r
1016 return (T) sourceDiagram;
\r
1017 // Why is this here ??
\r
1018 if (adapter == Session.class)
\r
1019 return (T) sessionContext.getSession();
\r
1020 if(adapter == RuntimeDiagramManager.class)
\r
1021 return (T) runtimeDiagramManager;
\r
1022 if (adapter == Resource.class)
\r
1023 return (T) getRuntime();
\r
1024 if (adapter == ICanvasChassis.class)
\r
1030 //-------------------------------------------------------------------------
\r
1033 protected static Object BEGIN(String name) {
\r
1035 //return ThreadLog.BEGIN(name);
\r
1040 protected static void END(Object task) {
\r
1042 //((Task) task).end();
\r
1046 //-------------------------------------------------------------------------
\r
1047 // implement ListenerSupport
\r
1050 public void exception(Throwable t) {
\r
1051 ErrorLogger.defaultLogError(t);
\r
1055 public boolean isDisposed() {
\r
1059 protected void collectGarbage() {
\r
1060 SessionGarbageCollectorJob.getInstance().schedule(0);
\r
1061 AWTThread.getThreadAccess().asyncExec(new Runnable() {
\r
1063 public void run() {
\r
1064 //System.out.println("BEFORE CLEAR: " + SVGCache.getSVGUniverse().report());
\r
1065 SVGCache.getSVGUniverse().clearUnreferenced();
\r
1066 //System.out.println("AFTER CLEAR: " + SVGCache.getSVGUniverse().report());
\r
1071 //-------------------------------------------------------------------------
\r
1072 // Listener for certain canvas context hint changes
\r
1074 IHintListener canvasHintListener = new HintListenerAdapter() {
\r
1076 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
\r
1077 if (key == GridPainter.KEY_GRID_ENABLED) {
\r
1078 boolean v = Boolean.TRUE.equals(newValue);
\r
1079 if (diagramDesc.isGridVisible() != v)
\r
1080 setGlobalPreference(DiagramResource.URIs.DisplayGrid, v);
\r
1081 } else if (key == RulerPainter.KEY_RULER_ENABLED) {
\r
1082 boolean v = Boolean.TRUE.equals(newValue);
\r
1083 if (diagramDesc.isRulerVisible() != v)
\r
1084 setGlobalPreference(DiagramResource.URIs.DisplayRuler, v);
\r
1089 private <T> void setGlobalPreference(final String preferenceURI, boolean value) {
\r
1090 TagUtil.execute(Simantics.getSession(), PREFERENCE_VIRTUAL_GRAPH, preferenceURI, value, Simantics.getProjectResource());
\r
1094 * --------------------------------------------------------------------
\r
1095 * Changes related to removal of EditorPart extension from here on down
\r
1096 * --------------------------------------------------------------------
\r
1099 private IWorkbenchPartSite partSite;
\r
1100 private DiagramViewerHost host;
\r
1101 private IEditorInput editorInput = null;
\r
1104 * Method declared on IWorkbenchPart.
\r
1106 public IWorkbenchPartSite getSite() {
\r
1110 public IEditorSite getEditorSite() {
\r
1111 return (IEditorSite) getSite();
\r
1114 public IEditorInput getEditorInput() {
\r
1115 return editorInput;
\r
1118 // protected void setPartName(String partName) {
\r
1119 //// if (compatibilityTitleListener != null) {
\r
1120 //// removePropertyListener(compatibilityTitleListener);
\r
1121 //// compatibilityTitleListener = null;
\r
1124 //// super.setPartName(partName);
\r
1127 // protected void setTitleToolTip(String toolTip) {
\r
1128 //// toolTip = Util.safeString(toolTip);
\r
1129 //// //Do not send changes if they are the same
\r
1130 //// if (Util.equals(this.toolTip, toolTip)) {
\r
1133 //// this.toolTip = toolTip;
\r
1134 //// firePropertyChange(IWorkbenchPart.PROP_TITLE);
\r
1137 protected void setHost(DiagramViewerHost host) {
\r
1141 protected void setSite(IWorkbenchPartSite site) {
\r
1142 this.partSite = site;
\r
1145 protected void setInput(IEditorInput input) {
\r
1146 Assert.isLegal(input != null);
\r
1147 editorInput = input;
\r
1150 public Composite getComposite() {
\r