diff --git a/iphone/Maps/Bookmarks/BookmarksRootVC.mm b/iphone/Maps/Bookmarks/BookmarksRootVC.mm index 05ab4e3940..4f1a580702 100644 --- a/iphone/Maps/Bookmarks/BookmarksRootVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksRootVC.mm @@ -52,7 +52,7 @@ extern NSString * const kBookmarkCategoryDeletedNotification = } else { - bool const showDetailedHint = !GetFramework().GetBmCategoriesCount(); + bool const showDetailedHint = !GetFramework().GetBookmarkManager().GetBmCategoriesCount(); label.text = showDetailedHint ? L(@"bookmarks_usage_hint") : L(@"bookmarks_usage_hint_import_only"); } @@ -118,25 +118,26 @@ extern NSString * const kBookmarkCategoryDeletedNotification = - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return GetFramework().GetBmCategoriesCount(); + return GetFramework().GetBookmarkManager().GetBmCategoriesCount(); } - (void)onEyeTapped:(id)sender { NSInteger row = ((UITapGestureRecognizer *)sender).view.tag; UITableViewCell * cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]]; - BookmarkCategory * cat = GetFramework().GetBmCategory(row); + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(row); if (cell && cat) { // Invert visibility - bool visible = !cat->IsVisible(); + bool visible = !bmManager.IsVisible(row); [Statistics logEvent:kStatEventName(kStatBookmarks, kStatToggleVisibility) withParameters:@{kStatValue : visible ? kStatVisible : kStatHidden}]; cell.imageView.image = [UIImage imageNamed:(visible ? @"ic_show" : @"ic_hide")]; cell.imageView.mwm_coloring = visible ? MWMImageColoringBlue : MWMImageColoringBlack; - cat->SetIsVisible(visible); - cat->NotifyChanges(); - cat->SaveToKMLFile(); + bmManager.SetCategoryIsVisible(row, visible); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, row); + bmManager.SaveToKMLFile(row); } } @@ -154,17 +155,20 @@ extern NSString * const kBookmarkCategoryDeletedNotification = [cell.imageView addGestureRecognizer:tapped]; } // To detect which row was tapped when user clicked on image - cell.imageView.tag = indexPath.row; + size_t const categoryIndex = indexPath.row; + cell.imageView.tag = categoryIndex; - BookmarkCategory const * cat = GetFramework().GetBmCategory(indexPath.row); + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory const * cat = bmManager.GetBmCategory(categoryIndex); if (cat) { - NSString * title = @(cat->GetName().c_str()); + NSString * title = @(bmManager.GetCategoryName(categoryIndex).c_str()); cell.textLabel.text = [self truncateString:title toWidth:(self.tableView.width - 122) withFont:cell.textLabel.font]; - BOOL const isVisible = cat->IsVisible(); + BOOL const isVisible = bmManager.IsVisible(categoryIndex); cell.imageView.image = [UIImage imageNamed:(isVisible ? @"ic_show" : @"ic_hide")]; cell.imageView.mwm_coloring = isVisible ? MWMImageColoringBlue : MWMImageColoringBlack; - cell.detailTextLabel.text = [NSString stringWithFormat:@"%ld", cat->GetUserMarkCount() + cat->GetTracksCount()]; + cell.detailTextLabel.text = [NSString stringWithFormat:@"%ld", + bmManager.GetBookmarksCount(categoryIndex) + bmManager.GetTracksCount(categoryIndex)]; } cell.backgroundColor = [UIColor white]; cell.textLabel.textColor = [UIColor blackPrimaryText]; @@ -214,11 +218,13 @@ extern NSString * const kBookmarkCategoryDeletedNotification = { cell.textLabel.text = txt; // Rename category - BookmarkCategory * cat = GetFramework().GetBmCategory([self.tableView indexPathForCell:cell].row); + size_t const categoryIndex = [self.tableView indexPathForCell:cell].row; + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(categoryIndex); if (cat) { - cat->SetName(txt.UTF8String); - cat->SaveToKMLFile(); + bmManager.SetCategoryName(categoryIndex, txt.UTF8String); + bmManager.SaveToKMLFile(categoryIndex); } } [f removeFromSuperview]; @@ -284,7 +290,7 @@ extern NSString * const kBookmarkCategoryDeletedNotification = f.DeleteBmCategory(indexPath.row); [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // Disable edit mode if no categories are left - if (!f.GetBmCategoriesCount()) + if (!f.GetBookmarkManager().GetBmCategoriesCount()) { self.navigationItem.rightBarButtonItem = nil; [self setEditing:NO animated:YES]; @@ -296,7 +302,7 @@ extern NSString * const kBookmarkCategoryDeletedNotification = { [super viewWillAppear:animated]; // Display Edit button only if table is not empty - if (GetFramework().GetBmCategoriesCount()) + if (GetFramework().GetBookmarkManager().GetBmCategoriesCount()) self.navigationItem.rightBarButtonItem = self.editButtonItem; else self.navigationItem.rightBarButtonItem = nil; diff --git a/iphone/Maps/Bookmarks/BookmarksVC.mm b/iphone/Maps/Bookmarks/BookmarksVC.mm index 3441b89af0..c8a48b526d 100644 --- a/iphone/Maps/Bookmarks/BookmarksVC.mm +++ b/iphone/Maps/Bookmarks/BookmarksVC.mm @@ -39,7 +39,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica if (self) { m_categoryIndex = index; - self.title = @(GetFramework().GetBmCategory(index)->GetName().c_str()); + self.title = @(GetFramework().GetBookmarkManager().GetCategoryName(index).c_str()); [self calculateSections]; } return self; @@ -61,9 +61,9 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica if (section == 0) return 2; else if (section == m_trackSection) - return GetFramework().GetBmCategory(m_categoryIndex)->GetTracksCount(); + return GetFramework().GetBookmarkManager().GetTracksCount(m_categoryIndex); else if (section == m_bookmarkSection) - return GetFramework().GetBmCategory(m_categoryIndex)->GetUserMarkCount(); + return GetFramework().GetBookmarkManager().GetBookmarksCount(m_categoryIndex); else if (section == m_shareSection) return 1; else @@ -74,10 +74,10 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { [Statistics logEvent:kStatEventName(kStatBookmarks, kStatToggleVisibility) withParameters:@{kStatValue : sender.on ? kStatVisible : kStatHidden}]; - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); - cat->SetIsVisible(sender.on); - cat->NotifyChanges(); - cat->SaveToKMLFile(); + auto & bmManager = GetFramework().GetBookmarkManager(); + bmManager.SetCategoryIsVisible(m_categoryIndex, sender.on); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, m_categoryIndex); + bmManager.SaveToKMLFile(m_categoryIndex); } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section @@ -92,7 +92,9 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { Framework & fr = GetFramework(); - BookmarkCategory * cat = fr.GetBmCategory(m_categoryIndex); + + auto & bmManager = fr.GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(m_categoryIndex); if (!cat) return nil; @@ -104,7 +106,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { cell = [tableView dequeueReusableCellWithCellClass:[MWMBookmarkNameCell class] indexPath:indexPath]; - [static_cast(cell) configWithName:@(cat->GetName().c_str()) delegate:self]; + [static_cast(cell) configWithName:@(bmManager.GetCategoryName(m_categoryIndex).c_str()) delegate:self]; } else { @@ -117,7 +119,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica cell.selectionStyle = UITableViewCellSelectionStyleNone; } UISwitch * sw = (UISwitch *)cell.accessoryView; - sw.on = cat->IsVisible(); + sw.on = bmManager.IsVisible(m_categoryIndex); sw.onTintColor = [UIColor linkBlue]; [sw addTarget:self action:@selector(onVisibilitySwitched:) forControlEvents:UIControlEventValueChanged]; } @@ -128,7 +130,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica cell = [tableView dequeueReusableCellWithIdentifier:@"TrackCell"]; if (!cell) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"TrackCell"]; - Track const * tr = cat->GetTrack(indexPath.row); + Track const * tr = bmManager.GetTrack(m_categoryIndex, indexPath.row); cell.textLabel.text = @(tr->GetName().c_str()); string dist; if (measurement_utils::FormatDistance(tr->GetLengthMeters(), dist)) @@ -146,7 +148,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica UITableViewCell * bmCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"BookmarksVCBookmarkItemCell"]; if (!bmCell) bmCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"BookmarksVCBookmarkItemCell"]; - Bookmark const * bm = static_cast(cat->GetUserMark(indexPath.row)); + Bookmark const * bm = bmManager.GetBookmarkTmp(m_categoryIndex, indexPath.row); if (bm) { bmCell.textLabel.text = @(bm->GetName().c_str()); @@ -194,7 +196,8 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; Framework & f = GetFramework(); - BookmarkCategory const * cat = f.GetBmCategory(m_categoryIndex); + auto & bmManager = f.GetBookmarkManager(); + BookmarkCategory const * cat = bmManager.GetBmCategory(m_categoryIndex); ASSERT(cat, ("NULL category")); if (indexPath.section == 0) { @@ -208,7 +211,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { if (cat) { - Track const * tr = cat->GetTrack(indexPath.row); + Track const * tr = bmManager.GetTrack(m_categoryIndex, indexPath.row); ASSERT(tr, ("NULL track")); if (tr) { @@ -221,7 +224,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { if (cat) { - Bookmark const * bm = static_cast(cat->GetUserMark(indexPath.row)); + Bookmark const * bm = bmManager.GetBookmarkTmp(m_categoryIndex, indexPath.row); ASSERT(bm, ("NULL bookmark")); if (bm) { @@ -235,15 +238,14 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica } else if (indexPath.section == m_shareSection) { - BookmarkCategory const * cat = GetFramework().GetBmCategory(m_categoryIndex); if (cat) { [Statistics logEvent:kStatEventName(kStatBookmarks, kStatExport)]; - NSString * catName = @(cat->GetName().c_str()); + NSString * catName = @(bmManager.GetCategoryName(m_categoryIndex).c_str()); if (![catName length]) catName = @"MapsMe"; - NSString * filePath = @(cat->GetFileName().c_str()); + NSString * filePath = @(bmManager.GetCategoryFileName(m_categoryIndex).c_str()); NSMutableString * kmzFile = [NSMutableString stringWithString:filePath]; [kmzFile replaceCharactersInRange:NSMakeRange([filePath length] - 1, 1) withString:@"z"]; @@ -275,14 +277,15 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica { if (indexPath.section == m_trackSection || indexPath.section == m_bookmarkSection) { - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(m_categoryIndex); if (cat) { if (editingStyle == UITableViewCellEditingStyleDelete) { if (indexPath.section == m_trackSection) { - cat->DeleteTrack(indexPath.row); + bmManager.DeleteTrack(m_categoryIndex, indexPath.row); } else { @@ -290,14 +293,14 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica NSValue * value = [NSValue valueWithBytes:&bac objCType:@encode(BookmarkAndCategory)]; [NSNotificationCenter.defaultCenter postNotificationName:kBookmarkDeletedNotification object:value]; - cat->DeleteUserMark(indexPath.row); + bmManager.DeleteBookmark(m_categoryIndex, indexPath.row); [NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification object:nil userInfo:nil]; } } - cat->NotifyChanges(); - cat->SaveToKMLFile(); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, m_categoryIndex); + bmManager.SaveToKMLFile(m_categoryIndex); size_t previousNumberOfSections = m_numberOfSections; [self calculateSections]; //We can delete the row with animation, if number of sections stay the same. @@ -305,7 +308,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica [self.tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade]; else [self.tableView reloadData]; - if (cat->GetUserMarkCount() + cat->GetTracksCount() == 0) + if (bmManager.GetBookmarksCount(m_categoryIndex) + bmManager.GetTracksCount(m_categoryIndex) == 0) { self.navigationItem.rightBarButtonItem = nil; [self setEditing:NO animated:YES]; @@ -319,7 +322,8 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica - (void)onLocationUpdate:(location::GpsInfo const &)info { // Refresh distance - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(m_categoryIndex); if (cat) { UITableView * table = (UITableView *)self.view; @@ -328,7 +332,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica NSIndexPath * indexPath = [table indexPathForCell:cell]; if (indexPath.section == self->m_bookmarkSection) { - Bookmark const * bm = static_cast(cat->GetUserMark(indexPath.row)); + Bookmark const * bm = bmManager.GetBookmarkTmp(m_categoryIndex, indexPath.row); if (bm) { m2::PointD const center = bm->GetPivot(); @@ -349,8 +353,9 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica [MWMLocationManager addObserver:self]; // Display Edit button only if table is not empty - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); - if (cat && (cat->GetUserMarkCount() + cat->GetTracksCount())) + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(m_categoryIndex); + if (cat && (bmManager.GetBookmarksCount(m_categoryIndex) + bmManager.GetTracksCount(m_categoryIndex))) self.navigationItem.rightBarButtonItem = self.editButtonItem; else self.navigationItem.rightBarButtonItem = nil; @@ -361,12 +366,12 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica - (void)renameBMCategoryIfChanged:(NSString *)newName { // Update edited category name - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); + auto & bmManager = GetFramework().GetBookmarkManager(); char const * newCharName = newName.UTF8String; - if (cat->GetName() != newCharName) + if (bmManager.GetCategoryName(m_categoryIndex) != newCharName) { - cat->SetName(newCharName); - cat->SaveToKMLFile(); + bmManager.SetCategoryName(m_categoryIndex, newCharName); + bmManager.SaveToKMLFile(m_categoryIndex); self.navigationController.title = newName; } } @@ -441,12 +446,12 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica - (void)calculateSections { int index = 1; - BookmarkCategory * cat = GetFramework().GetBmCategory(m_categoryIndex); - if (cat->GetTracksCount()) + auto & bmManager = GetFramework().GetBookmarkManager(); + if (bmManager.GetTracksCount(m_categoryIndex)) m_trackSection = index++; else m_trackSection = EMPTY_SECTION; - if (cat->GetUserMarkCount()) + if (bmManager.GetBookmarksCount(m_categoryIndex)) m_bookmarkSection = index++; else m_bookmarkSection = EMPTY_SECTION; diff --git a/iphone/Maps/Bookmarks/SelectSetVC.mm b/iphone/Maps/Bookmarks/SelectSetVC.mm index fbf615db3e..3c78c30850 100644 --- a/iphone/Maps/Bookmarks/SelectSetVC.mm +++ b/iphone/Maps/Bookmarks/SelectSetVC.mm @@ -50,7 +50,7 @@ if (section == 0) return 1; - return GetFramework().GetBmCategoriesCount(); + return GetFramework().GetBookmarkManager().GetBmCategoriesCount(); } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -64,9 +64,10 @@ } else { - BookmarkCategory * cat = GetFramework().GetBmCategory(indexPath.row); + auto & bmManager = GetFramework().GetBookmarkManager(); + BookmarkCategory * cat = bmManager.GetBmCategory(indexPath.row); if (cat) - cell.textLabel.text = @(cat->GetName().c_str()); + cell.textLabel.text = @(bmManager.GetCategoryName(indexPath.row).c_str()); if (m_categoryIndex == indexPath.row) cell.accessoryType = UITableViewCellAccessoryCheckmark; @@ -85,9 +86,7 @@ - (void)moveBookmarkToSetWithIndex:(int)setIndex { - BookmarkCategory const * category = - GetFramework().GetBookmarkManager().GetBmCategory(setIndex); - self.category = @(category->GetName().c_str()); + self.category = @(GetFramework().GetBookmarkManager().GetCategoryName(setIndex).c_str()); } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm index 557c01e925..e315d58876 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/APIBar/MWMAPIBar.mm @@ -50,8 +50,9 @@ static NSString * const kKeyPath = @"subviews"; [Statistics logEvent:kStatEventName(kStatAPI, kStatBack)]; Framework & f = GetFramework(); f.DeactivateMapSelection(true); - UserMarkNotificationGuard guard(f.GetBookmarkManager(), UserMark::Type::API); - guard.m_controller.Clear(); + auto & bmManager = f.GetBookmarkManager(); + UserMarkNotificationGuard guard(bmManager, UserMark::Type::API); + bmManager.ClearUserMarks(UserMark::Type::API); NSURL * url = [NSURL URLWithString:@(f.GetApiDataHolder().GetGlobalBackUrl().c_str())]; [UIApplication.sharedApplication openURL:url]; } diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index dccc2fa8bf..d80521222f 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -365,7 +365,7 @@ BOOL gIsFirstMyPositionMode = YES; - (void)openMigration { [self performSegueWithIdentifier:kMigrationSegue sender:self]; } - (void)openBookmarks { - BOOL const oneCategory = (GetFramework().GetBmCategoriesCount() == 1); + BOOL const oneCategory = (GetFramework().GetBookmarkManager().GetBmCategoriesCount() == 1); MWMTableViewController * vc = oneCategory ? [[BookmarksVC alloc] initWithCategory:0] : [[BookmarksRootVC alloc] init]; [self.navigationController pushViewController:vc animated:YES]; diff --git a/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm b/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm index c91e856de6..fec9e4b79e 100644 --- a/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm +++ b/iphone/Maps/UI/EditBookmark/MWMEditBookmarkController.mm @@ -102,12 +102,9 @@ static int const kInvalidCategoryIndex = -1; m_cachedBookmarkAndCategory.m_categoryIndex = self.cachedCategoryIndex; } - BookmarkCategory * category = f.GetBmCategory(m_cachedBookmarkAndCategory.m_categoryIndex); - if (!category) - return; - - auto bookmark = static_cast( - category->GetUserMarkForEdit(m_cachedBookmarkAndCategory.m_bookmarkIndex)); + BookmarkManager & bmManager = f.GetBookmarkManager(); + auto bookmark = bmManager.GetBookmarkForEditTmp(m_cachedBookmarkAndCategory.m_categoryIndex, + m_cachedBookmarkAndCategory.m_bookmarkIndex); if (!bookmark) return; @@ -115,8 +112,8 @@ static int const kInvalidCategoryIndex = -1; bookmark->SetDescription(self.cachedDescription.UTF8String); bookmark->SetName(self.cachedTitle.UTF8String); - category->SaveToKMLFile(); - category->NotifyChanges(); + bmManager.SaveToKMLFile(m_cachedBookmarkAndCategory.m_categoryIndex); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, m_cachedBookmarkAndCategory.m_categoryIndex); f.UpdatePlacePageInfoForCurrentSelection(); [self backTap]; diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm index 106588c7cc..37a433c8d1 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm @@ -436,25 +436,22 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS"; BookmarkData bmData{m_info.FormatNewBookmarkName(), f.LastEditedBMType()}; auto const bookmarkIndex = bmManager.AddBookmark(categoryIndex, self.mercator, bmData); - auto category = f.GetBmCategory(categoryIndex); - NSAssert(category, @"Category can't be nullptr!"); - auto bookmark = static_cast(category->GetUserMark(bookmarkIndex)); + auto const * bookmark = bmManager.GetBookmarkTmp(categoryIndex, bookmarkIndex); f.FillBookmarkInfo(*bookmark, {bookmarkIndex, categoryIndex}, m_info); - category->NotifyChanges(); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, categoryIndex); m_sections.insert(m_sections.begin() + 1, Sections::Bookmark); } else { auto const bac = m_info.GetBookmarkAndCategory(); - auto category = bmManager.GetBmCategory(bac.m_categoryIndex); - if (category) + auto const * bookmark = bmManager.GetBookmarkTmp(bac.m_categoryIndex, bac.m_bookmarkIndex); + if (bookmark) { - f.ResetBookmarkInfo(*static_cast(category->GetUserMark(bac.m_bookmarkIndex)), - m_info); + f.ResetBookmarkInfo(*bookmark, m_info); - category->DeleteUserMark(bac.m_bookmarkIndex); - category->NotifyChanges(); - category->SaveToKMLFile(); + bmManager.DeleteBookmark(bac.m_categoryIndex, bac.m_bookmarkIndex); + bmManager.NotifyChanges(UserMark::Type::BOOKMARK, bac.m_categoryIndex); + bmManager.SaveToKMLFile(bac.m_categoryIndex); } m_sections.erase(remove(m_sections.begin(), m_sections.end(), Sections::Bookmark)); diff --git a/map/api_mark_point.cpp b/map/api_mark_point.cpp index fe24568d1f..3f3d8f333d 100644 --- a/map/api_mark_point.cpp +++ b/map/api_mark_point.cpp @@ -29,13 +29,13 @@ string GetDefaultStyle() { return kSupportedColors[0]; } } // style -ApiMarkPoint::ApiMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container) +ApiMarkPoint::ApiMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, UserMark::Type::API, 0) {} ApiMarkPoint::ApiMarkPoint(string const & name, string const & id, string const & style, - m2::PointD const & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container), + m2::PointD const & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, UserMark::Type::API, 0), m_name(name), m_id(id), m_style(style) @@ -49,11 +49,6 @@ drape_ptr ApiMarkPoint::GetSymbolNames() return symbol; } -UserMark::Type ApiMarkPoint::GetMarkType() const -{ - return UserMark::Type::API; -} - m2::PointD ApiMarkPoint::GetPixelOffset() const { return m_style.empty() ? m2::PointD(0.0, 0.0) : m2::PointD(0.0, 3.0); diff --git a/map/api_mark_point.hpp b/map/api_mark_point.hpp index 04e951e3ea..913b2b9ee6 100644 --- a/map/api_mark_point.hpp +++ b/map/api_mark_point.hpp @@ -20,13 +20,12 @@ string GetDefaultStyle(); class ApiMarkPoint : public UserMark { public: - ApiMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); + ApiMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager); ApiMarkPoint(string const & name, string const & id, string const & style, - m2::PointD const & ptOrg, UserMarkContainer * container); + m2::PointD const & ptOrg, UserMarkManager * manager); drape_ptr GetSymbolNames() const override; - UserMark::Type GetMarkType() const override; m2::PointD GetPixelOffset() const override; string const & GetName() const { return m_name; } diff --git a/map/bookmark.cpp b/map/bookmark.cpp index e050ae8c71..6e617a3b53 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -1,5 +1,6 @@ #include "map/bookmark.hpp" #include "map/api_mark_point.hpp" +#include "map/bookmark_manager.hpp" #include "map/track.hpp" #include "base/scope_guard.hpp" @@ -27,12 +28,12 @@ #include #include -Bookmark::Bookmark(m2::PointD const & ptOrg, UserMarkContainer * container) - : Base(ptOrg, container) +Bookmark::Bookmark(m2::PointD const & ptOrg, UserMarkManager * manager, size_t index) + : Base(ptOrg, manager, UserMark::Type::BOOKMARK, index) {} -Bookmark::Bookmark(BookmarkData const & data, m2::PointD const & ptOrg, UserMarkContainer * container) - : Base(ptOrg, container) +Bookmark::Bookmark(BookmarkData const & data, m2::PointD const & ptOrg, UserMarkManager * manager, size_t index) + : Base(ptOrg, manager, UserMark::Type::BOOKMARK, index) , m_data(data) {} @@ -65,11 +66,6 @@ bool Bookmark::HasCreationAnimation() const return true; } -UserMark::Type Bookmark::GetMarkType() const -{ - return UserMark::Type::BOOKMARK; -} - std::string const & Bookmark::GetName() const { return m_data.GetName(); @@ -139,9 +135,11 @@ Track const * BookmarkCategory::GetTrack(size_t index) const } BookmarkCategory::BookmarkCategory(std::string const & name, + size_t index, Listeners const & listeners) : Base(0.0 /* bookmarkDepth */, UserMark::Type::BOOKMARK, listeners) , m_name(name) + , m_index(index) {} BookmarkCategory::~BookmarkCategory() @@ -216,369 +214,370 @@ namespace GEOMETRY_TYPE_POINT, GEOMETRY_TYPE_LINE }; +} - class KMLParser +class KMLParser +{ + // Fixes icons which are not supported by MapsWithMe. + std::string GetSupportedBMType(std::string const & s) const { - // Fixes icons which are not supported by MapsWithMe. - std::string GetSupportedBMType(std::string const & s) const + // Remove leading '#' symbol. + ASSERT(!s.empty(), ()); + std::string const result = s.substr(1); + return style::GetSupportedStyle(result, m_name, style::GetDefaultStyle()); + } + + UserMarkManager * m_manager; + BookmarkCategory & m_category; + + std::vector m_tags; + GeometryType m_geometryType; + m2::PolylineD m_points; + dp::Color m_trackColor; + + std::string m_styleId; + std::string m_mapStyleId; + std::string m_styleUrlKey; + std::map m_styleUrl2Color; + std::map m_mapStyle2Style; + + std::string m_name; + std::string m_type; + std::string m_description; + time_t m_timeStamp; + + m2::PointD m_org; + double m_scale; + + void Reset() + { + m_name.clear(); + m_description.clear(); + m_org = m2::PointD(-1000, -1000); + m_type.clear(); + m_scale = -1.0; + m_timeStamp = my::INVALID_TIME_STAMP; + + m_trackColor = df::GetColorConstant(kDefaultTrackColor); + m_styleId.clear(); + m_mapStyleId.clear(); + m_styleUrlKey.clear(); + + m_points.Clear(); + m_geometryType = GEOMETRY_TYPE_UNKNOWN; + } + + bool ParsePoint(std::string const & s, char const * delim, m2::PointD & pt) + { + // order in string is: lon, lat, z + + strings::SimpleTokenizer iter(s, delim); + if (iter) { - // Remove leading '#' symbol. - ASSERT(!s.empty(), ()); - std::string const result = s.substr(1); - return style::GetSupportedStyle(result, m_name, style::GetDefaultStyle()); - } - - BookmarkCategory & m_category; - - std::vector m_tags; - GeometryType m_geometryType; - m2::PolylineD m_points; - dp::Color m_trackColor; - - std::string m_styleId; - std::string m_mapStyleId; - std::string m_styleUrlKey; - std::map m_styleUrl2Color; - std::map m_mapStyle2Style; - - std::string m_name; - std::string m_type; - std::string m_description; - time_t m_timeStamp; - - m2::PointD m_org; - double m_scale; - - void Reset() - { - m_name.clear(); - m_description.clear(); - m_org = m2::PointD(-1000, -1000); - m_type.clear(); - m_scale = -1.0; - m_timeStamp = my::INVALID_TIME_STAMP; - - m_trackColor = df::GetColorConstant(kDefaultTrackColor); - m_styleId.clear(); - m_mapStyleId.clear(); - m_styleUrlKey.clear(); - - m_points.Clear(); - m_geometryType = GEOMETRY_TYPE_UNKNOWN; - } - - bool ParsePoint(std::string const & s, char const * delim, m2::PointD & pt) - { - // order in string is: lon, lat, z - - strings::SimpleTokenizer iter(s, delim); - if (iter) + double lon; + if (strings::to_double(*iter, lon) && MercatorBounds::ValidLon(lon) && ++iter) { - double lon; - if (strings::to_double(*iter, lon) && MercatorBounds::ValidLon(lon) && ++iter) + double lat; + if (strings::to_double(*iter, lat) && MercatorBounds::ValidLat(lat)) { - double lat; - if (strings::to_double(*iter, lat) && MercatorBounds::ValidLat(lat)) - { - pt = MercatorBounds::FromLatLon(lat, lon); - return true; - } - else - LOG(LWARNING, ("Invalid coordinates", s, "while loading", m_name)); - } - } - - return false; - } - - void SetOrigin(std::string const & s) - { - m_geometryType = GEOMETRY_TYPE_POINT; - - m2::PointD pt; - if (ParsePoint(s, ", \n\r\t", pt)) - m_org = pt; - } - - void ParseLineCoordinates(std::string const & s, char const * blockSeparator, char const * coordSeparator) - { - m_geometryType = GEOMETRY_TYPE_LINE; - - strings::SimpleTokenizer cortegeIter(s, blockSeparator); - while (cortegeIter) - { - m2::PointD pt; - if (ParsePoint(*cortegeIter, coordSeparator, pt)) - { - if (m_points.GetSize() == 0 || !(pt - m_points.Back()).IsAlmostZero()) - m_points.Add(pt); - } - ++cortegeIter; - } - } - - bool MakeValid() - { - if (GEOMETRY_TYPE_POINT == m_geometryType) - { - if (MercatorBounds::ValidX(m_org.x) && MercatorBounds::ValidY(m_org.y)) - { - // set default name - if (m_name.empty()) - m_name = PointToString(m_org); - - // set default pin - if (m_type.empty()) - m_type = "placemark-red"; - + pt = MercatorBounds::FromLatLon(lat, lon); return true; } - return false; + else + LOG(LWARNING, ("Invalid coordinates", s, "while loading", m_name)); } - else if (GEOMETRY_TYPE_LINE == m_geometryType) + } + + return false; + } + + void SetOrigin(std::string const & s) + { + m_geometryType = GEOMETRY_TYPE_POINT; + + m2::PointD pt; + if (ParsePoint(s, ", \n\r\t", pt)) + m_org = pt; + } + + void ParseLineCoordinates(std::string const & s, char const * blockSeparator, char const * coordSeparator) + { + m_geometryType = GEOMETRY_TYPE_LINE; + + strings::SimpleTokenizer cortegeIter(s, blockSeparator); + while (cortegeIter) + { + m2::PointD pt; + if (ParsePoint(*cortegeIter, coordSeparator, pt)) { - return m_points.GetSize() > 1; + if (m_points.GetSize() == 0 || !(pt - m_points.Back()).IsAlmostZero()) + m_points.Add(pt); } - - return false; + ++cortegeIter; } - - void ParseColor(std::string const & value) + } + + bool MakeValid() + { + if (GEOMETRY_TYPE_POINT == m_geometryType) { - std::string fromHex = FromHex(value); - ASSERT(fromHex.size() == 4, ("Invalid color passed")); - // Color positions in HEX – aabbggrr - m_trackColor = dp::Color(fromHex[3], fromHex[2], fromHex[1], fromHex[0]); - } - - bool GetColorForStyle(std::string const & styleUrl, dp::Color & color) - { - if (styleUrl.empty()) - return false; - - // Remove leading '#' symbol - auto it = m_styleUrl2Color.find(styleUrl.substr(1)); - if (it != m_styleUrl2Color.end()) + if (MercatorBounds::ValidX(m_org.x) && MercatorBounds::ValidY(m_org.y)) { - color = it->second; + // set default name + if (m_name.empty()) + m_name = PointToString(m_org); + + // set default pin + if (m_type.empty()) + m_type = "placemark-red"; + return true; } return false; } - - public: - KMLParser(BookmarkCategory & cat) - : m_category(cat) + else if (GEOMETRY_TYPE_LINE == m_geometryType) { - Reset(); + return m_points.GetSize() > 1; } - - ~KMLParser() + + return false; + } + + void ParseColor(std::string const & value) + { + std::string fromHex = FromHex(value); + ASSERT(fromHex.size() == 4, ("Invalid color passed")); + // Color positions in HEX – aabbggrr + m_trackColor = dp::Color(fromHex[3], fromHex[2], fromHex[1], fromHex[0]); + } + + bool GetColorForStyle(std::string const & styleUrl, dp::Color & color) + { + if (styleUrl.empty()) + return false; + + // Remove leading '#' symbol + auto it = m_styleUrl2Color.find(styleUrl.substr(1)); + if (it != m_styleUrl2Color.end()) { - m_category.NotifyChanges(); - } - - bool Push(std::string const & name) - { - m_tags.push_back(name); + color = it->second; return true; } - - void AddAttr(std::string const & attr, std::string const & value) + return false; + } + +public: + KMLParser(UserMarkManager * manager, BookmarkCategory & cat) + : m_manager(manager), + m_category(cat) + { + Reset(); + } + + ~KMLParser() + { + } + + bool Push(std::string const & name) + { + m_tags.push_back(name); + return true; + } + + void AddAttr(std::string const & attr, std::string const & value) + { + std::string attrInLowerCase = attr; + strings::AsciiToLower(attrInLowerCase); + + if (IsValidAttribute(kStyle, value, attrInLowerCase)) + m_styleId = value; + else if (IsValidAttribute(kStyleMap, value, attrInLowerCase)) + m_mapStyleId = value; + } + + bool IsValidAttribute(std::string const & type, std::string const & value, + std::string const & attrInLowerCase) const + { + return (GetTagFromEnd(0) == type && !value.empty() && attrInLowerCase == "id"); + } + + std::string const & GetTagFromEnd(size_t n) const + { + ASSERT_LESS(n, m_tags.size(), ()); + return m_tags[m_tags.size() - n - 1]; + } + + void Pop(std::string const & tag) + { + ASSERT_EQUAL(m_tags.back(), tag, ()); + + if (tag == kPlacemark) { - std::string attrInLowerCase = attr; - strings::AsciiToLower(attrInLowerCase); - - if (IsValidAttribute(kStyle, value, attrInLowerCase)) - m_styleId = value; - else if (IsValidAttribute(kStyleMap, value, attrInLowerCase)) - m_mapStyleId = value; - } - - bool IsValidAttribute(std::string const & type, std::string const & value, - std::string const & attrInLowerCase) const - { - return (GetTagFromEnd(0) == type && !value.empty() && attrInLowerCase == "id"); - } - - std::string const & GetTagFromEnd(size_t n) const - { - ASSERT_LESS(n, m_tags.size(), ()); - return m_tags[m_tags.size() - n - 1]; - } - - void Pop(std::string const & tag) - { - ASSERT_EQUAL(m_tags.back(), tag, ()); - - if (tag == kPlacemark) + if (MakeValid()) { - if (MakeValid()) + if (GEOMETRY_TYPE_POINT == m_geometryType) { - if (GEOMETRY_TYPE_POINT == m_geometryType) - { - Bookmark * bm = static_cast(m_category.CreateUserMark(m_org)); - bm->SetData(BookmarkData(m_name, m_type, m_description, m_scale, m_timeStamp)); - } - else if (GEOMETRY_TYPE_LINE == m_geometryType) - { - Track::Params params; - params.m_colors.push_back({ kDefaultTrackWidth, m_trackColor }); - params.m_name = m_name; - - /// @todo Add description, style, timestamp - m_category.AddTrack(make_unique(m_points, params)); - } + Bookmark * bm = static_cast(m_category.CreateUserMark(m_manager, m_org)); + bm->SetData(BookmarkData(m_name, m_type, m_description, m_scale, m_timeStamp)); } - Reset(); - } - else if (tag == kStyle) - { - if (GetTagFromEnd(1) == kDocument) + else if (GEOMETRY_TYPE_LINE == m_geometryType) { - if (!m_styleId.empty()) - { - m_styleUrl2Color[m_styleId] = m_trackColor; - m_trackColor = df::GetColorConstant(kDefaultTrackColor); - } + Track::Params params; + params.m_colors.push_back({ kDefaultTrackWidth, m_trackColor }); + params.m_name = m_name; + + /// @todo Add description, style, timestamp + m_category.AddTrack(make_unique(m_points, params)); } } - - m_tags.pop_back(); + Reset(); } - - void CharData(std::string value) + else if (tag == kStyle) { - strings::Trim(value); - - size_t const count = m_tags.size(); - if (count > 1 && !value.empty()) + if (GetTagFromEnd(1) == kDocument) { - std::string const & currTag = m_tags[count - 1]; - std::string const & prevTag = m_tags[count - 2]; - std::string const ppTag = count > 3 ? m_tags[count - 3] : std::string(); - - if (prevTag == kDocument) + if (!m_styleId.empty()) { - if (currTag == "name") - m_category.SetName(value); - else if (currTag == "visibility") - m_category.SetIsVisible(value == "0" ? false : true); - } - else if (prevTag == kPlacemark) - { - if (currTag == "name") - m_name = value; - else if (currTag == "styleUrl") - { - // Bookmark draw style. - m_type = GetSupportedBMType(value); - - // Check if url is in styleMap map. - if (!GetColorForStyle(value, m_trackColor)) - { - // Remove leading '#' symbol. - std::string styleId = m_mapStyle2Style[value.substr(1)]; - if (!styleId.empty()) - GetColorForStyle(styleId, m_trackColor); - } - } - else if (currTag == "description") - m_description = value; - } - else if (prevTag == "LineStyle" && currTag == "color") - { - ParseColor(value); - } - else if (ppTag == kStyleMap && prevTag == kPair && currTag == kStyleUrl && - m_styleUrlKey == "normal") - { - if (!m_mapStyleId.empty()) - m_mapStyle2Style[m_mapStyleId] = value; - } - else if (ppTag == kStyleMap && prevTag == kPair && currTag == "key") - { - m_styleUrlKey = value; - } - else if (ppTag == kPlacemark) - { - if (prevTag == "Point") - { - if (currTag == "coordinates") - SetOrigin(value); - } - else if (prevTag == "LineString") - { - if (currTag == "coordinates") - ParseLineCoordinates(value, " \n\r\t", ","); - } - else if (prevTag == "gx:Track") - { - if (currTag == "gx:coord") - ParseLineCoordinates(value, "\n\r\t", " "); - } - else if (prevTag == "ExtendedData") - { - if (currTag == "mwm:scale") - { - if (!strings::to_double(value, m_scale)) - m_scale = -1.0; - } - } - else if (prevTag == "TimeStamp") - { - if (currTag == "when") - { - m_timeStamp = my::StringToTimestamp(value); - if (m_timeStamp == my::INVALID_TIME_STAMP) - LOG(LWARNING, ("Invalid timestamp in Placemark:", value)); - } - } - else if (currTag == kStyleUrl) - { - GetColorForStyle(value, m_trackColor); - } - } - else if (ppTag == "MultiGeometry") - { - if (prevTag == "Point") - { - if (currTag == "coordinates") - SetOrigin(value); - } - else if (prevTag == "LineString") - { - if (currTag == "coordinates") - ParseLineCoordinates(value, " \n\r\t", ","); - } - else if (prevTag == "gx:Track") - { - if (currTag == "gx:coord") - ParseLineCoordinates(value, "\n\r\t", " "); - } - } - else if (ppTag == "gx:MultiTrack") - { - if (prevTag == "gx:Track") - { - if (currTag == "gx:coord") - ParseLineCoordinates(value, "\n\r\t", " "); - } + m_styleUrl2Color[m_styleId] = m_trackColor; + m_trackColor = df::GetColorConstant(kDefaultTrackColor); } } } - }; -} + + m_tags.pop_back(); + } + + void CharData(std::string value) + { + strings::Trim(value); + + size_t const count = m_tags.size(); + if (count > 1 && !value.empty()) + { + std::string const & currTag = m_tags[count - 1]; + std::string const & prevTag = m_tags[count - 2]; + std::string const ppTag = count > 3 ? m_tags[count - 3] : std::string(); + + if (prevTag == kDocument) + { + if (currTag == "name") + m_category.SetName(value); + else if (currTag == "visibility") + m_category.SetIsVisible(value == "0" ? false : true); + } + else if (prevTag == kPlacemark) + { + if (currTag == "name") + m_name = value; + else if (currTag == "styleUrl") + { + // Bookmark draw style. + m_type = GetSupportedBMType(value); + + // Check if url is in styleMap map. + if (!GetColorForStyle(value, m_trackColor)) + { + // Remove leading '#' symbol. + std::string styleId = m_mapStyle2Style[value.substr(1)]; + if (!styleId.empty()) + GetColorForStyle(styleId, m_trackColor); + } + } + else if (currTag == "description") + m_description = value; + } + else if (prevTag == "LineStyle" && currTag == "color") + { + ParseColor(value); + } + else if (ppTag == kStyleMap && prevTag == kPair && currTag == kStyleUrl && + m_styleUrlKey == "normal") + { + if (!m_mapStyleId.empty()) + m_mapStyle2Style[m_mapStyleId] = value; + } + else if (ppTag == kStyleMap && prevTag == kPair && currTag == "key") + { + m_styleUrlKey = value; + } + else if (ppTag == kPlacemark) + { + if (prevTag == "Point") + { + if (currTag == "coordinates") + SetOrigin(value); + } + else if (prevTag == "LineString") + { + if (currTag == "coordinates") + ParseLineCoordinates(value, " \n\r\t", ","); + } + else if (prevTag == "gx:Track") + { + if (currTag == "gx:coord") + ParseLineCoordinates(value, "\n\r\t", " "); + } + else if (prevTag == "ExtendedData") + { + if (currTag == "mwm:scale") + { + if (!strings::to_double(value, m_scale)) + m_scale = -1.0; + } + } + else if (prevTag == "TimeStamp") + { + if (currTag == "when") + { + m_timeStamp = my::StringToTimestamp(value); + if (m_timeStamp == my::INVALID_TIME_STAMP) + LOG(LWARNING, ("Invalid timestamp in Placemark:", value)); + } + } + else if (currTag == kStyleUrl) + { + GetColorForStyle(value, m_trackColor); + } + } + else if (ppTag == "MultiGeometry") + { + if (prevTag == "Point") + { + if (currTag == "coordinates") + SetOrigin(value); + } + else if (prevTag == "LineString") + { + if (currTag == "coordinates") + ParseLineCoordinates(value, " \n\r\t", ","); + } + else if (prevTag == "gx:Track") + { + if (currTag == "gx:coord") + ParseLineCoordinates(value, "\n\r\t", " "); + } + } + else if (ppTag == "gx:MultiTrack") + { + if (prevTag == "gx:Track") + { + if (currTag == "gx:coord") + ParseLineCoordinates(value, "\n\r\t", " "); + } + } + } + } +}; std::string BookmarkCategory::GetDefaultType() { return style::GetDefaultStyle(); } -bool BookmarkCategory::LoadFromKML(ReaderPtr const & reader) +bool BookmarkCategory::LoadFromKML(UserMarkManager * manager, ReaderPtr const & reader) { ReaderSource > src(reader); - KMLParser parser(*this); + KMLParser parser(manager, *this); if (!ParseXML(src, parser, true)) { LOG(LWARNING, ("XML read error. Probably, incorrect file encoding.")); @@ -588,13 +587,15 @@ bool BookmarkCategory::LoadFromKML(ReaderPtr const & reader) } // static -std::unique_ptr BookmarkCategory::CreateFromKMLFile(std::string const & file, +std::unique_ptr BookmarkCategory::CreateFromKMLFile(UserMarkManager * manager, + std::string const & file, + size_t index, Listeners const & listeners) { - auto cat = my::make_unique("", listeners); + auto cat = my::make_unique("", index, listeners); try { - if (cat->LoadFromKML(my::make_unique(file))) + if (cat->LoadFromKML(manager, my::make_unique(file))) cat->m_file = file; else cat.reset(); @@ -793,53 +794,9 @@ void BookmarkCategory::SaveToKML(std::ostream & s) s << kmlFooter; } -namespace +UserMark * BookmarkCategory::AllocateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) { - bool IsBadCharForPath(strings::UniChar const & c) - { - static strings::UniChar const illegalChars[] = {':', '/', '\\', '<', '>', '\"', '|', '?', '*'}; - - for (size_t i = 0; i < ARRAY_SIZE(illegalChars); ++i) - if (c < ' ' || illegalChars[i] == c) - return true; - - return false; - } -} - -std::string BookmarkCategory::RemoveInvalidSymbols(std::string const & name) -{ - // Remove not allowed symbols - strings::UniString uniName = strings::MakeUniString(name); - uniName.erase_if(&IsBadCharForPath); - return (uniName.empty() ? "Bookmarks" : strings::ToUtf8(uniName)); -} - -std::string BookmarkCategory::GenerateUniqueFileName(const std::string & path, std::string name) -{ - std::string const kmlExt(BOOKMARKS_FILE_EXTENSION); - - // check if file name already contains .kml extension - size_t const extPos = name.rfind(kmlExt); - if (extPos != std::string::npos) - { - // remove extension - ASSERT_GREATER_OR_EQUAL(name.size(), kmlExt.size(), ()); - size_t const expectedPos = name.size() - kmlExt.size(); - if (extPos == expectedPos) - name.resize(expectedPos); - } - - size_t counter = 1; - std::string suffix; - while (Platform::IsFileExistsByFullPath(path + name + suffix + kmlExt)) - suffix = strings::to_string(counter++); - return (path + name + suffix + kmlExt); -} - -UserMark * BookmarkCategory::AllocateUserMark(m2::PointD const & ptOrg) -{ - return new Bookmark(ptOrg, this); + return new Bookmark(ptOrg, manager, m_index); } bool BookmarkCategory::SaveToKMLFile() @@ -847,7 +804,7 @@ bool BookmarkCategory::SaveToKMLFile() std::string oldFile; // Get valid file name from category name - std::string const name = RemoveInvalidSymbols(m_name); + std::string const name = BookmarkManager::RemoveInvalidSymbols(m_name); if (!m_file.empty()) { @@ -863,13 +820,13 @@ bool BookmarkCategory::SaveToKMLFile() // If m_file doesn't match name, assign new m_file for this category and save old file name. if (m_file.substr(i1, i2 - i1).find(name) != 0) { - oldFile = GenerateUniqueFileName(GetPlatform().SettingsDir(), name); + oldFile = BookmarkManager::GenerateUniqueFileName(GetPlatform().SettingsDir(), name); m_file.swap(oldFile); } } else { - m_file = GenerateUniqueFileName(GetPlatform().SettingsDir(), name); + m_file = BookmarkManager::GenerateUniqueFileName(GetPlatform().SettingsDir(), name); } std::string const fileTmp = m_file + ".tmp"; diff --git a/map/bookmark.hpp b/map/bookmark.hpp index d9654f4ccf..21baebdc69 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -23,6 +23,8 @@ namespace anim class Task; } +class BookmarkManager; + class BookmarkData { public: @@ -72,10 +74,10 @@ class Bookmark : public UserMark { using Base = UserMark; public: - Bookmark(m2::PointD const & ptOrg, UserMarkContainer * container); + Bookmark(m2::PointD const & ptOrg, UserMarkManager * manager, size_t index); Bookmark(BookmarkData const & data, m2::PointD const & ptOrg, - UserMarkContainer * container); + UserMarkManager * manager, size_t index); void SetData(BookmarkData const & data); BookmarkData const & GetData() const; @@ -84,8 +86,6 @@ public: drape_ptr GetSymbolNames() const override; bool HasCreationAnimation() const override; - Type GetMarkType() const override; - std::string const & GetName() const; void SetName(std::string const & name); /// @return Now its a bookmark color - name of icon file @@ -110,10 +110,15 @@ private: class BookmarkCategory : public UserMarkContainer { using Base = UserMarkContainer; + public: - BookmarkCategory(std::string const & name, Listeners const & listeners); + BookmarkCategory(std::string const & name, size_t index, Listeners const & listeners); ~BookmarkCategory() override; +protected: + friend class BookmarkManager; + friend class KMLParser; + size_t GetUserLineCount() const override; df::UserLineMark const * GetUserLineMark(size_t index) const override; @@ -136,7 +141,7 @@ public: /// @name Theese fuctions are public for unit tests only. /// You don't need to call them from client code. //@{ - bool LoadFromKML(ReaderPtr const & reader); + bool LoadFromKML(UserMarkManager * manager, ReaderPtr const & reader); void SaveToKML(std::ostream & s); /// Uses the same file name from which was loaded, or @@ -144,22 +149,20 @@ public: bool SaveToKMLFile(); /// @return nullptr in the case of error - static std::unique_ptr CreateFromKMLFile(std::string const & file, + static std::unique_ptr CreateFromKMLFile(UserMarkManager * manager, + std::string const & file, + size_t index, Listeners const & listeners); - - /// Get valid file name from input (remove illegal symbols). - static std::string RemoveInvalidSymbols(std::string const & name); - /// Get unique bookmark file name from path and valid file name. - static std::string GenerateUniqueFileName(const std::string & path, std::string name); //@} protected: - UserMark * AllocateUserMark(m2::PointD const & ptOrg) override; + UserMark * AllocateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) override; private: std::vector> m_tracks; std::string m_name; + const size_t m_index; // Stores file name from which bookmarks were loaded. std::string m_file; }; diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 1443aa5ec5..323ebf5cf0 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -60,12 +60,53 @@ std::string const GetFileName(std::string const & filePath) std::string const GenerateValidAndUniqueFilePathForKML(std::string const & fileName) { - std::string filePath = BookmarkCategory::RemoveInvalidSymbols(fileName); - filePath = BookmarkCategory::GenerateUniqueFileName(GetPlatform().SettingsDir(), filePath); + std::string filePath = BookmarkManager::RemoveInvalidSymbols(fileName); + filePath = BookmarkManager::GenerateUniqueFileName(GetPlatform().SettingsDir(), filePath); return filePath; } + +bool IsBadCharForPath(strings::UniChar const & c) +{ + static strings::UniChar const illegalChars[] = {':', '/', '\\', '<', '>', '\"', '|', '?', '*'}; + + for (size_t i = 0; i < ARRAY_SIZE(illegalChars); ++i) + if (c < ' ' || illegalChars[i] == c) + return true; + + return false; +} } // namespace +std::string BookmarkManager::RemoveInvalidSymbols(std::string const & name) +{ + // Remove not allowed symbols + strings::UniString uniName = strings::MakeUniString(name); + uniName.erase_if(&IsBadCharForPath); + return (uniName.empty() ? "Bookmarks" : strings::ToUtf8(uniName)); +} + +std::string BookmarkManager::GenerateUniqueFileName(const std::string & path, std::string name) +{ + std::string const kmlExt(BOOKMARKS_FILE_EXTENSION); + + // check if file name already contains .kml extension + size_t const extPos = name.rfind(kmlExt); + if (extPos != std::string::npos) + { + // remove extension + ASSERT_GREATER_OR_EQUAL(name.size(), kmlExt.size(), ()); + size_t const expectedPos = name.size() - kmlExt.size(); + if (extPos == expectedPos) + name.resize(expectedPos); + } + + size_t counter = 1; + std::string suffix; + while (Platform::IsFileExistsByFullPath(path + name + suffix + kmlExt)) + suffix = strings::to_string(counter++); + return (path + name + suffix + kmlExt); +} + BookmarkManager::BookmarkManager(Callbacks && callbacks) : m_callbacks(std::move(callbacks)) , m_bookmarksListeners(std::bind(&BookmarkManager::OnCreateUserMarks, this, _1, _2), @@ -83,8 +124,8 @@ BookmarkManager::BookmarkManager(Callbacks && callbacks) m_userMarkLayers.emplace_back(my::make_unique()); auto staticMarksContainer = my::make_unique(); - m_selectionMark = my::make_unique(staticMarksContainer.get()); - m_myPositionMark = my::make_unique(staticMarksContainer.get()); + m_selectionMark = my::make_unique(this); + m_myPositionMark = my::make_unique(this); m_userMarkLayers.emplace_back(std::move(staticMarksContainer)); } @@ -96,6 +137,149 @@ BookmarkManager::~BookmarkManager() ClearCategories(); } +//////////////////////////// +float BookmarkManager::GetPointDepth(UserMark::Type type, size_t index) const +{ + if (type == UserMark::Type::BOOKMARK) + { + return GetBmCategory(index)->GetPointDepth(); + } + else + { + return FindUserMarksContainer(type)->GetPointDepth(); + } +} + +void BookmarkManager::NotifyChanges(UserMark::Type type, size_t index) +{ + if (type == UserMark::Type::BOOKMARK) + { + GetBmCategory(index)->NotifyChanges(); + } + else + { + GetUserMarksController(type).NotifyChanges(); + } +} + +size_t BookmarkManager::GetUserMarkCount(UserMark::Type type) const +{ + return GetUserMarksController(type).GetUserMarkCount(); +} + +UserMark const * BookmarkManager::GetUserMark(UserMark::Type type, size_t index) const +{ + return GetUserMarksController(type).GetUserMark(index); +} + +UserMark * BookmarkManager::GetUserMarkForEdit(UserMark::Type type, size_t index) +{ + return GetUserMarksController(type).GetUserMarkForEdit(index); +} + +void BookmarkManager::DeleteUserMark(UserMark::Type type, size_t index) +{ + GetUserMarksController(type).DeleteUserMark(index); +} + +void BookmarkManager::ClearUserMarks(UserMark::Type type) +{ + GetUserMarksController(type).Clear(); +} + +size_t BookmarkManager::GetBookmarksCount(size_t categoryIndex) const +{ + return GetBmCategory(categoryIndex)->GetUserMarkCount(); +} + +Bookmark const * BookmarkManager::GetBookmarkTmp(size_t categoryIndex, size_t bmIndex) const +{ + return static_cast(GetBmCategory(categoryIndex)->GetUserMark(bmIndex)); +} + +Bookmark * BookmarkManager::GetBookmarkForEditTmp(size_t categoryIndex, size_t bmIndex) +{ + return static_cast(GetBmCategory(categoryIndex)->GetUserMarkForEdit(bmIndex)); +} + +void BookmarkManager::DeleteBookmark(size_t categoryIndex, size_t bmIndex) +{ + GetBmCategory(categoryIndex)->DeleteUserMark(bmIndex); +} + +size_t BookmarkManager::GetTracksCount(size_t categoryIndex) const +{ + return GetBmCategory(categoryIndex)->GetTracksCount(); +} + +Track const * BookmarkManager::GetTrack(size_t categoryIndex, size_t index) const +{ + return GetBmCategory(categoryIndex)->GetTrack(index); +} + +void BookmarkManager::DeleteTrack(size_t categoryIndex, size_t index) +{ + return GetBmCategory(categoryIndex)->DeleteTrack(index); +} + +bool BookmarkManager::SaveToKMLFile(size_t categoryIndex) +{ + return GetBmCategory(categoryIndex)->SaveToKMLFile(); +} + +std::string const & BookmarkManager::GetCategoryName(size_t categoryIndex) const +{ + return GetBmCategory(categoryIndex)->GetName(); +} + +void BookmarkManager::SetCategoryName(size_t categoryIndex, std::string const & name) +{ + GetBmCategory(categoryIndex)->SetName(name); +} + +std::string const & BookmarkManager::GetCategoryFileName(size_t categoryIndex) const +{ + return GetBmCategory(categoryIndex)->GetFileName(); +} + +UserMark const * BookmarkManager::FindMarkInRect(UserMark::Type type, size_t index, m2::AnyRectD const & rect, double & d) const +{ + return type == UserMark::Type::BOOKMARK ? GetBmCategory(index)->FindMarkInRect(rect, d) + : FindUserMarksContainer(type)->FindMarkInRect(rect, d); +} + +UserMark * BookmarkManager::CreateUserMark(UserMark::Type type, m2::PointD const & ptOrg) +{ + return FindUserMarksContainer(type)->CreateUserMark(this, ptOrg); +} + +UserMark * BookmarkManager::CreateBookmark(size_t index, m2::PointD const & ptOrg) +{ + return GetBmCategory(index)->CreateUserMark(this, ptOrg); +} + +void BookmarkManager::SetContainerIsVisible(UserMark::Type type, bool visible) +{ + return FindUserMarksContainer(type)->SetIsVisible(visible); +} + +void BookmarkManager::SetCategoryIsVisible(size_t categoryId, bool visible) +{ + return GetBmCategory(categoryId)->SetIsVisible(visible); +} + +void BookmarkManager::SetContainerIsDrawable(UserMark::Type type, bool drawable) +{ + return FindUserMarksContainer(type)->SetIsDrawable(drawable); +} + +bool BookmarkManager::IsVisible(size_t categoryId) const +{ + return GetBmCategory(categoryId)->IsVisible(); +} + +//////////////////////////// + void BookmarkManager::SetDrapeEngine(ref_ptr engine) { m_drapeEngine.Set(engine); @@ -152,14 +336,18 @@ void BookmarkManager::LoadBookmarks() Platform::GetFilesByExt(dir, BOOKMARKS_FILE_EXTENSION, files); auto collection = std::make_shared(); + size_t index = 0; for (auto const & file : files) { - auto cat = BookmarkCategory::CreateFromKMLFile(dir + file, m_bookmarksListeners); + auto cat = BookmarkCategory::CreateFromKMLFile(this, dir + file, index, m_bookmarksListeners); if (m_needTeardown) return; if (cat != nullptr) + { collection->emplace_back(std::move(cat)); + ++index; + } } NotifyAboutFinishAsyncLoading(std::move(collection)); }); @@ -194,7 +382,9 @@ void BookmarkManager::LoadBookmarkRoutine(std::string const & filePath, bool isT } else { - auto cat = BookmarkCategory::CreateFromKMLFile(fileSavePath.get(), m_bookmarksListeners); + // XXX: will not work in case of several task work at the same time + auto const index = collection->size(); + auto cat = BookmarkCategory::CreateFromKMLFile(this, fileSavePath.get(), index, m_bookmarksListeners); if (m_needTeardown) return; @@ -324,7 +514,7 @@ size_t BookmarkManager::AddBookmark(size_t categoryIndex, m2::PointD const & ptO BookmarkCategory & cat = *m_categories[categoryIndex]; - auto bookmark = static_cast(cat.CreateUserMark(ptOrg)); + auto bookmark = static_cast(cat.CreateUserMark(this, ptOrg)); bookmark->SetData(bm); cat.SetIsVisible(true); cat.SaveToKMLFile(); @@ -447,7 +637,7 @@ void BookmarkManager::GetBookmarksData(UserMarkContainer const & container, df:: size_t BookmarkManager::CreateBmCategory(std::string const & name) { - m_categories.emplace_back(new BookmarkCategory(name, m_bookmarksListeners)); + m_categories.emplace_back(new BookmarkCategory(name, m_categories.size(), m_bookmarksListeners)); df::DrapeEngineLockGuard lock(m_drapeEngine); if (lock) @@ -478,17 +668,17 @@ namespace class BestUserMarkFinder { public: - explicit BestUserMarkFinder(BookmarkManager::TTouchRectHolder const & rectHolder) + explicit BestUserMarkFinder(BookmarkManager::TTouchRectHolder const & rectHolder, BookmarkManager const * manager) : m_rectHolder(rectHolder) , m_d(numeric_limits::max()) , m_mark(nullptr) + , m_manager(manager) {} - void operator()(UserMarkContainer const * container) + void operator()(UserMark::Type type, size_t index) { - ASSERT(container != nullptr, ()); - m2::AnyRectD const & rect = m_rectHolder(container->GetType()); - if (UserMark const * p = container->FindMarkInRect(rect, m_d)) + m2::AnyRectD const & rect = m_rectHolder(type); + if (UserMark const * p = m_manager->FindMarkInRect(type, index, rect, m_d)) { static double const kEps = 1e-5; if (m_mark == nullptr || !p->GetPivot().EqualDxDy(m_mark->GetPivot(), kEps)) @@ -502,6 +692,7 @@ private: BookmarkManager::TTouchRectHolder const & m_rectHolder; double m_d; UserMark const * m_mark; + BookmarkManager const * m_manager; }; } // namespace @@ -544,12 +735,12 @@ UserMark const * BookmarkManager::FindNearestUserMark(m2::AnyRectD const & rect) UserMark const * BookmarkManager::FindNearestUserMark(TTouchRectHolder const & holder) const { - BestUserMarkFinder finder(holder); - finder(FindUserMarksContainer(UserMark::Type::ROUTING)); - finder(FindUserMarksContainer(UserMark::Type::SEARCH)); - finder(FindUserMarksContainer(UserMark::Type::API)); - for (auto & cat : m_categories) - finder(cat.get()); + BestUserMarkFinder finder(holder, this); + finder(UserMark::Type::ROUTING, 0); + finder(UserMark::Type::SEARCH, 0); + finder(UserMark::Type::API, 0); + for (unsigned i = 0; i < m_categories.size(); ++i) + finder(UserMark::Type::BOOKMARK, i); return finder.GetFoundMark(); } @@ -564,6 +755,11 @@ UserMarksController & BookmarkManager::GetUserMarksController(UserMark::Type typ return *FindUserMarksContainer(type); } +UserMarksController const & BookmarkManager::GetUserMarksController(UserMark::Type type) const +{ + return *FindUserMarksContainer(type); +} + UserMarkContainer const * BookmarkManager::FindUserMarksContainer(UserMark::Type type) const { auto const iter = std::find_if(m_userMarkLayers.begin(), m_userMarkLayers.end(), @@ -629,7 +825,7 @@ void BookmarkManager::MergeCategories(CategoriesCollection && newCategories) for (size_t i = 0; i < (*it)->GetUserMarkCount(); ++i) { auto srcBookmark = static_cast((*it)->GetUserMark(i)); - auto bookmark = static_cast(category->CreateUserMark(srcBookmark->GetPivot())); + auto bookmark = static_cast(category->CreateUserMark(this, srcBookmark->GetPivot())); bookmark->SetData(srcBookmark->GetData()); } category->AppendTracks((*it)->StealTracks()); @@ -655,10 +851,12 @@ void BookmarkManager::MergeCategories(CategoriesCollection && newCategories) } UserMarkNotificationGuard::UserMarkNotificationGuard(BookmarkManager & mng, UserMark::Type type) - : m_controller(mng.GetUserMarksController(type)) + : m_manager(mng), + m_type(type) {} UserMarkNotificationGuard::~UserMarkNotificationGuard() { - m_controller.NotifyChanges(); + ASSERT(m_type != UserMark::Type::BOOKMARK, ()); + m_manager.NotifyChanges(m_type, 0); } diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 48c639d226..3e5b62d2ac 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -20,13 +20,14 @@ #include -class BookmarkManager final +class BookmarkManager final : public UserMarkManager { using CategoriesCollection = std::vector>; using CategoryIter = CategoriesCollection::iterator; using UserMarkLayers = std::vector>; public: + using AsyncLoadingStartedCallback = std::function; using AsyncLoadingFinishedCallback = std::function; using AsyncLoadingFileCallback = std::function; @@ -64,6 +65,43 @@ public: explicit BookmarkManager(Callbacks && callbacks); ~BookmarkManager(); + ////////////////// + float GetPointDepth(UserMark::Type type, size_t index) const override; + void NotifyChanges(UserMark::Type type, size_t index); + size_t GetUserMarkCount(UserMark::Type type) const; + UserMark const * GetUserMark(UserMark::Type type, size_t index) const; + UserMark * GetUserMarkForEdit(UserMark::Type type, size_t index); + void DeleteUserMark(UserMark::Type type, size_t index); + void ClearUserMarks(UserMark::Type type); + size_t GetBookmarksCount(size_t categoryIndex) const; + Bookmark const * GetBookmarkTmp(size_t categoryIndex, size_t bmIndex) const; + Bookmark * GetBookmarkForEditTmp(size_t categoryIndex, size_t bmIndex); + void DeleteBookmark(size_t categoryIndex, size_t bmIndex); + size_t GetTracksCount(size_t categoryIndex) const; + Track const * GetTrack(size_t categoryIndex, size_t index) const; + void DeleteTrack(size_t categoryIndex, size_t index); + bool SaveToKMLFile(size_t categoryIndex); + std::string const & GetCategoryName(size_t categoryIndex) const; + void SetCategoryName(size_t categoryIndex, std::string const & name); + std::string const & GetCategoryFileName(size_t categoryIndex) const; + + UserMark const * FindMarkInRect(UserMark::Type type, size_t index, m2::AnyRectD const & rect, double & d) const; + + UserMark * CreateUserMark(UserMark::Type type, m2::PointD const & ptOrg); + UserMark * CreateBookmark(size_t index, m2::PointD const & ptOrg); + + void SetContainerIsVisible(UserMark::Type type, bool visible); + void SetCategoryIsVisible(size_t categoryId, bool visible); + void SetContainerIsDrawable(UserMark::Type type, bool drawable); + + bool IsVisible(size_t catgoryId) const; + + /// Get valid file name from input (remove illegal symbols). + static std::string RemoveInvalidSymbols(std::string const & name); + /// Get unique bookmark file name from path and valid file name. + static std::string GenerateUniqueFileName(const std::string & path, std::string name); + ////////////////// + void SetDrapeEngine(ref_ptr engine); void UpdateViewport(ScreenBase const & screen); void SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks); @@ -109,6 +147,7 @@ public: /// Additional layer methods bool UserMarksIsVisible(UserMark::Type type) const; UserMarksController & GetUserMarksController(UserMark::Type type); + UserMarksController const & GetUserMarksController(UserMark::Type type) const; std::unique_ptr & SelectionMark(); std::unique_ptr const & SelectionMark() const; @@ -175,5 +214,6 @@ public: UserMarkNotificationGuard(BookmarkManager & mng, UserMark::Type type); ~UserMarkNotificationGuard(); - UserMarksController & m_controller; + BookmarkManager & m_manager; + UserMark::Type m_type; }; diff --git a/map/framework.cpp b/map/framework.cpp index 46e0e58614..965bddd769 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -755,25 +755,6 @@ size_t Framework::AddCategory(string const & categoryName) return GetBookmarkManager().CreateBmCategory(categoryName); } -namespace -{ - class EqualCategoryName - { - string const & m_name; - public: - EqualCategoryName(string const & name) : m_name(name) {} - bool operator() (BookmarkCategory const * cat) const - { - return (cat->GetName() == m_name); - } - }; -} - -BookmarkCategory * Framework::GetBmCategory(size_t index) const -{ - return GetBookmarkManager().GetBmCategory(index); -} - bool Framework::DeleteBmCategory(size_t index) { return GetBookmarkManager().DeleteBmCategory(index); @@ -781,9 +762,8 @@ bool Framework::DeleteBmCategory(size_t index) void Framework::FillBookmarkInfo(Bookmark const & bmk, BookmarkAndCategory const & bac, place_page::Info & info) const { - BookmarkCategory * cat = GetBmCategory(bac.m_categoryIndex); - info.SetBookmarkCategoryName(cat->GetName()); - BookmarkData const & data = static_cast(cat->GetUserMark(bac.m_bookmarkIndex))->GetData(); + info.SetBookmarkCategoryName(GetBookmarkManager().GetCategoryName(bac.m_categoryIndex)); + BookmarkData const & data = GetBookmarkManager().GetBookmarkTmp(bac.m_categoryIndex, bac.m_bookmarkIndex)->GetData(); info.SetBookmarkData(data); info.SetBac(bac); FillPointInfo(bmk.GetPivot(), {} /* customTitle */, info); @@ -1016,9 +996,7 @@ void Framework::ShowBookmark(df::MarkID id) void Framework::ShowBookmark(BookmarkAndCategory const & bnc) { - auto const usermark = GetBmCategory(bnc.m_categoryIndex)->GetUserMark(bnc.m_bookmarkIndex); - ASSERT(dynamic_cast(usermark) != nullptr, ()); - auto const bookmark = static_cast(usermark); + auto const bookmark = GetBookmarkManager().GetBookmarkTmp(bnc.m_categoryIndex, bnc.m_bookmarkIndex); ShowBookmark(bookmark, bnc); } @@ -1631,13 +1609,13 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be search::Results::ConstIter end, SearchMarkPostProcesing fn /* = nullptr */) { - UserMarkNotificationGuard guard(GetBookmarkManager(), UserMark::Type::SEARCH); + auto & bmManager = GetBookmarkManager(); + UserMarkNotificationGuard guard(bmManager, UserMark::Type::SEARCH); - auto & controller = guard.m_controller; if (clear) - controller.Clear(); - controller.SetIsVisible(true); - controller.SetIsDrawable(true); + bmManager.ClearUserMarks(UserMark::Type::SEARCH); + bmManager.SetContainerIsVisible(UserMark::Type::SEARCH, true); + bmManager.SetContainerIsDrawable(UserMark::Type::SEARCH, true); for (auto it = begin; it != end; ++it) { @@ -1645,7 +1623,7 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be if (!r.HasPoint()) continue; - auto mark = static_cast(controller.CreateUserMark(r.GetFeatureCenter())); + auto mark = static_cast(bmManager.CreateUserMark(UserMark::Type::SEARCH, r.GetFeatureCenter())); ASSERT_EQUAL(mark->GetMarkType(), UserMark::Type::SEARCH, ()); auto const isFeature = r.GetResultType() == search::Result::Type::Feature; if (isFeature) @@ -1668,7 +1646,8 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be void Framework::ClearSearchResultsMarks() { - UserMarkNotificationGuard(GetBookmarkManager(), UserMark::Type::SEARCH).m_controller.Clear(); + GetBookmarkManager().ClearUserMarks(UserMark::Type::SEARCH); + GetBookmarkManager().NotifyChanges(UserMark::Type::SEARCH, 0); } bool Framework::GetDistanceAndAzimut(m2::PointD const & point, @@ -2059,10 +2038,11 @@ url_scheme::ParsedMapApi::ParsingResult Framework::ParseAndSetApiURL(string cons // Clear every current API-mark. { - UserMarkNotificationGuard guard(GetBookmarkManager(), UserMark::Type::API); - guard.m_controller.Clear(); - guard.m_controller.SetIsVisible(true); - guard.m_controller.SetIsDrawable(true); + auto & bmManager = GetBookmarkManager(); + UserMarkNotificationGuard guard(bmManager, UserMark::Type::API); + bmManager.ClearUserMarks(UserMark::Type::API); + bmManager.SetContainerIsVisible(UserMark::Type::API, true); + bmManager.SetContainerIsDrawable(UserMark::Type::API, true); } return m_ParsedMapApi.SetUriAndParse(url); @@ -2142,21 +2122,13 @@ BookmarkAndCategory Framework::FindBookmark(UserMark const * mark) const BookmarkAndCategory empty; BookmarkAndCategory result; ASSERT_LESS_OR_EQUAL(GetBmCategoriesCount(), numeric_limits::max(), ()); - for (size_t i = 0; i < GetBmCategoriesCount(); ++i) - { - if (mark->GetContainer() == GetBmCategory(i)) - { - result.m_categoryIndex = static_cast(i); - break; - } - } - + result.m_categoryIndex = mark->GetCategoryIndex(); ASSERT(result.m_categoryIndex != empty.m_categoryIndex, ()); - BookmarkCategory const * cat = GetBmCategory(result.m_categoryIndex); - ASSERT_LESS_OR_EQUAL(cat->GetUserMarkCount(), numeric_limits::max(), ()); - for (size_t i = 0; i < cat->GetUserMarkCount(); ++i) + size_t const sz = GetBookmarkManager().GetBookmarksCount(result.m_categoryIndex); + ASSERT_LESS_OR_EQUAL(sz, numeric_limits::max(), ()); + for (size_t i = 0; i < sz; ++i) { - if (mark == cat->GetUserMark(i)) + if (mark == GetBookmarkManager().GetBookmarkTmp(result.m_categoryIndex, i)) { result.m_bookmarkIndex = static_cast(i); break; @@ -2231,7 +2203,7 @@ void Framework::InvalidateUserMarks() UserMark::Type::DEBUG_MARK, UserMark::Type::ROUTING, UserMark::Type::LOCAL_ADS, UserMark::Type::STATIC}; for (size_t typeIndex = 0; typeIndex < types.size(); typeIndex++) - GetBookmarkManager().GetUserMarksController(types[typeIndex]).NotifyChanges(); + GetBookmarkManager().NotifyChanges(types[typeIndex], 0); } void Framework::OnTapEvent(TapEvent const & tapEvent) diff --git a/map/framework.hpp b/map/framework.hpp index 7ef06f128f..5daf0a01de 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -323,10 +323,6 @@ public: /// @return Created bookmark category index. size_t AddCategory(string const & categoryName); - inline size_t GetBmCategoriesCount() const { return GetBookmarkManager().GetBmCategoriesCount(); } - /// @returns 0 if category is not found - BookmarkCategory * GetBmCategory(size_t index) const; - size_t LastEditedBMCategory() { return GetBookmarkManager().LastEditedBMCategory(); } string LastEditedBMType() const { return GetBookmarkManager().LastEditedBMType(); } diff --git a/map/local_ads_manager.cpp b/map/local_ads_manager.cpp index 07d38c0e39..836dcd3312 100644 --- a/map/local_ads_manager.cpp +++ b/map/local_ads_manager.cpp @@ -147,7 +147,7 @@ void CreateLocalAdsMarks(BookmarkManager * bmManager, CampaignData const & campa UserMarkNotificationGuard guard(*bmManager, UserMark::Type::LOCAL_ADS); for (auto const & data : campaignData) { - auto userMark = guard.m_controller.CreateUserMark(data.second.m_position); + auto userMark = bmManager->CreateUserMark(UserMark::Type::LOCAL_ADS, data.second.m_position); ASSERT(dynamic_cast(userMark) != nullptr, ()); LocalAdsMark * mark = static_cast(userMark); mark->SetData(LocalAdsMarkData(data.second)); @@ -164,13 +164,13 @@ void DeleteLocalAdsMarks(BookmarkManager * bmManager, MwmSet::MwmId const & mwmI GetPlatform().RunTask(Platform::Thread::Gui, [bmManager, mwmId]() { UserMarkNotificationGuard guard(*bmManager, UserMark::Type::LOCAL_ADS); - for (size_t i = 0; i < guard.m_controller.GetUserMarkCount();) + for (size_t i = 0; i < bmManager->GetUserMarkCount(UserMark::Type::LOCAL_ADS);) { - auto userMark = guard.m_controller.GetUserMark(i); + auto userMark = bmManager->GetUserMark(UserMark::Type::LOCAL_ADS, i); ASSERT(dynamic_cast(userMark) != nullptr, ()); LocalAdsMark const * mark = static_cast(userMark); if (mark->GetFeatureID().m_mwmId == mwmId) - guard.m_controller.DeleteUserMark(i); + bmManager->DeleteUserMark(UserMark::Type::LOCAL_ADS, i); else ++i; } @@ -185,7 +185,7 @@ void DeleteAllLocalAdsMarks(BookmarkManager * bmManager) GetPlatform().RunTask(Platform::Thread::Gui, [bmManager]() { UserMarkNotificationGuard guard(*bmManager, UserMark::Type::LOCAL_ADS); - guard.m_controller.Clear(); + bmManager->ClearUserMarks(UserMark::Type::LOCAL_ADS); }); } diff --git a/map/local_ads_mark.cpp b/map/local_ads_mark.cpp index e990d132f3..3ae250eedc 100644 --- a/map/local_ads_mark.cpp +++ b/map/local_ads_mark.cpp @@ -17,8 +17,8 @@ float const kSecondaryOffsetY = 2.0; } // namespace LocalAdsMark::LocalAdsMark(m2::PointD const & ptOrg, - UserMarkContainer * container) - : UserMark(ptOrg, container) + UserMarkManager * manager) + : UserMark(ptOrg, manager, Type::LOCAL_ADS, 0) { m_titleDecl.m_anchor = dp::Top; m_titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(kLocalAdsPrimaryText); diff --git a/map/local_ads_mark.hpp b/map/local_ads_mark.hpp index c7cfa68863..ae420fe81a 100644 --- a/map/local_ads_mark.hpp +++ b/map/local_ads_mark.hpp @@ -19,13 +19,12 @@ struct LocalAdsMarkData class LocalAdsMark : public UserMark { public: - LocalAdsMark(m2::PointD const & ptOrg, UserMarkContainer * container); + LocalAdsMark(m2::PointD const & ptOrg, UserMarkManager * manager); virtual ~LocalAdsMark() {} df::RenderState::DepthLayer GetDepthLayer() const override; drape_ptr GetSymbolNames() const override; - UserMark::Type GetMarkType() const override { return Type::LOCAL_ADS; } drape_ptr GetTitleDecl() const override; uint16_t GetPriority() const override { return m_data.m_priority; } diff --git a/map/mwm_url.cpp b/map/mwm_url.cpp index d66b134308..c2da65d864 100644 --- a/map/mwm_url.cpp +++ b/map/mwm_url.cpp @@ -197,7 +197,7 @@ ParsedMapApi::ParsingResult ParsedMapApi::Parse(Uri const & uri) for (auto const & p : points) { m2::PointD glPoint(MercatorBounds::FromLatLon(p.m_lat, p.m_lon)); - ApiMarkPoint * mark = static_cast(guard.m_controller.CreateUserMark(glPoint)); + ApiMarkPoint * mark = static_cast(m_bmManager->CreateUserMark(guard.m_type, glPoint)); mark->SetName(p.m_name); mark->SetApiID(p.m_id); mark->SetStyle(style::GetSupportedStyle(p.m_style, p.m_name, "")); @@ -448,18 +448,18 @@ bool ParsedMapApi::GetViewportRect(m2::RectD & rect) const ASSERT(m_bmManager != nullptr, ()); UserMarkNotificationGuard guard(*m_bmManager, UserMark::Type::API); - size_t markCount = guard.m_controller.GetUserMarkCount(); + size_t markCount = m_bmManager->GetUserMarkCount(UserMark::Type::API); if (markCount == 1 && m_zoomLevel >= 1) { double zoom = min(static_cast(scales::GetUpperComfortScale()), m_zoomLevel); - rect = df::GetRectForDrawScale(zoom, guard.m_controller.GetUserMark(0)->GetPivot()); + rect = df::GetRectForDrawScale(zoom, m_bmManager->GetUserMark(UserMark::Type::API, 0)->GetPivot()); return true; } else { m2::RectD result; - for (size_t i = 0; i < guard.m_controller.GetUserMarkCount(); ++i) - result.Add(guard.m_controller.GetUserMark(i)->GetPivot()); + for (size_t i = 0; i < markCount; ++i) + result.Add(m_bmManager->GetUserMark(UserMark::Type::API, i)->GetPivot()); if (result.IsValid()) { @@ -476,10 +476,10 @@ ApiMarkPoint const * ParsedMapApi::GetSinglePoint() const ASSERT(m_bmManager != nullptr, ()); UserMarkNotificationGuard guard(*m_bmManager, UserMark::Type::API); - if (guard.m_controller.GetUserMarkCount() != 1) + if (m_bmManager->GetUserMarkCount(UserMark::Type::API) != 1) return nullptr; - return static_cast(guard.m_controller.GetUserMark(0)); + return static_cast(m_bmManager->GetUserMark(UserMark::Type::API, 0)); } } diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index 435dca196e..702c4a6e06 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -334,7 +334,7 @@ void RoutingManager::OnRoutePointPassed(RouteMarkType type, size_t intermediateI { // Remove route point. ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.PassRoutePoint(type, intermediateIndex); routePoints.NotifyChanges(); @@ -412,9 +412,8 @@ void RoutingManager::SetRouterImpl(RouterType type) void RoutingManager::RemoveRoute(bool deactivateFollowing) { - auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT); - marksController.Clear(); - marksController.NotifyChanges(); + m_bmManager->ClearUserMarks(UserMark::Type::TRANSIT); + m_bmManager->NotifyChanges(UserMark::Type::TRANSIT, 0); if (deactivateFollowing) SetPointsFollowingMode(false /* enabled */); @@ -581,9 +580,8 @@ void RoutingManager::CloseRouting(bool removeRoutePoints) if (removeRoutePoints) { - auto & controller = m_bmManager->GetUserMarksController(UserMark::Type::ROUTING); - controller.Clear(); - controller.NotifyChanges(); + m_bmManager->ClearUserMarks(UserMark::Type::ROUTING); + m_bmManager->NotifyChanges(UserMark::Type::ROUTING, 0); CancelRecommendation(Recommendation::RebuildAfterPointsLoading); } @@ -596,7 +594,7 @@ void RoutingManager::SetLastUsedRouter(RouterType type) void RoutingManager::HideRoutePoint(RouteMarkType type, size_t intermediateIndex) { - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); RouteMarkPoint * mark = routePoints.GetRoutePoint(type, intermediateIndex); if (mark != nullptr) { @@ -607,7 +605,7 @@ void RoutingManager::HideRoutePoint(RouteMarkType type, size_t intermediateIndex bool RoutingManager::IsMyPosition(RouteMarkType type, size_t intermediateIndex) { - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); RouteMarkPoint * mark = routePoints.GetRoutePoint(type, intermediateIndex); return mark != nullptr ? mark->IsMyPosition() : false; } @@ -615,7 +613,7 @@ bool RoutingManager::IsMyPosition(RouteMarkType type, size_t intermediateIndex) vector RoutingManager::GetRoutePoints() const { vector result; - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); for (auto const & p : routePoints.GetRoutePoints()) result.push_back(p->GetMarkData()); return result; @@ -623,7 +621,7 @@ vector RoutingManager::GetRoutePoints() const size_t RoutingManager::GetRoutePointsCount() const { - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); return routePoints.GetRoutePointsCount(); } @@ -632,14 +630,13 @@ bool RoutingManager::CouldAddIntermediatePoint() const if (!IsRoutingActive()) return false; - auto const & controller = m_bmManager->GetUserMarksController(UserMark::Type::ROUTING); - return controller.GetUserMarkCount() < RoutePointsLayout::kMaxIntermediatePointsCount + 2; + return m_bmManager->GetUserMarkCount(UserMark::Type::ROUTING) < RoutePointsLayout::kMaxIntermediatePointsCount + 2; } void RoutingManager::AddRoutePoint(RouteMarkData && markData) { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); // Always replace start and finish points. if (markData.m_pointType == RouteMarkType::Start || markData.m_pointType == RouteMarkType::Finish) @@ -661,7 +658,7 @@ void RoutingManager::AddRoutePoint(RouteMarkData && markData) void RoutingManager::RemoveRoutePoint(RouteMarkType type, size_t intermediateIndex) { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveRoutePoint(type, intermediateIndex); routePoints.NotifyChanges(); } @@ -669,7 +666,7 @@ void RoutingManager::RemoveRoutePoint(RouteMarkType type, size_t intermediateInd void RoutingManager::RemoveRoutePoints() { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveRoutePoints(); routePoints.NotifyChanges(); } @@ -677,7 +674,7 @@ void RoutingManager::RemoveRoutePoints() void RoutingManager::RemoveIntermediateRoutePoints() { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.RemoveIntermediateRoutePoints(); routePoints.NotifyChanges(); } @@ -686,7 +683,7 @@ void RoutingManager::MoveRoutePoint(RouteMarkType currentType, size_t currentInt RouteMarkType targetType, size_t targetIntermediateIndex) { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.MoveRoutePoint(currentType, currentIntermediateIndex, targetType, targetIntermediateIndex); routePoints.NotifyChanges(); @@ -696,7 +693,7 @@ void RoutingManager::MoveRoutePoint(size_t currentIndex, size_t targetIndex) { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); size_t const sz = routePoints.GetRoutePointsCount(); auto const convertIndex = [sz](RouteMarkType & type, size_t & index) { if (index == 0) @@ -728,7 +725,7 @@ void RoutingManager::MoveRoutePoint(size_t currentIndex, size_t targetIndex) void RoutingManager::SetPointsFollowingMode(bool enabled) { ASSERT(m_bmManager != nullptr, ()); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); routePoints.SetFollowingMode(enabled); routePoints.NotifyChanges(); } @@ -739,7 +736,7 @@ void RoutingManager::ReorderIntermediatePoints() vector prevPositions; prevPoints.reserve(RoutePointsLayout::kMaxIntermediatePointsCount); prevPositions.reserve(RoutePointsLayout::kMaxIntermediatePointsCount); - RoutePointsLayout routePoints(m_bmManager->GetUserMarksController(UserMark::Type::ROUTING)); + RoutePointsLayout routePoints(*m_bmManager); RouteMarkPoint * addedPoint = nullptr; m2::PointD addedPosition; @@ -788,9 +785,8 @@ void RoutingManager::BuildRoute(uint32_t timeoutSec) { ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); - auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT); - marksController.Clear(); - marksController.NotifyChanges(); + m_bmManager->ClearUserMarks(UserMark::Type::TRANSIT); + m_bmManager->NotifyChanges(UserMark::Type::TRANSIT, 0); auto routePoints = GetRoutePoints(); if (routePoints.size() < 2) @@ -1134,9 +1130,8 @@ void RoutingManager::CancelRoutePointsTransaction(uint32_t transactionId) // Revert route points. ASSERT(m_bmManager != nullptr, ()); - auto & controller = m_bmManager->GetUserMarksController(UserMark::Type::ROUTING); - controller.Clear(); - RoutePointsLayout routePoints(controller); + m_bmManager->ClearUserMarks(UserMark::Type::ROUTING); + RoutePointsLayout routePoints(*m_bmManager); for (auto & markData : routeMarks) routePoints.AddRoutePoint(move(markData)); routePoints.NotifyChanges(); @@ -1175,7 +1170,7 @@ 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->GetUserMarksController(UserMark::Type::ROUTING).Clear(); + m_bmManager->ClearUserMarks(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 0bea98f5fe..c8a71e2bca 100644 --- a/map/routing_mark.cpp +++ b/map/routing_mark.cpp @@ -21,8 +21,8 @@ float const kRouteMarkSecondaryOffsetY = 2.0f; float const kTransitMarkTextSize = 12.0f; } // namespace -RouteMarkPoint::RouteMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container) +RouteMarkPoint::RouteMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, Type::ROUTING, 0) { m_titleDecl.m_anchor = dp::Top; m_titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(kRouteMarkPrimaryText); @@ -172,13 +172,14 @@ drape_ptr RouteMarkPoint::GetSymbolNames( size_t const RoutePointsLayout::kMaxIntermediatePointsCount = 3; -RoutePointsLayout::RoutePointsLayout(UserMarksController & routeMarks) - : m_routeMarks(routeMarks) +RoutePointsLayout::RoutePointsLayout(BookmarkManager & manager) + : m_manager(manager) {} RouteMarkPoint * RoutePointsLayout::AddRoutePoint(RouteMarkData && data) { - if (m_routeMarks.GetUserMarkCount() == kMaxIntermediatePointsCount + 2) + auto const count = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); + if (count == kMaxIntermediatePointsCount + 2) return nullptr; RouteMarkPoint * sameTypePoint = GetRoutePoint(data.m_pointType, data.m_intermediateIndex); @@ -186,9 +187,9 @@ RouteMarkPoint * RoutePointsLayout::AddRoutePoint(RouteMarkData && data) { if (data.m_pointType == RouteMarkType::Finish) { - if (m_routeMarks.GetUserMarkCount() > 1) + if (count > 1) { - size_t const intermediatePointsCount = m_routeMarks.GetUserMarkCount() - 2; + size_t const intermediatePointsCount = count - 2; sameTypePoint->SetRoutePointFullType(RouteMarkType::Intermediate, intermediatePointsCount); } else @@ -208,14 +209,14 @@ RouteMarkPoint * RoutePointsLayout::AddRoutePoint(RouteMarkData && data) if (data.m_pointType == RouteMarkType::Start) { - if (m_routeMarks.GetUserMarkCount() > 1) + if (count > 1) sameTypePoint->SetRoutePointFullType(RouteMarkType::Intermediate, 0); else sameTypePoint->SetRoutePointFullType(RouteMarkType::Finish, 0); } } } - auto userMark = m_routeMarks.CreateUserMark(data.m_position); + auto userMark = m_manager.CreateUserMark(UserMark::Type::ROUTING, data.m_position); ASSERT(dynamic_cast(userMark) != nullptr, ()); RouteMarkPoint * newPoint = static_cast(userMark); newPoint->SetMarkData(std::move(data)); @@ -227,7 +228,7 @@ bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, size_t intermediate { RouteMarkPoint * point = nullptr; size_t index = 0; - for (size_t sz = m_routeMarks.GetUserMarkCount(); index < sz; ++index) + for (size_t sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); index < sz; ++index) { RouteMarkPoint * mark = GetRouteMarkForEdit(index); if (mark->IsEqualFullType(type, intermediateIndex)) @@ -275,22 +276,25 @@ bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, size_t intermediate }); } - m_routeMarks.DeleteUserMark(index); + m_manager.DeleteUserMark(UserMark::Type::ROUTING, index); return true; } void RoutePointsLayout::RemoveRoutePoints() { - m_routeMarks.Clear(); + m_manager.ClearUserMarks(UserMark::Type::ROUTING); } void RoutePointsLayout::RemoveIntermediateRoutePoints() { - for (size_t i = 0; i < m_routeMarks.GetUserMarkCount();) + for (size_t i = 0, sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); i < sz;) { RouteMarkPoint const * mark = GetRouteMark(i); if (mark->GetRoutePointType() == RouteMarkType::Intermediate) - m_routeMarks.DeleteUserMark(i); + { + m_manager.DeleteUserMark(UserMark::Type::ROUTING, i); + --sz; + } else ++i; } @@ -324,13 +328,13 @@ void RoutePointsLayout::PassRoutePoint(RouteMarkType type, size_t intermediateIn void RoutePointsLayout::SetFollowingMode(bool enabled) { - for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i) + for (size_t i = 0, sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); i < sz; ++i) GetRouteMarkForEdit(i)->SetFollowingMode(enabled); } RouteMarkPoint * RoutePointsLayout::GetRoutePoint(RouteMarkType type, size_t intermediateIndex) { - for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i) + for (size_t i = 0, sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); i < sz; ++i) { RouteMarkPoint * mark = GetRouteMarkForEdit(i); if (mark->IsEqualFullType(type, intermediateIndex)) @@ -341,7 +345,7 @@ RouteMarkPoint * RoutePointsLayout::GetRoutePoint(RouteMarkType type, size_t int RouteMarkPoint * RoutePointsLayout::GetMyPositionPoint() { - for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i) + for (size_t i = 0, sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); i < sz; ++i) { RouteMarkPoint * mark = GetRouteMarkForEdit(i); if (mark->IsMyPosition()) @@ -352,11 +356,12 @@ RouteMarkPoint * RoutePointsLayout::GetMyPositionPoint() std::vector RoutePointsLayout::GetRoutePoints() { + size_t const sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); std::vector points; - points.reserve(m_routeMarks.GetUserMarkCount()); + points.reserve(sz); RouteMarkPoint * startPoint = nullptr; RouteMarkPoint * finishPoint = nullptr; - for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i) + for (size_t i = 0; i < sz; ++i) { RouteMarkPoint * p = GetRouteMarkForEdit(i); if (p->GetRoutePointType() == RouteMarkType::Start) @@ -379,26 +384,26 @@ std::vector RoutePointsLayout::GetRoutePoints() size_t RoutePointsLayout::GetRoutePointsCount() const { - return m_routeMarks.GetUserMarkCount(); + return m_manager.GetUserMarkCount(UserMark::Type::ROUTING); } RouteMarkPoint * RoutePointsLayout::GetRouteMarkForEdit(size_t index) { - auto userMark = m_routeMarks.GetUserMarkForEdit(index); + auto userMark = m_manager.GetUserMarkForEdit(UserMark::Type::ROUTING, index); ASSERT(dynamic_cast(userMark) != nullptr, ()); return static_cast(userMark); } RouteMarkPoint const * RoutePointsLayout::GetRouteMark(size_t index) { - auto userMark = m_routeMarks.GetUserMark(index); + auto userMark = m_manager.GetUserMark(UserMark::Type::ROUTING, index); ASSERT(dynamic_cast(userMark) != nullptr, ()); return static_cast(userMark); } void RoutePointsLayout::ForEachIntermediatePoint(TRoutePointCallback const & fn) { - for (size_t i = 0, sz = m_routeMarks.GetUserMarkCount(); i < sz; ++i) + for (size_t i = 0, sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING); i < sz; ++i) { RouteMarkPoint * mark = GetRouteMarkForEdit(i); if (mark->GetRoutePointType() == RouteMarkType::Intermediate) @@ -408,11 +413,11 @@ void RoutePointsLayout::ForEachIntermediatePoint(TRoutePointCallback const & fn) void RoutePointsLayout::NotifyChanges() { - m_routeMarks.NotifyChanges(); + m_manager.NotifyChanges(UserMark::Type::ROUTING, 0); } -TransitMark::TransitMark(m2::PointD const & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container) +TransitMark::TransitMark(m2::PointD const & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, Type::TRANSIT, 0) {} void TransitMark::SetFeatureId(FeatureID featureId) diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index b69a85cfc8..c0ab3942d2 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -1,6 +1,6 @@ #pragma once -#include "map/user_mark_container.hpp" +#include "map/bookmark_manager.hpp" #include @@ -27,7 +27,7 @@ struct RouteMarkData class RouteMarkPoint : public UserMark { public: - RouteMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); + RouteMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager); virtual ~RouteMarkPoint() {} bool IsVisible() const override { return m_markData.m_isVisible; } @@ -37,7 +37,6 @@ public: df::RenderState::DepthLayer GetDepthLayer() const override; drape_ptr GetSymbolNames() const override; - UserMark::Type GetMarkType() const override { return Type::ROUTING; } bool IsAvailableForSearch() const override { return !IsPassed(); } RouteMarkType GetRoutePointType() const { return m_markData.m_pointType; } @@ -79,7 +78,7 @@ class RoutePointsLayout public: static size_t const kMaxIntermediatePointsCount; - RoutePointsLayout(UserMarksController & routeMarks); + RoutePointsLayout(BookmarkManager & manager); RouteMarkPoint * AddRoutePoint(RouteMarkData && data); RouteMarkPoint * GetRoutePoint(RouteMarkType type, size_t intermediateIndex = 0); @@ -101,17 +100,16 @@ private: RouteMarkPoint * GetRouteMarkForEdit(size_t index); RouteMarkPoint const * GetRouteMark(size_t index); - UserMarksController & m_routeMarks; + BookmarkManager & m_manager; }; class TransitMark : public UserMark { public: - TransitMark(m2::PointD const & ptOrg, UserMarkContainer * container); + TransitMark(m2::PointD const & ptOrg, UserMarkManager * manager); virtual ~TransitMark() {} df::RenderState::DepthLayer GetDepthLayer() const override { return df::RenderState::TransitMarkLayer; } - UserMark::Type GetMarkType() const override { return Type::TRANSIT; } bool HasSymbolPriority() const override { return !m_symbolNames.empty() || !m_coloredSymbols.empty(); } bool HasTitlePriority() const override { return true; } diff --git a/map/search_mark.cpp b/map/search_mark.cpp index f0cf0eed2b..7cdffbf79b 100644 --- a/map/search_mark.cpp +++ b/map/search_mark.cpp @@ -28,8 +28,8 @@ std::vector const kPreparingSymbols = }; } // namespace -SearchMarkPoint::SearchMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container) +SearchMarkPoint::SearchMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, UserMark::Type::SEARCH, 0) {} drape_ptr SearchMarkPoint::GetSymbolNames() const @@ -53,11 +53,6 @@ drape_ptr SearchMarkPoint::GetSymbolNames return symbol; } -UserMark::Type SearchMarkPoint::GetMarkType() const -{ - return UserMark::Type::SEARCH; -} - void SearchMarkPoint::SetFoundFeature(FeatureID const & feature) { SetAttributeValue(m_featureID, feature); @@ -132,10 +127,10 @@ void SearchMarks::SetPreparingState(std::vector const & features, boo ASSERT(std::is_sorted(features.begin(), features.end()), ()); UserMarkNotificationGuard guard(*m_bmManager, UserMark::Type::SEARCH); - size_t const count = guard.m_controller.GetUserMarkCount(); + size_t const count = m_bmManager->GetUserMarkCount(UserMark::Type::SEARCH); for (size_t i = 0; i < count; ++i) { - auto mark = static_cast(guard.m_controller.GetUserMarkForEdit(i)); + auto mark = static_cast(m_bmManager->GetUserMarkForEdit(UserMark::Type::SEARCH, i)); if (std::binary_search(features.begin(), features.end(), mark->GetFeatureID())) mark->SetPreparing(isPreparing); } diff --git a/map/search_mark.hpp b/map/search_mark.hpp index 90e848a0c6..e4f46849a5 100644 --- a/map/search_mark.hpp +++ b/map/search_mark.hpp @@ -26,10 +26,9 @@ class BookmarkManager; class SearchMarkPoint : public UserMark { public: - SearchMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); + SearchMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager); drape_ptr GetSymbolNames() const override; - UserMark::Type GetMarkType() const override; FeatureID GetFeatureID() const override { return m_featureID; } void SetFoundFeature(FeatureID const & feature); diff --git a/map/transit/transit_display.cpp b/map/transit/transit_display.cpp index 591b225f21..cc3ef3f6fb 100644 --- a/map/transit/transit_display.cpp +++ b/map/transit/transit_display.cpp @@ -459,10 +459,9 @@ void TransitRouteDisplay::CollectTransitDisplayInfo(vector const & TransitMark * TransitRouteDisplay::CreateMark(m2::PointD const & pt, FeatureID const & fid) { - auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT); - uint32_t const nextIndex = static_cast(marksController.GetUserMarkCount()); + uint32_t const nextIndex = static_cast(m_bmManager->GetUserMarkCount(UserMark::Type::TRANSIT)); - auto userMark = marksController.CreateUserMark(pt); + auto userMark = m_bmManager->CreateUserMark(UserMark::Type::TRANSIT, pt); ASSERT(dynamic_cast(userMark) != nullptr, ()); auto transitMark = static_cast(userMark); @@ -606,6 +605,5 @@ void TransitRouteDisplay::CreateTransitMarks(std::vector const } } - auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT); - marksController.NotifyChanges(); + m_bmManager->NotifyChanges(UserMark::Type::TRANSIT, 0); } diff --git a/map/user_mark.cpp b/map/user_mark.cpp index 2e4d6cc3b0..ac580da49f 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -7,8 +7,8 @@ #include "base/string_utils.hpp" -UserMark::UserMark(m2::PointD const & ptOrg, UserMarkContainer * container) - : m_ptOrg(ptOrg), m_container(container) +UserMark::UserMark(m2::PointD const & ptOrg, UserMarkManager * manager, UserMark::Type type, size_t index) + : m_ptOrg(ptOrg), m_manager(manager), m_type(type), m_index(index) {} m2::PointD const & UserMark::GetPivot() const @@ -28,7 +28,7 @@ dp::Anchor UserMark::GetAnchor() const float UserMark::GetDepth() const { - return GetContainer()->GetPointDepth(); + return m_manager->GetPointDepth(m_type, m_index); } df::RenderState::DepthLayer UserMark::GetDepthLayer() const @@ -36,38 +36,27 @@ df::RenderState::DepthLayer UserMark::GetDepthLayer() const return df::RenderState::UserMarkLayer; } -UserMarkContainer const * UserMark::GetContainer() const -{ - ASSERT(m_container != nullptr, ()); - return m_container; -} - ms::LatLon UserMark::GetLatLon() const { return MercatorBounds::ToLatLon(m_ptOrg); } -StaticMarkPoint::StaticMarkPoint(UserMarkContainer * container) - : UserMark(m2::PointD{}, container) +StaticMarkPoint::StaticMarkPoint(UserMarkManager * manager) + : UserMark(m2::PointD{}, manager, UserMark::Type::STATIC, 0) {} -UserMark::Type StaticMarkPoint::GetMarkType() const -{ - return UserMark::Type::STATIC; -} - void StaticMarkPoint::SetPtOrg(m2::PointD const & ptOrg) { SetDirty(); m_ptOrg = ptOrg; } -MyPositionMarkPoint::MyPositionMarkPoint(UserMarkContainer * container) - : StaticMarkPoint(container) +MyPositionMarkPoint::MyPositionMarkPoint(UserMarkManager * manager) + : StaticMarkPoint(manager) {} -DebugMarkPoint::DebugMarkPoint(const m2::PointD & ptOrg, UserMarkContainer * container) - : UserMark(ptOrg, container) +DebugMarkPoint::DebugMarkPoint(const m2::PointD & ptOrg, UserMarkManager * manager) + : UserMark(ptOrg, manager, UserMark::Type::DEBUG_MARK, 0) {} drape_ptr DebugMarkPoint::GetSymbolNames() const diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 13dcba4a01..9ba806b9ea 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -13,7 +13,7 @@ #include "std/unique_ptr.hpp" #include "std/utility.hpp" -class UserMarkContainer; +class UserMarkManager; class UserMark : public df::UserPointMark { @@ -44,7 +44,7 @@ public: DEBUG_MARK }; - UserMark(m2::PointD const & ptOrg, UserMarkContainer * container); + UserMark(m2::PointD const & ptOrg, UserMarkManager * container, Type type, size_t index); // df::UserPointMark overrides. bool IsDirty() const override { return m_isDirty; } @@ -68,16 +68,18 @@ public: FeatureID GetFeatureID() const override { return FeatureID(); } bool HasCreationAnimation() const override { return false; } - UserMarkContainer const * GetContainer() const; ms::LatLon GetLatLon() const; - virtual Type GetMarkType() const = 0; + virtual Type GetMarkType() const { return m_type; }; virtual bool IsAvailableForSearch() const { return true; } + size_t GetCategoryIndex() const { return m_index; } protected: void SetDirty() { m_isDirty = true; } m2::PointD m_ptOrg; - mutable UserMarkContainer * m_container; + mutable UserMarkManager * m_manager; + Type m_type; + size_t m_index; private: mutable bool m_isDirty = true; @@ -88,10 +90,9 @@ private: class StaticMarkPoint : public UserMark { public: - explicit StaticMarkPoint(UserMarkContainer * container); + explicit StaticMarkPoint(UserMarkManager * manager); drape_ptr GetSymbolNames() const override { return nullptr; } - UserMark::Type GetMarkType() const override; void SetPtOrg(m2::PointD const & ptOrg); }; @@ -99,7 +100,7 @@ public: class MyPositionMarkPoint : public StaticMarkPoint { public: - explicit MyPositionMarkPoint(UserMarkContainer * container); + explicit MyPositionMarkPoint(UserMarkManager * manager); void SetUserPosition(m2::PointD const & pt, bool hasPosition) { @@ -115,11 +116,9 @@ private: class DebugMarkPoint : public UserMark { public: - DebugMarkPoint(m2::PointD const & ptOrg, UserMarkContainer * container); + DebugMarkPoint(m2::PointD const & ptOrg, UserMarkManager * manager); drape_ptr GetSymbolNames() const override; - - Type GetMarkType() const override { return UserMark::Type::DEBUG_MARK; } }; string DebugPrint(UserMark::Type type); diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index 2028ae3c28..ec8aafc3ff 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -207,11 +207,11 @@ bool UserMarkContainer::IsDrawable() const return m_flags[DrawableFlag]; } -UserMark * UserMarkContainer::CreateUserMark(m2::PointD const & ptOrg) +UserMark * UserMarkContainer::CreateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) { // Push front an user mark. SetDirty(); - m_userMarks.push_front(unique_ptr(AllocateUserMark(ptOrg))); + m_userMarks.push_front(unique_ptr(AllocateUserMark(manager, ptOrg))); m_userMarksDict.insert(make_pair(m_userMarks.front()->GetId(), m_userMarks.front().get())); m_createdMarks.insert(m_userMarks.front()->GetId()); return m_userMarks.front().get(); diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index 98ab389ec9..1b057c9058 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -19,13 +19,15 @@ class UserMarksController { -public: +protected: + friend class BookmarkManager; + virtual size_t GetUserMarkCount() const = 0; virtual UserMark::Type GetType() const = 0; virtual void SetIsDrawable(bool isDrawable) = 0; virtual void SetIsVisible(bool isVisible) = 0; - virtual UserMark * CreateUserMark(m2::PointD const & ptOrg) = 0; + virtual UserMark * CreateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) = 0; virtual UserMark const * GetUserMark(size_t index) const = 0; virtual UserMark * GetUserMarkForEdit(size_t index) = 0; virtual void DeleteUserMark(size_t index) = 0; @@ -34,6 +36,12 @@ public: virtual void NotifyChanges() = 0; }; +class UserMarkManager +{ +public: + virtual float GetPointDepth(UserMark::Type type, size_t index) const = 0; +}; + class UserMarkContainer : public df::UserMarksProvider , public UserMarksController { @@ -61,6 +69,10 @@ public: Listeners const & listeners = Listeners()); ~UserMarkContainer() override; +protected: + friend class BookmarkManager; + friend class KMLParser; + void SetDrapeEngine(ref_ptr engine); UserMark const * GetUserMarkById(df::MarkID id) const; UserMark const * GetUserMarkById(df::MarkID id, size_t & index) const; @@ -92,7 +104,7 @@ public: UserMark::Type GetType() const override final; // UserMarksController implementation. - UserMark * CreateUserMark(m2::PointD const & ptOrg) override; + UserMark * CreateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) override; UserMark * GetUserMarkForEdit(size_t index) override; void DeleteUserMark(size_t index) override; void Clear() override; @@ -104,7 +116,7 @@ public: protected: void SetDirty(); - virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg) = 0; + virtual UserMark * AllocateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) = 0; private: void NotifyListeners(); @@ -133,8 +145,8 @@ public: {} protected: - UserMark * AllocateUserMark(m2::PointD const & ptOrg) override + UserMark * AllocateUserMark(UserMarkManager * manager, m2::PointD const & ptOrg) override { - return new MarkPointClassType(ptOrg, this); + return new MarkPointClassType(ptOrg, manager); } };