diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2020-01-10 08:25:37 +0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2020-03-10 09:25:57 -0700 |
commit | 57b96490b2c5b81023439046dea225b8caf09946 (patch) | |
tree | 3c5a811d23fbd80720de18331786ab1b56222407 /mobile-widgets/qmlmanager.cpp | |
parent | 200932189451d52e277004871004e3b2a0593e58 (diff) | |
download | subsurface-57b96490b2c5b81023439046dea225b8caf09946.tar.gz |
mobile/undo: create EditDive command
Command that just swaps two dives. This is rather complex,
as for example a dive site might be created.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'mobile-widgets/qmlmanager.cpp')
-rw-r--r-- | mobile-widgets/qmlmanager.cpp | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index b34d5b8a4..0ccf6f42c 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -49,6 +49,7 @@ #include "core/worldmap-save.h" #include "core/uploadDiveLogsDE.h" #include "core/uploadDiveShare.h" +#include "commands/command_base.h" #include "commands/command.h" QMLManager *QMLManager::m_instance = NULL; @@ -874,20 +875,32 @@ void QMLManager::refreshDiveList() MobileModels::instance()->reset(); } -void QMLManager::setupDivesite(struct dive *d, struct dive_site *ds, double lat, double lon, const char *locationtext) +// Ouch. Editing a dive might create a dive site or change an existing dive site. +// The following structure describes such a change caused by a dive edit. +// Hopefully, we can remove this in due course by using finer-grained undo-commands. +struct DiveSiteChange { + Command::OwningDiveSitePtr createdDs; // not-null if we created a dive site. + + dive_site *editDs = nullptr; // not-null if we are supposed to edit an existing dive site. + location_t location = zero_location; // new value of the location if we edit an existing dive site. + + bool changed = false; // true if either a dive site or the dive was changed. +}; + +static void setupDivesite(DiveSiteChange &res, struct dive *d, struct dive_site *ds, double lat, double lon, const char *locationtext) { location_t location = create_location(lat, lon); if (ds) { - ds->location = location; + res.editDs = ds; + res.location = location; } else { - unregister_dive_from_dive_site(d); - add_dive_to_dive_site(d, create_dive_site_with_gps(locationtext, &location, &dive_site_table)); - // We created a new dive site - let the dive site model know. - updateSiteList(); + res.createdDs.reset(create_dive_site_with_gps(locationtext, &location, &dive_site_table)); + add_dive_to_dive_site(d, res.createdDs.get()); } + res.changed = true; } -bool QMLManager::checkDate(const DiveObjectHelper &myDive, struct dive * d, QString date) +bool QMLManager::checkDate(const DiveObjectHelper &myDive, struct dive *d, QString date) { QString oldDate = myDive.date() + " " + myDive.time(); if (date != oldDate) { @@ -992,20 +1005,19 @@ parsed: return false; } -bool QMLManager::checkLocation(const DiveObjectHelper &myDive, struct dive *d, QString location, QString gps) +bool QMLManager::checkLocation(DiveSiteChange &res, const DiveObjectHelper &myDive, struct dive *d, QString location, QString gps) { - bool diveChanged = false; struct dive_site *ds = get_dive_site_for_dive(d); qDebug() << "checkLocation" << location << "gps" << gps << "dive had" << myDive.location << "gps" << myDive.gas; if (myDive.location != location) { - diveChanged = true; ds = get_dive_site_by_name(qPrintable(location), &dive_site_table); - if (!ds && !location.isEmpty()) - ds = create_dive_site(qPrintable(location), &dive_site_table); + if (!ds && !location.isEmpty()) { + res.createdDs.reset(create_dive_site(qPrintable(location), &dive_site_table)); + res.changed = true; + ds = res.createdDs.get(); + } unregister_dive_from_dive_site(d); add_dive_to_dive_site(d, ds); - // We created a new dive site - let the dive site model know. - updateSiteList(); } // now make sure that the GPS coordinates match - if the user changed the name but not // the GPS coordinates, this still does the right thing as the now new dive site will @@ -1015,18 +1027,15 @@ bool QMLManager::checkLocation(const DiveObjectHelper &myDive, struct dive *d, Q if (parseGpsText(gps, &lat, &lon)) { qDebug() << "parsed GPS, using it"; // there are valid GPS coordinates - just use them - setupDivesite(d, ds, lat, lon, qPrintable(myDive.location)); - diveChanged = true; + setupDivesite(res, d, ds, lat, lon, qPrintable(myDive.location)); } else if (gps == GPS_CURRENT_POS) { qDebug() << "gps was our default text for no GPS"; // user asked to use current pos QString gpsString = getCurrentPosition(); if (gpsString != GPS_CURRENT_POS) { qDebug() << "but now I got a valid location" << gpsString; - if (parseGpsText(qPrintable(gpsString), &lat, &lon)) { - setupDivesite(d, ds, lat, lon, qPrintable(myDive.location)); - diveChanged = true; - } + if (parseGpsText(qPrintable(gpsString), &lat, &lon)) + setupDivesite(res, d, ds, lat, lon, qPrintable(myDive.location)); } else { appendTextToLog("couldn't get GPS location in time"); } @@ -1035,7 +1044,7 @@ bool QMLManager::checkLocation(const DiveObjectHelper &myDive, struct dive *d, Q appendTextToLog(QString("wasn't able to parse gps string '%1'").arg(gps)); } } - return diveChanged; + return res.changed; } bool QMLManager::checkDuration(const DiveObjectHelper &myDive, struct dive *d, QString duration) @@ -1101,13 +1110,16 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt QString airtemp, QString watertemp, QString suit, QString buddy, QString diveMaster, QString weight, QString notes, QStringList startpressure, QStringList endpressure, QStringList gasmix, QStringList usedCylinder, int rating, int visibility, QString state) { - struct dive *d = get_dive_by_uniq_id(diveId.toInt()); + struct dive *orig = get_dive_by_uniq_id(diveId.toInt()); - if (!d) { + if (!orig) { appendTextToLog("cannot commit changes: no dive"); return; } + Command::OwningDivePtr d_ptr(alloc_dive()); // Automatically delete dive if we exit early! + dive *d = d_ptr.get(); + copy_dive(orig, d); DiveObjectHelper myDive(d); // notes comes back as rich text - let's convert this into plain text @@ -1116,11 +1128,11 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt notes = doc.toPlainText(); bool diveChanged = false; - bool needResort = false; - diveChanged = needResort = checkDate(myDive, d, date); + diveChanged = checkDate(myDive, d, date); - diveChanged |= checkLocation(myDive, d, location, gps); + DiveSiteChange dsChange; + diveChanged |= checkLocation(dsChange, myDive, d, location, gps); diveChanged |= checkDuration(myDive, d, duration); @@ -1251,22 +1263,6 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt } // now that we have it all figured out, let's see what we need // to update - DiveListModel *dm = DiveListModel::instance(); - int modelIdx = dm->getDiveIdx(d->id); - int oldIdx = get_idx_by_uniq_id(d->id); - if (needResort) { - // we know that the only thing that might happen in a resort is that - // this one dive moves to a different spot in the dive list - sort_dive_table(&dive_table); - sort_trip_table(&trip_table); - int newIdx = get_idx_by_uniq_id(d->id); - if (newIdx != oldIdx) { - DiveListModel::instance()->removeDive(modelIdx); - modelIdx += (newIdx - oldIdx); - DiveListModel::instance()->insertDive(modelIdx); - diveChanged = true; // because we already modified things - } - } if (diveChanged) { if (d->maxdepth.mm == d->dc.maxdepth.mm && d->maxdepth.mm > 0 && @@ -1280,12 +1276,9 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt fake_dc(&d->dc); } fixup_dive(d); - DiveListModel::instance()->updateDive(modelIdx, d); - invalidate_dive_cache(d); - mark_divelist_changed(true); - } - if (diveChanged || needResort) + Command::editDive(orig, d_ptr.release(), dsChange.createdDs.release(), dsChange.editDs, dsChange.location); // With release() we're giving up ownership changesNeedSaving(); + } } void QMLManager::changesNeedSaving() |