PARP Research Group University of Murcia, Spain


src/qvgui/qvdesigner/slate/link.cpp

00001 /*
00002  *      Copyright (C) 2008, 2009. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 
00022 #include <QtGui>
00023 
00024 #include "link.h"
00025 #include "node.h"
00026 
00027 Link::Link(Node *fromNode, QString fromProp, Node *toNode, QString toProp, QGraphicsItem * parent, QGraphicsScene * scene): QGraphicsLineItem(parent, scene), line2(this, scene), line3(this, scene), line4(this, scene), line5(this, scene)
00028 {
00029     myFromNode = fromNode;
00030     myToNode = toNode;
00031         myFromProp = fromProp;
00032         myToProp = toProp;
00033 
00034     myFromNode->addOutLink(this);
00035     myToNode->addInLink(this);
00036 
00037     setFlags(QGraphicsItem::ItemIsSelectable);
00038         line2.setFlags(QGraphicsItem::ItemIsSelectable);
00039         line3.setFlags(QGraphicsItem::ItemIsSelectable);
00040         line4.setFlags(QGraphicsItem::ItemIsSelectable);
00041         line5.setFlags(QGraphicsItem::ItemIsSelectable);
00042 
00043         setHandlesChildEvents(true);
00044 
00045     trackNodes();
00046 }
00047 
00048 Link::~Link()
00049 {
00050     myFromNode->removeLink(this);
00051     myToNode->removeLink(this);
00052 }
00053 
00054 void Link::changeFromPoint(Node *newNode, QString NewProp)
00055 {
00056         myFromNode->removeLink(this);
00057         myFromNode = newNode;
00058         myFromProp = NewProp;
00059     myFromNode->addOutLink(this);
00060 
00061     trackNodes();
00062 }
00063 
00064 void Link::changeToPoint(Node *newNode, QString NewProp)
00065 {
00066         myToNode->removeLink(this);
00067         myToNode = newNode;
00068         myToProp = NewProp;
00069     myToNode->addInLink(this);
00070 
00071     trackNodes();
00072 }
00073 
00074 Node *Link::fromNode() const
00075 {
00076     return myFromNode;
00077 }
00078 
00079 Node *Link::toNode() const
00080 {
00081     return myToNode;
00082 }
00083 
00084 QString Link::fromProp() const
00085 {
00086         return myFromProp;
00087 }
00088 
00089 QString Link::toProp() const
00090 {
00091         return myToProp;
00092 }
00093 
00094 void Link::setColor(const QColor &color)
00095 {
00096     setPen(QPen(color, 1.0));
00097 }
00098 
00099 QColor Link::color() const
00100 {
00101     return pen().color();
00102 }
00103 
00104 
00105 void Link::trackNodes()
00106 {
00107         // actualiza el zValue al máximo de los dos, o al del mayor grupo al que pertenecen
00108         // reducimos el tamaño del Pen del link en función del número de antecesores (*0.5 por cada uno)
00109         //(solo se mira para uno pq no se permiten enlaces entre grupos)
00110         double zvalue = (myFromNode->zValue() > myToNode->zValue()) ? myFromNode->zValue() + 1 : myToNode->zValue() + 1;
00111 
00112         // obtenemos el pen
00113         QGraphicsItem *ancestor = myFromNode->parentItem();
00114         QPen myPen = pen();
00115     while (ancestor) {
00116                 setZValue(ancestor->zValue() + 1);
00117                 myPen.setWidthF(myPen.width() * 0.4);
00118                 ancestor = ancestor->parentItem();
00119         }
00120 
00121         // obtenemos las posiciones origen y destino
00122         QPointF orig = myFromNode->scenePointPos(myFromProp, FALSE);
00123         QPointF dest = myToNode->scenePointPos(myToProp, TRUE);
00124 
00125         if (orig.x() <= dest.x()) {
00126                 setZValue(zvalue);
00127                 setPen(myPen);
00128                 setLine(QLineF(orig, dest));
00129                 line2.hide();
00130                 line3.hide();
00131                 line4.hide();
00132                 line5.hide();
00133         }
00134         else {
00135                 // obtenemos el desplazamiento lateral para esta propiedad dentro de sus nodos (para que no se solapen verticalmente)
00136                 double origDesp = 10.0 * (fromNode()->numProps() - fromNode()->propPoint(fromProp(), true) + 1);
00137                 double destDesp = 10.0 * (toNode()->numProps() - toNode()->propPoint(toProp(), true) + 1);
00138 
00139                 // obtenemos la coordenada Y de las partes inferior
00140                 double origBottom = /*fromNode()->scenePos().y() +*/ fromNode()->sceneBoundingRect().bottom() + origDesp;
00141                 double destBottom = /*toNode()->scenePos().y() +*/ toNode()->sceneBoundingRect().bottom() + destDesp;
00142                 double bottom = origBottom > destBottom ? origBottom : destBottom;
00143 
00144                 setZValue(zvalue);
00145                 line2.setZValue(zvalue);
00146                 line3.setZValue(zvalue);
00147                 line4.setZValue(zvalue);
00148                 line5.setZValue(zvalue);
00149                 setPen(myPen);
00150                 line2.setPen(myPen);
00151                 line3.setPen(myPen);
00152                 line4.setPen(myPen);
00153                 line5.setPen(myPen);
00154                 setLine(QLineF(orig, orig + QPointF(origDesp, 0.0)));
00155                 line2.setLine(QLineF(orig + QPointF(origDesp, 0.0), QPointF(orig.x() + origDesp, bottom)));
00156                 line3.setLine(QLineF(QPointF(orig.x() + origDesp, bottom), QPointF(dest.x() - destDesp, bottom)));
00157                 line4.setLine(QLineF(QPointF(dest.x() - destDesp, bottom), dest + QPointF(0.0 - destDesp, 0.0)));
00158                 line5.setLine(QLineF(dest + QPointF(0.0 - destDesp, 0.0), dest));
00159                 line2.show();
00160                 line3.show();
00161                 line4.show();
00162                 line5.show();
00163         }
00164 }
00165 
00166 bool Link::sceneEvent(QEvent *)
00167 {
00168         setSelected(true);
00169         line2.setSelected(true);
00170         line3.setSelected(true);
00171         line4.setSelected(true);
00172         line5.setSelected(true);
00173 
00174         return true;
00175 }
00176 
00177 



QVision framework. PARP research group, copyright 2007, 2008.