1  | 
     | 
     | 
    /***************************************************************  | 
    
    
    2  | 
     | 
     | 
    QGVCore  | 
    
    
    3  | 
     | 
     | 
    Copyright (c) 2014, Bergont Nicolas, All rights reserved.  | 
    
    
    4  | 
     | 
     | 
     | 
    
    
    5  | 
     | 
     | 
    This library is free software; you can redistribute it and/or  | 
    
    
    6  | 
     | 
     | 
    modify it under the terms of the GNU Lesser General Public  | 
    
    
    7  | 
     | 
     | 
    License as published by the Free Software Foundation; either  | 
    
    
    8  | 
     | 
     | 
    version 3.0 of the License, or (at your option) any later version.  | 
    
    
    9  | 
     | 
     | 
     | 
    
    
    10  | 
     | 
     | 
    This library is distributed in the hope that it will be useful,  | 
    
    
    11  | 
     | 
     | 
    but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
    
    
    12  | 
     | 
     | 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  | 
    
    
    13  | 
     | 
     | 
    Lesser General Public License for more details.  | 
    
    
    14  | 
     | 
     | 
     | 
    
    
    15  | 
     | 
     | 
    You should have received a copy of the GNU Lesser General Public  | 
    
    
    16  | 
     | 
     | 
    License along with this library.  | 
    
    
    17  | 
     | 
     | 
    ***************************************************************/  | 
    
    
    18  | 
     | 
     | 
    #include <QGVCore.h>  | 
    
    
    19  | 
     | 
     | 
    #include <QGVEdge.h>  | 
    
    
    20  | 
     | 
     | 
    #include <QGVEdgePrivate.h>  | 
    
    
    21  | 
     | 
     | 
    #include <QGVGraphPrivate.h>  | 
    
    
    22  | 
     | 
     | 
    #include <QGVScene.h>  | 
    
    
    23  | 
     | 
     | 
     | 
    
    
    24  | 
     | 
     | 
    #include <QDebug>  | 
    
    
    25  | 
     | 
     | 
    #include <QPainter>  | 
    
    
    26  | 
     | 
     | 
     | 
    
    
    27  | 
     | 
     | 
    QGVEdge::QGVEdge(QGVEdgePrivate *edge, QGVScene *scene)  | 
    
    
    28  | 
     | 
     | 
        : _scene(scene), _edge(edge) { | 
    
    
    29  | 
     | 
     | 
      setFlag(QGraphicsItem::ItemIsSelectable, true);  | 
    
    
    30  | 
     | 
     | 
    }  | 
    
    
    31  | 
     | 
     | 
     | 
    
    
    32  | 
     | 
     | 
    QGVEdge::~QGVEdge() { | 
    
    
    33  | 
     | 
     | 
      _scene->removeItem(this);  | 
    
    
    34  | 
     | 
     | 
      delete _edge;  | 
    
    
    35  | 
     | 
     | 
    }  | 
    
    
    36  | 
     | 
     | 
     | 
    
    
    37  | 
     | 
     | 
    QString QGVEdge::label() const { return getAttribute("xlabel"); } | 
    
    
    38  | 
     | 
     | 
     | 
    
    
    39  | 
     | 
     | 
    QRectF QGVEdge::boundingRect() const { | 
    
    
    40  | 
     | 
     | 
      return _path.boundingRect() | _head_arrow.boundingRect() |  | 
    
    
    41  | 
     | 
     | 
             _tail_arrow.boundingRect() | _label_rect;  | 
    
    
    42  | 
     | 
     | 
    }  | 
    
    
    43  | 
     | 
     | 
     | 
    
    
    44  | 
     | 
     | 
    QPainterPath QGVEdge::shape() const { | 
    
    
    45  | 
     | 
     | 
      QPainterPathStroker ps;  | 
    
    
    46  | 
     | 
     | 
      ps.setCapStyle(_pen.capStyle());  | 
    
    
    47  | 
     | 
     | 
      ps.setWidth(_pen.widthF() + 10);  | 
    
    
    48  | 
     | 
     | 
      ps.setJoinStyle(_pen.joinStyle());  | 
    
    
    49  | 
     | 
     | 
      ps.setMiterLimit(_pen.miterLimit());  | 
    
    
    50  | 
     | 
     | 
      return ps.createStroke(_path);  | 
    
    
    51  | 
     | 
     | 
    }  | 
    
    
    52  | 
     | 
     | 
     | 
    
    
    53  | 
     | 
     | 
    void QGVEdge::setLabel(const QString &label) { setAttribute("xlabel", label); } | 
    
    
    54  | 
     | 
     | 
     | 
    
    
    55  | 
     | 
     | 
    void QGVEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *,  | 
    
    
    56  | 
     | 
     | 
                        QWidget *) { | 
    
    
    57  | 
     | 
     | 
      painter->save();  | 
    
    
    58  | 
     | 
     | 
     | 
    
    
    59  | 
     | 
     | 
      if (isSelected()) { | 
    
    
    60  | 
     | 
     | 
        QPen tpen(_pen);  | 
    
    
    61  | 
     | 
     | 
        tpen.setColor(_pen.color().darker(120));  | 
    
    
    62  | 
     | 
     | 
        tpen.setStyle(Qt::DotLine);  | 
    
    
    63  | 
     | 
     | 
        painter->setPen(tpen);  | 
    
    
    64  | 
     | 
     | 
      } else  | 
    
    
    65  | 
     | 
     | 
        painter->setPen(_pen);  | 
    
    
    66  | 
     | 
     | 
     | 
    
    
    67  | 
     | 
     | 
      painter->drawPath(_path);  | 
    
    
    68  | 
     | 
     | 
     | 
    
    
    69  | 
     | 
     | 
      /*  | 
    
    
    70  | 
     | 
     | 
      QRectF pp = _path.controlPointRect();  | 
    
    
    71  | 
     | 
     | 
      if(pp.width() < pp.height())  | 
    
    
    72  | 
     | 
     | 
      { | 
    
    
    73  | 
     | 
     | 
          painter->save();  | 
    
    
    74  | 
     | 
     | 
          painter->translate(_label_rect.topLeft());  | 
    
    
    75  | 
     | 
     | 
          painter->rotate(90);  | 
    
    
    76  | 
     | 
     | 
          painter->drawText(QRectF(QPointF(0, -_label_rect.width()),  | 
    
    
    77  | 
     | 
     | 
      _label_rect.size()), Qt::AlignCenter, _label); painter->restore();  | 
    
    
    78  | 
     | 
     | 
      }  | 
    
    
    79  | 
     | 
     | 
      else  | 
    
    
    80  | 
     | 
     | 
      */  | 
    
    
    81  | 
     | 
     | 
      painter->drawText(_label_rect, Qt::AlignCenter, _label);  | 
    
    
    82  | 
     | 
     | 
     | 
    
    
    83  | 
     | 
     | 
      // painter->setBrush(QBrush(_pen.color(), Qt::SolidPattern));  | 
    
    
    84  | 
     | 
     | 
      painter->drawPolygon(_head_arrow);  | 
    
    
    85  | 
     | 
     | 
      painter->drawPolygon(_tail_arrow);  | 
    
    
    86  | 
     | 
     | 
      painter->restore();  | 
    
    
    87  | 
     | 
     | 
    }  | 
    
    
    88  | 
     | 
     | 
     | 
    
    
    89  | 
     | 
     | 
    void QGVEdge::setAttribute(const QString &name, const QString &value) { | 
    
    
    90  | 
     | 
     | 
      char empty[] = "";  | 
    
    
    91  | 
     | 
     | 
      agsafeset(_edge->edge(), name.toLocal8Bit().data(),  | 
    
    
    92  | 
     | 
     | 
                value.toLocal8Bit().data(), empty);  | 
    
    
    93  | 
     | 
     | 
    }  | 
    
    
    94  | 
     | 
     | 
     | 
    
    
    95  | 
     | 
     | 
    QString QGVEdge::getAttribute(const QString &name) const { | 
    
    
    96  | 
     | 
     | 
      char *value = agget(_edge->edge(), name.toLocal8Bit().data());  | 
    
    
    97  | 
     | 
     | 
      if (value) return value;  | 
    
    
    98  | 
     | 
     | 
      return QString();  | 
    
    
    99  | 
     | 
     | 
    }  | 
    
    
    100  | 
     | 
     | 
     | 
    
    
    101  | 
     | 
     | 
    void QGVEdge::updateLayout() { | 
    
    
    102  | 
     | 
     | 
      prepareGeometryChange();  | 
    
    
    103  | 
     | 
     | 
     | 
    
    
    104  | 
     | 
     | 
      qreal gheight = QGVCore::graphHeight(_scene->_graph->graph());  | 
    
    
    105  | 
     | 
     | 
     | 
    
    
    106  | 
     | 
     | 
      const splines *spl = ED_spl(_edge->edge());  | 
    
    
    107  | 
     | 
     | 
      _path = QGVCore::toPath(spl, gheight);  | 
    
    
    108  | 
     | 
     | 
     | 
    
    
    109  | 
     | 
     | 
      // Edge arrows  | 
    
    
    110  | 
     | 
     | 
      if ((spl->list != 0) && (spl->list->size % 3 == 1)) { | 
    
    
    111  | 
     | 
     | 
        if (spl->list->sflag) { | 
    
    
    112  | 
     | 
     | 
          _tail_arrow =  | 
    
    
    113  | 
     | 
     | 
              toArrow(QLineF(QGVCore::toPoint(spl->list->list[0], gheight),  | 
    
    
    114  | 
     | 
     | 
                             QGVCore::toPoint(spl->list->sp, gheight)));  | 
    
    
    115  | 
     | 
     | 
        }  | 
    
    
    116  | 
     | 
     | 
     | 
    
    
    117  | 
     | 
     | 
        if (spl->list->eflag) { | 
    
    
    118  | 
     | 
     | 
          _head_arrow = toArrow(QLineF(  | 
    
    
    119  | 
     | 
     | 
              QGVCore::toPoint(spl->list->list[spl->list->size - 1], gheight),  | 
    
    
    120  | 
     | 
     | 
              QGVCore::toPoint(spl->list->ep, gheight)));  | 
    
    
    121  | 
     | 
     | 
        }  | 
    
    
    122  | 
     | 
     | 
      }  | 
    
    
    123  | 
     | 
     | 
     | 
    
    
    124  | 
     | 
     | 
      _pen.setWidth(QGVCore::toPenWidth(getAttribute("penwidth"))); | 
    
    
    125  | 
     | 
     | 
      _pen.setColor(QGVCore::toColor(getAttribute("color"))); | 
    
    
    126  | 
     | 
     | 
      _pen.setStyle(QGVCore::toPenStyle(getAttribute("style"))); | 
    
    
    127  | 
     | 
     | 
     | 
    
    
    128  | 
     | 
     | 
      // Edge label  | 
    
    
    129  | 
     | 
     | 
      textlabel_t *xlabel = ED_xlabel(_edge->edge());  | 
    
    
    130  | 
     | 
     | 
      if (xlabel) { | 
    
    
    131  | 
     | 
     | 
        _label = xlabel->text;  | 
    
    
    132  | 
     | 
     | 
        _label_rect.setSize(QSize(xlabel->dimen.x, xlabel->dimen.y));  | 
    
    
    133  | 
     | 
     | 
        _label_rect.moveCenter(QGVCore::toPoint(  | 
    
    
    134  | 
     | 
     | 
            xlabel->pos, QGVCore::graphHeight(_scene->_graph->graph())));  | 
    
    
    135  | 
     | 
     | 
      }  | 
    
    
    136  | 
     | 
     | 
     | 
    
    
    137  | 
     | 
     | 
      setToolTip(getAttribute("tooltip")); | 
    
    
    138  | 
     | 
     | 
    }  | 
    
    
    139  | 
     | 
     | 
     | 
    
    
    140  | 
     | 
     | 
    QPolygonF QGVEdge::toArrow(const QLineF &line) const { | 
    
    
    141  | 
     | 
     | 
      QLineF n = line.normalVector();  | 
    
    
    142  | 
     | 
     | 
      QPointF o(n.dx() / 3.0, n.dy() / 3.0);  | 
    
    
    143  | 
     | 
     | 
     | 
    
    
    144  | 
     | 
     | 
      // Only support normal arrow type  | 
    
    
    145  | 
     | 
     | 
      QPolygonF polygon;  | 
    
    
    146  | 
     | 
     | 
      polygon.append(line.p1() + o);  | 
    
    
    147  | 
     | 
     | 
      polygon.append(line.p2());  | 
    
    
    148  | 
     | 
     | 
      polygon.append(line.p1() - o);  | 
    
    
    149  | 
     | 
     | 
     | 
    
    
    150  | 
     | 
     | 
      return polygon;  | 
    
    
    151  | 
     | 
     | 
    }  |