undo: make picture (media) deletion undoable

The code is rather complex. Firstly, we have different representations
of pictures throughout the code. Secondly, this tries to do add the
pictures in batches to the divepicture model and that is always rather
tricky.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-04-17 23:18:58 +02:00 committed by Dirk Hohndel
parent 9962d47b56
commit 434644b381
13 changed files with 286 additions and 54 deletions

View file

@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
#include "profile-widget/divepixmapitem.h"
#include "profile-widget/animationfunctions.h"
#include "qt-models/divepicturemodel.h"
#include "core/pref.h"
#include "core/qthelper.h"
#include "core/settings/qPrefDisplay.h"
#ifndef SUBSURFACE_MOBILE
#include "desktop-widgets/preferences/preferencesdialog.h"
#include "core/dive.h" // for displayed_dive
#include "commands/command.h"
#endif
#include <QDesktopServices>
@ -123,6 +124,8 @@ void DivePictureItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
void DivePictureItem::removePicture()
{
#ifndef SUBSURFACE_MOBILE
DivePictureModel::instance()->removePictures({ fileUrl });
struct dive *d = get_dive_by_uniq_id(displayed_dive.id);
if (d)
Command::removePictures({ { d, { fileUrl.toStdString() } } });
#endif
}

View file

@ -169,9 +169,8 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
addActionShortcut(Qt::Key_Right, &ProfileWidget2::keyRightAction);
connect(Thumbnailer::instance(), &Thumbnailer::thumbnailChanged, this, &ProfileWidget2::updateThumbnail, Qt::QueuedConnection);
connect(DivePictureModel::instance(), &DivePictureModel::rowsInserted, this, &ProfileWidget2::plotPictures);
connect(DivePictureModel::instance(), &DivePictureModel::picturesRemoved, this, &ProfileWidget2::removePictures);
connect(DivePictureModel::instance(), &DivePictureModel::modelReset, this, &ProfileWidget2::plotPictures);
connect(&diveListNotifier, &DiveListNotifier::picturesRemoved, this, &ProfileWidget2::picturesRemoved);
connect(&diveListNotifier, &DiveListNotifier::picturesAdded, this, &ProfileWidget2::picturesAdded);
connect(&diveListNotifier, &DiveListNotifier::cylinderEdited, this, &ProfileWidget2::profileChanged);
connect(&diveListNotifier, &DiveListNotifier::eventsChanged, this, &ProfileWidget2::profileChanged);
connect(&diveListNotifier, &DiveListNotifier::pictureOffsetChanged, this, &ProfileWidget2::pictureOffsetChanged);
@ -2147,11 +2146,10 @@ void ProfileWidget2::plotPicturesInternal(const struct dive *d, bool synchronous
}
// Remove the pictures with the given filenames from the profile plot.
// TODO: This does not check for the fact that the same image may be attributed
// to different dives! Deleting the picture from one dive may therefore remove
// it from the profile of a different dive.
void ProfileWidget2::removePictures(const QVector<QString> &fileUrls)
void ProfileWidget2::picturesRemoved(dive *d, QVector<QString> fileUrls)
{
if (d->id != displayed_dive.id)
return;
// To remove the pictures, we use the std::remove_if() algorithm.
// std::remove_if() does not actually delete the elements, but moves
// them to the end of the given range. It returns an iterator to the
@ -2165,6 +2163,25 @@ void ProfileWidget2::removePictures(const QVector<QString> &fileUrls)
calculatePictureYPositions();
}
void ProfileWidget2::picturesAdded(dive *d, QVector<PictureObj> pics)
{
if (d->id != displayed_dive.id)
return;
for (const PictureObj &pic: pics) {
if (pic.offset.seconds > 0 && pic.offset.seconds <= d->duration.seconds) {
pictures.emplace_back(pic.offset, QString::fromStdString(pic.filename), scene(), false);
updateThumbnailXPos(pictures.back());
}
}
// Sort pictures by timestamp (and filename if equal timestamps).
// This will allow for proper location of the pictures on the profile plot.
std::sort(pictures.begin(), pictures.end());
calculatePictureYPositions();
}
void ProfileWidget2::profileChanged(dive *d)
{
if (!d || d->id != displayed_dive.id)

View file

@ -20,6 +20,7 @@
#include "profile-widget/diveprofileitem.h"
#include "core/display.h"
#include "core/color.h"
#include "core/pictureobj.h"
#include "core/units.h"
class RulerItem2;
@ -110,7 +111,8 @@ slots: // Necessary to call from QAction's signals.
void setProfileState();
#ifndef SUBSURFACE_MOBILE
void plotPictures();
void removePictures(const QVector<QString> &fileUrls);
void picturesRemoved(dive *d, QVector<QString> filenames);
void picturesAdded(dive *d, QVector<PictureObj> pics);
void setPlanState();
void setAddState();
void pointInserted(const QModelIndex &parent, int start, int end);