diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index f1afbceaf..36db76407 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -206,6 +206,7 @@ HEADERS += \ core/pref.h \ core/profile.h \ core/qthelper.h \ + core/range.h \ core/save-html.h \ core/statistics.h \ core/units.h \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 54cafd7d6..83ad52eb9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -147,6 +147,7 @@ set(SUBSURFACE_CORE_LIB_SRCS qt-init.cpp qthelper.cpp qthelper.h + range.h sample.c sample.h save-git.c diff --git a/core/qthelper.h b/core/qthelper.h index ddc0d3ac3..af73cc813 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -108,31 +108,6 @@ void uiNotification(const QString &msg); #define TITLE_OR_TEXT(_t, _m) _t, _m #endif -// Move a range in a vector to a different position. -// The parameters are given according to the usual STL-semantics: -// v: a container with STL-like random access iterator via std::begin(...) -// rangeBegin: index of first element -// rangeEnd: index one *past* last element -// destination: index to element before which the range will be moved -// Owing to std::begin() magic, this function works with STL-like containers: -// QVector v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// moveInVector(v, 1, 4, 6); -// as well as with C-style arrays: -// int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; -// moveInVector(array, 1, 4, 6); -// Both calls will have the following effect: -// Before: 0 1 2 3 4 5 6 7 8 9 -// After: 0 4 5 1 2 3 6 7 8 9 -// No sanitizing of the input arguments is performed. -template -void moveInVector(Vector &v, int rangeBegin, int rangeEnd, int destination) -{ - auto it = std::begin(v); - if (destination > rangeEnd) - std::rotate(it + rangeBegin, it + rangeEnd, it + destination); - else if (destination < rangeBegin) - std::rotate(it + destination, it + rangeBegin, it + rangeEnd); -} #endif // 3) Functions visible to C and C++ diff --git a/core/range.h b/core/range.h new file mode 100644 index 000000000..fa4f1465c --- /dev/null +++ b/core/range.h @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +// Helper functions for range manipulations +#ifndef RANGE_H +#define RANGE_H + +// Move a range in a vector to a different position. +// The parameters are given according to the usual STL-semantics: +// v: a container with STL-like random access iterator via std::begin(...) +// rangeBegin: index of first element +// rangeEnd: index one *past* last element +// destination: index to element before which the range will be moved +// Owing to std::begin() magic, this function works with STL-like containers: +// QVector v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +// move_in_range(v, 1, 4, 6); +// as well as with C-style arrays: +// int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +// move_in_range(array, 1, 4, 6); +// Both calls will have the following effect: +// Before: 0 1 2 3 4 5 6 7 8 9 +// After: 0 4 5 1 2 3 6 7 8 9 +// No sanitizing of the input arguments is performed. +template +void move_in_range(Range &v, int rangeBegin, int rangeEnd, int destination) +{ + auto it = std::begin(v); + if (destination > rangeEnd) + std::rotate(it + rangeBegin, it + rangeEnd, it + destination); + else if (destination < rangeBegin) + std::rotate(it + destination, it + rangeBegin, it + rangeEnd); +} + +#endif diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 89d1b2840..492588fbe 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -5,6 +5,7 @@ #include "core/event.h" #include "core/subsurface-string.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/settings/qPrefTechnicalDetails.h" #include "core/settings/qPrefPartialPressureGas.h" #include "profile-widget/diveeventitem.h" @@ -868,8 +869,8 @@ void ProfileWidget2::pointsRemoved(const QModelIndex &, int start, int end) void ProfileWidget2::pointsMoved(const QModelIndex &, int start, int end, const QModelIndex &, int row) { - moveInVector(handles, start, end + 1, row); - moveInVector(gases, start, end + 1, row); + move_in_range(handles, start, end + 1, row); + move_in_range(gases, start, end + 1, row); } void ProfileWidget2::repositionDiveHandlers() @@ -1317,7 +1318,7 @@ void ProfileWidget2::pictureOffsetChanged(dive *dIn, QString filename, offset_t // Move image from old to new position int oldIndex = oldPos - pictures.begin(); int newIndex = newPos - pictures.begin(); - moveInVector(pictures, oldIndex, oldIndex + 1, newIndex); + move_in_range(pictures, oldIndex, oldIndex + 1, newIndex); } else { // Case 1b): remove picture pictures.erase(oldPos); diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index af2813e78..867929911 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -5,6 +5,7 @@ #include "core/imagedownloader.h" #include "core/picture.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/selection.h" #include "core/subsurface-qt/divelistnotifier.h" #include "commands/command.h" @@ -312,6 +313,6 @@ void DivePictureModel::pictureOffsetChanged(dive *d, const QString filenameIn, o if (oldIndex == newIndex || oldIndex + 1 == newIndex) return; beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex); - moveInVector(pictures, oldIndex, oldIndex + 1, newIndex); + move_in_range(pictures, oldIndex, oldIndex + 1, newIndex); endMoveRows(); } diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 17be91a29..058bc3821 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -7,6 +7,7 @@ #include "qt-models/models.h" #include "core/device.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/sample.h" #include "core/settings/qPrefDivePlanner.h" #include "core/settings/qPrefUnit.h" @@ -877,7 +878,7 @@ void DivePlannerPointsModel::editStop(int row, divedatapoint newData) if (newRow != row && newRow != row + 1) { beginMoveRows(QModelIndex(), row, row, QModelIndex(), newRow); - moveInVector(divepoints, row, row + 1, newRow); + move_in_range(divepoints, row, row + 1, newRow); endMoveRows(); // Account for moving the row backwards in the array. diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 2f35367a3..a4dbbf25b 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -10,6 +10,7 @@ #include "core/string-format.h" #include "core/trip.h" #include "core/qthelper.h" +#include "core/range.h" #include "core/divesite.h" #include "core/picture.h" #include "core/subsurface-string.h" @@ -974,7 +975,7 @@ void DiveTripModelTree::topLevelChanged(int idx) // If index changed, move items if (newIdx != idx && newIdx != idx + 1) { beginMoveRows(QModelIndex(), idx, idx, QModelIndex(), newIdx); - moveInVector(items, idx, idx + 1, newIdx); + move_in_range(items, idx, idx + 1, newIdx); endMoveRows(); }