Patch - Make the DiveListModel works correctly with Dives and Trips.
Dirk Hohndel
dirk at hohndel.org
Wed May 1 22:07:36 PDT 2013
Thank you, Tomaz.
One request - please don't do the merges. I'd much rather pull from your
branch just as you were working on it and do the merge myself. That way
I see where things may have conflicted, etc.
It looks like the merge was fine, but in the future I'd prefer to do
them myself.
The code looked really good. I did a few minor cleanups - because you
had already done the merge I decided not to edit your commit but instead
to add a small cleanup commit - the advantage is that you can see my
changes by just doing
git show 6b7797140bcf706b1a0a2eeb70438d8572372b9f
The majority of them are one of two items:
I really don't like having lines start with a colon - neither for
inheritance nor for ternary operators.
The other one is curly braces for if statements when there is only one
statement:
if (some condition) {
something;
}
You can just do
if (some condition)
something;
But we DON'T do this if it's unbalanced:
if (some condition) {
something;
} else {
one thing;
another thing;
}
I realize that these are ridiculously nitpicky things. So let's repeat -
the code that you pushed looked really good and was very readable.
The grammar nerd in me dies to know what made you name a member
"childs" :-)
Yes - the completely empty trip lines look odd, but I'm sure you'll be
sending an update for that, soon...
/D
On Thu, 2013-05-02 at 00:02 -0300, Tomaz Canabrava wrote:
> â subsurface git:(DiveModel) â git request-pull
> 00d85313827af88ae5f35b239 origin -p
> The following changes since commit
> 00d85313827af88ae5f35b2391ffa6964e81da49:
>
> Fix a couple of small problems in add weightsystem (2013-05-01
> 16:23:20 -0700)
>
> are available in the git repository at:
>
> https://github.com/tcanabrava/subsurface.git DiveModel
>
> for you to fetch changes up to
> e5ad47e459af1d937d26782ce8308dbd67ecec4b:
>
> Merge branch 'Qt' into RenderStarsOnTable (2013-05-01 23:54:38
> -0300)
>
> ----------------------------------------------------------------
>
> Tomaz Canabrava (2):
> Added Support for the Trips and Dives on the DiveList model.
> Merge branch 'Qt' into RenderStarsOnTable
>
> qt-ui/divelistview.cpp | 2 +-
> qt-ui/modeldelegates.cpp | 12 ++-
> qt-ui/models.cpp | 445
> +++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------
> qt-ui/models.h | 41 +++++++--
> 4 files changed, 284 insertions(+), 216 deletions(-)
>
> diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
> index fb19a70..45b6cf4 100644
> --- a/qt-ui/divelistview.cpp
> +++ b/qt-ui/divelistview.cpp
> @@ -11,5 +11,5 @@
> DiveListView::DiveListView(QWidget *parent) : QTreeView(parent)
> {
> setUniformRowHeights(true);
> - setItemDelegateForColumn(DiveTripModel::RATING, new
> StarWidgetsDelegate());
> + setItemDelegateForColumn(TreeItemDT::RATING, new
> StarWidgetsDelegate());
> }
> diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp
> index 1ac2f46..00f1009 100644
> --- a/qt-ui/modeldelegates.cpp
> +++ b/qt-ui/modeldelegates.cpp
> @@ -14,10 +14,16 @@ void StarWidgetsDelegate::paint(QPainter* painter,
> const QStyleOptionViewItem& o
> return;
> }
>
> - int rating = index.model()->data(index,
> Qt::DisplayRole).toInt();
> + QVariant value = index.model()->data(index, Qt::DisplayRole);
>
> - if (option.state & QStyle::State_Selected)
> - painter->fillRect(option.rect, option.palette.highlight());
> + if (!value.isValid()){
> + return;
> + }
> +
> + int rating = value.toInt();
> +
> + if(option.state & QStyle::State_Selected)
> + painter->fillRect(option.rect,
> option.palette.highlight());
>
> painter->save();
> painter->setRenderHint(QPainter::Antialiasing, true);
> diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
> index f1bb8d1..6d9bbad 100644
> --- a/qt-ui/models.cpp
> +++ b/qt-ui/models.cpp
> @@ -5,7 +5,8 @@
> *
> */
> #include "models.h"
> -#include <QtDebug>
> +#include <QCoreApplication>
> +#include <QDebug>
>
> extern struct tank_info tank_info[100];
>
> @@ -330,59 +331,162 @@ void TankInfoModel::update()
> * QObject.
> *
> */
> -class DiveItem
> +
> +TreeItemDT::~TreeItemDT()
> {
> -public:
> - DiveItem(): dive(NULL), parentItem(NULL) {}
> + qDeleteAll(childs);
> +}
>
> - DiveItem(struct dive *d, DiveItem *parent = NULL);
> +int TreeItemDT::row() const
> +{
> + if (parent)
> + return
> parent->childs.indexOf(const_cast<TreeItemDT*>(this));
>
> - ~DiveItem() { qDeleteAll(childlist); }
> + return 0;
> +}
>
> - int diveNumber() const { return dive->number; }
> - const QString diveDateTime() const { return
> get_dive_date_string(dive->when); }
> - int diveDuration() const { return dive->duration.seconds; }
> - int diveDepth() const { return dive->maxdepth.mm; }
> - int diveSac() const { return dive->sac; }
> - int diveOtu() const { return dive->otu; }
> - int diveMaxcns() const { return dive->maxcns; }
> +QVariant TreeItemDT::data(int column, int role) const
> +{
> + QVariant ret;
> + 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;
> + }
> + return ret;
> +}
>
> - int diveWeight() const
> - {
> - weight_t tw = { total_weight(dive) };
> - return tw.grams;
> +struct TripItem : public TreeItemDT {
> + virtual QVariant data(int column, int role) const;
> + dive_trip_t* trip;
> +};
> +
> +QVariant TripItem::data(int column, int role) const
> +{
> + QVariant ret;
> +
> + if (column != LOCATION) {
> + return ret;
> }
>
> - int diveRating() const { return dive->rating; }
> + switch (role) {
> + case Qt::DisplayRole:
> + ret = QString(trip->location);
> + }
> +
> + return ret;
> +}
> +
> +struct DiveItem : public TreeItemDT {
> + virtual QVariant data(int column, int role) const;
> + struct dive* dive;
>
> QString displayDuration() const;
> QString displayDepth() const;
> QString displayTemperature() const;
> QString displayWeight() const;
> QString displaySac() const;
> - const QString diveLocation() const { return dive->location; }
> - const QString diveSuit() const { return dive->suit; }
> - DiveItem *parent() const { return parentItem; }
> - const QList<DiveItem *>& children() const { return
> childlist; }
> -
> - void addChild(DiveItem* item) {
> - item->parentItem = this;
> - childlist.push_back(item);
> - } /* parent = self */
> -
> -private:
> - struct dive *dive;
> - DiveItem *parentItem;
> - QList <DiveItem*> childlist;
> -};
> + int weight() const;
>
> +};
>
> -DiveItem::DiveItem(struct dive *d, DiveItem *p):
> - dive(d),
> - parentItem(p)
> +QVariant DiveItem::data(int column, int role) const
> {
> - if (parentItem)
> - parentItem->addChild(this);
> + QVariant retVal;
> +
> + if (role == Qt::TextAlignmentRole) {
> + switch (column) {
> + case DATE: /* fall through */
> + case SUIT: /* fall through */
> + case LOCATION:
> + retVal = Qt::AlignLeft;
> + break;
> + default:
> + retVal = Qt::AlignRight;
> + break;
> + }
> + }
> +
> + if (role == Qt::DisplayRole) {
> + switch (column) {
> + case NR:
> + retVal = dive->number;
> + break;
> + case DATE:
> + retVal =
> QString(get_dive_date_string(dive->when));
> + break;
> + case DEPTH:
> + retVal = displayDepth();
> + break;
> + case DURATION:
> + retVal = displayDuration();
> + break;
> + case TEMPERATURE:
> + retVal = displayTemperature();
> + break;
> + case TOTALWEIGHT:
> + retVal = displayWeight();
> + break;
> + case SUIT:
> + retVal = QString(dive->suit);
> + break;
> + case SAC:
> + retVal = displaySac();
> + break;
> + case OTU:
> + retVal = dive->otu;
> + break;
> + case MAXCNS:
> + retVal = dive->maxcns;
> + break;
> + case LOCATION:
> + retVal = QString(dive->location);
> + break;
> + case RATING:
> + retVal = dive->rating;
> + break;
> + }
> + }
> + return retVal;
> }
>
> QString DiveItem::displayDepth() const
> @@ -402,7 +506,6 @@ QString DiveItem::displayDepth() const
> QString DiveItem::displayDuration() const
> {
> int hrs, mins, secs;
> -
> secs = dive->duration.seconds % 60;
> mins = dive->duration.seconds / 60;
> hrs = mins / 60;
> @@ -446,215 +549,147 @@ QString DiveItem::displayWeight() const
> QString str;
>
> if (get_units()->weight == units::KG) {
> - int gr = diveWeight() % 1000;
> - int kg = diveWeight() / 1000;
> + int gr = weight() % 1000;
> + int kg = weight() / 1000;
> str = QString("%1.%2").arg(kg).arg((unsigned)(gr +
> 500) / 100);
> } else {
> - str = QString("%
> 1").arg((unsigned)(grams_to_lbs(diveWeight()) + 0.5));
> + str = QString("%
> 1").arg((unsigned)(grams_to_lbs(weight()) + 0.5));
> }
> +
> return str;
> }
>
> -DiveTripModel::DiveTripModel(QObject *parent) :
> QAbstractItemModel(parent)
> +int DiveItem::weight() const
> {
> - rootItem = new DiveItem;
> - int i;
> - struct dive *d;
> -
> - for_each_dive(i, d) {
> - new DiveItem(d, rootItem);
> - }
> + weight_t tw = { total_weight(dive) };
> + return tw.grams;
> }
>
>
> -Qt::ItemFlags DiveTripModel::flags(const QModelIndex &index) const
> +DiveTripModel::DiveTripModel(QObject* parent)
> + : QAbstractItemModel(parent)
> {
> - Qt::ItemFlags diveFlags = QAbstractItemModel::flags(index);
> - if (index.isValid()) {
> - diveFlags |= Qt::ItemIsSelectable|Qt::ItemIsEnabled;
> - }
> - return diveFlags;
> + rootItem = new TreeItemDT();
> + setupModelData();
> +}
> +
> +DiveTripModel::~DiveTripModel()
> +{
> + 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
> +QVariant DiveTripModel::data(const QModelIndex& index, int role)
> const
> {
> if (!index.isValid())
> return QVariant();
>
> - DiveItem *item =
> static_cast<DiveItem*>(index.internalPointer());
> -
> - QVariant retVal;
> - if (role == Qt::TextAlignmentRole) {
> - switch (index.column()) {
> - case DATE: /* fall through */
> - case SUIT: /* fall through */
> - case LOCATION:
> - retVal = Qt::AlignLeft;
> - break;
> - default:
> - retVal = Qt::AlignRight;
> - break;
> - }
> - }
> - if (role == Qt::DisplayRole) {
> - switch (index.column()) {
> - case NR:
> - retVal = item->diveNumber();
> - break;
> - case DATE:
> - retVal = item->diveDateTime();
> - break;
> - case DEPTH:
> - retVal = item->displayDepth();
> - break;
> - case DURATION:
> - retVal = item->displayDuration();
> - break;
> - case TEMPERATURE:
> - retVal = item->displayTemperature();
> - break;
> - case TOTALWEIGHT:
> - retVal = item->displayWeight();
> - break;
> - case SUIT:
> - retVal = item->diveSuit();
> - break;
> - case SAC:
> - retVal = item->displaySac();
> - break;
> - case OTU:
> - retVal = item->diveOtu();
> - break;
> - case MAXCNS:
> - retVal = item->diveMaxcns();
> - break;
> - case LOCATION:
> - retVal = item->diveLocation();
> - break;
> - case RATING:
> - retVal = item->diveRating();
> - break;
> - }
> - }
> - return retVal;
> -}
> + if (role != Qt::DisplayRole)
> + return QVariant();
>
> + TreeItemDT* item =
> static_cast<TreeItemDT*>(index.internalPointer());
>
> -QVariant DiveTripModel::headerData(int section, Qt::Orientation
> orientation, int role) const
> -{
> - QVariant ret;
> - if (orientation != Qt::Horizontal)
> - return ret;
> -
> - if (role == Qt::DisplayRole) {
> - switch(section) {
> - case NR:
> - ret = tr("#");
> - break;
> - case DATE:
> - ret = tr("Date");
> - break;
> - case RATING:
> - ret = UTF8_BLACKSTAR;
> - break;
> - case DEPTH:
> - if (get_units()->length ==
> units::METERS)
> - ret = tr("m");
> - else
> - ret = tr("ft");
> - break;
> - case DURATION:
> - ret = tr("min");
> - break;
> - case TEMPERATURE:
> - if (get_units()->temperature ==
> units::CELSIUS)
> - ret = QString("%1%
> 2").arg(UTF8_DEGREE).arg("C");
> - else
> - ret = QString("%1%
> 2").arg(UTF8_DEGREE).arg("F");
> - break;
> - case TOTALWEIGHT:
> - if (get_units()->weight == units::KG)
> - ret = tr("kg");
> - else
> - ret = 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;
> - }
> - }
> - return ret;
> + return item->data(index.column(), role);
> }
>
> -int DiveTripModel::rowCount(const QModelIndex &parent) const
> +Qt::ItemFlags DiveTripModel::flags(const QModelIndex& index) const
> {
> - /* only allow kids in column 0 */
> - if (parent.isValid() && parent.column() > 0)
> + if (!index.isValid())
> return 0;
> - DiveItem *item = itemForIndex(parent);
> - return item ? item->children().count() : 0;
> +
> + return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
> }
>
> -int DiveTripModel::columnCount(const QModelIndex &parent) const
> +QVariant DiveTripModel::headerData(int section, Qt::Orientation
> orientation,
> + int role) const
> {
> - return parent.isValid() && parent.column() != 0 ? 0 : COLUMNS;
> -}
> + if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
> + return rootItem->data(section, role);
>
> + return QVariant();
> +}
>
> -QModelIndex DiveTripModel::index(int row, int column, const
> QModelIndex &parent) const
> +QModelIndex DiveTripModel::index(int row, int column, const
> QModelIndex& parent)
> +const
> {
> -
> - if (!rootItem || row < 0 || column < 0 || column >= COLUMNS ||
> - (parent.isValid() && parent.column() != 0))
> + if (!hasIndex(row, column, parent))
> return QModelIndex();
>
> - DiveItem *parentItem = itemForIndex(parent);
> - Q_ASSERT(parentItem);
> - if (DiveItem *item = parentItem->children().at(row))
> - return createIndex(row, column, item);
> - return QModelIndex();
> -}
> + TreeItemDT* parentItem = (!parent.isValid()) ? rootItem
> + :
> static_cast<TreeItemDT*>(parent.internalPointer());
> +
> + TreeItemDT* childItem = parentItem->childs[row];
>
> + return (childItem) ? createIndex(row, column, childItem)
> + : QModelIndex();
> +}
>
> -QModelIndex DiveTripModel::parent(const QModelIndex &childIndex)
> const
> +QModelIndex DiveTripModel::parent(const QModelIndex& index) const
> {
> - if (!childIndex.isValid())
> + if (!index.isValid())
> return QModelIndex();
>
> - DiveItem *child =
> static_cast<DiveItem*>(childIndex.internalPointer());
> - DiveItem *parent = child->parent();
> + TreeItemDT* childItem =
> static_cast<TreeItemDT*>(index.internalPointer());
> + TreeItemDT* parentItem = childItem->parent;
>
> - if (parent == rootItem)
> + if (parentItem == rootItem)
> return QModelIndex();
>
> - return createIndex(parent->children().indexOf(child), 0,
> parent);
> + return createIndex(parentItem->row(), 0, parentItem);
> }
>
> +int DiveTripModel::rowCount(const QModelIndex& parent) const
> +{
> + TreeItemDT* parentItem;
> +
> + if (parent.column() > 0) {
> + return 0;
> + }
> +
> + if (!parent.isValid())
> + parentItem = rootItem;
> +
> + else
> + parentItem =
> static_cast<TreeItemDT*>(parent.internalPointer());
> +
> + return parentItem->childs.count();
> +}
>
> -DiveItem* DiveTripModel::itemForIndex(const QModelIndex &index) const
> +void DiveTripModel::setupModelData()
> {
> - if (index.isValid()) {
> - DiveItem *item =
> static_cast<DiveItem*>(index.internalPointer());
> - return item;
> + int i = dive_table.nr;
> +
> + while (--i >= 0) {
> + struct dive* dive = get_dive(i);
> + dive_trip_t* trip = dive->divetrip;
> +
> + DiveItem* diveItem = new DiveItem();
> + diveItem->dive = dive;
> +
> + if (!trip) {
> + diveItem->parent = rootItem;
> + rootItem->childs.push_back(diveItem);
> + continue;
> + }
> +
> + if (!trips.keys().contains(trip)) {
> + TripItem* tripItem = new TripItem();
> + tripItem->trip = trip;
> + tripItem->parent = rootItem;
> + tripItem->childs.push_back(diveItem);
> + trips[trip] = tripItem;
> + rootItem->childs.push_back(tripItem);
> + continue;
> + }
> +
> + TripItem* tripItem = trips[trip];
> + tripItem->childs.push_back(diveItem);
> }
> - return rootItem;
> }
> diff --git a/qt-ui/models.h b/qt-ui/models.h
> index 9a4602f..52a3498 100644
> --- a/qt-ui/models.h
> +++ b/qt-ui/models.h
> @@ -8,8 +8,11 @@
> #define MODELS_H
>
> #include <QAbstractTableModel>
> +#include <QCoreApplication>
> +
> #include "../dive.h"
> #include "../divelist.h"
> +
> /* Encapsulates the tank_info global variable
> * to show on Qt`s Model View System.*/
> class TankInfoModel : public QAbstractTableModel {
> @@ -75,25 +78,49 @@ private:
> /*! An AbstractItemModel for recording dive trip information such as
> a list of dives.
> *
> */
> -class DiveItem;
> -class DiveTripModel : public QAbstractItemModel
> -{
> +
> +
> +
> +struct TreeItemDT {
> + Q_DECLARE_TR_FUNCTIONS ( TreeItemDT );
> public:
> enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE,
> TOTALWEIGHT, SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION,
> COLUMNS };
> + virtual ~TreeItemDT();
> + int columnCount() const {
> + return COLUMNS;
> + };
> +
> + virtual QVariant data ( int column, int role ) const;
> + int row() const;
> + QList<TreeItemDT *> childs;
> + TreeItemDT *parent;
> +};
>
> +
> +struct TripItem;
> +
> +class DiveTripModel : public QAbstractItemModel
> +{
> + Q_OBJECT
> +
> +public:
> 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) const;
> - /*reimp*/ int rowCount(const QModelIndex &parent) const;
> + /*reimp*/ QVariant headerData(int section, Qt::Orientation
> orientation, int role = Qt::DisplayRole) 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;
>
> +
> private:
> - DiveItem *itemForIndex(const QModelIndex& index) const;
> - DiveItem *rootItem;
> + void setupModelData();
> +
> + TreeItemDT *rootItem;
> + QMap<dive_trip_t*, TripItem*> trips;
> };
>
> #endif
>
>
> _______________________________________________
> subsurface mailing list
> subsurface at hohndel.org
> http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface
More information about the subsurface
mailing list