Move the models to its own folder

This is an attempt to help share code between the desktop version of
Subsurface and the mobile version.
More code will be moved around and the models will be split in a way that
will help recompile times and also creation of different interfaces for
different form-factors.

Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Tomaz Canabrava 2015-05-28 14:40:07 -03:00 committed by Dirk Hohndel
parent 29e7459d6b
commit 338c0f22aa
7 changed files with 19 additions and 4 deletions

View file

@ -0,0 +1,69 @@
#include "completionmodels.h"
#include "dive.h"
#include "mainwindow.h"
#define CREATE_UPDATE_METHOD(Class, diveStructMember) \
void Class::updateModel() \
{ \
QStringList list; \
struct dive *dive; \
int i = 0; \
for_each_dive (i, dive) \
{ \
QString buddy(dive->diveStructMember); \
if (!list.contains(buddy)) { \
list.append(buddy); \
} \
} \
std::sort(list.begin(), list.end()); \
setStringList(list); \
}
#define CREATE_CSV_UPDATE_METHOD(Class, diveStructMember) \
void Class::updateModel() \
{ \
QSet<QString> set; \
struct dive *dive; \
int i = 0; \
for_each_dive (i, dive) \
{ \
QString buddy(dive->diveStructMember); \
foreach (const QString &value, buddy.split(",", QString::SkipEmptyParts)) \
{ \
set.insert(value.trimmed()); \
} \
} \
QStringList setList = set.toList(); \
std::sort(setList.begin(), setList.end()); \
setStringList(setList); \
}
CREATE_CSV_UPDATE_METHOD(BuddyCompletionModel, buddy);
CREATE_CSV_UPDATE_METHOD(DiveMasterCompletionModel, divemaster);
CREATE_UPDATE_METHOD(SuitCompletionModel, suit);
void LocationCompletionModel::updateModel()
{
QStringList list;
struct dive_site *ds;
int i = 0;
for_each_dive_site(i, ds) {
if (!list.contains(ds->name))
list.append(ds->name);
}
std::sort(list.begin(), list.end());
setStringList(list);
}
void TagCompletionModel::updateModel()
{
if (g_tag_list == NULL)
return;
QStringList list;
struct tag_entry *current_tag_entry = g_tag_list->next;
while (current_tag_entry != NULL) {
list.append(QString(current_tag_entry->tag->name));
current_tag_entry = current_tag_entry->next;
}
setStringList(list);
}

View file

@ -0,0 +1,36 @@
#ifndef COMPLETIONMODELS_H
#define COMPLETIONMODELS_H
#include <QStringListModel>
class BuddyCompletionModel : public QStringListModel {
Q_OBJECT
public:
void updateModel();
};
class DiveMasterCompletionModel : public QStringListModel {
Q_OBJECT
public:
void updateModel();
};
class LocationCompletionModel : public QStringListModel {
Q_OBJECT
public:
void updateModel();
};
class SuitCompletionModel : public QStringListModel {
Q_OBJECT
public:
void updateModel();
};
class TagCompletionModel : public QStringListModel {
Q_OBJECT
public:
void updateModel();
};
#endif // COMPLETIONMODELS_H

420
qt-models/filtermodels.cpp Normal file
View file

@ -0,0 +1,420 @@
#include "filtermodels.h"
#include "mainwindow.h"
#include "models.h"
#include "divelistview.h"
#include "display.h"
#define CREATE_INSTANCE_METHOD( CLASS ) \
CLASS *CLASS::instance() \
{ \
static CLASS *self = new CLASS(); \
return self; \
}
#define CREATE_MODEL_SET_DATA_METHOD( CLASS ) \
bool CLASS::setData(const QModelIndex &index, const QVariant &value, int role) \
{ \
if (role == Qt::CheckStateRole) { \
checkState[index.row()] = value.toBool(); \
anyChecked = false; \
for (int i = 0; i < rowCount(); i++) { \
if (checkState[i] == true) { \
anyChecked = true; \
break; \
} \
} \
dataChanged(index, index); \
return true; \
} \
return false; \
}
#define CREATE_CLEAR_FILTER_METHOD( CLASS ) \
void CLASS::clearFilter() \
{ \
memset(checkState, false, rowCount()); \
checkState[rowCount() - 1] = false; \
anyChecked = false; \
emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); \
}
#define CREATE_FLAGS_METHOD( CLASS ) \
Qt::ItemFlags CLASS::flags(const QModelIndex &index) const \
{ \
return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; \
}
#define CREATE_DATA_METHOD( CLASS, COUNTER_FUNCTION ) \
QVariant CLASS::data(const QModelIndex &index, int role) const \
{ \
if (role == Qt::CheckStateRole) { \
return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; \
} else if (role == Qt::DisplayRole) { \
QString value = stringList()[index.row()]; \
int count = COUNTER_FUNCTION((index.row() == rowCount() - 1) ? "" : value.toUtf8().data()); \
return value + QString(" (%1)").arg(count); \
} \
return QVariant(); \
}
#define CREATE_COMMON_METHODS_FOR_FILTER( CLASS, COUNTER_FUNCTION ) \
CREATE_FLAGS_METHOD( CLASS ); \
CREATE_CLEAR_FILTER_METHOD( CLASS ); \
CREATE_MODEL_SET_DATA_METHOD( CLASS ); \
CREATE_INSTANCE_METHOD( CLASS ); \
CREATE_DATA_METHOD( CLASS, COUNTER_FUNCTION )
CREATE_COMMON_METHODS_FOR_FILTER(TagFilterModel, count_dives_with_tag)
CREATE_COMMON_METHODS_FOR_FILTER(BuddyFilterModel, count_dives_with_person)
CREATE_COMMON_METHODS_FOR_FILTER(LocationFilterModel, count_dives_with_location)
CREATE_COMMON_METHODS_FOR_FILTER(SuitsFilterModel, count_dives_with_suit)
CREATE_INSTANCE_METHOD(MultiFilterSortModel)
SuitsFilterModel::SuitsFilterModel(QObject *parent) : QStringListModel(parent)
{
}
bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const
{
if (!anyChecked) {
return true;
}
// Checked means 'Show', Unchecked means 'Hide'.
QString suit(d->suit);
// only show empty suit dives if the user checked that.
if (suit.isEmpty()) {
if (rowCount() > 0)
return checkState[rowCount() - 1];
else
return true;
}
// there is a suit selected
QStringList suitList = stringList();
if (!suitList.isEmpty()) {
suitList.removeLast(); // remove the "Show Empty Suits";
for (int i = 0; i < rowCount(); i++) {
if (checkState[i] && (suit.indexOf(stringList()[i]) != -1)) {
return true;
}
}
}
return false;
}
void SuitsFilterModel::repopulate()
{
QStringList list;
struct dive *dive;
int i = 0;
for_each_dive (i, dive) {
QString suit(dive->suit);
if (!suit.isEmpty() && !list.contains(suit)) {
list.append(suit);
}
}
qSort(list);
list << tr("No suit set");
setStringList(list);
delete[] checkState;
checkState = new bool[list.count()];
memset(checkState, false, list.count());
checkState[list.count() - 1] = false;
anyChecked = false;
}
TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent)
{
}
void TagFilterModel::repopulate()
{
if (g_tag_list == NULL)
return;
QStringList list;
struct tag_entry *current_tag_entry = g_tag_list;
while (current_tag_entry != NULL) {
if (count_dives_with_tag(current_tag_entry->tag->name) > 0)
list.append(QString(current_tag_entry->tag->name));
current_tag_entry = current_tag_entry->next;
}
qSort(list);
list << tr("Empty tags");
setStringList(list);
delete[] checkState;
checkState = new bool[list.count()];
memset(checkState, false, list.count());
checkState[list.count() - 1] = false;
anyChecked = false;
}
bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const
{
// If there's nothing checked, this should show everything
if (!anyChecked) {
return true;
}
// Checked means 'Show', Unchecked means 'Hide'.
struct tag_entry *head = d->tag_list;
if (!head) { // last tag means "Show empty tags";
if (rowCount() > 0)
return checkState[rowCount() - 1];
else
return true;
}
// have at least one tag.
QStringList tagList = stringList();
if (!tagList.isEmpty()) {
tagList.removeLast(); // remove the "Show Empty Tags";
while (head) {
QString tagName(head->tag->name);
int index = tagList.indexOf(tagName);
if (checkState[index])
return true;
head = head->next;
}
}
return false;
}
BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent)
{
}
bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const
{
// If there's nothing checked, this should show everything
if (!anyChecked) {
return true;
}
// Checked means 'Show', Unchecked means 'Hide'.
QString diveBuddy(d->buddy);
QString divemaster(d->divemaster);
// only show empty buddie dives if the user checked that.
if (diveBuddy.isEmpty() && divemaster.isEmpty()) {
if (rowCount() > 0)
return checkState[rowCount() - 1];
else
return true;
}
// have at least one buddy
QStringList buddyList = stringList();
if (!buddyList.isEmpty()) {
buddyList.removeLast(); // remove the "Show Empty Tags";
for (int i = 0; i < rowCount(); i++) {
if (checkState[i] && (diveBuddy.indexOf(stringList()[i]) != -1 || divemaster.indexOf(stringList()[i]) != -1)) {
return true;
}
}
}
return false;
}
void BuddyFilterModel::repopulate()
{
QStringList list;
struct dive *dive;
int i = 0;
for_each_dive (i, dive) {
QString persons = QString(dive->buddy) + "," + QString(dive->divemaster);
Q_FOREACH (const QString &person, persons.split(',', QString::SkipEmptyParts)) {
// Remove any leading spaces
if (!list.contains(person.trimmed())) {
list.append(person.trimmed());
}
}
}
qSort(list);
list << tr("No buddies");
setStringList(list);
delete[] checkState;
checkState = new bool[list.count()];
memset(checkState, false, list.count());
checkState[list.count() - 1] = false;
anyChecked = false;
}
LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(parent)
{
}
bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const
{
if (!anyChecked) {
return true;
}
// Checked means 'Show', Unchecked means 'Hide'.
QString location(get_dive_location(d));
// only show empty location dives if the user checked that.
if (location.isEmpty()) {
if (rowCount() > 0)
return checkState[rowCount() - 1];
else
return true;
}
// there is a location selected
QStringList locationList = stringList();
if (!locationList.isEmpty()) {
locationList.removeLast(); // remove the "Show Empty Tags";
for (int i = 0; i < rowCount(); i++) {
if (checkState[i] && (location.indexOf(stringList()[i]) != -1)) {
return true;
}
}
}
return false;
}
void LocationFilterModel::repopulate()
{
QStringList list;
struct dive *dive;
int i = 0;
for_each_dive (i, dive) {
QString location(get_dive_location(dive));
if (!location.isEmpty() && !list.contains(location)) {
list.append(location);
}
}
qSort(list);
list << tr("No location set");
setStringList(list);
delete[] checkState;
checkState = new bool[list.count()];
memset(checkState, false, list.count());
checkState[list.count() - 1] = false;
anyChecked = false;
}
MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent), justCleared(false), curr_dive_site(NULL)
{
}
bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
bool shouldShow = true;
QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
QVariant diveVariant = sourceModel()->data(index0, DiveTripModel::DIVE_ROLE);
struct dive *d = (struct dive *)diveVariant.value<void *>();
if (curr_dive_site) {
if (!d) { // It's a trip, only show the ones that have dives to be shown.
bool showTrip = false;
for (int i = 0; i < sourceModel()->rowCount(index0); i++) {
QModelIndex child = sourceModel()->index(i, 0, index0);
d = (struct dive *) sourceModel()->data(child, DiveTripModel::DIVE_ROLE).value<void*>();
if ( d->dive_site_uuid == curr_dive_site->uuid )
showTrip = true; // do not shortcircuit the loop or the counts will be wrong
}
return showTrip;
}
return d->dive_site_uuid == curr_dive_site->uuid;
}
if (justCleared || models.isEmpty())
return true;
if (!d) { // It's a trip, only show the ones that have dives to be shown.
bool showTrip = false;
for (int i = 0; i < sourceModel()->rowCount(index0); i++) {
if (filterAcceptsRow(i, index0))
showTrip = true; // do not shortcircuit the loop or the counts will be wrong
}
return showTrip;
}
Q_FOREACH (MultiFilterInterface *model, models) {
if (!model->doFilter(d, index0, sourceModel()))
shouldShow = false;
}
filter_dive(d, shouldShow);
return shouldShow;
}
void MultiFilterSortModel::myInvalidate()
{
int i;
struct dive *d;
DiveListView *dlv = MainWindow::instance()->dive_list();
divesDisplayed = 0;
invalidate();
// first make sure the trips are no longer shown as selected
// (but without updating the selection state of the dives... this just cleans
// up an oddity in the filter handling)
// TODO: This should go internally to DiveList, to be triggered after a filter is due.
dlv->clearTripSelection();
// if we have no more selected dives, clean up the display - this later triggers us
// to pick one of the dives that are shown in the list as selected dive which is the
// natural behavior
if (amount_selected == 0) {
MainWindow::instance()->cleanUpEmpty();
} else {
// otherwise find the dives that should still be selected (the filter above unselected any
// dive that's no longer visible) and select them again
QList<int> curSelectedDives;
for_each_dive (i, d) {
if (d->selected)
curSelectedDives.append(get_divenr(d));
}
dlv->selectDives(curSelectedDives);
}
for_each_dive (i,d) {
if (!d->hidden_by_filter)
divesDisplayed++;
}
emit filterFinished();
if (curr_dive_site) {
dlv->expandAll();
}
}
void MultiFilterSortModel::addFilterModel(MultiFilterInterface *model)
{
QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel *>(model);
Q_ASSERT(itemModel);
models.append(model);
connect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate()));
}
void MultiFilterSortModel::removeFilterModel(MultiFilterInterface *model)
{
QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel *>(model);
Q_ASSERT(itemModel);
models.removeAll(model);
disconnect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate()));
}
void MultiFilterSortModel::clearFilter()
{
justCleared = true;
Q_FOREACH (MultiFilterInterface *iface, models) {
iface->clearFilter();
}
justCleared = false;
myInvalidate();
}
void MultiFilterSortModel::startFilterDiveSite(uint32_t uuid)
{
curr_dive_site = get_dive_site_by_uuid(uuid);
myInvalidate();
}
void MultiFilterSortModel::stopFilterDiveSite()
{
curr_dive_site = NULL;
myInvalidate();
}

109
qt-models/filtermodels.h Normal file
View file

@ -0,0 +1,109 @@
#ifndef FILTERMODELS_H
#define FILTERMODELS_H
#include <QStringListModel>
#include <QSortFilterProxyModel>
#include <stdint.h>
class MultiFilterInterface {
public:
MultiFilterInterface() : checkState(NULL), anyChecked(false) {}
virtual bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const = 0;
virtual void clearFilter() = 0;
bool *checkState;
bool anyChecked;
};
class TagFilterModel : public QStringListModel, public MultiFilterInterface {
Q_OBJECT
public:
static TagFilterModel *instance();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
void clearFilter();
public
slots:
void repopulate();
private:
explicit TagFilterModel(QObject *parent = 0);
};
class BuddyFilterModel : public QStringListModel, public MultiFilterInterface {
Q_OBJECT
public:
static BuddyFilterModel *instance();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
void clearFilter();
public
slots:
void repopulate();
private:
explicit BuddyFilterModel(QObject *parent = 0);
};
class LocationFilterModel : public QStringListModel, public MultiFilterInterface {
Q_OBJECT
public:
static LocationFilterModel *instance();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
void clearFilter();
public
slots:
void repopulate();
private:
explicit LocationFilterModel(QObject *parent = 0);
};
class SuitsFilterModel : public QStringListModel, public MultiFilterInterface {
Q_OBJECT
public:
static SuitsFilterModel *instance();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const;
void clearFilter();
public
slots:
void repopulate();
private:
explicit SuitsFilterModel(QObject *parent = 0);
};
class MultiFilterSortModel : public QSortFilterProxyModel {
Q_OBJECT
public:
static MultiFilterSortModel *instance();
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
void addFilterModel(MultiFilterInterface *model);
void removeFilterModel(MultiFilterInterface *model);
int divesDisplayed;
public
slots:
void myInvalidate();
void clearFilter();
void startFilterDiveSite(uint32_t uuid);
void stopFilterDiveSite();
signals:
void filterFinished();
private:
MultiFilterSortModel(QObject *parent = 0);
QList<MultiFilterInterface *> models;
bool justCleared;
struct dive_site *curr_dive_site;
};
#endif

2365
qt-models/models.cpp Normal file

File diff suppressed because it is too large Load diff

443
qt-models/models.h Normal file
View file

@ -0,0 +1,443 @@
/*
* models.h
*
* header file for the equipment models of Subsurface
*
*/
#ifndef MODELS_H
#define MODELS_H
#include <QAbstractTableModel>
#include <QCoreApplication>
#include <QStringList>
#include <QStringListModel>
#include <QSortFilterProxyModel>
#include "metrics.h"
#include "../dive.h"
#include "../divelist.h"
#include "../divecomputer.h"
// Encapsulates Boilerplate.
class CleanerTableModel : public QAbstractTableModel {
Q_OBJECT
public:
explicit CleanerTableModel(QObject *parent = 0);
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
protected:
void setHeaderDataStrings(const QStringList &headers);
private:
QStringList headers;
};
/* Encapsulates the tank_info global variable
* to show on Qt's Model View System.*/
class TankInfoModel : public CleanerTableModel {
Q_OBJECT
public:
static TankInfoModel *instance();
enum Column {
DESCRIPTION,
ML,
BAR
};
TankInfoModel();
/*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
/*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
const QString &biggerString() const;
void clear();
public
slots:
void update();
private:
int rows;
QString biggerEntry;
};
/* Encapsulate ws_info */
class WSInfoModel : public CleanerTableModel {
Q_OBJECT
public:
static WSInfoModel *instance();
enum Column {
DESCRIPTION,
GR
};
WSInfoModel();
/*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
/*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
const QString &biggerString() const;
void clear();
void update();
void updateInfo();
private:
int rows;
QString biggerEntry;
};
/* Retrieve the trash icon pixmap, common to most table models */
const QPixmap &trashIcon();
/* Encapsulation of the Cylinder Model, that presents the
* Current cylinders that are used on a dive. */
class CylindersModel : public CleanerTableModel {
Q_OBJECT
public:
enum Column {
REMOVE,
TYPE,
SIZE,
WORKINGPRESS,
START,
END,
O2,
HE,
DEPTH,
USE,
COLUMNS
};
explicit CylindersModel(QObject *parent = 0);
static CylindersModel *instance();
/*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const;
/*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void passInData(const QModelIndex &index, const QVariant &value);
void add();
void clear();
void updateDive();
void copyFromDive(struct dive *d);
cylinder_t *cylinderAt(const QModelIndex &index);
bool changed;
public
slots:
void remove(const QModelIndex &index);
private:
int rows;
};
/* Encapsulation of the Weight Model, that represents
* the current weights on a dive. */
class WeightModel : public CleanerTableModel {
Q_OBJECT
public:
enum Column {
REMOVE,
TYPE,
WEIGHT
};
explicit WeightModel(QObject *parent = 0);
/*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const;
/*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void passInData(const QModelIndex &index, const QVariant &value);
void add();
void clear();
void updateDive();
weightsystem_t *weightSystemAt(const QModelIndex &index);
bool changed;
public
slots:
void remove(const QModelIndex &index);
private:
int rows;
};
/* extra data model for additional dive computer data */
class ExtraDataModel : public CleanerTableModel {
Q_OBJECT
public:
enum Column {
KEY,
VALUE
};
explicit ExtraDataModel(QObject *parent = 0);
/*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
void clear();
void updateDive();
private:
int rows;
};
/*! An AbstractItemModel for recording dive trip information such as a list of dives.
*
*/
struct TreeItem {
Q_DECLARE_TR_FUNCTIONS(TreeItemDT);
public:
virtual ~TreeItem();
TreeItem();
virtual QVariant data(int column, int role) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
int row() const;
QList<TreeItem *> children;
TreeItem *parent;
};
struct DiveItem : public TreeItem {
enum Column {
NR,
DATE,
RATING,
DEPTH,
DURATION,
TEMPERATURE,
TOTALWEIGHT,
SUIT,
CYLINDER,
GAS,
SAC,
OTU,
MAXCNS,
LOCATION,
COLUMNS
};
virtual QVariant data(int column, int role) const;
int diveId;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
QString displayDate() const;
QString displayDuration() const;
QString displayDepth() const;
QString displayDepthWithUnit() const;
QString displayTemperature() const;
QString displayWeight() const;
QString displaySac() const;
int weight() const;
};
struct TripItem;
class TreeModel : public QAbstractItemModel {
Q_OBJECT
public:
TreeModel(QObject *parent = 0);
virtual ~TreeModel();
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 {
Q_OBJECT
public:
enum Column {
NR,
DATE,
RATING,
DEPTH,
DURATION,
TEMPERATURE,
TOTALWEIGHT,
SUIT,
CYLINDER,
GAS,
SAC,
OTU,
MAXCNS,
LOCATION,
COLUMNS
};
enum ExtraRoles {
STAR_ROLE = Qt::UserRole + 1,
DIVE_ROLE,
TRIP_ROLE,
SORT_ROLE,
DIVE_IDX
};
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;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
DiveTripModel(QObject *parent = 0);
Layout layout() const;
void setLayout(Layout layout);
private:
void setupModelData();
QMap<dive_trip_t *, TripItem *> trips;
Layout currentLayout;
};
class DiveComputerModel : public CleanerTableModel {
Q_OBJECT
public:
enum {
REMOVE,
MODEL,
ID,
NICKNAME
};
DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap, QObject *parent = 0);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void update();
void keepWorkingList();
void dropWorkingList();
public
slots:
void remove(const QModelIndex &index);
private:
int numRows;
QMultiMap<QString, DiveComputerNode> dcWorkingMap;
};
class YearlyStatisticsModel : public TreeModel {
Q_OBJECT
public:
enum {
YEAR,
DIVES,
TOTAL_TIME,
AVERAGE_TIME,
SHORTEST_TIME,
LONGEST_TIME,
AVG_DEPTH,
MIN_DEPTH,
MAX_DEPTH,
AVG_SAC,
MIN_SAC,
MAX_SAC,
AVG_TEMP,
MIN_TEMP,
MAX_TEMP,
COLUMNS
};
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
YearlyStatisticsModel(QObject *parent = 0);
void update_yearly_stats();
};
/* TablePrintModel:
* for now we use a blank table model with row items TablePrintItem.
* these are pretty much the same as DiveItem, but have color
* properties, as well. perhaps later one a more unified model has to be
* considered, but the current TablePrintModel idea has to be extended
* to support variadic column lists and column list orders that can
* be controlled by the user.
*/
struct TablePrintItem {
QString number;
QString date;
QString depth;
QString duration;
QString divemaster;
QString buddy;
QString location;
unsigned int colorBackground;
};
class TablePrintModel : public QAbstractTableModel {
Q_OBJECT
private:
QList<struct TablePrintItem *> list;
public:
~TablePrintModel();
TablePrintModel();
int rows, columns;
void insertRow(int index = -1);
void callReset();
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
};
/* ProfilePrintModel:
* this model is used when printing a data table under a profile. it requires
* some exact usage of setSpan(..) on the target QTableView widget.
*/
class ProfilePrintModel : public QAbstractTableModel {
Q_OBJECT
private:
int diveId;
double fontSize;
public:
ProfilePrintModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
void setDive(struct dive *divePtr);
void setFontsize(double size);
};
class GasSelectionModel : public QStringListModel {
Q_OBJECT
public:
static GasSelectionModel *instance();
Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant data(const QModelIndex &index, int role) const;
public
slots:
void repopulate();
};
class LanguageModel : public QAbstractListModel {
Q_OBJECT
public:
static LanguageModel *instance();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
private:
LanguageModel(QObject *parent = 0);
QStringList languages;
};
#endif // MODELS_H