Added Support for the Trips and Dives on the DiveList model.

Now the list and dives will work in the same way that the GTK
version does. The code got changed heavly because the old one
was just looking at the dives and didn't worked like a tree.

small adaptations on the list view and model delegates because
of the changes done on this model.

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
This commit is contained in:
Tomaz Canabrava 2013-05-01 23:51:34 -03:00
parent 0be521bb25
commit 764a863082
4 changed files with 285 additions and 217 deletions

View file

@ -11,5 +11,5 @@
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent)
{
setUniformRowHeights(true);
setItemDelegateForColumn(DiveTripModel::RATING, new StarWidgetsDelegate());
setItemDelegateForColumn(TreeItemDT::RATING, new StarWidgetsDelegate());
}

View file

@ -14,7 +14,13 @@ 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 (!value.isValid()){
return;
}
int rating = value.toInt();
if(option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());

View file

@ -5,7 +5,8 @@
*
*/
#include "models.h"
#include <QtDebug>
#include <QCoreApplication>
#include <QDebug>
extern struct tank_info tank_info[100];
@ -289,59 +290,162 @@ void TankInfoModel::update()
* QObject.
*
*/
class DiveItem
TreeItemDT::~TreeItemDT()
{
public:
DiveItem(): dive(NULL), parentItem(NULL) {}
DiveItem(struct dive *d, DiveItem *parent = NULL);
~DiveItem() { qDeleteAll(childlist); }
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; }
int diveWeight() const
{
weight_t tw = { total_weight(dive) };
return tw.grams;
qDeleteAll(childs);
}
int diveRating() const { return dive->rating; }
int TreeItemDT::row() const
{
if (parent)
return parent->childs.indexOf(const_cast<TreeItemDT*>(this));
return 0;
}
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;
}
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;
}
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; }
int weight() const;
void addChild(DiveItem* item) {
item->parentItem = this;
childlist.push_back(item);
} /* parent = self */
private:
struct dive *dive;
DiveItem *parentItem;
QList <DiveItem*> childlist;
};
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
@ -361,7 +465,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;
@ -405,215 +508,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
{
if (!index.isValid())
return QVariant();
DiveItem *item = static_cast<DiveItem*>(index.internalPointer());
if (role != Qt::DisplayRole)
return QVariant();
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;
TreeItemDT* item = static_cast<TreeItemDT*>(index.internalPointer());
return item->data(index.column(), role);
}
QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation, int role) const
Qt::ItemFlags DiveTripModel::flags(const QModelIndex& index) const
{
QVariant ret;
if (orientation != Qt::Horizontal)
return ret;
if (!index.isValid())
return 0;
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 Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section, role);
return QVariant();
}
return ret;
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->childs[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)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int DiveTripModel::rowCount(const QModelIndex& parent) const
{
/* only allow kids in column 0 */
if (parent.isValid() && parent.column() > 0)
TreeItemDT* parentItem;
if (parent.column() > 0) {
return 0;
DiveItem *item = itemForIndex(parent);
return item ? item->children().count() : 0;
}
int DiveTripModel::columnCount(const QModelIndex &parent) const
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItemDT*>(parent.internalPointer());
return parentItem->childs.count();
}
void DiveTripModel::setupModelData()
{
return parent.isValid() && parent.column() != 0 ? 0 : COLUMNS;
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;
}
QModelIndex DiveTripModel::index(int row, int column, const QModelIndex &parent) const
{
if (!rootItem || row < 0 || column < 0 || column >= COLUMNS ||
(parent.isValid() && parent.column() != 0))
return QModelIndex();
DiveItem *parentItem = itemForIndex(parent);
Q_ASSERT(parentItem);
if (DiveItem *item = parentItem->children().at(row))
return createIndex(row, column, item);
return QModelIndex();
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;
}
QModelIndex DiveTripModel::parent(const QModelIndex &childIndex) const
{
if (!childIndex.isValid())
return QModelIndex();
DiveItem *child = static_cast<DiveItem*>(childIndex.internalPointer());
DiveItem *parent = child->parent();
if (parent == rootItem)
return QModelIndex();
return createIndex(parent->children().indexOf(child), 0, parent);
TripItem* tripItem = trips[trip];
tripItem->childs.push_back(diveItem);
}
DiveItem* DiveTripModel::itemForIndex(const QModelIndex &index) const
{
if (index.isValid()) {
DiveItem *item = static_cast<DiveItem*>(index.internalPointer());
return item;
}
return rootItem;
}

View file

@ -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 {
@ -74,25 +77,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