// Copyright (C) 2008 Lukas Lalinsky // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include #include "databasetable.h" #include "databaserelation.h" DatabaseRelation::DatabaseRelation(QGraphicsItem *parent) : DatabaseModelItem(parent), m_source(0), m_target(0) { setFlag(ItemIsSelectable); } QRectF DatabaseRelation::boundingRect() const { return shape().boundingRect(); //return QRectF(m_line.p1(), m_line.p2()).normalized(); } QPainterPath DatabaseRelation::shape() const { QPainterPath path; path.moveTo(m_line.p1()); path.lineTo(m_line.p2()); path.addPolygon(m_arrowHead); QPen pen(QPen(QColor(0, 0, 0), 1)); pen.setJoinStyle(Qt::MiterJoin); QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); ps.setWidth(pen.widthF() + 0.3); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); return ps.createStroke(path); } void DatabaseRelation::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); QPen pen(QPen(QColor(0, 0, 0), 1)); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); painter->drawLine(m_line); painter->setBrush(pen.color()); painter->drawPolygon(m_arrowHead); } void DatabaseRelation::setSource(DatabaseTable *source) { m_source = source; if (scene()) { updateLayout(); } } void DatabaseRelation::setTarget(DatabaseTable *target) { m_target = target; if (scene()) { updateLayout(); } } QVariant DatabaseRelation::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemSceneHasChanged) { updateLayout(); } return QGraphicsItem::itemChange(change, value); } void DatabaseRelation::updatePositions() { updateLayout(); } void DatabaseRelation::updateLayout() { if (!scene()) return; prepareGeometryChange(); QRectF rect1 = m_source->boundingRect().translated(m_source->pos()); QRectF rect2 = m_target->boundingRect().translated(m_target->pos()); QPointF p1 = rect1.center(); QPointF p2 = rect2.center(); m_line = QLineF(p1, p2); QPolygonF polygon; polygon = rect1; for (int i = 0; i < 4; i++) { QLineF line(polygon[i], polygon[(i+1)%4]); QPointF intersectionPoint; if (m_line.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { m_line.setP1(intersectionPoint); break; } } polygon = rect2; for (int i = 0; i < 4; i++) { QLineF line(polygon[i], polygon[(i+1)%4]); QPointF intersectionPoint; if (m_line.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { m_line.setP2(intersectionPoint); break; } } m_arrowHead.resize(3); m_arrowHead[0] = QPointF(0.0, 0.0); m_arrowHead[1] = QPointF(-4.5, 10.0); m_arrowHead[2] = QPointF(4.5, 10.0); QMatrix matrix; matrix.rotate(-m_line.angle() + 90); m_arrowHead = matrix.map(m_arrowHead); m_arrowHead.translate(m_line.p2()); }