[bookmarks] Share single track

Signed-off-by: cyber-toad <the.cyber.toad@proton.me>
This commit is contained in:
cyber-toad 2025-02-16 23:58:31 +01:00 committed by Konstantin Pastbin
parent 83df1e5004
commit 04eb9642bb
7 changed files with 133 additions and 0 deletions

View file

@ -591,6 +591,15 @@ Java_app_organicmaps_bookmarks_data_BookmarkManager_nativeSetAllCategoriesVisibi
frm()->GetBookmarkManager().SetAllCategoriesVisibility(static_cast<bool>(visible));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_bookmarks_data_BookmarkManager_nativePrepareTrackFileForSharing(JNIEnv * env, jclass, jlong trackId, jint kmlFileType)
{
frm()->GetBookmarkManager().PrepareTrackFileForSharing(static_cast<kml::TrackId>(trackId), [env](BookmarkManager::SharingResult const & result)
{
OnPreparedFileForSharing(env, result);
}, static_cast<KmlFileType>(kmlFileType));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_bookmarks_data_BookmarkManager_nativePrepareFileForSharing(JNIEnv * env, jclass, jlongArray catIds, jint kmlFileType)
{

View file

@ -795,10 +795,17 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_edit, this::onTrackEditActionSelected));
items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Text)));
items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Gpx)));
items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, () -> onDeleteTrackSelected(track.getTrackId())));
return items;
}
private void onShareTrackSelected(long trackId, KmlFileType kmlFileType)
{
BookmarksSharingHelper.INSTANCE.prepareTrackForSharing(requireActivity(), trackId, kmlFileType);
}
@Override
public void onPreparedFileForSharing(@NonNull BookmarkSharingResult result)
{

View file

@ -36,6 +36,12 @@ public enum BookmarksSharingHelper
BookmarkManager.INSTANCE.prepareCategoriesForSharing(new long[]{catId}, kmlFileType);
}
public void prepareTrackForSharing(@NonNull Activity context, long trackId, KmlFileType kmlFileType)
{
showProgressDialog(context);
BookmarkManager.INSTANCE.prepareTrackForSharing(trackId, kmlFileType);
}
private void showProgressDialog(@NonNull Activity context)
{
mProgressDialog = new ProgressDialog(context, R.style.MwmTheme_ProgressDialog);

View file

@ -527,6 +527,11 @@ public enum BookmarkManager
nativePrepareFileForSharing(catIds, kmlFileType.ordinal());
}
public void prepareTrackForSharing(long trackId, KmlFileType kmlFileType)
{
nativePrepareTrackFileForSharing(trackId, kmlFileType.ordinal());
}
public void setNotificationsEnabled(boolean enabled)
{
nativeSetNotificationsEnabled(enabled);
@ -806,6 +811,8 @@ public enum BookmarkManager
private static native void nativePrepareFileForSharing(long[] catIds, int kmlFileType);
private static native void nativePrepareTrackFileForSharing(long trackId, int kmlFileType);
private static native boolean nativeIsCategoryEmpty(long catId);
private static native void nativeSetNotificationsEnabled(boolean enabled);

View file

@ -2901,6 +2901,24 @@ bool BookmarkManager::SaveBookmarkCategory(kml::MarkGroupId groupId, Writer & wr
return SaveKmlData(*kmlData, writer, fileType);
}
BookmarkManager::KMLDataCollectionPtr BookmarkManager::PrepareToSaveBookmarksForTrack(kml::TrackId trackId)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
auto collection = std::make_shared<KMLDataCollection>();
auto const & track = GetTrack(trackId);
auto const & categoryData = new kml::CategoryData();
auto name = kml::LocalizableString();
kml::SetDefaultStr(name, track->GetName());
categoryData->m_name = name;
auto const & trackData = track->GetData();
auto const & fileData = new kml::FileData();
fileData->m_categoryData = *categoryData;
fileData->m_tracksData.push_back(trackData);
collection->emplace_back("", fileData);
return collection;
}
BookmarkManager::KMLDataCollectionPtr BookmarkManager::PrepareToSaveBookmarks(
kml::GroupIdCollection const & groupIdCollection)
{
@ -2959,6 +2977,23 @@ void BookmarkManager::SaveBookmarks(kml::GroupIdCollection const & groupIdCollec
});
}
void BookmarkManager::PrepareTrackFileForSharing(kml::TrackId trackId, SharingHandler && handler, KmlFileType kmlFileType)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
ASSERT(handler, ());
auto collection = PrepareToSaveBookmarksForTrack(trackId);
if (m_testModeEnabled)
{
handler(GetFileForSharing(std::move(collection), kmlFileType));
}
else
{
GetPlatform().RunTask(Platform::Thread::File,
[collection = std::move(collection), handler = std::move(handler), kmlFileType = kmlFileType]() mutable
{ handler(GetFileForSharing(std::move(collection), kmlFileType)); });
}
}
void BookmarkManager::PrepareFileForSharing(kml::GroupIdCollection && categoriesIds, SharingHandler && handler, KmlFileType kmlFileType)
{
CHECK_THREAD_CHECKER(m_threadChecker, ());

View file

@ -354,6 +354,7 @@ public:
using SharingHandler = platform::SafeCallback<void(SharingResult const & result)>;
void PrepareFileForSharing(kml::GroupIdCollection && categoriesIds, SharingHandler && handler, KmlFileType kmlFileType);
void PrepareTrackFileForSharing(kml::TrackId trackId, SharingHandler && handler, KmlFileType kmlFileType);
void PrepareAllFilesForSharing(SharingHandler && handler);
bool AreAllCategoriesEmpty() const;
@ -649,6 +650,7 @@ private:
std::unique_ptr<kml::FileData> CollectBmGroupKMLData(BookmarkCategory const * group) const;
KMLDataCollectionPtr PrepareToSaveBookmarks(kml::GroupIdCollection const & groupIdCollection);
KMLDataCollectionPtr PrepareToSaveBookmarksForTrack(kml::TrackId trackId);
bool HasDuplicatedIds(kml::FileData const & fileData) const;
template <typename UniquityChecker>
@ -830,6 +832,7 @@ private:
Metadata m_metadata;
// Switch some operations in bookmark manager to synchronous mode to simplify unit-testing.
bool m_testModeEnabled = false;
CategoriesCollection m_compilations;

View file

@ -1507,6 +1507,72 @@ UNIT_CLASS_TEST(Runner, ExportSingleUnicode)
bmManager.PrepareFileForSharing(std::move(categories), checker, KmlFileType::Text);
}
UNIT_CLASS_TEST(Runner, ExportSingleTrackKmz)
{
std::string const file = GetPlatform().TestsDataPathForFile("test_data/gpx/export_test.gpx");
BookmarkManager bmManager(BM_CALLBACKS);
bmManager.EnableTestMode(true);
BookmarkManager::KMLDataCollection kmlDataCollection;
kmlDataCollection.emplace_back(file, LoadKmlFile(file, KmlFileType::Gpx));
bmManager.CreateCategories(std::move(kmlDataCollection));
auto const kmzChecker = [](BookmarkManager::SharingResult const & result)
{
auto filePath = result.m_sharingPath;
TEST(filePath.find("Some random route.kmz") != std::string::npos, ());
ZipFileReader::FileList files;
ZipFileReader::FilesList(filePath, files);
std::string kmlFileName = "Some random route.kml";
auto kmlFilePath = base::JoinPath(GetPlatform().TmpDir(), kmlFileName);
ZipFileReader::UnzipFile(filePath, kmlFileName, kmlFilePath);
auto fileData = LoadKmlFile(kmlFilePath, KmlFileType::Text);
TEST_EQUAL(1, fileData->m_tracksData.size(), ());
TEST(base::DeleteFileX(filePath), ());
TEST(base::DeleteFileX(kmlFilePath), ());
};
auto category = bmManager.GetUnsortedBmGroupsIdList()[0];
auto tracks = bmManager.GetTrackIds(category);
for (auto const & trackId : tracks)
{
auto track = bmManager.GetTrack(trackId);
if (track->GetName().find("Some random route") != std::string::npos)
{
bmManager.PrepareTrackFileForSharing(track->GetId(), kmzChecker, KmlFileType::Text);
}
}
}
UNIT_CLASS_TEST(Runner, ExportSingleTrackGpx)
{
std::string const file = GetPlatform().TestsDataPathForFile("test_data/gpx/export_test.gpx");
BookmarkManager bmManager(BM_CALLBACKS);
bmManager.EnableTestMode(true);
BookmarkManager::KMLDataCollection kmlDataCollection;
kmlDataCollection.emplace_back(file, LoadKmlFile(file, KmlFileType::Gpx));
bmManager.CreateCategories(std::move(kmlDataCollection));
auto const gpxChecker = [](BookmarkManager::SharingResult const & result)
{
auto filePath = result.m_sharingPath;
TEST(filePath.find("Some random route.gpx") != std::string::npos, ());
auto fileData = LoadKmlFile(filePath, KmlFileType::Gpx);
TEST_EQUAL(1, fileData->m_tracksData.size(), ());
TEST(base::DeleteFileX(filePath), ());
};
auto category = bmManager.GetUnsortedBmGroupsIdList()[0];
auto tracks = bmManager.GetTrackIds(category);
for (auto const & trackId : tracks)
{
auto track = bmManager.GetTrack(trackId);
if (track->GetName().find("Some random route") != std::string::npos)
{
bmManager.PrepareTrackFileForSharing(track->GetId(), gpxChecker, KmlFileType::Gpx);
}
}
}
UNIT_CLASS_TEST(Runner, ExportSingleGpx)
{
std::string const file = GetPlatform().TestsDataPathForFile("test_data/gpx/route.gpx");