/******************************************************************************* * Copyright (c) 2007, 2013 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation * Semantum Oy - issue #4384 *******************************************************************************/ package org.simantics.modeling.ui.diagramEditor; import java.awt.Color; import java.lang.reflect.InvocationTargetException; import java.util.function.Supplier; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.common.ResourceArray; import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.db.management.ISessionContextProvider; import org.simantics.db.request.Read; import org.simantics.diagram.adapter.DefaultConnectionClassFactory; import org.simantics.diagram.adapter.FlagClassFactory; import org.simantics.diagram.adapter.GraphToDiagramSynchronizer; import org.simantics.diagram.handler.ConnectionCommandHandler; import org.simantics.diagram.handler.CopyPasteHandler; import org.simantics.diagram.handler.DeleteHandler; import org.simantics.diagram.handler.ExpandSelectionHandler; import org.simantics.diagram.handler.SimpleElementTransformHandler; import org.simantics.diagram.layer.ILayersViewPage; import org.simantics.diagram.participant.ContextUtil; import org.simantics.diagram.participant.SGFocusParticipant; import org.simantics.diagram.query.DiagramRequests; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; import org.simantics.diagram.ui.SWTPopupMenuParticipant; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.CanvasContext; import org.simantics.g2d.chassis.SWTChassis; import org.simantics.g2d.diagram.DiagramClass; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.impl.Diagram; import org.simantics.g2d.diagram.participant.DiagramParticipant; import org.simantics.g2d.diagram.participant.ElementInteractor; import org.simantics.g2d.diagram.participant.ElementPainter; import org.simantics.g2d.diagram.participant.Selection; import org.simantics.g2d.diagram.participant.TerminalPainter; import org.simantics.g2d.diagram.participant.ZOrderHandler; import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; import org.simantics.g2d.element.ElementClassProviders; import org.simantics.g2d.element.ElementClasses; import org.simantics.g2d.element.IElementClassProvider; import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; import org.simantics.g2d.participant.CanvasBoundsParticipant; import org.simantics.g2d.participant.CanvasGrab; import org.simantics.g2d.participant.KeyUtil; import org.simantics.g2d.participant.MouseUtil; import org.simantics.g2d.participant.MultitouchPanZoomRotateInteractor; import org.simantics.g2d.participant.Notifications; import org.simantics.g2d.participant.PageBorderParticipant; import org.simantics.g2d.participant.PanZoomRotateHandler; import org.simantics.g2d.participant.PointerPainter; import org.simantics.g2d.participant.RulerPainter; import org.simantics.g2d.participant.SymbolUtil; import org.simantics.g2d.participant.TimeParticipant; import org.simantics.g2d.participant.TransformUtil; import org.simantics.g2d.participant.ZoomToAreaHandler; import org.simantics.layer0.utils.triggers.IActivation; import org.simantics.layer0.utils.triggers.IActivationManager; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.mapping.ModelingSynchronizationHints; import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider; import org.simantics.modeling.ui.preferences.DiagramPreferenceUtil; import org.simantics.modeling.ui.preferences.DiagramPreferences; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.snap.GridSnapAdvisor; import org.simantics.scenegraph.utils.NodeUtil; import org.simantics.selectionview.StandardPropertyPage; import org.simantics.ui.SimanticsUI; import org.simantics.ui.workbench.IPropertyPage; import org.simantics.ui.workbench.IResourceEditorInput; import org.simantics.ui.workbench.IResourceEditorInput2; import org.simantics.ui.workbench.IResourceEditorPart2; import org.simantics.ui.workbench.ResourceEditorSupport; import org.simantics.ui.workbench.TitleRequest; import org.simantics.ui.workbench.TitleUpdater; import org.simantics.ui.workbench.ToolTipRequest; import org.simantics.utils.DataContainer; import org.simantics.utils.datastructures.hints.IHintContext; import org.simantics.utils.page.PageDesc; import org.simantics.utils.threads.AWTThread; import org.simantics.utils.threads.IThreadWorkQueue; import org.simantics.utils.threads.SWTThread; import org.simantics.utils.threads.ThreadUtils; import org.simantics.utils.ui.ErrorLogger; /** * @author Toni Kalajainen * @author Tuukka Lehtonen */ public class SheetViewer extends EditorPart implements IResourceEditorPart2 { private static final boolean PROFILE = false; protected boolean disposed = false; protected IThreadWorkQueue swt; protected IStatusLineManager statusLineManager; protected SWTChassis c; protected IDiagram sourceDiagram; protected ICanvasContext canvasContext; protected ResourceEditorSupport support; protected ISessionContextProvider sessionContextProvider; protected ISessionContext sessionContext; protected Resource diagramResource; protected GraphToDiagramSynchronizer synchronizer; protected IActivation activation; protected ContextUtil contextUtil; protected DiagramPreferences diagramPreferences; protected GridSnapAdvisor snapAdvisor; public ResourceArray structuralPath; IPreferenceChangeListener preferenceListener = new IPreferenceChangeListener() { @Override public void preferenceChange(PreferenceChangeEvent event) { String value = (String) event.getNewValue(); if (DiagramPreferences.P_SNAP_GRID_SIZE.equals(event.getKey())) { double grid = DiagramPreferences.DEFAULT_SNAP_GRID_SIZE; if (value != null) grid = Double.parseDouble(value); snapAdvisor.setResolution(grid); } else if (DiagramPreferences.P_DEFAULT_PAGE_SIZE.equals(event.getKey())) { PageDesc pageDesc = PageDesc.deserialize(value, DiagramPreferences.DEFAULT_PAGE_SIZE); //System.out.println("new page desc: " + pageDesc); canvasContext.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc); } else if (DiagramPreferences.P_DISPLAY_PAGE_SIZE.equals(event.getKey())) { Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_PAGE_SIZE; canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, display); } else if (DiagramPreferences.P_DISPLAY_MARGINS.equals(event.getKey())) { Boolean display = value != null ? Boolean.parseBoolean(value) : DiagramPreferences.DEFAULT_DISPLAY_MARGINS; canvasContext.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_MARGINS, display); } } }; protected void addDropParticipants(ICanvasContext ctx) { // FIXME This is a workaround so that this participant can be disabled // for SymbolViewer ctx.add(new PopulateElementDropParticipant(synchronizer)); ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.5, 0.5)); } protected void addKeyBindingParticipants(CanvasContext ctx) { //ctx.add( new KeyToCommand( CommandKeyBinding.DEFAULT_BINDINGS ) ); ctx.add(new DeleteHandler(statusLineManager)); ctx.add(new CopyPasteHandler(statusLineManager)); ctx.add(new ConnectionCommandHandler()); } protected void addPopupmenu(ICanvasContext ctx) { ctx.add(new SWTPopupMenuParticipant(getSite(), c, getPopupId())); } protected void addStructureParticipants(ICanvasContext ctx) { structuralPath = getResourceInput().getResourceArray().removeFromBeginning(1); ctx.add(new WorkbenchStructuralSelectionProvider(swt, getSite(), structuralPath)); // Add visual browsing capabilities for structural models // ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, structuralPath)); // ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext)); } protected String getPopupId() { return "#ModelingDiagramPopup"; //$NON-NLS-1$ } protected void getPreferences() { this.diagramPreferences = DiagramPreferenceUtil.getPreferences(); } protected void initSession() { sessionContextProvider = Simantics.getSessionContextProvider(); sessionContext = sessionContextProvider.getSessionContext(); } protected void readNames() { String name = getEditorInput().getName(); setPartName(name); setTitleToolTip(name); } protected void createChassis(Composite parent) { c = new SWTChassis(parent, 0); c.syncPopulate(); } protected void setCanvasContext(ICanvasContext context) { c.setCanvasContext(canvasContext); } @Override public void createPartControl(Composite parent) { swt = SWTThread.getThreadAccess(parent.getDisplay()); statusLineManager = getEditorSite().getActionBars().getStatusLineManager(); Object task = BEGIN("DV.initSession"); //$NON-NLS-1$ initSession(); END(task); diagramResource = getInputResource(); readNames(); getPreferences(); task = BEGIN("DV.createChassis"); //$NON-NLS-1$ createChassis(parent); END(task); initializeCanvas(); // Start tracking changes in diagram preferences. diagramPreferences.preferences.addPreferenceChangeListener(preferenceListener); } protected void initializeCanvas() { Object canvasInit = BEGIN("DV.canvasInitialization"); //$NON-NLS-1$ Object task = BEGIN("DV.createViewerCanvas"); //$NON-NLS-1$ // ThreadUtils.syncExec(AWTThread.getThreadAccess(), new Runnable() { // @Override // public void run() { canvasContext = createViewerCanvas(); // } // }); END(task); //FullscreenUtils.addFullScreenHandler(canvasContext, s, canvasProvider); task = BEGIN("DV.setCanvasContext"); //$NON-NLS-1$ setCanvasContext(canvasContext); END(task); try { task = BEGIN("DV.loadDiagram"); //$NON-NLS-1$ sourceDiagram = loadDiagram(diagramResource); END(task); // Zoom to fit task = BEGIN("DV.scheduleZoomToFit"); //$NON-NLS-1$ // canvasContext.getDefaultHintContext().setHint(Hints.KEY_CANVAS_TRANSFORM, new AffineTransform()); // canvasContext.getContentContext().setDirty(); scheduleZoomToFit(); END(task); // Start an activation for the input resource. // This will activate mapping if necessary. task = BEGIN("DV.performActivation"); //$NON-NLS-1$ performActivation(); END(task); task = BEGIN("DV.activate context"); //$NON-NLS-1$ contextUtil.activate(DiagramViewer.DIAGRAMMING_CONTEXT); END(task); task = BEGIN("DV.onCreated"); //$NON-NLS-1$ onCreated(); END(task); } catch (DatabaseException e) { ErrorLogger.defaultLogError(e); // Without this all diagram participants will crash like there's no tomorrow. // Just trying to keep the behavior a bit more sane in case of // errors instead of flooding the console with exceptions. canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, Diagram.spawnNew(DiagramClass.DEFAULT)); } END(canvasInit); } protected void performActivation() { IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class); if (activationManager != null) { activation = activationManager.activate(diagramResource); } } protected void scheduleZoomToFit() { if (sourceDiagram == null) throw new IllegalStateException("source diagram is null"); //$NON-NLS-1$ sourceDiagram.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE); sourceDiagram.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE); ThreadUtils.asyncExec(swt, new Runnable() { @Override public void run() { if (disposed) return; // System.out.println("size: " + c.getSize()); ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() { @Override public void run() { if (disposed) return; // System.out.println("fit diagram to view"); sourceDiagram.removeHint(Hints.KEY_DISABLE_PAINTING); /*Boolean zoomToFit =*/ sourceDiagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT); canvasContext.getDefaultHintContext().removeHint(Hints.KEY_DISABLE_PAINTING); // if (Boolean.TRUE.equals(zoomToFit)) // CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT); canvasContext.getContentContext().setDirty(); } }); } }); } protected IDiagram loadDiagram(final Resource r) throws DatabaseException { final DataContainer dc = new DataContainer(); //dc.set( loadDiagram(new NullProgressMonitor(), r) ); try { PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { SubMonitor mon = SubMonitor.convert(monitor, Messages.SheetViewer_MonitorLoadingDiagram, 100); try { dc.set( loadDiagram(mon.newChild(100), r) ); } catch (DatabaseException e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof DatabaseException) throw (DatabaseException) t; throw new DatabaseException(t); } catch (InterruptedException e) { throw new DatabaseException(e); } return dc.get(); } protected IDiagram loadDiagram(IProgressMonitor monitor, Resource r) throws DatabaseException { SubMonitor mon = SubMonitor.convert(monitor, Messages.SheetViewer_MonitorLoadingDiagram, 100); Object task = BEGIN("DV.DiagramLoadQuery"); //$NON-NLS-1$ IDiagram d = sessionContext.getSession().syncRequest(DiagramRequests.loadDiagram(mon.newChild(100), getResourceInput2().getModel(null), r, null, structuralPath, synchronizer, null)); END(task); task = BEGIN("DV.setDiagramHint"); //$NON-NLS-1$ canvasContext.getDefaultHintContext().setHint(DiagramHints.KEY_DIAGRAM, d); END(task); task = BEGIN("DV.set other hints"); //$NON-NLS-1$ // Setup a copy advisor for the synchronizer //d.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ComponentCopyAdvisor())); d.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, Boolean.FALSE); d.setHint(DiagramHints.KEY_ALLOW_CONNECTION_BRANCHING, Boolean.FALSE); d.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE); END(task); return d; } protected GraphToDiagramSynchronizer createSynchronizer(final ICanvasContext ctx, final ISessionContext sessionContext) { try { return sessionContext.getSession().syncRequest(new Read() { @Override public GraphToDiagramSynchronizer perform(ReadGraph graph) throws DatabaseException { GraphToDiagramSynchronizer sync = new GraphToDiagramSynchronizer(graph, ctx, createElementClassProvider(graph)); initializeSynchronizationContext(graph, sync); return sync; } }); } catch (DatabaseException e) { throw new UnsupportedOperationException("Failed to initialize data model synchronizer", e); //$NON-NLS-1$ } } protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) { context.set(ModelingSynchronizationHints.MODELING_RESOURCE, ModelingResources.getInstance(graph)); } protected IElementClassProvider createElementClassProvider(ReadGraph graph) { DiagramResource dr = DiagramResource.getInstance(graph); return ElementClassProviders.mappedProvider( ElementClasses.CONNECTION, DefaultConnectionClassFactory.CLASS.newClassWith(new StaticObjectAdapter(dr.Connection)), ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag, dr.Flag_Terminal) ); } public ICanvasContext createViewerCanvas() { IThreadWorkQueue thread = AWTThread.getThreadAccess(); CanvasContext ctx = new CanvasContext(thread); IHintContext h = ctx.getDefaultHintContext(); Object task = BEGIN("createSynchronizer"); //$NON-NLS-1$ this.synchronizer = createSynchronizer(ctx, sessionContext); END(task); IContextService contextService = (IContextService) getSite().getService(IContextService.class); contextUtil = new ContextUtil(contextService, swt); ctx.add(new PanZoomRotateHandler()); // Must be before TransformUtil // Support & Util Participants ctx.add(new TransformUtil()); ctx.add(new MouseUtil()); ctx.add(new KeyUtil()); ctx.add(contextUtil); ctx.add(new CanvasGrab()); ctx.add(new SymbolUtil()); ctx.add(new TimeParticipant()); ctx.add(new CanvasBoundsParticipant()); ctx.add(new Notifications()); ctx.add( new SGFocusParticipant(c, DiagramViewer.DIAGRAMMING_CONTEXT) ); // Debug participant(s) // ctx.add( new PointerPainter() ); // ctx.add( new HandPainter() ); h.setHint(PointerPainter.KEY_PAINT_POINTER, true); // Pan & Zoom & Rotate ctx.add(new MultitouchPanZoomRotateInteractor()); // ctx.add( new OrientationRestorer() ); ctx.add(new ZoomToAreaHandler()); ctx.add(new SimpleElementTransformHandler(true, true, true)); ctx.add(new ExpandSelectionHandler(getEditorSite().getActionBars().getStatusLineManager())); // Key bindings addKeyBindingParticipants(ctx); // Grid & Ruler & Background // ctx.add(new GridPainter()); // ctx.add(new RulerPainter()); // ctx.add(new BackgroundPainter()); h.setHint(PanZoomRotateHandler.KEY_ADAPT_VIEWPORT_TO_RESIZED_CONTROL, Boolean.FALSE); h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE)); h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS)); ctx.add(new PageBorderParticipant()); // h.setHint(Hints.KEY_GRID_COLOR, new Color(0.9f, 0.9f, 0.9f)); // h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.LIGHT_GRAY); h.setHint(Hints.KEY_GRID_COLOR, new Color(0.95f, 0.95f, 0.95f)); h.setHint(Hints.KEY_BACKGROUND_COLOR, Color.WHITE); h.setHint(RulerPainter.KEY_RULER_BACKGROUND_COLOR, new Color(0.9f, 0.9f, 0.9f, 0.75f)); h.setHint(RulerPainter.KEY_RULER_TEXT_COLOR, Color.BLACK); ////// Diagram Participants ////// ctx.add(new ZOrderHandler()); ctx.add(new PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider(), null)); ctx.add(new ElementInteractor()); ctx.add(new Selection()); ctx.add(new DiagramParticipant()); ctx.add(new ElementPainter()); ctx.add(new TerminalPainter(true, true, false, true)); //ctx.add(new ElementHeartbeater()); // ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID)); /////// D'n'D /////// addDropParticipants(ctx); h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA); h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL); h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0); h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0); Double snapResolution = diagramPreferences.get(DiagramPreferences.P_SNAP_GRID_SIZE); this.snapAdvisor = new GridSnapAdvisor(snapResolution); h.setHint(DiagramHints.SNAP_ADVISOR, this.snapAdvisor); // Workbench selection provider addStructureParticipants(ctx); // Pop-up menu addPopupmenu(ctx); // Load page frame description settings loadPageSettings(ctx); // The canvas context should not be painted until it is ready to avoid // unnecessary visual glitches. h.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE); ctx.assertParticipantDependencies(); return ctx; } protected void loadPageSettings(ICanvasContext ctx) { PageDesc pageDesc = null; if (diagramResource != null) { try { pageDesc = sessionContext.getSession().syncRequest(new Read() { @Override public PageDesc perform(ReadGraph graph) throws DatabaseException { return DiagramGraphUtil.getPageDesc(graph, diagramResource, null); } }); } catch (DatabaseException e) { ErrorLogger.defaultLogError(e); } } if (pageDesc == null) { // Take page description from the preferences if nothing else is available. PageDesc pd = diagramPreferences.getCompletePageDesc(); pageDesc = pd; } ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc); } private boolean firstFocus = true; @Override public void setFocus() { c.setFocus(); if (firstFocus) { // This is a workaround for using the symbol viewer in multi-page // editors which causes the first zoom-to-fit scheduling to happen // already before the controls have been laid out properly. firstFocus = false; firstTimeSetFocus(); } } protected void firstTimeSetFocus() { //scheduleZoomToFit(); } @Override public void dispose() { // Remember to remove the added preference change listener diagramPreferences.preferences.removePreferenceChangeListener(preferenceListener); // Deactivate all contexts here because after this the context service // in question will not be available. contextUtil.deactivateAll(); disposed = true; if (activation != null) { activation.deactivate(); activation = null; } synchronizer.dispose(); ThreadUtils.asyncExec(c.getCanvasContext().getThreadAccess(), new Runnable() { @Override public void run() { c.getCanvasContext().dispose(); } }); sourceDiagram.dispose(); support.dispose(); super.dispose(); } protected Resource getInputResource() { return getResourceInput().getResource(); } @Override public IResourceEditorInput2 getResourceInput2() { return (IResourceEditorInput2) getEditorInput(); } @Override public IResourceEditorInput getResourceInput() { return (IResourceEditorInput) getEditorInput(); } @Override public void doSave(IProgressMonitor monitor) { } @Override public void doSaveAs() { } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { if (!(input instanceof IResourceEditorInput)) throw new PartInitException("Invalid input: must be IResourceEditorInput"); //$NON-NLS-1$ setSite(site); setInput(input); support = new ResourceEditorSupport(this); // Set initial part name according to the name given by IEditorInput setPartName(getEditorInput().getName()); Session session = Simantics.peekSession(); if (session != null) { Supplier disposedCallback = () -> disposed; session.asyncRequest( new TitleRequest(site.getId(), getResourceInput2()), new TitleUpdater(site.getShell().getDisplay(), this::setPartName, disposedCallback)); session.asyncRequest( new ToolTipRequest(site.getId(), getResourceInput2()), new TitleUpdater(site.getShell().getDisplay(), this::setTitleToolTip, disposedCallback)); } } @Override public boolean isDirty() { return false; } @Override public boolean isSaveAsAllowed() { return false; } @SuppressWarnings("unchecked") @Override public T getAdapter(Class adapter) { if (adapter == IPropertyPage.class) return (T) new StandardPropertyPage(getSite()); if (adapter == IContentOutlinePage.class) return (T) new DiagramOutlinePage(sessionContextProvider, getResourceInput2()); if (adapter == ILayersViewPage.class) return (T) new DiagramLayersPage(sourceDiagram, canvasContext); if (adapter == ICanvasContext.class) return (T) canvasContext; if (adapter == INode.class) { if (canvasContext != null) { INode node = canvasContext.getCanvasNode(); if (node != null) return (T) NodeUtil.getRootNode(node); } return null; } if (adapter == IDiagram.class) return (T) sourceDiagram; if (adapter == Session.class) return (T) sessionContext.getSession(); return super.getAdapter(adapter); } protected void onCreated() { } private static Object BEGIN(String name) { if (PROFILE) { //return ThreadLog.BEGIN(name); } return null; } private static void END(Object task) { if (PROFILE) { //((Task) task).end(); } } }