diff --git a/android/jni/com/mapswithme/maps/editor/Editor.cpp b/android/jni/com/mapswithme/maps/editor/Editor.cpp index 5b46bfa5f7..d20a134331 100644 --- a/android/jni/com/mapswithme/maps/editor/Editor.cpp +++ b/android/jni/com/mapswithme/maps/editor/Editor.cpp @@ -6,6 +6,7 @@ #include "base/assert.hpp" #include "base/logging.hpp" #include "base/string_utils.hpp" +#include "indexer/cuisines.hpp" #include "indexer/editable_map_object.hpp" #include "indexer/osm_editor.hpp" @@ -16,6 +17,7 @@ namespace { +using TCuisine = pair; osm::EditableMapObject g_editableMapObject; jclass g_featureCategoryClazz; @@ -25,6 +27,19 @@ jobject ToJavaFeatureCategory(JNIEnv * env, osm::Category const & category) { return env->NewObject(g_featureCategoryClazz, g_featureCtor, category.m_type, jni::TScopedLocalRef(env, jni::ToJavaString(env, category.m_name)).get()); } + +jobjectArray ToJavaArray(JNIEnv * env, vector const & src) +{ + int const size = src.size(); + auto jArray = env->NewObjectArray(size, jni::GetStringClass(env), 0); + for (size_t i = 0; i < size; i++) + { + jni::TScopedLocalRef jItem(env, jni::ToJavaString(env, src[i])); + env->SetObjectArrayElement(jArray, i, jItem.get()); + } + + return jArray; +} } // namespace extern "C" @@ -54,8 +69,6 @@ Java_com_mapswithme_maps_editor_Editor_nativeSetMetadata(JNIEnv * env, jclass cl using feature::Metadata; switch (type) { - // TODO(yunikkk): Pass cuisines in a separate setter via vector of osm untranslated keys (SetCuisines()). - case Metadata::FMD_CUISINE: g_editableMapObject.SetRawOSMCuisines(v); break; case Metadata::FMD_OPEN_HOURS: g_editableMapObject.SetOpeningHours(v); break; case Metadata::FMD_PHONE_NUMBER: g_editableMapObject.SetPhone(v); break; case Metadata::FMD_FAX_NUMBER: g_editableMapObject.SetFax(v); break; @@ -274,4 +287,46 @@ Java_com_mapswithme_maps_editor_Editor_nativeGetNewFeatureCategories(JNIEnv * en return jCategories; } + +JNIEXPORT jobjectArray JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetCuisines(JNIEnv * env, jclass clazz) +{ + osm::TAllCuisines const & cuisines = osm::Cuisines::Instance().AllSupportedCuisines(); + vector keys(cuisines.size()); + for (size_t i = 0; i < cuisines.size(); i++) + keys[i] = cuisines[i].first; + return ToJavaArray(env, keys); +} + +JNIEXPORT jobjectArray JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetSelectedCuisines(JNIEnv * env, jclass clazz) +{ + return ToJavaArray(env, g_editableMapObject.GetCuisines()); +} + +JNIEXPORT jobjectArray JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetCuisinesTranslations(JNIEnv * env, jclass clazz) +{ + osm::TAllCuisines const & cuisines = osm::Cuisines::Instance().AllSupportedCuisines(); + vector keys(cuisines.size()); + for (size_t i = 0; i < cuisines.size(); i++) + keys[i] = cuisines[i].second; + return ToJavaArray(env, keys); +} + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeSetSelectedCuisines(JNIEnv * env, jclass clazz, jobjectArray jCuisines) +{ + int const length = env->GetArrayLength(jCuisines); + vector cuisines(length); + for (int i = 0; i < length; i++) + cuisines[i] = jni::ToNativeString(env, (jstring) env->GetObjectArrayElement(jCuisines, i)); + g_editableMapObject.SetCuisines(cuisines); +} + +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_editor_Editor_nativeGetFormattedCuisine(JNIEnv * env, jclass clazz) +{ + return jni::ToJavaString(env, g_editableMapObject.FormatCuisines()); +} } // extern "C" diff --git a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java index 29e996bb72..8d9caae8a1 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java @@ -1,6 +1,5 @@ package com.mapswithme.maps.bookmarks.data; -import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.IntDef; @@ -10,9 +9,6 @@ import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import com.mapswithme.maps.BuildConfig; -import com.mapswithme.maps.MwmApplication; - // 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 @@ -208,27 +204,4 @@ public class MapObject implements Parcelable return new MapObject[size]; } }; - - /** - * @return properly formatted and translated cuisine string. - */ - @NonNull - static public String formatCuisine(String rawOsmCuisineValue) - { - 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(rawOsmCuisineValue)) - { - int resId = resources.getIdentifier(Metadata.osmCuisineToStringName(Metadata.normalizeCuisine(rawCuisine)), "string", BuildConfig.APPLICATION_ID); - if (result.length() > 0) - result.append(", "); - result.append(resId == 0 ? rawCuisine : resources.getString(resId)); - } - - return result.toString(); - } } diff --git a/android/src/com/mapswithme/maps/bookmarks/data/Metadata.java b/android/src/com/mapswithme/maps/bookmarks/data/Metadata.java index a9d535d9cd..8410fa2baa 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/Metadata.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/Metadata.java @@ -61,58 +61,8 @@ public class Metadata implements Parcelable } } - private static final String CUISINE_TRANSLATION_PREFIX = "cuisine_"; - private Map mMetadataMap = new HashMap<>(); - public static String osmCuisineToStringName(String cuisineKey) - { - return CUISINE_TRANSLATION_PREFIX + cuisineKey; - } - - public static String stringNameToOsmCuisine(String cuisineTranslation) - { - return cuisineTranslation.replace(CUISINE_TRANSLATION_PREFIX, ""); - } - - public static boolean isCuisineString(String cuisineTranslation) - { - return cuisineTranslation.startsWith(CUISINE_TRANSLATION_PREFIX); - } - - /** - * Cuisines translations can contain unsupported symbols, - * replace them with supported "_"( so ', ' and ' ' are replaced with underlines) - */ - public static String normalizeCuisine(String cuisineRaw) - { - return cuisineRaw.replace(", ", "_").replace(' ', '_').toLowerCase(); - } - - /** - * Splits cuisine from osm format. - */ - public static String[] splitCuisines(String cuisines) - { - return cuisines.split(";"); - } - - /** - * Combines cuisines to osm format. - */ - public static String combineCuisines(@NonNull String[] cuisines) - { - final StringBuilder builder = new StringBuilder(); - for (String cuisine : cuisines) - { - if (builder.length() > 0) - builder.append(";"); - builder.append(cuisine); - } - - return builder.toString(); - } - /** * Adds metadata with type code and value. Returns false if metaType is wrong or unknown * diff --git a/android/src/com/mapswithme/maps/editor/CuisineAdapter.java b/android/src/com/mapswithme/maps/editor/CuisineAdapter.java index e4c0badd48..8d25d43282 100644 --- a/android/src/com/mapswithme/maps/editor/CuisineAdapter.java +++ b/android/src/com/mapswithme/maps/editor/CuisineAdapter.java @@ -1,6 +1,5 @@ package com.mapswithme.maps.editor; -import android.content.res.Resources; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -10,80 +9,47 @@ import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.TextView; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; -import com.mapswithme.maps.MwmApplication; import com.mapswithme.maps.R; -import com.mapswithme.maps.bookmarks.data.Metadata; public class CuisineAdapter extends RecyclerView.Adapter { private static class Item implements Comparable { - String translatedCuisine; - String cuisineStringName; + String cuisineTranslated; + String cuisineKey; boolean selected; - public Item(String cuisine, String cuisineKey, boolean selected) + public Item(String key, String translation, boolean selected) { - this.translatedCuisine = cuisine; - this.cuisineStringName = cuisineKey; + this.cuisineKey = key; + this.cuisineTranslated = translation; this.selected = selected; } @Override public int compareTo(@NonNull Item another) { - return translatedCuisine.compareTo(another.translatedCuisine); + return cuisineTranslated.compareTo(another.cuisineTranslated); } } - private List mTranslatedItems; private List mItems; - public CuisineAdapter(@NonNull String cuisine) + public CuisineAdapter(@NonNull String[] selectedCuisines, @NonNull String[] cuisines, @NonNull String[] translations) { - initAllCuisinesFromStrings(); - String[] selectedCuisines = Metadata.splitCuisines(cuisine); + mItems = new ArrayList<>(cuisines.length); Arrays.sort(selectedCuisines); - mItems = new ArrayList<>(mTranslatedItems.size()); - for (Item item : mTranslatedItems) + for (int i = 0; i < cuisines.length; i++) { - final String cuisineString = item.translatedCuisine; - mItems.add(new Item(cuisineString, item.cuisineStringName, - Arrays.binarySearch(selectedCuisines, Metadata.stringNameToOsmCuisine(item.cuisineStringName)) >= 0)); + final String key = cuisines[i]; + mItems.add(new Item(key, translations[i], Arrays.binarySearch(selectedCuisines, key) >= 0)); } } - private void initAllCuisinesFromStrings() - { - if (mTranslatedItems != null) - return; - - mTranslatedItems = new ArrayList<>(); - final Resources resources = MwmApplication.get().getResources(); - for (Field stringField : R.string.class.getDeclaredFields()) - { - try - { - final String fieldName = stringField.getName(); - if (Metadata.isCuisineString(fieldName)) - { - int resId = stringField.getInt(stringField); - final String cuisine = resources.getString(resId); - mTranslatedItems.add(new Item(cuisine, fieldName, false)); - } - - } catch (IllegalAccessException ignored) { } - } - - Collections.sort(mTranslatedItems); - } - @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -99,21 +65,19 @@ public class CuisineAdapter extends RecyclerView.Adapter selectedList = new ArrayList<>(); for (Item item : mItems) { if (item.selected) - selectedList.add(Metadata.stringNameToOsmCuisine(item.cuisineStringName)); + selectedList.add(item.cuisineKey); } - String[] cuisines = new String[selectedList.size()]; - cuisines = selectedList.toArray(cuisines); - return Metadata.combineCuisines(cuisines); + return selectedList.toArray(new String[selectedList.size()]); } protected class ViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener @@ -139,7 +103,7 @@ public class CuisineAdapter extends RecyclerView.Adapter const & cuisine) m_metadata.Set(feature::Metadata::FMD_CUISINE, strings::JoinStrings(cuisine, ';')); } -void EditableMapObject::SetRawOSMCuisines(string const & cuisine) -{ - m_metadata.Set(feature::Metadata::FMD_CUISINE, cuisine); -} - void EditableMapObject::SetOpeningHours(string const & openingHours) { m_metadata.Set(feature::Metadata::FMD_OPEN_HOURS, openingHours); diff --git a/indexer/editable_map_object.hpp b/indexer/editable_map_object.hpp index 3331097e7c..3f4aaa2322 100644 --- a/indexer/editable_map_object.hpp +++ b/indexer/editable_map_object.hpp @@ -86,8 +86,6 @@ public: void SetBuildingLevels(string const & buildingLevels); /// @param[in] cuisine is a vector of osm cuisine ids. void SetCuisines(vector const & cuisine); - // TODO(yunikkk): Refactor out this method in jni, because it lacks possible validation. - void SetRawOSMCuisines(string const & cuisine); void SetOpeningHours(string const & openingHours); /// Special mark that it's a point feature, not area or line. diff --git a/indexer/map_object.hpp b/indexer/map_object.hpp index eeef2421c2..a97dae8b7c 100644 --- a/indexer/map_object.hpp +++ b/indexer/map_object.hpp @@ -72,9 +72,9 @@ public: string GetEmail() const; string GetWebsite() const; Internet GetInternet() const; - /// @returns translated cuisine(s). + /// @returns not localized cuisines keys. vector GetCuisines() const; - // @returns not localized cuisines keys. + /// @returns translated cuisine(s). vector GetLocalizedCuisines() const; /// @returns translated and formatted cuisines. string FormatCuisines() const;