summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-05-23 18:40:16 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-05-23 21:36:33 -0700
commit01a3bd2cc6dcc035607cce61285ed9cc8d807b9b (patch)
treeb263322c484290a41af33fa74521f03349cf9cca
parentecbcd4db4721c9e4a6b4253a5f45f43fa9e80fc7 (diff)
downloadsubsurface-01a3bd2cc6dcc035607cce61285ed9cc8d807b9b.tar.gz
Add weightsystem delegate to enable editing of weightsystem
This is very much analogous to the way cylinders are implemented. That means that just like with cylinders, if the user enters a new type and hits 'tab' before hitting 'enter', Subsurface will crash. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--qt-ui/maintab.cpp3
-rw-r--r--qt-ui/modeldelegates.cpp40
-rw-r--r--qt-ui/modeldelegates.h9
-rw-r--r--qt-ui/models.cpp148
-rw-r--r--qt-ui/models.h27
5 files changed, 218 insertions, 9 deletions
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index 2306e22dc..65b636961 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -83,7 +83,8 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui->cylinders->horizontalHeader()->setResizeMode (CylindersModel::REMOVE , QHeaderView::Fixed);
ui->cylinders->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate());
ui->weights->setColumnWidth(WeightModel::REMOVE, 24);
- ui->cylinders->horizontalHeader()->setResizeMode (WeightModel::REMOVE , QHeaderView::Fixed);
+ ui->weights->horizontalHeader()->setResizeMode (WeightModel::REMOVE , QHeaderView::Fixed);
+ ui->weights->setItemDelegateForColumn(WeightModel::TYPE, new WSInfoDelegate());
}
// We need to manually position the 'plus' on cylinder and weight.
diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp
index 0cffe98c4..b80e30fcd 100644
--- a/qt-ui/modeldelegates.cpp
+++ b/qt-ui/modeldelegates.cpp
@@ -92,3 +92,43 @@ void TankInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
TankInfoDelegate::TankInfoDelegate(QObject* parent): QStyledItemDelegate(parent)
{
}
+
+QWidget* WSInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ QComboBox *comboDelegate = new QComboBox(parent);
+ WSInfoModel *model = WSInfoModel::instance();
+ comboDelegate->setModel(model);
+ comboDelegate->setEditable(true);
+ comboDelegate->setAutoCompletion(true);
+ comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive);
+ comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion);
+ return comboDelegate;
+}
+
+void WSInfoDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
+{
+ QComboBox *c = qobject_cast<QComboBox*>(editor);
+ QString data = index.model()->data(index, Qt::DisplayRole).toString();
+ int i = c->findText(data);
+ if (i != -1)
+ c->setCurrentIndex(i);
+ else
+ c->setEditText(data);
+}
+
+void WSInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
+{
+ QComboBox *c = static_cast<QComboBox*>(editor);
+ WeightModel *mymodel = qobject_cast<WeightModel *>(model);
+ WSInfoModel *ws = WSInfoModel::instance();
+ QModelIndex wsIndex = ws->match(ws->index(0,0), Qt::DisplayRole, c->currentText()).first();
+
+ int grams = ws->data(ws->index(wsIndex.row(), WSInfoModel::GR)).toInt();
+
+ mymodel->setData(index, c->currentText(), Qt::EditRole);
+ mymodel->passInData(model->index(index.row(), WeightModel::WEIGHT), grams);
+}
+
+WSInfoDelegate::WSInfoDelegate(QObject* parent): QStyledItemDelegate(parent)
+{
+}
diff --git a/qt-ui/modeldelegates.h b/qt-ui/modeldelegates.h
index eb78d12b6..79fbe297b 100644
--- a/qt-ui/modeldelegates.h
+++ b/qt-ui/modeldelegates.h
@@ -22,4 +22,13 @@ public:
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
};
+class WSInfoDelegate : public QStyledItemDelegate{
+ Q_OBJECT
+public:
+ explicit WSInfoDelegate(QObject* parent = 0);
+ virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ virtual void setEditorData(QWidget* editor, const QModelIndex& index) const;
+ virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
+};
+
#endif
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 5809fa55b..ee7628528 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -287,6 +287,10 @@ void CylindersModel::remove(const QModelIndex& index)
endRemoveRows();
}
+WeightModel::WeightModel(QObject* parent): QAbstractTableModel(parent), current(0), rows(0)
+{
+}
+
void WeightModel::remove(const QModelIndex& index)
{
if (index.column() != REMOVE) {
@@ -318,7 +322,7 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const
if (!index.isValid() || index.row() >= MAX_WEIGHTSYSTEMS)
return ret;
- weightsystem_t *ws = &current_dive->weightsystem[index.row()];
+ weightsystem_t *ws = &current->weightsystem[index.row()];
if (role == Qt::DisplayRole || role == Qt::EditRole) {
switch(index.column()) {
@@ -336,19 +340,43 @@ QVariant WeightModel::data(const QModelIndex& index, int role) const
return ret;
}
+// this is our magic 'pass data in' function that allows the delegate to get
+// the data here without silly unit conversions;
+// so we only implement the two columns we care about
+void WeightModel::passInData(const QModelIndex& index, const QVariant& value)
+{
+ weightsystem_t *ws = &current->weightsystem[index.row()];
+ if (index.column() == WEIGHT) {
+ if (ws->weight.grams != value.toInt()) {
+ ws->weight.grams = value.toInt();
+ mark_divelist_changed(TRUE);
+ }
+ }
+}
+
bool WeightModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
- weightsystem_t *ws = &current_dive->weightsystem[index.row()];
+ weightsystem_t *ws = &current->weightsystem[index.row()];
switch(index.column()) {
- case TYPE:{
- QByteArray desc = value.toByteArray();
- ws->description = strdup(desc.data());
+ case TYPE:
+ if (!value.isNull()) {
+ char *text= value.toByteArray().data();
+ if (!ws->description || strcmp(ws->description, text)) {
+ ws->description = strdup(text);
+ mark_divelist_changed(TRUE);
+ }
+ }
break;
- }
case WEIGHT:
- ws->weight.grams = value.toInt() *1000;
+ if (CHANGED(toDouble, "kg", "lbs")) {
+ if (prefs.units.weight == prefs.units.LBS)
+ ws->weight.grams = lbs_to_grams(value.toDouble());
+ else
+ ws->weight.grams = value.toDouble() * 1000.0;
+ }
break;
}
+ return QAbstractItemModel::setData(index, value, role);
}
Qt::ItemFlags WeightModel::flags(const QModelIndex& index) const
@@ -418,6 +446,111 @@ void WeightModel::setDive(dive* d)
endInsertRows();
}
+WSInfoModel* WSInfoModel::instance()
+{
+ static WSInfoModel *self = new WSInfoModel();
+ return self;
+}
+
+bool WSInfoModel::insertRows(int row, int count, const QModelIndex& parent)
+{
+ beginInsertRows(parent, rowCount(), rowCount());
+ rows += count;
+ endInsertRows();
+ return true;
+}
+
+bool WSInfoModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+ struct ws_info *info = &ws_info[index.row()];
+ QByteArray name = value.toByteArray();
+ info->name = strdup(name.data());
+ return TRUE;
+}
+
+void WSInfoModel::clear()
+{
+}
+
+int WSInfoModel::columnCount(const QModelIndex& parent) const
+{
+ return 2;
+}
+
+QVariant WSInfoModel::data(const QModelIndex& index, int role) const
+{
+ QVariant ret;
+ if (!index.isValid()) {
+ return ret;
+ }
+ struct ws_info *info = &ws_info[index.row()];
+
+ int gr = info->grams;
+
+ if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ switch(index.column()) {
+ case GR:
+ ret = gr;
+ break;
+ case DESCRIPTION:
+ ret = QString(info->name);
+ break;
+ }
+ }
+ return ret;
+}
+
+QVariant WSInfoModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ QVariant ret;
+
+ if (orientation != Qt::Horizontal)
+ return ret;
+
+ if (role == Qt::DisplayRole) {
+ switch(section) {
+ case GR:
+ ret = tr("kg");
+ break;
+ case DESCRIPTION:
+ ret = tr("Description");
+ break;
+ }
+ }
+ return ret;
+}
+
+int WSInfoModel::rowCount(const QModelIndex& parent) const
+{
+ return rows+1;
+}
+
+WSInfoModel::WSInfoModel() : QAbstractTableModel(), rows(-1)
+{
+ struct ws_info *info = ws_info;
+ for (info = ws_info; info->name; info++, rows++);
+
+ if (rows > -1) {
+ beginInsertRows(QModelIndex(), 0, rows);
+ endInsertRows();
+ }
+}
+
+void WSInfoModel::update()
+{
+ if (rows > -1) {
+ beginRemoveRows(QModelIndex(), 0, rows);
+ endRemoveRows();
+ }
+ struct ws_info *info = ws_info;
+ for (info = ws_info; info->name; info++, rows++);
+
+ if (rows > -1) {
+ beginInsertRows(QModelIndex(), 0, rows);
+ endInsertRows();
+ }
+}
+
TankInfoModel* TankInfoModel::instance()
{
static TankInfoModel *self = new TankInfoModel();
@@ -437,6 +570,7 @@ bool TankInfoModel::setData(const QModelIndex& index, const QVariant& value, int
struct tank_info *info = &tank_info[index.row()];
QByteArray name = value.toByteArray();
info->name = strdup(name.data());
+ return TRUE;
}
void TankInfoModel::clear()
diff --git a/qt-ui/models.h b/qt-ui/models.h
index 556651ffe..ad909abe1 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -21,7 +21,7 @@ Q_OBJECT
public:
static TankInfoModel* instance();
- enum Column { DESCRIPTION, ML, BAR};
+ enum Column {DESCRIPTION, ML, BAR};
TankInfoModel();
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
@@ -36,6 +36,28 @@ private:
int rows;
};
+/* Encapsulate ws_info */
+class WSInfoModel : public QAbstractTableModel {
+Q_OBJECT
+public:
+ static WSInfoModel* instance();
+
+ enum Column {DESCRIPTION, GR};
+ WSInfoModel();
+
+ /*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ /*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ /*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);
+ void clear();
+ void update();
+private:
+ int rows;
+
+};
+
/* Encapsulation of the Cylinder Model, that presents the
* Current cylinders that are used on a dive. */
class CylindersModel : public QAbstractTableModel {
@@ -70,6 +92,8 @@ class WeightModel : public QAbstractTableModel {
Q_OBJECT
public:
enum Column {REMOVE, TYPE, WEIGHT, COLUMNS};
+
+ explicit WeightModel(QObject *parent = 0);
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
/*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const;
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
@@ -77,6 +101,7 @@ public:
/*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 update();