undo: implement undo of setting a picture time by drag&drop

Even though the functionality is seemingly trivial, this is a bit
invasive, as the code has to be split into two distinct parts:
1) Post undo command
2) React to changes to the divelist

Don't compile that code on mobile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-04-14 22:07:00 +02:00 committed by Dirk Hohndel
parent ebdb3e3c30
commit e61641c79c
11 changed files with 178 additions and 90 deletions

View file

@ -16,6 +16,8 @@ set(SUBSURFACE_GENERIC_COMMANDS_SRCS
command_edit_trip.h
command_event.cpp
command_event.h
command_pictures.cpp
command_pictures.h
)
add_library(subsurface_commands STATIC ${SUBSURFACE_GENERIC_COMMANDS_SRCS})
target_link_libraries(subsurface_commands ${QT_LIBRARIES})

View file

@ -6,6 +6,7 @@
#include "command_edit.h"
#include "command_edit_trip.h"
#include "command_event.h"
#include "command_pictures.h"
namespace Command {
@ -359,4 +360,11 @@ void addGasSwitch(struct dive *d, int dcNr, int seconds, int tank)
execute(new AddGasSwitch(d, dcNr, seconds, tank));
}
// Picture (media) commands
void setPictureOffset(dive *d, const QString &filename, offset_t offset)
{
execute(new SetPictureOffset(d, filename, offset));
}
} // namespace Command

View file

@ -118,6 +118,10 @@ void renameEvent(struct dive *d, int dcNr, struct event *ev, const char *name);
void removeEvent(struct dive *d, int dcNr, struct event *ev);
void addGasSwitch(struct dive *d, int dcNr, int seconds, int tank);
// 7) Picture (media) commands
void setPictureOffset(dive *d, const QString &filename, offset_t offset);
} // namespace Command
#endif // COMMAND_H

View file

@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0
#include "command_pictures.h"
#include "core/subsurface-qt/divelistnotifier.h"
namespace Command {
static picture *dive_get_picture(const dive *d, const QString &fn)
{
int idx = get_picture_idx(&d->pictures, qPrintable(fn));
return idx < 0 ? nullptr : &d->pictures.pictures[idx];
}
SetPictureOffset::SetPictureOffset(dive *dIn, const QString &filenameIn, offset_t offsetIn) :
d(dIn), filename(filenameIn), offset(offsetIn)
{
if (!dive_get_picture(d, filename))
d = nullptr;
setText(Command::Base::tr("Change media time"));
}
void SetPictureOffset::redo()
{
picture *pic = dive_get_picture(d, filename);
if (!pic) {
fprintf(stderr, "SetPictureOffset::redo(): picture disappeared!");
return;
}
std::swap(pic->offset, offset);
offset_t newOffset = pic->offset;
// Instead of trying to be smart, let's simply resort the picture table.
// If someone complains about speed, do our usual "smart" thing.
sort_picture_table(&d->pictures);
emit diveListNotifier.pictureOffsetChanged(d, filename, newOffset);
invalidate_dive_cache(d);
}
// Undo and redo do the same thing
void SetPictureOffset::undo()
{
redo();
}
bool SetPictureOffset::workToBeDone()
{
return !!d;
}
} // namespace Command

View file

@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-2.0
// Note: this header file is used by the undo-machinery and should not be included elsewhere.
#ifndef COMMAND_PICTURES_H
#define COMMAND_PICTURES_H
#include "command_base.h"
// We put everything in a namespace, so that we can shorten names without polluting the global namespace
namespace Command {
class SetPictureOffset final : public Base {
public:
SetPictureOffset(dive *d, const QString &filename, offset_t offset); // Pictures are identified by the unique (dive,filename) pair
private:
dive *d; // null means no work to be done
QString filename;
offset_t offset;
void undo() override;
void redo() override;
bool workToBeDone() override;
};
} // namespace Command
#endif