diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 6467e1098f..883644428d 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -4,8 +4,6 @@ #include "com/mapswithme/opengl/androidoglcontextfactory.hpp" #include "com/mapswithme/platform/Platform.hpp" -#include "map/user_mark.hpp" - #include "drape_frontend/visual_params.hpp" #include "drape_frontend/user_event_stream.hpp" #include "drape/pointers.hpp" @@ -61,7 +59,6 @@ Framework::Framework() , m_currentMode(location::MODE_UNKNOWN_POSITION) , m_isCurrentModeInitialized(false) , m_isChoosePositionMode(false) - , m_activeUserMark(nullptr) { ASSERT_EQUAL ( g_framework, 0, () ); g_framework = this; @@ -293,11 +290,6 @@ void Framework::RemoveLocalMaps() m_work.DeregisterAllMaps(); } -BookmarkAndCategory Framework::AddBookmark(size_t cat, m2::PointD const & pt, BookmarkData & bm) -{ - return BookmarkAndCategory(cat, m_work.AddBookmark(cat, pt, bm)); -} - void Framework::ReplaceBookmark(BookmarkAndCategory const & ind, BookmarkData & bm) { m_work.ReplaceBookmark(ind.first, ind.second, bm); @@ -315,7 +307,7 @@ bool Framework::ShowMapForURL(string const & url) void Framework::DeactivatePopup() { - m_work.DeactivateUserMark(); + m_work.DeactivateMapSelection(false); } string Framework::GetOutdatedCountriesString() @@ -399,14 +391,14 @@ void Framework::ExecuteDrapeTasks() m_drapeTasksQueue.clear(); } -void Framework::SetActiveUserMark(UserMark const * mark) +void Framework::SetPlacePageInfo(place_page::Info const & info) { - m_activeUserMark = mark; + m_info = info; } -UserMark const * Framework::GetActiveUserMark() +place_page::Info & Framework::GetPlacePageInfo() { - return m_activeUserMark; + return m_info; } bool Framework::HasSpaceForMigration() @@ -443,38 +435,6 @@ bool Framework::PreMigrate(ms::LatLon const & position, Storage::TChangeCountryF extern "C" { - void CallOnMapObjectActivatedListener(shared_ptr listener, jobject mapObject) - { - JNIEnv * env = jni::GetEnv(); - jmethodID const methodId = jni::GetMethodID(env, *listener, "onMapObjectActivated", - "(Lcom/mapswithme/maps/bookmarks/data/MapObject;)V"); - //public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName) - env->CallVoidMethod(*listener, methodId, mapObject); - } - - void CallOnDismissListener(shared_ptr obj) - { - JNIEnv * env = jni::GetEnv(); - jmethodID const methodId = jni::GetMethodID(env, *obj, "onDismiss", "()V"); - ASSERT(methodId, ()); - env->CallVoidMethod(*obj, methodId); - } - - void CallOnUserMarkActivated(shared_ptr obj, unique_ptr markCopy) - { - if (markCopy == nullptr) - { - g_framework->SetActiveUserMark(nullptr); - CallOnDismissListener(obj); - return; - } - - UserMark const * mark = markCopy->GetUserMark(); - g_framework->SetActiveUserMark(mark); - jni::TScopedLocalRef mapObject(jni::GetEnv(), usermark_helper::CreateMapObject(mark)); - CallOnMapObjectActivatedListener(obj, mapObject.get()); - } - void CallRoutingListener(shared_ptr listener, int errorCode, vector const & absentMaps) { JNIEnv * env = jni::GetEnv(); @@ -517,13 +477,34 @@ extern "C" JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetMapObjectListener(JNIEnv * env, jclass clazz, jobject l) { - frm()->SetUserMarkActivationListener(bind(&CallOnUserMarkActivated, jni::make_global_ref(l), _1)); + // TODO: We never clean up this global ref. + jobject const listener = env->NewGlobalRef(l); + frm()->SetMapSelectionListeners([listener](place_page::Info const & info) + { + // 1st listener: User has selected an object on a map. + JNIEnv * env = jni::GetEnv(); + g_framework->SetPlacePageInfo(info); + jni::TScopedLocalRef mapObject(env, usermark_helper::CreateMapObject(env, info)); + jmethodID const methodId = jni::GetMethodID(env, listener, "onMapObjectActivated", + "(Lcom/mapswithme/maps/bookmarks/data/MapObject;)V"); + //public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName) + env->CallVoidMethod(listener, methodId, mapObject.get()); + }, [listener](bool /*enterFullScreenMode*/) + { + // 2nd listener: User has deselected object on a map, or tapped on an empty space (iOS toggles full screen mode in this case). + JNIEnv * env = jni::GetEnv(); + // TODO(yunikkk): Do we really need the next line? UI should always know when this info is valid, right? + g_framework->SetPlacePageInfo({}); + jmethodID const methodId = jni::GetMethodID(env, listener, "onDismiss", "()V"); + ASSERT(methodId, ()); + env->CallVoidMethod(listener, methodId); + }); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeRemoveMapObjectListener(JNIEnv * env, jobject thiz) { - frm()->SetUserMarkActivationListener(::Framework::TActivateCallbackFn()); + frm()->SetMapSelectionListeners({}, {}); } JNIEXPORT jstring JNICALL @@ -979,17 +960,20 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_Framework_nativeGetActiveMapObject(JNIEnv * env, jclass thiz) { - UserMark const * mark = g_framework->GetActiveUserMark(); - if (!mark) - return nullptr; - return usermark_helper::CreateMapObject(mark); + return usermark_helper::CreateMapObject(env, g_framework->GetPlacePageInfo()); } + extern JNIEXPORT void JNICALL + Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeDeleteBookmark(JNIEnv *, jobject, jint, jint); + JNIEXPORT jobject JNICALL - Java_com_mapswithme_maps_Framework_nativeActivateMapObject(JNIEnv * env, jclass clazz, jdouble lat, jdouble lon) + Java_com_mapswithme_maps_Framework_nativeDeleteBookmarkFromMapObject(JNIEnv * env, jclass clazz) { - UserMark const * mark = frm()->GetAddressMark(MercatorBounds::FromLatLon(lat, lon)); - g_framework->SetActiveUserMark(mark); - return usermark_helper::CreateMapObject(mark); + place_page::Info & info = g_framework->GetPlacePageInfo(); + // TODO(yunikkk): Reuse already existing implementation. It probably can be done better. + Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeDeleteBookmark(nullptr, nullptr, + info.m_bac.first, info.m_bac.second); + info.m_bac = MakeEmptyBookmarkAndCategory(); + return usermark_helper::CreateMapObject(env, info); } } // extern "C" diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index d23599bfbf..75cf71b8f0 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -3,6 +3,7 @@ #include #include "map/framework.hpp" +#include "map/place_page_info.hpp" #include "search/result.hpp" @@ -49,7 +50,7 @@ namespace android bool m_isChoosePositionMode; - UserMark const * m_activeUserMark; + place_page::Info m_info; public: Framework(); @@ -112,7 +113,6 @@ namespace android void Scale(::Framework::EScaleMode mode); - BookmarkAndCategory AddBookmark(size_t category, m2::PointD const & pt, BookmarkData & bm); void ReplaceBookmark(BookmarkAndCategory const & ind, BookmarkData & bm); size_t ChangeBookmarkCategory(BookmarkAndCategory const & ind, size_t newCat); @@ -146,8 +146,8 @@ namespace android // Posts a task which must be executed when Drape Engine is alive. void PostDrapeTask(TDrapeTask && task); - void SetActiveUserMark(UserMark const * mark); - UserMark const * GetActiveUserMark(); + void SetPlacePageInfo(place_page::Info const & info); + place_page::Info & GetPlacePageInfo(); bool HasSpaceForMigration(); bool NeedMigrate(); diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index 3be664c597..d66f82fc63 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -199,7 +199,8 @@ extern "C" { lock_guard guard(g_resultsMutex); Result const & result = g_results.GetResult(index); - g_framework->SetActiveUserMark(nullptr); + // TODO(yunikkk): why do we need to do it? + g_framework->SetPlacePageInfo({}); g_framework->PostDrapeTask([result]() { g_framework->NativeFramework()->ShowSearchResult(result); diff --git a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp index 789ee0128f..e5f4a813bd 100644 --- a/android/jni/com/mapswithme/maps/UserMarkHelper.cpp +++ b/android/jni/com/mapswithme/maps/UserMarkHelper.cpp @@ -1,16 +1,12 @@ #include "UserMarkHelper.hpp" +#include "map/place_page_info.hpp" + namespace usermark_helper { using search::AddressInfo; using feature::Metadata; -template -T const * CastMark(UserMark const * data) -{ - return static_cast(data); -} - void InjectMetadata(JNIEnv * env, jclass const clazz, jobject const mapObject, feature::Metadata const & metadata) { static jmethodID const addId = env->GetMethodID(clazz, "addMetadata", "(ILjava/lang/String;)V"); @@ -48,41 +44,10 @@ pair NativeMetadataToJavaMetadata(JNIEnv * env, Metadat return make_pair(j_metaTypes, j_metaValues); } -void FillAddressAndMetadata(UserMark const * mark, AddressInfo & info, Metadata & metadata) +// TODO(yunikkk): displayed information does not need separate street and house. +// There is an AddressInfo::FormatAddress() method which should be used instead. +jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & name, double lat, double lon, string const & typeName, string const & street, string const & house, Metadata const & metadata) { - Framework * frm = g_framework->NativeFramework(); - auto * feature = mark->GetFeature(); - if (feature) - { - info = frm->GetFeatureAddressInfo(*feature); - metadata = feature->GetMetadata(); - } - else - { - // Calculate at least country name for a point. Can we provide more address information? - info.m_country = frm->GetCountryName(mark->GetPivot()); - } -} - -jobject CreateBookmark(int categoryId, int bookmarkId, string const & typeName, Metadata const & metadata) -{ - JNIEnv * env = jni::GetEnv(); - // Java signature : - // public Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String name) - static jmethodID const ctorId = jni::GetConstructorID(env, g_bookmarkClazz, "(IILjava/lang/String;)V"); - jni::TScopedLocalRef name(env, jni::ToJavaString(env, typeName)); - jobject mapObject = env->NewObject(g_bookmarkClazz, ctorId, - static_cast(categoryId), - static_cast(bookmarkId), - name.get()); - - InjectMetadata(env, g_mapObjectClazz, mapObject, metadata); - return mapObject; -} - -jobject CreateMapObject(int mapObjectType, string const & name, double lat, double lon, string const & typeName, string const & street, string const & house, Metadata const & metadata) -{ - JNIEnv * env = jni::GetEnv(); // Java signature : // public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName, String street, String house) static jmethodID const ctorId = @@ -101,55 +66,43 @@ jobject CreateMapObject(int mapObjectType, string const & name, double lat, doub return mapObject; } -jobject CreateMapObject(UserMark const * userMark) +jobject CreateMapObject(JNIEnv * env, place_page::Info const & info) { - search::AddressInfo info; - feature::Metadata metadata; - FillAddressAndMetadata(userMark, info, metadata); - jobject mapObject = nullptr; - ms::LatLon ll = userMark->GetLatLon(); - switch (userMark->GetMarkType()) + ms::LatLon const ll = info.GetLatLon(); + + if (info.IsMyPosition()) + return CreateMapObject(env, kMyPosition, {}, ll.lat, ll.lon, {}, {}, {}, {}); + + // TODO(yunikkk): object can be POI + API + search result + bookmark simultaneously. + if (info.HasApiUrl()) + return CreateMapObject(env, kApiPoint, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), {}, {}, info.GetMetadata()); + + // TODO(yunikkk): Bookmark can also be a feature. + if (info.IsBookmark()) { - case UserMark::Type::API: - { - ApiMarkPoint const * apiMark = CastMark(userMark); - mapObject = CreateMapObject(kApiPoint, apiMark->GetName(), ll.lat, ll.lon, apiMark->GetID(), "", "", metadata); - break; - } - case UserMark::Type::BOOKMARK: - { - BookmarkAndCategory bmAndCat = g_framework->NativeFramework()->FindBookmark(userMark); - Bookmark const * bookmark = CastMark(userMark); - if (IsValid(bmAndCat)) - mapObject = CreateBookmark(bmAndCat.first, bmAndCat.second, bookmark->GetName(), metadata); - break; - } - case UserMark::Type::POI: - { - // TODO(AlexZ): Refactor out passing custom name for shared links. - auto const & cn = CastMark(userMark)->GetCustomName(); - if (!cn.empty()) - info.m_name = cn; - mapObject = CreateMapObject(kPoi, info.GetPinName(), ll.lat, ll.lon, info.GetPinType(), info.m_street, info.m_house, metadata); - break; - } - case UserMark::Type::SEARCH: - { - mapObject = CreateMapObject(kSearch, info.GetPinName(), ll.lat, ll.lon, info.GetPinType(), info.m_street, info.m_house, metadata); - break; - } - case UserMark::Type::MY_POSITION: - { - mapObject = CreateMapObject(kMyPosition, "", ll.lat, ll.lon, "", "", "", metadata); - break; - } - case UserMark::Type::DEBUG_MARK: - { - // Ignore clicks to debug marks. - break; - } + // Java signature : + // public Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String name) + static jmethodID const ctorId = jni::GetConstructorID(env, g_bookmarkClazz, "(IILjava/lang/String;)V"); + jni::TScopedLocalRef jName(env, jni::ToJavaString(env, info.GetTitle())); + jobject mapObject = env->NewObject(g_bookmarkClazz, ctorId, + static_cast(info.m_bac.first), + static_cast(info.m_bac.second), + jName.get()); + if (info.IsFeature()) + InjectMetadata(env, g_mapObjectClazz, mapObject, info.GetMetadata()); + return mapObject; } - return mapObject; + Framework * frm = g_framework->NativeFramework(); + if (info.IsFeature()) + { + search::AddressInfo const address = frm->GetFeatureAddressInfo(info.GetID()); + // TODO(yunikkk): Pass address.FormatAddress() to UI instead of separate house and street. + // TODO(yunikkk): Should we pass localized strings here and in other methods as byte arrays? + return CreateMapObject(env, kPoi, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), address.m_street, + address.m_house, info.GetMetadata()); + } + // User have selected an empty place on a map with a long tap. + return CreateMapObject(env, kPoi, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), {}, {}, {}); } } // namespace usermark_helper diff --git a/android/jni/com/mapswithme/maps/UserMarkHelper.hpp b/android/jni/com/mapswithme/maps/UserMarkHelper.hpp index 4a15aacd82..71d4b460c6 100644 --- a/android/jni/com/mapswithme/maps/UserMarkHelper.hpp +++ b/android/jni/com/mapswithme/maps/UserMarkHelper.hpp @@ -5,10 +5,19 @@ #include "com/mapswithme/core/jni_helper.hpp" #include "com/mapswithme/maps/Framework.hpp" -#include "map/user_mark.hpp" +namespace place_page +{ +class Info; +} // namespace place_page +// TODO(yunikkk): this helper is redundant with new place page info approach. +// It's better to refactor MapObject in Java, may be removing it at all, and to make simple jni getters for +// globally stored place_page::Info object. Code should be clean and easy to support in this way. namespace usermark_helper { +// TODO(yunikkk): PP can be POI and bookmark at the same time. And can be even POI + bookmark + API at the same time. +// The same for search result: it can be also a POI and bookmark (and API!). +// That is one of the reasons why existing solution should be refactored. // should be equal with definitions in MapObject.java static constexpr int kPoi = 0; static constexpr int kApiPoint = 1; @@ -16,19 +25,14 @@ static constexpr int kBookmark = 2; static constexpr int kMyPosition = 3; static constexpr int kSearch = 4; -// Fills mapobject's metadata from UserMark -void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature::Metadata const & metadata); +// Fills mapobject's metadata. +//void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature::Metadata const & metadata); -template -T const * CastMark(UserMark const * data); +//pair NativeMetadataToJavaMetadata(JNIEnv * env, feature::Metadata const & metadata); -pair NativeMetadataToJavaMetadata(JNIEnv * env, feature::Metadata const & metadata); +jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & name, double lat, double lon, + string const & typeName, string const & street, string const & house, + feature::Metadata const & metadata); -void FillAddressAndMetadata(UserMark const * mark, search::AddressInfo & info, feature::Metadata & metadata); - -jobject CreateBookmark(int categoryId, int bookmarkId, string const & typeName, feature::Metadata const & metadata); - -jobject CreateMapObject(int mapObjectType, string const & name, double lat, double lon, string const & typeName, feature::Metadata const & metadata); - -jobject CreateMapObject(UserMark const * userMark); -} // namespace usermark +jobject CreateMapObject(JNIEnv * env, place_page::Info const & info); +} // namespace usermark_helper diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp index b114fb5de8..a952e58667 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkCategory.cpp @@ -79,7 +79,15 @@ JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_bookmarks_data_BookmarkCategory_nativeGetBookmark( JNIEnv * env, jobject thiz, jint id, jint bmkId) { - return usermark_helper::CreateMapObject(getBmCategory(id)->GetUserMark(bmkId)); + BookmarkCategory * category = getBmCategory(id); + // TODO(AlexZ): Get rid of UserMarks completely in UI code. + Bookmark const * bm = static_cast(category->GetUserMark(bmkId)); + // TODO(yunikkk): Refactor java code to get all necessary info without Bookmark wrapper, and without hierarchy. + // If bookmark information is needed in the BookmarkManager, it does not relate in any way to Place Page info + // and should be passed separately via simple name string and lat lon to calculate a distance. + ms::LatLon const ll = bm->GetLatLon(); + return usermark_helper::CreateMapObject(env, usermark_helper::kBookmark, bm->GetName(), ll.lat, ll.lon, + bm->GetType(), "", "", {}); } static uint32_t shift(uint32_t v, uint8_t bitCount) { return v << bitCount; } diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp index 473fe78fed..b01f922cb0 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp @@ -3,12 +3,12 @@ #include "com/mapswithme/maps/UserMarkHelper.hpp" #include "coding/zip_creator.hpp" - +#include "map/place_page_info.hpp" namespace { ::Framework * frm() { return g_framework->NativeFramework(); } -} +} // namespace extern "C" { @@ -52,8 +52,7 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeDeleteCategory( } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeDeleteBookmark( - JNIEnv * env, jobject thiz, jint cat, jint bmk) +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeDeleteBookmark(JNIEnv *, jobject, jint cat, jint bmk) { BookmarkCategory * pCat = frm()->GetBmCategory(cat); if (pCat) @@ -98,13 +97,11 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeAddBookmarkToLastE m2::PointD const glbPoint(MercatorBounds::FromLatLon(lat, lon)); ::Framework * f = frm(); BookmarkData bmkData(ToNativeString(env, name), f->LastEditedBMType()); - BookmarkAndCategory const bmkAndCat = g_framework->AddBookmark(f->LastEditedBMCategory(), glbPoint, bmkData); - BookmarkCategory::Guard guard(*f->GetBookmarkManager().GetBmCategory(bmkAndCat.first)); - UserMark * newBookmark = guard.m_controller.GetUserMarkForEdit(bmkAndCat.second); - // TODO @deathbaba or @yunikkk - remove that hack after BookmarkManager will correctly set features for bookmarks. - newBookmark->SetFeature(f->GetFeatureAtPoint(glbPoint)); - g_framework->SetActiveUserMark(newBookmark); - return usermark_helper::CreateMapObject(newBookmark); + size_t const lastEditedCategory = f->LastEditedBMCategory(); + size_t const createdBookmarkIndex = f->AddBookmark(lastEditedCategory, glbPoint, bmkData); + place_page::Info & info = g_framework->GetPlacePageInfo(); + info.m_bac = {lastEditedCategory, createdBookmarkIndex}; + return usermark_helper::CreateMapObject(env, info); } JNIEXPORT jint JNICALL @@ -115,7 +112,7 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_getLastEditedCategory( } JNIEXPORT jstring JNICALL -Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGenerateUniqueBookmarkName(JNIEnv * env, jclass thiz, jstring jBaseName) +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGenerateUniqueFileName(JNIEnv * env, jclass thiz, jstring jBaseName) { string baseName = ToNativeString(env, jBaseName); string bookmarkFileName = BookmarkCategory::GenerateUniqueFileName(GetPlatform().SettingsDir(), baseName); @@ -127,4 +124,10 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeLoadKmzFile(JNIEnv { return frm()->AddBookmarksFile(ToNativeString(env, path)); } + +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeFormatNewBookmarkName(JNIEnv * env, jclass) +{ + return ToJavaString(env, g_framework->GetPlacePageInfo().FormatNewBookmarkName()); } +} // extern "C" diff --git a/android/jni/com/mapswithme/maps/editor/Editor.cpp b/android/jni/com/mapswithme/maps/editor/Editor.cpp index c8f7867a94..f0bc42153c 100644 --- a/android/jni/com/mapswithme/maps/editor/Editor.cpp +++ b/android/jni/com/mapswithme/maps/editor/Editor.cpp @@ -3,7 +3,10 @@ #include "com/mapswithme/core/jni_helper.hpp" #include "com/mapswithme/maps/Framework.hpp" +#include "base/assert.hpp" #include "base/logging.hpp" +#include "base/string_utils.hpp" +#include "indexer/editable_map_object.hpp" #include "indexer/osm_editor.hpp" #include "std/algorithm.hpp" @@ -12,88 +15,187 @@ namespace { -using feature::Metadata; -using osm::Editor; - -FeatureType * activeFeature() -{ - return g_framework->GetActiveUserMark()->GetFeature(); -} +osm::EditableMapObject gEditableMapObject; } // namespace extern "C" { using osm::Editor; +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetMetadata(JNIEnv * env, jclass, jint type) +{ + // TODO(yunikkk): Switch to osm::Props enum instead of metadata, and use separate getters instead a generic one. + return jni::ToJavaString(env, gEditableMapObject.GetMetadata().Get(static_cast(type))); +} + JNIEXPORT void JNICALL Java_com_mapswithme_maps_editor_Editor_nativeSetMetadata(JNIEnv * env, jclass clazz, jint type, jstring value) { - auto * feature = activeFeature(); - CHECK(feature, ("Feature is not editable!")); - auto & metadata = feature->GetMetadata(); - metadata.Set(static_cast(type), jni::ToNativeString(env, value)); + // TODO(yunikkk): I would recommend to use separate setters/getters for each metadata field. + string const v = jni::ToNativeString(env, value); + using feature::Metadata; + switch (type) + { + // TODO(yunikkk): Pass cuisines in a separate setter via vector of osm untranslated keys (SetCuisines()). + case Metadata::FMD_CUISINE: gEditableMapObject.SetRawOSMCuisines(v); break; + case Metadata::FMD_OPEN_HOURS: gEditableMapObject.SetOpeningHours(v); break; + case Metadata::FMD_PHONE_NUMBER: gEditableMapObject.SetPhone(v); break; + case Metadata::FMD_FAX_NUMBER: gEditableMapObject.SetFax(v); break; + case Metadata::FMD_STARS: + { + // TODO(yunikkk): Pass stars in a separate integer setter. + int stars; + if (strings::to_int(v, stars)) + gEditableMapObject.SetStars(stars); + break; + } + case Metadata::FMD_OPERATOR: gEditableMapObject.SetOperator(v); break; + case Metadata::FMD_URL: // We don't allow url in UI. Website should be used instead. + case Metadata::FMD_WEBSITE: gEditableMapObject.SetWebsite(v); break; + case Metadata::FMD_INTERNET: // TODO(yunikkk): use separate setter for Internet. + { + osm::Internet inet = osm::Internet::Unknown; + if (v == DebugPrint(osm::Internet::Wlan)) + inet = osm::Internet::Wlan; + if (v == DebugPrint(osm::Internet::Wired)) + inet = osm::Internet::Wired; + if (v == DebugPrint(osm::Internet::No)) + inet = osm::Internet::No; + if (v == DebugPrint(osm::Internet::Yes)) + inet = osm::Internet::Yes; + gEditableMapObject.SetInternet(inet); + } + break; + case Metadata::FMD_ELE: + { + double ele; + if (strings::to_double(v, ele)) + gEditableMapObject.SetElevation(ele); + break; + } + case Metadata::FMD_EMAIL: gEditableMapObject.SetEmail(v); break; + case Metadata::FMD_POSTCODE: gEditableMapObject.SetPostcode(v); break; + case Metadata::FMD_WIKIPEDIA: gEditableMapObject.SetWikipedia(v); break; + case Metadata::FMD_FLATS: gEditableMapObject.SetFlats(v); break; + case Metadata::FMD_BUILDING_LEVELS: gEditableMapObject.SetBuildingLevels(v); break; + case Metadata::FMD_TURN_LANES: + case Metadata::FMD_TURN_LANES_FORWARD: + case Metadata::FMD_TURN_LANES_BACKWARD: + case Metadata::FMD_MAXSPEED: + case Metadata::FMD_HEIGHT: + case Metadata::FMD_MIN_HEIGHT: + case Metadata::FMD_DENOMINATION: + case Metadata::FMD_TEST_ID: + case Metadata::FMD_COUNT: + break; + } } -JNIEXPORT void JNICALL -Java_com_mapswithme_maps_editor_Editor_nativeEditFeature(JNIEnv * env, jclass clazz, jstring street, jstring houseNumber) +JNIEXPORT jboolean JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeSaveEditedFeature(JNIEnv *, jclass) { - auto * feature = activeFeature(); - CHECK(feature, ("Feature is not editable!")); - Editor::Instance().EditFeature(*feature, jni::ToNativeString(env, street), jni::ToNativeString(env, houseNumber)); + switch (g_framework->NativeFramework()->SaveEditedMapObject(gEditableMapObject)) + { + case osm::Editor::NothingWasChanged: + case osm::Editor::SavedSuccessfully: + return true; + case osm::Editor::NoFreeSpaceError: + return false; + } +} + +JNIEXPORT jboolean JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeIsFeatureEditable(JNIEnv *, jclass) +{ + return g_framework->GetPlacePageInfo().IsEditable(); } JNIEXPORT jintArray JNICALL -Java_com_mapswithme_maps_editor_Editor_nativeGetEditableMetadata(JNIEnv * env, jclass clazz) +Java_com_mapswithme_maps_editor_Editor_nativeGetEditableFields(JNIEnv * env, jclass clazz) { - auto const * feature = activeFeature(); - auto const editable = feature ? Editor::Instance().GetEditableProperties(*feature) : osm::EditableProperties(); - int const size = editable.m_metadata.size(); - jintArray jEditableTypes = env->NewIntArray(size); - jint * arr = env->GetIntArrayElements(jEditableTypes, 0); - for (int i = 0; i < size; i++) - arr[i] = static_cast(editable.m_metadata[i]); - env->ReleaseIntArrayElements(jEditableTypes, arr, 0); + auto const & editable = gEditableMapObject.GetEditableFields(); + int const size = editable.size(); + jintArray jEditableFields = env->NewIntArray(size); + jint * arr = env->GetIntArrayElements(jEditableFields, 0); + for (int i = 0; i < size; ++i) + arr[i] = editable[i]; + env->ReleaseIntArrayElements(jEditableFields, arr, 0); - return jEditableTypes; + return jEditableFields; } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_editor_Editor_nativeIsAddressEditable(JNIEnv * env, jclass clazz) { - auto const * feature = activeFeature(); - return feature && Editor::Instance().GetEditableProperties(*feature).m_address; + return gEditableMapObject.IsAddressEditable(); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_editor_Editor_nativeIsNameEditable(JNIEnv * env, jclass clazz) { - auto const * feature = activeFeature(); - return feature && Editor::Instance().GetEditableProperties(*feature).m_name; + return gEditableMapObject.IsNameEditable(); +} + +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetDefaultName(JNIEnv * env, jclass) +{ + // TODO(yunikkk): add multilanguage names support via EditableMapObject::GetLocalizedName(). + return jni::ToJavaString(env, gEditableMapObject.GetDefaultName()); } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_editor_Editor_nativeSetName(JNIEnv * env, jclass clazz, jstring name) +Java_com_mapswithme_maps_editor_Editor_nativeSetDefaultName(JNIEnv * env, jclass, jstring name) { - auto * feature = activeFeature(); - CHECK(feature, ("Feature is not editable!")); - auto names = feature->GetNames(); + StringUtf8Multilang names = gEditableMapObject.GetName(); + // TODO(yunikkk): add multilanguage names support. names.AddString(StringUtf8Multilang::kDefaultCode, jni::ToNativeString(env, name)); - feature->SetNames(names); + gEditableMapObject.SetName(names); +} + +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetStreet(JNIEnv * env, jclass) +{ + return jni::ToJavaString(env, gEditableMapObject.GetStreet()); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeSetStreet(JNIEnv * env, jclass, jstring street) +{ + gEditableMapObject.SetStreet(jni::ToNativeString(env, street)); +} + +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetHouseNumber(JNIEnv * env, jclass) +{ + return jni::ToJavaString(env, gEditableMapObject.GetHouseNumber()); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeSetHouseNumber(JNIEnv * env, jclass, jstring houseNumber) +{ + gEditableMapObject.SetHouseNumber(jni::ToNativeString(env, houseNumber)); } JNIEXPORT jobjectArray JNICALL Java_com_mapswithme_maps_editor_Editor_nativeGetNearbyStreets(JNIEnv * env, jclass clazz) { - auto const * feature = activeFeature(); - auto const & streets = feature ? g_framework->NativeFramework()->GetNearbyFeatureStreets(*feature) - : vector{}; + auto const & streets = gEditableMapObject.GetNearbyStreets(); int const size = streets.size(); jobjectArray jStreets = env->NewObjectArray(size, jni::GetStringClass(env), 0); - for (int i = 0; i < size; i++) + for (int i = 0; i < size; ++i) env->SetObjectArrayElement(jStreets, i, jni::TScopedLocalRef(env, jni::ToJavaString(env, streets[i])).get()); return jStreets; } +JNIEXPORT jboolean JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeHasWifi(JNIEnv *, jclass) +{ + // TODO(AlexZ): Support 3-state: yes, no, unknown. + return gEditableMapObject.GetMetadata().Get(feature::Metadata::FMD_INTERNET) == "wlan"; +} + + JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_editor_Editor_nativeHasSomethingToUpload(JNIEnv * env, jclass clazz) { @@ -123,4 +225,12 @@ Java_com_mapswithme_maps_editor_Editor_nativeClearLocalEdits(JNIEnv * env, jclas { Editor::Instance().ClearAllLocalEdits(); } + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeStartEdit(JNIEnv *, jclass) +{ + ::Framework * frm = g_framework->NativeFramework(); + place_page::Info const & info = g_framework->GetPlacePageInfo(); + CHECK(frm->GetEditableMapObject(info.GetID(), gEditableMapObject), ("Invalid feature in the place page.")); + } } // extern "C" diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index 353790a33c..35f4ed334a 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -188,5 +188,5 @@ public class Framework public static native MapObject nativeGetActiveMapObject(); @NonNull - public static native MapObject nativeActivateMapObject(double lat, double lon); + public static native MapObject nativeDeleteBookmarkFromMapObject(); } diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 998c5546b5..13dab9eb1b 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -42,6 +42,7 @@ import com.mapswithme.maps.downloader.MapManager; import com.mapswithme.maps.downloader.MigrationFragment; import com.mapswithme.maps.downloader.OnmapDownloader; import com.mapswithme.maps.editor.AuthFragment; +import com.mapswithme.maps.editor.Editor; import com.mapswithme.maps.editor.EditorActivity; import com.mapswithme.maps.editor.EditorHostFragment; import com.mapswithme.maps.location.LocationHelper; @@ -253,16 +254,19 @@ public class MwmActivity extends BaseMwmFragmentActivity SearchActivity.start(this, query); } - public void showEditor(MapObject point) + public void showEditor() { if (mIsFragmentContainer) { final Bundle args = new Bundle(); - args.putParcelable(EditorHostFragment.EXTRA_MAP_OBJECT, point); replaceFragment(EditorHostFragment.class, args, null); } else - EditorActivity.start(this, point); + { + // Initializes editable feature from currently active place page. + Editor.nativeStartEdit(); + EditorActivity.start(this); + } } private void shareMyLocation() @@ -1007,7 +1011,7 @@ public class MwmActivity extends BaseMwmFragmentActivity if (request == null) return; - request.setPointData(object.getLat(), object.getLon(), object.getName(), object.getSearchId()); + request.setPointData(object.getLat(), object.getLon(), object.getTitle(), object.getSearchId()); object.setTypeName(request.getCallerName(MwmApplication.get()).toString()); } diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarkListAdapter.java b/android/src/com/mapswithme/maps/bookmarks/BookmarkListAdapter.java index 75017b2ea9..d1f39f3b3f 100644 --- a/android/src/com/mapswithme/maps/bookmarks/BookmarkListAdapter.java +++ b/android/src/com/mapswithme/maps/bookmarks/BookmarkListAdapter.java @@ -163,7 +163,7 @@ public class BookmarkListAdapter extends BaseAdapter void setName(Bookmark bmk) { - name.setText(bmk.getName()); + name.setText(bmk.getTitle()); } void setName(Track trk) diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java b/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java index c276abe865..1645f77b11 100644 --- a/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java +++ b/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java @@ -123,7 +123,7 @@ public class BookmarksListFragment extends BaseMwmListFragment break; case BookmarkListAdapter.TYPE_BOOKMARK: - BottomSheetHelper.Builder bs = BottomSheetHelper.create(getActivity(), ((Bookmark) item).getName()) + BottomSheetHelper.Builder bs = BottomSheetHelper.create(getActivity(), ((Bookmark) item).getTitle()) .sheet(R.menu.menu_bookmarks) .listener(this); if (!ShareOption.SMS.isSupported(getActivity())) diff --git a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java index 1fbba6bb45..0791e07486 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/Bookmark.java @@ -24,7 +24,7 @@ public class Bookmark extends MapObject mCategoryId = categoryId; mBookmarkId = bookmarkId; - mName = name; + mTitle = name; mIcon = getIconInternal(); initXY(); } @@ -85,7 +85,7 @@ public class Bookmark extends MapObject } @Override - public String getTypeName() + public String getSubtitle() { // TODO get correct value return getCategory().getName(); @@ -116,10 +116,10 @@ public class Bookmark extends MapObject if (icon == null) icon = mIcon; - if (!name.equals(getName()) || icon != mIcon || !description.equals(getBookmarkDescription())) + if (!name.equals(getTitle()) || icon != mIcon || !description.equals(getBookmarkDescription())) { nativeSetBookmarkParams(mCategoryId, mBookmarkId, name, icon.getType(), description); - mName = name; + mTitle = name; } } diff --git a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java index 6bc1f3f099..b6afc82dd5 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java @@ -102,7 +102,9 @@ public enum BookmarkManager public native int nativeGetLastEditedCategory(); - public static native String nativeGenerateUniqueBookmarkName(String baseName); + public static native String nativeGenerateUniqueFileName(String baseName); public static native boolean nativeLoadKmzFile(String path); + + public static native String nativeFormatNewBookmarkName(); } diff --git a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java index 8f98ba9da6..dbea5122a2 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java @@ -14,6 +14,8 @@ import com.mapswithme.maps.BuildConfig; import com.mapswithme.maps.MwmApplication; import com.mapswithme.maps.R; +// TODO(yunikkk): Refactor. Displayed information is different from edited information, and it's better to +// separate them. Simple getters from jni place_page::Info and osm::EditableFeature should be enough. public class MapObject implements Parcelable { @Retention(RetentionPolicy.SOURCE) @@ -28,10 +30,10 @@ public class MapObject implements Parcelable @MapObjectType protected final int mMapObjectType; - protected String mName; + protected String mTitle; protected double mLat; protected double mLon; - protected String mTypeName; + protected String mSubtitle; protected String mStreet; protected String mHouseNumber; protected Metadata mMetadata; @@ -48,14 +50,14 @@ public class MapObject implements Parcelable public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName, String street, String house, Metadata metadata) { mMapObjectType = mapObjectType; - mName = name; + mTitle = name; mLat = lat; mLon = lon; - mTypeName = typeName; + mSubtitle = typeName; mStreet = street; mHouseNumber = house; mMetadata = metadata; - mIsDroppedPin = TextUtils.isEmpty(mName); + mIsDroppedPin = TextUtils.isEmpty(mTitle); } protected MapObject(Parcel source) @@ -76,12 +78,12 @@ public class MapObject implements Parcelable public void setDefaultIfEmpty() { - if (TextUtils.isEmpty(mName)) - mName = TextUtils.isEmpty(mTypeName) ? MwmApplication.get().getString(R.string.dropped_pin) - : mTypeName; + if (TextUtils.isEmpty(mTitle)) + mTitle = TextUtils.isEmpty(mSubtitle) ? MwmApplication.get().getString(R.string.dropped_pin) + : mSubtitle; - if (TextUtils.isEmpty(mTypeName)) - mTypeName = MwmApplication.get().getString(R.string.placepage_unsorted); + if (TextUtils.isEmpty(mSubtitle)) + mSubtitle = MwmApplication.get().getString(R.string.placepage_unsorted); } /** @@ -103,8 +105,8 @@ public class MapObject implements Parcelable return Double.doubleToLongBits(mLon) == Double.doubleToLongBits(other.mLon) && Double.doubleToLongBits(mLat) == Double.doubleToLongBits(other.mLat) && - TextUtils.equals(mName, other.mName) && - TextUtils.equals(mTypeName, other.mTypeName); + TextUtils.equals(mTitle, other.mTitle) && + TextUtils.equals(mSubtitle, other.mSubtitle); } public static boolean same(MapObject one, MapObject another) @@ -118,13 +120,13 @@ public class MapObject implements Parcelable public double getScale() { return 0; } - public String getName() { return mName; } + public String getTitle() { return mTitle; } public double getLat() { return mLat; } public double getLon() { return mLon; } - public String getTypeName() { return mTypeName; } + public String getSubtitle() { return mSubtitle; } public boolean getIsDroppedPin() { @@ -142,16 +144,15 @@ public class MapObject implements Parcelable * @return properly formatted and translated cuisine string. */ @NonNull - public String getFormattedCuisine() + static public String formatCuisine(String rawOsmCuisineValue) { - final String rawCuisines = mMetadata.getMetadata(Metadata.MetadataType.FMD_CUISINE); - if (TextUtils.isEmpty(rawCuisines)) + if (TextUtils.isEmpty(rawOsmCuisineValue)) return ""; final StringBuilder result = new StringBuilder(); // search translations for each cuisine final Resources resources = MwmApplication.get().getResources(); - for (String rawCuisine : Metadata.splitCuisines(rawCuisines)) + for (String rawCuisine : Metadata.splitCuisines(rawOsmCuisineValue)) { int resId = resources.getIdentifier(Metadata.osmCuisineToStringName(Metadata.normalizeCuisine(rawCuisine)), "string", BuildConfig.APPLICATION_ID); if (result.length() > 0) @@ -185,7 +186,7 @@ public class MapObject implements Parcelable public void setName(String name) { - mName = name; + mTitle = name; } public void setHouseNumber(String houseNumber) @@ -205,7 +206,7 @@ public class MapObject implements Parcelable public void setTypeName(String typeName) { - mTypeName = typeName; + mSubtitle = typeName; } public void addMetadata(Metadata.MetadataType type, String value) @@ -254,10 +255,10 @@ public class MapObject implements Parcelable { dest.writeInt(mMapObjectType); // write map object type twice - first int is used to distinguish created object (MapObject or Bookmark) dest.writeInt(mMapObjectType); - dest.writeString(mName); + dest.writeString(mTitle); dest.writeDouble(mLat); dest.writeDouble(mLon); - dest.writeString(mTypeName); + dest.writeString(mSubtitle); dest.writeString(mStreet); dest.writeString(mHouseNumber); dest.writeParcelable(mMetadata, 0); diff --git a/android/src/com/mapswithme/maps/editor/Editor.java b/android/src/com/mapswithme/maps/editor/Editor.java index 328a78b81b..bb5987ccc8 100644 --- a/android/src/com/mapswithme/maps/editor/Editor.java +++ b/android/src/com/mapswithme/maps/editor/Editor.java @@ -10,8 +10,7 @@ import com.mapswithme.maps.bookmarks.data.Metadata; /** - * Edits active(selected on the map) MapObjects(aka UserMark in core). - * All the methods apply to currently active objects. + * Edits active(selected on the map) feature, which is represented as osm::EditableFeature in the core. */ public final class Editor { @@ -32,32 +31,27 @@ public final class Editor MwmApplication.backgroundTracker().addListener(sOsmUploader); } - public static boolean hasEditableAttributes() - { - return Editor.nativeGetEditableMetadata().length != 0 || - Editor.nativeIsAddressEditable() || - Editor.nativeIsNameEditable(); - } - @WorkerThread public static void uploadChanges() { - if (nativeHasSomethingToUpload() && - OsmOAuth.isAuthorized()) + if (nativeHasSomethingToUpload() && OsmOAuth.isAuthorized()) nativeUploadChanges(OsmOAuth.getAuthToken(), OsmOAuth.getAuthSecret()); } + public static native boolean nativeIsFeatureEditable(); @NonNull - public static native int[] nativeGetEditableMetadata(); + public static native int[] nativeGetEditableFields(); + public static String getMetadata(Metadata.MetadataType type) + { + return nativeGetMetadata(type.toInt()); + } public static void setMetadata(Metadata.MetadataType type, String value) { nativeSetMetadata(type.toInt(), value); } - - public static native void nativeSetMetadata(int type, String value); - - public static native void nativeEditFeature(String street, String houseNumber); + private static native String nativeGetMetadata(int type); + private static native void nativeSetMetadata(int type, String value); public static native boolean nativeIsAddressEditable(); @@ -66,17 +60,28 @@ public final class Editor @NonNull public static native String[] nativeGetNearbyStreets(); - public static native void nativeSetName(String name); + // TODO(yunikkk): add get/set name in specific language. + // To do that correctly, UI should query available languages, their translations and codes from + // osm::EditableFeature. And pass these codes back in setter together with edited name. + public static native String nativeGetDefaultName(); + public static native void nativeSetDefaultName(String name); + public static native String nativeGetStreet(); + public static native void nativeSetStreet(String street); + public static native String nativeGetHouseNumber(); + public static native void nativeSetHouseNumber(String houseNumber); + + // TODO(AlexZ): Support 3-state: Yes, No, Unknown. + public static native boolean nativeHasWifi(); + // Generic methods. public static native boolean nativeHasSomethingToUpload(); - @WorkerThread private static native void nativeUploadChanges(String token, String secret); - /** * @return array [total edits count, uploaded edits count, last upload timestamp] */ public static native long[] nativeGetStats(); - public static native void nativeClearLocalEdits(); + public static native void nativeStartEdit(); + public static native boolean nativeSaveEditedFeature(); } diff --git a/android/src/com/mapswithme/maps/editor/EditorActivity.java b/android/src/com/mapswithme/maps/editor/EditorActivity.java index cdd4d81bc6..a57a4a46a8 100644 --- a/android/src/com/mapswithme/maps/editor/EditorActivity.java +++ b/android/src/com/mapswithme/maps/editor/EditorActivity.java @@ -16,10 +16,9 @@ public class EditorActivity extends BaseMwmFragmentActivity return EditorHostFragment.class; } - public static void start(@NonNull Activity activity, @NonNull MapObject point) + public static void start(@NonNull Activity activity) { final Intent intent = new Intent(activity, EditorActivity.class); - intent.putExtra(EditorHostFragment.EXTRA_MAP_OBJECT, point); activity.startActivity(intent); } } diff --git a/android/src/com/mapswithme/maps/editor/EditorFragment.java b/android/src/com/mapswithme/maps/editor/EditorFragment.java index 2503eb33d9..94d2333f8c 100644 --- a/android/src/com/mapswithme/maps/editor/EditorFragment.java +++ b/android/src/com/mapswithme/maps/editor/EditorFragment.java @@ -20,8 +20,6 @@ import com.mapswithme.util.UiUtils; public class EditorFragment extends BaseMwmFragment implements View.OnClickListener { - private MapObject mEditedPoi; - private View mNameBlock; private View mAddressBlock; private View mMetadataBlock; @@ -62,19 +60,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe initViews(view); - mEditedPoi = getArguments().getParcelable(EditorHostFragment.EXTRA_MAP_OBJECT); - if (mEditedPoi == null) - throw new IllegalStateException("Valid MapObject should be passed to edit it."); - mEtName.setText(mEditedPoi.getName()); - // TODO read names - // mTvLocalizedNames.setText(); - mTvStreet.setText(mEditedPoi.getStreet()); - mEtHouseNumber.setText(mEditedPoi.getHouseNumber()); - mEtPhone.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER)); - mEtWebsite.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_WEBSITE)); - mEtEmail.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_EMAIL)); - mTvCuisine.setText(mEditedPoi.getFormattedCuisine()); - mSwWifi.setChecked(!TextUtils.isEmpty(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_INTERNET))); + // TODO(yunikkk): Add multilanguages support. + mEtName.setText(Editor.nativeGetDefaultName()); + mTvStreet.setText(Editor.nativeGetStreet()); + mEtHouseNumber.setText(Editor.nativeGetHouseNumber()); + mEtPhone.setText(Editor.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER)); + mEtWebsite.setText(Editor.getMetadata(Metadata.MetadataType.FMD_WEBSITE)); + mEtEmail.setText(Editor.getMetadata(Metadata.MetadataType.FMD_EMAIL)); + // TODO(AlexZ): Localize cuisines in the core. + mTvCuisine.setText(MapObject.formatCuisine(Editor.getMetadata(Metadata.MetadataType.FMD_CUISINE))); + mSwWifi.setChecked(Editor.nativeHasWifi()); refreshOpeningTime(); refreshEditableFields(); @@ -118,12 +113,12 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe public String getWifi() { - return mSwWifi.isChecked() ? "Yes" : ""; + return mSwWifi.isChecked() ? "wlan" : ""; } public String getOpeningHours() { - return mEditedPoi.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); + return Editor.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); } public Metadata getMetadata() @@ -143,7 +138,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe UiUtils.showIf(Editor.nativeIsNameEditable(), mNameBlock); UiUtils.showIf(Editor.nativeIsAddressEditable(), mAddressBlock); - final int[] editableMeta = Editor.nativeGetEditableMetadata(); + final int[] editableMeta = Editor.nativeGetEditableFields(); if (editableMeta.length == 0) { UiUtils.hide(mMetadataBlock); @@ -189,7 +184,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe private void refreshOpeningTime() { - final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS)); + final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(Editor.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS)); if (timetables == null) { UiUtils.show(mEmptyOpeningHours); diff --git a/android/src/com/mapswithme/maps/editor/EditorHostFragment.java b/android/src/com/mapswithme/maps/editor/EditorHostFragment.java index 1fb9fc65c6..1eb61ae760 100644 --- a/android/src/com/mapswithme/maps/editor/EditorHostFragment.java +++ b/android/src/com/mapswithme/maps/editor/EditorHostFragment.java @@ -10,7 +10,7 @@ import android.view.ViewGroup; import com.mapswithme.maps.R; import com.mapswithme.maps.base.BaseMwmToolbarFragment; import com.mapswithme.maps.base.OnBackPressListener; -import com.mapswithme.maps.bookmarks.data.MapObject; +// TODO(yunikkk): why is feature metadata in bookmarks? How are they related to each other? import com.mapswithme.maps.bookmarks.data.Metadata; import com.mapswithme.util.Utils; @@ -18,8 +18,6 @@ import com.mapswithme.util.Utils; public class EditorHostFragment extends BaseMwmToolbarFragment implements OnBackPressListener, View.OnClickListener { - public static final String EXTRA_MAP_OBJECT = "MapObject"; - enum Mode { MAP_OBJECT, @@ -29,8 +27,6 @@ public class EditorHostFragment extends BaseMwmToolbarFragment } private Mode mMode; - private MapObject mEditedObject; - @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) @@ -42,8 +38,6 @@ public class EditorHostFragment extends BaseMwmToolbarFragment public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - getArguments().setClassLoader(MapObject.class.getClassLoader()); - mEditedObject = getArguments().getParcelable(EditorHostFragment.EXTRA_MAP_OBJECT); editMapObject(); mToolbarController.findViewById(R.id.save).setOnClickListener(this); mToolbarController.getToolbar().setNavigationOnClickListener(new View.OnClickListener() { @@ -75,17 +69,14 @@ public class EditorHostFragment extends BaseMwmToolbarFragment public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - saveEditedPoi(); - outState.putParcelable(EXTRA_MAP_OBJECT, mEditedObject); + temporaryStoreEdits(); } protected void editMapObject() { mMode = Mode.MAP_OBJECT; mToolbarController.setTitle(R.string.edit_place); - final Bundle args = new Bundle(); - args.putParcelable(EXTRA_MAP_OBJECT, mEditedObject); - final Fragment editorFragment = Fragment.instantiate(getActivity(), EditorFragment.class.getName(), args); + final Fragment editorFragment = Fragment.instantiate(getActivity(), EditorFragment.class.getName()); getChildFragmentManager().beginTransaction() .replace(R.id.fragment_container, editorFragment, EditorFragment.class.getName()) .commit(); @@ -93,11 +84,11 @@ public class EditorHostFragment extends BaseMwmToolbarFragment protected void editTimetable() { - saveEditedPoi(); + temporaryStoreEdits(); mMode = Mode.OPENING_HOURS; mToolbarController.setTitle(R.string.editor_time_title); final Bundle args = new Bundle(); - args.putString(TimetableFragment.EXTRA_TIME, mEditedObject.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS)); + args.putString(TimetableFragment.EXTRA_TIME, Editor.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS)); final Fragment editorFragment = Fragment.instantiate(getActivity(), TimetableFragment.class.getName(), args); getChildFragmentManager().beginTransaction() .replace(R.id.fragment_container, editorFragment, TimetableFragment.class.getName()) @@ -106,11 +97,11 @@ public class EditorHostFragment extends BaseMwmToolbarFragment protected void editStreet() { - saveEditedPoi(); + temporaryStoreEdits(); mMode = Mode.STREET; mToolbarController.setTitle(R.string.choose_street); final Bundle args = new Bundle(); - args.putString(StreetFragment.EXTRA_CURRENT_STREET, mEditedObject.getStreet()); + args.putString(StreetFragment.EXTRA_CURRENT_STREET, Editor.nativeGetStreet()); final Fragment streetFragment = Fragment.instantiate(getActivity(), StreetFragment.class.getName(), args); getChildFragmentManager().beginTransaction() .replace(R.id.fragment_container, streetFragment, StreetFragment.class.getName()) @@ -119,29 +110,29 @@ public class EditorHostFragment extends BaseMwmToolbarFragment protected void editCuisine() { - saveEditedPoi(); + temporaryStoreEdits(); mMode = Mode.CUISINE; mToolbarController.setTitle(R.string.select_cuisine); final Bundle args = new Bundle(); - args.putString(CuisineFragment.EXTRA_CURRENT_CUISINE, mEditedObject.getMetadata(Metadata.MetadataType.FMD_CUISINE)); + args.putString(CuisineFragment.EXTRA_CURRENT_CUISINE, Editor.getMetadata(Metadata.MetadataType.FMD_CUISINE)); final Fragment cuisineFragment = Fragment.instantiate(getActivity(), CuisineFragment.class.getName(), args); getChildFragmentManager().beginTransaction() .replace(R.id.fragment_container, cuisineFragment, CuisineFragment.class.getName()) .commit(); } - protected void saveEditedPoi() + protected void temporaryStoreEdits() { final EditorFragment editorFragment = (EditorFragment) getChildFragmentManager().findFragmentByTag(EditorFragment.class.getName()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER, editorFragment.getPhone()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_WEBSITE, editorFragment.getWebsite()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_EMAIL, editorFragment.getEmail()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_CUISINE, editorFragment.getCuisine()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_INTERNET, editorFragment.getWifi()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_OPEN_HOURS, editorFragment.getOpeningHours()); - mEditedObject.setName(editorFragment.getName()); - mEditedObject.setStreet(editorFragment.getStreet()); - mEditedObject.setHouseNumber(editorFragment.getHouseNumber()); + Editor.setMetadata(Metadata.MetadataType.FMD_OPEN_HOURS, editorFragment.getOpeningHours()); + Editor.setMetadata(Metadata.MetadataType.FMD_CUISINE, editorFragment.getCuisine()); + Editor.setMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER, editorFragment.getPhone()); + Editor.setMetadata(Metadata.MetadataType.FMD_WEBSITE, editorFragment.getWebsite()); + Editor.setMetadata(Metadata.MetadataType.FMD_EMAIL, editorFragment.getEmail()); + Editor.setMetadata(Metadata.MetadataType.FMD_INTERNET, editorFragment.getWifi()); + Editor.nativeSetDefaultName(editorFragment.getName()); + Editor.nativeSetHouseNumber(editorFragment.getHouseNumber()); + Editor.nativeSetStreet(editorFragment.getStreet()); } @Override @@ -153,17 +144,17 @@ public class EditorHostFragment extends BaseMwmToolbarFragment { case OPENING_HOURS: final TimetableFragment fragment = (TimetableFragment) getChildFragmentManager().findFragmentByTag(TimetableFragment.class.getName()); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_OPEN_HOURS, fragment.getTimetable()); + Editor.setMetadata(Metadata.MetadataType.FMD_OPEN_HOURS, fragment.getTimetable()); editMapObject(); break; case STREET: final String street = ((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())).getStreet(); - mEditedObject.setStreet(street); + Editor.nativeSetStreet(street); editMapObject(); break; case CUISINE: String cuisine = ((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName())).getCuisine(); - mEditedObject.addMetadata(Metadata.MetadataType.FMD_CUISINE, cuisine); + Editor.setMetadata(Metadata.MetadataType.FMD_CUISINE, cuisine); editMapObject(); break; case MAP_OBJECT: @@ -171,15 +162,23 @@ public class EditorHostFragment extends BaseMwmToolbarFragment Editor.setMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER, editorFragment.getPhone()); Editor.setMetadata(Metadata.MetadataType.FMD_WEBSITE, editorFragment.getWebsite()); Editor.setMetadata(Metadata.MetadataType.FMD_EMAIL, editorFragment.getEmail()); - Editor.setMetadata(Metadata.MetadataType.FMD_CUISINE, editorFragment.getCuisine()); Editor.setMetadata(Metadata.MetadataType.FMD_INTERNET, editorFragment.getWifi()); - Editor.setMetadata(Metadata.MetadataType.FMD_OPEN_HOURS, editorFragment.getOpeningHours()); - Editor.nativeSetName(editorFragment.getName()); - Editor.nativeEditFeature(editorFragment.getStreet(), editorFragment.getHouseNumber()); - if (OsmOAuth.isAuthorized()) - Utils.navigateToParent(getActivity()); + Editor.nativeSetDefaultName(editorFragment.getName()); + // Street, cuisine and opening hours are saved in separate cases. + Editor.nativeSetHouseNumber(editorFragment.getHouseNumber()); + if (Editor.nativeSaveEditedFeature()) + { + if (OsmOAuth.isAuthorized()) + Utils.navigateToParent(getActivity()); + else + // TODO(yunikkk): auth should be displayed only once, we should remember the time it was displayed. + // And if there is no connection, no auth should be displayed at all. + showAuthorization(); + } else - showAuthorization(); + { + // TODO(yunikkk): Show error dialog that changes can't be saved (for example, there is no free space). + } break; } } diff --git a/android/src/com/mapswithme/maps/routing/SlotFrame.java b/android/src/com/mapswithme/maps/routing/SlotFrame.java index 76848048f7..1d621c6c84 100644 --- a/android/src/com/mapswithme/maps/routing/SlotFrame.java +++ b/android/src/com/mapswithme/maps/routing/SlotFrame.java @@ -99,7 +99,7 @@ public class SlotFrame extends LinearLayout if (MapObject.isOfType(MapObject.MY_POSITION, mMapObject)) mText.setText(R.string.p2p_your_location); else - mText.setText(mMapObject.getName()); + mText.setText(mMapObject.getTitle()); mText.setTextColor(mTextColor); } diff --git a/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java b/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java index c1af396b12..479f9fb946 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java +++ b/android/src/com/mapswithme/maps/widget/placepage/DirectionFragment.java @@ -84,8 +84,8 @@ public class DirectionFragment extends BaseMwmDialogFragment implements Location { if (mMapObject != null && isResumed()) { - mTvTitle.setText(mMapObject.getName()); - mTvSubtitle.setText(mMapObject.getTypeName()); + mTvTitle.setText(mMapObject.getTitle()); + mTvSubtitle.setText(mMapObject.getSubtitle()); } } diff --git a/android/src/com/mapswithme/maps/widget/placepage/EditBookmarkFragment.java b/android/src/com/mapswithme/maps/widget/placepage/EditBookmarkFragment.java index b1d01def43..7c57cd07f7 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/EditBookmarkFragment.java +++ b/android/src/com/mapswithme/maps/widget/placepage/EditBookmarkFragment.java @@ -140,7 +140,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. if (!TextUtils.equals(from, to)) Statistics.INSTANCE.trackColorChanged(from, to); - mBookmark.setParams(mBookmark.getName(), newIcon, mBookmark.getBookmarkDescription()); + mBookmark.setParams(mBookmark.getTitle(), newIcon, mBookmark.getBookmarkDescription()); mBookmark = BookmarkManager.INSTANCE.getBookmark(mBookmark.getCategoryId(), mBookmark.getBookmarkId()); refreshColorMarker(); } @@ -156,7 +156,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. private void refreshBookmark() { - mEtName.setText(mBookmark.getName()); + mEtName.setText(mBookmark.getTitle()); mEtName.selectAll(); InputUtils.showKeyboard(mEtName); diff --git a/android/src/com/mapswithme/maps/widget/placepage/EditDescriptionFragment.java b/android/src/com/mapswithme/maps/widget/placepage/EditDescriptionFragment.java index 265a8dad9e..6194ab77b1 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/EditDescriptionFragment.java +++ b/android/src/com/mapswithme/maps/widget/placepage/EditDescriptionFragment.java @@ -102,7 +102,7 @@ public class EditDescriptionFragment extends BaseMwmDialogFragment private void saveDescription() { - mBookmark.setParams(mBookmark.getName(), null, mEtDescription.getText().toString()); + mBookmark.setParams(mBookmark.getTitle(), null, mEtDescription.getText().toString()); if (mListener != null) { diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java index ae066a55e2..d5209b686a 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java +++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java @@ -415,11 +415,10 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene private void refreshPreview() { - mTvTitle.setText(mMapObject.getName()); + mTvTitle.setText(mMapObject.getTitle()); if (mToolbar != null) - mToolbar.setTitle(mMapObject.getName()); - String subtitle = mMapObject.getFormattedCuisine().isEmpty() ? mMapObject.getTypeName() - : mMapObject.getTypeName() + ", " + mMapObject.getFormattedCuisine(); + mToolbar.setTitle(mMapObject.getTitle()); + String subtitle = mMapObject.getSubtitle(); mTvSubtitle.setText(subtitle); mAvDirection.setVisibility(View.GONE); } @@ -432,7 +431,8 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER), mPhone, mTvPhone); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_EMAIL), mEmail, mTvEmail); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_OPERATOR), mOperator, mTvOperator); - refreshMetadataOrHide(mMapObject.getFormattedCuisine(), mCuisine, mTvCuisine); + // TODO(AlexZ): Localize cuisines in the core. + refreshMetadataOrHide(MapObject.formatCuisine(mMapObject.getMetadata(Metadata.MetadataType.FMD_CUISINE)), mCuisine, mTvCuisine); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA), mWiki, null); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_INTERNET), mWifi, null); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_FLATS), mEntrance, mTvEntrance); @@ -440,7 +440,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene refreshMetadataStars(mMapObject.getMetadata(Metadata.MetadataType.FMD_STARS)); UiUtils.setTextAndHideIfEmpty(mTvElevation, mMapObject.getMetadata(Metadata.MetadataType.FMD_ELE)); - if (mMapObject == null || !Editor.hasEditableAttributes()) + if (mMapObject == null || !Editor.nativeIsFeatureEditable()) { UiUtils.hide(mEditor); } @@ -504,7 +504,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene private void showBookmarkDetails() { final Bookmark bookmark = (Bookmark) mMapObject; - mEtBookmarkName.setText(bookmark.getName()); + mEtBookmarkName.setText(bookmark.getTitle()); mTvBookmarkGroup.setText(bookmark.getCategoryName()); mIvColor.setImageResource(bookmark.getIcon().getSelectedResId()); mIvBookmark.setImageResource(R.drawable.ic_bookmarks_on); @@ -694,7 +694,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene private void showEditor() { - ((MwmActivity) getContext()).showEditor(mMapObject); + ((MwmActivity) getContext()).showEditor(); } @Override @@ -725,7 +725,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene { final ParsedMwmRequest request = ParsedMwmRequest.getCurrentRequest(); if (ParsedMwmRequest.isPickPointMode()) - request.setPointData(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getName(), ""); + request.setPointData(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getTitle(), ""); request.sendResponseAndFinish(activity, true); } else @@ -804,16 +804,17 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene { if (mMapObject == null) return; + // TODO(yunikkk): this can be done by querying place_page::Info::IsBookmark(), without passing any + // specific Bookmark object instance. if (MapObject.isOfType(MapObject.BOOKMARK, mMapObject)) { final Bookmark currentBookmark = (Bookmark) mMapObject; - setMapObject(Framework.nativeActivateMapObject(mMapObject.getLat(), mMapObject.getLon()), false); + setMapObject(Framework.nativeDeleteBookmarkFromMapObject(), false); setState(State.DETAILS); - BookmarkManager.INSTANCE.deleteBookmark(currentBookmark); } else { - setMapObject(BookmarkManager.INSTANCE.addNewBookmark(mMapObject.getName(), mMapObject.getLat(), mMapObject.getLon()), false); + setMapObject(BookmarkManager.INSTANCE.addNewBookmark(BookmarkManager.nativeFormatNewBookmarkName(), mMapObject.getLat(), mMapObject.getLon()), false); // FIXME this hack is necessary to get correct views height in animation controller. remove after further investigation. post(new Runnable() { @@ -857,7 +858,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene if (!TextUtils.equals(from, to)) Statistics.INSTANCE.trackColorChanged(from, to); - bmk.setParams(bmk.getName(), newIcon, bmk.getBookmarkDescription()); + bmk.setParams(bmk.getTitle(), newIcon, bmk.getBookmarkDescription()); bmk = BookmarkManager.INSTANCE.getBookmark(bmk.getCategoryId(), bmk.getBookmarkId()); setMapObject(bmk, false); } diff --git a/android/src/com/mapswithme/util/sharing/MapObjectShareable.java b/android/src/com/mapswithme/util/sharing/MapObjectShareable.java index a50adb3641..94b597492b 100644 --- a/android/src/com/mapswithme/util/sharing/MapObjectShareable.java +++ b/android/src/com/mapswithme/util/sharing/MapObjectShareable.java @@ -17,8 +17,8 @@ public class MapObjectShareable extends BaseShareable mMapObject = mapObject; final Activity activity = getActivity(); - final String ge0Url = Framework.nativeGetGe0Url(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), mMapObject.getName()); - final String httpUrl = Framework.getHttpGe0Url(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), mMapObject.getName()); + final String ge0Url = Framework.nativeGetGe0Url(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), mMapObject.getTitle()); + final String httpUrl = Framework.getHttpGe0Url(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), mMapObject.getTitle()); final String address = Framework.nativeGetNameAndAddress(mMapObject.getLat(), mMapObject.getLon()); final int textId = MapObject.isOfType(MapObject.MY_POSITION, mMapObject) ? R.string.my_position_share_email : R.string.bookmark_share_email;