mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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:
parent
9e603cbe2b
commit
45ef879546
5 changed files with 67 additions and 12 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue