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
|
@ -304,4 +304,11 @@ void editTripNotes(dive_trip *trip, const QString &s)
|
|||
execute(new EditTripNotes(trip, s));
|
||||
}
|
||||
|
||||
#ifdef SUBSURFACE_MOBILE
|
||||
void editDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *changeDs, location_t dsLocation)
|
||||
{
|
||||
execute(new EditDive(oldDive, newDive, createDs, changeDs, dsLocation));
|
||||
}
|
||||
#endif // SUBSURFACE_MOBILE
|
||||
|
||||
} // namespace Command
|
||||
|
|
|
@ -89,6 +89,11 @@ void editProfile(dive *d); // dive computer(s) and cylinder(s) will be reset!
|
|||
int addWeight(bool currentDiveOnly);
|
||||
int removeWeight(int index, bool currentDiveOnly);
|
||||
int editWeight(int index, weightsystem_t ws, bool currentDiveOnly);
|
||||
#ifdef SUBSURFACE_MOBILE
|
||||
// Edits a dive and creates a divesite (if createDs != NULL) or edits a divesite (if changeDs != NULL).
|
||||
// Takes ownership of newDive and createDs!
|
||||
void editDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *changeDs, location_t dsLocation);
|
||||
#endif
|
||||
|
||||
// 5) Trip editing commands
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include "core/subsurface-string.h"
|
||||
#include "core/tag.h"
|
||||
#include "qt-models/weightsysteminfomodel.h"
|
||||
#ifdef SUBSURFACE_MOBILE
|
||||
#include "qt-models/divelocationmodel.h"
|
||||
#endif
|
||||
|
||||
namespace Command {
|
||||
|
||||
|
@ -1145,4 +1148,134 @@ void EditWeight::undo()
|
|||
redo();
|
||||
}
|
||||
|
||||
#ifdef SUBSURFACE_MOBILE
|
||||
|
||||
EditDive::EditDive(dive *oldDiveIn, dive *newDiveIn, dive_site *createDs, dive_site *editDs, location_t dsLocationIn)
|
||||
: oldDive(oldDiveIn)
|
||||
, newDive(newDiveIn)
|
||||
, changedFields(DiveField::NONE)
|
||||
, siteToRemove(nullptr)
|
||||
, siteToAdd(createDs)
|
||||
, siteToEdit(editDs)
|
||||
, dsLocation(dsLocationIn)
|
||||
{
|
||||
if (!oldDive || ! newDive)
|
||||
return;
|
||||
|
||||
setText(tr("Edit dive"));
|
||||
|
||||
// Calculate the fields that changed.
|
||||
// Note: Probably not needed, as on mobile we don't have that granularity.
|
||||
// However, for future-proofeness let's just do it.
|
||||
changedFields = DiveField::NONE;
|
||||
if (oldDive->number != newDive->number)
|
||||
changedFields |= DiveField::NR;
|
||||
if (oldDive->when != newDive->when)
|
||||
changedFields |= DiveField::DATETIME;
|
||||
if (oldDive->maxdepth.mm != newDive->maxdepth.mm)
|
||||
changedFields |= DiveField::DEPTH;
|
||||
if (oldDive->duration.seconds != newDive->duration.seconds)
|
||||
changedFields |= DiveField::DURATION;
|
||||
if (oldDive->airtemp.mkelvin != newDive->airtemp.mkelvin)
|
||||
changedFields |= DiveField::AIR_TEMP;
|
||||
if (oldDive->watertemp.mkelvin != newDive->watertemp.mkelvin)
|
||||
changedFields |= DiveField::WATER_TEMP;
|
||||
if (oldDive->surface_pressure.mbar != newDive->surface_pressure.mbar)
|
||||
changedFields |= DiveField::ATM_PRESS;
|
||||
if (oldDive->dive_site != newDive->dive_site)
|
||||
changedFields |= DiveField::DIVESITE;
|
||||
if (!same_string(oldDive->divemaster, newDive->divemaster))
|
||||
changedFields |= DiveField::DIVEMASTER;
|
||||
if (!same_string(oldDive->buddy, newDive->buddy))
|
||||
changedFields |= DiveField::BUDDY;
|
||||
if (oldDive->rating != newDive->rating)
|
||||
changedFields |= DiveField::RATING;
|
||||
if (oldDive->visibility != newDive->visibility)
|
||||
changedFields |= DiveField::VISIBILITY;
|
||||
if (oldDive->wavesize != newDive->wavesize)
|
||||
changedFields |= DiveField::WAVESIZE;
|
||||
if (oldDive->current != newDive->current)
|
||||
changedFields |= DiveField::CURRENT;
|
||||
if (oldDive->surge != newDive->surge)
|
||||
changedFields |= DiveField::SURGE;
|
||||
if (oldDive->chill != newDive->chill)
|
||||
changedFields |= DiveField::CHILL;
|
||||
if (!same_string(oldDive->suit, newDive->suit))
|
||||
changedFields |= DiveField::SUIT;
|
||||
if (get_taglist_string(oldDive->tag_list) != get_taglist_string(newDive->tag_list)) // This is cheating. Do we have a taglist comparison function?
|
||||
changedFields |= DiveField::TAGS;
|
||||
if (oldDive->dc.divemode != newDive->dc.divemode)
|
||||
changedFields |= DiveField::MODE;
|
||||
if (!same_string(oldDive->notes, newDive->notes))
|
||||
changedFields |= DiveField::NOTES;
|
||||
if (oldDive->salinity != newDive->salinity)
|
||||
changedFields |= DiveField::SALINITY;
|
||||
}
|
||||
|
||||
void EditDive::undo()
|
||||
{
|
||||
if (siteToRemove) {
|
||||
int idx = unregister_dive_site(siteToRemove);
|
||||
siteToAdd.reset(siteToRemove);
|
||||
emit diveListNotifier.diveSiteDeleted(siteToRemove, idx); // Inform frontend of removed dive site.
|
||||
}
|
||||
|
||||
exchangeDives();
|
||||
editDs();
|
||||
}
|
||||
|
||||
void EditDive::redo()
|
||||
{
|
||||
if (siteToAdd) {
|
||||
siteToRemove = siteToAdd.get();
|
||||
int idx = register_dive_site(siteToAdd.release()); // Return ownership to backend.
|
||||
emit diveListNotifier.diveSiteAdded(siteToRemove, idx); // Inform frontend of new dive site.
|
||||
}
|
||||
|
||||
exchangeDives();
|
||||
editDs();
|
||||
}
|
||||
|
||||
void EditDive::exchangeDives()
|
||||
{
|
||||
// Bluntly exchange dive data by shallow copy
|
||||
std::swap(*newDive, *oldDive);
|
||||
invalidate_dive_cache(oldDive);
|
||||
|
||||
// Changing times may have unsorted the dive and trip tables
|
||||
QVector<dive *> dives = { oldDive };
|
||||
timestamp_t delta = oldDive->when - newDive->when;
|
||||
if (delta != 0) {
|
||||
sort_dive_table(&dive_table);
|
||||
sort_trip_table(&trip_table);
|
||||
if (newDive->divetrip != oldDive->divetrip)
|
||||
qWarning("Command::EditDive::redo(): This command does not support moving between trips!");
|
||||
if (oldDive->divetrip)
|
||||
sort_dive_table(&newDive->divetrip->dives); // Keep the trip-table in order
|
||||
emit diveListNotifier.divesTimeChanged(delta, dives);
|
||||
}
|
||||
|
||||
// Send signals
|
||||
emit diveListNotifier.divesChanged(dives, changedFields);
|
||||
|
||||
// Select the changed dives
|
||||
setSelection( { oldDive }, oldDive);
|
||||
}
|
||||
|
||||
void EditDive::editDs()
|
||||
{
|
||||
if (siteToEdit) {
|
||||
std::swap(siteToEdit->location, dsLocation);
|
||||
emit diveListNotifier.diveSiteChanged(siteToEdit, LocationInformationModel::LOCATION); // Inform frontend of changed dive site.
|
||||
}
|
||||
}
|
||||
|
||||
bool EditDive::workToBeDone()
|
||||
{
|
||||
// We trust the frontend that an EditDive command is only created if there are changes.
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // SUBSURFACE_MOBILE
|
||||
|
||||
} // namespace Command
|
||||
|
|
|
@ -375,6 +375,33 @@ private:
|
|||
void redo() override;
|
||||
};
|
||||
|
||||
#ifdef SUBSURFACE_MOBILE
|
||||
// Edit a full dive. This is used on mobile where we don't have per-field granularity.
|
||||
// It may add or edit a dive site.
|
||||
class EditDive : public Base {
|
||||
public:
|
||||
EditDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *editDs, location_t dsLocation); // Takes ownership of newDive
|
||||
private:
|
||||
dive *oldDive; // Dive that is going to be overwritten
|
||||
OwningDivePtr newDive; // New data
|
||||
int changedFields;
|
||||
|
||||
dive_site *siteToRemove;
|
||||
OwningDiveSitePtr siteToAdd;
|
||||
|
||||
dive_site *siteToEdit;
|
||||
location_t dsLocation;
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
bool workToBeDone() override;
|
||||
|
||||
void exchangeDives();
|
||||
void editDs();
|
||||
};
|
||||
|
||||
#endif // SUBSURFACE_MOBILE
|
||||
|
||||
} // namespace Command
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue