summaryrefslogtreecommitdiff
path: root/src/diagramdocument.cpp
diff options
context:
space:
mode:
authorLukáš Lalinský <lalinsky@gmail.com>2008-12-07 01:05:09 +0100
committerLukáš Lalinský <lalinsky@gmail.com>2008-12-07 01:05:09 +0100
commit364531ec14761f07b22dbec6461376aad81159f6 (patch)
treed12861cb31805dfb551a9b1361a5c8513bbfd7a3 /src/diagramdocument.cpp
parent67ee0e1c5b11cc2a4c70018f524c9ce00da30b60 (diff)
downloaddbmodel-364531ec14761f07b22dbec6461376aad81159f6.tar.xz
Move source code to src/ and add translation support
Diffstat (limited to 'src/diagramdocument.cpp')
-rw-r--r--src/diagramdocument.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/diagramdocument.cpp b/src/diagramdocument.cpp
new file mode 100644
index 0000000..573d08c
--- /dev/null
+++ b/src/diagramdocument.cpp
@@ -0,0 +1,298 @@
+// 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 "diagramdocument.h"
+#include "databasetable.h"
+#include "databaserelationship.h"
+#include "column.h"
+#include <QGraphicsItem>
+#include <QDebug>
+#include <QFile>
+#include <QTextStream>
+
+DiagramDocument::DiagramDocument(QObject *parent)
+ : QGraphicsScene(parent), m_mode(DiagramDocument::Select), m_line(NULL)
+{
+ m_undoStack = new QUndoStack(this);
+ connect(this, SIGNAL(tableMoved(DatabaseTable *)), SLOT(updatePositions(DatabaseTable *)));
+}
+
+DiagramDocument::Mode
+DiagramDocument::mode()
+{
+ return m_mode;
+}
+
+void
+DiagramDocument::setMode(Mode mode)
+{
+ m_mode = mode;
+ emit modeChanged(mode);
+}
+
+void
+DiagramDocument::updatePositions(DatabaseTable *table)
+{
+ foreach (DatabaseRelationship *relation, findTableRelations(table)) {
+ relation->updatePositions();
+ }
+}
+
+void
+DiagramDocument::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_mode == AddTable && event->button() == Qt::LeftButton) {
+ DatabaseTable *table = new DatabaseTable();
+ table->setPos(event->scenePos());
+ table->setZValue(10.0);
+ m_tables << table;
+ addItem(table);
+ clearSelection();
+ table->setSelected(true);
+ setMode(Select);
+ event->accept();
+ return;
+ }
+ if (m_mode == AddRelation && event->button() == Qt::LeftButton) {
+ m_line = new QGraphicsLineItem();
+ m_line->setLine(QLineF(event->scenePos(), event->scenePos()));
+ m_line->setZValue(1000.0);
+ addItem(m_line);
+ event->accept();
+ return;
+ }
+ QGraphicsScene::mousePressEvent(event);
+}
+
+void
+DiagramDocument::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_line) {
+ m_line->setLine(QLineF(m_line->line().p1(), event->scenePos()));
+ event->accept();
+ return;
+ }
+ QGraphicsScene::mouseMoveEvent(event);
+}
+
+void
+DiagramDocument::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_line) {
+ removeItem(m_line);
+ DatabaseTable *source = qgraphicsitem_cast<DatabaseTable *>(itemAt(m_line->line().p1()));
+ DatabaseTable *target = qgraphicsitem_cast<DatabaseTable *>(itemAt(m_line->line().p2()));
+ if (source && target && source != target) {
+ //qDebug() << "Add relation between " << source << " and " << target;
+ DatabaseRelationship *relation = new DatabaseRelationship();
+ relation->setSource(source);
+ relation->setTarget(target);
+ relation->setZValue(1.0);
+ addItem(relation);
+ m_relations << relation;
+ }
+
+ delete m_line;
+ m_line = NULL;
+ setMode(Select);
+ event->accept();
+ return;
+ }
+ QGraphicsScene::mouseReleaseEvent(event);
+}
+
+DatabaseTable *
+DiagramDocument::selectedTable()
+{
+ QList<QGraphicsItem *> items = selectedItems();
+ if (items.size() != 1)
+ return NULL;
+ return qgraphicsitem_cast<DatabaseTable *>(items[0]);
+}
+
+void
+DiagramDocument::deleteSelectedItems()
+{
+ foreach (QGraphicsItem *item, selectedItems()) {
+ DatabaseTable *table = qgraphicsitem_cast<DatabaseTable *>(item);
+ if (table) {
+ foreach (DatabaseRelationship *relation, findTableRelations(table)) {
+ removeItem(relation);
+ m_relations.removeAll(relation);
+ }
+ removeItem(table);
+ m_tables.removeAll(table);
+ }
+ }
+}
+
+QList<DatabaseRelationship *>
+DiagramDocument::findTableRelations(DatabaseTable *table)
+{
+ QList<DatabaseRelationship *> result;
+ foreach (DatabaseRelationship *relation, m_relations) {
+ if (relation->source() == table || relation->target() == table) {
+ result << relation;
+ }
+ }
+ return result;
+}
+
+void
+appendStringElement(QDomDocument &doc, QDomElement &parent, const QString &name, const QString &value)
+{
+ if (!value.isEmpty()) {
+ QDomElement element = doc.createElement(name);
+ element.appendChild(doc.createTextNode(value));
+ parent.appendChild(element);
+ }
+}
+
+QString
+readStringElement(QDomElement &parent, const QString &name, const QString &defaultValue = QString())
+{
+ QDomElement element = parent.firstChildElement(name);
+ if (!element.isNull()) {
+ return element.text();
+ }
+ return defaultValue;
+}
+
+void
+DiagramDocument::save(const QString &fileName)
+{
+ QDomDocument doc;
+
+ QDomElement root = doc.createElement("database-model");
+ doc.appendChild(root);
+
+ QDomElement tableListElement = doc.createElement("table-list");
+ root.appendChild(tableListElement);
+
+ foreach (DatabaseTable *table, m_tables) {
+ QDomElement tableElement = doc.createElement("table");
+ tableListElement.appendChild(tableElement);
+
+ QDomElement positionElement = doc.createElement("position");
+ positionElement.setAttribute("x", table->pos().x());
+ positionElement.setAttribute("y", table->pos().y());
+ tableElement.appendChild(positionElement);
+
+ QDomElement nameElement = doc.createElement("name");
+ nameElement.appendChild(doc.createTextNode(table->name()));
+ tableElement.appendChild(nameElement);
+
+ QDomElement columnListElement = doc.createElement("column-list");
+ tableElement.appendChild(columnListElement);
+
+ foreach (Column *column, table->columnList()->columns()) {
+ QDomElement columnElement = doc.createElement("column");
+ columnListElement.appendChild(columnElement);
+ appendStringElement(doc, columnElement, "name", column->name());
+ appendStringElement(doc, columnElement, "data-type", column->dataType());
+ appendStringElement(doc, columnElement, "required", column->isRequired() ? "yes" : QString());
+ appendStringElement(doc, columnElement, "primary-key", column->isPrimaryKey() ? "yes" : QString());
+ appendStringElement(doc, columnElement, "notes", column->notes());
+ }
+ }
+
+ QDomElement relationListElement = doc.createElement("relation-list");
+ root.appendChild(relationListElement);
+
+ foreach (DatabaseRelationship *relation, m_relations) {
+ QDomElement relationElement = doc.createElement("relation");
+ relationElement.setAttribute("from", QString::number(m_tables.indexOf(relation->sourceTable())));
+ relationElement.setAttribute("to", QString::number(m_tables.indexOf(relation->targetTable())));
+ relationListElement.appendChild(relationElement);
+ }
+
+ QFile file(fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ QTextStream stream(&file);
+ doc.save(stream, 0);
+ file.close();
+ }
+
+ setFileName(fileName);
+}
+
+void
+DiagramDocument::load(const QString &fileName)
+{
+ QDomDocument doc;
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ doc.setContent(&file);
+ file.close();
+ }
+
+ setFileName(fileName);
+
+ QDomElement root = doc.firstChildElement("database-model");
+
+ QDomElement tableListElement = root.firstChildElement("table-list");
+ QDomElement tableElement = tableListElement.firstChildElement("table");
+ while (!tableElement.isNull()) {
+ DatabaseTable *table = new DatabaseTable;
+
+ QDomElement positionElement = tableElement.firstChildElement("position");
+ if (!positionElement.isNull()) {
+ QPoint pos;
+ pos.setX(positionElement.attribute("x", "0").toInt());
+ pos.setY(positionElement.attribute("y", "0").toInt());
+ table->setPos(pos);
+ }
+
+ table->setName(readStringElement(tableElement, "name"));
+
+ QDomElement columnListElement = tableElement.firstChildElement("column-list");
+ QDomElement columnElement = columnListElement.firstChildElement("column");
+ while (!columnElement.isNull()) {
+ Column *column = new Column();
+ column->setName(readStringElement(columnElement, "name"));
+ column->setDataType(readStringElement(columnElement, "data-type"));
+ column->setRequired(readStringElement(columnElement, "required") == "yes");
+ column->setPrimaryKey(readStringElement(columnElement, "primary-key") == "yes");
+ column->setNotes(readStringElement(columnElement, "notes"));
+ table->columnList()->appendColumn(column);
+ columnElement = columnElement.nextSiblingElement("column");
+ }
+
+ m_tables << table;
+ addItem(table);
+
+ tableElement = tableElement.nextSiblingElement("table");
+ }
+
+ QDomElement relationListElement = root.firstChildElement("relation-list");
+ QDomElement relationElement = relationListElement.firstChildElement("relation");
+ while (!relationElement.isNull()) {
+ relationElement = relationElement.nextSiblingElement("relation");
+ bool ok;
+ int index0 = relationElement.attribute("from").toInt(&ok);
+ if (ok) {
+ int index1 = relationElement.attribute("to").toInt(&ok);
+ if (ok) {
+ DatabaseRelationship *relation = new DatabaseRelationship();
+ relation->setSource(m_tables[index0]);
+ relation->setTarget(m_tables[index1]);
+ m_relations << relation;
+ addItem(relation);
+ }
+ }
+ }
+
+}