Framework::Addbookmark now automatically edits or moves bookmark from one category to another if it exists

This commit is contained in:
Alex Zolotarev 2012-10-08 14:32:33 +03:00 committed by Alex Zolotarev
parent 5340642367
commit f3c89d79e6
5 changed files with 112 additions and 29 deletions

View file

@ -17,22 +17,22 @@
void BookmarkCategory::AddBookmark(Bookmark const & bm)
{
// Replace existing bookmark if coordinates are (almost) the same
double const eps = my::sq(1.0 * MercatorBounds::degreeInMetres);
for (size_t i = 0; i < m_bookmarks.size(); ++i)
{
Bookmark const * oldBookmark = m_bookmarks[i];
if (eps >= bm.GetOrg().SquareLength(oldBookmark->GetOrg()))
{
m_bookmarks[i] = new Bookmark(bm);
delete oldBookmark;
return;
}
}
m_bookmarks.push_back(new Bookmark(bm));
}
void BookmarkCategory::ReplaceBookmark(size_t index, Bookmark const & bm)
{
ASSERT_LESS(index, m_bookmarks.size(), ());
if (index < m_bookmarks.size())
{
Bookmark const * old = m_bookmarks[index];
m_bookmarks[index] = new Bookmark(bm);
delete old;
}
else
LOG(LWARNING, ("Trying to replace non-existing bookmark"));
}
BookmarkCategory::~BookmarkCategory()
{
ClearBookmarks();
@ -65,6 +65,16 @@ Bookmark const * BookmarkCategory::GetBookmark(size_t index) const
return (index < m_bookmarks.size() ? m_bookmarks[index] : 0);
}
int BookmarkCategory::GetBookmark(m2::PointD const org, double const squareDistance) const
{
for (size_t i = 0; i < m_bookmarks.size(); ++i)
{
if (squareDistance >= org.SquareLength(m_bookmarks[i]->GetOrg()))
return static_cast<int>(i);
}
return -1;
}
namespace
{
// Fixes icons which are not supported by MapsWithMe

View file

@ -55,7 +55,11 @@ public:
inline size_t GetBookmarksCount() const { return m_bookmarks.size(); }
Bookmark const * GetBookmark(size_t index) const;
/// @param[in] distance in metres between orgs
/// @returns -1 or index of found bookmark
int GetBookmark(m2::PointD const org, double const squareDistance) const;
void DeleteBookmark(size_t index);
void ReplaceBookmark(size_t index, Bookmark const & bm);
void LoadFromKML(ReaderPtr<Reader> const & reader);
void SaveToKML(ostream & s);

View file

@ -319,13 +319,36 @@ void Framework::LoadBookmarks()
void Framework::AddBookmark(string const & category, Bookmark const & bm)
{
BookmarkCategory * cat = GetBmCategory(category);
if (!cat)
// @TODO not optimal for 1st release
// Existing bookmark can be moved from one category to another,
// or simply replaced in the same category,
// so we scan all categories for the same bookmark
double const squareDistance = my::sq(1.0 * MercatorBounds::degreeInMetres);
for (size_t i = 0; i < m_bookmarks.size(); ++i)
{
cat = new BookmarkCategory(category);
m_bookmarks.push_back(cat);
m2::PointD const org = bm.GetOrg();
BookmarkCategory * cat = m_bookmarks[i];
int index = cat->GetBookmark(org, squareDistance);
if (index >= 0)
{
// found bookmark to replace
if (category == cat->GetName())
{
cat->ReplaceBookmark(static_cast<size_t>(index), bm);
// Autosave added bookmark
(void)cat->SaveToKMLFileAtPath(GetPlatform().WritableDir());
return;
}
else
{
// Bookmark was moved from one category to another
cat->DeleteBookmark(static_cast<size_t>(index));
}
}
}
BookmarkCategory * cat = GetBmCategory(category);
ASSERT(cat, ("category should autocreate if not exists"));
cat->AddBookmark(bm);
// Autosave added bookmark
(void)cat->SaveToKMLFileAtPath(GetPlatform().WritableDir());
@ -358,7 +381,10 @@ BookmarkCategory * Framework::GetBmCategory(string const & name)
if (i != m_bookmarks.end())
return (*i);
return 0;
// Automatically create not existing category
BookmarkCategory * cat = new BookmarkCategory(name);
m_bookmarks.push_back(cat);
return cat;
}
bool Framework::DeleteBmCategory(size_t index)
@ -383,11 +409,12 @@ BookmarkAndCategory Framework::GetBookmark(m2::PointD pt) const
return GetBookmark(pt, m_renderPolicy->VisualScale());
}
BookmarkAndCategory Framework::GetBookmark(m2::PointD pt, double visualScale) const
BookmarkAndCategory Framework::GetBookmark(m2::PointD pxPoint, double visualScale) const
{
// Get the global rect of touching area.
int const sm = TOUCH_PIXEL_RADIUS * visualScale;
m2::RectD rect(PtoG(m2::PointD(pt.x - sm, pt.y - sm)), PtoG(m2::PointD(pt.x + sm, pt.y + sm)));
m2::RectD rect(PtoG(m2::PointD(pxPoint.x - sm, pxPoint.y - sm)),
PtoG(m2::PointD(pxPoint.x + sm, pxPoint.y + sm)));
int retBookmark = -1;
string retBookmarkCategory;

View file

@ -170,10 +170,9 @@ public:
void AddBookmark(string const & category, Bookmark const & bm);
inline size_t GetBmCategoriesCount() const { return m_bookmarks.size(); }
/// @returns 0 if category is not found
//@{
BookmarkCategory * GetBmCategory(size_t index) const;
/// Always creates not existing category
BookmarkCategory * GetBmCategory(string const & name);
//@}
/// Delete bookmarks category with all bookmarks
/// @return true if category was deleted
bool DeleteBmCategory(size_t index);

View file

@ -167,8 +167,6 @@ UNIT_TEST(Bookmarks_Getting)
fm.OnSize(800, 400);
fm.ShowRect(m2::RectD(0, 0, 80, 40));
m2::PointD const pixC = fm.GtoP(m2::PointD(40, 20));
// This is not correct because Framework::OnSize doesn't work until SetRenderPolicy is called.
//TEST(m2::AlmostEqual(m2::PointD(400, 200), pixC), (pixC));
@ -176,17 +174,20 @@ UNIT_TEST(Bookmarks_Getting)
fm.AddBookmark("cat2", Bookmark(m2::PointD(41, 20), "2", "placemark-red"));
fm.AddBookmark("cat3", Bookmark(m2::PointD(41, 40), "3", "placemark-red"));
BookmarkAndCategory res = fm.GetBookmark(pixC, 1.0);
(void)fm.GetBmCategory("notExistingCat");
TEST_EQUAL(fm.GetBmCategoriesCount(), 4, ());
BookmarkAndCategory res = fm.GetBookmark(fm.GtoP(m2::PointD(40, 20)), 1.0);
TEST(IsValid(res), ());
TEST_EQUAL(res.second, 0, ());
TEST_EQUAL(res.first, "cat2" , ());
res = fm.GetBookmark(m2::PointD(0, 0));
res = fm.GetBookmark(fm.GtoP(m2::PointD(0, 0)), 1.0);
TEST(!IsValid(res), ());
res = fm.GetBookmark(m2::PointD(800, 400));
res = fm.GetBookmark(fm.GtoP(m2::PointD(800, 400)), 1.0);
TEST(!IsValid(res), ());
res = fm.GetBookmark(m2::PointD(41, 40));
res = fm.GetBookmark(fm.GtoP(m2::PointD(41, 40)), 1.0);
TEST(IsValid(res), ());
TEST_EQUAL(res.first, "cat3", ());
Bookmark const * bm = fm.GetBmCategory(res.first)->GetBookmark(res.second);
@ -196,7 +197,7 @@ UNIT_TEST(Bookmarks_Getting)
// This one should replace previous bookmark
fm.AddBookmark("cat3", Bookmark(m2::PointD(41, 40), "4", "placemark-blue"));
res = fm.GetBookmark(m2::PointD(41, 40));
res = fm.GetBookmark(fm.GtoP(m2::PointD(41, 40)), 1.0);
TEST(IsValid(res), ());
BookmarkCategory * cat = fm.GetBmCategory(res.first);
TEST(cat, ());
@ -254,3 +255,45 @@ UNIT_TEST(Bookmarks_UniqueFileName)
gen = BookmarkCategory::GenerateUniqueFileName("", FILENAME);
TEST_EQUAL(gen, FILENAME + ".kml", ());
}
UNIT_TEST(Bookmarks_AddingMoving)
{
Framework fm;
fm.OnSize(800, 400);
fm.ShowRect(m2::RectD(0, 0, 80, 40));
string const categoryOne = "cat1";
string const categoryTwo = "cat2";
m2::PointD const globalPoint = m2::PointD(40, 20);
m2::PointD const pixelPoint = fm.GtoP(globalPoint);
fm.AddBookmark(categoryOne, Bookmark(globalPoint, "name", "placemark-red"));
BookmarkAndCategory res = fm.GetBookmark(pixelPoint, 1.0);
TEST(IsValid(res), ());
TEST_EQUAL(res.second, 0, ());
TEST_EQUAL(res.first, categoryOne, ());
// Edit the name and type of bookmark
fm.AddBookmark(categoryOne, Bookmark(globalPoint, "name2", "placemark-blue"));
res = fm.GetBookmark(pixelPoint, 1.0);
TEST(IsValid(res), ());
TEST_EQUAL(res.second, 0, ());
TEST_EQUAL(res.first, categoryOne, ());
Bookmark const * pBm = fm.GetBmCategory(res.first)->GetBookmark(res.second);
TEST_EQUAL(pBm->GetName(), "name2", ());
TEST_EQUAL(pBm->GetType(), "placemark-blue", ());
// Edit name, type and category of bookmark
fm.AddBookmark(categoryTwo, Bookmark(globalPoint, "name3", "placemark-green"));
TEST_EQUAL(fm.GetBmCategoriesCount(), 2, ());
res = fm.GetBookmark(pixelPoint, 1.0);
TEST(IsValid(res), ());
TEST_EQUAL(res.second, 0, ());
TEST_EQUAL(res.first, categoryTwo, ());
TEST_EQUAL(fm.GetBmCategory(categoryOne)->GetBookmarksCount(), 0,
("Bookmark wasn't moved from one category to another"));
pBm = fm.GetBmCategory(res.first)->GetBookmark(res.second);
TEST_EQUAL(pBm->GetName(), "name3", ());
TEST_EQUAL(pBm->GetType(), "placemark-green", ());
}