diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-11-04 20:20:32 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-12-05 10:14:25 -0800 |
commit | 029c9ccf020fdb73c148da489e0e7b1acd3ca149 (patch) | |
tree | 28e92d6662d6e6ece3755369b30164d316d76f53 | |
parent | ab99ca85f12b92ed55219c82ec2220aebfe1dda5 (diff) | |
download | subsurface-029c9ccf020fdb73c148da489e0e7b1acd3ca149.tar.gz |
Desktop: refactor WSInfoDelegate logic
The WSInfoDelegate (weight-system-info delegate) is used to display
a combo box of known weightsystem-types and auto-fills the weight if
the weightsystem-type is changed.
This would overwrite the weight data of the displayed dive when the
user hovers over the different entries. Moreover, it saves the original
weight in case the user cancels the editing action.
This is not viable when implementing undo of weightsystem changes,
because hovering over entries should not produce individual undo
commands. Instead, implement a special "temporary" row in the
weightsystem model. On canceling of the edit actions, simply reload
the weightsystem from the unmodified dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | desktop-widgets/modeldelegates.cpp | 45 | ||||
-rw-r--r-- | desktop-widgets/modeldelegates.h | 11 | ||||
-rw-r--r-- | qt-models/weightmodel.cpp | 52 | ||||
-rw-r--r-- | qt-models/weightmodel.h | 7 |
4 files changed, 63 insertions, 52 deletions
diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index 6d5d9f9a4..715150386 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -85,10 +85,8 @@ const QSize& StarWidgetsDelegate::starSize() const ComboBoxDelegate::ComboBoxDelegate(QAbstractItemModel *model, QObject *parent, bool allowEdit) : QStyledItemDelegate(parent), model(model) { editable = allowEdit; - connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), - this, SLOT(revertModelData(QWidget *, QAbstractItemDelegate::EndEditHint))); - connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), - this, SLOT(fixTabBehavior())); + connect(this, &ComboBoxDelegate::closeEditor, this, &ComboBoxDelegate::editorClosed); + connect(this, &ComboBoxDelegate::closeEditor, this, &ComboBoxDelegate::fixTabBehavior); } void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const @@ -276,7 +274,7 @@ void TankInfoDelegate::reenableReplot(QWidget*, QAbstractItemDelegate::EndEditHi // MainWindow::instance()->graphics->replot(); } -void TankInfoDelegate::revertModelData(QWidget*, QAbstractItemDelegate::EndEditHint hint) +void TankInfoDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint hint) { if (hint == QAbstractItemDelegate::NoHint || hint == QAbstractItemDelegate::RevertModelCache) { @@ -326,19 +324,13 @@ void TankUseDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, model->setData(index, comboBox->currentIndex()); } -static struct RevertWeightData { - QString type; - int weight; -} currWeight; - -void WSInfoDelegate::revertModelData(QWidget*, QAbstractItemDelegate::EndEditHint hint) +void WSInfoDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint hint) { - if (hint == QAbstractItemDelegate::NoHint || - hint == QAbstractItemDelegate::RevertModelCache) { - WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); - mymodel->setData(IDX(WeightModel::TYPE), currWeight.type, Qt::EditRole); - mymodel->passInData(IDX(WeightModel::WEIGHT), currWeight.weight); - } + WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); + if (hint == QAbstractItemDelegate::RevertModelCache) + mymodel->clearTempWS(); + else + mymodel->commitTempWS(); } void WSInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelIndex&) const @@ -356,28 +348,15 @@ void WSInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelInd row = matches.first().row(); } int grams = wsim->data(wsim->index(row, WSInfoModel::GR)).toInt(); - QVariant v = QString(currCombo.activeText); - mymodel->setData(IDX(WeightModel::TYPE), v, Qt::EditRole); - mymodel->passInData(IDX(WeightModel::WEIGHT), grams); + mymodel->setTempWS(currCombo.currRow, weightsystem_t{ { grams }, copy_qstring(currCombo.activeText) }); } WSInfoDelegate::WSInfoDelegate(QObject *parent) : ComboBoxDelegate(WSInfoModel::instance(), parent, true) { } -QWidget *WSInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - /* First, call the combobox-create editor, it will setup our globals. */ - QWidget *editor = ComboBoxDelegate::createEditor(parent, option, index); - WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); - weightsystem_t ws = mymodel->weightSystemAt(index); - currWeight.type = ws.description; - currWeight.weight = ws.weight.grams; - return editor; -} - -void AirTypesDelegate::revertModelData(QWidget*, QAbstractItemDelegate::EndEditHint) +void AirTypesDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint) { } @@ -393,7 +372,7 @@ AirTypesDelegate::AirTypesDelegate(QObject *parent) : ComboBoxDelegate(GasSelect { } -void DiveTypesDelegate::revertModelData(QWidget*, QAbstractItemDelegate::EndEditHint) +void DiveTypesDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint) { } diff --git a/desktop-widgets/modeldelegates.h b/desktop-widgets/modeldelegates.h index e2baa1582..277bf994e 100644 --- a/desktop-widgets/modeldelegates.h +++ b/desktop-widgets/modeldelegates.h @@ -45,7 +45,7 @@ slots: //HACK: try to get rid of this in the future. void fakeActivation(); void fixTabBehavior(); - virtual void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) = 0; + virtual void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) = 0; private: bool editable; protected: @@ -60,7 +60,7 @@ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; public slots: - void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); + void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); void reenableReplot(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); }; @@ -78,10 +78,9 @@ class WSInfoDelegate : public ComboBoxDelegate { public: explicit WSInfoDelegate(QObject *parent = 0); void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; public slots: - void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); + void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); }; class AirTypesDelegate : public ComboBoxDelegate { @@ -91,7 +90,7 @@ public: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; public slots: - void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); + void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); }; class DiveTypesDelegate : public ComboBoxDelegate { @@ -101,7 +100,7 @@ public: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; public slots: - void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); + void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint); }; class SpinBoxDelegate : public QStyledItemDelegate { diff --git a/qt-models/weightmodel.cpp b/qt-models/weightmodel.cpp index 087d877ab..dbdbcdb88 100644 --- a/qt-models/weightmodel.cpp +++ b/qt-models/weightmodel.cpp @@ -9,7 +9,9 @@ WeightModel::WeightModel(QObject *parent) : CleanerTableModel(parent), changed(false), - d(nullptr) + d(nullptr), + tempRow(-1), + tempWS(empty_weightsystem) { //enum Column {REMOVE, TYPE, WEIGHT}; setHeaderDataStrings(QStringList() << tr("") << tr("Type") << tr("Weight")); @@ -38,7 +40,7 @@ QVariant WeightModel::data(const QModelIndex &index, int role) const if (!index.isValid() || index.row() >= d->weightsystems.nr) return QVariant(); - const weightsystem_t ws = weightSystemAt(index); + weightsystem_t ws = index.row() == tempRow ? tempWS : weightSystemAt(index); switch (role) { case Qt::FontRole: @@ -70,18 +72,44 @@ QVariant WeightModel::data(const QModelIndex &index, int role) const return QVariant(); } -// 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) +// Ownership of passed in weight system will be taken. Caller must not use it any longer. +void WeightModel::setTempWS(int row, weightsystem_t ws) { - weightsystem_t *ws = &d->weightsystems.weightsystems[index.row()]; - if (index.column() == WEIGHT) { - if (ws->weight.grams != value.toInt()) { - ws->weight.grams = value.toInt(); - dataChanged(index, index); - } + if (!d || row < 0 || row >= d->weightsystems.nr) // Sanity check: row must exist + return; + + clearTempWS(); // Shouldn't be necessary, just in case: Reset old temporary row. + free_weightsystem(tempWS); + + // It is really hard to get the editor-close-hints and setModelData calls under + // control. Therefore, if the row is set to the already existing entry, don't + // enter temporary mode. + if (same_string(d->weightsystems.weightsystems[row].description, ws.description)) { + free_weightsystem(ws); + tempWS.description = nullptr; + } else { + tempRow = row; + tempWS = ws; } + dataChanged(index(row, TYPE), index(row, WEIGHT)); +} + +void WeightModel::clearTempWS() +{ + if (tempRow < 0) + return; + int oldRow = tempRow; + tempRow = -1; + dataChanged(index(oldRow, TYPE), index(oldRow, WEIGHT)); +} + +void WeightModel::commitTempWS() +{ + if (tempRow < 0) + return; + tempRow = -1; + setData(index(tempRow, TYPE), QVariant::fromValue(QString(tempWS.description)), Qt::EditRole); + setData(index(tempRow, WEIGHT), QVariant::fromValue(get_weight_string(tempWS.weight, true)), Qt::EditRole); } bool WeightModel::setData(const QModelIndex &index, const QVariant &value, int role) diff --git a/qt-models/weightmodel.h b/qt-models/weightmodel.h index f3002a1ae..c8f9c9776 100644 --- a/qt-models/weightmodel.h +++ b/qt-models/weightmodel.h @@ -21,8 +21,10 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + void setTempWS(int row, weightsystem_t ws); + void clearTempWS(); + void commitTempWS(); - void passInData(const QModelIndex &index, const QVariant &value); void clear(); void updateDive(dive *d); weightsystem_t weightSystemAt(const QModelIndex &index) const; @@ -36,6 +38,9 @@ slots: private: dive *d; + // If we temporarily change a line because the user is selecting a weight type + int tempRow; + weightsystem_t tempWS; }; #endif |