aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-05-19 21:18:39 +0200
committerGravatar Lubomir I. Ivanov <neolit123@gmail.com>2018-05-21 22:17:28 +0300
commitf47f2773fd4de5bfbb8d90e5e00dc18e0c18e5bb (patch)
tree2735961e5d272b79ce8ff81b8d6fd2197d00026b
parent3c0c1801cd869f7a98c23356ab2ae4e373f55f31 (diff)
downloadsubsurface-f47f2773fd4de5bfbb8d90e5e00dc18e0c18e5bb.tar.gz
Dive pictures: don't repopulate DivePictureModel on deletion
On deletion of a single or multiple pictures, the whole DivePictureModel was repopulated, which was clearly visible in the UI, owing to the reconstructing of all images in the profile plot. To avoid this vexing behavior, implement proper deletion routines in DivePictureModel and ProfileWidget2. Since this needs sensible erase() semantics the QList<PictureEntry> member of DivePictureModel was replaced by a QVector. A QVector should be the default anyway, unless there are very specific reasons to use a QList (which actually is a deque, not a classical linked list). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--profile-widget/profilewidget2.cpp15
-rw-r--r--profile-widget/profilewidget2.h1
-rw-r--r--qt-models/divepicturemodel.cpp17
-rw-r--r--qt-models/divepicturemodel.h2
4 files changed, 32 insertions, 3 deletions
diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp
index 85653d1fc..e8291e8e9 100644
--- a/profile-widget/profilewidget2.cpp
+++ b/profile-widget/profilewidget2.cpp
@@ -1118,7 +1118,7 @@ void ProfileWidget2::setProfileState()
#ifndef SUBSURFACE_MOBILE
connect(DivePictureModel::instance(), &DivePictureModel::dataChanged, this, &ProfileWidget2::updatePictures);
connect(DivePictureModel::instance(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(plotPictures()));
- connect(DivePictureModel::instance(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(plotPictures()));
+ connect(DivePictureModel::instance(), &DivePictureModel::rowsRemoved, this, &ProfileWidget2::removePictures);
connect(DivePictureModel::instance(), &DivePictureModel::modelReset, this, &ProfileWidget2::plotPictures);
#endif
/* show the same stuff that the profile shows. */
@@ -2089,6 +2089,19 @@ void ProfileWidget2::plotPictures()
item->setPos(x, y);
}
}
+
+void ProfileWidget2::removePictures(const QModelIndex &, int first, int last)
+{
+ DivePictureModel *m = DivePictureModel::instance();
+ first = std::max(0, first - m->rowDDStart);
+ // Note that last points *to* the last item and not *past* the last item,
+ // therefore we add 1 to achieve conventional C++ semantics.
+ last = std::min((int)pictures.size(), last + 1 - m->rowDDStart);
+ if (first >= (int)pictures.size() || last <= first)
+ return;
+ pictures.erase(pictures.begin() + first, pictures.begin() + last);
+}
+
#endif
void ProfileWidget2::dropEvent(QDropEvent *event)
diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h
index 545c6475d..91774c9a9 100644
--- a/profile-widget/profilewidget2.h
+++ b/profile-widget/profilewidget2.h
@@ -110,6 +110,7 @@ slots: // Necessary to call from QAction's signals.
void replot(dive *d = 0);
#ifndef SUBSURFACE_MOBILE
void plotPictures();
+ void removePictures(const QModelIndex &, int first, int last);
void setPlanState();
void setAddState();
void changeGas();
diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp
index 3fa1a07f4..48fa652c9 100644
--- a/qt-models/divepicturemodel.cpp
+++ b/qt-models/divepicturemodel.cpp
@@ -149,7 +149,22 @@ void DivePictureModel::removePictures(const QVector<QString> &fileUrls)
copy_dive(current_dive, &displayed_dive);
mark_divelist_changed(true);
- updateDivePictures();
+ for (int i = 0; i < pictures.size(); ++i) {
+ // Find range [i j) of pictures to remove
+ if (std::find(fileUrls.begin(), fileUrls.end(), pictures[i].filename) == fileUrls.end())
+ continue;
+ int j;
+ for (j = i + 1; j < pictures.size(); ++j) {
+ if (std::find(fileUrls.begin(), fileUrls.end(), pictures[j].filename) == fileUrls.end())
+ break;
+ }
+
+ // Qt's model-interface is surprisingly idiosyncratic: you don't pass [first last), but [first last] ranges.
+ // For example, an empty list would be [0 -1].
+ beginRemoveRows(QModelIndex(), i, j - 1);
+ pictures.erase(pictures.begin() + i, pictures.begin() + j);
+ endRemoveRows();
+ }
}
int DivePictureModel::rowCount(const QModelIndex &parent) const
diff --git a/qt-models/divepicturemodel.h b/qt-models/divepicturemodel.h
index 61eb1d984..a7a3d7180 100644
--- a/qt-models/divepicturemodel.h
+++ b/qt-models/divepicturemodel.h
@@ -30,7 +30,7 @@ public slots:
void updateThumbnail(QString filename, QImage thumbnail);
private:
DivePictureModel();
- QList<PictureEntry> pictures;
+ QVector<PictureEntry> pictures;
int findPictureId(const QString &filename); // Return -1 if not found
double zoomLevel; // -1.0: minimum, 0.0: standard, 1.0: maximum
int size;