Bookmarks callbacks.

This commit is contained in:
Daria Volvenkova 2017-12-08 15:16:14 +03:00 committed by Yuri Gorshenin
parent 738cd6012f
commit 0341d4508b
9 changed files with 198 additions and 25 deletions

View file

@ -138,8 +138,9 @@ Track const * BookmarkCategory::GetTrack(size_t index) const
return (index < m_tracks.size() ? m_tracks[index].get() : 0);
}
BookmarkCategory::BookmarkCategory(std::string const & name)
: Base(0.0 /* bookmarkDepth */, UserMark::Type::BOOKMARK)
BookmarkCategory::BookmarkCategory(std::string const & name,
Listeners const & listeners)
: Base(0.0 /* bookmarkDepth */, UserMark::Type::BOOKMARK, listeners)
, m_name(name)
{}
@ -587,9 +588,10 @@ bool BookmarkCategory::LoadFromKML(ReaderPtr<Reader> const & reader)
}
// static
std::unique_ptr<BookmarkCategory> BookmarkCategory::CreateFromKMLFile(std::string const & file)
std::unique_ptr<BookmarkCategory> BookmarkCategory::CreateFromKMLFile(std::string const & file,
Listeners const & listeners)
{
auto cat = my::make_unique<BookmarkCategory>("");
auto cat = my::make_unique<BookmarkCategory>("", listeners);
try
{
if (cat->LoadFromKML(my::make_unique<FileReader>(file)))

View file

@ -111,7 +111,8 @@ class BookmarkCategory : public UserMarkContainer
{
using Base = UserMarkContainer;
public:
explicit BookmarkCategory(std::string const & name);
explicit BookmarkCategory(std::string const & name,
Listeners const & listeners);
~BookmarkCategory() override;
size_t GetUserLineCount() const override;
@ -144,7 +145,8 @@ 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(std::string const & file,
Listeners const & listeners);
/// Get valid file name from input (remove illegal symbols).
static std::string RemoveInvalidSymbols(std::string const & name);

View file

@ -64,8 +64,20 @@ std::string const GenerateValidAndUniqueFilePathForKML(std::string const & fileN
}
} // namespace
BookmarkManager::BookmarkManager(GetStringsBundleFn && getStringsBundleFn)
BookmarkManager::BookmarkManager(GetStringsBundleFn && getStringsBundleFn,
CreatedBookmarksCallback && createdBookmarksCallback,
UpdatedBookmarksCallback && updatedBookmarksCallback,
DeletedBookmarksCallback && deletedBookmarksCallback)
: m_getStringsBundle(std::move(getStringsBundleFn))
, m_createdBookmarksCallback(std::move(createdBookmarksCallback))
, m_updatedBookmarksCallback(std::move(updatedBookmarksCallback))
, m_deletedBookmarksCallback(std::move(deletedBookmarksCallback))
, m_bookmarksListeners(std::bind(&BookmarkManager::OnCreateUserMarks, this,
std::placeholders::_1, std::placeholders::_2),
std::bind(&BookmarkManager::OnUpdateUserMarks, this,
std::placeholders::_1, std::placeholders::_2),
std::bind(&BookmarkManager::OnDeleteUserMarks, this,
std::placeholders::_1, std::placeholders::_2))
, m_needTeardown(false)
{
ASSERT(m_getStringsBundle != nullptr, ());
@ -149,7 +161,7 @@ void BookmarkManager::LoadBookmarks()
auto collection = std::make_shared<CategoriesCollection>();
for (auto const & file : files)
{
auto cat = BookmarkCategory::CreateFromKMLFile(dir + file);
auto cat = BookmarkCategory::CreateFromKMLFile(dir + file, m_bookmarksListeners);
if (m_needTeardown)
return;
@ -189,7 +201,7 @@ void BookmarkManager::LoadBookmarkRoutine(std::string const & filePath, bool isT
}
else
{
auto cat = BookmarkCategory::CreateFromKMLFile(fileSavePath.get());
auto cat = BookmarkCategory::CreateFromKMLFile(fileSavePath.get(), m_bookmarksListeners);
if (m_needTeardown)
return;
@ -385,9 +397,64 @@ BookmarkCategory * BookmarkManager::GetBmCategory(size_t index) const
return (index < m_categories.size() ? m_categories[index].get() : 0);
}
void BookmarkManager::OnCreateUserMarks(UserMarkContainer * container, df::IDCollection const & markIds)
{
if (container->GetType() != UserMark::Type::BOOKMARK)
return;
if (m_createdBookmarksCallback == nullptr)
return;
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(container, markIds, marksInfo);
m_createdBookmarksCallback(marksInfo);
}
void BookmarkManager::OnUpdateUserMarks(UserMarkContainer * container, df::IDCollection const & markIds)
{
if (container->GetType() != UserMark::Type::BOOKMARK)
return;
if (m_updatedBookmarksCallback == nullptr)
return;
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(container, markIds, marksInfo);
m_updatedBookmarksCallback(marksInfo);
}
void BookmarkManager::OnDeleteUserMarks(UserMarkContainer * container, df::IDCollection const & markIds)
{
if (container->GetType() != UserMark::Type::BOOKMARK)
return;
if (m_deletedBookmarksCallback == nullptr)
return;
m_deletedBookmarksCallback(markIds);
}
void BookmarkManager::GetBookmarksData(UserMarkContainer * container, df::IDCollection const & markIds,
std::vector<std::pair<df::MarkID, BookmarkData>> & data) const
{
data.reserve(markIds.size());
for (auto markId : markIds)
{
auto const userMark = container->GetUserMarkById(markId);
ASSERT(userMark != nullptr, ());
ASSERT(dynamic_cast<Bookmark const *>(userMark) != nullptr, ());
auto const bookmark = static_cast<Bookmark const *>(userMark);
data.push_back(std::make_pair(markId, bookmark->GetData()));
}
}
size_t BookmarkManager::CreateBmCategory(std::string const & name)
{
m_categories.emplace_back(new BookmarkCategory(name));
m_categories.emplace_back(new BookmarkCategory(name, m_bookmarksListeners));
df::DrapeEngineLockGuard lock(m_drapeEngine);
if (lock)
m_categories.back()->SetDrapeEngine(lock.Get());

View file

@ -32,6 +32,9 @@ public:
using AsyncLoadingStartedCallback = std::function<void()>;
using AsyncLoadingFinishedCallback = std::function<void()>;
using AsyncLoadingFileCallback = std::function<void(std::string const &, bool)>;
using CreatedBookmarksCallback = std::function<void(std::vector<std::pair<df::MarkID, BookmarkData>> const &)>;
using UpdatedBookmarksCallback = std::function<void(std::vector<std::pair<df::MarkID, BookmarkData>> const &)>;
using DeletedBookmarksCallback = std::function<void(std::vector<df::MarkID> const &)>;
struct AsyncLoadingCallbacks
{
@ -41,7 +44,10 @@ public:
AsyncLoadingFileCallback m_onFileSuccess;
};
explicit BookmarkManager(GetStringsBundleFn && getStringsBundleFn);
explicit BookmarkManager(GetStringsBundleFn && getStringsBundleFn,
CreatedBookmarksCallback && createdBookmarksCallback,
UpdatedBookmarksCallback && updatedBookmarksCallback,
DeletedBookmarksCallback && deletedBookmarksCallback);
~BookmarkManager();
void SetDrapeEngine(ref_ptr<df::DrapeEngine> engine);
@ -107,7 +113,18 @@ private:
void NotifyAboutFile(bool success, std::string const & filePath, bool isTemporaryFile);
void LoadBookmarkRoutine(std::string const & filePath, bool isTemporaryFile);
void OnCreateUserMarks(UserMarkContainer * container, df::IDCollection const & markIds);
void OnUpdateUserMarks(UserMarkContainer * container, df::IDCollection const & markIds);
void OnDeleteUserMarks(UserMarkContainer * container, df::IDCollection const & markIds);
void GetBookmarksData(UserMarkContainer * container, df::IDCollection const & markIds,
std::vector<std::pair<df::MarkID, BookmarkData>> & data) const;
GetStringsBundleFn m_getStringsBundle;
CreatedBookmarksCallback m_createdBookmarksCallback;
UpdatedBookmarksCallback m_updatedBookmarksCallback;
DeletedBookmarksCallback m_deletedBookmarksCallback;
UserMarkContainer::Listeners m_bookmarksListeners;
df::DrapeEngineSafePtr m_drapeEngine;
AsyncLoadingCallbacks m_asyncLoadingCallbacks;
std::atomic<bool> m_needTeardown;

View file

@ -359,7 +359,19 @@ Framework::Framework(FrameworkParams const & params)
: m_startForegroundTime(0.0)
, m_storage(platform::migrate::NeedMigrate() ? COUNTRIES_OBSOLETE_FILE : COUNTRIES_FILE)
, m_enabledDiffs(params.m_enableDiffs)
, m_bmManager([this]() -> StringsBundle const & { return m_stringsBundle; })
, m_bmManager([this]() -> StringsBundle const & { return m_stringsBundle; },
[](std::vector<std::pair<df::MarkID, BookmarkData>> const & marks)
{
// TODO: Add processing of the created marks.
},
[](std::vector<std::pair<df::MarkID, BookmarkData>> const & marks)
{
// TODO: Add processing of the updated marks.
},
[](std::vector<df::MarkID> const & marks)
{
// TODO: Add processing of the deleted marks.
})
, m_isRenderingEnabled(true)
, m_routingManager(RoutingManager::Callbacks([this]() -> Index & { return m_model.GetIndex(); },
[this]() -> storage::CountryInfoGetter & { return GetCountryInfoGetter(); },

View file

@ -157,7 +157,7 @@ char const * kmlString =
UNIT_TEST(Bookmarks_ImportKML)
{
BookmarkCategory cat("Default");
BookmarkCategory cat("Default", UserMarkContainer::Listeners());
TEST(cat.LoadFromKML(make_unique<MemReader>(kmlString, strlen(kmlString))), ());
CheckBookmarks(cat);
@ -171,7 +171,7 @@ UNIT_TEST(Bookmarks_ExportKML)
{
char const * BOOKMARKS_FILE_NAME = "UnitTestBookmarks.kml";
BookmarkCategory cat("Default");
BookmarkCategory cat("Default", UserMarkContainer::Listeners());
TEST(cat.LoadFromKML(make_unique<MemReader>(kmlString, strlen(kmlString))), ());
CheckBookmarks(cat);
@ -191,7 +191,7 @@ UNIT_TEST(Bookmarks_ExportKML)
CheckBookmarks(cat);
TEST_EQUAL(cat.IsVisible(), true, ());
auto cat2 = BookmarkCategory::CreateFromKMLFile(BOOKMARKS_FILE_NAME);
auto cat2 = BookmarkCategory::CreateFromKMLFile(BOOKMARKS_FILE_NAME, UserMarkContainer::Listeners());
CheckBookmarks(*cat2);
TEST(cat2->SaveToKMLFile(), ());
@ -201,7 +201,7 @@ UNIT_TEST(Bookmarks_ExportKML)
// MapName is the <name> tag in test kml data.
string const catFileName = GetPlatform().SettingsDir() + "MapName.kml";
cat2 = BookmarkCategory::CreateFromKMLFile(catFileName);
cat2 = BookmarkCategory::CreateFromKMLFile(catFileName, UserMarkContainer::Listeners());
CheckBookmarks(*cat2);
TEST(my::DeleteFileX(catFileName), ());
}
@ -536,7 +536,7 @@ char const * kmlString2 =
UNIT_TEST(Bookmarks_InnerFolder)
{
BookmarkCategory cat("Default");
BookmarkCategory cat("Default", UserMarkContainer::Listeners());
TEST(cat.LoadFromKML(make_unique<MemReader>(kmlString2, strlen(kmlString2))), ());
TEST_EQUAL(cat.GetUserMarkCount(), 1, ());
@ -544,7 +544,7 @@ UNIT_TEST(Bookmarks_InnerFolder)
UNIT_TEST(BookmarkCategory_EmptyName)
{
unique_ptr<BookmarkCategory> pCat(new BookmarkCategory(""));
unique_ptr<BookmarkCategory> pCat(new BookmarkCategory("", UserMarkContainer::Listeners()));
static_cast<Bookmark *>(pCat->CreateUserMark(m2::PointD(0, 0)))->SetData(BookmarkData("", "placemark-red"));
TEST(pCat->SaveToKMLFile(), ());
@ -593,13 +593,14 @@ char const * kmlString3 =
UNIT_TEST(Bookmarks_SpecialXMLNames)
{
BookmarkCategory cat1("");
BookmarkCategory cat1("", UserMarkContainer::Listeners());
TEST(cat1.LoadFromKML(make_unique<MemReader>(kmlString3, strlen(kmlString3))), ());
TEST_EQUAL(cat1.GetUserMarkCount(), 1, ());
TEST(cat1.SaveToKMLFile(), ());
unique_ptr<BookmarkCategory> const cat2(BookmarkCategory::CreateFromKMLFile(cat1.GetFileName()));
unique_ptr<BookmarkCategory> const cat2(BookmarkCategory::CreateFromKMLFile(cat1.GetFileName(),
UserMarkContainer::Listeners()));
TEST(cat2.get(), ());
TEST_EQUAL(cat2->GetUserMarkCount(), 1, ());
@ -617,7 +618,7 @@ UNIT_TEST(Bookmarks_SpecialXMLNames)
UNIT_TEST(TrackParsingTest_1)
{
string const kmlFile = GetPlatform().TestsDataPathForFile("kml-with-track-kml.test");
auto cat = BookmarkCategory::CreateFromKMLFile(kmlFile);
auto cat = BookmarkCategory::CreateFromKMLFile(kmlFile, UserMarkContainer::Listeners());
TEST(cat, ("Category can't be created"));
TEST_EQUAL(cat->GetTracksCount(), 4, ());
@ -642,7 +643,7 @@ UNIT_TEST(TrackParsingTest_1)
UNIT_TEST(TrackParsingTest_2)
{
string const kmlFile = GetPlatform().TestsDataPathForFile("kml-with-track-from-google-earth.test");
auto cat = BookmarkCategory::CreateFromKMLFile(kmlFile);
auto cat = BookmarkCategory::CreateFromKMLFile(kmlFile, UserMarkContainer::Listeners());
TEST(cat, ("Category can't be created"));
TEST_EQUAL(cat->GetTracksCount(), 1, ());

View file

@ -35,7 +35,7 @@ UNIT_TEST(KMZ_UnzipTest)
MY_SCOPE_GUARD(fileGuard, bind(&FileWriter::DeleteFileX, kmlFile));
ZipFileReader::UnzipFile(kmzFile, "doc.kml", kmlFile);
BookmarkCategory cat("Default");
BookmarkCategory cat("Default", UserMarkContainer::Listeners());
TEST(cat.LoadFromKML(make_unique<FileReader>(kmlFile)), ());
TEST_EQUAL(files.size(), 6, ("KMZ file wrong number of files"));

View file

@ -53,9 +53,11 @@ df::MarkGroupID GenerateMarkGroupId(UserMarkContainer const * cont)
}
} // namespace
UserMarkContainer::UserMarkContainer(double layerDepth, UserMark::Type type)
UserMarkContainer::UserMarkContainer(double layerDepth, UserMark::Type type,
Listeners const & listeners)
: m_layerDepth(layerDepth)
, m_type(type)
, m_listeners(listeners)
{
m_flags.set();
}
@ -71,6 +73,21 @@ void UserMarkContainer::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine)
m_drapeEngine.Set(engine);
}
void UserMarkContainer::SetListeners(Listeners const & listeners)
{
m_listeners = listeners;
}
UserMark const * UserMarkContainer::GetUserMarkById(df::MarkID id) const
{
for (auto const & mark : m_userMarks)
{
if (mark->GetId() == id)
return mark.get();
}
return nullptr;
}
UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, double & d) const
{
UserMark * mark = nullptr;
@ -86,11 +103,41 @@ UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, do
return mark;
}
void UserMarkContainer::NotifyListeners()
{
if (!IsDirty())
return;
if (m_listeners.m_createListener != nullptr && !m_createdMarks.empty())
{
df::IDCollection marks(m_createdMarks.begin(), m_createdMarks.end());
m_listeners.m_createListener(this, marks);
}
if (m_listeners.m_updateListener != nullptr)
{
df::IDCollection marks;
for (auto const & mark : m_userMarks)
{
if (mark->IsDirty() && m_createdMarks.find(mark->GetId()) == m_createdMarks.end())
marks.push_back(mark->GetId());
}
if (!marks.empty())
m_listeners.m_updateListener(this, marks);
}
if (m_listeners.m_deleteListener != nullptr && !m_removedMarks.empty())
{
df::IDCollection marks(m_removedMarks.begin(), m_removedMarks.end());
m_listeners.m_deleteListener(this, marks);
}
}
void UserMarkContainer::NotifyChanges()
{
if (!IsDirty())
return;
NotifyListeners();
df::DrapeEngineLockGuard lock(m_drapeEngine);
if (!lock)
return;

View file

@ -13,6 +13,7 @@
#include <bitset>
#include <deque>
#include <functional>
#include <memory>
#include <set>
@ -38,11 +39,31 @@ class UserMarkContainer : public df::UserMarksProvider
{
public:
using TUserMarksList = std::deque<std::unique_ptr<UserMark>>;
using NotifyChangesFn = std::function<void (UserMarkContainer *, df::IDCollection const &)>;
UserMarkContainer(double layerDepth, UserMark::Type type);
struct Listeners
{
Listeners() = default;
Listeners(NotifyChangesFn const & createListener,
NotifyChangesFn const & updateListener,
NotifyChangesFn const & deleteListener)
: m_createListener(createListener)
, m_updateListener(updateListener)
, m_deleteListener(deleteListener)
{}
NotifyChangesFn m_createListener;
NotifyChangesFn m_updateListener;
NotifyChangesFn m_deleteListener;
};
UserMarkContainer(double layerDepth, UserMark::Type type,
Listeners const & listeners = Listeners());
~UserMarkContainer() override;
void SetDrapeEngine(ref_ptr<df::DrapeEngine> engine);
void SetListeners(Listeners const & listeners);
UserMark const * GetUserMarkById(df::MarkID id) const;
// If not found mark on rect result is nullptr.
// If mark is found in "d" return distance from rect center.
@ -86,6 +107,8 @@ protected:
virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg) = 0;
private:
void NotifyListeners();
df::DrapeEngineSafePtr m_drapeEngine;
std::bitset<4> m_flags;
double m_layerDepth;
@ -95,6 +118,8 @@ private:
std::set<df::MarkID> m_removedMarks;
bool m_isDirty = false;
Listeners m_listeners;
DISALLOW_COPY_AND_MOVE(UserMarkContainer);
};