Dive site: use own copy of taxonomy in dive-site-edit widget

The dive-site-edit widget uses a copy of the to-be-edited site
to compare with old values. Generally, this seems overkill
(the original dive-site can be used for such a comparison).
But one place where it can't simply be removed is the taxonomy,
because the widget needs a place to store the unsaved data.

Change the code to use an explicit taxonomy structure instead
of the one provided in the copy. This should ultimately allow
removal of the latter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2018-10-13 11:52:59 +02:00 committed by Dirk Hohndel
parent 5d3967ce84
commit 8815f77ea0
8 changed files with 44 additions and 37 deletions

View file

@ -3,11 +3,11 @@
#include "pref.h" #include "pref.h"
#include "gettextfromc.h" #include "gettextfromc.h"
QString constructLocationTags(struct dive_site *ds, bool for_maintab) QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab)
{ {
QString locationTag; QString locationTag;
if (!ds || !ds->taxonomy.nr) if (!taxonomy->nr)
return locationTag; return locationTag;
/* Check if the user set any of the 3 geocoding categories */ /* Check if the user set any of the 3 geocoding categories */
@ -33,9 +33,9 @@ QString constructLocationTags(struct dive_site *ds, bool for_maintab)
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (prefs.geocoding.category[i] == TC_NONE) if (prefs.geocoding.category[i] == TC_NONE)
continue; continue;
for (int j = 0; j < ds->taxonomy.nr; j++) { for (int j = 0; j < taxonomy->nr; j++) {
if (ds->taxonomy.category[j].category == prefs.geocoding.category[i]) { if (taxonomy->category[j].category == prefs.geocoding.category[i]) {
QString tag = ds->taxonomy.category[j].value; QString tag = taxonomy->category[j].value;
if (!tag.isEmpty()) { if (!tag.isEmpty()) {
locationTag += connector + tag; locationTag += connector + tag;
connector = " / "; connector = " / ";

View file

@ -249,26 +249,6 @@ bool dive_site_is_empty(struct dive_site *ds)
ds->longitude.udeg == 0); ds->longitude.udeg == 0);
} }
void copy_dive_site_taxonomy(struct dive_site *orig, struct dive_site *copy)
{
if (orig->taxonomy.category == NULL) {
free_taxonomy(&copy->taxonomy);
} else {
if (copy->taxonomy.category == NULL)
copy->taxonomy.category = alloc_taxonomy();
for (int i = 0; i < TC_NR_CATEGORIES; i++) {
if (i < copy->taxonomy.nr) {
free((void *)copy->taxonomy.category[i].value);
copy->taxonomy.category[i].value = NULL;
}
if (i < orig->taxonomy.nr) {
copy->taxonomy.category[i] = orig->taxonomy.category[i];
copy->taxonomy.category[i].value = copy_string(orig->taxonomy.category[i].value);
}
}
copy->taxonomy.nr = orig->taxonomy.nr;
}
}
void copy_dive_site(struct dive_site *orig, struct dive_site *copy) void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
{ {
free(copy->name); free(copy->name);
@ -281,7 +261,7 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
copy->notes = copy_string(orig->notes); copy->notes = copy_string(orig->notes);
copy->description = copy_string(orig->description); copy->description = copy_string(orig->description);
copy->uuid = orig->uuid; copy->uuid = orig->uuid;
copy_dive_site_taxonomy(orig, copy); copy_taxonomy(&orig->taxonomy, &copy->taxonomy);
} }
static void merge_string(char **a, char **b) static void merge_string(char **a, char **b)

View file

@ -75,7 +75,7 @@ void merge_dive_sites(uint32_t ref, uint32_t *uuids, int count);
#ifdef __cplusplus #ifdef __cplusplus
} }
QString constructLocationTags(struct dive_site *ds, bool for_maintab); QString constructLocationTags(struct taxonomy_data *taxonomy, bool for_maintab);
#endif #endif

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include "taxonomy.h" #include "taxonomy.h"
#include "gettext.h" #include "gettext.h"
#include "subsurface-string.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -41,6 +42,27 @@ void free_taxonomy(struct taxonomy_data *t)
} }
} }
void copy_taxonomy(struct taxonomy_data *orig, struct taxonomy_data *copy)
{
if (orig->category == NULL) {
free_taxonomy(copy);
} else {
if (copy->category == NULL)
copy->category = alloc_taxonomy();
for (int i = 0; i < TC_NR_CATEGORIES; i++) {
if (i < copy->nr) {
free((void *)copy->category[i].value);
copy->category[i].value = NULL;
}
if (i < orig->nr) {
copy->category[i] = orig->category[i];
copy->category[i].value = copy_string(orig->category[i].value);
}
}
copy->nr = orig->nr;
}
}
int taxonomy_index_for_category(struct taxonomy_data *t, enum taxonomy_category cat) int taxonomy_index_for_category(struct taxonomy_data *t, enum taxonomy_category cat)
{ {
for (int i = 0; i < t->nr; i++) for (int i = 0; i < t->nr; i++)

View file

@ -41,6 +41,7 @@ struct taxonomy_data {
struct taxonomy *alloc_taxonomy(); struct taxonomy *alloc_taxonomy();
void free_taxonomy(struct taxonomy_data *t); void free_taxonomy(struct taxonomy_data *t);
void copy_taxonomy(struct taxonomy_data *orig, struct taxonomy_data *copy);
int taxonomy_index_for_category(struct taxonomy_data *t, enum taxonomy_category cat); int taxonomy_index_for_category(struct taxonomy_data *t, enum taxonomy_category cat);
const char *taxonomy_get_country(struct taxonomy_data *t); const char *taxonomy_get_country(struct taxonomy_data *t);
void taxonomy_set_country(struct taxonomy_data *t, const char *country, enum taxonomy_origin origin); void taxonomy_set_country(struct taxonomy_data *t, const char *country, enum taxonomy_origin origin);

View file

@ -20,6 +20,7 @@
LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false) LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false)
{ {
memset(&displayed_dive_site, 0, sizeof(displayed_dive_site)); memset(&displayed_dive_site, 0, sizeof(displayed_dive_site));
memset(&taxonomy, 0, sizeof(taxonomy));
ui.setupUi(this); ui.setupUi(this);
ui.diveSiteMessage->setCloseButtonVisible(false); ui.diveSiteMessage->setCloseButtonVisible(false);
@ -97,7 +98,7 @@ void LocationInformationWidget::updateLabels()
ui.diveSiteName->setText(displayed_dive_site.name); ui.diveSiteName->setText(displayed_dive_site.name);
else else
ui.diveSiteName->clear(); ui.diveSiteName->clear();
const char *country = taxonomy_get_country(&displayed_dive_site.taxonomy); const char *country = taxonomy_get_country(&taxonomy);
if (country) if (country)
ui.diveSiteCountry->setText(country); ui.diveSiteCountry->setText(country);
else else
@ -118,7 +119,7 @@ void LocationInformationWidget::updateLabels()
ui.diveSiteCoordinates->clear(); ui.diveSiteCoordinates->clear();
} }
ui.locationTags->setText(constructLocationTags(&displayed_dive_site, false)); ui.locationTags->setText(constructLocationTags(&taxonomy, false));
} }
@ -172,15 +173,15 @@ void LocationInformationWidget::acceptChanges()
free(uiString); free(uiString);
} }
uiString = copy_qstring(ui.diveSiteCountry->text()); uiString = copy_qstring(ui.diveSiteCountry->text());
// if the user entered a different contriy, first update the taxonomy // if the user entered a different country, first update the local taxonomy
// for the displayed dive site; this below will get copied into the currentDs // this below will get copied into the currentDs
if (!same_string(uiString, taxonomy_get_country(&displayed_dive_site.taxonomy)) && if (!same_string(uiString, taxonomy_get_country(&taxonomy)) &&
!empty_string(uiString)) !empty_string(uiString))
taxonomy_set_country(&displayed_dive_site.taxonomy, uiString, taxonomy_origin::GEOMANUAL); taxonomy_set_country(&taxonomy, uiString, taxonomy_origin::GEOMANUAL);
else else
free(uiString); free(uiString);
// now update the currentDs (which we then later copy back ontop of displayed_dive_site // now update the currentDs (which we then later copy back ontop of displayed_dive_site
copy_dive_site_taxonomy(&displayed_dive_site, currentDs); copy_taxonomy(&taxonomy, &currentDs->taxonomy);
uiString = copy_qstring(ui.diveSiteNotes->document()->toPlainText()); uiString = copy_qstring(ui.diveSiteNotes->document()->toPlainText());
if (!same_string(uiString, currentDs->notes)) { if (!same_string(uiString, currentDs->notes)) {
@ -214,6 +215,7 @@ void LocationInformationWidget::initFields(dive_site *ds)
{ {
if (ds) { if (ds) {
copy_dive_site(ds, &displayed_dive_site); copy_dive_site(ds, &displayed_dive_site);
copy_taxonomy(&ds->taxonomy, &taxonomy);
filter_model.set(displayed_dive_site.uuid, displayed_dive_site.latitude, displayed_dive_site.longitude); filter_model.set(displayed_dive_site.uuid, displayed_dive_site.latitude, displayed_dive_site.longitude);
updateLabels(); updateLabels();
enableLocationButtons(dive_site_has_gps_location(&displayed_dive_site)); enableLocationButtons(dive_site_has_gps_location(&displayed_dive_site));
@ -283,7 +285,7 @@ void LocationInformationWidget::on_diveSiteCoordinates_textChanged(const QString
void LocationInformationWidget::on_diveSiteCountry_textChanged(const QString& text) void LocationInformationWidget::on_diveSiteCountry_textChanged(const QString& text)
{ {
if (!same_string(qPrintable(text), taxonomy_get_country(&displayed_dive_site.taxonomy))) if (!same_string(qPrintable(text), taxonomy_get_country(&taxonomy)))
markChangedWidget(ui.diveSiteCountry); markChangedWidget(ui.diveSiteCountry);
} }
@ -317,7 +319,7 @@ void LocationInformationWidget::resetPallete()
void LocationInformationWidget::reverseGeocode() void LocationInformationWidget::reverseGeocode()
{ {
reverseGeoLookup(displayed_dive_site.latitude, displayed_dive_site.longitude, &displayed_dive_site.taxonomy); reverseGeoLookup(displayed_dive_site.latitude, displayed_dive_site.longitude, &taxonomy);
updateLabels(); updateLabels();
} }

View file

@ -4,6 +4,7 @@
#include "core/units.h" #include "core/units.h"
#include "core/divesite.h" #include "core/divesite.h"
#include "core/taxonomy.h"
#include "ui_locationInformation.h" #include "ui_locationInformation.h"
#include "qt-models/divelocationmodel.h" #include "qt-models/divelocationmodel.h"
#include <stdint.h> #include <stdint.h>
@ -52,6 +53,7 @@ private:
QAction *acceptAction, *rejectAction; QAction *acceptAction, *rejectAction;
GPSLocationInformationModel filter_model; GPSLocationInformationModel filter_model;
dive_site displayed_dive_site; dive_site displayed_dive_site;
taxonomy_data taxonomy;
}; };
class DiveLocationFilterProxyModel : public QSortFilterProxyModel { class DiveLocationFilterProxyModel : public QSortFilterProxyModel {

View file

@ -418,7 +418,7 @@ void MainTab::updateDiveInfo(bool clear)
ds = get_dive_site_by_uuid(displayed_dive.dive_site_uuid); ds = get_dive_site_by_uuid(displayed_dive.dive_site_uuid);
if (ds) { if (ds) {
ui.location->setCurrentDiveSiteUuid(ds->uuid); ui.location->setCurrentDiveSiteUuid(ds->uuid);
ui.locationTags->setText(constructLocationTags(ds, true)); ui.locationTags->setText(constructLocationTags(&ds->taxonomy, true));
} else { } else {
ui.location->clear(); ui.location->clear();
ui.locationTags->clear(); ui.locationTags->clear();