mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
2009321894
commit
57b96490b2
7 changed files with 218 additions and 67 deletions
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue