[bookmarks] Track visibility of bookmarks, that belong to any number of compilations MAPSME-14915

This commit is contained in:
Anatoliy Tomilov 2020-10-14 20:29:00 +05:00 committed by Arsentiy Milchakov
parent ecd03ce3a1
commit 85a41c0e84
6 changed files with 150 additions and 10 deletions

View file

@ -1013,6 +1013,15 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeSetAllCategoriesVi
frm()->GetBookmarkManager().SetAllCategoriesVisibility(filter, static_cast<bool>(visible));
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeSetChildCategoriesVisibility(
JNIEnv * env, jobject thiz, jlong categoryId, jint compilationType, jboolean visible)
{
frm()->GetBookmarkManager().SetChildCategoriesVisibility(categoryId,
static_cast<kml::CompilationType>(compilationType),
static_cast<bool>(visible));
}
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGetKmlFilesCountForConversion(
JNIEnv * env, jobject thiz)

View file

@ -64,6 +64,14 @@ public enum BookmarkManager
public static final int SORT_BY_DISTANCE = 1;
public static final int SORT_BY_TIME = 2;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ CATEGORY, COLLECTION, DAY })
public @interface CompilationType {}
public static final int CATEGORY = 0;
public static final int COLLECTION = 1;
public static final int DAY = 2;
public static final List<Icon> ICONS = new ArrayList<>();
@NonNull
@ -700,6 +708,11 @@ public enum BookmarkManager
nativeSetAllCategoriesVisibility(visible, type.ordinal());
}
public void setChildCategoriesVisibility(long catId, @BookmarkManager.CompilationType int compilationType, boolean visible)
{
nativeSetChildCategoriesVisibility(catId, compilationType, visible);
}
public int getKmlFilesCountForConversion()
{
return nativeGetKmlFilesCountForConversion();
@ -1110,6 +1123,8 @@ public enum BookmarkManager
private static native boolean nativeAreAllCategoriesInvisible(int type);
private static native void nativeSetAllCategoriesVisibility(boolean visible, int type);
private static native void nativeSetChildCategoriesVisibility(long catId, int compilationType, boolean visible);
private static native int nativeGetKmlFilesCountForConversion();

View file

@ -93,6 +93,12 @@ void Bookmark::SetAddress(search::ReverseGeocoder::RegionAddress const & address
m_address = address;
}
void Bookmark::SetIsVisible(bool isVisible)
{
SetDirty();
m_isVisible = isVisible;
}
dp::Anchor Bookmark::GetAnchor() const
{
return dp::Bottom;

View file

@ -25,6 +25,9 @@ public:
search::ReverseGeocoder::RegionAddress const & GetAddress() const;
void SetAddress(search::ReverseGeocoder::RegionAddress const & address);
bool IsVisible() const override { return m_isVisible; }
void SetIsVisible(bool isVisible);
bool HasCreationAnimation() const override;
std::string GetPreferredName() const;
@ -64,12 +67,15 @@ public:
void AttachCompilation(kml::MarkGroupId groupId);
void Detach();
kml::GroupIdCollection const & GetCompilations() const { return m_compilationIds; }
private:
drape_ptr<df::UserPointMark::SymbolNameZoomInfo> GetCustomSymbolNames() const;
kml::BookmarkData m_data;
kml::MarkGroupId m_groupId;
kml::GroupIdCollection m_compilationIds;
bool m_isVisible = true;
search::ReverseGeocoder::RegionAddress m_address;
};
@ -84,6 +90,8 @@ public:
static kml::PredefinedColor GetDefaultColor();
kml::MarkGroupId GetID() const { return m_data.m_id; }
kml::MarkGroupId GetParentID() const { return m_parentId; }
void SetParentId(kml::MarkGroupId parentId) { m_parentId = parentId; }
void SetIsVisible(bool isVisible) override;
void SetName(std::string const & name);
@ -110,12 +118,13 @@ public:
void SetTags(std::vector<std::string> const & tags);
void SetCustomProperty(std::string const & key, std::string const & value);
private:
void SetDirty() override;
private:
// Stores file name from which bookmarks were loaded.
std::string m_file;
bool m_autoSave = true;
kml::CategoryData m_data;
std::string m_serverId;
kml::MarkGroupId m_parentId = kml::kInvalidMarkGroupId;
};

View file

@ -674,6 +674,13 @@ Bookmark * BookmarkManager::GetBookmarkForEdit(kml::MarkId markId)
return it->second.get();
}
Bookmark * BookmarkManager::GetBookmarkForVisibilityChange(kml::MarkId markId)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
auto it = m_bookmarks.find(markId);
return (it != m_bookmarks.end()) ? it->second.get() : nullptr;
}
void BookmarkManager::AttachBookmark(kml::MarkId bmId, kml::MarkGroupId catId)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
@ -1386,8 +1393,10 @@ kml::GroupIdCollection BookmarkManager::GetCompilationOfType(kml::MarkGroupId pa
std::copy_if(compilations.cbegin(), compilations.cend(), std::back_inserter(result),
[this, type](auto const groupId)
{
auto const & child = m_compilations.at(groupId);
return child->GetCategoryData().m_type == type;
auto const compilation = m_compilations.find(groupId);
ASSERT(compilation != m_compilations.end(), ());
auto const & child = *compilation->second;
return child.GetCategoryData().m_type == type;
});
return result;
@ -1962,6 +1971,12 @@ void BookmarkManager::SetIsVisible(kml::MarkGroupId groupId, bool visible)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
GetGroup(groupId)->SetIsVisible(visible);
if (visible)
{
auto const compilation = m_compilations.find(groupId);
if (compilation != m_compilations.end())
GetGroup(compilation->second->GetParentID())->SetIsVisible(true);
}
UpdateTrackMarksVisibility(groupId);
}
@ -2977,6 +2992,12 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool
group->SetFileName(fileName);
group->SetServerId(fileData.m_serverId);
for (auto const & [compilationId, compilation] : compilations)
{
UNUSED_VALUE(compilationId);
compilation->SetParentId(groupId);
}
// Restore sensitive info from the cache.
auto const cacheIt = m_restoringCache.find(fileName);
if (cacheIt != m_restoringCache.end() &&
@ -3323,7 +3344,7 @@ bool BookmarkManager::AreAllCategoriesInvisible(CategoryFilterType const filter)
return CheckVisibility(filter, false /* isVisible */);
}
bool BookmarkManager::CheckVisibility(BookmarkManager::CategoryFilterType const filter,
bool BookmarkManager::CheckVisibility(CategoryFilterType const filter,
bool isVisible) const
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
@ -3352,6 +3373,30 @@ void BookmarkManager::SetAllCategoriesVisibility(CategoryFilterType const filter
}
}
void BookmarkManager::SetChildCategoriesVisibility(kml::MarkGroupId categoryId, kml::CompilationType compilationType,
bool visible)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
auto session = GetEditSession();
auto const categoryIt = m_categories.find(categoryId);
CHECK(categoryIt != m_categories.end(), ());
auto & category = *categoryIt->second;
kml::GroupIdCollection const & compilationIds = category.GetCategoryData().m_compilationIds;
for (kml::MarkGroupId const compilationId : compilationIds)
{
auto const compilationIt = m_compilations.find(compilationId);
CHECK(compilationIt != m_compilations.cend(), ());
auto & compilation = *compilationIt->second;
if (compilation.GetCategoryData().m_type != compilationType)
continue;
if (visible)
category.SetIsVisible(true);
else if (compilation.IsVisible())
category.SetDirty();
compilation.SetIsVisible(visible);
}
}
bool BookmarkManager::CanConvert() const
{
// The conversion available only after successful migration.
@ -4038,6 +4083,55 @@ bool BookmarkManager::MarksChangesTracker::HasBookmarkCategories(
return false;
}
void BookmarkManager::MarksChangesTracker::InferBookmarksVisibility(BookmarkCategory * const group,
kml::MarkIdSet & dirtyMarks)
{
kml::CategoryData const & categoryData = group->GetCategoryData();
if (categoryData.m_compilationIds.empty())
return;
std::unordered_set<kml::MarkGroupId> visibility;
visibility.reserve(categoryData.m_compilationIds.size());
for (kml::MarkGroupId const compilationId : categoryData.m_compilationIds)
{
auto const compilation = m_bmManager->m_compilations.find(compilationId);
CHECK(compilation != m_bmManager->m_compilations.end(), ());
if (compilation->second.get()->IsVisible())
visibility.emplace(compilationId);
}
auto const groupId = group->GetID();
bool hasUserMarksOrDanglingBookmarks = false;
for (kml::MarkId const userMark : m_bmManager->GetUserMarkIds(groupId))
{
if (!m_bmManager->IsBookmark(userMark))
{
hasUserMarksOrDanglingBookmarks = true;
continue;
}
Bookmark * const bookmark = m_bmManager->GetBookmarkForVisibilityChange(userMark);
if (bookmark->GetCompilations().empty())
hasUserMarksOrDanglingBookmarks = true;
bool isVisible = false;
for (kml::MarkGroupId const compilationId : bookmark->GetCompilations())
{
if (visibility.count(compilationId) != 0)
{
isVisible = true;
break;
}
}
if (isVisible != bookmark->IsVisible())
{
dirtyMarks.insert(userMark);
bookmark->SetIsVisible(isVisible);
}
}
if (visibility.empty() && m_bmManager->GetTrackIds(groupId).empty() &&
!hasUserMarksOrDanglingBookmarks)
{
group->SetIsVisible(false);
}
}
void BookmarkManager::MarksChangesTracker::OnAttachBookmark(kml::MarkId markId,
kml::MarkGroupId catId)
{
@ -4107,22 +4201,25 @@ void BookmarkManager::MarksChangesTracker::OnBecomeInvisibleGroup(kml::MarkGroup
void BookmarkManager::MarksChangesTracker::AcceptDirtyItems()
{
kml::MarkIdSet dirtyMarks;
CHECK(m_updatedGroups.empty(), ());
m_bmManager->GetDirtyGroups(m_updatedGroups);
for (auto groupId : m_updatedGroups)
{
auto group = m_bmManager->GetGroup(groupId);
if (group->IsVisibilityChanged())
auto userMarkLayer = m_bmManager->GetGroup(groupId);
if (auto const group = dynamic_cast<BookmarkCategory *>(userMarkLayer))
InferBookmarksVisibility(group, dirtyMarks);
if (userMarkLayer->IsVisibilityChanged())
{
if (group->IsVisible())
if (userMarkLayer->IsVisible())
m_becameVisibleGroups.insert(groupId);
else
m_becameInvisibleGroups.insert(groupId);
}
group->ResetChanges();
userMarkLayer->ResetChanges();
}
kml::MarkIdSet dirtyMarks;
for (auto const markId : m_updatedMarks)
{
auto const mark = m_bmManager->GetMark(markId);

View file

@ -49,7 +49,6 @@ class BookmarkManager final
{
using UserMarkLayers = std::vector<std::unique_ptr<UserMarkLayer>>;
using CategoriesCollection = std::map<kml::MarkGroupId, std::unique_ptr<BookmarkCategory>>;
using MarksCollection = std::map<kml::MarkId, std::unique_ptr<UserMark>>;
using BookmarksCollection = std::map<kml::MarkId, std::unique_ptr<Bookmark>>;
using TracksCollection = std::map<kml::TrackId, std::unique_ptr<Track>>;
@ -372,6 +371,8 @@ public:
bool AreAllCategoriesVisible(CategoryFilterType const filter) const;
bool AreAllCategoriesInvisible(CategoryFilterType const filter) const;
void SetAllCategoriesVisibility(CategoryFilterType const filter, bool visible);
void SetChildCategoriesVisibility(kml::MarkGroupId categoryId, kml::CompilationType compilationType,
bool visible);
// Return number of files for the conversion to the binary format.
size_t GetKmlFilesCountForConversion() const;
@ -573,6 +574,8 @@ private:
GroupMarkIdSet & setToInsert, GroupMarkIdSet & setToErase);
bool HasBookmarkCategories(kml::GroupIdSet const & groupIds) const;
void InferBookmarksVisibility(BookmarkCategory * const group, kml::MarkIdSet & dirtyMarks);
BookmarkManager * m_bmManager;
kml::MarkIdSet m_createdMarks;
@ -641,6 +644,7 @@ private:
Bookmark * CreateBookmark(kml::BookmarkData && bmData, kml::MarkGroupId groupId);
Bookmark * GetBookmarkForEdit(kml::MarkId markId);
Bookmark * GetBookmarkForVisibilityChange(kml::MarkId markId);
void AttachBookmark(kml::MarkId bmId, kml::MarkGroupId groupId);
void DetachBookmark(kml::MarkId bmId, kml::MarkGroupId groupId);
void DeleteBookmark(kml::MarkId bmId);