diff --git a/iphone/Maps/Bookmarks/BookmarksRootVC.mm b/iphone/Maps/Bookmarks/BookmarksRootVC.mm index 1dff504d08..af13397b66 100644 --- a/iphone/Maps/Bookmarks/BookmarksRootVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksRootVC.mm @@ -136,8 +136,7 @@ extern NSString * const kBookmarkCategoryDeletedNotification = withParameters:@{kStatValue : visible ? kStatVisible : kStatHidden}]; cell.imageView.image = [UIImage imageNamed:(visible ? @"ic_show" : @"ic_hide")]; cell.imageView.mwm_coloring = visible ? MWMImageColoringBlue : MWMImageColoringBlack; - bmManager.SetIsVisible(categoryId, visible); - bmManager.NotifyChanges(categoryId); + bmManager.GetEditSession().SetIsVisible(categoryId, visible); bmManager.SaveToKMLFile(categoryId); } } @@ -286,11 +285,12 @@ extern NSString * const kBookmarkCategoryDeletedNotification = [Statistics logEvent:kStatEventName(kStatPlacePage, kStatRemove)]; [NSNotificationCenter.defaultCenter postNotificationName:kBookmarkCategoryDeletedNotification object:@(indexPath.row)]; - Framework & f = GetFramework(); - f.DeleteBmCategory(indexPath.row); + auto & bmManager = GetFramework().GetBookmarkManager(); + auto categoryId = bmManager.GetBmGroupsIdList()[indexPath.row]; + bmManager.GetEditSession().DeleteBmCategory(categoryId); [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // Disable edit mode if no categories are left - if (f.GetBookmarkManager().GetBmGroupsIdList().empty()) + if (bmManager.GetBmGroupsIdList().empty()) { self.navigationItem.rightBarButtonItem = nil; [self setEditing:NO animated:YES]; diff --git a/iphone/Maps/Bookmarks/BookmarksVC.mm b/iphone/Maps/Bookmarks/BookmarksVC.mm index f77f281cba..3f3508dcfd 100644 --- a/iphone/Maps/Bookmarks/BookmarksVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksVC.mm @@ -85,8 +85,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica [Statistics logEvent:kStatEventName(kStatBookmarks, kStatToggleVisibility) withParameters:@{kStatValue : sender.on ? kStatVisible : kStatHidden}]; auto & bmManager = GetFramework().GetBookmarkManager(); - bmManager.SetIsVisible(m_categoryId, sender.on); - bmManager.NotifyChanges(m_categoryId); + bmManager.GetEditSession().SetIsVisible(m_categoryId, sender.on); bmManager.SaveToKMLFile(m_categoryId); } @@ -298,7 +297,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica if (indexPath.section == m_trackSection) { df::MarkID trackId = [[m_trackIds objectAtIndex:indexPath.row] intValue]; - bmManager.DeleteTrack(trackId); + bmManager.GetEditSession().DeleteTrack(trackId); [m_trackIds removeObjectAtIndex:indexPath.row]; } else @@ -307,14 +306,13 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica NSValue * value = [NSValue valueWithBytes:&bmId objCType:@encode(df::MarkID*)]; [NSNotificationCenter.defaultCenter postNotificationName:kBookmarkDeletedNotification object:value]; - bmManager.DeleteBookmark(bmId); + bmManager.GetEditSession().DeleteBookmark(bmId); [m_bookmarkIds removeObjectAtIndex:indexPath.row]; [NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification object:nil userInfo:nil]; } } - bmManager.NotifyChanges(m_categoryId); bmManager.SaveToKMLFile(m_categoryId); size_t previousNumberOfSections = m_numberOfSections; [self calculateSections]; diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm index 291e242b86..0456c1930b 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm @@ -51,8 +51,7 @@ static NSString * const kKeyPath = @"subviews"; Framework & f = GetFramework(); f.DeactivateMapSelection(true); auto & bmManager = f.GetBookmarkManager(); - bmManager.ClearGroup(UserMark::Type::API); - bmManager.NotifyChanges(UserMark::Type::API); + bmManager.GetEditSession().ClearGroup(UserMark::Type::API); NSURL * url = [NSURL URLWithString:@(f.GetApiDataHolder().GetGlobalBackUrl().c_str())]; [UIApplication.sharedApplication openURL:url]; } diff --git a/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm b/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm index 10d541fe01..cb97383f4a 100644 --- a/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm +++ b/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm @@ -94,14 +94,15 @@ static int const kInvalidCategoryId = 0; { [self.view endEditing:YES]; auto & f = GetFramework(); + BookmarkManager & bmManager = f.GetBookmarkManager(); + auto editSession = bmManager.GetEditSession(); if (self.cachedBmCatId != kInvalidCategoryId) { - f.MoveBookmark(m_cachedBookmarkId, m_cachedBookmarkCatId, self.cachedBmCatId); + editSession.MoveBookmark(m_cachedBookmarkId, m_cachedBookmarkCatId, self.cachedBmCatId); m_cachedBookmarkCatId = self.cachedBmCatId; } - BookmarkManager & bmManager = f.GetBookmarkManager(); - auto bookmark = bmManager.GetBookmarkForEdit(m_cachedBookmarkId); + auto bookmark = editSession.GetBookmarkForEdit(m_cachedBookmarkId); if (!bookmark) return; @@ -110,7 +111,6 @@ static int const kInvalidCategoryId = 0; bookmark->SetName(self.cachedTitle.UTF8String); bmManager.SaveToKMLFile(m_cachedBookmarkCatId); - bmManager.NotifyChanges(m_cachedBookmarkCatId); f.UpdatePlacePageInfoForCurrentSelection(); [self backTap]; diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm index a9c3242381..51f2391a19 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm @@ -434,9 +434,9 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS"; { auto const categoryId = f.LastEditedBMCategory(); BookmarkData bmData{m_info.FormatNewBookmarkName(), f.LastEditedBMType()}; - auto const * bookmark = bmManager.CreateBookmark(self.mercator, bmData, categoryId); + auto editSession = bmManager.GetEditSession(); + auto const * bookmark = editSession.CreateBookmark(self.mercator, bmData, categoryId); f.FillBookmarkInfo(*bookmark, m_info); - bmManager.NotifyChanges(categoryId); m_sections.insert(m_sections.begin() + 1, Sections::Bookmark); } else @@ -447,8 +447,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS"; { f.ResetBookmarkInfo(*bookmark, m_info); auto const categoryId = bookmark->GetGroupId(); - bmManager.DeleteBookmark(bookmarkId); - bmManager.NotifyChanges(categoryId); + bmManager.GetEditSession().DeleteBookmark(bookmarkId); bmManager.SaveToKMLFile(categoryId); } diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index b82c14089a..22d0e532b0 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -153,7 +153,10 @@ BookmarkManager::~BookmarkManager() ClearCategories(); } -//////////////////////////// +BookmarkManager::EditSession BookmarkManager::GetEditSession() +{ + return EditSession(*this); +} UserMark const * BookmarkManager::GetMark(df::MarkID markID) const { @@ -204,7 +207,8 @@ Bookmark * BookmarkManager::CreateBookmark(m2::PointD const & ptOrg, BookmarkDat group->AttachUserMark(bookmark->GetId()); group->SetIsVisible(true); SaveToKMLFile(groupID); - NotifyChanges(groupID); +// TODO(darina): get rid of this +// NotifyChanges(groupID); m_lastCategoryUrl = group->GetFileName(); m_lastType = bm.GetType(); @@ -305,7 +309,18 @@ void BookmarkManager::CollectDirtyGroups(df::GroupIDSet & dirtyGroups) } } -void BookmarkManager::NotifyChanges(df::MarkGroupID) +void BookmarkManager::OnEditSessionOpened() +{ + ++m_openedEditSessionsCount; +} + +void BookmarkManager::OnEditSessionClosed() +{ + if (!--m_openedEditSessionsCount) + NotifyChanges(); +} + +void BookmarkManager::NotifyChanges() { if (!m_changesTracker.CheckChanges()) return; @@ -645,12 +660,6 @@ boost::optional BookmarkManager::GetKMLPath(std::string const & fil return fileSavePath; } -void BookmarkManager::InitBookmarks() -{ - for (auto & cat : m_categories) - NotifyChanges(cat.first); -} - void BookmarkManager::MoveBookmark(df::MarkID bmID, df::MarkGroupID curGroupID, df::MarkGroupID newGroupID) { DetachBookmark(bmID, curGroupID); @@ -664,7 +673,6 @@ void BookmarkManager::UpdateBookmark(df::MarkID bmID, BookmarkData const & bm) bookmark->SetData(bm); ASSERT(bookmark->GetGroupId(), ()); SaveToKMLFile(bookmark->GetGroupId()); - NotifyChanges(bookmark->GetGroupId()); m_lastType = bm.GetType(); SaveState(); @@ -762,7 +770,8 @@ bool BookmarkManager::DeleteBmCategory(df::MarkGroupID groupID) // cat.DeleteLater(); FileWriter::DeleteFileX(group.GetFileName()); ClearGroup(groupID); - NotifyChanges(groupID); + // TODO(darina): think of a way to get rid of extra Notify here + NotifyChanges(); m_categories.erase(it); m_bmGroupsIdList.erase(std::remove(m_bmGroupsIdList.begin(), m_bmGroupsIdList.end(), groupID), m_bmGroupsIdList.end()); @@ -883,8 +892,8 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection) } } - for (auto & cat : m_categories) - NotifyChanges(cat.first); + // TODO(darina): Can we get rid of this Notify? + NotifyChanges(); } namespace @@ -1216,3 +1225,106 @@ void BookmarkManager::MarksChangesTracker::ResetChanges() m_removedMarks.clear(); m_updatedMarks.clear(); } + +BookmarkManager::EditSession::EditSession(BookmarkManager & manager) + : m_bmManager(manager) +{ + m_bmManager.OnEditSessionOpened(); +} + +BookmarkManager::EditSession::~EditSession() +{ + m_bmManager.OnEditSessionClosed(); +} + +Bookmark * BookmarkManager::EditSession::CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm) +{ + return m_bmManager.CreateBookmark(ptOrg, bm); +} + +Bookmark * BookmarkManager::EditSession::CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm, df::MarkGroupID groupID) +{ + return m_bmManager.CreateBookmark(ptOrg, bm, groupID); +} + +Track * BookmarkManager::EditSession::CreateTrack(m2::PolylineD const & polyline, Track::Params const & p) +{ + return m_bmManager.CreateTrack(polyline, p); +} + +/* +UserMark * BookmarkManager::EditSession::GetUserMarkForEdit(df::MarkID markID) +{ + return m_bmManager.GetUserMarkForEdit(markID); +}*/ + +Bookmark * BookmarkManager::EditSession::GetBookmarkForEdit(df::MarkID markID) +{ + return m_bmManager.GetBookmarkForEdit(markID); +} + +void BookmarkManager::EditSession::DeleteUserMark(df::MarkID markId) +{ + return m_bmManager.DeleteUserMark(markId); +} + +void BookmarkManager::EditSession::DeleteBookmark(df::MarkID bmId) +{ + return m_bmManager.DeleteBookmark(bmId); +} + +void BookmarkManager::EditSession::DeleteTrack(df::LineID trackID) +{ + return m_bmManager.DeleteTrack(trackID); +} + +void BookmarkManager::EditSession::ClearGroup(df::MarkGroupID groupID) +{ + return m_bmManager.ClearGroup(groupID); +} + +void BookmarkManager::EditSession::SetIsVisible(df::MarkGroupID groupId, bool visible) +{ + return m_bmManager.SetIsVisible(groupId, visible); +} + +void BookmarkManager::EditSession::MoveBookmark( + df::MarkID bmID, df::MarkGroupID curGroupID, df::MarkGroupID newGroupID) +{ + return m_bmManager.MoveBookmark(bmID, curGroupID, newGroupID); +} + +void BookmarkManager::EditSession::UpdateBookmark(df::MarkID bmId, BookmarkData const & bm) +{ + return m_bmManager.UpdateBookmark(bmId, bm); +} + +void BookmarkManager::EditSession::AttachBookmark(df::MarkID bmId, df::MarkGroupID groupID) +{ + return m_bmManager.AttachBookmark(bmId, groupID); +} + +void BookmarkManager::EditSession::DetachBookmark(df::MarkID bmId, df::MarkGroupID groupID) +{ + return m_bmManager.DetachBookmark(bmId, groupID); +} + +void BookmarkManager::EditSession::AttachTrack(df::LineID trackID, df::MarkGroupID groupID) +{ + return m_bmManager.AttachTrack(trackID, groupID); +} + +void BookmarkManager::EditSession::DetachTrack(df::LineID trackID, df::MarkGroupID groupID) +{ + return m_bmManager.DetachTrack(trackID, groupID); +} + +bool BookmarkManager::EditSession::DeleteBmCategory(df::MarkGroupID groupID) +{ + return m_bmManager.DeleteBmCategory(groupID); +} + +void BookmarkManager::EditSession::NotifyChanges() +{ + return m_bmManager.NotifyChanges(); +} diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index f8145979e7..f53bab679a 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -22,17 +22,14 @@ class BookmarkManager final { + using UserMarkLayers = std::vector>; using CategoriesCollection = std::map>; + using MarksCollection = std::map>; using BookmarksCollection = std::map>; using TracksCollection = std::map>; - using CategoryIter = CategoriesCollection::iterator; - using GroupIdList = std::vector; - - using UserMarkLayers = std::vector>; public: - using AsyncLoadingStartedCallback = std::function; using AsyncLoadingFinishedCallback = std::function; using AsyncLoadingFileCallback = std::function; @@ -67,31 +64,74 @@ public: DeletedBookmarksCallback m_deletedBookmarksCallback; }; + class EditSession + { + public: + EditSession(BookmarkManager & bmManager); + ~EditSession(); + + template + UserMarkT * CreateUserMark(m2::PointD const & ptOrg) + { + return m_bmManager.CreateUserMark(ptOrg); + } + + Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm); + Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm, df::MarkGroupID groupID); + Track * CreateTrack(m2::PolylineD const & polyline, Track::Params const & p); + + template + UserMarkT * GetMarkForEdit(df::MarkID markId) + { + return m_bmManager.GetMarkForEdit(markId); + } + + //UserMark * GetUserMarkForEdit(df::MarkID markID); + Bookmark * GetBookmarkForEdit(df::MarkID markID); + + template + void DeleteUserMarks(UserMark::Type type, F deletePredicate) + { + return m_bmManager.DeleteUserMarks(type, deletePredicate); + }; + + void DeleteUserMark(df::MarkID markId); + void DeleteBookmark(df::MarkID bmId); + void DeleteTrack(df::LineID trackID); + + void ClearGroup(df::MarkGroupID groupID); + + void SetIsVisible(df::MarkGroupID groupId, bool visible); + + void MoveBookmark(df::MarkID bmID, df::MarkGroupID curGroupID, df::MarkGroupID newGroupID); + void UpdateBookmark(df::MarkID bmId, BookmarkData const & bm); + + void AttachBookmark(df::MarkID bmId, df::MarkGroupID groupID); + void DetachBookmark(df::MarkID bmId, df::MarkGroupID groupID); + + void AttachTrack(df::LineID trackID, df::MarkGroupID groupID); + void DetachTrack(df::LineID trackID, df::MarkGroupID groupID); + + bool DeleteBmCategory(df::MarkGroupID groupID); + + void NotifyChanges(); + + private: + BookmarkManager & m_bmManager; + }; + explicit BookmarkManager(Callbacks && callbacks); ~BookmarkManager(); - template - UserMarkT * CreateUserMark(m2::PointD const & ptOrg) - { - auto mark = std::make_unique(ptOrg); - auto * m = mark.get(); - auto const markId = m->GetId(); - auto const groupId = static_cast(m->GetMarkType()); - ASSERT(m_userMarks.count(markId) == 0, ()); - ASSERT_LESS(groupId, m_userMarkLayers.size(), ()); - m_userMarks.emplace(markId, std::move(mark)); - m_changesTracker.OnAddMark(markId); - m_userMarkLayers[groupId]->AttachUserMark(markId); - return m; - } + void SetDrapeEngine(ref_ptr engine); - template - UserMarkT * GetMarkForEdit(df::MarkID markId) - { - auto * mark = GetUserMarkForEdit(markId); - ASSERT(dynamic_cast(mark) != nullptr, ()); - return static_cast(mark); - } + void SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks); + bool IsAsyncLoadingInProgress() const { return m_asyncLoadingInProgress; } + + EditSession GetEditSession(); + + void UpdateViewport(ScreenBase const & screen); + void Teardown(); template UserMarkT const * GetMark(df::MarkID markId) const @@ -101,53 +141,34 @@ public: return static_cast(mark); } - template - void DeleteUserMarks(UserMark::Type type, F deletePredicate) - { - std::list marksToDelete; - for (auto markId : GetUserMarkIds(type)) - { - if (deletePredicate(GetMark(markId))) - marksToDelete.push_back(markId); - } - // Delete after iterating to avoid iterators invalidation issues. - for (auto markId : marksToDelete) - DeleteUserMark(markId); - }; - UserMark const * GetUserMark(df::MarkID markID) const; - UserMark * GetUserMarkForEdit(df::MarkID markID); - void DeleteUserMark(df::MarkID markId); - - Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm); - Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm, df::MarkGroupID groupID); Bookmark const * GetBookmark(df::MarkID markID) const; - Bookmark * GetBookmarkForEdit(df::MarkID markID); - void AttachBookmark(df::MarkID bmId, df::MarkGroupID groupID); - void DetachBookmark(df::MarkID bmId, df::MarkGroupID groupID); - void DeleteBookmark(df::MarkID bmId); - - Track * CreateTrack(m2::PolylineD const & polyline, Track::Params const & p); Track const * GetTrack(df::LineID trackID) const; - void AttachTrack(df::LineID trackID, df::MarkGroupID groupID); - void DetachTrack(df::LineID trackID, df::MarkGroupID groupID); - void DeleteTrack(df::LineID trackID); - - ////////////////// - void ClearGroup(df::MarkGroupID groupID); - - void NotifyChanges(df::MarkGroupID groupID); df::MarkIDSet const & GetUserMarkIds(df::MarkGroupID groupID) const; df::LineIDSet const & GetTrackIds(df::MarkGroupID groupID) const; + bool IsVisible(df::MarkGroupID groupId) const; + + df::MarkGroupID CreateBmCategory(std::string const & name); + std::string const & GetCategoryName(df::MarkGroupID categoryId) const; + std::string const & GetCategoryFileName(df::MarkGroupID categoryId) const; void SetCategoryName(df::MarkGroupID categoryId, std::string const & name); + df::GroupIDList const & GetBmGroupsIdList() const { return m_bmGroupsIdList; } + bool HasBmCategory(df::MarkGroupID groupID) const; + df::MarkGroupID LastEditedBMCategory(); + std::string LastEditedBMType() const; + + using TTouchRectHolder = function; + UserMark const * FindNearestUserMark(TTouchRectHolder const & holder) const; + UserMark const * FindNearestUserMark(m2::AnyRectD const & rect) const; UserMark const * FindMarkInRect(df::MarkGroupID groupId, m2::AnyRectD const & rect, double & d) const; - void SetIsVisible(df::MarkGroupID groupId, bool visible); - bool IsVisible(df::MarkGroupID groupId) const; + /// Scans and loads all kml files with bookmarks in WritableDir. + void LoadBookmarks(); + void LoadBookmark(std::string const & filePath, bool isTemporaryFile); /// Uses the same file name from which was loaded, or /// creates unique file name on first save and uses it every time. @@ -156,50 +177,12 @@ public: /// You don't need to call it from client code. void SaveToKML(BookmarkCategory * group, std::ostream & s); - std::string const & GetCategoryFileName(df::MarkGroupID categoryId) const; - ////////////////// - - void SetDrapeEngine(ref_ptr engine); - void UpdateViewport(ScreenBase const & screen); - void SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks); - void Teardown(); - - void ClearCategories(); - - /// Scans and loads all kml files with bookmarks in WritableDir. - void LoadBookmarks(); - void LoadBookmark(std::string const & filePath, bool isTemporaryFile); - - void InitBookmarks(); - - /// Client should know where it moves bookmark - void MoveBookmark(df::MarkID bmID, df::MarkGroupID curGroupID, df::MarkGroupID newGroupID); - void UpdateBookmark(df::MarkID bmId, BookmarkData const & bm); - - df::MarkGroupID LastEditedBMCategory(); - std::string LastEditedBMType() const; - - GroupIdList const & GetBmGroupsIdList() const { return m_bmGroupsIdList; } - bool HasBmCategory(df::MarkGroupID groupID) const; - - df::MarkGroupID CreateBmCategory(std::string const & name); - - /// @name Delete bookmarks category with all bookmarks. - /// @return true if category was deleted - bool DeleteBmCategory(df::MarkGroupID groupID); - - using TTouchRectHolder = function; - - UserMark const * FindNearestUserMark(m2::AnyRectD const & rect) const; - UserMark const * FindNearestUserMark(TTouchRectHolder const & holder) const; - StaticMarkPoint & SelectionMark() { return *m_selectionMark; } StaticMarkPoint const & SelectionMark() const { return *m_selectionMark; } + MyPositionMarkPoint & MyPositionMark() { return *m_myPositionMark; } MyPositionMarkPoint const & MyPositionMark() const { return *m_myPositionMark; } - bool IsAsyncLoadingInProgress() const { return m_asyncLoadingInProgress; } - private: class MarksChangesTracker : public df::UserMarksProvider { @@ -236,6 +219,69 @@ private: using KMLDataCollection = std::vector>; + template + UserMarkT * CreateUserMark(m2::PointD const & ptOrg) + { + auto mark = std::make_unique(ptOrg); + auto * m = mark.get(); + auto const markId = m->GetId(); + auto const groupId = static_cast(m->GetMarkType()); + ASSERT(m_userMarks.count(markId) == 0, ()); + ASSERT_LESS(groupId, m_userMarkLayers.size(), ()); + m_userMarks.emplace(markId, std::move(mark)); + m_changesTracker.OnAddMark(markId); + m_userMarkLayers[groupId]->AttachUserMark(markId); + return m; + } + + template + UserMarkT * GetMarkForEdit(df::MarkID markId) + { + auto * mark = GetUserMarkForEdit(markId); + ASSERT(dynamic_cast(mark) != nullptr, ()); + return static_cast(mark); + } + + template + void DeleteUserMarks(UserMark::Type type, F deletePredicate) + { + std::list marksToDelete; + for (auto markId : GetUserMarkIds(type)) + { + if (deletePredicate(GetMark(markId))) + marksToDelete.push_back(markId); + } + // Delete after iterating to avoid iterators invalidation issues. + for (auto markId : marksToDelete) + DeleteUserMark(markId); + }; + + UserMark * GetUserMarkForEdit(df::MarkID markID); + void DeleteUserMark(df::MarkID markId); + + Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm); + Bookmark * CreateBookmark(m2::PointD const & ptOrg, BookmarkData & bm, df::MarkGroupID groupID); + + Bookmark * GetBookmarkForEdit(df::MarkID markID); + void AttachBookmark(df::MarkID bmId, df::MarkGroupID groupID); + void DetachBookmark(df::MarkID bmId, df::MarkGroupID groupID); + void DeleteBookmark(df::MarkID bmId); + + Track * CreateTrack(m2::PolylineD const & polyline, Track::Params const & p); + + void AttachTrack(df::LineID trackID, df::MarkGroupID groupID); + void DetachTrack(df::LineID trackID, df::MarkGroupID groupID); + void DeleteTrack(df::LineID trackID); + + void ClearGroup(df::MarkGroupID groupID); + void SetIsVisible(df::MarkGroupID groupId, bool visible); + + bool DeleteBmCategory(df::MarkGroupID groupID); + void ClearCategories(); + + void MoveBookmark(df::MarkID bmID, df::MarkGroupID curGroupID, df::MarkGroupID newGroupID); + void UpdateBookmark(df::MarkID bmId, BookmarkData const & bm); + static bool IsBookmarkCategory(df::MarkGroupID groupId) { return groupId >= UserMark::BOOKMARK; } static bool IsBookmark(df::MarkID markID) { return UserMark::GetMarkType(markID) == UserMark::BOOKMARK; } @@ -248,6 +294,10 @@ private: Bookmark * AddBookmark(std::unique_ptr && bookmark); Track * AddTrack(std::unique_ptr && track); + void OnEditSessionOpened(); + void OnEditSessionClosed(); + void NotifyChanges(); + void SaveState() const; void LoadState(); void CreateCategories(KMLDataCollection && dataCollection); @@ -269,6 +319,7 @@ private: AsyncLoadingCallbacks m_asyncLoadingCallbacks; std::atomic m_needTeardown; df::MarkGroupID m_nextGroupID; + uint32_t m_openedEditSessionsCount = 0; bool m_loadBookmarksFinished = false; ScreenBase m_viewport; diff --git a/map/framework.cpp b/map/framework.cpp index 3dcef1099e..2a67508b82 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -733,33 +733,11 @@ void Framework::LoadBookmarks() GetBookmarkManager().LoadBookmarks(); } -df::MarkID Framework::AddBookmark(df::MarkGroupID catId, const m2::PointD & ptOrg, BookmarkData & bm) -{ - GetPlatform().GetMarketingService().SendMarketingEvent(marketing::kBookmarksBookmarkAction, - {{"action", "create"}}); - return GetBookmarkManager().CreateBookmark(ptOrg, bm, catId)->GetId(); -} - -void Framework::MoveBookmark(df::MarkID bmId, df::MarkGroupID curCatId, df::MarkGroupID newCatId) -{ - return GetBookmarkManager().MoveBookmark(bmId, curCatId, newCatId); -} - -void Framework::ReplaceBookmark(df::MarkID bmId, BookmarkData const & bm) -{ - GetBookmarkManager().UpdateBookmark(bmId, bm); -} - df::MarkGroupID Framework::AddCategory(string const & categoryName) { return GetBookmarkManager().CreateBmCategory(categoryName); } -bool Framework::DeleteBmCategory(size_t index) -{ - return GetBookmarkManager().DeleteBmCategory(index); -} - void Framework::FillBookmarkInfo(Bookmark const & bmk, place_page::Info & info) const { info.SetBookmarkCategoryName(GetBookmarkManager().GetCategoryName(bmk.GetGroupId())); @@ -1044,11 +1022,6 @@ void Framework::ShowFeatureByMercator(m2::PointD const & pt) m_lastTapEvent = MakeTapEvent(info.GetMercator(), info.GetID(), TapEvent::Source::Other); } -void Framework::ClearBookmarks() -{ - GetBookmarkManager().ClearCategories(); -} - void Framework::AddBookmarksFile(string const & filePath, bool isTemporaryFile) { GetBookmarkManager().LoadBookmark(filePath, isTemporaryFile); @@ -1603,10 +1576,10 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be search::Results::ConstIter end, SearchMarkPostProcesing fn /* = nullptr */) { - auto & bmManager = GetBookmarkManager(); + auto editSession = GetBookmarkManager().GetEditSession(); if (clear) - bmManager.ClearGroup(UserMark::Type::SEARCH); - bmManager.SetIsVisible(UserMark::Type::SEARCH, true); + editSession.ClearGroup(UserMark::Type::SEARCH); + editSession.SetIsVisible(UserMark::Type::SEARCH, true); for (auto it = begin; it != end; ++it) { @@ -1614,7 +1587,7 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be if (!r.HasPoint()) continue; - auto * mark = bmManager.CreateUserMark(r.GetFeatureCenter()); + auto * mark = editSession.CreateUserMark(r.GetFeatureCenter()); auto const isFeature = r.GetResultType() == search::Result::Type::Feature; if (isFeature) mark->SetFoundFeature(r.GetFeatureID()); @@ -1632,13 +1605,6 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be if (fn) fn(*mark); } - bmManager.NotifyChanges(UserMark::Type::SEARCH); -} - -void Framework::ClearSearchResultsMarks() -{ - GetBookmarkManager().ClearGroup(UserMark::Type::SEARCH); - GetBookmarkManager().NotifyChanges(UserMark::Type::SEARCH); } bool Framework::GetDistanceAndAzimut(m2::PointD const & point, @@ -2029,10 +1995,9 @@ url_scheme::ParsedMapApi::ParsingResult Framework::ParseAndSetApiURL(string cons // Clear every current API-mark. { - auto & bmManager = GetBookmarkManager(); - bmManager.ClearGroup(UserMark::Type::API); - bmManager.SetIsVisible(UserMark::Type::API, true); - bmManager.NotifyChanges(UserMark::Type::API); + auto editSession = GetBookmarkManager().GetEditSession(); + editSession.ClearGroup(UserMark::Type::API); + editSession.SetIsVisible(UserMark::Type::API, true); } return m_ParsedMapApi.SetUriAndParse(url); @@ -2165,13 +2130,7 @@ void Framework::UpdatePlacePageInfoForCurrentSelection() void Framework::InvalidateUserMarks() { - GetBookmarkManager().InitBookmarks(); - - std::vector const types = {UserMark::Type::SEARCH, UserMark::Type::API, - UserMark::Type::DEBUG_MARK, UserMark::Type::ROUTING, - UserMark::Type::LOCAL_ADS, UserMark::Type::STATIC}; - for (size_t typeIndex = 0; typeIndex < types.size(); typeIndex++) - GetBookmarkManager().NotifyChanges(types[typeIndex]); + GetBookmarkManager().GetEditSession(); } void Framework::OnTapEvent(TapEvent const & tapEvent) @@ -3184,7 +3143,7 @@ void Framework::ShowViewportSearchResults(bool clear, search::Results::ConstIter void Framework::ClearViewportSearchResults() { - ClearSearchResultsMarks(); + GetBookmarkManager().GetEditSession().ClearGroup(UserMark::Type::SEARCH); } boost::optional Framework::GetCurrentPosition() const diff --git a/map/framework.hpp b/map/framework.hpp index c37010bc2d..9379295875 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -315,27 +315,17 @@ public: /// Scans and loads all kml files with bookmarks in WritableDir. void LoadBookmarks(); - /// @return Created bookmark id. - df::MarkID AddBookmark(df::MarkGroupID catId, m2::PointD const & ptOrg, BookmarkData & bm); - void MoveBookmark(df::MarkID bmId, df::MarkGroupID curCatId, df::MarkGroupID newCatId); - void ReplaceBookmark(df::MarkID bmId, BookmarkData const & bm); /// @return Created bookmark category id. df::MarkGroupID AddCategory(string const & categoryName); - size_t LastEditedBMCategory() { return GetBookmarkManager().LastEditedBMCategory(); } + df::MarkGroupID LastEditedBMCategory() { return GetBookmarkManager().LastEditedBMCategory(); } string LastEditedBMType() const { return GetBookmarkManager().LastEditedBMType(); } - /// Delete bookmarks category with all bookmarks. - /// @return true if category was deleted - bool DeleteBmCategory(size_t index); - void ShowBookmark(df::MarkID id); void ShowBookmark(Bookmark const * bookmark); void ShowTrack(Track const & track); void ShowFeatureByMercator(m2::PointD const & pt); - void ClearBookmarks(); - void AddBookmarksFile(string const & filePath, bool isTemporaryFile); BookmarkManager & GetBookmarkManager(); @@ -556,8 +546,6 @@ public: void FillSearchResultsMarks(bool clear, search::Results const & results); void FillSearchResultsMarks(bool clear, search::Results::ConstIter begin, search::Results::ConstIter end, SearchMarkPostProcesing fn = nullptr); - void ClearSearchResultsMarks(); - list const & GetLastSearchQueries() const { return m_searchQuerySaver.Get(); } void SaveSearchQuery(TSearchRequest const & query) { m_searchQuerySaver.Add(query); } void ClearSearchHistory() { m_searchQuerySaver.Clear(); } diff --git a/map/local_ads_manager.cpp b/map/local_ads_manager.cpp index 54c051e53f..970c2f7493 100644 --- a/map/local_ads_manager.cpp +++ b/map/local_ads_manager.cpp @@ -144,13 +144,13 @@ void CreateLocalAdsMarks(BookmarkManager * bmManager, CampaignData const & campa // Here we copy campaign data, because we can create user marks only from UI thread. GetPlatform().RunTask(Platform::Thread::Gui, [bmManager, campaignData]() { + auto editSession = bmManager->GetEditSession(); for (auto const & data : campaignData) { - auto * mark = bmManager->CreateUserMark(data.second.m_position); + auto * mark = editSession.CreateUserMark(data.second.m_position); mark->SetData(LocalAdsMarkData(data.second)); mark->SetFeatureId(data.first); } - bmManager->NotifyChanges(UserMark::Type::LOCAL_ADS); }); } @@ -161,12 +161,11 @@ void DeleteLocalAdsMarks(BookmarkManager * bmManager, MwmSet::MwmId const & mwmI GetPlatform().RunTask(Platform::Thread::Gui, [bmManager, mwmId]() { - bmManager->DeleteUserMarks(UserMark::Type::LOCAL_ADS, - [&mwmId](LocalAdsMark const * mark) - { - return mark->GetFeatureID().m_mwmId == mwmId; - }); - bmManager->NotifyChanges(UserMark::Type::LOCAL_ADS); + bmManager->GetEditSession().DeleteUserMarks(UserMark::Type::LOCAL_ADS, + [&mwmId](LocalAdsMark const * mark) + { + return mark->GetFeatureID().m_mwmId == mwmId; + }); }); } @@ -177,8 +176,7 @@ void DeleteAllLocalAdsMarks(BookmarkManager * bmManager) GetPlatform().RunTask(Platform::Thread::Gui, [bmManager]() { - bmManager->ClearGroup(UserMark::Type::LOCAL_ADS); - bmManager->NotifyChanges(UserMark::Type::LOCAL_ADS); + bmManager->GetEditSession().ClearGroup(UserMark::Type::LOCAL_ADS); }); } diff --git a/map/mwm_url.cpp b/map/mwm_url.cpp index 40d64cba1b..4a24bbccc3 100644 --- a/map/mwm_url.cpp +++ b/map/mwm_url.cpp @@ -193,15 +193,15 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri) return ParsingResult::Incorrect; ASSERT(m_bmManager != nullptr, ()); + auto editSession = m_bmManager->GetEditSession(); for (auto const & p : points) { m2::PointD glPoint(MercatorBounds::FromLatLon(p.m_lat, p.m_lon)); - auto * mark = m_bmManager->CreateUserMark(glPoint); + auto * mark = editSession.CreateUserMark(glPoint); mark->SetName(p.m_name); mark->SetApiID(p.m_id); mark->SetStyle(style::GetSupportedStyle(p.m_style, p.m_name, "")); } - m_bmManager->NotifyChanges(UserMark::Type::API); return ParsingResult::Map; } diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index 2cbfa2746d..5750942600 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -334,7 +334,6 @@ void RoutingManager::OnRoutePointPassed(RouteMarkType type, size_t intermediateI ASSERT(m_bmManager != nullptr, ()); RoutePointsLayout routePoints(*m_bmManager); routePoints.PassRoutePoint(type, intermediateIndex); - routePoints.NotifyChanges(); if (type == RouteMarkType::Finish) RemoveRoute(false /* deactivateFollowing */); @@ -410,8 +409,7 @@ void RoutingManager::SetRouterImpl(RouterType type) void RoutingManager::RemoveRoute(bool deactivateFollowing) { - m_bmManager->ClearGroup(UserMark::Type::TRANSIT); - m_bmManager->NotifyChanges(UserMark::Type::TRANSIT); + m_bmManager->GetEditSession().ClearGroup(UserMark::Type::TRANSIT); if (deactivateFollowing) SetPointsFollowingMode(false /* enabled */); @@ -578,9 +576,7 @@ void RoutingManager::CloseRouting(bool removeRoutePoints) if (removeRoutePoints) { - m_bmManager->ClearGroup(UserMark::Type::ROUTING); - m_bmManager->NotifyChanges(UserMark::Type::ROUTING); - + m_bmManager->GetEditSession().ClearGroup(UserMark::Type::ROUTING); CancelRecommendation(Recommendation::RebuildAfterPointsLoading); } } @@ -593,18 +589,15 @@ void RoutingManager::SetLastUsedRouter(RouterType type) void RoutingManager::HideRoutePoint(RouteMarkType type, size_t intermediateIndex) { RoutePointsLayout routePoints(*m_bmManager); - RouteMarkPoint * mark = routePoints.GetRoutePoint(type, intermediateIndex); + RouteMarkPoint * mark = routePoints.GetRoutePointForEdit(type, intermediateIndex); if (mark != nullptr) - { mark->SetIsVisible(false); - routePoints.NotifyChanges(); - } } bool RoutingManager::IsMyPosition(RouteMarkType type, size_t intermediateIndex) { RoutePointsLayout routePoints(*m_bmManager); - RouteMarkPoint * mark = routePoints.GetRoutePoint(type, intermediateIndex); + RouteMarkPoint const * mark = routePoints.GetRoutePoint(type, intermediateIndex); return mark != nullptr ? mark->IsMyPosition() : false; } @@ -643,7 +636,7 @@ void RoutingManager::AddRoutePoint(RouteMarkData && markData) if (markData.m_isMyPosition) { - RouteMarkPoint * mark = routePoints.GetMyPositionPoint(); + RouteMarkPoint const * mark = routePoints.GetMyPositionPoint(); if (mark != nullptr) routePoints.RemoveRoutePoint(mark->GetRoutePointType(), mark->GetIntermediateIndex()); } @@ -651,7 +644,6 @@ void RoutingManager::AddRoutePoint(RouteMarkData && markData) markData.m_isVisible = !markData.m_isMyPosition; routePoints.AddRoutePoint(move(markData)); ReorderIntermediatePoints(); - routePoints.NotifyChanges(); } void RoutingManager::RemoveRoutePoint(RouteMarkType type, size_t intermediateIndex) @@ -659,7 +651,6 @@ void RoutingManager::RemoveRoutePoint(RouteMarkType type, size_t intermediateInd ASSERT(m_bmManager != nullptr, ()); RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveRoutePoint(type, intermediateIndex); - routePoints.NotifyChanges(); } void RoutingManager::RemoveRoutePoints() @@ -667,7 +658,6 @@ void RoutingManager::RemoveRoutePoints() ASSERT(m_bmManager != nullptr, ()); RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveRoutePoints(); - routePoints.NotifyChanges(); } void RoutingManager::RemoveIntermediateRoutePoints() @@ -675,7 +665,6 @@ void RoutingManager::RemoveIntermediateRoutePoints() ASSERT(m_bmManager != nullptr, ()); RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveIntermediateRoutePoints(); - routePoints.NotifyChanges(); } void RoutingManager::MoveRoutePoint(RouteMarkType currentType, size_t currentIntermediateIndex, @@ -685,7 +674,6 @@ void RoutingManager::MoveRoutePoint(RouteMarkType currentType, size_t currentInt RoutePointsLayout routePoints(*m_bmManager); routePoints.MoveRoutePoint(currentType, currentIntermediateIndex, targetType, targetIntermediateIndex); - routePoints.NotifyChanges(); } void RoutingManager::MoveRoutePoint(size_t currentIndex, size_t targetIndex) @@ -718,7 +706,6 @@ void RoutingManager::MoveRoutePoint(size_t currentIndex, size_t targetIndex) convertIndex(targetType, targetIndex); routePoints.MoveRoutePoint(currentType, currentIndex, targetType, targetIndex); - routePoints.NotifyChanges(); } void RoutingManager::SetPointsFollowingMode(bool enabled) @@ -726,7 +713,6 @@ void RoutingManager::SetPointsFollowingMode(bool enabled) ASSERT(m_bmManager != nullptr, ()); RoutePointsLayout routePoints(*m_bmManager); routePoints.SetFollowingMode(enabled); - routePoints.NotifyChanges(); } void RoutingManager::ReorderIntermediatePoints() @@ -768,8 +754,6 @@ void RoutingManager::ReorderIntermediatePoints() addedPoint->SetIntermediateIndex(insertIndex); for (size_t i = 0; i < prevPoints.size(); ++i) prevPoints[i]->SetIntermediateIndex(i < insertIndex ? i : i + 1); - - routePoints.NotifyChanges(); } void RoutingManager::GenerateTurnNotifications(vector & turnNotifications) @@ -784,8 +768,7 @@ void RoutingManager::BuildRoute(uint32_t timeoutSec) { ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); - m_bmManager->ClearGroup(UserMark::Type::TRANSIT); - m_bmManager->NotifyChanges(UserMark::Type::TRANSIT); + m_bmManager->GetEditSession().ClearGroup(UserMark::Type::TRANSIT); auto routePoints = GetRoutePoints(); if (routePoints.size() < 2) @@ -1129,11 +1112,11 @@ void RoutingManager::CancelRoutePointsTransaction(uint32_t transactionId) // Revert route points. ASSERT(m_bmManager != nullptr, ()); - m_bmManager->ClearGroup(UserMark::Type::ROUTING); + auto editSession = m_bmManager->GetEditSession(); + editSession.ClearGroup(UserMark::Type::ROUTING); RoutePointsLayout routePoints(*m_bmManager); for (auto & markData : routeMarks) routePoints.AddRoutePoint(move(markData)); - routePoints.NotifyChanges(); } bool RoutingManager::HasSavedRoutePoints() const @@ -1169,7 +1152,8 @@ bool RoutingManager::LoadRoutePoints() // If we have found my position, we use my position as start point. auto const & myPosMark = m_bmManager->MyPositionMark(); ASSERT(m_bmManager != nullptr, ()); - m_bmManager->ClearGroup(UserMark::Type::ROUTING); + auto editSession = m_bmManager->GetEditSession(); + editSession.ClearGroup(UserMark::Type::ROUTING); for (auto & p : points) { if (p.m_pointType == RouteMarkType::Start && myPosMark.HasPosition()) diff --git a/map/routing_mark.cpp b/map/routing_mark.cpp index b861d992c0..2d35be7265 100644 --- a/map/routing_mark.cpp +++ b/map/routing_mark.cpp @@ -174,15 +174,16 @@ size_t const RoutePointsLayout::kMaxIntermediatePointsCount = 3; RoutePointsLayout::RoutePointsLayout(BookmarkManager & manager) : m_manager(manager) + , m_editSession(manager.GetEditSession()) {} -RouteMarkPoint * RoutePointsLayout::AddRoutePoint(RouteMarkData && data) +void RoutePointsLayout::AddRoutePoint(RouteMarkData && data) { auto const count = m_manager.GetUserMarkIds(UserMark::Type::ROUTING).size(); if (count == kMaxIntermediatePointsCount + 2) - return nullptr; + return; - RouteMarkPoint * sameTypePoint = GetRoutePoint(data.m_pointType, data.m_intermediateIndex); + RouteMarkPoint * sameTypePoint = GetRoutePointForEdit(data.m_pointType, data.m_intermediateIndex); if (sameTypePoint != nullptr) { if (data.m_pointType == RouteMarkType::Finish) @@ -216,10 +217,8 @@ RouteMarkPoint * RoutePointsLayout::AddRoutePoint(RouteMarkData && data) } } } - auto * newPoint = m_manager.CreateUserMark(data.m_position); + auto * newPoint = m_editSession.CreateUserMark(data.m_position); newPoint->SetMarkData(std::move(data)); - - return newPoint; } bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, size_t intermediateIndex) @@ -273,28 +272,29 @@ bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, size_t intermediate }); } - m_manager.DeleteUserMark(point->GetId()); + m_editSession.DeleteUserMark(point->GetId()); return true; } void RoutePointsLayout::RemoveRoutePoints() { - m_manager.ClearGroup(UserMark::Type::ROUTING); + m_editSession.ClearGroup(UserMark::Type::ROUTING); } void RoutePointsLayout::RemoveIntermediateRoutePoints() { - m_manager.DeleteUserMarks(UserMark::Type::ROUTING, - [](RouteMarkPoint const * mark) - { - return mark->GetRoutePointType() == RouteMarkType::Intermediate; - }); + m_editSession.DeleteUserMarks( + UserMark::Type::ROUTING, + [](RouteMarkPoint const * mark) + { + return mark->GetRoutePointType() == RouteMarkType::Intermediate; + }); } bool RoutePointsLayout::MoveRoutePoint(RouteMarkType currentType, size_t currentIntermediateIndex, RouteMarkType destType, size_t destIntermediateIndex) { - RouteMarkPoint * point = GetRoutePoint(currentType, currentIntermediateIndex); + RouteMarkPoint const * point = GetRoutePoint(currentType, currentIntermediateIndex); if (point == nullptr) return false; @@ -310,7 +310,7 @@ bool RoutePointsLayout::MoveRoutePoint(RouteMarkType currentType, size_t current void RoutePointsLayout::PassRoutePoint(RouteMarkType type, size_t intermediateIndex) { - RouteMarkPoint * point = GetRoutePoint(type, intermediateIndex); + RouteMarkPoint * point = GetRoutePointForEdit(type, intermediateIndex); if (point == nullptr) return; point->SetPassed(true); @@ -320,27 +320,33 @@ void RoutePointsLayout::PassRoutePoint(RouteMarkType type, size_t intermediateIn void RoutePointsLayout::SetFollowingMode(bool enabled) { for (auto markId : m_manager.GetUserMarkIds(UserMark::Type::ROUTING)) - m_manager.GetMarkForEdit(markId)->SetFollowingMode(enabled); + m_editSession.GetMarkForEdit(markId)->SetFollowingMode(enabled); } -RouteMarkPoint * RoutePointsLayout::GetRoutePoint(RouteMarkType type, size_t intermediateIndex) +RouteMarkPoint const * RoutePointsLayout::GetRoutePoint(RouteMarkType type, size_t intermediateIndex) const { for (auto markId : m_manager.GetUserMarkIds(UserMark::Type::ROUTING)) { auto const * mark = m_manager.GetMark(markId); if (mark->IsEqualFullType(type, intermediateIndex)) - return m_manager.GetMarkForEdit(markId); + return mark; } return nullptr; } -RouteMarkPoint * RoutePointsLayout::GetMyPositionPoint() +RouteMarkPoint * RoutePointsLayout::GetRoutePointForEdit(RouteMarkType type, size_t intermediateIndex) +{ + auto const * mark = GetRoutePoint(type, intermediateIndex); + return mark ? m_editSession.GetMarkForEdit(mark->GetId()) : nullptr; +} + +RouteMarkPoint const * RoutePointsLayout::GetMyPositionPoint() const { for (auto markId : m_manager.GetUserMarkIds(UserMark::Type::ROUTING)) { auto const * mark = m_manager.GetMark(markId); if (mark->IsMyPosition()) - return m_manager.GetMarkForEdit(markId); + return mark; } return nullptr; } @@ -354,7 +360,7 @@ std::vector RoutePointsLayout::GetRoutePoints() RouteMarkPoint * finishPoint = nullptr; for (auto markId : markIds) { - auto * p = m_manager.GetMarkForEdit(markId); + auto * p = m_editSession.GetMarkForEdit(markId); if (p->GetRoutePointType() == RouteMarkType::Start) startPoint = p; else if (p->GetRoutePointType() == RouteMarkType::Finish) @@ -382,17 +388,12 @@ void RoutePointsLayout::ForEachIntermediatePoint(TRoutePointCallback const & fn) { for (auto markId : m_manager.GetUserMarkIds(UserMark::Type::ROUTING)) { - auto * mark = m_manager.GetMarkForEdit(markId); + auto * mark = m_editSession.GetMarkForEdit(markId); if (mark->GetRoutePointType() == RouteMarkType::Intermediate) fn(mark); } } -void RoutePointsLayout::NotifyChanges() -{ - m_manager.NotifyChanges(UserMark::Type::ROUTING); -} - TransitMark::TransitMark(m2::PointD const & ptOrg) : UserMark(ptOrg, Type::TRANSIT) {} diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index cbeba826f6..35ae42dd02 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -80,9 +80,10 @@ public: RoutePointsLayout(BookmarkManager & manager); - RouteMarkPoint * AddRoutePoint(RouteMarkData && data); - RouteMarkPoint * GetRoutePoint(RouteMarkType type, size_t intermediateIndex = 0); - RouteMarkPoint * GetMyPositionPoint(); + void AddRoutePoint(RouteMarkData && data); + RouteMarkPoint const * GetRoutePoint(RouteMarkType type, size_t intermediateIndex = 0) const; + RouteMarkPoint * GetRoutePointForEdit(RouteMarkType type, size_t intermediateIndex = 0); + RouteMarkPoint const * GetMyPositionPoint() const; std::vector GetRoutePoints(); size_t GetRoutePointsCount() const; bool RemoveRoutePoint(RouteMarkType type, size_t intermediateIndex = 0); @@ -92,13 +93,13 @@ public: RouteMarkType destType, size_t destIntermediateIndex); void PassRoutePoint(RouteMarkType type, size_t intermediateIndex = 0); void SetFollowingMode(bool enabled); - void NotifyChanges(); private: using TRoutePointCallback = function; void ForEachIntermediatePoint(TRoutePointCallback const & fn); BookmarkManager & m_manager; + BookmarkManager::EditSession m_editSession; }; class TransitMark : public UserMark diff --git a/map/search_mark.cpp b/map/search_mark.cpp index a2b6f72b7b..23175e56da 100644 --- a/map/search_mark.cpp +++ b/map/search_mark.cpp @@ -126,11 +126,11 @@ void SearchMarks::SetPreparingState(std::vector const & features, boo ASSERT(std::is_sorted(features.begin(), features.end()), ()); + auto editSession = m_bmManager->GetEditSession(); for (auto markId : m_bmManager->GetUserMarkIds(UserMark::Type::SEARCH)) { - auto mark = static_cast(m_bmManager->GetUserMarkForEdit(markId)); + auto * mark = editSession.GetMarkForEdit(markId); if (std::binary_search(features.begin(), features.end(), mark->GetFeatureID())) mark->SetPreparing(isPreparing); } - m_bmManager->NotifyChanges(UserMark::Type::SEARCH); } diff --git a/map/transit/transit_display.cpp b/map/transit/transit_display.cpp index 5ea26e1b9c..82c3aa85ac 100644 --- a/map/transit/transit_display.cpp +++ b/map/transit/transit_display.cpp @@ -460,7 +460,8 @@ TransitMark * TransitRouteDisplay::CreateMark(m2::PointD const & pt, FeatureID c { uint32_t const nextIndex = static_cast(m_bmManager->GetUserMarkIds(UserMark::Type::TRANSIT).size()); - auto * transitMark = m_bmManager->CreateUserMark(pt); + auto editSession = m_bmManager->GetEditSession(); + auto * transitMark = editSession.CreateUserMark(pt); transitMark->SetFeatureId(fid); transitMark->SetIndex(nextIndex); return transitMark; @@ -476,7 +477,8 @@ void TransitRouteDisplay::CreateTransitMarks(std::vector const transferArrowOffsets.emplace_back(0.0f, size.y * 0.5f); auto const vs = static_cast(df::VisualParams::Instance().GetVisualScale()); - + + auto editSession = m_bmManager->GetEditSession(); for (size_t i = 0; i < transitMarks.size(); ++i) { auto const & mark = transitMarks[i]; @@ -600,6 +602,4 @@ void TransitRouteDisplay::CreateTransitMarks(std::vector const } } } - - m_bmManager->NotifyChanges(UserMark::Type::TRANSIT); }