summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Lalinský <lalinsky@gmail.com>2008-12-30 10:26:14 +0100
committerLukáš Lalinský <lalinsky@gmail.com>2008-12-30 10:26:14 +0100
commit033bf7a0b5baa26af94ad006f6576d04c8609e9e (patch)
tree499e36f09515f2bc3f23cf09e2364666888002bb
parent3a95c3cd621e3904d717b591aaa9f2c89959981e (diff)
downloaddbmodel-033bf7a0b5baa26af94ad006f6576d04c8609e9e.tar.gz
dbmodel-033bf7a0b5baa26af94ad006f6576d04c8609e9e.tar.bz2
Implement orthogonal line drawing
-rw-r--r--src/boxsidehub.cpp140
-rw-r--r--src/boxsidehub.h29
-rw-r--r--src/commands.cpp3
-rw-r--r--src/connector.cpp99
-rw-r--r--src/connector.h52
-rw-r--r--src/diagramconnection.cpp28
-rw-r--r--src/diagramconnection.h13
-rw-r--r--src/diagramdocument.cpp19
-rw-r--r--src/diagramitem.cpp12
-rw-r--r--src/diagramitem.h11
-rw-r--r--src/diagramobject.cpp14
-rw-r--r--src/diagramobject.h11
-rw-r--r--src/hub.cpp52
-rw-r--r--src/hub.h42
-rw-r--r--src/items/database/column.h3
-rw-r--r--src/items/database/databasecommands.cpp4
-rw-r--r--src/items/database/databaserelationship.cpp95
-rw-r--r--src/items/database/databaserelationship.h8
-rw-r--r--src/items/database/databasetable.cpp2
-rw-r--r--src/src.pri8
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 = \