diff options
author | Lukáš Lalinský <lalinsky@gmail.com> | 2008-12-13 00:12:20 +0100 |
---|---|---|
committer | Lukáš Lalinský <lalinsky@gmail.com> | 2008-12-13 00:12:20 +0100 |
commit | 6f1ca5aaa1bbfe699434b4021b0bc101e5d28e8b (patch) | |
tree | 506839f57adeb10588ffd3cf9d094a2509e33832 | |
parent | 2b09f7747c171c4c39538c844a616b60424f16a3 (diff) | |
download | dbmodel-6f1ca5aaa1bbfe699434b4021b0bc101e5d28e8b.tar.gz dbmodel-6f1ca5aaa1bbfe699434b4021b0bc101e5d28e8b.tar.bz2 |
Add a way to select FK/referenced columns in a relationship
-rw-r--r-- | src/items/database/column.h | 2 | ||||
-rw-r--r-- | src/items/database/columnlist.h | 2 | ||||
-rw-r--r-- | src/items/database/columnlistcombomodel.cpp | 35 | ||||
-rw-r--r-- | src/items/database/columnlistcombomodel.h | 34 | ||||
-rw-r--r-- | src/items/database/columnlistmodel.cpp | 19 | ||||
-rw-r--r-- | src/items/database/columnlistmodel.h | 5 | ||||
-rw-r--r-- | src/items/database/database.pri | 2 | ||||
-rw-r--r-- | src/items/database/databaserelationship.cpp | 40 | ||||
-rw-r--r-- | src/items/database/databaserelationship.h | 13 | ||||
-rw-r--r-- | src/items/database/databaserelationshipproperties.cpp | 70 | ||||
-rw-r--r-- | src/items/database/databaserelationshipproperties.h | 4 | ||||
-rw-r--r-- | src/items/database/databaserelationshipproperties.ui | 59 | ||||
-rw-r--r-- | src/items/database/databasetable.cpp | 10 | ||||
-rw-r--r-- | src/items/database/databasetable.h | 4 | ||||
-rw-r--r-- | src/main.cpp | 4 |
15 files changed, 282 insertions, 21 deletions
diff --git a/src/items/database/column.h b/src/items/database/column.h index 2930efa..36e6680 100644 --- a/src/items/database/column.h +++ b/src/items/database/column.h @@ -62,4 +62,6 @@ private: bool m_required; }; +Q_DECLARE_METATYPE(Column*) + #endif diff --git a/src/items/database/columnlist.h b/src/items/database/columnlist.h index 51a25be..c493c6d 100644 --- a/src/items/database/columnlist.h +++ b/src/items/database/columnlist.h @@ -28,7 +28,7 @@ class ColumnList : public QObject public: ColumnList(DatabaseTable *table); - DatabaseTable *table() { return qobject_cast<DatabaseTable *>(parent()); } + DatabaseTable *table() const { return qobject_cast<DatabaseTable *>(parent()); } QList<Column *> columns() { return m_columns; } int columnCount() const { return m_columns.size(); } diff --git a/src/items/database/columnlistcombomodel.cpp b/src/items/database/columnlistcombomodel.cpp new file mode 100644 index 0000000..c5c558c --- /dev/null +++ b/src/items/database/columnlistcombomodel.cpp @@ -0,0 +1,35 @@ +// 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 "columnlist.h" +#include "columnlistcombomodel.h" + +ColumnListComboModel::ColumnListComboModel(QObject *parent) + : ColumnListModel(parent) +{ +} + +QVariant +ColumnListComboModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::DisplayRole) { + if (index.row() == 0) { + return "-"; + } + } + return ColumnListModel::data(index, role); +} diff --git a/src/items/database/columnlistcombomodel.h b/src/items/database/columnlistcombomodel.h new file mode 100644 index 0000000..a98bb1b --- /dev/null +++ b/src/items/database/columnlistcombomodel.h @@ -0,0 +1,34 @@ +// 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 COLUMNLISTCOMBOMODEL_H +#define COLUMNLISTCOMBOMODEL_H + +#include "columnlistmodel.h" + +class ColumnListComboModel : public ColumnListModel +{ + Q_OBJECT + +public: + ColumnListComboModel(QObject *parent = 0); + QVariant data(const QModelIndex &index, int role) const; + +protected: + int firstRow() const { return 1; } +}; + +#endif diff --git a/src/items/database/columnlistmodel.cpp b/src/items/database/columnlistmodel.cpp index c826611..84ba804 100644 --- a/src/items/database/columnlistmodel.cpp +++ b/src/items/database/columnlistmodel.cpp @@ -68,10 +68,11 @@ ColumnListModel::data(const QModelIndex &index, int role) const { if (m_columnList) { Q_ASSERT(index.isValid()); - if (index.row() == m_columnList->columnCount()) { + int row = index.row() - firstRow(); + if (row < 0 || row >= m_columnList->columnCount()) { return QVariant(); } - Column *column = m_columnList->column(index.row()); + Column *column = m_columnList->column(row); if (role == Qt::DisplayRole || role == Qt::EditRole) { if (index.column() == 0) { return column->name(); @@ -101,13 +102,14 @@ ColumnListModel::setData(const QModelIndex &index, const QVariant &value, int ro if (m_columnList) { Q_ASSERT(index.isValid()); Column *column; - if (index.row() == m_columnList->columnCount()) { + int row = index.row() - firstRow(); + if (row == m_columnList->columnCount()) { column = new Column(); m_columnList->table()->document()->undoStack()->push( new AddColumnCommand(m_columnList, column)); } else { - column = m_columnList->column(index.row()); + column = m_columnList->column(row); } if (role == Qt::DisplayRole || role == Qt::EditRole) { QString text = value.toString(); @@ -151,7 +153,6 @@ ColumnListModel::setData(const QModelIndex &index, const QVariant &value, int ro } return false; OK: - emit dataChanged(createIndex(index.row(), 0), createIndex(index.row(), COLUMN_COUNT)); return true; } @@ -189,13 +190,13 @@ ColumnListModel::headerData(int section, Qt::Orientation orientation, int role) QModelIndex ColumnListModel::indexFromRow(int i) const { - return createIndex(i, 0); + return createIndex(firstRow() + i, 0); } void ColumnListModel::_columnAboutToBeInserted(int index) { - beginInsertRows(QModelIndex(), index, index); + beginInsertRows(QModelIndex(), firstRow() + index, firstRow() + index); } void @@ -207,7 +208,7 @@ ColumnListModel::_columnInserted() void ColumnListModel::_columnAboutToBeRemoved(int index) { - beginRemoveRows(QModelIndex(), index, index); + beginRemoveRows(QModelIndex(), firstRow() + index, firstRow() + index); } void @@ -219,5 +220,5 @@ ColumnListModel::_columnRemoved() void ColumnListModel::_columnChanged(int index) { - emit dataChanged(createIndex(index, 0), createIndex(index, COLUMN_COUNT)); + emit dataChanged(createIndex(firstRow() + index, 0), createIndex(firstRow() + index, COLUMN_COUNT)); } diff --git a/src/items/database/columnlistmodel.h b/src/items/database/columnlistmodel.h index 2944223..61b1047 100644 --- a/src/items/database/columnlistmodel.h +++ b/src/items/database/columnlistmodel.h @@ -28,7 +28,7 @@ class ColumnListModel : public QAbstractTableModel public: ColumnListModel(QObject *parent = 0); - ColumnList *columnList() { return m_columnList; } + ColumnList *columnList() const { return m_columnList; } void setColumnList(ColumnList *columnList); // QAbstractItemModel methods @@ -41,6 +41,9 @@ public: QModelIndex indexFromRow(int i) const; +protected: + virtual int firstRow() const { return 0; } + private slots: void _columnAboutToBeInserted(int index); void _columnInserted(); diff --git a/src/items/database/database.pri b/src/items/database/database.pri index 5fd4397..c65f9e9 100644 --- a/src/items/database/database.pri +++ b/src/items/database/database.pri @@ -4,6 +4,7 @@ SOURCES += \ databasecommands.cpp \ column.cpp \ columnlist.cpp \ + columnlistcombomodel.cpp \ columnlistmodel.cpp \ columnlistview.cpp \ databasetable.cpp \ @@ -15,6 +16,7 @@ HEADERS += \ databasecommands.h \ column.h \ columnlist.h \ + columnlistcombomodel.h \ columnlistmodel.h \ columnlistview.h \ databasetable.h \ diff --git a/src/items/database/databaserelationship.cpp b/src/items/database/databaserelationship.cpp index c51d9d7..b03723c 100644 --- a/src/items/database/databaserelationship.cpp +++ b/src/items/database/databaserelationship.cpp @@ -30,7 +30,9 @@ public: childOptional(false), parentOptional(false), onUpdateAction(NoAction), - onDeleteAction(NoAction) + onDeleteAction(NoAction), + childColumn(0), + parentColumn(0) { if (!pathsInitialized) { pathsInitialized = true; @@ -66,6 +68,8 @@ public: bool parentOptional; Action onUpdateAction; Action onDeleteAction; + Column *childColumn; + Column *parentColumn; bool fillEnds; QPainterPath sourceEnd; @@ -163,6 +167,40 @@ DatabaseRelationship::setParentOptional(bool optional) } } +Column * +DatabaseRelationship::childColumn() const +{ + return d->childColumn; +} + +void +DatabaseRelationship::setChildColumn(Column *column) +{ + if (d->childColumn != column) { + d->childColumn = column; + emit propertyChanged("childColumn", column); + updateLayout(); + update(); + } +} + +Column * +DatabaseRelationship::parentColumn() const +{ + return d->parentColumn; +} + +void +DatabaseRelationship::setParentColumn(Column *column) +{ + if (d->parentColumn != column) { + d->parentColumn = column; + emit propertyChanged("parentColumn", column); + updateLayout(); + update(); + } +} + QRectF DatabaseRelationship::boundingRect() const { diff --git a/src/items/database/databaserelationship.h b/src/items/database/databaserelationship.h index 5d7e812..c4c58a1 100644 --- a/src/items/database/databaserelationship.h +++ b/src/items/database/databaserelationship.h @@ -30,6 +30,8 @@ class DatabaseRelationship : public DiagramConnection Q_PROPERTY(Cardinality cardinality READ cardinality WRITE setCardinality); Q_PROPERTY(bool childOptional READ isChildOptional WRITE setChildOptional); Q_PROPERTY(bool parentOptional READ isParentOptional WRITE setParentOptional); + Q_PROPERTY(Column* childColumn READ childColumn WRITE setChildColumn); + Q_PROPERTY(Column* parentColumn READ parentColumn WRITE setParentColumn); public: DatabaseRelationship(DiagramItem *parent = 0); @@ -42,6 +44,9 @@ public: DatabaseTable *sourceTable() { return qobject_cast<DatabaseTable *>(source()); } DatabaseTable *targetTable() { return qobject_cast<DatabaseTable *>(target()); } + DatabaseTable *childTable() { return sourceTable(); } + DatabaseTable *parentTable() { return targetTable(); } + enum { Type = DiagramItem::Relation }; virtual int type() const { return Type; } @@ -75,10 +80,14 @@ public: void setCardinality(Cardinality cardinality); //! List of columns in the child (referencing) table - QList<Column *> sourceColumns() const; + Column *childColumn() const; + + void setChildColumn(Column *column); //! List of columns in the parent (referenced) table - QList<Column *> targetColumns() const; + Column *parentColumn() const; + + void setParentColumn(Column *column); enum Action { NoAction, diff --git a/src/items/database/databaserelationshipproperties.cpp b/src/items/database/databaserelationshipproperties.cpp index bcdc104..f34d045 100644 --- a/src/items/database/databaserelationshipproperties.cpp +++ b/src/items/database/databaserelationshipproperties.cpp @@ -14,6 +14,7 @@ // 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 <QComboBox> #include <QCheckBox> #include <QHBoxLayout> @@ -22,6 +23,9 @@ #include <QLineEdit> #include "commands.h" #include "diagramdocument.h" +#include "column.h" +#include "columnlist.h" +#include "columnlistcombomodel.h" #include "databaserelationship.h" #include "databaserelationshipproperties.h" #include "ui_databaserelationshipproperties.h" @@ -30,6 +34,7 @@ class DatabaseRelationshipProperties::PrivateData { public: PrivateData() + : ignoreColumnChanges(true) {} QWidget *nameEdit; @@ -37,6 +42,9 @@ public: QComboBox *cardinalityComboBox; Ui_DatabaseRelationshipForm ui; QButtonGroup *cardinalityButtonGroup; + ColumnListComboModel *childColumnModel; + ColumnListComboModel *parentColumnModel; + bool ignoreColumnChanges; }; DatabaseRelationshipProperties::DatabaseRelationshipProperties(QWidget *parent) @@ -63,27 +71,45 @@ DatabaseRelationshipProperties::createRelationshipPage() connect(d->ui.modalityChildCheckBox, SIGNAL(toggled(bool)), SLOT(setChildOptional(bool))); connect(d->ui.modalityParentCheckBox, SIGNAL(toggled(bool)), SLOT(setParentOptional(bool))); + d->childColumnModel = new ColumnListComboModel(this); + d->ui.childColumnComboBox->setModel(d->childColumnModel); + d->parentColumnModel = new ColumnListComboModel(this); + d->ui.parentColumnComboBox->setModel(d->parentColumnModel); + + connect(d->ui.childColumnComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setChildColumn(int))); + connect(d->ui.parentColumnComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setParentColumn(int))); + return page; } void -DatabaseRelationshipProperties::switchCurrentItem(DiagramItem *oldItem, DiagramItem *newItem) +DatabaseRelationshipProperties::switchCurrentItem(DiagramItem *oldItem, DiagramItem *) { if (oldItem) disconnect(oldItem, 0, this, 0); + d->ignoreColumnChanges = true; DatabaseRelationship *relationship = currentRelationship(); if (relationship) { updateCardinality(); updateChildOptional(); updateParentOptional(); + d->childColumnModel->setColumnList(relationship->childTable()->columnList()); + d->parentColumnModel->setColumnList(relationship->parentTable()->columnList()); + d->ui.childColumnComboBox->updateGeometry(); + d->ui.parentColumnComboBox->updateGeometry(); + updateChildColumn(); + updateParentColumn(); connect(relationship, SIGNAL(propertyChanged(const QString &, const QVariant &)), SLOT(updateProperty(const QString &, const QVariant &))); + d->ignoreColumnChanges = false; } else { + d->childColumnModel->setColumnList(0); + d->parentColumnModel->setColumnList(0); } } void -DatabaseRelationshipProperties::updateProperty(const QString &name, const QVariant &value) +DatabaseRelationshipProperties::updateProperty(const QString &name, const QVariant &) { if (name == "cardinality") { updateCardinality(); @@ -127,6 +153,24 @@ DatabaseRelationshipProperties::updateParentOptional() d->ui.modalityParentCheckBox->setChecked(relationship->isParentOptional()); } +void +DatabaseRelationshipProperties::updateChildColumn() +{ + DatabaseRelationship *relationship = currentRelationship(); + Column *column = relationship->childColumn(); + int index = column ? 1 + relationship->childTable()->columnList()->indexOf(column) : 0; + d->ui.childColumnComboBox->setCurrentIndex(index); +} + +void +DatabaseRelationshipProperties::updateParentColumn() +{ + DatabaseRelationship *relationship = currentRelationship(); + Column *column = relationship->parentColumn(); + int index = column ? 1 + relationship->parentTable()->columnList()->indexOf(column) : 0; + d->ui.parentColumnComboBox->setCurrentIndex(index); +} + DatabaseRelationship * DatabaseRelationshipProperties::currentRelationship() { @@ -164,3 +208,25 @@ DatabaseRelationshipProperties::setParentOptional(bool optional) relationship->document()->undoStack()->push( new SetObjectPropertyCommand(relationship, "parentOptional", optional)); } + +void +DatabaseRelationshipProperties::setChildColumn(int index) +{ + if (d->ignoreColumnChanges) + return; + DatabaseRelationship *relationship = currentRelationship(); + Column *column = index > 0 ? relationship->childTable()->columnList()->column(index - 1) : NULL; + relationship->document()->undoStack()->push( + new SetObjectPropertyCommand(relationship, "childColumn", qVariantFromValue(column))); +} + +void +DatabaseRelationshipProperties::setParentColumn(int index) +{ + if (d->ignoreColumnChanges) + return; + DatabaseRelationship *relationship = currentRelationship(); + Column *column = index > 0 ? relationship->parentTable()->columnList()->column(index - 1) : NULL; + relationship->document()->undoStack()->push( + new SetObjectPropertyCommand(relationship, "parentColumn", qVariantFromValue(column))); +} diff --git a/src/items/database/databaserelationshipproperties.h b/src/items/database/databaserelationshipproperties.h index 7229139..a5c6ac5 100644 --- a/src/items/database/databaserelationshipproperties.h +++ b/src/items/database/databaserelationshipproperties.h @@ -34,12 +34,16 @@ protected: void updateCardinality(); void updateChildOptional(); void updateParentOptional(); + void updateChildColumn(); + void updateParentColumn(); protected slots: void updateProperty(const QString &name, const QVariant &value); void setCardinality(QAbstractButton *button); void setChildOptional(bool); void setParentOptional(bool); + void setChildColumn(int); + void setParentColumn(int); private: class PrivateData; diff --git a/src/items/database/databaserelationshipproperties.ui b/src/items/database/databaserelationshipproperties.ui index 4bc8bac..0b99f15 100644 --- a/src/items/database/databaserelationshipproperties.ui +++ b/src/items/database/databaserelationshipproperties.ui @@ -5,8 +5,8 @@ <rect> <x>0</x> <y>0</y> - <width>501</width> - <height>142</height> + <width>507</width> + <height>145</height> </rect> </property> <layout class="QGridLayout" name="gridLayout" > @@ -114,7 +114,58 @@ </item> </layout> </item> - <item row="3" column="0" colspan="2" > + <item row="3" column="0" > + <widget class="QLabel" name="label_4" > + <property name="text" > + <string>Columns:</string> + </property> + </widget> + </item> + <item row="3" column="1" > + <layout class="QHBoxLayout" name="horizontalLayout_4" > + <item> + <widget class="QComboBox" name="childColumnComboBox" > + <property name="sizeAdjustPolicy" > + <enum>QComboBox::AdjustToContents</enum> + </property> + <property name="minimumContentsLength" > + <number>15</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5" > + <property name="text" > + <string>references</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="parentColumnComboBox" > + <property name="sizeAdjustPolicy" > + <enum>QComboBox::AdjustToContents</enum> + </property> + <property name="minimumContentsLength" > + <number>15</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="4" column="0" colspan="2" > <spacer name="verticalSpacer" > <property name="orientation" > <enum>Qt::Vertical</enum> @@ -122,7 +173,7 @@ <property name="sizeHint" stdset="0" > <size> <width>418</width> - <height>27</height> + <height>5</height> </size> </property> </spacer> diff --git a/src/items/database/databasetable.cpp b/src/items/database/databasetable.cpp index 3a2387b..2e3519a 100644 --- a/src/items/database/databasetable.cpp +++ b/src/items/database/databasetable.cpp @@ -40,6 +40,16 @@ DatabaseTable::boundingRect() const return m_outerRect; } +QList<Column *> +DatabaseTable::primaryKeys() const +{ + QList<Column *> result; + foreach (Column *column, m_columnList->columns()) + if (column->isPrimaryKey()) + result.append(column); + return result; +} + void DatabaseTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { diff --git a/src/items/database/databasetable.h b/src/items/database/databasetable.h index b66eb91..c2306e2 100644 --- a/src/items/database/databasetable.h +++ b/src/items/database/databasetable.h @@ -40,7 +40,9 @@ public: void setName(const QString &name); void setInitialName(int counter); - ColumnList *columnList() { return m_columnList; } + QList<Column *> primaryKeys() const; + + ColumnList *columnList() const { return m_columnList; } // void setColumn(int index, const QString &name); // void removeColumn(int index); diff --git a/src/main.cpp b/src/main.cpp index 37fabe6..628856c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,12 +20,16 @@ #include <QApplication> #include "mainwindow.h" +class Column; + int main(int argc, char **argv) { Q_INIT_RESOURCE(dbmodel); QApplication app(argc, argv); + qRegisterMetaType<Column*>("Column*"); + QCoreApplication::setOrganizationName("Lukas Lalinsky"); QCoreApplication::setApplicationName("Database Modeller"); |