Work with the BookmarkManager instead of containers everywhere.

This commit is contained in:
Daria Volvenkova 2018-01-30 16:27:48 +03:00 committed by Roman Kuznetsov
parent 7293c8e76a
commit ed95316340
29 changed files with 849 additions and 695 deletions

View file

@ -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;

View file

@ -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<MWMBookmarkNameCell *>(cell) configWithName:@(cat->GetName().c_str()) delegate:self];
[static_cast<MWMBookmarkNameCell *>(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<Bookmark const *>(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<Bookmark const *>(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<Bookmark const *>(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;

View file

@ -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

View file

@ -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];
}

View file

@ -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];

View file

@ -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<Bookmark *>(
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];

View file

@ -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<Bookmark const *>(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<Bookmark const *>(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));

View file

@ -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<df::UserPointMark::SymbolNameZoomInfo> 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);

View file

@ -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<SymbolNameZoomInfo> GetSymbolNames() const override;
UserMark::Type GetMarkType() const override;
m2::PointD GetPixelOffset() const override;
string const & GetName() const { return m_name; }

View file

@ -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 <map>
#include <memory>
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<std::string> 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<std::string, dp::Color> m_styleUrl2Color;
std::map<std::string, std::string> 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<std::string> 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<std::string, dp::Color> m_styleUrl2Color;
std::map<std::string, std::string> 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<Bookmark *>(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<Track>(m_points, params));
}
Bookmark * bm = static_cast<Bookmark *>(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<Track>(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<Reader> const & reader)
bool BookmarkCategory::LoadFromKML(UserMarkManager * manager, ReaderPtr<Reader> const & reader)
{
ReaderSource<ReaderPtr<Reader> > 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<Reader> const & reader)
}
// static
std::unique_ptr<BookmarkCategory> BookmarkCategory::CreateFromKMLFile(std::string const & file,
std::unique_ptr<BookmarkCategory> BookmarkCategory::CreateFromKMLFile(UserMarkManager * manager,
std::string const & file,
size_t index,
Listeners const & listeners)
{
auto cat = my::make_unique<BookmarkCategory>("", listeners);
auto cat = my::make_unique<BookmarkCategory>("", index, listeners);
try
{
if (cat->LoadFromKML(my::make_unique<FileReader>(file)))
if (cat->LoadFromKML(manager, my::make_unique<FileReader>(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";

View file

@ -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<SymbolNameZoomInfo> 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<Reader> const & reader);
bool LoadFromKML(UserMarkManager * manager, ReaderPtr<Reader> 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<BookmarkCategory> CreateFromKMLFile(std::string const & file,
static std::unique_ptr<BookmarkCategory> 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<std::unique_ptr<Track>> m_tracks;
std::string m_name;
const size_t m_index;
// Stores file name from which bookmarks were loaded.
std::string m_file;
};

View file

@ -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<TransitMarkContainer>());
auto staticMarksContainer = my::make_unique<StaticUserMarkContainer>();
m_selectionMark = my::make_unique<StaticMarkPoint>(staticMarksContainer.get());
m_myPositionMark = my::make_unique<MyPositionMarkPoint>(staticMarksContainer.get());
m_selectionMark = my::make_unique<StaticMarkPoint>(this);
m_myPositionMark = my::make_unique<MyPositionMarkPoint>(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<Bookmark const *>(GetBmCategory(categoryIndex)->GetUserMark(bmIndex));
}
Bookmark * BookmarkManager::GetBookmarkForEditTmp(size_t categoryIndex, size_t bmIndex)
{
return static_cast<Bookmark *>(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<df::DrapeEngine> engine)
{
m_drapeEngine.Set(engine);
@ -152,14 +336,18 @@ void BookmarkManager::LoadBookmarks()
Platform::GetFilesByExt(dir, BOOKMARKS_FILE_EXTENSION, files);
auto collection = std::make_shared<CategoriesCollection>();
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<Bookmark *>(cat.CreateUserMark(ptOrg));
auto bookmark = static_cast<Bookmark *>(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<double>::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<Bookmark const *>((*it)->GetUserMark(i));
auto bookmark = static_cast<Bookmark *>(category->CreateUserMark(srcBookmark->GetPivot()));
auto bookmark = static_cast<Bookmark *>(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);
}

View file

@ -20,13 +20,14 @@
#include <boost/optional.hpp>
class BookmarkManager final
class BookmarkManager final : public UserMarkManager
{
using CategoriesCollection = std::vector<std::unique_ptr<BookmarkCategory>>;
using CategoryIter = CategoriesCollection::iterator;
using UserMarkLayers = std::vector<std::unique_ptr<UserMarkContainer>>;
public:
using AsyncLoadingStartedCallback = std::function<void()>;
using AsyncLoadingFinishedCallback = std::function<void()>;
using AsyncLoadingFileCallback = std::function<void(std::string const &, bool)>;
@ -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<df::DrapeEngine> 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<StaticMarkPoint> & SelectionMark();
std::unique_ptr<StaticMarkPoint> 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;
};

View file

@ -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<Bookmark const *>(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<Bookmark const *>(usermark) != nullptr, ());
auto const bookmark = static_cast<Bookmark const *>(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<SearchMarkPoint *>(controller.CreateUserMark(r.GetFeatureCenter()));
auto mark = static_cast<SearchMarkPoint *>(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<int>::max(), ());
for (size_t i = 0; i < GetBmCategoriesCount(); ++i)
{
if (mark->GetContainer() == GetBmCategory(i))
{
result.m_categoryIndex = static_cast<int>(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<int>::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<int>::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<int>(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)

View file

@ -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(); }

View file

@ -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<LocalAdsMark *>(userMark) != nullptr, ());
LocalAdsMark * mark = static_cast<LocalAdsMark *>(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<LocalAdsMark const *>(userMark) != nullptr, ());
LocalAdsMark const * mark = static_cast<LocalAdsMark const *>(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);
});
}

View file

@ -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);

View file

@ -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<SymbolNameZoomInfo> GetSymbolNames() const override;
UserMark::Type GetMarkType() const override { return Type::LOCAL_ADS; }
drape_ptr<TitlesInfo> GetTitleDecl() const override;
uint16_t GetPriority() const override { return m_data.m_priority; }

View file

@ -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<ApiMarkPoint *>(guard.m_controller.CreateUserMark(glPoint));
ApiMarkPoint * mark = static_cast<ApiMarkPoint *>(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<double>(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<ApiMarkPoint const *>(guard.m_controller.GetUserMark(0));
return static_cast<ApiMarkPoint const *>(m_bmManager->GetUserMark(UserMark::Type::API, 0));
}
}

View file

@ -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<RouteMarkData> RoutingManager::GetRoutePoints() const
{
vector<RouteMarkData> 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<RouteMarkData> 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<m2::PointD> 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())

View file

@ -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<df::UserPointMark::SymbolNameZoomInfo> 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<RouteMarkPoint *>(userMark) != nullptr, ());
RouteMarkPoint * newPoint = static_cast<RouteMarkPoint *>(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<RouteMarkPoint *> RoutePointsLayout::GetRoutePoints()
{
size_t const sz = m_manager.GetUserMarkCount(UserMark::Type::ROUTING);
std::vector<RouteMarkPoint *> 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<RouteMarkPoint *> 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<RouteMarkPoint *>(userMark) != nullptr, ());
return static_cast<RouteMarkPoint *>(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<RouteMarkPoint const *>(userMark) != nullptr, ());
return static_cast<RouteMarkPoint const *>(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)

View file

@ -1,6 +1,6 @@
#pragma once
#include "map/user_mark_container.hpp"
#include "map/bookmark_manager.hpp"
#include <string>
@ -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<SymbolNameZoomInfo> 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; }

View file

@ -28,8 +28,8 @@ std::vector<std::string> 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<df::UserPointMark::SymbolNameZoomInfo> SearchMarkPoint::GetSymbolNames() const
@ -53,11 +53,6 @@ drape_ptr<df::UserPointMark::SymbolNameZoomInfo> 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<FeatureID> 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<SearchMarkPoint *>(guard.m_controller.GetUserMarkForEdit(i));
auto mark = static_cast<SearchMarkPoint *>(m_bmManager->GetUserMarkForEdit(UserMark::Type::SEARCH, i));
if (std::binary_search(features.begin(), features.end(), mark->GetFeatureID()))
mark->SetPreparing(isPreparing);
}

View file

@ -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<SymbolNameZoomInfo> GetSymbolNames() const override;
UserMark::Type GetMarkType() const override;
FeatureID GetFeatureID() const override { return m_featureID; }
void SetFoundFeature(FeatureID const & feature);

View file

@ -459,10 +459,9 @@ void TransitRouteDisplay::CollectTransitDisplayInfo(vector<RouteSegment> 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<uint32_t>(marksController.GetUserMarkCount());
uint32_t const nextIndex = static_cast<uint32_t>(m_bmManager->GetUserMarkCount(UserMark::Type::TRANSIT));
auto userMark = marksController.CreateUserMark(pt);
auto userMark = m_bmManager->CreateUserMark(UserMark::Type::TRANSIT, pt);
ASSERT(dynamic_cast<TransitMark *>(userMark) != nullptr, ());
auto transitMark = static_cast<TransitMark *>(userMark);
@ -606,6 +605,5 @@ void TransitRouteDisplay::CreateTransitMarks(std::vector<TransitMarkInfo> const
}
}
auto & marksController = m_bmManager->GetUserMarksController(UserMark::Type::TRANSIT);
marksController.NotifyChanges();
m_bmManager->NotifyChanges(UserMark::Type::TRANSIT, 0);
}

View file

@ -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<df::UserPointMark::SymbolNameZoomInfo> DebugMarkPoint::GetSymbolNames() const

View file

@ -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<SymbolNameZoomInfo> 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<SymbolNameZoomInfo> GetSymbolNames() const override;
Type GetMarkType() const override { return UserMark::Type::DEBUG_MARK; }
};
string DebugPrint(UserMark::Type type);

View file

@ -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<UserMark>(AllocateUserMark(ptOrg)));
m_userMarks.push_front(unique_ptr<UserMark>(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();

View file

@ -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<df::DrapeEngine> 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);
}
};