diff options
author | Tomaz Canabrava <tcanabrava@kde.org> | 2013-06-17 18:59:50 -0300 |
---|---|---|
committer | Tomaz Canabrava <tcanabrava@kde.org> | 2013-06-17 18:59:50 -0300 |
commit | ae68ae38bbbc981aab4b8eaf1e84a15b8ab05bf4 (patch) | |
tree | 1b8cd2c26c573aa444f701ee0848a22d4ad1d8e0 | |
parent | 14ccbbf6e87b69267426ae69c402c1bae70ec5d5 (diff) | |
download | subsurface-ae68ae38bbbc981aab4b8eaf1e84a15b8ab05bf4.tar.gz |
Changed a lot of code to reduce boilerplate on models in the future.
So, I changed a lot of code to reduce boilerplate on models in the
future. Currently we do not have a lot of models, but this can increase
quite rapdly. There's a second TreeModel in the works, the Yearly
Statistics, this patch will save around 250 LOC for this new model,
and more and more models will give us a greater saving.
Iwll do that for the table models in the future too - I did the tree
models now because they are the most complex case and I didn't wanted
to create a second tree model without this.
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
-rw-r--r-- | qt-ui/divelistview.cpp | 32 | ||||
-rw-r--r-- | qt-ui/mainwindow.cpp | 4 | ||||
-rw-r--r-- | qt-ui/modeldelegates.cpp | 2 | ||||
-rw-r--r-- | qt-ui/models.cpp | 228 | ||||
-rw-r--r-- | qt-ui/models.h | 51 |
5 files changed, 164 insertions, 153 deletions
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index 752e12242..480decd2d 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -23,9 +23,9 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec currentHeaderClicked(-1), searchBox(new QLineEdit(this)) { setUniformRowHeights(true); - setItemDelegateForColumn(TreeItemDT::RATING, new StarWidgetsDelegate()); + setItemDelegateForColumn(DiveTripModel::RATING, new StarWidgetsDelegate()); QSortFilterProxyModel *model = new QSortFilterProxyModel(this); - model->setSortRole(TreeItemDT::SORT_ROLE); + model->setSortRole(DiveTripModel::SORT_ROLE); model->setFilterKeyColumn(-1); // filter all columns setModel(model); connect(model, SIGNAL(layoutChanged()), this, SLOT(fixMessyQtModelBehaviour())); @@ -63,7 +63,7 @@ void DiveListView::unselectDives() void DiveListView::selectDive(struct dive *dive, bool scrollto, bool toggle) { QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); - QModelIndexList match = m->match(m->index(0,0), TreeItemDT::NR, dive->number, 1, Qt::MatchRecursive); + QModelIndexList match = m->match(m->index(0,0), DiveTripModel::NR, dive->number, 1, Qt::MatchRecursive); QItemSelectionModel::SelectionFlags flags; QModelIndex idx = match.first(); @@ -111,13 +111,13 @@ void DiveListView::headerClicked(int i) DiveTripModel::Layout newLayout; bool first = true; - newLayout = i == (int) TreeItemDT::NR ? DiveTripModel::TREE : DiveTripModel::LIST; + newLayout = i == (int) DiveTripModel::NR ? DiveTripModel::TREE : DiveTripModel::LIST; Q_FOREACH(const QModelIndex& index , oldSelection.indexes()) { if (index.column() != 0) // We only care about the dives, so, let's stick to rows and discard columns. continue; - struct dive *d = (struct dive *) index.data(TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *d = (struct dive *) index.data(DiveTripModel::DIVE_ROLE).value<void*>(); if (d) currentSelectedDives.push_back(d); } @@ -228,9 +228,9 @@ void DiveListView::currentChanged(const QModelIndex& current, const QModelIndex& return; const QAbstractItemModel *model = current.model(); int selectedDive = 0; - struct dive *dive = (struct dive*) model->data(current, TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *dive = (struct dive*) model->data(current, DiveTripModel::DIVE_ROLE).value<void*>(); if (!dive) // it's a trip! select first child. - dive = (struct dive*) model->data(current.child(0,0), TreeItemDT::DIVE_ROLE).value<void*>(); + dive = (struct dive*) model->data(current.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); selectedDive = get_divenr(dive); scrollTo(current); if (selectedDive == selected_dive) @@ -250,10 +250,10 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS if (index.column() != 0) continue; const QAbstractItemModel *model = index.model(); - struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *dive = (struct dive*) model->data(index, DiveTripModel::DIVE_ROLE).value<void*>(); if (!dive) { // it's a trip! if (model->rowCount(index)) { - struct dive *child = (struct dive*) model->data(index.child(0,0), TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); if (child && child->divetrip) selectedTrips.remove(child->divetrip); while (child) { @@ -270,11 +270,11 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS continue; const QAbstractItemModel *model = index.model(); - struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *dive = (struct dive*) model->data(index, DiveTripModel::DIVE_ROLE).value<void*>(); if (!dive) { // it's a trip! if (model->rowCount(index)) { QItemSelection selection; - struct dive *child = (struct dive*) model->data(index.child(0,0), TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); if (child && child->divetrip) selectedTrips.insert(child->divetrip); while (child) { @@ -300,7 +300,7 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS void DiveListView::removeFromTrip() { - struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); if (!d) // shouldn't happen as we only are setting up this action if this is a dive return; remove_dive_from_trip(d); @@ -309,7 +309,7 @@ void DiveListView::removeFromTrip() void DiveListView::deleteDive() { - struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); if (d) delete_single_dive(get_index_for_dive(d)); reload(currentLayout, false); @@ -317,12 +317,12 @@ void DiveListView::deleteDive() void DiveListView::testSlot() { - struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); if (d) { qDebug("testSlot called on dive #%d", d->number); } else { QModelIndex child = contextMenuIndex.child(0, 0); - d = (struct dive *) child.data(TreeItemDT::DIVE_ROLE).value<void*>(); + d = (struct dive *) child.data(DiveTripModel::DIVE_ROLE).value<void*>(); if (d) qDebug("testSlot called on trip including dive #%d", d->number); else @@ -335,7 +335,7 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event) QAction *collapseAction = NULL; // let's remember where we are contextMenuIndex = indexAt(event->pos()); - struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>(); + struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); QMenu popup(this); if (currentLayout == DiveTripModel::TREE) { popup.addAction(tr("expand all"), this, SLOT(expandAll())); diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index f477a0d4f..45b8df80a 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -437,7 +437,7 @@ void MainWindow::initialUiSetup() /* if no width are set, use the calculated width for each column; * for that to work we need to temporarily expand all rows */ ui->ListWidget->expandAll(); - for (i = TreeItemDT::NR; i < TreeItemDT::COLUMNS; i++) { + for (i = DiveTripModel::NR; i < DiveTripModel::COLUMNS; i++) { QVariant width = settings.value(QString("colwidth%1").arg(i)); if (width.isValid()) ui->ListWidget->setColumnWidth(i, width.toInt()); @@ -526,7 +526,7 @@ void MainWindow::writeSettings() settings.endGroup(); settings.beginGroup("ListWidget"); - for (i = TreeItemDT::NR; i < TreeItemDT::COLUMNS; i++) + for (i = DiveTripModel::NR; i < DiveTripModel::COLUMNS; i++) if (!ui->ListWidget->isColumnHidden(i)) settings.setValue(QString("colwidth%1").arg(i), ui->ListWidget->columnWidth(i)); settings.endGroup(); diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp index 01f5197ce..3aeaa02b5 100644 --- a/qt-ui/modeldelegates.cpp +++ b/qt-ui/modeldelegates.cpp @@ -26,7 +26,7 @@ void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o if (!index.isValid()) return; - QVariant value = index.model()->data(index, TreeItemDT::STAR_ROLE); + QVariant value = index.model()->data(index, DiveTripModel::STAR_ROLE); if (!value.isValid()) return; diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index 9e076930d..4d1fb9d41 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -769,6 +769,11 @@ void TankInfoModel::update() } } +//################################################################################################# +//# +//# Tree Model - a Basic Tree Model so I don't need to kill myself repeating this for every model. +//# +//################################################################################################# /*! A DiveItem for use with a DiveTripModel * @@ -778,46 +783,98 @@ void TankInfoModel::update() * */ -TreeItemDT::~TreeItemDT() +TreeItem::~TreeItem() { qDeleteAll(children); } -int TreeItemDT::row() const +int TreeItem::row() const { if (parent) - return parent->children.indexOf(const_cast<TreeItemDT*>(this)); - + return parent->children.indexOf(const_cast<TreeItem*>(this)); return 0; } -QVariant TreeItemDT::data(int column, int role) const +QVariant TreeItem::data(int column, int role) const { - QVariant ret; - switch(role){ - case Qt::DisplayRole : - switch (column) { - case NR: ret = tr("#"); break; - case DATE: ret = tr("Date"); break; - case RATING: ret = UTF8_BLACKSTAR; break; - case DEPTH: ret = (get_units()->length == units::METERS) ? tr("m") : tr("ft"); break; - case DURATION: ret = tr("min"); break; - case TEMPERATURE: ret = QString("%1%2").arg(UTF8_DEGREE).arg((get_units()->temperature == units::CELSIUS) ? "C" : "F"); break; - case TOTALWEIGHT: ret = (get_units()->weight == units::KG) ? tr("kg") : tr("lbs"); break; - case SUIT: ret = tr("Suit"); break; - case CYLINDER: ret = tr("Cyl"); break; - case NITROX: ret = QString("O%1%").arg(UTF8_SUBSCRIPT_2); break; - case SAC: ret = tr("SAC"); break; - case OTU: ret = tr("OTU"); break; - case MAXCNS: ret = tr("maxCNS"); break; - case LOCATION: ret = tr("Location"); break; - } - break; + return QVariant(); +} + +TreeModel::TreeModel(QObject* parent): QAbstractItemModel(parent) +{ + rootItem = new TreeItem(); +} + +TreeModel::~TreeModel() +{ + delete rootItem; +} + +QVariant TreeModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::FontRole) { + return defaultModelFont(); } - return ret; + TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); + + return item->data(index.column(), role); } -struct TripItem : public TreeItemDT { +QModelIndex TreeModel::index(int row, int column, const QModelIndex& parent) +const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeItem* parentItem = (!parent.isValid()) ? rootItem : static_cast<TreeItem*>(parent.internalPointer()); + + TreeItem* childItem = parentItem->children[row]; + + return (childItem) ? createIndex(row, column, childItem) : QModelIndex(); +} + +QModelIndex TreeModel::parent(const QModelIndex& index) const +{ + if (!index.isValid()) + return QModelIndex(); + + TreeItem* childItem = static_cast<TreeItem*>(index.internalPointer()); + TreeItem* parentItem = childItem->parent; + + if (parentItem == rootItem || !parentItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int TreeModel::rowCount(const QModelIndex& parent) const +{ + TreeItem* parentItem; + + if (!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast<TreeItem*>(parent.internalPointer()); + + int amount = parentItem->children.count(); + + return amount; +} + +int TreeModel::columnCount(const QModelIndex& parent) const +{ + return columns; +} + +/*################################################################ + * + * Implementation of the Dive List. + * + * ############################################################### */ +struct TripItem : public TreeItem { virtual QVariant data(int column, int role) const; dive_trip_t* trip; }; @@ -826,12 +883,12 @@ QVariant TripItem::data(int column, int role) const { QVariant ret; - if (role == SORT_ROLE) + if (role == DiveTripModel::SORT_ROLE) return (qulonglong)trip->when; if (role == Qt::DisplayRole) { switch (column) { - case NR: + case DiveTripModel::NR: ret = QString(trip->location) + ", " + QString(get_trip_date_string(trip->when, trip->nrdives)); break; } @@ -840,7 +897,10 @@ QVariant TripItem::data(int column, int role) const return ret; } -struct DiveItem : public TreeItemDT { +struct DiveItem : public TreeItem { + enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, + SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; + virtual QVariant data(int column, int role) const; struct dive* dive; @@ -876,7 +936,7 @@ QVariant DiveItem::data(int column, int role) const break; } break; - case SORT_ROLE: + case DiveTripModel::SORT_ROLE: switch (column) { case NR: retVal = (qulonglong) dive->when; break; case DATE: retVal = (qulonglong) dive->when; break; @@ -913,10 +973,10 @@ QVariant DiveItem::data(int column, int role) const break; } - if (role == STAR_ROLE) + if (role == DiveTripModel::STAR_ROLE) retVal = dive->rating; - if (role == DIVE_ROLE) + if (role == DiveTripModel::DIVE_ROLE) retVal = QVariant::fromValue<void*>(dive); return retVal; @@ -1001,37 +1061,9 @@ int DiveItem::weight() const return tw.grams; } - -DiveTripModel::DiveTripModel(QObject* parent) : - QAbstractItemModel(parent) -{ - rootItem = new TreeItemDT(); -} - -DiveTripModel::~DiveTripModel() +DiveTripModel::DiveTripModel(QObject* parent): TreeModel(parent) { - delete rootItem; -} - -int DiveTripModel::columnCount(const QModelIndex& parent) const -{ - if (parent.isValid()) - return static_cast<TreeItemDT*>(parent.internalPointer())->columnCount(); - else - return rootItem->columnCount(); -} - -QVariant DiveTripModel::data(const QModelIndex& index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (role == Qt::FontRole) { - return defaultModelFont(); - } - TreeItemDT* item = static_cast<TreeItemDT*>(index.internalPointer()); - - return item->data(index.column(), role); + columns = COLUMNS; } Qt::ItemFlags DiveTripModel::flags(const QModelIndex& index) const @@ -1042,59 +1074,35 @@ Qt::ItemFlags DiveTripModel::flags(const QModelIndex& index) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation, - int role) const +QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - return rootItem->data(section, role); + QVariant ret; + if (orientation == Qt::Vertical) + return ret; switch(role){ case Qt::FontRole : - return defaultModelFont(); + ret = defaultModelFont(); break; + case Qt::DisplayRole : + switch (section) { + case NR: ret = tr("#"); break; + case DATE: ret = tr("Date"); break; + case RATING: ret = UTF8_BLACKSTAR; break; + case DEPTH: ret = (get_units()->length == units::METERS) ? tr("m") : tr("ft"); break; + case DURATION: ret = tr("min"); break; + case TEMPERATURE:ret = QString("%1%2").arg(UTF8_DEGREE).arg((get_units()->temperature == units::CELSIUS) ? "C" : "F"); break; + case TOTALWEIGHT:ret = (get_units()->weight == units::KG) ? tr("kg") : tr("lbs"); break; + case SUIT: ret = tr("Suit"); break; + case CYLINDER: ret = tr("Cyl"); break; + case NITROX: ret = QString("O%1%").arg(UTF8_SUBSCRIPT_2); break; + case SAC: ret = tr("SAC"); break; + case OTU: ret = tr("OTU"); break; + case MAXCNS: ret = tr("maxCNS"); break; + case LOCATION: ret = tr("Location"); break; + }break; } - return QVariant(); -} - -QModelIndex DiveTripModel::index(int row, int column, const QModelIndex& parent) -const -{ - if (!hasIndex(row, column, parent)) - return QModelIndex(); - - TreeItemDT* parentItem = (!parent.isValid()) ? rootItem : static_cast<TreeItemDT*>(parent.internalPointer()); - - TreeItemDT* childItem = parentItem->children[row]; - - return (childItem) ? createIndex(row, column, childItem) : QModelIndex(); -} - -QModelIndex DiveTripModel::parent(const QModelIndex& index) const -{ - if (!index.isValid()) - return QModelIndex(); - - TreeItemDT* childItem = static_cast<TreeItemDT*>(index.internalPointer()); - TreeItemDT* parentItem = childItem->parent; - - if (parentItem == rootItem || !parentItem) - return QModelIndex(); - - return createIndex(parentItem->row(), 0, parentItem); -} - -int DiveTripModel::rowCount(const QModelIndex& parent) const -{ - TreeItemDT* parentItem; - - if (!parent.isValid()) - parentItem = rootItem; - else - parentItem = static_cast<TreeItemDT*>(parent.internalPointer()); - - int amount = parentItem->children.count(); - - return amount; + return ret; } void DiveTripModel::setupModelData() diff --git a/qt-ui/models.h b/qt-ui/models.h index b61c79cd6..67e7e3b98 100644 --- a/qt-ui/models.h +++ b/qt-ui/models.h @@ -123,51 +123,54 @@ private: * */ -struct TreeItemDT { +struct TreeItem { Q_DECLARE_TR_FUNCTIONS (TreeItemDT); public: - enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, - SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; - - enum ExtraRoles{STAR_ROLE = Qt::UserRole + 1, DIVE_ROLE, SORT_ROLE}; - - virtual ~TreeItemDT(); - int columnCount() const { - return COLUMNS; - }; + virtual ~TreeItem(); virtual QVariant data (int column, int role) const; int row() const; - QList<TreeItemDT *> children; - TreeItemDT *parent; + QList<TreeItem*> children; + TreeItem *parent; }; struct TripItem; -class DiveTripModel : public QAbstractItemModel +class TreeModel : public QAbstractItemModel { Q_OBJECT public: - enum Layout{TREE, LIST, CURRENT}; + TreeModel(QObject *parent = 0); + virtual ~TreeModel(); - DiveTripModel(QObject *parent = 0); - ~DiveTripModel(); - - /*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const; - /*reimp*/ QVariant data(const QModelIndex &index, int role) const; - /*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const; /*reimp*/ int columnCount(const QModelIndex &parent = QModelIndex()) const; /*reimp*/ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; /*reimp*/ QModelIndex parent(const QModelIndex &child) const; +protected: + int columns; + TreeItem *rootItem; +}; + +class DiveTripModel : public TreeModel { +public: + enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, + SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; + + enum ExtraRoles{STAR_ROLE = Qt::UserRole + 1, DIVE_ROLE, SORT_ROLE}; + enum Layout{TREE, LIST, CURRENT}; + + Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + DiveTripModel(QObject* parent = 0); Layout layout() const; void setLayout(Layout layout); + private: void setupModelData(); - - TreeItemDT *rootItem; QMap<dive_trip_t*, TripItem*> trips; Layout currentLayout; }; @@ -185,12 +188,12 @@ public: virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); void update(); - + public slots: void remove(const QModelIndex& index); private: int numRows; - + }; #endif |