summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2020-03-03 22:34:50 +0100
committerGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2020-04-07 00:13:35 +0200
commit30c7499a3c656784cc45825b4b1b2fca61081308 (patch)
tree32f8ad2c085e3a1706ed0994c0f39eadde39830d
parent3aa1bb5bfae9a7ebf8f5e6cdbf751afcafdb4baf (diff)
downloadsubsurface-30c7499a3c656784cc45825b4b1b2fca61081308.tar.gz
undo: implement addBookmark undo command
Create a new translation unit for event-related undo commands. Create a base class of commands that add events and one subclass that adds a bookmark event. Use this command in the profile-widget. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--commands/CMakeLists.txt2
-rw-r--r--commands/command.cpp8
-rw-r--r--commands/command.h4
-rw-r--r--commands/command_base.h9
-rw-r--r--commands/command_event.cpp43
-rw-r--r--commands/command_event.h44
-rw-r--r--profile-widget/profilewidget2.cpp5
7 files changed, 108 insertions, 7 deletions
diff --git a/commands/CMakeLists.txt b/commands/CMakeLists.txt
index 4b0c37dc6..ceb2740f0 100644
--- a/commands/CMakeLists.txt
+++ b/commands/CMakeLists.txt
@@ -14,6 +14,8 @@ set(SUBSURFACE_GENERIC_COMMANDS_SRCS
command_edit.h
command_edit_trip.cpp
command_edit_trip.h
+ command_event.cpp
+ command_event.h
)
add_library(subsurface_commands STATIC ${SUBSURFACE_GENERIC_COMMANDS_SRCS})
target_link_libraries(subsurface_commands ${QT_LIBRARIES})
diff --git a/commands/command.cpp b/commands/command.cpp
index 5d71e6725..e9b4e0738 100644
--- a/commands/command.cpp
+++ b/commands/command.cpp
@@ -5,6 +5,7 @@
#include "command_divesite.h"
#include "command_edit.h"
#include "command_edit_trip.h"
+#include "command_event.h"
namespace Command {
@@ -326,4 +327,11 @@ void editDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *chan
}
#endif // SUBSURFACE_MOBILE
+// Event commands
+
+void addEventBookmark(struct dive *d, int dcNr, int seconds)
+{
+ execute(new AddEventBookmark(d, dcNr, seconds));
+}
+
} // namespace Command
diff --git a/commands/command.h b/commands/command.h
index b8024c03d..88614b1e9 100644
--- a/commands/command.h
+++ b/commands/command.h
@@ -104,6 +104,10 @@ void editDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *chan
void editTripLocation(dive_trip *trip, const QString &s);
void editTripNotes(dive_trip *trip, const QString &s);
+// 6) Event commands
+
+void addEventBookmark(struct dive *d, int dcNr, int seconds);
+
} // namespace Command
#endif // COMMAND_H
diff --git a/commands/command_base.h b/commands/command_base.h
index ffc6c4e91..be725d6a5 100644
--- a/commands/command_base.h
+++ b/commands/command_base.h
@@ -141,7 +141,7 @@
// We put everything in a namespace, so that we can shorten names without polluting the global namespace
namespace Command {
-// Classes used to automatically call free_dive()/free_trip for owning pointers that go out of scope.
+// Classes used to automatically call the appropriate free_*() function for owning pointers that go out of scope.
struct DiveDeleter {
void operator()(dive *d) { free_dive(d); }
};
@@ -151,11 +151,15 @@ struct TripDeleter {
struct DiveSiteDeleter {
void operator()(dive_site *ds) { free_dive_site(ds); }
};
+struct EventDeleter {
+ void operator()(event *ev) { free(ev); }
+};
-// Owning pointers to dive and dive_trip objects.
+// Owning pointers to dive, dive_trip, dive_site and event objects.
typedef std::unique_ptr<dive, DiveDeleter> OwningDivePtr;
typedef std::unique_ptr<dive_trip, TripDeleter> OwningTripPtr;
typedef std::unique_ptr<dive_site, DiveSiteDeleter> OwningDiveSitePtr;
+typedef std::unique_ptr<event, EventDeleter> OwningEventPtr;
// This is the base class of all commands.
// It defines the Qt-translation functions
@@ -182,4 +186,3 @@ QString getListOfDives(QVector<struct dive *> dives);
} // namespace Command
#endif // COMMAND_BASE_H
-
diff --git a/commands/command_event.cpp b/commands/command_event.cpp
new file mode 100644
index 000000000..ea35402e4
--- /dev/null
+++ b/commands/command_event.cpp
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "command_event.h"
+#include "core/dive.h"
+#include "core/subsurface-qt/divelistnotifier.h"
+#include "core/libdivecomputer.h"
+
+namespace Command {
+
+AddEventBase::AddEventBase(struct dive *dIn, int dcNrIn, struct event *ev) :
+ d(dIn), dcNr(dcNrIn), eventToAdd(ev)
+{
+}
+
+bool AddEventBase::workToBeDone()
+{
+ return true;
+}
+
+void AddEventBase::redo()
+{
+ struct divecomputer *dc = get_dive_dc(d, dcNr);
+ eventToRemove = eventToAdd.get();
+ add_event_to_dc(dc, eventToAdd.release()); // return ownership to backend
+ invalidate_dive_cache(d);
+}
+
+void AddEventBase::undo()
+{
+ struct divecomputer *dc = get_dive_dc(d, dcNr);
+ remove_event_from_dc(dc, eventToRemove);
+ eventToAdd.reset(eventToRemove); // take ownership of event
+ eventToRemove = nullptr;
+ invalidate_dive_cache(d);
+}
+
+AddEventBookmark::AddEventBookmark(struct dive *d, int dcNr, int seconds) :
+ AddEventBase(d, dcNr, create_event(seconds, SAMPLE_EVENT_BOOKMARK, 0, 0, "bookmark"))
+{
+ setText(tr("Add bookmark"));
+}
+
+} // namespace Command
diff --git a/commands/command_event.h b/commands/command_event.h
new file mode 100644
index 000000000..6e387d543
--- /dev/null
+++ b/commands/command_event.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+// Note: this header file is used by the undo-machinery and should not be included elsewhere.
+
+#ifndef COMMAND_EVENT_H
+#define COMMAND_EVENT_H
+
+#include "command_base.h"
+
+
+// We put everything in a namespace, so that we can shorten names without polluting the global namespace
+namespace Command {
+
+// Events are a strange thing: they contain there own description which means
+// that on changing the description a new object must be allocated. Moreover,
+// it means that these objects can't be collected in a table.
+// Therefore, the undo commands work on events as they do with dives: using
+// owning pointers. See comments in command_base.h
+
+class AddEventBase : public Base {
+public:
+ AddEventBase(struct dive *d, int dcNr, struct event *ev); // Takes ownership of event!
+private:
+ bool workToBeDone() override;
+ void undo() override;
+ void redo() override;
+
+ // Note: we store dive and the divecomputer-number instead of a pointer to the divecomputer.
+ // Since one divecomputer is integrated into the dive structure, pointers to divecomputers
+ // are probably not stable.
+ struct dive *d;
+ int dcNr;
+
+ OwningEventPtr eventToAdd; // for redo
+ event *eventToRemove; // for undo
+};
+
+class AddEventBookmark : public AddEventBase {
+public:
+ AddEventBookmark(struct dive *d, int dcNr, int seconds);
+};
+
+} // namespace Command
+
+#endif // COMMAND_EVENT_H
diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp
index 566c97732..67962b3bb 100644
--- a/profile-widget/profilewidget2.cpp
+++ b/profile-widget/profilewidget2.cpp
@@ -1600,10 +1600,7 @@ void ProfileWidget2::removeEvent(DiveEventItem *item)
void ProfileWidget2::addBookmark(int seconds)
{
- add_event(current_dc, seconds, SAMPLE_EVENT_BOOKMARK, 0, 0, "bookmark");
- invalidate_dive_cache(current_dive);
- mark_divelist_changed(true);
- replot();
+ Command::addEventBookmark(current_dive, dc_number, seconds);
}
void ProfileWidget2::addDivemodeSwitch(int seconds, int divemode)