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(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(editor); + WeightModel *mymodel = qobject_cast(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 = ¤t_dive->weightsystem[index.row()]; + weightsystem_t *ws = ¤t->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 = ¤t->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 = ¤t_dive->weightsystem[index.row()]; + weightsystem_t *ws = ¤t->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();