summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/subsurface-qt/DiveListNotifier.h9
-rw-r--r--desktop-widgets/CMakeLists.txt2
-rw-r--r--desktop-widgets/command.cpp11
-rw-r--r--desktop-widgets/command.h4
-rw-r--r--desktop-widgets/command_edit_trip.cpp85
-rw-r--r--desktop-widgets/command_edit_trip.h58
-rw-r--r--desktop-widgets/tab-widgets/maintab.cpp89
-rw-r--r--desktop-widgets/tab-widgets/maintab.h6
8 files changed, 207 insertions, 57 deletions
diff --git a/core/subsurface-qt/DiveListNotifier.h b/core/subsurface-qt/DiveListNotifier.h
index 46e160208..b57595aa6 100644
--- a/core/subsurface-qt/DiveListNotifier.h
+++ b/core/subsurface-qt/DiveListNotifier.h
@@ -10,7 +10,7 @@
#include <QObject>
-// Dive fields that can be edited.
+// Dive and trip fields that can be edited.
// Use "enum class" to not polute the global name space.
enum class DiveField {
NR,
@@ -29,6 +29,10 @@ enum class DiveField {
MODE,
NOTES,
};
+enum class TripField {
+ LOCATION,
+ NOTES
+};
class DiveListNotifier : public QObject {
Q_OBJECT
@@ -54,6 +58,9 @@ signals:
void cylindersReset(dive_trip *trip, const QVector<dive *> &dives);
void weightsystemsReset(dive_trip *trip, const QVector<dive *> &dives);
+ // Trip edited signal
+ void tripChanged(dive_trip *trip, TripField field);
+
// Selection-signals come in two kinds:
// - divesSelected, divesDeselected and currentDiveChanged are finer grained and are
// called batch-wise per trip (except currentDiveChanged, of course). These signals
diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt
index f3718935f..b86bd0524 100644
--- a/desktop-widgets/CMakeLists.txt
+++ b/desktop-widgets/CMakeLists.txt
@@ -66,6 +66,8 @@ set(SUBSURFACE_INTERFACE
command_divesite.h
command_edit.cpp
command_edit.h
+ command_edit_trip.cpp
+ command_edit_trip.h
command_private.cpp
command_private.h
configuredivecomputerdialog.cpp
diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp
index 07c8be61d..55fbeded9 100644
--- a/desktop-widgets/command.cpp
+++ b/desktop-widgets/command.cpp
@@ -4,6 +4,7 @@
#include "command_divelist.h"
#include "command_divesite.h"
#include "command_edit.h"
+#include "command_edit_trip.h"
namespace Command {
@@ -205,4 +206,14 @@ void pasteDives(const dive *d, dive_components what)
execute(new PasteDives(d, what));
}
+void editTripLocation(dive_trip *trip, const QString &s)
+{
+ execute(new EditTripLocation(trip, s));
+}
+
+void editTripNotes(dive_trip *trip, const QString &s)
+{
+ execute(new EditTripNotes(trip, s));
+}
+
} // namespace Command
diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h
index 6cfd7fc4e..627e5360d 100644
--- a/desktop-widgets/command.h
+++ b/desktop-widgets/command.h
@@ -68,6 +68,10 @@ void editBuddies(const QStringList &newList, bool currentDiveOnly);
void editDiveMaster(const QStringList &newList, bool currentDiveOnly);
void pasteDives(const dive *d, dive_components what);
+// 4) Trip editing commands
+void editTripLocation(dive_trip *trip, const QString &s);
+void editTripNotes(dive_trip *trip, const QString &s);
+
} // namespace Command
#endif // COMMAND_H
diff --git a/desktop-widgets/command_edit_trip.cpp b/desktop-widgets/command_edit_trip.cpp
new file mode 100644
index 000000000..4dc680e2d
--- /dev/null
+++ b/desktop-widgets/command_edit_trip.cpp
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "command_edit_trip.h"
+#include "command_private.h"
+#include "core/divelist.h" // for mark_divelist_changed(). TODO: remove
+#include "core/qthelper.h"
+
+namespace Command {
+
+EditTripBase::EditTripBase(dive_trip *tripIn, const QString &newValue) : trip(tripIn),
+ value(newValue)
+{
+}
+
+// Note: Virtual functions cannot be called in the constructor.
+// Therefore, setting of the title is done here.
+bool EditTripBase::workToBeDone()
+{
+ setText(tr("Edit %1").arg(fieldName()));
+ return data(trip) != value;
+}
+
+void EditTripBase::undo()
+{
+ QString old = data(trip);
+ set(trip, value);
+ value = old;
+
+ emit diveListNotifier.tripChanged(trip, fieldId());
+ mark_divelist_changed(true);
+}
+
+// Undo and redo do the same as just the stored value is exchanged
+void EditTripBase::redo()
+{
+ undo();
+}
+
+// Implementation of virtual functions
+
+// ***** Location *****
+void EditTripLocation::set(dive_trip *t, const QString &s) const
+{
+ free(t->location);
+ t->location = copy_qstring(s);
+}
+
+QString EditTripLocation::data(dive_trip *t) const
+{
+ return QString(t->location);
+}
+
+QString EditTripLocation::fieldName() const
+{
+ return tr("trip location");
+}
+
+TripField EditTripLocation::fieldId() const
+{
+ return TripField::LOCATION;
+}
+
+// ***** Notes *****
+void EditTripNotes::set(dive_trip *t, const QString &s) const
+{
+ free(t->notes);
+ t->notes = copy_qstring(s);
+}
+
+QString EditTripNotes::data(dive_trip *t) const
+{
+ return QString(t->notes);
+}
+
+QString EditTripNotes::fieldName() const
+{
+ return tr("trip notes");
+}
+
+TripField EditTripNotes::fieldId() const
+{
+ return TripField::NOTES;
+}
+
+} // namespace Command
diff --git a/desktop-widgets/command_edit_trip.h b/desktop-widgets/command_edit_trip.h
new file mode 100644
index 000000000..ae41ca252
--- /dev/null
+++ b/desktop-widgets/command_edit_trip.h
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+// Note: this header file is used by the undo-machinery and should not be included elsewhere.
+
+#ifndef COMMAND_EDIT_TRIP_H
+#define COMMAND_EDIT_TRIP_H
+
+#include "command_base.h"
+#include "core/subsurface-qt/DiveListNotifier.h"
+
+#include <QVector>
+
+// These are commands that edit individual fields of a a trip.
+// The implementation follows the (rather verbose) OO-style of the dive-edit commands.
+// But here, no template is used as the two fields are both of string type.
+
+// We put everything in a namespace, so that we can shorten names without polluting the global namespace
+namespace Command {
+
+class EditTripBase : public Base {
+ bool workToBeDone() override;
+
+ dive_trip *trip; // Trip to be edited.
+public:
+ EditTripBase(dive_trip *trip, const QString &newValue);
+
+protected:
+ QString value; // Value to be set
+ void undo() override;
+ void redo() override;
+
+ // Get and set functions to be overriden by sub-classes.
+ virtual void set(struct dive_trip *t, const QString &) const = 0;
+ virtual QString data(struct dive_trip *t) const = 0;
+ virtual QString fieldName() const = 0; // Name of the field, used to create the undo menu-entry
+ virtual TripField fieldId() const = 0;
+};
+
+class EditTripLocation : public EditTripBase {
+public:
+ using EditTripBase::EditTripBase; // Use constructor of base class.
+ void set(dive_trip *t, const QString &s) const override;
+ QString data(dive_trip *t) const override;
+ QString fieldName() const override;
+ TripField fieldId() const override;
+};
+
+class EditTripNotes : public EditTripBase {
+public:
+ using EditTripBase::EditTripBase; // Use constructor of base class.
+ void set(dive_trip *t, const QString &s) const override;
+ QString data(dive_trip *t) const override;
+ QString fieldName() const override;
+ TripField fieldId() const override;
+};
+
+} // namespace Command
+
+#endif
diff --git a/desktop-widgets/tab-widgets/maintab.cpp b/desktop-widgets/tab-widgets/maintab.cpp
index fe4f6186a..5509a5c93 100644
--- a/desktop-widgets/tab-widgets/maintab.cpp
+++ b/desktop-widgets/tab-widgets/maintab.cpp
@@ -69,7 +69,6 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui.timeEdit->setDisplayFormat(prefs.time_format);
memset(&displayed_dive, 0, sizeof(displayed_dive));
- memset(&displayedTrip, 0, sizeof(displayedTrip));
// This makes sure we only delete the models
// after the destructor of the tables,
@@ -82,6 +81,8 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
closeMessage();
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &MainTab::divesChanged);
+ connect(&diveListNotifier, &DiveListNotifier::tripChanged, this, &MainTab::tripChanged);
+
connect(ui.editDiveSiteButton, &QToolButton::clicked, MainWindow::instance(), &MainWindow::startDiveSiteEdit);
connect(ui.location, &DiveLocationLineEdit::entered, MapWidget::instance(), &MapWidget::centerOnIndex);
connect(ui.location, &DiveLocationLineEdit::currentChanged, MapWidget::instance(), &MapWidget::centerOnIndex);
@@ -281,14 +282,10 @@ void MainTab::updateTextLabels(bool showUnits)
void MainTab::enableEdition(EditMode newEditMode)
{
- const bool isTripEdit = MainWindow::instance() &&
- MainWindow::instance()->diveList->selectedTrips().count() == 1;
-
if (((newEditMode == DIVE || newEditMode == NONE) && current_dive == NULL) || editMode != NONE)
return;
modified = false;
if ((newEditMode == DIVE || newEditMode == NONE) &&
- !isTripEdit &&
current_dive->dc.model &&
strcmp(current_dive->dc.model, "manually added dive") == 0) {
// editCurrentDive will call enableEdition with newEditMode == MANUALLY_ADDED_DIVE
@@ -312,21 +309,13 @@ void MainTab::enableEdition(EditMode newEditMode)
ui.tabWidget->setTabEnabled(3, false);
ui.tabWidget->setTabEnabled(5, false);
- if (isTripEdit) {
- // we are editing trip location and notes
- displayMessage(tr("This trip is being edited."));
- currentTrip = current_dive->divetrip;
- ui.dateEdit->setEnabled(false);
- editMode = TRIP;
+ ui.dateEdit->setEnabled(true);
+ if (amount_selected > 1) {
+ displayMessage(tr("Multiple dives are being edited."));
} else {
- ui.dateEdit->setEnabled(true);
- if (amount_selected > 1) {
- displayMessage(tr("Multiple dives are being edited."));
- } else {
- displayMessage(tr("This dive is being edited."));
- }
- editMode = newEditMode != NONE ? newEditMode : DIVE;
+ displayMessage(tr("This dive is being edited."));
}
+ editMode = newEditMode != NONE ? newEditMode : DIVE;
}
static void profileFromDive(struct dive *d)
@@ -397,6 +386,26 @@ void MainTab::divesChanged(dive_trip *trip, const QVector<dive *> &dives, DiveFi
}
}
+// This function gets called if a trip-field gets updated by an undo command.
+// Refresh the corresponding UI field.
+void MainTab::tripChanged(dive_trip *trip, TripField field)
+{
+ // If the current dive is not in list of changed dives, do nothing
+ if (currentTrip != trip)
+ return;
+
+ switch(field) {
+ case TripField::NOTES:
+ ui.notes->setText(currentTrip->notes);
+ break;
+ case TripField::LOCATION:
+ ui.diveTripLocation->setText(currentTrip->location);
+ break;
+ default:
+ break;
+ }
+}
+
void MainTab::clearEquipment()
{
cylindersModel->clear();
@@ -767,18 +776,6 @@ void MainTab::acceptChanges()
resetPallete();
displayed_dive.divetrip = nullptr; // Should not be necessary, just in case!
return;
- } else if (MainWindow::instance() && MainWindow::instance()->diveList->selectedTrips().count() == 1) {
- /* now figure out if things have changed */
- if (displayedTrip.notes && !same_string(displayedTrip.notes, currentTrip->notes)) {
- currentTrip->notes = copy_string(displayedTrip.notes);
- mark_divelist_changed(true);
- }
- if (displayedTrip.location && !same_string(displayedTrip.location, currentTrip->location)) {
- currentTrip->location = copy_string(displayedTrip.location);
- mark_divelist_changed(true);
- }
- currentTrip = NULL;
- ui.dateEdit->setEnabled(true);
} else {
// Get list of selected dives, but put the current dive last;
// this is required in case the invocation wants to compare things
@@ -1102,13 +1099,11 @@ void MainTab::on_location_diveSiteSelected()
Command::editDiveSite(newDs, false);
}
-void MainTab::on_diveTripLocation_textEdited(const QString& text)
+void MainTab::on_diveTripLocation_editingFinished()
{
- if (currentTrip) {
- free(displayedTrip.location);
- displayedTrip.location = copy_qstring(text);
- markChangedWidget(ui.diveTripLocation);
- }
+ if (!currentTrip)
+ return;
+ Command::editTripLocation(currentTrip, ui.diveTripLocation->text());
}
void MainTab::on_suit_editingFinished()
@@ -1119,28 +1114,18 @@ void MainTab::on_suit_editingFinished()
Command::editSuit(ui.suit->text(), false);
}
-void MainTab::on_notes_textChanged()
-{
- if (editMode == IGNORE)
- return;
- if (currentTrip) {
- if (same_string(displayedTrip.notes, qPrintable(ui.notes->toPlainText())))
- return;
- free(displayedTrip.notes);
- displayedTrip.notes = copy_qstring(ui.notes->toPlainText());
- markChangedWidget(ui.notes);
- }
-}
-
void MainTab::on_notes_editingFinished()
{
- if (currentTrip || !current_dive)
- return; // Trip-note editing is done via on_notes_textChanged()
+ if (!currentTrip && !current_dive)
+ return;
QString notes = ui.notes->toHtml().indexOf("<div") != -1 ?
ui.notes->toHtml() : ui.notes->toPlainText();
- Command::editNotes(notes, false);
+ if (currentTrip)
+ Command::editTripNotes(currentTrip, notes);
+ else
+ Command::editNotes(notes, false);
}
void MainTab::on_rating_valueChanged(int value)
diff --git a/desktop-widgets/tab-widgets/maintab.h b/desktop-widgets/tab-widgets/maintab.h
index 83a19895a..6a41a1f64 100644
--- a/desktop-widgets/tab-widgets/maintab.h
+++ b/desktop-widgets/tab-widgets/maintab.h
@@ -39,7 +39,6 @@ public:
enum EditMode {
NONE,
DIVE,
- TRIP,
ADD,
MANUALLY_ADDED_DIVE,
IGNORE
@@ -62,6 +61,7 @@ signals:
public
slots:
void divesChanged(dive_trip *trip, const QVector<dive *> &dives, DiveField field);
+ void tripChanged(dive_trip *trip, TripField field);
void addCylinder_clicked();
void addWeight_clicked();
void updateDiveInfo(bool clear = false);
@@ -76,8 +76,7 @@ slots:
void on_divemaster_editingFinished();
void on_buddy_editingFinished();
void on_suit_editingFinished();
- void on_diveTripLocation_textEdited(const QString& text);
- void on_notes_textChanged();
+ void on_diveTripLocation_editingFinished();
void on_notes_editingFinished();
void on_airtemp_editingFinished();
void on_duration_editingFinished();
@@ -119,7 +118,6 @@ private:
void copyTagsToDisplayedDive();
void markChangedWidget(QWidget *w);
dive_trip_t *currentTrip;
- dive_trip_t displayedTrip;
QList<TabBase*> extraWidgets;
};