Add a new dialog to allow to merge dive sites
From 1cd16399069a3d0b23825761cd7992d0356b2c03 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:17:06 -0300 Subject: [PATCH 01/11] Widget to show other dive sites on same coordinate
Add a new widget on the dive site management view to display all other dive sites on the same coordinate. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationInformation.ui | 65 ++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/qt-ui/locationInformation.ui b/qt-ui/locationInformation.ui index 56e8b0e..34cc2d5 100644 --- a/qt-ui/locationInformation.ui +++ b/qt-ui/locationInformation.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>556</width> - <height>584</height> + <height>707</height> </rect> </property> <property name="windowTitle"> @@ -30,19 +30,6 @@ </property> </widget> </item> - <item row="5" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> <item row="3" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> @@ -67,6 +54,15 @@ </property> </widget> </item> + <item row="3" column="1" colspan="2"> + <widget class="QLineEdit" name="diveSiteDescription"/> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="diveSiteName"/> + </item> + <item row="4" column="1" rowspan="2" colspan="2"> + <widget class="QPlainTextEdit" name="diveSiteNotes"/> + </item> <item row="2" column="2"> <widget class="QToolButton" name="geoCodeButton"> <property name="text"> @@ -78,15 +74,6 @@ </property> </widget> </item> - <item row="1" column="1" colspan="2"> - <widget class="QLineEdit" name="diveSiteName"/> - </item> - <item row="3" column="1" colspan="2"> - <widget class="QLineEdit" name="diveSiteDescription"/> - </item> - <item row="4" column="1" rowspan="2" colspan="2"> - <widget class="QPlainTextEdit" name="diveSiteNotes"/> - </item> <item row="0" column="0" colspan="3"> <widget class="KMessageWidget" name="diveSiteMessage" native="true"> <property name="sizePolicy"> @@ -97,6 +84,38 @@ </property> </widget> </item> + <item row="6" column="0" colspan="3"> + <widget class="QGroupBox" name="diveSiteGroupBox"> + <property name="title"> + <string>Dive sites on same coordinates</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QListView" name="diveSiteListView"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="5" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <customwidgets> -- 2.5.1
From 61ffb867063773d9e9152c395adcb0545e083556 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:19:06 -0300 Subject: [PATCH 02/11] Add a new Model: SsrfFilterProxyModel Add a new Model, it's the QSortFilterProxyModel that accept functions to filter / sort. so instead of creating a new class for each different sorting ( overkill ), now we can just create a function and pass to this class. I'll rework the filtering system of subsurface to use this - in the meantime I'v created this to ease the creation of another filter: the Dive Sites by gps coordinates. Signed-off-by: Tomaz Canabrava <[email protected]> --- CMakeLists.txt | 1 + qt-models/ssrfsortfilterproxymodel.cpp | 39 ++++++++++++++++++++++++++++++++++ qt-models/ssrfsortfilterproxymodel.h | 33 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 qt-models/ssrfsortfilterproxymodel.cpp create mode 100644 qt-models/ssrfsortfilterproxymodel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c0374f1..1426040 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -390,6 +390,7 @@ set(SUBSURFACE_MODELS_LIB_SRCS qt-models/diveplotdatamodel.cpp qt-models/divelocationmodel.cpp qt-models/divesitepicturesmodel.cpp + qt-models/ssrfsortfilterproxymodel.cpp ) source_group("Subsurface Models" FILES ${SUBSURFACE_MODELS}) diff --git a/qt-models/ssrfsortfilterproxymodel.cpp b/qt-models/ssrfsortfilterproxymodel.cpp new file mode 100644 index 0000000..443f6de --- /dev/null +++ b/qt-models/ssrfsortfilterproxymodel.cpp @@ -0,0 +1,39 @@ +#include "ssrfsortfilterproxymodel.h" + +SsrfSortFilterProxyModel::SsrfSortFilterProxyModel(QObject *parent) +: QSortFilterProxyModel(parent), less_than(0), accepts_col(0), accepts_row(0) +{ +} + +bool SsrfSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const +{ + Q_ASSERT(less_than); + return less_than(source_left, source_right); +} + +bool SsrfSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const +{ + Q_ASSERT(accepts_row); + return accepts_row(source_row, source_parent); +} + +bool SsrfSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const +{ + Q_ASSERT(accepts_col); + return accepts_col(source_column, source_parent); +} + +void SsrfSortFilterProxyModel::setLessThan(less_than_cb func) +{ + +} + +void SsrfSortFilterProxyModel::setFilterRow(filter_accepts_row_cb func) +{ + +} + +void SsrfSortFilterProxyModel::setFilterCol(filter_accepts_col_cb func) +{ + +} \ No newline at end of file diff --git a/qt-models/ssrfsortfilterproxymodel.h b/qt-models/ssrfsortfilterproxymodel.h new file mode 100644 index 0000000..f2c22f0 --- /dev/null +++ b/qt-models/ssrfsortfilterproxymodel.h @@ -0,0 +1,33 @@ +#ifndef SSRFSORTFILTERPROXYMODEL_H +#define SSRFSORTFILTERPROXYMODEL_H + +#include <QSortFilterProxyModel> + +typedef bool (*filter_accepts_col_cb) (int sourceRow, const QModelIndex& parent); +typedef bool (*filter_accepts_row_cb) (int sourceRow, const QModelIndex& parent); +typedef bool (*less_than_cb) (const QModelIndex& left, const QModelIndex& right); + +/* Use this class when you wanna a quick filter. + * instead of creating a new class, just create a new instance of this class + * and plug your callback. + */ +class SsrfSortFilterProxyModel : public QSortFilterProxyModel { + Q_OBJECT + +public: + SsrfSortFilterProxyModel(QObject *parent = 0); + virtual bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const; + virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; + virtual bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const; + + void setLessThan(less_than_cb func); + void setFilterRow(filter_accepts_row_cb func); + void setFilterCol(filter_accepts_col_cb func); + +private: + less_than_cb less_than; + filter_accepts_col_cb accepts_col; + filter_accepts_row_cb accepts_row; +}; + +#endif \ No newline at end of file -- 2.5.1
From 2c060fb4c6a7645d26cd55a2cd0d4925ef3597ef Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:37:15 -0300 Subject: [PATCH 03/11] Pass the model as parameter to the callback Forgot to add the model as a parameter to the callback this whould made the callback useless. ;p Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-models/ssrfsortfilterproxymodel.cpp | 15 +++++++++------ qt-models/ssrfsortfilterproxymodel.h | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/qt-models/ssrfsortfilterproxymodel.cpp b/qt-models/ssrfsortfilterproxymodel.cpp index 443f6de..b3f67c1 100644 --- a/qt-models/ssrfsortfilterproxymodel.cpp +++ b/qt-models/ssrfsortfilterproxymodel.cpp @@ -8,32 +8,35 @@ SsrfSortFilterProxyModel::SsrfSortFilterProxyModel(QObject *parent) bool SsrfSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const { Q_ASSERT(less_than); - return less_than(source_left, source_right); + const QAbstractItemModel *self = this; + return less_than(const_cast<QAbstractItemModel*>(self), source_left, source_right); } bool SsrfSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { Q_ASSERT(accepts_row); - return accepts_row(source_row, source_parent); + const QAbstractItemModel *self = this; + return accepts_row(const_cast<QAbstractItemModel*>(self), source_row, source_parent); } bool SsrfSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const { Q_ASSERT(accepts_col); - return accepts_col(source_column, source_parent); + const QAbstractItemModel *self = this; + return accepts_col(const_cast<QAbstractItemModel*>(self), source_column, source_parent); } void SsrfSortFilterProxyModel::setLessThan(less_than_cb func) { - + less_than = func; } void SsrfSortFilterProxyModel::setFilterRow(filter_accepts_row_cb func) { - + accepts_row = func; } void SsrfSortFilterProxyModel::setFilterCol(filter_accepts_col_cb func) { - + accepts_col = func; } \ No newline at end of file diff --git a/qt-models/ssrfsortfilterproxymodel.h b/qt-models/ssrfsortfilterproxymodel.h index f2c22f0..2f94a0e 100644 --- a/qt-models/ssrfsortfilterproxymodel.h +++ b/qt-models/ssrfsortfilterproxymodel.h @@ -3,9 +3,9 @@ #include <QSortFilterProxyModel> -typedef bool (*filter_accepts_col_cb) (int sourceRow, const QModelIndex& parent); -typedef bool (*filter_accepts_row_cb) (int sourceRow, const QModelIndex& parent); -typedef bool (*less_than_cb) (const QModelIndex& left, const QModelIndex& right); +typedef bool (*filter_accepts_col_cb) (QAbstractItemModel *model,int sourceRow, const QModelIndex& parent); +typedef bool (*filter_accepts_row_cb) (QAbstractItemModel *model,int sourceRow, const QModelIndex& parent); +typedef bool (*less_than_cb) (QAbstractItemModel *model, const QModelIndex& left, const QModelIndex& right); /* Use this class when you wanna a quick filter. * instead of creating a new class, just create a new instance of this class -- 2.5.1
From 8749b15f7a13a01c0b36ea861b8f32cb6726930b Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:37:49 -0300 Subject: [PATCH 04/11] Add function to filter same-gps dive sites This should be userfull to show dive sites that are mergeable. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-models/divelocationmodel.cpp | 10 ++++++++++ qt-models/divelocationmodel.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/qt-models/divelocationmodel.cpp b/qt-models/divelocationmodel.cpp index fca322d..abdf69f 100644 --- a/qt-models/divelocationmodel.cpp +++ b/qt-models/divelocationmodel.cpp @@ -183,3 +183,13 @@ GeoReferencingOptionsModel::GeoReferencingOptionsModel(QObject *parent) : QStrin list << taxonomy_category_names[i]; setStringList(list); } + +bool filter_same_gps_cb (QAbstractItemModel *model, int sourceRow, const QModelIndex& parent) +{ + int ref_lat = displayed_dive_site.latitude.udeg; + int ref_lon = displayed_dive_site.longitude.udeg; + QModelIndex curr = model->index(sourceRow, LocationInformationModel::UUID, parent.isValid() ? parent : QModelIndex()); + + struct dive_site *ds = get_dive_site_by_uuid(curr.data().toInt()); + return (ds->latitude.udeg == ref_lat && ds->longitude.udeg == ref_lon); +} \ No newline at end of file diff --git a/qt-models/divelocationmodel.h b/qt-models/divelocationmodel.h index 3bf7161..f40bbd1 100644 --- a/qt-models/divelocationmodel.h +++ b/qt-models/divelocationmodel.h @@ -5,10 +5,14 @@ #include <QStringListModel> #include <stdint.h> +#include "ssrfsortfilterproxymodel.h" + class QLineEdit; #define RECENTLY_ADDED_DIVESITE 1 +bool filter_same_gps_cb (int sourceRow, const QModelIndex& parent); + class LocationInformationModel : public QAbstractTableModel { Q_OBJECT public: -- 2.5.1
From 5e0f144811d1f8e9ba68243deea120d476566889 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:58:31 -0300 Subject: [PATCH 05/11] Fix recursive stack-overflow only call this when needed, if there's no function set as callback, always return true. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-models/ssrfsortfilterproxymodel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qt-models/ssrfsortfilterproxymodel.cpp b/qt-models/ssrfsortfilterproxymodel.cpp index b3f67c1..585f7b5 100644 --- a/qt-models/ssrfsortfilterproxymodel.cpp +++ b/qt-models/ssrfsortfilterproxymodel.cpp @@ -14,14 +14,16 @@ bool SsrfSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM bool SsrfSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { - Q_ASSERT(accepts_row); + if (!accepts_row) + return true; const QAbstractItemModel *self = this; return accepts_row(const_cast<QAbstractItemModel*>(self), source_row, source_parent); } bool SsrfSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const { - Q_ASSERT(accepts_col); + if (!accepts_col) + return true; const QAbstractItemModel *self = this; return accepts_col(const_cast<QAbstractItemModel*>(self), source_column, source_parent); } -- 2.5.1
From df39065028f286fe8781fc8c904e4bc51ffcc809 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 20:59:13 -0300 Subject: [PATCH 06/11] Display dive sites with same gps as the current So we can merge them later - currently we are showing only the ID, ugly - fixing next. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-models/divelocationmodel.cpp | 9 +++++++-- qt-models/divelocationmodel.h | 2 +- qt-ui/locationinformation.cpp | 8 ++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/qt-models/divelocationmodel.cpp b/qt-models/divelocationmodel.cpp index abdf69f..ff733f5 100644 --- a/qt-models/divelocationmodel.cpp +++ b/qt-models/divelocationmodel.cpp @@ -188,8 +188,13 @@ bool filter_same_gps_cb (QAbstractItemModel *model, int sourceRow, const QModelI { int ref_lat = displayed_dive_site.latitude.udeg; int ref_lon = displayed_dive_site.longitude.udeg; - QModelIndex curr = model->index(sourceRow, LocationInformationModel::UUID, parent.isValid() ? parent : QModelIndex()); + QSortFilterProxyModel *self = (QSortFilterProxyModel*) model; + + int ds_uuid = self->sourceModel()->index(sourceRow, LocationInformationModel::UUID, parent).data().toInt(); + struct dive_site *ds = get_dive_site_by_uuid(ds_uuid); + + if (!ds) + return false; - struct dive_site *ds = get_dive_site_by_uuid(curr.data().toInt()); return (ds->latitude.udeg == ref_lat && ds->longitude.udeg == ref_lon); } \ No newline at end of file diff --git a/qt-models/divelocationmodel.h b/qt-models/divelocationmodel.h index f40bbd1..83bc97e 100644 --- a/qt-models/divelocationmodel.h +++ b/qt-models/divelocationmodel.h @@ -11,7 +11,7 @@ class QLineEdit; #define RECENTLY_ADDED_DIVESITE 1 -bool filter_same_gps_cb (int sourceRow, const QModelIndex& parent); +bool filter_same_gps_cb (QAbstractItemModel *m, int sourceRow, const QModelIndex& parent); class LocationInformationModel : public QAbstractTableModel { Q_OBJECT diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 6006b18..4a4fff0 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -30,6 +30,11 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo connect(this, SIGNAL(stopFilterDiveSite()), MultiFilterSortModel::instance(), SLOT(stopFilterDiveSite())); connect(ui.geoCodeButton, SIGNAL(clicked()), this, SLOT(reverseGeocode())); + SsrfSortFilterProxyModel *filter_model = new SsrfSortFilterProxyModel(this); + filter_model->setSourceModel(LocationInformationModel::instance()); + filter_model->setFilterRow(filter_same_gps_cb); + ui.diveSiteListView->setModel(filter_model); + #ifndef NO_MARBLE // Globe Management Code. connect(this, &LocationInformationWidget::requestCoordinates, @@ -133,7 +138,10 @@ void LocationInformationWidget::showEvent(QShowEvent *ev) { if (displayed_dive_site.uuid) { updateLabels(); + QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(ui.diveSiteListView->model()); emit startFilterDiveSite(displayed_dive_site.uuid); + if (m) + m->invalidate(); } emit requestCoordinates(); -- 2.5.1
From b7e3327be63f8d7450b8f75348ce0c0ef0519141 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 21:03:31 -0300 Subject: [PATCH 07/11] Show the correct data on the Dive Site List We where showing the UID, wich didn't made sense. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationInformation.ui | 3 +++ qt-ui/locationinformation.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/qt-ui/locationInformation.ui b/qt-ui/locationInformation.ui index 34cc2d5..e7ab45c 100644 --- a/qt-ui/locationInformation.ui +++ b/qt-ui/locationInformation.ui @@ -98,6 +98,9 @@ <verstretch>0</verstretch> </sizepolicy> </property> + <property name="modelColumn"> + <number>0</number> + </property> </widget> </item> </layout> diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 4a4fff0..616a714 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -34,6 +34,7 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo filter_model->setSourceModel(LocationInformationModel::instance()); filter_model->setFilterRow(filter_same_gps_cb); ui.diveSiteListView->setModel(filter_model); + ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME); #ifndef NO_MARBLE // Globe Management Code. -- 2.5.1
From 259d091740a16d202ebad1fa2b914be1726a6434 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 21:11:28 -0300 Subject: [PATCH 08/11] Offer the option to merge dive sites. Almost finishing. :) Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationInformation.ui | 3 +++ qt-ui/locationinformation.cpp | 15 ++++++++++++++- qt-ui/locationinformation.h | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/qt-ui/locationInformation.ui b/qt-ui/locationInformation.ui index e7ab45c..a2fd635 100644 --- a/qt-ui/locationInformation.ui +++ b/qt-ui/locationInformation.ui @@ -98,6 +98,9 @@ <verstretch>0</verstretch> </sizepolicy> </property> + <property name="selectionMode"> + <enum>QAbstractItemView::MultiSelection</enum> + </property> <property name="modelColumn"> <number>0</number> </property> diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 616a714..b3acc66 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -10,6 +10,7 @@ #include <QDebug> #include <QShowEvent> +#include <QItemSelectionModel> LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false) { @@ -35,7 +36,7 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo filter_model->setFilterRow(filter_same_gps_cb); ui.diveSiteListView->setModel(filter_model); ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME); - + ui.diveSiteListView->installEventFilter(this); #ifndef NO_MARBLE // Globe Management Code. connect(this, &LocationInformationWidget::requestCoordinates, @@ -49,6 +50,18 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo #endif } +bool LocationInformationWidget::eventFilter(QObject*, QEvent *ev) +{ + if( ev->type() == QEvent::ContextMenu ) { + if (ui.diveSiteListView->selectionModel()->selectedIndexes().count() >= 2) { + QContextMenuEvent *ctx = (QContextMenuEvent*) ev; + QMenu contextMenu; + contextMenu.addAction(tr("Merge dive Sites"), this, SLOT(merge_dive_sites())); + contextMenu.exec(ctx->globalPos()); + } + } +} + void LocationInformationWidget::updateLabels() { if (displayed_dive_site.name) diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 445fd87..2442e16 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -9,6 +9,8 @@ class LocationInformationWidget : public QGroupBox { Q_OBJECT public: LocationInformationWidget(QWidget *parent = 0); + virtual bool eventFilter(QObject*, QEvent*); + protected: void showEvent(QShowEvent *); @@ -35,6 +37,7 @@ signals: void stopFilterDiveSite(); void requestCoordinates(); void endRequestCoordinates(); + private: Ui::LocationInformation ui; bool modified; -- 2.5.1
From b8729896abfc864574d6fe596c3b81be8646dac1 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 21:35:17 -0300 Subject: [PATCH 09/11] UI Code to merge dive sites Get the Qt data structures and convert to something that we can use on our c - core. Signed-off-by: Tomaz Canabrava <[email protected]> --- divesite.c | 5 +++++ divesite.h | 2 ++ qt-models/divelocationmodel.cpp | 3 ++- qt-models/divelocationmodel.h | 1 + qt-ui/locationinformation.cpp | 14 +++++++++++++- qt-ui/locationinformation.h | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/divesite.c b/divesite.c index ec552b6..2b5c488 100644 --- a/divesite.c +++ b/divesite.c @@ -276,6 +276,11 @@ void clear_dive_site(struct dive_site *ds) free_taxonomy(&ds->taxonomy); } +void merge_dive_sites(uint32_t* uuids, int count) +{ + +} + uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t divetime) { int i; diff --git a/divesite.h b/divesite.h index b0d56f1..1547884 100644 --- a/divesite.h +++ b/divesite.h @@ -66,10 +66,12 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy); void clear_dive_site(struct dive_site *ds); unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degrees_t lon2); uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t divetime); +void merge_dive_sites(uint32_t *uuids, int count); #define INVALID_DIVE_SITE_NAME "development use only - not a valid dive site name" #ifdef __cplusplus } #endif + #endif // DIVESITE_H diff --git a/qt-models/divelocationmodel.cpp b/qt-models/divelocationmodel.cpp index ff733f5..0ddd0eb 100644 --- a/qt-models/divelocationmodel.cpp +++ b/qt-models/divelocationmodel.cpp @@ -109,8 +109,9 @@ QVariant LocationInformationModel::data(const QModelIndex &index, int role) cons else return QVariant(); } + case UUID_ROLE: + return ds->uuid; } - return QVariant(); } diff --git a/qt-models/divelocationmodel.h b/qt-models/divelocationmodel.h index 83bc97e..d5b8705 100644 --- a/qt-models/divelocationmodel.h +++ b/qt-models/divelocationmodel.h @@ -17,6 +17,7 @@ class LocationInformationModel : public QAbstractTableModel { Q_OBJECT public: enum Columns { UUID, NAME, LATITUDE, LONGITUDE, COORDS, DESCRIPTION, NOTES, TAXONOMY_1, TAXONOMY_2, TAXONOMY_3, COLUMNS}; + enum Roles { UUID_ROLE = Qt::UserRole + 1 }; static LocationInformationModel *instance(); int columnCount(const QModelIndex &parent) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index b3acc66..d029dd2 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -11,6 +11,7 @@ #include <QDebug> #include <QShowEvent> #include <QItemSelectionModel> +#include <cstdlib> LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false) { @@ -56,12 +57,23 @@ bool LocationInformationWidget::eventFilter(QObject*, QEvent *ev) if (ui.diveSiteListView->selectionModel()->selectedIndexes().count() >= 2) { QContextMenuEvent *ctx = (QContextMenuEvent*) ev; QMenu contextMenu; - contextMenu.addAction(tr("Merge dive Sites"), this, SLOT(merge_dive_sites())); + contextMenu.addAction(tr("Merge dive Sites"), this, SLOT(mergeSelectedDiveSites())); contextMenu.exec(ctx->globalPos()); } } } +void LocationInformationWidget::mergeSelectedDiveSites() { + QModelIndexList selection = ui.diveSiteListView->selectionModel()->selectedIndexes(); + uint32_t *selected_dive_sites = (uint32_t*) malloc(sizeof(u_int32_t) * selection.count()); + int i = 0; + Q_FOREACH(const QModelIndex& idx, selection) { + selected_dive_sites[i] = (uint32_t) idx.data(LocationInformationModel::UUID_ROLE).toInt(); + } + merge_dive_sites(selected_dive_sites, i); + free(selected_dive_sites); +} + void LocationInformationWidget::updateLabels() { if (displayed_dive_site.name) diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 2442e16..080e013 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -27,6 +27,7 @@ public slots: void on_diveSiteName_textChanged(const QString& text); void on_diveSiteNotes_textChanged(); void reverseGeocode(); + void mergeSelectedDiveSites(); private slots: void updateLabels(); signals: -- 2.5.1
From e88e9a15d9ffd9795a4e83bbc988c25edc0047c2 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 21:45:31 -0300 Subject: [PATCH 10/11] Merge the dive sites selected. Wee. :) Signed-off-by: Tomaz Canabrava <[email protected]> --- divesite.c | 21 ++++++++++++++++++++- divesite.h | 2 +- qt-ui/locationinformation.cpp | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/divesite.c b/divesite.c index 2b5c488..96c41d1 100644 --- a/divesite.c +++ b/divesite.c @@ -1,6 +1,7 @@ /* divesite.c */ #include "divesite.h" #include "dive.h" +#include "divelist.h" #include <math.h> @@ -276,9 +277,27 @@ void clear_dive_site(struct dive_site *ds) free_taxonomy(&ds->taxonomy); } -void merge_dive_sites(uint32_t* uuids, int count) +void merge_dive_sites(uint32_t ref, uint32_t* uuids, int count) { + int curr_dive, i; + struct dive *d; + for(i = 0; i < count; i++){ + if (uuids[i] == ref) + continue; + + for_each_dive(curr_dive, d) { + if (d->dive_site_uuid != uuids[i] ) + continue; + d->dive_site_uuid = ref; + } + } + for(int i = 0; i < count; i++) { + if (uuids[i] == ref) + continue; + delete_dive_site(uuids[i]); + } + mark_divelist_changed(true); } uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t divetime) diff --git a/divesite.h b/divesite.h index 1547884..345b504 100644 --- a/divesite.h +++ b/divesite.h @@ -66,7 +66,7 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy); void clear_dive_site(struct dive_site *ds); unsigned int get_distance(degrees_t lat1, degrees_t lon1, degrees_t lat2, degrees_t lon2); uint32_t find_or_create_dive_site_with_name(const char *name, timestamp_t divetime); -void merge_dive_sites(uint32_t *uuids, int count); +void merge_dive_sites(uint32_t ref, uint32_t *uuids, int count); #define INVALID_DIVE_SITE_NAME "development use only - not a valid dive site name" diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index d029dd2..9e2821c 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -70,7 +70,7 @@ void LocationInformationWidget::mergeSelectedDiveSites() { Q_FOREACH(const QModelIndex& idx, selection) { selected_dive_sites[i] = (uint32_t) idx.data(LocationInformationModel::UUID_ROLE).toInt(); } - merge_dive_sites(selected_dive_sites, i); + merge_dive_sites(displayed_dive_site.uuid, selected_dive_sites, i); free(selected_dive_sites); } -- 2.5.1
From 96340eb4297500d8c4337ab7041ef53c36f2a040 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 31 Aug 2015 22:01:25 -0300 Subject: [PATCH 11/11] Correctly refresh dive site list And also show a warning to the user saying that that action is non-cancelable. Signed-off-by: Tomaz Canabrava <[email protected]> --- divesite.c | 2 +- qt-ui/locationinformation.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/divesite.c b/divesite.c index 96c41d1..a8c5ea4 100644 --- a/divesite.c +++ b/divesite.c @@ -292,7 +292,7 @@ void merge_dive_sites(uint32_t ref, uint32_t* uuids, int count) } } - for(int i = 0; i < count; i++) { + for(i = 0; i < count; i++) { if (uuids[i] == ref) continue; delete_dive_site(uuids[i]); diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 9e2821c..1c65015 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -11,6 +11,7 @@ #include <QDebug> #include <QShowEvent> #include <QItemSelectionModel> +#include <qmessagebox.h> #include <cstdlib> LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false) @@ -64,13 +65,22 @@ bool LocationInformationWidget::eventFilter(QObject*, QEvent *ev) } void LocationInformationWidget::mergeSelectedDiveSites() { + if (QMessageBox::warning(MainWindow::instance(), tr("Merging dive sites"), + tr("You are about to merge dive sites, you can't undo that action \n Are you sure you want to continue?"), + QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) + return; + QModelIndexList selection = ui.diveSiteListView->selectionModel()->selectedIndexes(); uint32_t *selected_dive_sites = (uint32_t*) malloc(sizeof(u_int32_t) * selection.count()); int i = 0; Q_FOREACH(const QModelIndex& idx, selection) { selected_dive_sites[i] = (uint32_t) idx.data(LocationInformationModel::UUID_ROLE).toInt(); + i++; } merge_dive_sites(displayed_dive_site.uuid, selected_dive_sites, i); + LocationInformationModel::instance()->update(); + QSortFilterProxyModel *m = (QSortFilterProxyModel *) ui.diveSiteListView->model(); + m->invalidate(); free(selected_dive_sites); } -- 2.5.1
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
