X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fimpl%2FAbstractDiagram.java;h=76b1496bdc064d108a955e3ab62f2e32ed96ef73;hp=7e2bcd98a4b337689d6ad82c3f0d98345f849778;hb=refs%2Fchanges%2F38%2F238%2F2;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/impl/AbstractDiagram.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/impl/AbstractDiagram.java index 7e2bcd98a..76b1496bd 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/impl/AbstractDiagram.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/impl/AbstractDiagram.java @@ -1,456 +1,456 @@ -/******************************************************************************* - * 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.g2d.diagram.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.simantics.g2d.diagram.DiagramClass; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.diagram.handler.DiagramAdapter; -import org.simantics.g2d.diagram.handler.ElementListener; -import org.simantics.g2d.diagram.handler.LifeCycle; -import org.simantics.g2d.element.IElement; -import org.simantics.utils.datastructures.ListenerList; -import org.simantics.utils.datastructures.hints.IHintContext; -import org.simantics.utils.datastructures.hints.IHintListener; -import org.simantics.utils.threads.IThreadWorkQueue; - -/** - * @author Toni Kalajainen - */ -public class AbstractDiagram implements IDiagram { - - ListenerList compositionVetoListeners; - ListenerList compositionListeners; - - Set elements = new HashSet(); - ArrayList list = new ArrayList(); - List unmodifiableList = Collections.unmodifiableList(list); - volatile List snapshot = null; - DiagramClass clazz; - IHintContext hintCtx; - - public AbstractDiagram(DiagramClass clazz, IHintContext hintCtx) - { - if (clazz == null) - throw new NullPointerException("null clazz"); - this.clazz = clazz; - this.hintCtx = hintCtx; - } - - public void destroy() - { - List ss = getElements(); - - dispose(); - - // Fire destroy elements - for (IElement e : ss) - e.destroy(); - - // Fire destroy diagram - for (org.simantics.g2d.diagram.handler.LifeCycle lc : clazz.getItemsByClass(org.simantics.g2d.diagram.handler.LifeCycle.class)) - lc.onDiagramDestroyed(this); - } - - public void dispose() - { - List ss = getElements(); - // Fire deactiavate elements - for (IElement e : ss) - for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) - lc.onElementDeactivated(this, e); - - // Fire deactivate diagram - fireDeactivated(); - - // Dispose all elements to ensure their hints are freed up. - for (IElement e : ss) { - e.addedToDiagram(null); - e.dispose(); - } - - elements.clear(); - list.clear(); - snapshot = null; - - hintCtx.clearWithoutNotification(); - } - - public DiagramClass getDiagramClass() - { - return clazz; - } - - public synchronized void addCompositionListener(CompositionListener listener) { - if (compositionListeners ==null) - compositionListeners = new ListenerList(CompositionListener.class); - compositionListeners.add(listener); - } - public synchronized void removeCompositionListener(CompositionListener listener) { - if (compositionListeners == null) - return; - compositionListeners.remove(listener); - if (compositionListeners.isEmpty()) - compositionListeners = null; - } - - public synchronized void addCompositionVetoListener(CompositionVetoListener listener) { - if (compositionVetoListeners ==null) - compositionVetoListeners = new ListenerList(CompositionVetoListener.class); - compositionVetoListeners.add(listener); - } - public synchronized void removeCompositionVetoListener(CompositionVetoListener listener) { - if (compositionVetoListeners == null) - return; - compositionVetoListeners.remove(listener); - if (compositionVetoListeners.isEmpty()) - compositionVetoListeners = null; - } - - /** - * Adds a new element. The element will not be initialized - * @param clazz element class - * @return element of class - */ - public synchronized void addElement(IElement e) { - assert(clazz!=null); - - // Give the possibility for listeners to veto an element addition - if (!fireBeforeElementAdded(e)) { - System.out.println("Element addition VETOED for " + e); - return; - } - - snapshot = null; - elements.add(e); - list.add(e); - - e.addedToDiagram(this); - - for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) - lc.onElementActivated(this, e); - - for (ElementListener el : clazz.getItemsByClass(ElementListener.class)) - el.onElementAdded(this, e); - - fireElementAdded(e); - } - - protected void assertHasElement(IElement e) - { - assert(elements.contains(e)); - } - - @Override - public boolean containsElement(IElement element) { - return elements.contains(element); - } - - /** - * Remove element from the diagram - * @param element element to remove - */ - public synchronized void removeElement(IElement e) { - -// new Exception(e.toString()).printStackTrace(); - - // Give the possibility for listeners to veto an element removal. - if (!fireBeforeElementRemoved(e)) { - System.out.println("Element removal VETOED for " + e); - return; - } - - //System.out.println("[" + this + "] removed element " + e + ""); - - boolean removed = elements.remove(e); - assert(removed); - list.remove(e); - snapshot = null; - - e.addedToDiagram(null); - - for (ElementListener el : clazz.getItemsByClass(ElementListener.class)) - el.onElementRemoved(this, e); - - for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) - lc.onElementDeactivated(this, e); - - fireElementRemoved(e); - } - - /** - * @param e the element to be added - * @return true if the addition was allowed by all listeners or - * false if the addition was vetoed - */ - protected boolean fireBeforeElementAdded(IElement e) { - if (compositionVetoListeners==null) return true; - for (CompositionVetoListener l : compositionVetoListeners.getListeners()) - if (!l.beforeElementAdded(this, e)) - return false; - return true; - } - - /** - * @param e the element to be removed - * @return true if the removal was allowed by all listeners or - * false if the removal was vetoed - */ - protected boolean fireBeforeElementRemoved(IElement e) { - if (compositionVetoListeners==null) return true; - for (CompositionVetoListener l : compositionVetoListeners.getListeners()) - if (!l.beforeElementRemoved(this, e)) - return false; - return true; - } - protected void fireElementAdded(IElement e) { - if (compositionListeners==null) return; - for (CompositionListener l : compositionListeners.getListeners()) - l.onElementAdded(this, e); - } - protected void fireElementRemoved(IElement e) { - if (compositionListeners==null) return; - for (CompositionListener l : compositionListeners.getListeners()) - l.onElementRemoved(this, e); - } - - @Override - public List getSnapshot() { - List snap = snapshot; - if (snap != null) - return snap; - synchronized (this) { - snap = snapshot; - if (snap == null) - snapshot = snap = Collections.unmodifiableList( new ArrayList(list) ); - } - return snap; - } - - protected static void fireDestroyed(IDiagram e) - { - for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) - lc.onDiagramDestroyed(e); - } - - protected static void fireDeactivated(IDiagram e) - { - for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) - lc.onDiagramDisposed(e); - } - - protected static void fireCreated(IDiagram e) - { - for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) - lc.onDiagramCreated(e); - } - - protected static void fireLoaded(IDiagram e) - { - for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) - lc.onDiagramLoaded(e, e.getElements()); - } - - protected void fireCreated() - { - fireCreated(this); - } - - protected void fireLoaded() - { - fireLoaded(this); - } - - protected void fireDestroyed() - { - fireDestroyed(this); - } - - protected void fireDeactivated() - { - fireDeactivated(this); - } - - @Override - public void clearWithoutNotification() { - hintCtx.clearWithoutNotification(); - } - - @Override - public E removeHint(Key key) { - return hintCtx.removeHint(key); - } - - @Override - public void setHint(Key key, Object value) { - hintCtx.setHint(key, value); - } - - @Override - public void setHints(Map hints) { - hintCtx.setHints(hints); - } - - @Override - public void addHintListener(IHintListener listener) { - hintCtx.addHintListener(listener); - } - - @Override - public void addHintListener(IThreadWorkQueue threadAccess, - IHintListener listener) { - hintCtx.addHintListener(threadAccess, listener); - } - - @Override - public void addKeyHintListener(Key key, IHintListener listener) { - hintCtx.addKeyHintListener(key, listener); - } - - @Override - public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, - IHintListener listener) { - hintCtx.addKeyHintListener(threadAccess, key, listener); - } - - @Override - public boolean containsHint(Key key) { - return hintCtx.containsHint(key); - } - - @Override - public E getHint(Key key) { - return hintCtx.getHint(key); - } - - @Override - public Map getHints() { - return hintCtx.getHints(); - } - - @Override - public Map getHintsUnsafe() { - return hintCtx.getHintsUnsafe(); - } - - @Override - public Map getHintsOfClass(Class clazz) { - return hintCtx.getHintsOfClass(clazz); - } - - @Override - public void removeHintListener(IHintListener listener) { - hintCtx.removeHintListener(listener); - } - - @Override - public void removeHintListener(IThreadWorkQueue threadAccess, - IHintListener listener) { - hintCtx.removeHintListener(threadAccess, listener); - } - - @Override - public void removeKeyHintListener(Key key, IHintListener listener) { - hintCtx.removeKeyHintListener(key, listener); - } - - @Override - public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, - IHintListener listener) { - hintCtx.removeKeyHintListener(threadAccess, key, listener); - } - - @Override - public boolean bringToTop(IElement e) { - assertHasElement(e); - if (list.get(list.size()-1)==e) return false; - list.add( e ); - list.remove( e ); - snapshot = null; - return true; - } - - @Override - public boolean bringUp(IElement e) { - assertHasElement(e); - int i = list.indexOf(e); - if (i==list.size()-1) return false; - int j = i+1; - IElement upper = list.get(j); - list.set(j, e); - list.set(i, upper); - snapshot = null; - return true; - } - - @Override - public boolean sendDown(IElement e) { - assertHasElement(e); - int i = list.indexOf(e); - if (i==0) return false; - int j = i-1; - IElement lower = list.get(j); - list.set(j, e); - list.set(i, lower); - snapshot = null; - return true; - } - - @Override - public boolean sendToBottom(IElement e) { - assertHasElement(e); - if (list.get(0)==e) return false; - list.remove(e); - list.add(0, e); - snapshot = null; - return true; - } - - @Override - public boolean moveTo(IElement e, int position) { - assertHasElement(e); - int indexOf = list.indexOf(e); - if (indexOf==position) return false; - list.remove(indexOf); - list.add(position, e); - snapshot = null; - return true; - } - - @Override - public List getElements() { - return unmodifiableList; - } - - @Override - public void sort(Comparator comparator) { - Collections.sort(list, comparator); - } - - @SuppressWarnings("rawtypes") - public Object getAdapter(Class adapter) { - for (DiagramAdapter ea : clazz.getItemsByClass(DiagramAdapter.class)) { - Object result = ea.getAdapter(this, adapter); - if (result != null) - return result; - } - return null; - } - -} +/******************************************************************************* + * 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.g2d.diagram.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.simantics.g2d.diagram.DiagramClass; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.DiagramAdapter; +import org.simantics.g2d.diagram.handler.ElementListener; +import org.simantics.g2d.diagram.handler.LifeCycle; +import org.simantics.g2d.element.IElement; +import org.simantics.utils.datastructures.ListenerList; +import org.simantics.utils.datastructures.hints.IHintContext; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.threads.IThreadWorkQueue; + +/** + * @author Toni Kalajainen + */ +public class AbstractDiagram implements IDiagram { + + ListenerList compositionVetoListeners; + ListenerList compositionListeners; + + Set elements = new HashSet(); + ArrayList list = new ArrayList(); + List unmodifiableList = Collections.unmodifiableList(list); + volatile List snapshot = null; + DiagramClass clazz; + IHintContext hintCtx; + + public AbstractDiagram(DiagramClass clazz, IHintContext hintCtx) + { + if (clazz == null) + throw new NullPointerException("null clazz"); + this.clazz = clazz; + this.hintCtx = hintCtx; + } + + public void destroy() + { + List ss = getElements(); + + dispose(); + + // Fire destroy elements + for (IElement e : ss) + e.destroy(); + + // Fire destroy diagram + for (org.simantics.g2d.diagram.handler.LifeCycle lc : clazz.getItemsByClass(org.simantics.g2d.diagram.handler.LifeCycle.class)) + lc.onDiagramDestroyed(this); + } + + public void dispose() + { + List ss = getElements(); + // Fire deactiavate elements + for (IElement e : ss) + for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) + lc.onElementDeactivated(this, e); + + // Fire deactivate diagram + fireDeactivated(); + + // Dispose all elements to ensure their hints are freed up. + for (IElement e : ss) { + e.addedToDiagram(null); + e.dispose(); + } + + elements.clear(); + list.clear(); + snapshot = null; + + hintCtx.clearWithoutNotification(); + } + + public DiagramClass getDiagramClass() + { + return clazz; + } + + public synchronized void addCompositionListener(CompositionListener listener) { + if (compositionListeners ==null) + compositionListeners = new ListenerList(CompositionListener.class); + compositionListeners.add(listener); + } + public synchronized void removeCompositionListener(CompositionListener listener) { + if (compositionListeners == null) + return; + compositionListeners.remove(listener); + if (compositionListeners.isEmpty()) + compositionListeners = null; + } + + public synchronized void addCompositionVetoListener(CompositionVetoListener listener) { + if (compositionVetoListeners ==null) + compositionVetoListeners = new ListenerList(CompositionVetoListener.class); + compositionVetoListeners.add(listener); + } + public synchronized void removeCompositionVetoListener(CompositionVetoListener listener) { + if (compositionVetoListeners == null) + return; + compositionVetoListeners.remove(listener); + if (compositionVetoListeners.isEmpty()) + compositionVetoListeners = null; + } + + /** + * Adds a new element. The element will not be initialized + * @param clazz element class + * @return element of class + */ + public synchronized void addElement(IElement e) { + assert(clazz!=null); + + // Give the possibility for listeners to veto an element addition + if (!fireBeforeElementAdded(e)) { + System.out.println("Element addition VETOED for " + e); + return; + } + + snapshot = null; + elements.add(e); + list.add(e); + + e.addedToDiagram(this); + + for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) + lc.onElementActivated(this, e); + + for (ElementListener el : clazz.getItemsByClass(ElementListener.class)) + el.onElementAdded(this, e); + + fireElementAdded(e); + } + + protected void assertHasElement(IElement e) + { + assert(elements.contains(e)); + } + + @Override + public boolean containsElement(IElement element) { + return elements.contains(element); + } + + /** + * Remove element from the diagram + * @param element element to remove + */ + public synchronized void removeElement(IElement e) { + +// new Exception(e.toString()).printStackTrace(); + + // Give the possibility for listeners to veto an element removal. + if (!fireBeforeElementRemoved(e)) { + System.out.println("Element removal VETOED for " + e); + return; + } + + //System.out.println("[" + this + "] removed element " + e + ""); + + boolean removed = elements.remove(e); + assert(removed); + list.remove(e); + snapshot = null; + + e.addedToDiagram(null); + + for (ElementListener el : clazz.getItemsByClass(ElementListener.class)) + el.onElementRemoved(this, e); + + for (org.simantics.g2d.element.handler.LifeCycle lc : e.getElementClass().getItemsByClass(org.simantics.g2d.element.handler.LifeCycle.class)) + lc.onElementDeactivated(this, e); + + fireElementRemoved(e); + } + + /** + * @param e the element to be added + * @return true if the addition was allowed by all listeners or + * false if the addition was vetoed + */ + protected boolean fireBeforeElementAdded(IElement e) { + if (compositionVetoListeners==null) return true; + for (CompositionVetoListener l : compositionVetoListeners.getListeners()) + if (!l.beforeElementAdded(this, e)) + return false; + return true; + } + + /** + * @param e the element to be removed + * @return true if the removal was allowed by all listeners or + * false if the removal was vetoed + */ + protected boolean fireBeforeElementRemoved(IElement e) { + if (compositionVetoListeners==null) return true; + for (CompositionVetoListener l : compositionVetoListeners.getListeners()) + if (!l.beforeElementRemoved(this, e)) + return false; + return true; + } + protected void fireElementAdded(IElement e) { + if (compositionListeners==null) return; + for (CompositionListener l : compositionListeners.getListeners()) + l.onElementAdded(this, e); + } + protected void fireElementRemoved(IElement e) { + if (compositionListeners==null) return; + for (CompositionListener l : compositionListeners.getListeners()) + l.onElementRemoved(this, e); + } + + @Override + public List getSnapshot() { + List snap = snapshot; + if (snap != null) + return snap; + synchronized (this) { + snap = snapshot; + if (snap == null) + snapshot = snap = Collections.unmodifiableList( new ArrayList(list) ); + } + return snap; + } + + protected static void fireDestroyed(IDiagram e) + { + for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) + lc.onDiagramDestroyed(e); + } + + protected static void fireDeactivated(IDiagram e) + { + for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) + lc.onDiagramDisposed(e); + } + + protected static void fireCreated(IDiagram e) + { + for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) + lc.onDiagramCreated(e); + } + + protected static void fireLoaded(IDiagram e) + { + for (LifeCycle lc : e.getDiagramClass().getItemsByClass(LifeCycle.class)) + lc.onDiagramLoaded(e, e.getElements()); + } + + protected void fireCreated() + { + fireCreated(this); + } + + protected void fireLoaded() + { + fireLoaded(this); + } + + protected void fireDestroyed() + { + fireDestroyed(this); + } + + protected void fireDeactivated() + { + fireDeactivated(this); + } + + @Override + public void clearWithoutNotification() { + hintCtx.clearWithoutNotification(); + } + + @Override + public E removeHint(Key key) { + return hintCtx.removeHint(key); + } + + @Override + public void setHint(Key key, Object value) { + hintCtx.setHint(key, value); + } + + @Override + public void setHints(Map hints) { + hintCtx.setHints(hints); + } + + @Override + public void addHintListener(IHintListener listener) { + hintCtx.addHintListener(listener); + } + + @Override + public void addHintListener(IThreadWorkQueue threadAccess, + IHintListener listener) { + hintCtx.addHintListener(threadAccess, listener); + } + + @Override + public void addKeyHintListener(Key key, IHintListener listener) { + hintCtx.addKeyHintListener(key, listener); + } + + @Override + public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, + IHintListener listener) { + hintCtx.addKeyHintListener(threadAccess, key, listener); + } + + @Override + public boolean containsHint(Key key) { + return hintCtx.containsHint(key); + } + + @Override + public E getHint(Key key) { + return hintCtx.getHint(key); + } + + @Override + public Map getHints() { + return hintCtx.getHints(); + } + + @Override + public Map getHintsUnsafe() { + return hintCtx.getHintsUnsafe(); + } + + @Override + public Map getHintsOfClass(Class clazz) { + return hintCtx.getHintsOfClass(clazz); + } + + @Override + public void removeHintListener(IHintListener listener) { + hintCtx.removeHintListener(listener); + } + + @Override + public void removeHintListener(IThreadWorkQueue threadAccess, + IHintListener listener) { + hintCtx.removeHintListener(threadAccess, listener); + } + + @Override + public void removeKeyHintListener(Key key, IHintListener listener) { + hintCtx.removeKeyHintListener(key, listener); + } + + @Override + public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, + IHintListener listener) { + hintCtx.removeKeyHintListener(threadAccess, key, listener); + } + + @Override + public boolean bringToTop(IElement e) { + assertHasElement(e); + if (list.get(list.size()-1)==e) return false; + list.add( e ); + list.remove( e ); + snapshot = null; + return true; + } + + @Override + public boolean bringUp(IElement e) { + assertHasElement(e); + int i = list.indexOf(e); + if (i==list.size()-1) return false; + int j = i+1; + IElement upper = list.get(j); + list.set(j, e); + list.set(i, upper); + snapshot = null; + return true; + } + + @Override + public boolean sendDown(IElement e) { + assertHasElement(e); + int i = list.indexOf(e); + if (i==0) return false; + int j = i-1; + IElement lower = list.get(j); + list.set(j, e); + list.set(i, lower); + snapshot = null; + return true; + } + + @Override + public boolean sendToBottom(IElement e) { + assertHasElement(e); + if (list.get(0)==e) return false; + list.remove(e); + list.add(0, e); + snapshot = null; + return true; + } + + @Override + public boolean moveTo(IElement e, int position) { + assertHasElement(e); + int indexOf = list.indexOf(e); + if (indexOf==position) return false; + list.remove(indexOf); + list.add(position, e); + snapshot = null; + return true; + } + + @Override + public List getElements() { + return unmodifiableList; + } + + @Override + public void sort(Comparator comparator) { + Collections.sort(list, comparator); + } + + @SuppressWarnings("rawtypes") + public Object getAdapter(Class adapter) { + for (DiagramAdapter ea : clazz.getItemsByClass(DiagramAdapter.class)) { + Object result = ea.getAdapter(this, adapter); + if (result != null) + return result; + } + return null; + } + +}