diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2020-04-19 18:48:23 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2020-05-06 13:58:09 -0700 |
commit | 4374605c1295ede804d1ae1355094f8a3e0429e9 (patch) | |
tree | c1ab60086a08627a8b3d10f25aef14339e5bc792 /commands/command_pictures.cpp | |
parent | 6ae2d36e381b4f676eb9d8c0e06245989ef16383 (diff) | |
download | subsurface-4374605c1295ede804d1ae1355094f8a3e0429e9.tar.gz |
undo: make adding of pictures undoable
This one is a bit hairy, because two things might happen if the
picture has a geo location:
- A dive gets a newly generated dive site set.
- The dive site of a dive is edited.
Therefore the undo command has to store keep track of that.
Oh my.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'commands/command_pictures.cpp')
-rw-r--r-- | commands/command_pictures.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/commands/command_pictures.cpp b/commands/command_pictures.cpp index 2e40c0362..66284fc86 100644 --- a/commands/command_pictures.cpp +++ b/commands/command_pictures.cpp @@ -2,6 +2,7 @@ #include "command_pictures.h" #include "core/subsurface-qt/divelistnotifier.h" +#include "qt-models/divelocationmodel.h" namespace Command { @@ -153,4 +154,87 @@ void RemovePictures::redo() picturesToAdd = removePictures(picturesToRemove); } +AddPictures::AddPictures(const std::vector<PictureListForAddition> &pictures) : picturesToAdd(pictures) +{ + // Sort the pictures according to the backend-rules. Moreover see if we have to set / create divesites. + size_t count = 0; + for (PictureListForAddition &p: picturesToAdd) { + count += p.pics.size(); + std::sort(p.pics.begin(), p.pics.end()); + + // Find a picture with a location + auto it = std::find_if(p.pics.begin(), p.pics.end(), [](const PictureObj &p) { return has_location(&p.location); }); + if (it != p.pics.end()) { + // There is a dive with a location, we might want to modify the dive accordingly. + struct dive_site *ds = p.d->dive_site; + if (!ds) { + // This dive doesn't yet have a dive site -> add a new dive site. + dive_site *ds = alloc_dive_site_with_gps("", &it->location); + sitesToAdd.emplace_back(ds); + sitesToSet.push_back({ p.d, ds }); + } else if (!dive_site_has_gps_location(ds)) { + // This dive has a dive site, but without coordinates. Let's add them. + sitesToEdit.push_back({ ds, it->location }); + } + } + } + + if (count == 0) { + picturesToAdd.clear(); // This signals that nothing is to be done + return; + } + setText(Command::Base::tr("add %n pictures(s)", "", count)); +} + +bool AddPictures::workToBeDone() +{ + return !picturesToAdd.empty(); +} + +void AddPictures::swapDiveSites() +{ + for (DiveSiteEntry &entry: sitesToSet) { + dive_site *ds = entry.d->dive_site; + if (ds) + unregister_dive_from_dive_site(entry.d); // the dive-site pointer in the dive is now NULL + std::swap(ds, entry.ds); + if (ds) + add_dive_to_dive_site(entry.d, ds); + emit diveListNotifier.divesChanged(QVector<dive *>{ entry.d }, DiveField::DIVESITE); + } + + for (DiveSiteEditEntry &entry: sitesToEdit) { + std::swap(entry.ds->location, entry.location); + emit diveListNotifier.diveSiteChanged(entry.ds, LocationInformationModel::LOCATION); // Inform frontend of changed dive site. + } +} + +void AddPictures::undo() +{ + swapDiveSites(); + picturesToAdd = removePictures(picturesToRemove); + + // Remove dive sites + for (dive_site *siteToRemove: sitesToRemove) { + int idx = unregister_dive_site(siteToRemove); + sitesToAdd.emplace_back(siteToRemove); + emit diveListNotifier.diveSiteDeleted(siteToRemove, idx); // Inform frontend of removed dive site. + } + sitesToRemove.clear(); +} + +void AddPictures::redo() +{ + // Add dive sites + for (OwningDiveSitePtr &siteToAdd: sitesToAdd) { + sitesToRemove.push_back(siteToAdd.get()); + int idx = register_dive_site(siteToAdd.release()); // Return ownership to backend. + emit diveListNotifier.diveSiteAdded(sitesToRemove.back(), idx); // Inform frontend of new dive site. + } + sitesToAdd.clear(); + + swapDiveSites(); + picturesToRemove = addPictures(picturesToAdd); +} + } // namespace Command |