X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FDiagramModelActivityTracker.java;fp=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FDiagramModelActivityTracker.java;h=630032baeda2def1bd4b1e0b4c39a4c53907fb04;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=a12043f10375dd7c781c402e531c18e200772e01;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java index a12043f10..630032bae 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/DiagramModelActivityTracker.java @@ -1,245 +1,245 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 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 - *******************************************************************************/ -package org.simantics.diagram.participant; - -import java.awt.Color; -import java.awt.Font; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.common.request.PossibleIndexRoot; -import org.simantics.db.common.request.UnaryRead; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.adapter.Instances; -import org.simantics.db.layer0.request.IsActive; -import org.simantics.db.layer0.util.Layer0Utils; -import org.simantics.db.procedure.Listener; -import org.simantics.diagram.elements.TextNode; -import org.simantics.diagram.stubs.DiagramResource; -import org.simantics.g2d.canvas.Hints; -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.canvas.SGDesignation; -import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; -import org.simantics.g2d.canvas.impl.HintReflection.HintListener; -import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; -import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; -import org.simantics.g2d.utils.Alignment; -import org.simantics.layer0.Layer0; -import org.simantics.modeling.ModelingResources; -import org.simantics.scenegraph.g2d.G2DParentNode; -import org.simantics.structural.stubs.StructuralResource2; -import org.simantics.utils.datastructures.hints.IHintContext; -import org.simantics.utils.datastructures.hints.IHintContext.Key; -import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; -import org.simantics.utils.datastructures.hints.IHintObservable; -import org.simantics.utils.ui.ErrorLogger; - -/** - * DiagramModelActivityTracker tracks whether or not the specified input - * resource is part of the diagram model or not and modifies the canvas - * background color accordingly. If the diagram is not in an active model, an - * INACTIVE MODEL banner is also shown in the background using - * {@link TextNode}. - * - * @author Tuukka Lehtonen - */ -public class DiagramModelActivityTracker extends AbstractCanvasParticipant { - - public static final Key KEY_IN_ACTIVE_MODEL = new KeyOf(String.class, "IN_ACTIVE_MODEL"); - public static final Key KEY_ACTIVE_BACKGROUND = new KeyOf(Color.class, "ACTIVE_BACKGROUND"); - public static final Key KEY_INACTIVE_BACKGROUND = new KeyOf(Color.class, "INACTIVE_BACKGROUND"); - - private static final Color DEFAULT_ACTIVE_BACKGROUND = Color.WHITE; - private static final Color DEFAULT_INACTIVE_BACKGROUND = new Color(242, 242, 242); - - Resource input; - IsInActiveModelListener listener; - TextNode bannerNode; - - public DiagramModelActivityTracker(Resource input) { - if (input == null) - throw new NullPointerException("null input"); - this.input = input; - } - - @HintListener(Class=Hints.class, Field="KEY_CONTROL_BOUNDS") - public void controlBoundsChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { - if (bannerNode == null) - return; - if (newValue != null) { - Rectangle2D bounds = (Rectangle2D) newValue; - AffineTransform at = new AffineTransform(); - at.translate(5,5); -// at.translate(bounds.getWidth() / 2, bounds.getHeight() / 2); -// at.scale(2, 2); -// at.rotate(-Math.PI/6); -// at.translate(bounds.getWidth() - 150, bounds.getHeight() - 30); -// at.scale(1, 1); - bannerNode.setTransform(at); - } else { - // Disable rendering - bannerNode.setColor(null); - } - } - - @HintListener(Class=DiagramModelActivityTracker.class, Field="KEY_IN_ACTIVE_MODEL") - public void containingModelActivityChanged(IHintObservable sender, Key key, Object oldValue, Object _newValue) { - String newValue = (String)_newValue; - if (bannerNode == null) - return; - if (newValue == null) { - bannerNode.setText(""); - } else { - bannerNode.setText(newValue); - //bannerNode.setColor(new Color(192, 32, 32, 128)); - //bannerNode.setColor(new Color(192, 32, 32, 32)); - } - } - - @Override - public void addedToContext(ICanvasContext ctx) { - super.addedToContext(ctx); - - listener = new IsInActiveModelListener(ctx); - Simantics.getSession().async(new IsActiveDiagram(input), listener); - - if (!ctx.getHintStack().containsHint(KEY_ACTIVE_BACKGROUND)) - ctx.getDefaultHintContext().setHint(KEY_ACTIVE_BACKGROUND, DEFAULT_ACTIVE_BACKGROUND); - if (!ctx.getHintStack().containsHint(KEY_INACTIVE_BACKGROUND)) - ctx.getDefaultHintContext().setHint(KEY_INACTIVE_BACKGROUND, DEFAULT_INACTIVE_BACKGROUND); - } - - @Override - public void removedFromContext(ICanvasContext ctx) { - if (listener != null) { - listener.dispose(); - listener = null; - } - super.removedFromContext(ctx); - } - - @SGInit(designation = SGDesignation.CONTROL) - public void initSG(G2DParentNode parent) { - bannerNode = parent.addNode("inactivity-banner", TextNode.class); - bannerNode.setZIndex(Integer.MIN_VALUE / 4); - //bannerNode.setZIndex(Integer.MAX_VALUE / 4); - bannerNode.setHorizontalAlignment((byte) Alignment.LEADING.ordinal()); - bannerNode.setVerticalAlignment((byte) Alignment.LEADING.ordinal()); - //bannerNode.setText("Model is not active."); - bannerNode.setText(""); - bannerNode.setFont(Font.decode("Arial 16")); - //bannerNode.setBackgroundColor(new Color(192, 192, 192, 128)); - bannerNode.setPadding(10, 10); - bannerNode.setBorderColor(Color.GRAY); - bannerNode.setBorderWidth(0); - bannerNode.setEditable(false); - } - - @SGCleanup - public void cleanupSG() { - if (bannerNode != null) { - bannerNode.remove(); - bannerNode = null; - } - } - - static class IsActiveDiagram extends UnaryRead { - public IsActiveDiagram(Resource parameter) { - super(parameter); - } - @Override - public String perform(ReadGraph graph) throws DatabaseException { - - Resource indexRoot = graph.syncRequest( new PossibleIndexRoot(parameter) ); - if (indexRoot == null) { - return "This diagram is not part of any model or shared library"; - } - Layer0 L0 = Layer0.getInstance(graph); - StructuralResource2 STR = StructuralResource2.getInstance(graph); - ModelingResources MOD = ModelingResources.getInstance(graph); - Resource composite = graph.getPossibleObject(parameter, MOD.DiagramToComposite); - if(composite == null) - return "This diagram does not have a corresponding configuration"; - - Resource componentType = graph.getPossibleObject(composite, STR.Defines); - if(componentType != null) { - // This is a component type - boolean published = Layer0Utils.isPublished(graph, componentType); - if(published) - return "This diagram defines a published (read-only) user component"; - } - - if(graph.isInstanceOf(indexRoot, L0.SharedOntology)) { - return ""; - } - - boolean activeModel = graph.syncRequest( new IsActive(indexRoot) ); - if(!activeModel) - return "The model of this diagram is not active"; - - DiagramResource DIA = DiagramResource.getInstance(graph); - Instances query = graph.adapt(DIA.DiagramActivityCondition, Instances.class); - - for(Resource condition : query.find(graph, indexRoot)) { - String value = Simantics.tryInvokeSCL(graph, condition, DIA.DiagramActivityCondition_test, parameter); - if(value != null && !value.isEmpty()) return value; - } - - return ""; - - } - } - - static class IsInActiveModelListener implements Listener { - ICanvasContext context; - public IsInActiveModelListener(ICanvasContext context) { - this.context = context; - } - @Override - public void execute(final String result) { - final Color color = (result.isEmpty()) - ? context.getHintStack().getHint(KEY_ACTIVE_BACKGROUND) - : context.getHintStack().getHint(KEY_INACTIVE_BACKGROUND); - - context.getThreadAccess().asyncExec(new Runnable() { - @Override - public void run() { - ICanvasContext ctx = context; - if (ctx == null) - return; - if (ctx.isDisposed()) - return; - IHintContext hints = ctx.getDefaultHintContext(); - if (color != null) - hints.setHint(Hints.KEY_BACKGROUND_COLOR, color); - hints.setHint(KEY_IN_ACTIVE_MODEL, result); - } - }); - } - public void dispose() { - context = null; - } - @Override - public boolean isDisposed() { - ICanvasContext context = this.context; - return context == null || context.isDisposed(); - } - @Override - public void exception(Throwable t) { - ErrorLogger.defaultLogError(t); - } - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + *******************************************************************************/ +package org.simantics.diagram.participant; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Instances; +import org.simantics.db.layer0.request.IsActive; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.db.procedure.Listener; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.SGDesignation; +import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; +import org.simantics.g2d.canvas.impl.HintReflection.HintListener; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; +import org.simantics.g2d.utils.Alignment; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.utils.datastructures.hints.IHintContext; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.ui.ErrorLogger; + +/** + * DiagramModelActivityTracker tracks whether or not the specified input + * resource is part of the diagram model or not and modifies the canvas + * background color accordingly. If the diagram is not in an active model, an + * INACTIVE MODEL banner is also shown in the background using + * {@link TextNode}. + * + * @author Tuukka Lehtonen + */ +public class DiagramModelActivityTracker extends AbstractCanvasParticipant { + + public static final Key KEY_IN_ACTIVE_MODEL = new KeyOf(String.class, "IN_ACTIVE_MODEL"); + public static final Key KEY_ACTIVE_BACKGROUND = new KeyOf(Color.class, "ACTIVE_BACKGROUND"); + public static final Key KEY_INACTIVE_BACKGROUND = new KeyOf(Color.class, "INACTIVE_BACKGROUND"); + + private static final Color DEFAULT_ACTIVE_BACKGROUND = Color.WHITE; + private static final Color DEFAULT_INACTIVE_BACKGROUND = new Color(242, 242, 242); + + Resource input; + IsInActiveModelListener listener; + TextNode bannerNode; + + public DiagramModelActivityTracker(Resource input) { + if (input == null) + throw new NullPointerException("null input"); + this.input = input; + } + + @HintListener(Class=Hints.class, Field="KEY_CONTROL_BOUNDS") + public void controlBoundsChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + if (bannerNode == null) + return; + if (newValue != null) { + Rectangle2D bounds = (Rectangle2D) newValue; + AffineTransform at = new AffineTransform(); + at.translate(5,5); +// at.translate(bounds.getWidth() / 2, bounds.getHeight() / 2); +// at.scale(2, 2); +// at.rotate(-Math.PI/6); +// at.translate(bounds.getWidth() - 150, bounds.getHeight() - 30); +// at.scale(1, 1); + bannerNode.setTransform(at); + } else { + // Disable rendering + bannerNode.setColor(null); + } + } + + @HintListener(Class=DiagramModelActivityTracker.class, Field="KEY_IN_ACTIVE_MODEL") + public void containingModelActivityChanged(IHintObservable sender, Key key, Object oldValue, Object _newValue) { + String newValue = (String)_newValue; + if (bannerNode == null) + return; + if (newValue == null) { + bannerNode.setText(""); + } else { + bannerNode.setText(newValue); + //bannerNode.setColor(new Color(192, 32, 32, 128)); + //bannerNode.setColor(new Color(192, 32, 32, 32)); + } + } + + @Override + public void addedToContext(ICanvasContext ctx) { + super.addedToContext(ctx); + + listener = new IsInActiveModelListener(ctx); + Simantics.getSession().async(new IsActiveDiagram(input), listener); + + if (!ctx.getHintStack().containsHint(KEY_ACTIVE_BACKGROUND)) + ctx.getDefaultHintContext().setHint(KEY_ACTIVE_BACKGROUND, DEFAULT_ACTIVE_BACKGROUND); + if (!ctx.getHintStack().containsHint(KEY_INACTIVE_BACKGROUND)) + ctx.getDefaultHintContext().setHint(KEY_INACTIVE_BACKGROUND, DEFAULT_INACTIVE_BACKGROUND); + } + + @Override + public void removedFromContext(ICanvasContext ctx) { + if (listener != null) { + listener.dispose(); + listener = null; + } + super.removedFromContext(ctx); + } + + @SGInit(designation = SGDesignation.CONTROL) + public void initSG(G2DParentNode parent) { + bannerNode = parent.addNode("inactivity-banner", TextNode.class); + bannerNode.setZIndex(Integer.MIN_VALUE / 4); + //bannerNode.setZIndex(Integer.MAX_VALUE / 4); + bannerNode.setHorizontalAlignment((byte) Alignment.LEADING.ordinal()); + bannerNode.setVerticalAlignment((byte) Alignment.LEADING.ordinal()); + //bannerNode.setText("Model is not active."); + bannerNode.setText(""); + bannerNode.setFont(Font.decode("Arial 16")); + //bannerNode.setBackgroundColor(new Color(192, 192, 192, 128)); + bannerNode.setPadding(10, 10); + bannerNode.setBorderColor(Color.GRAY); + bannerNode.setBorderWidth(0); + bannerNode.setEditable(false); + } + + @SGCleanup + public void cleanupSG() { + if (bannerNode != null) { + bannerNode.remove(); + bannerNode = null; + } + } + + static class IsActiveDiagram extends UnaryRead { + public IsActiveDiagram(Resource parameter) { + super(parameter); + } + @Override + public String perform(ReadGraph graph) throws DatabaseException { + + Resource indexRoot = graph.syncRequest( new PossibleIndexRoot(parameter) ); + if (indexRoot == null) { + return "This diagram is not part of any model or shared library"; + } + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + Resource composite = graph.getPossibleObject(parameter, MOD.DiagramToComposite); + if(composite == null) + return "This diagram does not have a corresponding configuration"; + + Resource componentType = graph.getPossibleObject(composite, STR.Defines); + if(componentType != null) { + // This is a component type + boolean published = Layer0Utils.isPublished(graph, componentType); + if(published) + return "This diagram defines a published (read-only) user component"; + } + + if(graph.isInstanceOf(indexRoot, L0.SharedOntology)) { + return ""; + } + + boolean activeModel = graph.syncRequest( new IsActive(indexRoot) ); + if(!activeModel) + return "The model of this diagram is not active"; + + DiagramResource DIA = DiagramResource.getInstance(graph); + Instances query = graph.adapt(DIA.DiagramActivityCondition, Instances.class); + + for(Resource condition : query.find(graph, indexRoot)) { + String value = Simantics.tryInvokeSCL(graph, condition, DIA.DiagramActivityCondition_test, parameter); + if(value != null && !value.isEmpty()) return value; + } + + return ""; + + } + } + + static class IsInActiveModelListener implements Listener { + ICanvasContext context; + public IsInActiveModelListener(ICanvasContext context) { + this.context = context; + } + @Override + public void execute(final String result) { + final Color color = (result.isEmpty()) + ? context.getHintStack().getHint(KEY_ACTIVE_BACKGROUND) + : context.getHintStack().getHint(KEY_INACTIVE_BACKGROUND); + + context.getThreadAccess().asyncExec(new Runnable() { + @Override + public void run() { + ICanvasContext ctx = context; + if (ctx == null) + return; + if (ctx.isDisposed()) + return; + IHintContext hints = ctx.getDefaultHintContext(); + if (color != null) + hints.setHint(Hints.KEY_BACKGROUND_COLOR, color); + hints.setHint(KEY_IN_ACTIVE_MODEL, result); + } + }); + } + public void dispose() { + context = null; + } + @Override + public boolean isDisposed() { + ICanvasContext context = this.context; + return context == null || context.isDisposed(); + } + @Override + public void exception(Throwable t) { + ErrorLogger.defaultLogError(t); + } + } + +}