package agg.editor.impl;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Vector;
import agg.attribute.view.AttrViewSetting;
import agg.gui.editor.EditorConstants;
import agg.gui.editor.GraphPanel;
import agg.xt_basis.GraphObject;
/**
* An EdGraphObject specifies the common layout interface and implementations
* for nodes and arcs. This abstract class is the superclass of EdNode and
* EdArc.
*
* @author $Author: olga $
* @version $Id: EdGraphObject.java,v 1.35 2010/11/13 02:25:16 olga Exp $
*/
public abstract class EdGraphObject {
// public final static int CRITICAL_GREEN = 0;
// public final static int CRITICAL_BLACK_BOLD = 1;
protected int criticalStyle = 0;
protected Integer itsUndoReprDataHC;
protected EdType eType;
protected EdGraph eGraph;
protected int x;
protected int y;
protected int w;
protected int h;
double itsScale = 1.0;
// contextUsage is used for undo and stores its hashcode(s)
// as string like this - ":hashcode:hashcode:hashcode:"
// it used from NodeReprData and ArcReprDate to store/restore node, edge
// DO NOT REWRITE THIS!
protected String contextUsage = "";
protected boolean hasDefaultLayout;
protected boolean elemOfTG; // is element of a TypeGraph
/**
* true, if the graph object has (type) errors. if true the object will be
* marked.
*/
protected boolean errorMode;
protected boolean visible = true;
protected boolean attrVisible = true;
protected Color backgroundColor = null; //Color.white;
protected int myKey = 0;
transient protected final Vector<String> marks;
transient protected EdGraphObject myCopy;
transient protected boolean selected, weakselected;
transient protected boolean moved;
transient protected GraphPanel myGraphPanel;
transient protected boolean attrObserver;
transient protected boolean attrChanged;
protected AttrViewSetting view;
transient protected boolean init;
/** Creates a layout specified by the EdType eType */
public EdGraphObject(EdType eType) {
this.contextUsage = "";
this.x = 0;
this.y = 0;
this.eType = eType;
// if (this.eType != null) {
// this.eType.addUser(this);
// }
this.marks = new Vector<String>();
}
public abstract void dispose();
public EdGraph getContext() {
return this.eGraph;
}
public void setContext(EdGraph g) {
this.eGraph = g;
}
/** Returns the used object */
public abstract GraphObject getBasisObject();
/** Returns TRUE if the used object is a node */
public abstract boolean isNode();
/** Returns TRUE if the used object is a n arc */
public abstract boolean isArc();
/** Returns the parent object */
public abstract EdNode getNode();
/** Returns the parent object */
public abstract EdArc getArc();
public abstract void setCritical(boolean b);
public abstract void setDrawingStyleOfCriticalObject(int criticalStyle);
public abstract boolean isCritical();
/** Returns the attributes */
public abstract Vector<Vector<String>> getAttributes();
public abstract void refreshAttributeInstance();
public abstract void removeFromAttributeViewObserver();
/** Sets a graph panel */
public abstract void setGraphPanel(GraphPanel gp);
/** Sets the attributes */
public abstract Vector<Vector<String>> setAttributes(GraphObject obj);
public abstract void drawGraphic(Graphics grs);
/** Returns TRUE if this is attribute observer */
public boolean isAttrObserver() {
return this.attrObserver;
}
/** Sets this to attribute observer */
public void setAttrObserver(boolean obs) {
this.attrObserver = obs;
this.init = true;
}
/** Returns my copy */
public EdGraphObject getCopy() {
return this.myCopy;
}
/** Returns my X position */
public int getX() {
return this.x;
}
/** Returns my Y position */
public int getY() {
return this.y;
}
/** Returns my width */
public int getWidth() {
return this.w;
}
/** Returns my height */
public int getHeight() {
return this.h;
}
/** Returns my layout type */
public EdType getType() {
return this.eType;
}
/** Returns the name of my layout type */
public String getTypeName() {
return this.eType.getTypeName();
}
/** Returns my key used by the morphism marking */
public int getMyKey() {
return this.myKey;
}
/** Returns my morphism mark */
public String getMorphismMark() {
StringBuffer markBuf = new StringBuffer();
for (int i = 0; i < this.marks.size(); i++) {
if (i > 0)
markBuf.append(',');
markBuf.append(this.marks.elementAt(i));
}
return markBuf.toString();
}
/** Returns the text height */
public int getTextHeight(FontMetrics fm) {
Vector<Vector<String>> attrs = getAttributes();
int nn = 0;
int h1 = 0;
// die Hoehe einer Zeile
if (fm == null)
h1 = 17; // default
else
h1 = fm.getHeight();
if ((fm != null && fm.getFont().getSize() < 8)
|| !this.attrVisible)
return h1;
if (attrs != null) {
nn = attrs.size();
for (int i = 0; i < attrs.size(); i++) {
Vector<String> attr = attrs.elementAt(i);
if (!this.elemOfTG && (attr.elementAt(2).length() == 0))
nn--;
else if (this.elemOfTG && (attr.elementAt(1) == null))
nn--;
}
}
// die Hoehe aller Attribute
int hght = h1 * nn;
// gesamte Hoehe
// if((getTypeString().length() != 0) || (isNode() && this.elemOfTG))
hght = hght + h1;
return hght;
}
/** Returns the text width */
public int getTextWidth(FontMetrics fm) {
int nn = 6; // default char width
String typeStr = "";
typeStr = getTypeString();
if (isNode()) {
if (getType().getBasisType().isAbstract()) {
if (!typeStr.equals(""))
typeStr = "{" + typeStr + "}";
else
typeStr = "{ }";
}
if (this.elemOfTG)
typeStr = typeStr + " " + ((EdNode) this).getMultiplicityString();
}
int wdth = 0;
if (fm == null)
wdth = nn * typeStr.length();
else
wdth = fm.stringWidth(typeStr);
if ((fm != null && fm.getFont().getSize() < 8)
|| !this.attrVisible)
return wdth;
Vector<Vector<String>> attrs = getAttributes();
if (attrs != null) {
for (int i = 0; i < attrs.size(); i++) {
Vector<String> attr = attrs.elementAt(i);
if (this.elemOfTG) {
if (attr.elementAt(1) != null) {
String tstStr = attr.elementAt(0) + " " + attr.elementAt(1);
// Type graph: default attr value
if (attr.elementAt(2).length() != 0) {
tstStr = tstStr + "=" + attr.elementAt(2);
}
if (fm == null) {
if ((nn * tstStr.length()) > wdth)
wdth = nn * tstStr.length();
} else if (fm.stringWidth(tstStr) > wdth)
wdth = fm.stringWidth(tstStr);
}
}
else if (attr.elementAt(2).length() != 0) {
String tstStr = attr.elementAt(1) + "=" + attr.elementAt(2);
if (fm == null) {
if ((nn * tstStr.length()) > wdth)
wdth = nn * tstStr.length();
} else if (fm.stringWidth(tstStr) > wdth)
wdth = fm.stringWidth(tstStr);
}
}
}
return wdth;
}
/** Returns the type name with mapping mark if it exists. */
protected String getTypeString() {
String typeStr = this.eType.getBasisType().getStringRepr();
if (!this.getBasisObject().getObjectName().equals("")) {
typeStr = this.getBasisObject().getObjectName().concat(":").concat(typeStr);
}
if (getMorphismMark().length() != 0) {
typeStr = getMorphismMark().concat(":").concat(typeStr);
}
return typeStr;
}
/** Returns my shape */
public int getShape() {
return this.eType.shape;
}
/** Returns my color */
public Color getColor() {
return this.eType.color;
}
/** Returns the color used by selecting */
public Color getSelectColor() {
return EditorConstants.selectColor;
}
/** Returns TRUE if i am selected */
public boolean isSelected() {
return this.selected;
}
/** Returns TRUE if i'm visible */
public boolean isVisible() {
return this.visible;
}
/** Returns TRUE if my attribute is visible */
public boolean isAttributeVisible() {
return this.visible;
}
/** Returns TRUE if i am an element of a type graph */
public boolean isElementOfTypeGraph() {
return this.elemOfTG;
}
/**
* Returns TRUE if my type is the same as the type specified by the
* EdGraphObject eObj
*/
public boolean hasSimilarType(EdGraphObject eObj) {
if (this.eType.isParentOf(eObj.getType()))
return true;
return false;
}
/**
* Returns TRUE if the point specified by the int X, int Y is inside of
* myself
*/
public abstract boolean inside(int X, int Y);
/**
* Returns the dimension of the overlapping from another layout specified by
* the EdGraphObject eObj
*/
public Dimension ifOverlapFrom(EdGraphObject eObj) {
Point p1 = new Point(this.x - this.w / 2, this.y - this.h / 2);
Point p2 = new Point(this.x + this.w / 2, this.y - this.h / 2);
Point p3 = new Point(this.x + this.w / 2, this.y + this.h / 2);
Point p4 = new Point(this.x - this.w / 2, this.y + this.h / 2);
Point p11 = new Point(eObj.getX() - eObj.getWidth() / 2, eObj.getY()
- eObj.getHeight() / 2);
Point p12 = new Point(eObj.getX() + eObj.getWidth() / 2, eObj.getY()
- eObj.getHeight() / 2);
Point p13 = new Point(eObj.getX() + eObj.getWidth() / 2, eObj.getY()
+ eObj.getHeight() / 2);
Point p14 = new Point(eObj.getX() - eObj.getWidth() / 2, eObj.getY()
+ eObj.getHeight() / 2);
int minDist = 10;
Dimension overlapSize = new Dimension(
((p3.x + eObj.getWidth() / 2 + minDist) - this.x), ((p3.y
+ eObj.getHeight() / 2 + minDist) - this.y));
boolean overlap = false;
if (p1.equals(p11) && p2.equals(p12) && p3.equals(p13)
&& p4.equals(p14)) {
overlap = true;
} else if (inside(eObj.getX(), eObj.getY()) || inside(p11.x, p11.y)
|| inside(p12.x, p12.y) || inside(p13.x, p13.y)
|| inside(p14.x, p14.y) || eObj.inside(getX(), getY())
|| eObj.inside(p1.x, p1.y) || eObj.inside(p2.x, p2.y)
|| eObj.inside(p3.x, p3.y) || eObj.inside(p4.x, p4.y)) {
overlap = true;
}
if (overlap) {
return overlapSize;
}
return new Dimension(0, 0);
}
/** Marks this as element of a type graph */
public void markElementOfTypeGraph(boolean val) {
this.elemOfTG = val;
}
/** Sets x, y positions */
public void setXY(int X, int Y) {
this.x = X;
this.y = Y;
}
/** Sets x positions */
public void setX(int X) {
this.x = X;
}
/** Sets y positions */
public void setY(int Y) {
this.y = Y;
}
/** Sets the width */
public void setWidth(int W) {
this.w = W;
}
/** Sets the height */
public void setHeight(int H) {
this.h = H;
}
/** Selects/deselects this object */
public void setSelected(boolean sel) {
if (!this.selected && sel) {
this.selected = true;
} else {
this.selected = false;
}
this.weakselected = false;
}
/** Selects this object */
public void select() {
this.selected = true;
}
/** Deselects this object */
public void deselect() {
this.selected = false;
}
/** Selects/deselects this object as weak selected (using gray color)*/
public void setWeakselected(boolean weaksel) {
this.weakselected = weaksel;
}
public boolean isWeakselected() {
return this.weakselected;
}
public void setBackground(Color c) {
this.backgroundColor = c;
}
/** Sets my layout type to the EdType t */
public void setType(EdType t) {
this.eType = t;
}
/** Sets my key to int m */
public void setMorphismMark(int m) {
this.myKey = m;
}
/**
* Adds the morphism mark specified by the int m to my morphism mark
*/
public void addMorphismMark(int m) {
this.marks.addElement(String.valueOf(m));
}
/**
* Adds the morphism mark specified by the String m to my morphism mark
*/
public void addMorphismMark(String m) {
this.marks.addElement(m);
}
/** Returns TRUE if my morphism mark is empty */
public boolean isMorphismMarkEmpty() {
if (this.marks.isEmpty())
return true;
return false;
}
/* Makes my morphism mark empty */
public void clearMorphismMark() {
this.marks.clear();
}
protected void setContextUsage(String context) {
this.contextUsage = context;
}
protected void addContextUsage(String context) {
this.contextUsage = this.contextUsage.concat(":");
this.contextUsage = this.contextUsage.concat(context);
}
protected String getContextUsage() {
return this.contextUsage;
}
/** Sets my visibility to value specified by the boolean vis */
public void setVisible(boolean vis) {
this.visible = vis;
}
/** Sets visibility of my attribute to value specified by the boolean vis */
public void setAttributeVisible(boolean vis) {
this.attrVisible = vis;
}
/** Sets my copy to the object specified by the EdGraphObject ec */
public void setCopy(EdGraphObject ec) {
this.myCopy = ec;
}
/** Sets my attribute view to the view specified by the AttrViewSetting aView */
public void setAttrViewSetting(AttrViewSetting aView) {
this.view = aView;
this.init = true;
}
/** Returns an open view of my attribute */
protected AttrViewSetting getView() {
return this.view;
}
/**
* sets if the current graph object has an error or not. If called with
* true, the object will be marked in the display and unmarked, if called
* with false as parameter.
*
* @author Joerg <komm>
*/
public void setErrorMode(boolean errorMode) {
this.errorMode = errorMode;
}// setErrorMode
}
// $Log: EdGraphObject.java,v $
// Revision 1.35 2010/11/13 02:25:16 olga
// tuning
//
// Revision 1.34 2010/08/25 00:33:06 olga
// tuning
//
// Revision 1.33 2010/03/08 15:40:02 olga
// code optimizing
//
// Revision 1.32 2010/02/22 15:07:57 olga
// code optimizing
//
// Revision 1.31 2009/10/14 07:52:53 olga
// GUI bug fixed
//
// Revision 1.30 2009/06/30 09:50:18 olga
// agg.xt_basis.GraphObject: added: setObjectName(String), getObjectName()
// agg.xt_basis.Node, Arc: changed: save, load the object name
// agg.editor.impl.EdGraphObject: changed: String getTypeString() - contains object name if set
//
// workaround of Applicability of Rule Sequences and Object Flow
//
// Revision 1.29 2009/03/25 15:19:14 olga
// code tuning
//
// Revision 1.28 2008/10/29 09:04:04 olga
// new sub packages of the package agg.gui: typeeditor, editor, trafo, cpa, options, treeview, popupmenu, saveload
//
// Revision 1.27 2008/09/04 07:48:42 olga
// GUI extension: hide nodes, edges
//
// Revision 1.26 2008/07/21 10:03:28 olga
// Code tuning
//
// Revision 1.25 2008/07/17 15:51:50 olga
// GraphEditor - graph scaling tuning
//
// Revision 1.24 2008/07/14 07:35:47 olga
// Applicability of RS - new option added, more tuning
// Node animation - new animation parameter added,
// Undo edit manager - possibility to disable it when graph transformation
// because it costs much more time and memory
//
// Revision 1.23 2008/07/02 17:14:36 olga
// Code tuning
//
// Revision 1.22 2008/04/21 09:32:19 olga
// Visualization of inheritance edge - bugs fixed
// Graph layout tuning
//
// Revision 1.21 2008/04/17 10:11:07 olga
// Undo, redo edit and graph layout tuning,
//
// Revision 1.20 2008/04/07 09:36:49 olga
// Code tuning: refactoring + profiling
// Extension: CPA - two new options added
//
// Revision 1.19 2008/01/23 15:03:18 olga
// Tuning of usability of the gragra editor.
//
// Revision 1.18 2007/12/05 08:57:00 olga
// Delete a conclusion of an Atomic graph constraint : bug fixed
// Graph visualization update after the marking "Abstract" of a type node in the type graph : bug fixed
// CPA : some bug fixed; code tuning
//
// Revision 1.17 2007/12/03 08:35:12 olga
// - Some bugs fixed in visualization of morphism mappings after deleting and creating
// nodes, edges
// - implemented: matching with non-injective NAC and Match morphism
//
// Revision 1.16 2007/11/19 08:48:38 olga
// Some GUI usability mistakes fixed.
// Default values in node/edge of a type graph implemented.
// Code tuning.
//
// Revision 1.15 2007/11/01 09:58:11 olga
// Code refactoring: generic types- done
//
// Revision 1.14 2007/10/11 08:05:04 olga
// Enumeration typing
//
// Revision 1.13 2007/09/24 09:42:33 olga
// AGG transformation engine tuning
//
// Revision 1.12 2007/09/10 13:05:15 olga
// In this update:
// - package xerces2.5.0 is not used anymore;
// - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair;
// - bugs fixed in: usage of PACs in rules; match completion;
// usage of static method calls in attr. conditions
// - graph editing: added some new features
//
// Revision 1.11 2007/04/19 07:52:32 olga
// Tuning of: Undo/Redo, Graph layouter, loading grammars
//
// Revision 1.10 2007/04/11 10:03:32 olga
// Undo, Redo tuning,
// Simple Parser- bug fixed
//
// Revision 1.9 2007/03/28 10:00:22 olga
// - extensive changes of Node/Edge Type Editor,
// - first Undo implementation for graphs and Node/edge Type editing and
// transformation,
// - new / reimplemented options for layered transformation, for graph layouter
// - enable / disable for NACs, attr conditions, formula
// - GUI tuning
//
// Revision 1.8 2007/01/22 08:28:28 olga
// GUI bugs fixed
//
// Revision 1.7 2006/11/01 11:17:29 olga
// Optimized agg sources of CSP algorithm, match usability,
// graph isomorphic copy,
// node/edge type multiplicity check for injective rule and match
//
// Revision 1.6 2006/08/02 09:00:57 olga
// Preliminary version 1.5.0 with
// - multiple node type inheritance,
// - new implemented evolutionary graph layouter for
// graph transformation sequences
//
// Revision 1.5 2006/04/06 09:28:53 olga
// Tuning of Import Type Graph and Import Graph
//
// Revision 1.4 2006/03/01 09:55:46 olga
// - new CPA algorithm, new CPA GUI
//
// Revision 1.3 2005/12/21 14:49:20 olga
// GUI tuning
//
// Revision 1.2 2005/09/19 09:12:14 olga
// CPA GUI tuning
//
// Revision 1.1 2005/08/25 11:56:56 enrico
// *** empty log message ***
//
// Revision 1.3 2005/07/11 09:30:20 olga
// This is test version AGG V1.2.8alfa .
// What is new:
// - saving rule option <disabled>
// - setting trigger rule for layer
// - display attr. conditions in gragra tree view
// - CPA algorithm <dependencies>
// - creating and display CPA graph with conflicts and/or dependencies
// based on (.cpx) file
//
// Revision 1.2 2005/06/20 13:37:04 olga
// Up to now the version 1.2.8 will be prepared.
//
// Revision 1.1 2005/05/30 12:58:01 olga
// Version with Eclipse
//
// Revision 1.14 2005/01/28 14:02:32 olga
// -Fehlerbehandlung beim Typgraph check
// -Erweiterung CP GUI / CP Menu
// -Fehlerbehandlung mit identification option
// -Fehlerbehandlung bei Rule PAC
//
// Revision 1.13 2004/11/15 11:24:45 olga
// Neue Optionen fuer Transformation;
// verbesserter default Graphlayout;
// Close GraGra mit Abfrage wenn was geaendert wurde statt Delete GraGra
//
// Revision 1.12 2004/06/14 12:34:19 olga
// CP Analyse and Transformation
//
// Revision 1.11 2003/12/18 16:26:23 olga
// Copy method and Layout
//
// Revision 1.10 2003/04/10 09:05:24 olga
// Aenderungen wegen serializable Ausgabe
//
// Revision 1.9 2003/04/10 08:50:33 olga
// Tests mit serializable Ausgabe
//
// Revision 1.8 2003/03/05 18:24:24 komm
// sorted/optimized import statements
//
// Revision 1.7 2002/11/25 15:03:51 olga
// Arbeit an den Typen.
//
// Revision 1.6 2002/11/14 14:29:39 olga
// Anzeige von Multiplicity -- ein Versuch.
//
// Revision 1.5 2002/09/30 10:08:10 komm
// insert TypeException and type error marks
//
// Revision 1.4 2002/09/30 10:02:29 olga
// Layout
//
// Revision 1.3 2002/09/23 12:24:06 komm
// added type graph in xt_basis, editor and GUI
//
// Revision 1.2 2002/09/19 16:21:23 olga
// Layout von Knoten geaendert.
//
// Revision 1.1.1.1 2002/07/11 12:17:07 olga
// Imported sources
//
// Revision 1.15 2001/05/14 12:00:41 olga
// Graph Layout und Graphobject Layout optimiert.
//
// Revision 1.14 2001/03/08 10:53:20 olga
// Das ist Stand nach der AGG GUI Reimplementierung.
//
// Revision 1.13 2000/12/21 09:48:52 olga
// In dieser Version wurden XML und GUI Reimplementierung zusammen gefuehrt.
//
// Revision 1.12.6.2 2000/11/09 17:54:41 olga
// Fehlerbeseitigt im TypeEditor und bei den Kanten.
//
// Revision 1.12.6.1 2000/11/06 09:32:32 olga
// Erste Version fuer neue GUI (Branch reimpl)
//
// Revision 1.12 2000/06/07 09:54:20 olga
// Der Layoutvergleich wurde erweitert durch Color Vergleich.
//
// Revision 1.11 1999/09/23 14:04:29 olga
// *** empty log message ***
//
// Revision 1.10 1999/09/23 14:00:39 olga
// Aenderung betreff.AttrTopEditor.
// AttrViewSetting view nicht mehr transient.
//
// Revision 1.9 1999/09/16 13:56:57 olga
// *** empty log message ***
//
// Revision 1.8 1999/09/15 15:59:34 olga
// *** empty log message ***
//
// Revision 1.7 1999/09/15 12:52:32 olga
// *** empty log message ***
//
// Revision 1.6 1999/09/06 13:59:47 shultzke
// Editoren sind statisch samt serialVersionUID
//