diff options
author | Lukáš Lalinský <lalinsky@gmail.com> | 2008-12-30 10:26:14 +0100 |
---|---|---|
committer | Lukáš Lalinský <lalinsky@gmail.com> | 2008-12-30 10:26:14 +0100 |
commit | 033bf7a0b5baa26af94ad006f6576d04c8609e9e (patch) | |
tree | 499e36f09515f2bc3f23cf09e2364666888002bb | |
parent | 3a95c3cd621e3904d717b591aaa9f2c89959981e (diff) | |
download | dbmodel-033bf7a0b5baa26af94ad006f6576d04c8609e9e.tar.gz dbmodel-033bf7a0b5baa26af94ad006f6576d04c8609e9e.tar.bz2 |
Implement orthogonal line drawing
-rw-r--r-- | src/boxsidehub.cpp | 140 | ||||
-rw-r--r-- | src/boxsidehub.h | 29 | ||||
-rw-r--r-- | src/commands.cpp | 3 | ||||
-rw-r--r-- | src/connector.cpp | 99 | ||||
-rw-r--r-- | src/connector.h | 52 | ||||
-rw-r--r-- | src/diagramconnection.cpp | 28 | ||||
-rw-r--r-- | src/diagramconnection.h | 13 | ||||
-rw-r--r-- | src/diagramdocument.cpp | 19 | ||||
-rw-r--r-- | src/diagramitem.cpp | 12 | ||||
-rw-r--r-- | src/diagramitem.h | 11 | ||||
-rw-r--r-- | src/diagramobject.cpp | 14 | ||||
-rw-r--r-- | src/diagramobject.h | 11 | ||||
-rw-r--r-- | src/hub.cpp | 52 | ||||
-rw-r--r-- | src/hub.h | 42 | ||||
-rw-r--r-- | src/items/database/column.h | 3 | ||||
-rw-r--r-- | src/items/database/databasecommands.cpp | 4 | ||||
-rw-r--r-- | src/items/database/databaserelationship.cpp | 95 | ||||
-rw-r--r-- | src/items/database/databaserelationship.h | 8 | ||||
-rw-r--r-- | src/items/database/databasetable.cpp | 2 | ||||
-rw-r--r-- | src/src.pri | 8 |
20 files changed, 524 insertions, 121 deletions
diff --git a/src/boxsidehub.cpp b/src/boxsidehub.cpp new file mode 100644 index 0000000..e0c0692 --- /dev/null +++ b/src/boxsidehub.cpp @@ -0,0 +1,140 @@ +// 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 <QDebug> +#include <QGraphicsItem> +#include <QPair> +#include "connector.h" +#include "diagramobject.h" +#include "diagramconnection.h" +#include "boxsidehub.h" + +BoxSideHub::BoxSideHub(DiagramObject *owner) + : Hub(owner) +{ +} + +enum Side { + Top, + Right, + Bottom, + Left +}; + +static int +cmpAngle(qreal a, qreal b) +{ + qreal d = a - b; + if (d > 180) + d = d - 360; + else if (d < -180) + d = d + 360; + return d; +} + +typedef QPair<Connector *, qreal> ConnectorRealPair; + +static bool +itemLessThan(const ConnectorRealPair &a, const ConnectorRealPair &b) +{ + int r = cmpAngle(a.second, b.second); + if (r == 0) { + return a.first->owner() < b.first->owner(); + } + return r < 0; +} + +// | +// 180-cA | cA +// _____________________ +// | +// 180+cA | 360-cA +// | + +void +BoxSideHub::update() +{ + QHash<Side, QList<ConnectorRealPair> > sides; + DiagramObject *item = owner(); + QRectF rect = item->boundingRect().translated(item->pos()); + qDebug() << this; + foreach (Connector *connector, connectors()) { + DiagramConnection *connection = connector->owner(); + Connector *connector1 = connection->connector(0); + Connector *connector2 = connection->connector(1); + DiagramObject *item1, *item2; + if (connector1 == connector) { + item1 = item; + item2 = connector2->connectedObject(); + } + else { + item1 = item; + item2 = connector1->connectedObject(); + } + QRectF rect1 = rect; + QRectF rect2 = item2->boundingRect().translated(item2->pos()); + qreal angle = QLineF(rect1.center(), rect2.center()).angle(); + qreal cornerAngle = QLineF(rect1.center(), rect1.topRight()).angle(); + Side side = Right; + if (angle > cornerAngle) { + if (angle <= 180 - cornerAngle) { + side = Top; + } + else if (angle <= 180 + cornerAngle) { + side = Left; + } + else if (angle <= 360 - cornerAngle) { + side = Bottom; + } + } + qDebug() << angle << cornerAngle << side; + sides[side].append(qMakePair(connector, angle)); + } + qDebug() << sides; + foreach (Side side, sides.keys()) { + QPointF p, dp; + QList<ConnectorRealPair> c = sides[side]; + qSort(c.begin(), c.end(), itemLessThan); + qreal angle; + switch (side) { + case Top: + p = rect.topLeft(); + dp = QPointF(rect.width() / (c.size() + 1), 0); + angle = 90; + break; + case Right: + p = rect.topRight(); + dp = QPointF(0, rect.height() / (c.size() + 1)); + angle = 0; + break; + case Bottom: + p = rect.bottomLeft(); + dp = QPointF(rect.width() / (c.size() + 1), 0); + angle = 270; + break; + case Left: + p = rect.topLeft(); + dp = QPointF(0, rect.height() / (c.size() + 1)); + angle = 180; + break; + } + foreach (ConnectorRealPair item, c) { + p += dp; + item.first->setPos(p); + item.first->setAngle(angle); + } + } +} diff --git a/src/boxsidehub.h b/src/boxsidehub.h new file mode 100644 index 0000000..a20e80e --- /dev/null +++ b/src/boxsidehub.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef BOXSIDEHUB_H +#define BOXSIDEHUB_H + +#include "hub.h" + +class BoxSideHub : public Hub +{ +public: + BoxSideHub(DiagramObject *owner); + virtual void update(); +}; + +#endif diff --git a/src/commands.cpp b/src/commands.cpp index 1ff3def..4d6a5bb 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -155,7 +155,8 @@ void RemoveObjectCommand::undo() { m_document->addItem(m_object); - foreach (DiagramConnection *connection, m_connections) + foreach (DiagramConnection *connection, m_connections) { m_document->addItem(connection); + } m_owner = false; } diff --git a/src/connector.cpp b/src/connector.cpp new file mode 100644 index 0000000..6395546 --- /dev/null +++ b/src/connector.cpp @@ -0,0 +1,99 @@ +// 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 "connector.h" +#include "hub.h" +#include "diagramconnection.h" + +Connector::Connector(DiagramConnection *owner) + : m_owner(owner), m_hub(NULL) +{ +} + +DiagramConnection * +Connector::owner() const +{ + return m_owner; +} + +QPointF +Connector::pos() const +{ + return m_pos; +} + +void +Connector::setPos(const QPointF &pos) +{ + if (m_pos != pos) { + m_pos = pos; + } +} + +qreal +Connector::angle() const +{ + return m_angle; +} + +void +Connector::setAngle(qreal angle) +{ + if (m_angle != angle) { + m_angle = angle; + } +} + +Hub * +Connector::hub() const +{ + return m_hub; +} + +void +Connector::setHub(Hub *hub) +{ + if (hub) + hub->removeConnector(this); + m_hub = hub; + m_hub->addConnector(this); +} + +bool +Connector::isConnected() const +{ + return m_hub; +} + +DiagramObject * +Connector::connectedObject() const +{ + if (isConnected()) + return hub()->owner(); + return NULL; +} + +Connector * +Connector::otherEnd() const +{ + DiagramConnection *conn = owner(); + if (conn->connector(0) == this) { + return conn->connector(1); + } + else { + return conn->connector(0); + } +} diff --git a/src/connector.h b/src/connector.h new file mode 100644 index 0000000..f1b6b74 --- /dev/null +++ b/src/connector.h @@ -0,0 +1,52 @@ +// 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. + +#ifndef CONNECTOR_H +#define CONNECTOR_H + +#include <QPointF> +class DiagramConnection; +class DiagramObject; +class Hub; + +class Connector +{ +public: + Connector(DiagramConnection *owner); + DiagramConnection *owner() const; + + QPointF pos() const; + void setPos(const QPointF &pos); + + qreal angle() const; + void setAngle(qreal angle); + + bool isConnected() const; + DiagramObject *connectedObject() const; + + Connector *otherEnd() const; + + Hub *hub() const; + void setHub(Hub *hub); + +private: + QPointF m_pos; + qreal m_angle; + DiagramConnection *m_owner; + Hub *m_hub; +}; + +#endif diff --git a/src/diagramconnection.cpp b/src/diagramconnection.cpp index 545f9bf..1c8d73b 100644 --- a/src/diagramconnection.cpp +++ b/src/diagramconnection.cpp @@ -17,27 +17,21 @@ #include "diagramconnection.h" #include "diagramdocument.h" #include "diagramobject.h" +#include "connector.h" DiagramConnection::DiagramConnection(DiagramItem *parent) : DiagramItem(parent) { + m_connectors[0] = new Connector(this); + m_connectors[1] = new Connector(this); setZValue(1.0); - m_objects[0] = 0; - m_objects[1] = 0; } -void -DiagramConnection::setSource(DiagramObject *object) -{ - m_objects[0] = object; - emit endPointChanged(); -} - -void -DiagramConnection::setTarget(DiagramObject *object) +Connector * +DiagramConnection::connector(int index) const { - m_objects[1] = object; - emit endPointChanged(); + Q_ASSERT(index == 0 || index == 1); + return m_connectors[index]; } void @@ -56,8 +50,8 @@ DiagramConnection::loadFromXml(QDomElement element, DiagramDocument *document) QString sourceId = readStringElement(connectionElement, "source"); QString targetId = readStringElement(connectionElement, "target"); if (document) { - setSource(qobject_cast<DiagramObject *>(document->itemById(sourceId))); - setTarget(qobject_cast<DiagramObject *>(document->itemById(targetId))); +/* setSource(qobject_cast<DiagramObject *>(document->itemById(sourceId))); + setTarget(qobject_cast<DiagramObject *>(document->itemById(targetId)));*/ } } } @@ -68,8 +62,8 @@ DiagramConnection::saveToXml(QDomDocument doc, QDomElement element) DiagramItem::saveToXml(doc, element); QDomElement connectionElement = doc.createElement("connection"); element.appendChild(connectionElement); - if (m_objects[0] != NULL) +/* if (m_objects[0] != NULL) appendStringElement(doc, connectionElement, "source", m_objects[0]->id()); if (m_objects[1] != NULL) - appendStringElement(doc, connectionElement, "target", m_objects[1]->id()); + appendStringElement(doc, connectionElement, "target", m_objects[1]->id());*/ } diff --git a/src/diagramconnection.h b/src/diagramconnection.h index 8dcc721..66ad706 100644 --- a/src/diagramconnection.h +++ b/src/diagramconnection.h @@ -18,6 +18,7 @@ #define DIAGRAMCONNECTION_H #include "diagramitem.h" +class Connector; class DiagramObject; class DiagramConnection : public DiagramItem @@ -27,11 +28,13 @@ class DiagramConnection : public DiagramItem public: DiagramConnection(DiagramItem *parent = 0); - DiagramObject *source() const { return m_objects[0]; } - DiagramObject *target() const { return m_objects[1]; } + enum LineLayout + { + StraightLineLayout, + OrthogonalLineLayout + }; - void setSource(DiagramObject *object); - void setTarget(DiagramObject *object); + Connector *connector(int index) const; virtual void updatePositions(); @@ -42,7 +45,7 @@ signals: void endPointChanged(); private: - DiagramObject *m_objects[2]; + Connector *m_connectors[2]; }; #endif diff --git a/src/diagramdocument.cpp b/src/diagramdocument.cpp index e5caf13..ea73abe 100644 --- a/src/diagramdocument.cpp +++ b/src/diagramdocument.cpp @@ -15,6 +15,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include <cmath> +#include "hub.h" #include "diagramdocument.h" #include "diagramobject.h" #include "diagramconnection.h" @@ -140,8 +141,16 @@ DiagramDocument::setMode(Mode mode) void DiagramDocument::updatePositions(DiagramObject *object) { - foreach (DiagramConnection *connection, findConnections(object)) + Connector *connector; + foreach (DiagramConnection *connection, findConnections(object)) { + connector = connection->connector(0); + if (connector->isConnected()) + connector->hub()->update(); + connector = connection->connector(1); + if (connector->isConnected()) + connector->hub()->update(); connection->updatePositions(); + } } template <class T> QList<T *> @@ -243,8 +252,10 @@ DiagramDocument::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (source && target && source != target) { DatabaseRelationship *relation = new DatabaseRelationship(); relation->createId(); - relation->setSource(source); - relation->setTarget(target); + relation->connector(0)->setHub(source->hub()); + relation->connector(1)->setHub(target->hub()); + source->hub()->update(); + target->hub()->update(); undoStack()->push(new AddItemCommand(this, relation)); } delete m_line; @@ -288,7 +299,7 @@ DiagramDocument::findConnections(DiagramObject *object) { QList<DiagramConnection *> result; foreach (DiagramConnection *connection, itemsByType<DiagramConnection>()) - if (connection->source() == object || connection->target() == object) + if (connection->connector(0)->connectedObject() == object || connection->connector(1)->connectedObject() == object) result.append(connection); return result; } diff --git a/src/diagramitem.cpp b/src/diagramitem.cpp index 5b5133e..3079590 100644 --- a/src/diagramitem.cpp +++ b/src/diagramitem.cpp @@ -26,18 +26,6 @@ DiagramItem::DiagramItem(DiagramItem *parent) { } -void -DiagramItem::setId(QUuid id) -{ - m_id = id; -} - -void -DiagramItem::createId() -{ - m_id = QUuid::createUuid(); -} - DiagramDocument * DiagramItem::document() const { diff --git a/src/diagramitem.h b/src/diagramitem.h index e0ce662..f597a48 100644 --- a/src/diagramitem.h +++ b/src/diagramitem.h @@ -20,12 +20,12 @@ #include <QGraphicsItem> #include <QDomDocument> #include <QDomElement> -#include <QUuid> +#include "identifiableobject.h" class QMimeData; class DiagramDocument; class DiagramItemProperties; -class DiagramItem : public QObject, public QGraphicsItem +class DiagramItem : public QObject, public QGraphicsItem, public IdentifiableObject { Q_OBJECT @@ -37,10 +37,6 @@ public: DiagramDocument *document() const; - QUuid id() const { return m_id; } - void setId(QUuid id); - void createId(); - DiagramItem(DiagramItem *parent = 0); static const char *staticTypeName() { return ""; } @@ -56,9 +52,6 @@ public: signals: void propertyChanged(const QString &name, const QVariant &value); - -public: - QUuid m_id; }; #endif diff --git a/src/diagramobject.cpp b/src/diagramobject.cpp index e0d6c17..6783455 100644 --- a/src/diagramobject.cpp +++ b/src/diagramobject.cpp @@ -17,7 +17,19 @@ #include "diagramobject.h" DiagramObject::DiagramObject(DiagramItem *parent) - : DiagramItem(parent) + : DiagramItem(parent), m_hub(NULL) { setZValue(100.0); } + +Hub * +DiagramObject::hub() const +{ + return m_hub; +} + +void +DiagramObject::setHub(Hub *hub) +{ + m_hub = hub; +} diff --git a/src/diagramobject.h b/src/diagramobject.h index 6650968..96b027c 100644 --- a/src/diagramobject.h +++ b/src/diagramobject.h @@ -18,6 +18,8 @@ #define DIAGRAMOBJECT_H #include "diagramitem.h" +class Hub; +class DiagramConnection; class DiagramObject : public DiagramItem { @@ -25,6 +27,15 @@ class DiagramObject : public DiagramItem public: DiagramObject(DiagramItem *parent = 0); + + Hub *hub() const; + +protected: + void setHub(Hub *hub); + +private: + Hub *m_hub; + //QMap<ConnectionSlot, DiagramConnection*> m_connections; }; #endif diff --git a/src/hub.cpp b/src/hub.cpp new file mode 100644 index 0000000..aec14a6 --- /dev/null +++ b/src/hub.cpp @@ -0,0 +1,52 @@ +// 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 "hub.h" +#include "diagramobject.h" + +Hub::Hub(DiagramObject *owner) + : m_owner(owner) +{ +} + +DiagramObject * +Hub::owner() const +{ + return m_owner; +} + +void +Hub::addConnector(Connector *connector) +{ + m_connectors.insert(connector); +} + +void +Hub::removeConnector(Connector *connector) +{ + m_connectors.remove(connector); +} + +QSet<Connector *> +Hub::connectors() const +{ + return m_connectors; +} + +void +Hub::update() +{ +} diff --git a/src/hub.h b/src/hub.h new file mode 100644 index 0000000..83ff2fd --- /dev/null +++ b/src/hub.h @@ -0,0 +1,42 @@ +// 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. + +#ifndef HUB_H +#define HUB_H + +#include <QSet> +class Connector; +class DiagramObject; + +class Hub +{ +public: + Hub(DiagramObject *owner); + DiagramObject *owner() const; + + void addConnector(Connector *connector); + void removeConnector(Connector *connector); + + virtual void update(); + + QSet<Connector *> connectors() const; + +private: + QSet<Connector *> m_connectors; + DiagramObject *m_owner; +}; + +#endif diff --git a/src/items/database/column.h b/src/items/database/column.h index 36e6680..bbf4fff 100644 --- a/src/items/database/column.h +++ b/src/items/database/column.h @@ -20,8 +20,9 @@ #include <QObject> #include <QString> #include "columnlist.h" +#include "identifiableobject.h" -class Column : public QObject +class Column : public QObject, public IdentifiableObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) diff --git a/src/items/database/databasecommands.cpp b/src/items/database/databasecommands.cpp index 7156d4a..eae59db 100644 --- a/src/items/database/databasecommands.cpp +++ b/src/items/database/databasecommands.cpp @@ -26,8 +26,10 @@ AddColumnCommand::AddColumnCommand(ColumnList *columnList, Column *column, QUndoCommand *parent) : QUndoCommand(parent), m_columnList(columnList), m_column(column) { - if (!m_column) + if (!m_column) { m_column = new Column(); + m_column->createId(); + } m_index = columnList->columnCount(); } diff --git a/src/items/database/databaserelationship.cpp b/src/items/database/databaserelationship.cpp index 3be258c..a95ac6e 100644 --- a/src/items/database/databaserelationship.cpp +++ b/src/items/database/databaserelationship.cpp @@ -291,8 +291,11 @@ DatabaseRelationship::updateLayout() if (!scene()) return; - DatabaseTable *source = sourceTable(); - DatabaseTable *target = targetTable(); + Connector *connector1 = connector(0); + Connector *connector2 = connector(1); + + DatabaseTable *source = childTable(); + DatabaseTable *target = parentTable(); if (!source || !target) return; @@ -339,80 +342,42 @@ DatabaseRelationship::updateLayout() } } - // Two-segment line - if (0 && !haveLine) { - - qreal x1, x2, x3, y1, y2, y3; - - if (rect1.right() < rect2.left()) { - x1 = rect1.right(); - y1 = verticalRange1.center(); - - x2 = horizontalRange2.center(); - y2 = verticalRange1.center(); - - if (rect1.bottom() < rect2.top()) { - x3 = horizontalRange2.center(); - y3 = rect2.top(); - } - else { - x3 = horizontalRange2.center(); - y3 = rect2.bottom(); - } + // Orthogonal line + if (!haveLine) { + QPointF p1 = connector1->pos(); + QPointF p2 = connector2->pos(); + qreal a1 = connector1->angle(); + qreal a2 = connector2->angle(); + + QLineF line1 = QLineF::fromPolar(1, a1).translated(p1); + QLineF line2 = QLineF::fromPolar(1, a2).translated(p2); + QPointF intersection; + d->line.clear(); + d->line << p1; + if (line1.intersect(line2, &intersection) != QLineF::NoIntersection) { + // 2-segment line + d->line << intersection; } else { - x1 = rect1.left(); - y1 = verticalRange1.center(); - - x2 = horizontalRange2.center(); - y2 = verticalRange1.center(); - - if (rect1.bottom() < rect2.top()) { - x3 = horizontalRange2.center(); - y3 = rect2.top(); + if (line1.intersect(line2.normalVector(), &intersection) != QLineF::NoIntersection) { + // 3-segment line + qreal len = QLineF(p1, intersection).length() * 0.5; + d->line << QLineF::fromPolar(len, a1).translated(p1).p2(); + d->line << QLineF::fromPolar(len, a2).translated(p2).p2(); } else { - x3 = horizontalRange2.center(); - y3 = rect2.bottom(); + qFatal("No line?"); } } - - d->line = QPolygonF() - << QPointF(x1, y1) - << QPointF(x2, y2) - << QPointF(x3, y3); + d->line << p2; haveLine = true; } // Simple center<->center line if (!haveLine) { - QPointF p1 = rect1.center(); - QPointF p2 = rect2.center(); - QLineF finalLine = 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 (finalLine.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { - finalLine.setP1(intersectionPoint); - break; - } - } - - polygon = rect2; - for (int i = 0; i < 4; i++) { - QLineF line(polygon[i], polygon[(i+1)%4]); - QPointF intersectionPoint; - if (finalLine.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { - finalLine.setP2(intersectionPoint); - break; - } - } - - d->line = QPolygonF() << finalLine.p1() << finalLine.p2(); + QPointF p1 = connector1->pos(); + QPointF p2 = connector2->pos(); + d->line = QPolygonF() << p1 << p2; haveLine = true; } diff --git a/src/items/database/databaserelationship.h b/src/items/database/databaserelationship.h index 5a21c98..f8f381e 100644 --- a/src/items/database/databaserelationship.h +++ b/src/items/database/databaserelationship.h @@ -22,6 +22,7 @@ #include <QPainter> #include "diagramconnection.h" #include "databasetable.h" +#include "connector.h" class DatabaseRelationship : public DiagramConnection { @@ -41,11 +42,8 @@ public: QPainterPath shape() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - DatabaseTable *sourceTable() const { return qobject_cast<DatabaseTable *>(source()); } - DatabaseTable *targetTable() const { return qobject_cast<DatabaseTable *>(target()); } - - DatabaseTable *childTable() const { return sourceTable(); } - DatabaseTable *parentTable() const { return targetTable(); } + DatabaseTable *childTable() const { return qobject_cast<DatabaseTable *>(connector(0)->connectedObject()); } + DatabaseTable *parentTable() const { return qobject_cast<DatabaseTable *>(connector(1)->connectedObject()); } enum { Type = DiagramItem::Relation }; virtual int type() const { return Type; } diff --git a/src/items/database/databasetable.cpp b/src/items/database/databasetable.cpp index ca3827b..3c6318a 100644 --- a/src/items/database/databasetable.cpp +++ b/src/items/database/databasetable.cpp @@ -22,12 +22,14 @@ #include "diagramdocument.h" #include "column.h" #include "columnlist.h" +#include "boxsidehub.h" DatabaseTable::DatabaseTable(DiagramItem *parent) : DiagramObject(parent) { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); + setHub(new BoxSideHub(this)); m_columnList = new ColumnList(this); connect(m_columnList, SIGNAL(columnInserted(int)), this, SLOT(updateLayout())); connect(m_columnList, SIGNAL(columnRemoved(int)), this, SLOT(updateLayout())); diff --git a/src/src.pri b/src/src.pri index 2dcc581..5a96c1f 100644 --- a/src/src.pri +++ b/src/src.pri @@ -3,6 +3,9 @@ DEPENDPATH += $$PWD RESOURCES = ../dbmodel.qrc SOURCES = \ + connector.cpp \ + hub.cpp \ + boxsidehub.cpp \ main.cpp \ mainwindow.cpp \ diagramview.cpp \ @@ -12,9 +15,13 @@ SOURCES = \ diagramitemfactory.cpp \ diagramitemproperties.cpp \ diagramobject.cpp \ + identifiableobject.cpp \ commands.cpp HEADERS = \ + connector.h \ + hub.h \ + boxsidehub.h \ mainwindow.h \ diagramview.h \ diagramdocument.h \ @@ -23,6 +30,7 @@ HEADERS = \ diagramitemfactory.h \ diagramitemproperties.h \ diagramobject.h \ + identifiableobject.h \ commands.h TRANSLATIONS = \ |