Undo: update notes field if changed by undo commands

To keep the UI in a consistent state, update the notes field if
it is changed by an undo command. To that purpose, add a new
signal to diveListNotifier with a list of dives and a field-id
as payload.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-01-27 22:08:13 +01:00 committed by Dirk Hohndel
parent 9e603cbe2b
commit 45ef879546
5 changed files with 67 additions and 12 deletions

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// The DiveListNotifier emits signals when the dive-list changes (dives/trips created/deleted/moved) // The DiveListNotifier emits signals when the dive-list changes (dives/trips created/deleted/moved/edited)
// Note that vectors are passed by reference, so this will only work for signals inside the UI thread! // Note that vectors are passed by reference, so this will only work for signals inside the UI thread!
#ifndef DIVELISTNOTIFIER_H #ifndef DIVELISTNOTIFIER_H
@ -10,6 +10,23 @@
#include <QObject> #include <QObject>
// Dive fields that can be edited.
// Use "enum class" to not polute the global name space.
enum class DiveField {
DATETIME,
AIR_TEMP,
WATER_TEMP,
LOCATION,
DIVEMASTER,
BUDDY,
RATING,
VISIBILITY,
SUIT,
TAGS,
MODE,
NOTES,
};
class DiveListNotifier : public QObject { class DiveListNotifier : public QObject {
Q_OBJECT Q_OBJECT
signals: signals:
@ -49,6 +66,9 @@ signals:
void diveSiteDeleted(dive_site *ds, int idx); void diveSiteDeleted(dive_site *ds, int idx);
void diveSiteDiveCountChanged(dive_site *ds); void diveSiteDiveCountChanged(dive_site *ds);
void diveSiteChanged(dive_site *ds, int field); // field according to LocationInformationModel void diveSiteChanged(dive_site *ds, int field); // field according to LocationInformationModel
// Signals emitted when dives are edited.
void divesEdited(const QVector<dive *> &dives, DiveField);
public: public:
// Desktop uses the QTreeView class to present the list of dives. The layout // Desktop uses the QTreeView class to present the list of dives. The layout
// of this class gives us a very fundamental problem, as we can not easily // of this class gives us a very fundamental problem, as we can not easily
@ -60,7 +80,7 @@ public:
bool inCommand() const; bool inCommand() const;
// The following class and function are used by divelist-modifying commands // The following class and function are used by divelist-modifying commands
// to signalize that are in-flight. If the returned object goes out of scope, // to signal that they are in-flight. If the returned object goes out of scope,
// the command-in-flight status is reset to its previous value. Thus, the // the command-in-flight status is reset to its previous value. Thus, the
// function can be called recursively. // function can be called recursively.
class InCommandMarker { class InCommandMarker {

View file

@ -57,6 +57,8 @@ void EditBase<T>::undo()
std::swap(old, value); std::swap(old, value);
emit diveListNotifier.divesEdited(QVector<dive *>::fromStdVector(dives), fieldId());
mark_divelist_changed(true); mark_divelist_changed(true);
} }
@ -90,4 +92,9 @@ QString EditNotes::fieldName() const
return tr("notes"); return tr("notes");
} }
DiveField EditNotes::fieldId() const
{
return DiveField::NOTES;
}
} // namespace Command } // namespace Command

View file

@ -5,6 +5,7 @@
#define COMMAND_EDIT_H #define COMMAND_EDIT_H
#include "command_base.h" #include "command_base.h"
#include "core/subsurface-qt/DiveListNotifier.h"
#include <QVector> #include <QVector>
@ -43,6 +44,7 @@ protected:
virtual void set(struct dive *d, T) const = 0; virtual void set(struct dive *d, T) const = 0;
virtual T data(struct dive *d) const = 0; virtual T data(struct dive *d) const = 0;
virtual QString fieldName() const = 0; // Name of the field, used to create the undo menu-entry virtual QString fieldName() const = 0; // Name of the field, used to create the undo menu-entry
virtual DiveField fieldId() const = 0;
}; };
class EditNotes : public EditBase<QString> { class EditNotes : public EditBase<QString> {
@ -51,6 +53,7 @@ public:
void set(struct dive *d, QString s) const override; void set(struct dive *d, QString s) const override;
QString data(struct dive *d) const override; QString data(struct dive *d) const override;
QString fieldName() const override; QString fieldName() const override;
DiveField fieldId() const override;
}; };
} // namespace Command } // namespace Command

View file

@ -82,6 +82,7 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui.weights->setModel(weightModel); ui.weights->setModel(weightModel);
closeMessage(); closeMessage();
connect(&diveListNotifier, &DiveListNotifier::divesEdited, this, &MainTab::divesEdited);
connect(ui.editDiveSiteButton, &QToolButton::clicked, MainWindow::instance(), &MainWindow::startDiveSiteEdit); connect(ui.editDiveSiteButton, &QToolButton::clicked, MainWindow::instance(), &MainWindow::startDiveSiteEdit);
connect(ui.location, &DiveLocationLineEdit::entered, MapWidget::instance(), &MapWidget::centerOnIndex); connect(ui.location, &DiveLocationLineEdit::entered, MapWidget::instance(), &MapWidget::centerOnIndex);
connect(ui.location, &DiveLocationLineEdit::currentChanged, MapWidget::instance(), &MapWidget::centerOnIndex); connect(ui.location, &DiveLocationLineEdit::currentChanged, MapWidget::instance(), &MapWidget::centerOnIndex);
@ -332,6 +333,23 @@ void MainTab::enableEdition(EditMode newEditMode)
} }
} }
// This function gets called if a field gets updated by an undo command.
// Refresh the corresponding UI field.
void MainTab::divesEdited(const QVector<dive *> &, DiveField field)
{
// If there is no current dive, no point in updating anything
if (!current_dive)
return;
switch(field) {
case DiveField::NOTES:
updateNotes(current_dive);
break;
default:
break;
}
}
void MainTab::clearEquipment() void MainTab::clearEquipment()
{ {
cylindersModel->clear(); cylindersModel->clear();
@ -370,6 +388,17 @@ void MainTab::updateDepthDuration()
ui.depth->setText(get_depth_string(displayed_dive.maxdepth, true)); ui.depth->setText(get_depth_string(displayed_dive.maxdepth, true));
} }
void MainTab::updateNotes(const struct dive *d)
{
QString tmp(d->notes);
if (tmp.indexOf("<div") != -1) {
tmp.replace(QString("\n"), QString("<br>"));
ui.notes->setHtml(tmp);
} else {
ui.notes->setPlainText(tmp);
}
}
void MainTab::updateDiveInfo(bool clear) void MainTab::updateDiveInfo(bool clear)
{ {
ui.location->refreshDiveSiteCache(); ui.location->refreshDiveSiteCache();
@ -388,15 +417,8 @@ void MainTab::updateDiveInfo(bool clear)
} }
ui.notes->setText(QString()); ui.notes->setText(QString());
if (!clear) { if (!clear)
QString tmp(displayed_dive.notes); updateNotes(&displayed_dive);
if (tmp.indexOf("<div") != -1) {
tmp.replace(QString("\n"), QString("<br>"));
ui.notes->setHtml(tmp);
} else {
ui.notes->setPlainText(tmp);
}
}
UPDATE_TEXT(displayed_dive, suit); UPDATE_TEXT(displayed_dive, suit);
UPDATE_TEXT(displayed_dive, divemaster); UPDATE_TEXT(displayed_dive, divemaster);
UPDATE_TEXT(displayed_dive, buddy); UPDATE_TEXT(displayed_dive, buddy);

View file

@ -17,6 +17,7 @@
#include "qt-models/completionmodels.h" #include "qt-models/completionmodels.h"
#include "qt-models/divelocationmodel.h" #include "qt-models/divelocationmodel.h"
#include "core/dive.h" #include "core/dive.h"
#include "core/subsurface-qt/DiveListNotifier.h"
class WeightModel; class WeightModel;
class CylindersModel; class CylindersModel;
@ -62,9 +63,11 @@ signals:
void diveSiteChanged(); void diveSiteChanged();
public public
slots: slots:
void divesEdited(const QVector<dive *> &dives, DiveField field);
void addCylinder_clicked(); void addCylinder_clicked();
void addWeight_clicked(); void addWeight_clicked();
void updateDiveInfo(bool clear = false); void updateDiveInfo(bool clear = false);
void updateNotes(const struct dive *d);
void updateDepthDuration(); void updateDepthDuration();
void acceptChanges(); void acceptChanges();
void rejectChanges(); void rejectChanges();