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.lang.reflect.InvocationTargetException;
\r
17 import java.util.function.Supplier;
\r
19 import org.eclipse.core.runtime.IProgressMonitor;
\r
20 import org.eclipse.core.runtime.SubMonitor;
\r
21 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
\r
22 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
\r
23 import org.eclipse.jface.action.IStatusLineManager;
\r
24 import org.eclipse.jface.operation.IRunnableWithProgress;
\r
25 import org.eclipse.swt.widgets.Composite;
\r
26 import org.eclipse.ui.IEditorInput;
\r
27 import org.eclipse.ui.IEditorSite;
\r
28 import org.eclipse.ui.PartInitException;
\r
29 import org.eclipse.ui.PlatformUI;
\r
30 import org.eclipse.ui.contexts.IContextService;
\r
31 import org.eclipse.ui.part.EditorPart;
\r
32 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
\r
33 import org.simantics.db.ReadGraph;
\r
34 import org.simantics.db.Resource;
\r
35 import org.simantics.db.Session;
\r
36 import org.simantics.db.common.ResourceArray;
\r
37 import org.simantics.db.exception.DatabaseException;
\r
38 import org.simantics.db.management.ISessionContext;
\r
39 import org.simantics.db.management.ISessionContextProvider;
\r
40 import org.simantics.db.request.Read;
\r
41 import org.simantics.diagram.adapter.DefaultConnectionClassFactory;
\r
42 import org.simantics.diagram.adapter.FlagClassFactory;
\r
43 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
\r
44 import org.simantics.diagram.handler.ConnectionCommandHandler;
\r
45 import org.simantics.diagram.handler.CopyPasteHandler;
\r
46 import org.simantics.diagram.handler.DeleteHandler;
\r
47 import org.simantics.diagram.handler.ExpandSelectionHandler;
\r
48 import org.simantics.diagram.handler.SimpleElementTransformHandler;
\r
49 import org.simantics.diagram.layer.ILayersViewPage;
\r
50 import org.simantics.diagram.participant.ContextUtil;
\r
51 import org.simantics.diagram.participant.SGFocusParticipant;
\r
52 import org.simantics.diagram.query.DiagramRequests;
\r
53 import org.simantics.diagram.stubs.DiagramResource;
\r
54 import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;
\r
55 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
\r
56 import org.simantics.diagram.ui.SWTPopupMenuParticipant;
\r
57 import org.simantics.g2d.canvas.Hints;
\r
58 import org.simantics.g2d.canvas.ICanvasContext;
\r
59 import org.simantics.g2d.canvas.impl.CanvasContext;
\r
60 import org.simantics.g2d.chassis.SWTChassis;
\r
61 import org.simantics.g2d.diagram.DiagramClass;
\r
62 import org.simantics.g2d.diagram.DiagramHints;
\r
63 import org.simantics.g2d.diagram.IDiagram;
\r
64 import org.simantics.g2d.diagram.impl.Diagram;
\r
65 import org.simantics.g2d.diagram.participant.DiagramParticipant;
\r
66 import org.simantics.g2d.diagram.participant.ElementInteractor;
\r
67 import org.simantics.g2d.diagram.participant.ElementPainter;
\r
68 import org.simantics.g2d.diagram.participant.Selection;
\r
69 import org.simantics.g2d.diagram.participant.TerminalPainter;
\r
70 import org.simantics.g2d.diagram.participant.ZOrderHandler;
\r
71 import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
\r
72 import org.simantics.g2d.element.ElementClassProviders;
\r
73 import org.simantics.g2d.element.ElementClasses;
\r
74 import org.simantics.g2d.element.IElementClassProvider;
\r
75 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
\r
76 import org.simantics.g2d.participant.CanvasBoundsParticipant;
\r
77 import org.simantics.g2d.participant.CanvasGrab;
\r
78 import org.simantics.g2d.participant.KeyUtil;
\r
79 import org.simantics.g2d.participant.MouseUtil;
\r
80 import org.simantics.g2d.participant.MultitouchPanZoomRotateInteractor;
\r
81 import org.simantics.g2d.participant.Notifications;
\r
82 import org.simantics.g2d.participant.PageBorderParticipant;
\r
83 import org.simantics.g2d.participant.PanZoomRotateHandler;
\r
84 import org.simantics.g2d.participant.PointerPainter;
\r
85 import org.simantics.g2d.participant.RulerPainter;
\r
86 import org.simantics.g2d.participant.SymbolUtil;
\r
87 import org.simantics.g2d.participant.TimeParticipant;
\r
88 import org.simantics.g2d.participant.TransformUtil;
\r
89 import org.simantics.g2d.participant.ZoomToAreaHandler;
\r
90 import org.simantics.layer0.utils.triggers.IActivation;
\r
91 import org.simantics.layer0.utils.triggers.IActivationManager;
\r
92 import org.simantics.modeling.ModelingResources;
\r
93 import org.simantics.modeling.mapping.ModelingSynchronizationHints;
\r
94 import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider;
\r
95 import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil;
\r
96 import org.simantics.modeling.ui.preferences.DiagramPreferences;
\r
97 import org.simantics.scenegraph.INode;
\r
98 import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor;
\r
99 import org.simantics.scenegraph.utils.NodeUtil;
\r
100 import org.simantics.selectionview.StandardPropertyPage;
\r
101 import org.simantics.ui.SimanticsUI;
\r
102 import org.simantics.ui.workbench.IPropertyPage;
\r
103 import org.simantics.ui.workbench.IResourceEditorInput;
\r
104 import org.simantics.ui.workbench.IResourceEditorInput2;
\r
105 import org.simantics.ui.workbench.IResourceEditorPart2;
\r
106 import org.simantics.ui.workbench.ResourceEditorSupport;
\r
107 import org.simantics.ui.workbench.TitleRequest;
\r
108 import org.simantics.ui.workbench.TitleUpdater;
\r
109 import org.simantics.ui.workbench.ToolTipRequest;
\r
110 import org.simantics.utils.DataContainer;
\r
111 import org.simantics.utils.datastructures.hints.IHintContext;
\r
112 import org.simantics.utils.page.PageDesc;
\r
113 import org.simantics.utils.threads.AWTThread;
\r
114 import org.simantics.utils.threads.IThreadWorkQueue;
\r
115 import org.simantics.utils.threads.SWTThread;
\r
116 import org.simantics.utils.threads.ThreadUtils;
\r
117 import org.simantics.utils.ui.ErrorLogger;
\r
120 * @author Toni Kalajainen
\r
121 * @author Tuukka Lehtonen
\r
123 public class SheetViewer extends EditorPart implements IResourceEditorPart2 {
\r
125 private static final boolean PROFILE = false;
\r
127 protected boolean disposed = false;
\r
128 protected IThreadWorkQueue swt;
\r
129 protected IStatusLineManager statusLineManager;
\r
130 protected SWTChassis c;
\r
131 protected IDiagram sourceDiagram;
\r
132 protected ICanvasContext canvasContext;
\r
133 protected ResourceEditorSupport support;
\r
134 protected ISessionContextProvider sessionContextProvider;
\r
135 protected ISessionContext sessionContext;
\r
136 protected Resource diagramResource;
\r
137 protected GraphToDiagramSynchronizer synchronizer;
\r
138 protected IActivation activation;
\r
139 protected ContextUtil contextUtil;
\r
141 protected DiagramPreferences diagramPreferences;
\r
142 protected GridSnapAdvisor snapAdvisor;
\r
144 public ResourceArray structuralPath;
\r
146 IPreferenceChangeListener preferenceListener = new IPreferenceChangeListener() {
\r
148 public void preferenceChange(PreferenceChangeEvent event) {
\r
149 String value = (String) event.getNewValue();
\r
150 if (DiagramPreferences.P_SNAP_GRID_SIZE.equals(event.getKey())) {
\r
151 double grid = DiagramPreferences.DEFAULT_SNAP_GRID_SIZE;
\r
153 grid = Double.parseDouble(value);
\r
154 snapAdvisor.setResolution(grid);
\r
155 } else if (DiagramPreferences.P_DEFAULT_PAGE_SIZE.equals(event.getKey())) {
\r
156 PageDesc pageDesc = PageDesc.deserialize(value, DiagramPreferences.DEFAULT_PAGE_SIZE);
\r
157 //System.out.println("new page desc: " + pageDesc);
\r
158 canvasContext.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
\r
159 } else if (DiagramPreferences.P_DISPLAY_PAGE_SIZE.equals(event.getKey())) {
\r
160 Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_PAGE_SIZE;
\r
161 canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, display);
\r
162 } else if (DiagramPreferences.P_DISPLAY_MARGINS.equals(event.getKey())) {
\r
163 Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_MARGINS;
\r
164 canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_MARGINS, display);
\r
169 protected void addDropParticipants(ICanvasContext ctx) {
\r
170 // FIXME This is a workaround so that this participant can be disabled
\r
171 // for SymbolViewer
\r
172 ctx.add(new PopulateElementDropParticipant(synchronizer));
\r
173 ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5));
\r
176 protected void addKeyBindingParticipants(CanvasContext ctx) {
\r
177 //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) );
\r
178 ctx.add(new DeleteHandler(statusLineManager));
\r
179 ctx.add(new CopyPasteHandler(statusLineManager));
\r
180 ctx.add(new ConnectionCommandHandler());
\r
183 protected void addPopupmenu(ICanvasContext ctx) {
\r
184 ctx.add(new SWTPopupMenuParticipant(getSite(), c, getPopupId()));
\r
187 protected void addStructureParticipants(ICanvasContext ctx) {
\r
188 structuralPath = getResourceInput().getResourceArray().removeFromBeginning(1);
\r
190 ctx.add(new WorkbenchStructuralSelectionProvider(swt, getSite(), structuralPath));
\r
191 // Add visual browsing capabilities for structural models
\r
192 // ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, structuralPath));
\r
193 // ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));
\r
196 protected String getPopupId() {
\r
197 return "#ModelingDiagramPopup";
\r
200 protected void getPreferences() {
\r
201 this.diagramPreferences = DiagramPreferenceUtil.getPreferences();
\r
204 protected void initSession() {
\r
205 sessionContextProvider = SimanticsUI.getSessionContextProvider();
\r
206 sessionContext = sessionContextProvider.getSessionContext();
\r
209 protected void readNames() {
\r
210 String name = getEditorInput().getName();
\r
212 setTitleToolTip(name);
\r
215 protected void createChassis(Composite parent) {
\r
216 c = new SWTChassis(parent, 0);
\r
220 protected void setCanvasContext(ICanvasContext context) {
\r
221 c.setCanvasContext(canvasContext);
\r
225 public void createPartControl(Composite parent) {
\r
226 swt = SWTThread.getThreadAccess(parent.getDisplay());
\r
227 statusLineManager = getEditorSite().getActionBars().getStatusLineManager();
\r
229 Object task = BEGIN("DV.initSession");
\r
233 diagramResource = getInputResource();
\r
237 task = BEGIN("DV.createChassis");
\r
238 createChassis(parent);
\r
241 initializeCanvas();
\r
243 // Start tracking changes in diagram preferences.
\r
244 diagramPreferences.preferences.addPreferenceChangeListener(preferenceListener);
\r
247 protected void initializeCanvas() {
\r
248 Object canvasInit = BEGIN("DV.canvasInitialization");
\r
250 Object task = BEGIN("DV.createViewerCanvas");
\r
251 // ThreadUtils.syncExec(AWTThread.getThreadAccess(), new Runnable() {
\r
253 // public void run() {
\r
254 canvasContext = createViewerCanvas();
\r
259 //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider);
\r
261 task = BEGIN("DV.setCanvasContext");
\r
262 setCanvasContext(canvasContext);
\r
266 task = BEGIN("DV.loadDiagram");
\r
267 sourceDiagram = loadDiagram(diagramResource);
\r
271 task = BEGIN("DV.scheduleZoomToFit");
\r
273 // canvasContext.getDefaultHintContext().setHint(Hints.KEY_CANVAS_TRANSFORM, new AffineTransform());
\r
274 // canvasContext.getContentContext().setDirty();
\r
275 scheduleZoomToFit();
\r
279 // Start an activation for the input resource.
\r
280 // This will activate mapping if necessary.
\r
281 task = BEGIN("DV.performActivation");
\r
282 performActivation();
\r
285 task = BEGIN("DV.activate context");
\r
286 contextUtil.activate(DiagramViewer.DIAGRAMMING_CONTEXT);
\r
289 task = BEGIN("DV.onCreated");
\r
293 } catch (DatabaseException e) {
\r
294 ErrorLogger.defaultLogError(e);
\r
296 // Without this all diagram participants will crash like there's no tomorrow.
\r
297 // Just trying to keep the behavior a bit more sane in case of
\r
298 // errors instead of flooding the console with exceptions.
\r
299 canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT));
\r
304 protected void performActivation() {
\r
306 IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);
\r
307 if (activationManager != null) {
\r
308 activation = activationManager.activate(diagramResource);
\r
313 protected void scheduleZoomToFit() {
\r
314 if (sourceDiagram == null)
\r
315 throw new IllegalStateException("source diagram is null");
\r
317 sourceDiagram.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
\r
318 sourceDiagram.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE);
\r
319 ThreadUtils.asyncExec(swt, new Runnable() {
\r
321 public void run() {
\r
325 // System.out.println("size: " + c.getSize());
\r
326 ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {
\r
328 public void run() {
\r
331 // System.out.println("fit diagram to view");
\r
332 sourceDiagram.removeHint(Hints.KEY_DISABLE_PAINTING);
\r
333 /*Boolean zoomToFit =*/ sourceDiagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);
\r
334 canvasContext.getDefaultHintContext().removeHint(Hints.KEY_DISABLE_PAINTING);
\r
336 // if (Boolean.TRUE.equals(zoomToFit))
\r
337 // CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT);
\r
339 canvasContext.getContentContext().setDirty();
\r
348 protected IDiagram loadDiagram(final Resource r) throws DatabaseException {
\r
349 final DataContainer<IDiagram> dc = new DataContainer<IDiagram>();
\r
350 //dc.set( loadDiagram(new NullProgressMonitor(), r) );
\r
352 PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
\r
354 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
\r
355 SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);
\r
357 dc.set( loadDiagram(mon.newChild(100), r) );
\r
358 } catch (DatabaseException e) {
\r
359 throw new InvocationTargetException(e);
\r
365 } catch (InvocationTargetException e) {
\r
366 Throwable t = e.getTargetException();
\r
367 if (t instanceof DatabaseException)
\r
368 throw (DatabaseException) t;
\r
369 throw new DatabaseException(t);
\r
370 } catch (InterruptedException e) {
\r
371 throw new DatabaseException(e);
\r
376 protected IDiagram loadDiagram(IProgressMonitor monitor, Resource r) throws DatabaseException {
\r
377 SubMonitor mon = SubMonitor.convert(monitor, "Loading Diagram", 100);
\r
379 Object task = BEGIN("DV.DiagramLoadQuery");
\r
380 IDiagram d = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(mon.newChild(100), getResourceInput2().getModel(null), r, null, structuralPath, synchronizer, null));
\r
383 task = BEGIN("DV.setDiagramHint");
\r
384 canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, d);
\r
387 task = BEGIN("DV.set other hints");
\r
388 // Setup a copy advisor for the synchronizer
\r
389 //d.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ComponentCopyAdvisor()));
\r
390 d.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.FALSE);
\r
391 d.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.FALSE);
\r
392 d.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE);
\r
398 protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) {
\r
400 return sessionContext.getSession().syncRequest(new Read<GraphToDiagramSynchronizer>() {
\r
402 public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException {
\r
403 GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph));
\r
404 initializeSynchronizationContext(graph, sync);
\r
408 } catch (DatabaseException e) {
\r
409 throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e);
\r
413 protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {
\r
414 context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph));
\r
417 protected IElementClassProvider createElementClassProvider(ReadGraph graph) {
\r
418 DiagramResource dr = DiagramResource.getInstance(graph);
\r
419 return ElementClassProviders.mappedProvider(
\r
420 ElementClasses.CONNECTION, DefaultConnectionClassFactory.CLASS.newClassWith(new StaticObjectAdapter(dr.Connection)),
\r
421 ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal)
\r
425 public ICanvasContext createViewerCanvas() {
\r
426 IThreadWorkQueue thread = AWTThread.getThreadAccess();
\r
427 CanvasContext ctx = new CanvasContext(thread);
\r
428 IHintContext h = ctx.getDefaultHintContext();
\r
430 Object task = BEGIN("createSynchronizer");
\r
431 this.synchronizer = createSynchronizer(ctx, sessionContext);
\r
434 IContextService contextService = (IContextService) getSite().getService(IContextService.class);
\r
435 contextUtil = new ContextUtil(contextService, swt);
\r
437 ctx.add(new PanZoomRotateHandler()); // Must be before TransformUtil
\r
439 // Support & Util Participants
\r
440 ctx.add(new TransformUtil());
\r
441 ctx.add(new MouseUtil());
\r
442 ctx.add(new KeyUtil());
\r
443 ctx.add(contextUtil);
\r
444 ctx.add(new CanvasGrab());
\r
445 ctx.add(new SymbolUtil());
\r
446 ctx.add(new TimeParticipant());
\r
447 ctx.add(new CanvasBoundsParticipant());
\r
448 ctx.add(new Notifications());
\r
450 ctx.add( new SGFocusParticipant(c, DiagramViewer.DIAGRAMMING_CONTEXT) );
\r
452 // Debug participant(s)
\r
453 // ctx.add( new PointerPainter() );
\r
454 // ctx.add( new HandPainter() );
\r
455 h.setHint(PointerPainter.KEY_PAINT_POINTER, true);
\r
457 // Pan & Zoom & Rotate
\r
458 ctx.add(new MultitouchPanZoomRotateInteractor());
\r
459 // ctx.add( new OrientationRestorer() );
\r
460 ctx.add(new ZoomToAreaHandler());
\r
461 ctx.add(new SimpleElementTransformHandler(true, true, true));
\r
462 ctx.add(new ExpandSelectionHandler(getEditorSite().getActionBars().getStatusLineManager()));
\r
465 addKeyBindingParticipants(ctx);
\r
467 // Grid & Ruler & Background
\r
468 // ctx.add(new GridPainter());
\r
469 // ctx.add(new RulerPainter());
\r
470 // ctx.add(new BackgroundPainter());
\r
473 h.setHint(PanZoomRotateHandler.KEY_ADAPT_VIEWPORT_TO_RESIZED_CONTROL, Boolean.FALSE);
\r
474 h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));
\r
475 h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));
\r
476 ctx.add(new PageBorderParticipant());
\r
478 // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f));
\r
479 // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY);
\r
480 h.setHint(Hints.KEY_GRID_COLOR, new Color(0.95f, 0.95f, 0.95f));
\r
481 h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE);
\r
482 h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f));
\r
483 h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK);
\r
485 ////// Diagram Participants //////
\r
486 ctx.add(new ZOrderHandler());
\r
487 ctx.add(new PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider(), null));
\r
488 ctx.add(new ElementInteractor());
\r
489 ctx.add(new Selection());
\r
490 ctx.add(new DiagramParticipant());
\r
491 ctx.add(new ElementPainter());
\r
492 ctx.add(new TerminalPainter(true, true, false, true));
\r
493 //ctx.add(new ElementHeartbeater());
\r
494 // ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));
\r
496 /////// D'n'D ///////
\r
497 addDropParticipants(ctx);
\r
499 h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA);
\r
500 h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);
\r
502 h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0);
\r
503 h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0);
\r
505 Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE);
\r
506 this.snapAdvisor = new GridSnapAdvisor(snapResolution);
\r
507 h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor);
\r
509 // Workbench selection provider
\r
510 addStructureParticipants(ctx);
\r
515 // Load page frame description settings
\r
516 loadPageSettings(ctx);
\r
518 // The canvas context should not be painted until it is ready to avoid
\r
519 // unnecessary visual glitches.
\r
520 h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);
\r
522 ctx.assertParticipantDependencies();
\r
527 protected void loadPageSettings(ICanvasContext ctx) {
\r
528 PageDesc pageDesc = null;
\r
530 if (diagramResource != null) {
\r
532 pageDesc = sessionContext.getSession().syncRequest(new Read<PageDesc>() {
\r
534 public PageDesc perform(ReadGraph graph) throws DatabaseException {
\r
535 return DiagramGraphUtil.getPageDesc(graph, diagramResource, null);
\r
538 } catch (DatabaseException e) {
\r
539 ErrorLogger.defaultLogError(e);
\r
543 if (pageDesc == null) {
\r
544 // Take page description from the preferences if nothing else is available.
\r
545 PageDesc pd = diagramPreferences.getCompletePageDesc();
\r
548 ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
\r
551 private boolean firstFocus = true;
\r
554 public void setFocus() {
\r
558 // This is a workaround for using the symbol viewer in multi-page
\r
559 // editors which causes the first zoom-to-fit scheduling to happen
\r
560 // already before the controls have been laid out properly.
\r
561 firstFocus = false;
\r
562 firstTimeSetFocus();
\r
566 protected void firstTimeSetFocus() {
\r
567 //scheduleZoomToFit();
\r
571 public void dispose() {
\r
572 // Remember to remove the added preference change listener
\r
573 diagramPreferences.preferences.removePreferenceChangeListener(preferenceListener);
\r
575 // Deactivate all contexts here because after this the context service
\r
576 // in question will not be available.
\r
577 contextUtil.deactivateAll();
\r
580 if (activation != null) {
\r
581 activation.deactivate();
\r
584 synchronizer.dispose();
\r
585 ThreadUtils.asyncExec(c.getCanvasContext().getThreadAccess(), new Runnable() {
\r
587 public void run() {
\r
588 c.getCanvasContext().dispose();
\r
591 sourceDiagram.dispose();
\r
596 protected Resource getInputResource() {
\r
597 return getResourceInput().getResource();
\r
601 public IResourceEditorInput2 getResourceInput2() {
\r
602 return (IResourceEditorInput2) getEditorInput();
\r
606 public IResourceEditorInput getResourceInput() {
\r
607 return (IResourceEditorInput) getEditorInput();
\r
611 public void doSave(IProgressMonitor monitor) {
\r
615 public void doSaveAs() {
\r
619 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
\r
620 if (!(input instanceof IResourceEditorInput))
\r
621 throw new PartInitException("Invalid input: must be IResourceEditorInput");
\r
624 support = new ResourceEditorSupport(this);
\r
626 // Set initial part name according to the name given by IEditorInput
\r
627 setPartName(getEditorInput().getName());
\r
629 Session session = SimanticsUI.peekSession();
\r
630 if (session != null) {
\r
631 Supplier<Boolean> disposedCallback = () -> disposed;
\r
632 session.asyncRequest(
\r
633 new TitleRequest(site.getId(), getResourceInput2()),
\r
634 new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback));
\r
635 session.asyncRequest(
\r
636 new ToolTipRequest(site.getId(), getResourceInput2()),
\r
637 new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback));
\r
643 public boolean isDirty() {
\r
648 public boolean isSaveAsAllowed() {
\r
652 @SuppressWarnings("unchecked")
\r
654 public <T> T getAdapter(Class<T> adapter) {
\r
655 if (adapter == IPropertyPage.class)
\r
656 return (T) new StandardPropertyPage(getSite());
\r
657 if (adapter == IContentOutlinePage.class)
\r
658 return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2());
\r
659 if (adapter == ILayersViewPage.class)
\r
660 return (T) new DiagramLayersPage(sourceDiagram, canvasContext);
\r
661 if (adapter == ICanvasContext.class)
\r
662 return (T) canvasContext;
\r
663 if (adapter == INode.class) {
\r
664 if (canvasContext != null) {
\r
665 INode node = canvasContext.getCanvasNode();
\r
667 return (T) NodeUtil.getRootNode(node);
\r
671 if (adapter == IDiagram.class)
\r
672 return (T) sourceDiagram;
\r
673 if (adapter == Session.class)
\r
674 return (T) sessionContext.getSession();
\r
675 return super.getAdapter(adapter);
\r
678 protected void onCreated() {
\r
682 private static Object BEGIN(String name) {
\r
684 //return ThreadLog.BEGIN(name);
\r
689 private static void END(Object task) {
\r
691 //((Task) task).end();
\r