Undo: implement undo of dive site location editing

Simply copy the code of note editing. It's a bit more complex,
since we have to parse the Gps coordinates. For consitency,
rename the COORD field to LOCATION (the field in the dive_site
struct is called LOCATION).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-03-14 22:07:48 +01:00 committed by Dirk Hohndel
parent 1deded7874
commit fa4fedbb48
9 changed files with 69 additions and 25 deletions

View file

@ -103,6 +103,11 @@ void editDiveSiteCountry(dive_site *ds, const QString &value)
execute(new EditDiveSiteCountry(ds, value)); execute(new EditDiveSiteCountry(ds, value));
} }
void editDiveSiteLocation(dive_site *ds, const QString &value)
{
execute(new EditDiveSiteLocation(ds, value));
}
void addDiveSite(const QString &name) void addDiveSite(const QString &name)
{ {
execute(new AddDiveSite(name)); execute(new AddDiveSite(name));

View file

@ -45,6 +45,7 @@ void editDiveSiteName(dive_site *ds, const QString &value);
void editDiveSiteDescription(dive_site *ds, const QString &value); void editDiveSiteDescription(dive_site *ds, const QString &value);
void editDiveSiteNotes(dive_site *ds, const QString &value); void editDiveSiteNotes(dive_site *ds, const QString &value);
void editDiveSiteCountry(dive_site *ds, const QString &value); void editDiveSiteCountry(dive_site *ds, const QString &value);
void editDiveSiteLocation(dive_site *ds, const QString &value);
void addDiveSite(const QString &name); void addDiveSite(const QString &name);
} // namespace Command } // namespace Command

View file

@ -208,4 +208,40 @@ void EditDiveSiteCountry::undo()
redo(); redo();
} }
// Parse GPS text into location_t
static location_t parseGpsText(const QString &text)
{
double lat, lon;
if (parseGpsText(text, &lat, &lon))
return create_location(lat, lon);
return { {0}, {0} };
}
EditDiveSiteLocation::EditDiveSiteLocation(dive_site *dsIn, const QString &location) : ds(dsIn),
value(parseGpsText(location))
{
setText(tr("Edit dive site location"));
}
bool EditDiveSiteLocation::workToBeDone()
{
bool ok = has_location(&value);
bool old_ok = has_location(&ds->location);
if (ok != old_ok)
return true;
return ok && !same_location(&value, &ds->location);
}
void EditDiveSiteLocation::redo()
{
std::swap(value, ds->location);
emit diveListNotifier.diveSiteChanged(ds, LocationInformationModel::LOCATION); // Inform frontend of changed dive site.
}
void EditDiveSiteLocation::undo()
{
// Undo and redo do the same
redo();
}
} // namespace Command } // namespace Command

View file

@ -92,6 +92,18 @@ private:
QString value; // Value to be set QString value; // Value to be set
}; };
class EditDiveSiteLocation : public Base {
public:
EditDiveSiteLocation(dive_site *ds, const QString &location);
private:
bool workToBeDone() override;
void undo() override;
void redo() override;
dive_site *ds;
location_t value; // Value to be set
};
} // namespace Command } // namespace Command
#endif // COMMAND_DIVESITE_H #endif // COMMAND_DIVESITE_H

View file

@ -142,6 +142,15 @@ void LocationInformationWidget::diveSiteChanged(struct dive_site *ds, int field)
case LocationInformationModel::TAXONOMY: case LocationInformationModel::TAXONOMY:
ui.diveSiteCountry->setText(taxonomy_get_country(&diveSite->taxonomy)); ui.diveSiteCountry->setText(taxonomy_get_country(&diveSite->taxonomy));
return; return;
case LocationInformationModel::LOCATION:
filter_model.setCoordinates(diveSite->location);
if (has_location(&diveSite->location)) {
enableLocationButtons(true);
ui.diveSiteCoordinates->setText(printGPSCoords(&diveSite->location));
} else {
enableLocationButtons(false);
ui.diveSiteCoordinates->clear();
}
default: default:
return; return;
} }
@ -181,14 +190,6 @@ bool parseGpsText(const QString &text, location_t &location)
void LocationInformationWidget::acceptChanges() void LocationInformationWidget::acceptChanges()
{ {
if (!diveSite) {
qWarning() << "did not have valid dive site in LocationInformationWidget";
return;
}
if (!ui.diveSiteCoordinates->text().isEmpty())
parseGpsText(ui.diveSiteCoordinates->text(), diveSite->location);
mark_divelist_changed(true);
resetState(); resetState();
} }
@ -250,22 +251,11 @@ void LocationInformationWidget::enableEdition()
ui.diveSiteMessage->setText(tr("You are editing a dive site")); ui.diveSiteMessage->setText(tr("You are editing a dive site"));
} }
void LocationInformationWidget::on_diveSiteCoordinates_textChanged(const QString &text) void LocationInformationWidget::on_diveSiteCoordinates_editingFinished()
{ {
if (!diveSite) if (!diveSite)
return; return;
location_t location; Command::editDiveSiteLocation(diveSite, ui.diveSiteCoordinates->text());
bool ok_old = has_location(&diveSite->location);
bool ok = parseGpsText(text, location);
if (ok != ok_old || !same_location(&location, &diveSite->location)) {
if (ok) {
markChangedWidget(ui.diveSiteCoordinates);
enableLocationButtons(true);
filter_model.setCoordinates(location);
} else {
enableLocationButtons(false);
}
}
} }
void LocationInformationWidget::on_diveSiteCountry_editingFinished() void LocationInformationWidget::on_diveSiteCountry_editingFinished()

View file

@ -30,7 +30,7 @@ public slots:
void resetState(); void resetState();
void resetPallete(); void resetPallete();
void on_diveSiteCountry_editingFinished(); void on_diveSiteCountry_editingFinished();
void on_diveSiteCoordinates_textChanged(const QString& text); void on_diveSiteCoordinates_editingFinished();
void on_diveSiteDescription_editingFinished(); void on_diveSiteDescription_editingFinished();
void on_diveSiteName_editingFinished(); void on_diveSiteName_editingFinished();
void on_diveSiteNotes_editingFinished(); void on_diveSiteNotes_editingFinished();

View file

@ -17,7 +17,7 @@ TabDiveSite::TabDiveSite(QWidget *parent) : TabBase(parent)
ui.diveSites->view()->setSortingEnabled(true); ui.diveSites->view()->setSortingEnabled(true);
// Show only the first few columns // Show only the first few columns
for (int i = LocationInformationModel::COORDS; i < LocationInformationModel::COLUMNS; ++i) for (int i = LocationInformationModel::LOCATION; i < LocationInformationModel::COLUMNS; ++i)
ui.diveSites->view()->setColumnHidden(i, true); ui.diveSites->view()->setColumnHidden(i, true);
connect(ui.diveSites, &TableView::addButtonClicked, this, &TabDiveSite::add); connect(ui.diveSites, &TableView::addButtonClicked, this, &TabDiveSite::add);

View file

@ -92,7 +92,7 @@ QVariant LocationInformationModel::getDiveSiteData(const struct dive_site *ds, i
case DIVESITE: return QVariant::fromValue<dive_site *>((dive_site *)ds); // Not nice: casting away const case DIVESITE: return QVariant::fromValue<dive_site *>((dive_site *)ds); // Not nice: casting away const
case NAME: return ds->name; case NAME: return ds->name;
case NUM_DIVES: return ds->dives.nr; case NUM_DIVES: return ds->dives.nr;
case COORDS: return "TODO"; case LOCATION: return "TODO";
case DESCRIPTION: return ds->description; case DESCRIPTION: return ds->description;
case NOTES: return ds->name; case NOTES: return ds->name;
case TAXONOMY: return "TODO"; case TAXONOMY: return "TODO";

View file

@ -17,7 +17,7 @@ class LocationInformationModel : public QAbstractTableModel {
public: public:
// Common columns, roles and accessor function for all dive-site models. // Common columns, roles and accessor function for all dive-site models.
// Thus, different views can connect to different models. // Thus, different views can connect to different models.
enum Columns { REMOVE, NAME, DESCRIPTION, NUM_DIVES, COORDS, NOTES, DIVESITE, TAXONOMY, COLUMNS}; enum Columns { REMOVE, NAME, DESCRIPTION, NUM_DIVES, LOCATION, NOTES, DIVESITE, TAXONOMY, COLUMNS};
enum Roles { DIVESITE_ROLE = Qt::UserRole + 1 }; enum Roles { DIVESITE_ROLE = Qt::UserRole + 1 };
static QVariant getDiveSiteData(const struct dive_site *ds, int column, int role); static QVariant getDiveSiteData(const struct dive_site *ds, int column, int role);