-/*******************************************************************************\r
- * Copyright (c) 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.diagram.synchronization.runtime;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Set;\r
-import java.util.concurrent.atomic.AtomicReference;\r
-\r
-import org.simantics.diagram.ui.DiagramModelHints;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.DataElementMap;\r
-import org.simantics.g2d.diagram.participant.Selection;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintObservable;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class DiagramSelectionUpdater extends HintListenerAdapter {\r
-\r
- private static final boolean DEBUG_SELECTION_UPDATE = false;\r
-\r
- private final ICanvasContext ctx;\r
- private final Selection selection;\r
- private final IDiagram diagram;\r
-\r
- private int selectionId;\r
- private AtomicReference<Set<?>> newSelection = new AtomicReference<Set<?>>();\r
-\r
- private boolean oneshot = false;\r
- private boolean tracking = false;\r
-\r
- public DiagramSelectionUpdater(ICanvasContext ctx) {\r
- this.ctx = ctx;\r
- this.selection = ctx.getAtMostOneItemOfClass(Selection.class);\r
- if (selection == null)\r
- throw new IllegalArgumentException("no selection participant");\r
- this.diagram = ctx.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM);\r
- if (diagram == null)\r
- throw new IllegalArgumentException("no diagram");\r
- }\r
-\r
- public DiagramSelectionUpdater(ICanvasContext ctx, IDiagram diagram) {\r
- this.ctx = ctx;\r
- this.selection = ctx.getAtMostOneItemOfClass(Selection.class);\r
- if (selection == null)\r
- throw new IllegalArgumentException("no selection participant");\r
- this.diagram = diagram;\r
- if (diagram == null)\r
- throw new IllegalArgumentException("no diagram");\r
- }\r
-\r
- protected Selection getSelectionParticipant() {\r
- return ctx.getSingleItem(Selection.class);\r
- }\r
-\r
- public DiagramSelectionUpdater setNewSelection(int selectionId, Set<?> newSelection) {\r
- this.selectionId = selectionId;\r
- this.newSelection.set(newSelection);\r
- return this;\r
- }\r
-\r
- public Set<?> getNewSelection() {\r
- return newSelection.get();\r
- }\r
-\r
- public DiagramSelectionUpdater setOneshot(boolean oneshot) {\r
- this.oneshot = oneshot;\r
- return this;\r
- }\r
-\r
- public DiagramSelectionUpdater track() {\r
- if (!tracking) {\r
- diagram.addKeyHintListener(DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED, this);\r
- tracking = true;\r
- }\r
- return this;\r
- }\r
-\r
- public DiagramSelectionUpdater untrack() {\r
- if (tracking) {\r
- diagram.removeKeyHintListener(DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED, this);\r
- tracking = false;\r
- }\r
- return this;\r
- }\r
-\r
- @Override\r
- public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
- if (!ctx.isDisposed() && key == DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED) {\r
- if (DEBUG_SELECTION_UPDATE)\r
- System.out.println(getClass().getSimpleName() + ": DIAGRAM UPDATED @" + System.currentTimeMillis() + ", selection to set: " + newSelection);\r
- Set<?> ns = newSelection.getAndSet(null);\r
- if (ns != null) {\r
- scheduleSetDiagramSelection(2, ns);\r
- }\r
- }\r
-\r
- if (oneshot) {\r
- // Remove self from listening duties.\r
- sender.removeHintListener(this);\r
- }\r
- }\r
-\r
- private void scheduleSetDiagramSelection(final int tries, final Set<?> data) {\r
- ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {\r
- @Override\r
- public void run() {\r
- setDiagramSelectionToData(tries, data);\r
- }\r
- });\r
- }\r
-\r
- private void setDiagramSelectionToData(final int tries, final Set<?> data) {\r
- if (DEBUG_SELECTION_UPDATE)\r
- System.out.println("setDiagramSelectionToData(" + tries + ", " + data + ")");\r
-\r
- DataElementMap dem = diagram.getDiagramClass().getAtMostOneItemOfClass(DataElementMap.class);\r
- if (dem != null) {\r
- final Collection<IElement> newSelection = new ArrayList<IElement>(data.size());\r
- for (Object datum : data) {\r
- IElement element = dem.getElement(diagram, datum);\r
- if (DEBUG_SELECTION_UPDATE)\r
- System.out.println(" DATUM " + datum + " -> " + element);\r
- if (element != null) {\r
- newSelection.add(element);\r
- } else {\r
- if (tries > 0) {\r
- // Try later if there are tries left.\r
- ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {\r
- @Override\r
- public void run() {\r
- setDiagramSelectionToData(tries - 1, data);\r
- }\r
- });\r
- return;\r
- }\r
- // Otherwise select whatever is found.\r
- }\r
- }\r
-\r
- if (DEBUG_SELECTION_UPDATE)\r
- System.out.println("[" + tries + "] final new selection: " + newSelection);\r
-\r
- if (!newSelection.isEmpty()) {\r
- //for (IElement e : newSelection)\r
- // e.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY);\r
- selection.setSelection(selectionId, newSelection);\r
- }\r
- }\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2011 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.synchronization.runtime;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.DataElementMap;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.element.IElement;
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.threads.ThreadUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class DiagramSelectionUpdater extends HintListenerAdapter {
+
+ private static final boolean DEBUG_SELECTION_UPDATE = false;
+
+ private final ICanvasContext ctx;
+ private final Selection selection;
+ private final IDiagram diagram;
+
+ private int selectionId;
+ private AtomicReference<Set<?>> newSelection = new AtomicReference<Set<?>>();
+
+ private boolean oneshot = false;
+ private boolean tracking = false;
+
+ public DiagramSelectionUpdater(ICanvasContext ctx) {
+ this.ctx = ctx;
+ this.selection = ctx.getAtMostOneItemOfClass(Selection.class);
+ if (selection == null)
+ throw new IllegalArgumentException("no selection participant");
+ this.diagram = ctx.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM);
+ if (diagram == null)
+ throw new IllegalArgumentException("no diagram");
+ }
+
+ public DiagramSelectionUpdater(ICanvasContext ctx, IDiagram diagram) {
+ this.ctx = ctx;
+ this.selection = ctx.getAtMostOneItemOfClass(Selection.class);
+ if (selection == null)
+ throw new IllegalArgumentException("no selection participant");
+ this.diagram = diagram;
+ if (diagram == null)
+ throw new IllegalArgumentException("no diagram");
+ }
+
+ protected Selection getSelectionParticipant() {
+ return ctx.getSingleItem(Selection.class);
+ }
+
+ public DiagramSelectionUpdater setNewSelection(int selectionId, Set<?> newSelection) {
+ this.selectionId = selectionId;
+ this.newSelection.set(newSelection);
+ return this;
+ }
+
+ public Set<?> getNewSelection() {
+ return newSelection.get();
+ }
+
+ public DiagramSelectionUpdater setOneshot(boolean oneshot) {
+ this.oneshot = oneshot;
+ return this;
+ }
+
+ public DiagramSelectionUpdater track() {
+ if (!tracking) {
+ diagram.addKeyHintListener(DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED, this);
+ tracking = true;
+ }
+ return this;
+ }
+
+ public DiagramSelectionUpdater untrack() {
+ if (tracking) {
+ diagram.removeKeyHintListener(DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED, this);
+ tracking = false;
+ }
+ return this;
+ }
+
+ @Override
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ if (!ctx.isDisposed() && key == DiagramModelHints.KEY_DIAGRAM_CONTENTS_UPDATED) {
+ if (DEBUG_SELECTION_UPDATE)
+ System.out.println(getClass().getSimpleName() + ": DIAGRAM UPDATED @" + System.currentTimeMillis() + ", selection to set: " + newSelection);
+ Set<?> ns = newSelection.getAndSet(null);
+ if (ns != null) {
+ scheduleSetDiagramSelection(2, ns);
+ }
+ }
+
+ if (oneshot) {
+ // Remove self from listening duties.
+ sender.removeHintListener(this);
+ }
+ }
+
+ private void scheduleSetDiagramSelection(final int tries, final Set<?> data) {
+ ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
+ @Override
+ public void run() {
+ setDiagramSelectionToData(tries, data);
+ }
+ });
+ }
+
+ private void setDiagramSelectionToData(final int tries, final Set<?> data) {
+ if (DEBUG_SELECTION_UPDATE)
+ System.out.println("setDiagramSelectionToData(" + tries + ", " + data + ")");
+
+ DataElementMap dem = diagram.getDiagramClass().getAtMostOneItemOfClass(DataElementMap.class);
+ if (dem != null) {
+ final Collection<IElement> newSelection = new ArrayList<IElement>(data.size());
+ for (Object datum : data) {
+ IElement element = dem.getElement(diagram, datum);
+ if (DEBUG_SELECTION_UPDATE)
+ System.out.println(" DATUM " + datum + " -> " + element);
+ if (element != null) {
+ newSelection.add(element);
+ } else {
+ if (tries > 0) {
+ // Try later if there are tries left.
+ ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
+ @Override
+ public void run() {
+ setDiagramSelectionToData(tries - 1, data);
+ }
+ });
+ return;
+ }
+ // Otherwise select whatever is found.
+ }
+ }
+
+ if (DEBUG_SELECTION_UPDATE)
+ System.out.println("[" + tries + "] final new selection: " + newSelection);
+
+ if (!newSelection.isEmpty()) {
+ //for (IElement e : newSelection)
+ // e.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY);
+ selection.setSelection(selectionId, newSelection);
+ }
+ }
+ }
+
+}