diff --git a/OsmAnd/src/net/osmand/plus/CustomOsmandPlugin.java b/OsmAnd/src/net/osmand/plus/CustomOsmandPlugin.java index f0a9955903..be34408516 100644 --- a/OsmAnd/src/net/osmand/plus/CustomOsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/CustomOsmandPlugin.java @@ -1,6 +1,7 @@ package net.osmand.plus; import android.app.Activity; +import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -15,7 +16,6 @@ import net.osmand.map.ITileSource; import net.osmand.map.TileSourceManager; import net.osmand.map.WorldRegion; import net.osmand.plus.SettingsHelper.AvoidRoadsSettingsItem; -import net.osmand.plus.SettingsHelper.CustomRegion; import net.osmand.plus.SettingsHelper.MapSourcesSettingsItem; import net.osmand.plus.SettingsHelper.PluginSettingsItem; import net.osmand.plus.SettingsHelper.PoiUiFilterSettingsItem; @@ -66,7 +66,7 @@ public class CustomOsmandPlugin extends OsmandPlugin { private List rendererNames = new ArrayList<>(); private List routerNames = new ArrayList<>(); private List suggestedDownloadItems = new ArrayList<>(); - private List customRegions = new ArrayList<>(); + private List customRegions = new ArrayList<>(); public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException { super(app); @@ -76,6 +76,25 @@ public class CustomOsmandPlugin extends OsmandPlugin { loadResources(); } + @Override + public String getId() { + return pluginId; + } + + @Override + public String getName() { + return getLocalizedResFromMap(app, names, app.getString(R.string.custom_osmand_plugin)); + } + + @Override + public String getDescription() { + return getLocalizedResFromMap(app, descriptions, null); + } + + public String getResourceDirName() { + return resourceDirName; + } + @Override public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) { super.init(app, activity); @@ -89,6 +108,108 @@ public class CustomOsmandPlugin extends OsmandPlugin { return true; } + @Override + public void disable(OsmandApplication app) { + super.disable(app); + removePluginItems(null); + } + + public File getPluginDir() { + return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId); + } + + public File getPluginItemsFile() { + return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT); + } + + public File getPluginResDir() { + File pluginDir = getPluginDir(); + if (!Algorithms.isEmpty(resourceDirName)) { + return new File(pluginDir, resourceDirName); + } + return pluginDir; + } + + @Override + public List getRendererNames() { + return rendererNames; + } + + @Override + public List getRouterNames() { + return routerNames; + } + + private Drawable getIconForFile(String path, Map fileNames) { + for (Map.Entry entry : fileNames.entrySet()) { + String value = entry.getValue(); + if (value.startsWith("@")) { + value = value.substring(1); + } + if (path.endsWith(value)) { + return BitmapDrawable.createFromPath(path); + } + } + return null; + } + + @NonNull + @Override + public Drawable getLogoResource() { + return icon != null ? icon : super.getLogoResource(); + } + + @Override + public Drawable getAssetResourceImage() { + return image; + } + + @Override + public List getDownloadMaps() { + return customRegions; + } + + @Override + public List getSuggestedMaps() { + List suggestedMaps = new ArrayList<>(); + + DownloadIndexesThread downloadThread = app.getDownloadThread(); + if (!downloadThread.getIndexes().isDownloadedFromInternet && app.getSettings().isInternetConnectionAvailable()) { + downloadThread.runReloadIndexFiles(); + } + + boolean downloadIndexes = app.getSettings().isInternetConnectionAvailable() + && !downloadThread.getIndexes().isDownloadedFromInternet + && !downloadThread.getIndexes().downloadFromInternetFailed; + + if (!downloadIndexes) { + for (SuggestedDownloadItem item : suggestedDownloadItems) { + DownloadActivityType type = DownloadActivityType.getIndexType(item.scopeId); + if (type != null) { + List foundMaps = new ArrayList<>(); + String searchType = item.getSearchType(); + if ("latlon".equalsIgnoreCase(searchType)) { + LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation(); + foundMaps.addAll(getMapsForType(latLon, type)); + } else if ("worldregion".equalsIgnoreCase(searchType)) { + LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation(); + foundMaps.addAll(getMapsForType(latLon, type)); + } + if (!Algorithms.isEmpty(item.getNames())) { + foundMaps.addAll(getMapsForType(item.getNames(), type, item.getLimit())); + } + suggestedMaps.addAll(foundMaps); + } + } + } + + return suggestedMaps; + } + + public void setResourceDirName(String resourceDirName) { + this.resourceDirName = resourceDirName; + } + private void addPluginItemsFromFile(final File file) { app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() { @Override @@ -188,129 +309,23 @@ public class CustomOsmandPlugin extends OsmandPlugin { }); } - @Override - public void disable(OsmandApplication app) { - super.disable(app); - removePluginItems(null); - } - - public File getPluginDir() { - return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId); - } - - public File getPluginItemsFile() { - return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT); - } - - public File getPluginResDir() { - File pluginDir = getPluginDir(); - if (!Algorithms.isEmpty(resourceDirName)) { - return new File(pluginDir, resourceDirName); - } - return pluginDir; - } - - @Override - public String getId() { - return pluginId; - } - - @Override - public String getName() { - Configuration config = app.getResources().getConfiguration(); - String lang = config.locale.getLanguage(); - String name = names.get(lang); - if (Algorithms.isEmpty(name)) { - name = names.get(""); - } - if (Algorithms.isEmpty(name)) { - name = app.getString(R.string.custom_osmand_plugin); - } - return name; - } - - @Override - public String getDescription() { - Configuration config = app.getResources().getConfiguration(); - String lang = config.locale.getLanguage(); - String description = descriptions.get(lang); - if (Algorithms.isEmpty(description)) { - description = descriptions.get(""); - } - return description; - } - - public String getResourceDirName() { - return resourceDirName; - } - - public void setResourceDirName(String resourceDirName) { - this.resourceDirName = resourceDirName; - } - public void readAdditionalDataFromJson(JSONObject json) throws JSONException { - JSONObject iconJson = json.has("icon") ? json.getJSONObject("icon") : null; - if (iconJson != null) { - for (Iterator it = iconJson.keys(); it.hasNext(); ) { - String iconKey = it.next(); - String name = iconJson.getString(iconKey); - iconNames.put(iconKey, name); - } - } - JSONObject imageJson = json.has("image") ? json.getJSONObject("image") : null; - if (imageJson != null) { - for (Iterator it = imageJson.keys(); it.hasNext(); ) { - String imageKey = it.next(); - String name = imageJson.getString(imageKey); - imageNames.put(imageKey, name); - } - } - JSONObject nameJson = json.has("name") ? json.getJSONObject("name") : null; - if (nameJson != null) { - for (Iterator it = nameJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = nameJson.getString(localeKey); - names.put(localeKey, name); - } - } - JSONObject descriptionJson = json.has("description") ? json.getJSONObject("description") : null; - if (descriptionJson != null) { - for (Iterator it = descriptionJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = descriptionJson.getString(localeKey); - descriptions.put(localeKey, name); - } - } - JSONArray regionsJson = json.has("regionsJson") ? json.getJSONArray("regionsJson") : null; + iconNames = getLocalizedMapFromJson("icon", json); + imageNames = getLocalizedMapFromJson("image", json); + names = getLocalizedMapFromJson("name", json); + descriptions = getLocalizedMapFromJson("description", json); + + JSONArray regionsJson = json.optJSONArray("regionsJson"); if (regionsJson != null) { customRegions.addAll(collectRegionsFromJson(regionsJson)); } } public void writeAdditionalDataToJson(JSONObject json) throws JSONException { - JSONObject iconJson = new JSONObject(); - for (Map.Entry entry : iconNames.entrySet()) { - iconJson.put(entry.getKey(), entry.getValue()); - } - json.put("icon", iconJson); - - JSONObject imageJson = new JSONObject(); - for (Map.Entry entry : imageNames.entrySet()) { - imageJson.put(entry.getKey(), entry.getValue()); - } - json.put("image", imageJson); - - JSONObject nameJson = new JSONObject(); - for (Map.Entry entry : names.entrySet()) { - nameJson.put(entry.getKey(), entry.getValue()); - } - json.put("name", nameJson); - - JSONObject descriptionJson = new JSONObject(); - for (Map.Entry entry : descriptions.entrySet()) { - descriptionJson.put(entry.getKey(), entry.getValue()); - } - json.put("description", descriptionJson); + writeLocalizedMapToJson("icon", json, iconNames); + writeLocalizedMapToJson("image", json, imageNames); + writeLocalizedMapToJson("name", json, names); + writeLocalizedMapToJson("description", json, descriptions); JSONArray regionsJson = new JSONArray(); for (WorldRegion region : getFlatCustomRegions()) { @@ -322,9 +337,8 @@ public class CustomOsmandPlugin extends OsmandPlugin { } private List getFlatCustomRegions() { - List l = new ArrayList<>(); + List l = new ArrayList<>(customRegions); for (WorldRegion region : customRegions) { - l.add(region); collectCustomSubregionsFromRegion(region, l); } return l; @@ -333,70 +347,24 @@ public class CustomOsmandPlugin extends OsmandPlugin { private void collectCustomSubregionsFromRegion(WorldRegion region, List items) { items.addAll(region.getSubregions()); for (WorldRegion subregion : region.getSubregions()) { - if (subregion instanceof CustomRegion) { - collectCustomSubregionsFromRegion(subregion, items); - } + collectCustomSubregionsFromRegion(subregion, items); } } public void readDependentFilesFromJson(JSONObject json) throws JSONException { - JSONArray rendererNamesJson = json.has("rendererNames") ? json.getJSONArray("rendererNames") : null; - if (rendererNamesJson != null) { - for (int i = 0; i < rendererNamesJson.length(); i++) { - String renderer = rendererNamesJson.getString(i); - rendererNames.add(renderer); - } - } - JSONArray routerNamesJson = json.has("routerNames") ? json.getJSONArray("routerNames") : null; - if (routerNamesJson != null) { - for (int i = 0; i < routerNamesJson.length(); i++) { - String renderer = routerNamesJson.getString(i); - routerNames.add(renderer); - } - } - JSONObject iconNamesJson = json.has("iconNames") ? json.getJSONObject("iconNames") : null; - if (iconNamesJson != null) { - for (Iterator it = iconNamesJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = iconNamesJson.getString(localeKey); - iconNames.put(localeKey, name); - } - } - JSONObject imageNamesJson = json.has("imageNames") ? json.getJSONObject("imageNames") : null; - if (imageNamesJson != null) { - for (Iterator it = imageNamesJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = imageNamesJson.getString(localeKey); - imageNames.put(localeKey, name); - } - } - resourceDirName = json.has("pluginResDir") ? json.getString("pluginResDir") : null; + rendererNames = jsonArrayToList("rendererNames", json); + routerNames = jsonArrayToList("routerNames", json); + iconNames = getLocalizedMapFromJson("iconNames", json); + imageNames = getLocalizedMapFromJson("imageNames", json); + resourceDirName = json.optString("pluginResDir"); } public void writeDependentFilesJson(JSONObject json) throws JSONException { - JSONArray rendererNamesJson = new JSONArray(); - for (String render : rendererNames) { - rendererNamesJson.put(render); - } - json.put("rendererNames", rendererNamesJson); + writeStringListToJson("rendererNames", json, rendererNames); + writeStringListToJson("routerNames", json, routerNames); - JSONArray routerNamesJson = new JSONArray(); - for (String render : routerNames) { - routerNamesJson.put(render); - } - json.put("routerNames", routerNamesJson); - - JSONObject iconNamesJson = new JSONObject(); - for (Map.Entry entry : iconNames.entrySet()) { - iconNamesJson.put(entry.getKey(), entry.getValue()); - } - json.put("iconNames", iconNamesJson); - - JSONObject imageNamesJson = new JSONObject(); - for (Map.Entry entry : imageNames.entrySet()) { - imageNamesJson.put(entry.getKey(), entry.getValue()); - } - json.put("imageNames", imageNamesJson); + writeLocalizedMapToJson("iconNames", json, iconNames); + writeLocalizedMapToJson("imageNames", json, imageNames); json.put("pluginResDir", resourceDirName); } @@ -407,11 +375,11 @@ public class CustomOsmandPlugin extends OsmandPlugin { for (int i = 0; i < jsonArray.length(); i++) { JSONObject regionJson = jsonArray.getJSONObject(i); CustomRegion region = CustomRegion.fromJson(regionJson); - flatRegions.put(region.path, region); + flatRegions.put(region.getPath(), region); } for (CustomRegion region : flatRegions.values()) { - if (!Algorithms.isEmpty(region.parentPath)) { - CustomRegion parentReg = flatRegions.get(region.parentPath); + if (!Algorithms.isEmpty(region.getParentPath())) { + CustomRegion parentReg = flatRegions.get(region.getParentPath()); if (parentReg != null) { parentReg.addSubregion(region); } @@ -422,16 +390,6 @@ public class CustomOsmandPlugin extends OsmandPlugin { return customRegions; } - @Override - public List getRendererNames() { - return rendererNames; - } - - @Override - public List getRouterNames() { - return routerNames; - } - public void addRouter(String fileName) { String routerName = Algorithms.getFileWithoutDirs(fileName); if (!routerNames.contains(routerName)) { @@ -462,80 +420,14 @@ public class CustomOsmandPlugin extends OsmandPlugin { } } - private Drawable getIconForFile(String path, Map fileNames) { - for (Map.Entry entry : fileNames.entrySet()) { - String value = entry.getValue(); - if (value.startsWith("@")) { - value = value.substring(1); - } - if (path.endsWith(value)) { - return BitmapDrawable.createFromPath(path); - } - } - return null; - } - - @NonNull - @Override - public Drawable getLogoResource() { - return icon != null ? icon : super.getLogoResource(); - } - - @Override - public Drawable getAssetResourceImage() { - return image; - } - public void updateSuggestedDownloads(List items) { suggestedDownloadItems = new ArrayList<>(items); } - public void updateDownloadItems(List items) { + public void updateDownloadItems(List items) { customRegions = new ArrayList<>(items); } - @Override - public List getDownloadMaps() { - return customRegions; - } - - @Override - public List getSuggestedMaps() { - List suggestedMaps = new ArrayList<>(); - - DownloadIndexesThread downloadThread = app.getDownloadThread(); - if (!downloadThread.getIndexes().isDownloadedFromInternet && app.getSettings().isInternetConnectionAvailable()) { - downloadThread.runReloadIndexFiles(); - } - - boolean downloadIndexes = app.getSettings().isInternetConnectionAvailable() - && !downloadThread.getIndexes().isDownloadedFromInternet - && !downloadThread.getIndexes().downloadFromInternetFailed; - - if (!downloadIndexes) { - for (SuggestedDownloadItem item : suggestedDownloadItems) { - DownloadActivityType type = DownloadActivityType.getIndexType(item.scopeId); - if (type != null) { - List foundMaps = new ArrayList<>(); - String searchType = item.getSearchType(); - if ("latlon".equalsIgnoreCase(searchType)) { - LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation(); - foundMaps.addAll(getMapsForType(latLon, type)); - } else if ("worldregion".equalsIgnoreCase(searchType)) { - LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation(); - foundMaps.addAll(getMapsForType(latLon, type)); - } - if (!Algorithms.isEmpty(item.getNames())) { - foundMaps.addAll(getMapsForType(item.getNames(), type, item.getLimit())); - } - suggestedMaps.addAll(foundMaps); - } - } - } - - return suggestedMaps; - } - private List getMapsForType(LatLon latLon, DownloadActivityType type) { try { return DownloadResources.findIndexItemsAt(app, latLon, type); @@ -549,6 +441,65 @@ public class CustomOsmandPlugin extends OsmandPlugin { return DownloadResources.findIndexItemsAt(app, names, type, false, limit); } + public static String getLocalizedResFromMap(Context ctx, Map localizedMap, String defVal) { + if (!Algorithms.isEmpty(localizedMap)) { + Configuration config = ctx.getResources().getConfiguration(); + String lang = config.locale.getLanguage(); + String name = localizedMap.get(lang); + if (Algorithms.isEmpty(name)) { + name = localizedMap.get(""); + } + if (!Algorithms.isEmpty(name)) { + return name; + } + } + return defVal; + } + + public static List jsonArrayToList(String key, JSONObject json) throws JSONException { + List items = new ArrayList<>(); + JSONArray jsonArray = json.optJSONArray(key); + if (jsonArray != null) { + for (int i = 0; i < jsonArray.length(); i++) { + items.add(jsonArray.getString(i)); + } + } + return items; + } + + public static Map getLocalizedMapFromJson(String key, JSONObject json) throws JSONException { + Map localizedMap = new HashMap<>(); + JSONObject jsonObject = json.optJSONObject(key); + if (jsonObject != null) { + for (Iterator it = jsonObject.keys(); it.hasNext(); ) { + String localeKey = it.next(); + String name = jsonObject.getString(localeKey); + localizedMap.put(localeKey, name); + } + } + return localizedMap; + } + + public static void writeStringListToJson(String key, JSONObject json, List items) throws JSONException { + if (!Algorithms.isEmpty(items)) { + JSONArray jsonArray = new JSONArray(); + for (String render : items) { + jsonArray.put(render); + } + json.put(key, jsonArray); + } + } + + public static void writeLocalizedMapToJson(String jsonKey, JSONObject json, Map map) throws JSONException { + if (!Algorithms.isEmpty(map)) { + JSONObject jsonObject = new JSONObject(); + for (Map.Entry entry : map.entrySet()) { + jsonObject.put(entry.getKey(), entry.getValue()); + } + json.put(jsonKey, jsonObject); + } + } + public interface PluginItemsListener { void onItemsRemoved(); diff --git a/OsmAnd/src/net/osmand/plus/CustomRegion.java b/OsmAnd/src/net/osmand/plus/CustomRegion.java new file mode 100644 index 0000000000..fe1c2d86b8 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/CustomRegion.java @@ -0,0 +1,172 @@ +package net.osmand.plus; + +import androidx.annotation.ColorInt; + +import net.osmand.PlatformUtil; +import net.osmand.map.WorldRegion; +import net.osmand.plus.download.CustomIndexItem; +import net.osmand.plus.download.DownloadActivityType; +import net.osmand.plus.download.IndexItem; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CustomRegion extends WorldRegion { + + private static final Log LOG = PlatformUtil.getLog(CustomRegion.class); + + private String scopeId; + private String path; + private String parentPath; + private String type; + private String subfolder; + private String headerButton; + + private JSONArray downloadItemsJson; + + private Map names = new HashMap<>(); + private Map icons = new HashMap<>(); + private Map headers = new HashMap<>(); + + private int headerColor = -1; + + + private CustomRegion(String scopeId, String path, String type) { + super(path, null); + this.scopeId = scopeId; + this.path = path; + this.type = type; + } + + public String getScopeId() { + return scopeId; + } + + public String getPath() { + return path; + } + + public String getParentPath() { + return parentPath; + } + + @ColorInt + public int getHeaderColor() { + return headerColor; + } + + public static CustomRegion fromJson(JSONObject object) throws JSONException { + String scopeId = object.optString("scope-id", null); + String path = object.optString("path", null); + String type = object.optString("type", null); + + CustomRegion region = new CustomRegion(scopeId, path, type); + region.subfolder = object.optString("subfolder", null); + + int index = path.lastIndexOf(File.separator); + if (index != -1) { + region.parentPath = path.substring(0, index); + } + + region.names = CustomOsmandPlugin.getLocalizedMapFromJson("name", object); + if (!Algorithms.isEmpty(region.names)) { + region.regionName = region.names.get(""); + region.regionNameEn = region.names.get(""); + region.regionFullName = region.names.get(""); + region.regionNameLocale = region.names.get(""); + } + + region.icons = CustomOsmandPlugin.getLocalizedMapFromJson("icon", object); + region.headers = CustomOsmandPlugin.getLocalizedMapFromJson("header", object); + + region.headerButton = object.optString("header-button", null); + region.downloadItemsJson = object.optJSONArray("items"); + + String headerColor = object.optString("header-color", null); + try { + region.headerColor = Algorithms.isEmpty(headerColor) ? 0 : Algorithms.parseColor(headerColor); + } catch (IllegalArgumentException e) { + region.headerColor = 0; + } + + return region; + } + + public List loadIndexItems() { + List items = new ArrayList<>(); + if (downloadItemsJson != null) { + try { + for (int i = 0; i < downloadItemsJson.length(); i++) { + JSONObject itemJson = downloadItemsJson.getJSONObject(i); + + long timestamp = itemJson.optLong("timestamp") * 1000; + long contentSize = itemJson.optLong("contentSize"); + long containerSize = itemJson.optLong("containerSize"); + + String indexType = itemJson.optString("type", type); + String webUrl = itemJson.optString("weburl"); + String fileName = itemJson.optString("filename"); + String downloadUrl = itemJson.optString("downloadurl"); + String size = new DecimalFormat("#.#").format(containerSize / (1024f * 1024f)); + + List descrImageUrl = CustomOsmandPlugin.jsonArrayToList("image-description-url", itemJson); + Map indexNames = CustomOsmandPlugin.getLocalizedMapFromJson("name", itemJson); + Map descriptions = CustomOsmandPlugin.getLocalizedMapFromJson("description", itemJson); + Map webButtonText = CustomOsmandPlugin.getLocalizedMapFromJson("web-button-text", itemJson); + + DownloadActivityType type = DownloadActivityType.getIndexType(indexType); + if (type != null) { + IndexItem indexItem = new CustomIndexItem.CustomIndexItemBuilder() + .setFileName(fileName) + .setSubfolder(subfolder) + .setDownloadUrl(downloadUrl) + .setNames(indexNames) + .setDescriptions(descriptions) + .setImageDescrUrl(descrImageUrl) + .setWebUrl(webUrl) + .setWebButtonText(webButtonText) + .setTimestamp(timestamp) + .setSize(size) + .setContentSize(contentSize) + .setContainerSize(containerSize) + .setType(type) + .create(); + + items.add(indexItem); + } + } + } catch (JSONException e) { + LOG.error(e); + } + } + return items; + } + + public JSONObject toJson() throws JSONException { + JSONObject jsonObject = new JSONObject(); + + jsonObject.putOpt("scope-id", scopeId); + jsonObject.putOpt("path", path); + jsonObject.putOpt("type", type); + jsonObject.putOpt("subfolder", subfolder); + jsonObject.putOpt("header-button", headerButton); + + CustomOsmandPlugin.writeLocalizedMapToJson("name", jsonObject, names); + CustomOsmandPlugin.writeLocalizedMapToJson("icon", jsonObject, icons); + CustomOsmandPlugin.writeLocalizedMapToJson("header", jsonObject, headers); + + jsonObject.putOpt("items", downloadItemsJson); + + return jsonObject; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index 77f3911137..3aff417123 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -22,7 +22,6 @@ import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.access.AccessibilityPlugin; import net.osmand.map.WorldRegion; -import net.osmand.plus.SettingsHelper.CustomRegion; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TabActivity.TabItem; import net.osmand.plus.api.SettingsAPI; @@ -184,7 +183,7 @@ public abstract class OsmandPlugin { return Collections.emptyList(); } - public List getDownloadMaps() { + public List getDownloadMaps() { return Collections.emptyList(); } @@ -651,8 +650,8 @@ public abstract class OsmandPlugin { return null; } - public static List getCustomDownloadRegions() { - List l = new ArrayList<>(); + public static List getCustomDownloadRegions() { + List l = new ArrayList<>(); for (OsmandPlugin plugin : getEnabledPlugins()) { l.addAll(plugin.getDownloadMaps()); } @@ -661,18 +660,18 @@ public abstract class OsmandPlugin { public static List getCustomDownloadItems() { List l = new ArrayList<>(); - for (CustomRegion region : getCustomDownloadRegions()) { + for (WorldRegion region : getCustomDownloadRegions()) { collectIndexItemsFromSubregion(region, l); } return l; } - public static void collectIndexItemsFromSubregion(CustomRegion region, List items) { - items.addAll(region.loadIndexItems()); + public static void collectIndexItemsFromSubregion(WorldRegion region, List items) { + if (region instanceof CustomRegion) { + items.addAll(((CustomRegion) region).loadIndexItems()); + } for (WorldRegion subregion : region.getSubregions()) { - if (subregion instanceof CustomRegion) { - collectIndexItemsFromSubregion((CustomRegion) subregion, items); - } + collectIndexItemsFromSubregion(subregion, items); } } diff --git a/OsmAnd/src/net/osmand/plus/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/SettingsHelper.java index e92b984d8e..faa9760aa9 100644 --- a/OsmAnd/src/net/osmand/plus/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/SettingsHelper.java @@ -23,10 +23,6 @@ import net.osmand.plus.ApplicationMode.ApplicationModeBean; import net.osmand.plus.ApplicationMode.ApplicationModeBuilder; import net.osmand.plus.CustomOsmandPlugin.SuggestedDownloadItem; import net.osmand.plus.OsmandSettings.OsmandPreference; -import net.osmand.plus.download.CustomIndexItem; -import net.osmand.plus.download.DownloadActivityType; -import net.osmand.plus.download.DownloadResourceGroup; -import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.poi.PoiUIFilter; @@ -53,7 +49,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.reflect.Type; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -566,7 +561,7 @@ public class SettingsHelper { public static class DownloadsItem extends SettingsItem { - private List items; + private List items; DownloadsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException { super(app, json); @@ -597,12 +592,7 @@ public class SettingsHelper { return "downloads"; } - @Override - public void apply() { - super.apply(); - } - - public List getItems() { + public List getItems() { return items; } @@ -625,9 +615,11 @@ public class SettingsHelper { JSONArray jsonArray = new JSONArray(); if (!items.isEmpty()) { try { - for (CustomRegion customRegion : items) { - JSONObject regionJson = customRegion.toJson(); - jsonArray.put(regionJson); + for (WorldRegion region : items) { + if (region instanceof CustomRegion) { + JSONObject regionJson = ((CustomRegion) region).toJson(); + jsonArray.put(regionJson); + } } json.put("items", jsonArray); } catch (JSONException e) { @@ -650,203 +642,6 @@ public class SettingsHelper { } } - public static class CustomRegion extends WorldRegion { - - public String scopeId; - public String path; - public String parentPath; - public String type; - public String subfolder; - public String headerButton; - - public JSONArray downloadItemsJson; - - public Map names = new HashMap<>(); - public Map icons = new HashMap<>(); - public Map headers = new HashMap<>(); - - public int headerColor; - - - private CustomRegion(String scopeId, String path, String type) { - super(path, null); - this.scopeId = scopeId; - this.path = path; - this.type = type; - } - - public static CustomRegion fromJson(JSONObject object) throws JSONException { - String scopeId = object.optString("scope-id", null); - String path = object.optString("path", null); - String type = object.optString("type", null); - - CustomRegion region = new CustomRegion(scopeId, path, type); - region.subfolder = object.optString("subfolder", null); - - int index = path.lastIndexOf(File.separator); - if (index != -1) { - region.parentPath = path.substring(0, index); - } - - JSONObject namesJson = object.optJSONObject("name"); - if (namesJson != null) { - for (Iterator it = namesJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = namesJson.getString(localeKey); - region.names.put(localeKey, name); - } - - region.regionName = region.names.get(""); - region.regionNameEn = region.names.get(""); - region.regionFullName = region.names.get(""); - region.regionNameLocale = region.names.get(""); - if (Algorithms.isEmpty(region.regionName)) { - region.regionName = region.names.get(""); - } - if (Algorithms.isEmpty(region.regionName)) { - region.regionName = DownloadResourceGroup.DownloadResourceGroupType.REGION.getDefaultId(); - } - } - - JSONObject iconJson = object.optJSONObject("icon"); - if (iconJson != null) { - for (Iterator it = iconJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = iconJson.getString(localeKey); - region.icons.put(localeKey, name); - } - } - - JSONObject headerJson = object.optJSONObject("header"); - if (headerJson != null) { - for (Iterator it = headerJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = headerJson.getString(localeKey); - region.headers.put(localeKey, name); - } - } - - region.headerButton = object.optString("header-button", null); - region.downloadItemsJson = object.optJSONArray("items"); - - String headerColor = object.optString("header-color", null); - try { - region.headerColor = Algorithms.isEmpty(headerColor) ? 0 : Algorithms.parseColor(headerColor); - } catch (IllegalArgumentException e) { - region.headerColor = 0; - } - - return region; - } - - public List loadIndexItems() { - List items = new ArrayList<>(); - if (downloadItemsJson != null) { - try { - for (int i = 0; i < downloadItemsJson.length(); i++) { - JSONObject indexItemJson = downloadItemsJson.getJSONObject(i); - - JSONObject indexNamesJson = indexItemJson.optJSONObject("name"); - Map indexNames = new HashMap<>(); - if (indexNamesJson != null) { - for (Iterator it = indexNamesJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = indexNamesJson.getString(localeKey); - indexNames.put(localeKey, name); - } - } - long timestamp = indexItemJson.optLong("timestamp") * 1000; - long contentSize = indexItemJson.optLong("contentSize"); - long containerSize = indexItemJson.optLong("containerSize"); - - String fileName = indexItemJson.optString("filename"); - String downloadUrl = indexItemJson.optString("downloadurl"); - String size = new DecimalFormat("#.#").format(containerSize / (1024f * 1024f)); - - JSONObject descriptionJson = indexItemJson.optJSONObject("description"); - Map descriptions = new HashMap<>(); - if (descriptionJson != null) { - for (Iterator it = descriptionJson.keys(); it.hasNext(); ) { - String localeKey = it.next(); - String name = descriptionJson.getString(localeKey); - descriptions.put(localeKey, name); - } - } - - List descrImageUrl = new ArrayList<>(); - JSONArray imageDescriptionUrlJson = indexItemJson.optJSONArray("image-description-url"); - if (imageDescriptionUrlJson != null) { - for (int j = 0; j < imageDescriptionUrlJson.length(); j++) { - String renderer = imageDescriptionUrlJson.getString(i); - descrImageUrl.add(renderer); - } - } - String indexType = indexItemJson.optString("type", type); - - @NonNull DownloadActivityType tp = DownloadActivityType.getIndexType(indexType); - if (tp != null) { - IndexItem indexItem = new CustomIndexItem(fileName, subfolder, downloadUrl, indexNames,descriptions, descrImageUrl, timestamp, size, contentSize, containerSize, tp); - items.add(indexItem); - } - } - } catch (JSONException e) { - LOG.error(e); - } - } - return items; - } - - public JSONObject toJson() throws JSONException { - JSONObject jsonObject = new JSONObject(); - - if (!Algorithms.isEmpty(scopeId)) { - jsonObject.put("scope-id", scopeId); - } - if (!Algorithms.isEmpty(path)) { - jsonObject.put("path", path); - } - if (!Algorithms.isEmpty(type)) { - jsonObject.put("type", type); - } - if (!Algorithms.isEmpty(subfolder)) { - jsonObject.put("subfolder", subfolder); - } - if (!Algorithms.isEmpty(headerButton)) { - jsonObject.put("header-button", headerButton); - } - - if (!Algorithms.isEmpty(names)) { - JSONObject namesJson = new JSONObject(); - for (Map.Entry entry : names.entrySet()) { - namesJson.put(entry.getKey(), entry.getValue()); - } - jsonObject.put("name", namesJson); - } - - if (!Algorithms.isEmpty(icons)) { - JSONObject iconsJson = new JSONObject(); - for (Map.Entry entry : icons.entrySet()) { - iconsJson.put(entry.getKey(), entry.getValue()); - } - jsonObject.put("icon", iconsJson); - } - - if (!Algorithms.isEmpty(headers)) { - JSONObject headerJson = new JSONObject(); - for (Map.Entry entry : headers.entrySet()) { - headerJson.put(entry.getKey(), entry.getValue()); - } - jsonObject.put("header", headerJson); - } - - if (downloadItemsJson != null) { - jsonObject.put("items", downloadItemsJson); - } - - return jsonObject; - } - } - public abstract static class CollectionSettingsItem extends SettingsItem { protected List items; diff --git a/OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java b/OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java index 63a4adb243..e48179d1e0 100644 --- a/OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java +++ b/OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java @@ -1,9 +1,11 @@ package net.osmand.plus.download; import android.content.Context; -import android.content.res.Configuration; + +import androidx.annotation.NonNull; import net.osmand.map.OsmandRegions; +import net.osmand.plus.CustomOsmandPlugin; import net.osmand.plus.OsmandApplication; import net.osmand.util.Algorithms; @@ -13,21 +15,36 @@ import java.util.Map; public class CustomIndexItem extends IndexItem { - private String downloadUrl; private String subfolder; + private String downloadUrl; + private String webUrl; + + private List imageDescrUrl; private Map names; private Map descriptions; - private List descrImageUrl; + private Map webButtonTexts; - public CustomIndexItem(String fileName, String subfolder, String downloadUrl, - Map names, Map descriptions, List descrImageUrl, long dateModified, String size, long contentSize, - long containerSize, DownloadActivityType type) { - super(fileName, null, dateModified, size, contentSize, containerSize, type); - this.names = names; - this.descriptions = descriptions; + public CustomIndexItem(String fileName, + String subfolder, + String downloadUrl, + String webUrl, + String size, + long timestamp, + long contentSize, + long containerSize, + List imageDescrUrl, + Map names, + Map descriptions, + Map webButtonTexts, + @NonNull DownloadActivityType type) { + super(fileName, null, timestamp, size, contentSize, containerSize, type); this.subfolder = subfolder; this.downloadUrl = downloadUrl; - this.descrImageUrl = descrImageUrl; + this.webUrl = webUrl; + this.imageDescrUrl = imageDescrUrl; + this.names = names; + this.descriptions = descriptions; + this.webButtonTexts = webButtonTexts; } @Override @@ -36,7 +53,6 @@ public class CustomIndexItem extends IndexItem { if (entry != null) { entry.urlToDownload = downloadUrl; } - return entry; } @@ -56,38 +72,125 @@ public class CustomIndexItem extends IndexItem { @Override public String getVisibleName(Context ctx, OsmandRegions osmandRegions, boolean includingParent) { - if (!Algorithms.isEmpty(names)) { - Configuration config = ctx.getResources().getConfiguration(); - String lang = config.locale.getLanguage(); - String name = names.get(lang); - if (Algorithms.isEmpty(name)) { - name = names.get(""); - } - if (!Algorithms.isEmpty(name)) { - return name; - } - } - - return super.getVisibleName(ctx, osmandRegions, includingParent); + String name = super.getVisibleName(ctx, osmandRegions, includingParent); + return CustomOsmandPlugin.getLocalizedResFromMap(ctx, names, name); } public List getDescriptionImageUrl() { - return descrImageUrl; + return imageDescrUrl; } public String getLocalizedDescription(Context ctx) { - if (!Algorithms.isEmpty(descriptions)) { - Configuration config = ctx.getResources().getConfiguration(); - String lang = config.locale.getLanguage(); - String name = descriptions.get(lang); - if (Algorithms.isEmpty(name)) { - name = descriptions.get(""); - } - if (!Algorithms.isEmpty(name)) { - return name; - } + String description = super.getDescription(); + return CustomOsmandPlugin.getLocalizedResFromMap(ctx, descriptions, description); + } + + public String getWebUrl() { + return webUrl; + } + + public String getWebButtonText(Context ctx) { + return CustomOsmandPlugin.getLocalizedResFromMap(ctx, webButtonTexts, null); + } + + public static class CustomIndexItemBuilder { + + private String fileName; + private String subfolder; + private String downloadUrl; + private String webUrl; + private String size; + + private long timestamp; + private long contentSize; + private long containerSize; + + private List imageDescrUrl; + private Map names; + private Map descriptions; + private Map webButtonText; + private DownloadActivityType type; + + + public CustomIndexItemBuilder setFileName(String fileName) { + this.fileName = fileName; + return this; } - return super.getDescription(); + public CustomIndexItemBuilder setSubfolder(String subfolder) { + this.subfolder = subfolder; + return this; + } + + public CustomIndexItemBuilder setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + return this; + } + + public CustomIndexItemBuilder setWebUrl(String webUrl) { + this.webUrl = webUrl; + return this; + } + + public CustomIndexItemBuilder setSize(String size) { + this.size = size; + return this; + } + + public CustomIndexItemBuilder setTimestamp(long timestamp) { + this.timestamp = timestamp; + return this; + } + + public CustomIndexItemBuilder setContentSize(long contentSize) { + this.contentSize = contentSize; + return this; + } + + public CustomIndexItemBuilder setContainerSize(long containerSize) { + this.containerSize = containerSize; + return this; + } + + public CustomIndexItemBuilder setImageDescrUrl(List imageDescrUrl) { + this.imageDescrUrl = imageDescrUrl; + return this; + } + + public CustomIndexItemBuilder setNames(Map names) { + this.names = names; + return this; + } + + public CustomIndexItemBuilder setDescriptions(Map descriptions) { + this.descriptions = descriptions; + return this; + } + + public CustomIndexItemBuilder setWebButtonText(Map webButtonText) { + this.webButtonText = webButtonText; + return this; + } + + public CustomIndexItemBuilder setType(@NonNull DownloadActivityType type) { + this.type = type; + return this; + } + + public CustomIndexItem create() { + return new CustomIndexItem(fileName, + subfolder, + downloadUrl, + webUrl, + size, + timestamp, + contentSize, + containerSize, + imageDescrUrl, + names, + descriptions, + webButtonText, + type); + } } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java index 3c512ef305..61ed7b303f 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadResources.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadResources.java @@ -10,7 +10,7 @@ import net.osmand.map.OsmandRegions; import net.osmand.map.WorldRegion; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.SettingsHelper.CustomRegion; +import net.osmand.plus.CustomRegion; import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetIndexItem; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.util.Algorithms; @@ -368,10 +368,10 @@ public class DownloadResources extends DownloadResourceGroup { } this.groupByRegion = groupByRegion; - List customRegions = OsmandPlugin.getCustomDownloadRegions(); + List customRegions = OsmandPlugin.getCustomDownloadRegions(); if (!Algorithms.isEmpty(customRegions)) { addGroup(extraMapsGroup); - for (CustomRegion region : customRegions) { + for (WorldRegion region : customRegions) { buildRegionsGroups(region, extraMapsGroup); } } diff --git a/OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java index f073a871a1..bd709d80ac 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java @@ -1,6 +1,7 @@ package net.osmand.plus.download.ui; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -17,18 +18,21 @@ import com.squareup.picasso.RequestCreator; import net.osmand.AndroidUtils; import net.osmand.PicassoUtils; +import net.osmand.map.WorldRegion; +import net.osmand.plus.CustomRegion; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.download.CustomIndexItem; import net.osmand.plus.download.DownloadActivity; -import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadResourceGroup; import net.osmand.plus.download.DownloadResources; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; +import net.osmand.util.Algorithms; import static net.osmand.plus.download.ui.DownloadResourceGroupFragment.REGION_ID_DLG_KEY; -public class DownloadItemFragment extends DialogFragment implements DownloadIndexesThread.DownloadEvents { +public class DownloadItemFragment extends DialogFragment { public static final String ITEM_ID_DLG_KEY = "index_item_dialog_key"; @@ -41,11 +45,12 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde private CustomIndexItem indexItem; private View view; - private TextView description; - private ImageView image; private Toolbar toolbar; + private ImageView image; + private TextView description; + private TextView buttonTextView; - boolean nightMode; + private boolean nightMode; @Override public void onCreate(Bundle savedInstanceState) { @@ -84,7 +89,16 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde image = view.findViewById(R.id.item_image); View dismissButton = view.findViewById(R.id.dismiss_button); - UiUtilities.setupDialogButton(nightMode, dismissButton, UiUtilities.DialogButtonType.PRIMARY, "Test"); + dismissButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (indexItem != null && !Algorithms.isEmpty(indexItem.getWebUrl())) { + WikipediaDialogFragment.showFullArticle(v.getContext(), Uri.parse(indexItem.getWebUrl()), nightMode); + } + } + }); + UiUtilities.setupDialogButton(nightMode, dismissButton, UiUtilities.DialogButtonType.PRIMARY, ""); + buttonTextView = (TextView) dismissButton.findViewById(R.id.button_text); return view; } @@ -95,20 +109,6 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde reloadData(); } - @Override - public void newDownloadIndexes() { - reloadData(); - } - - @Override - public void downloadHasFinished() { - - } - - @Override - public void downloadInProgress() { - } - @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -125,7 +125,17 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde indexItem = (CustomIndexItem) group.getItemByIndex(itemIndex); if (indexItem != null) { toolbar.setTitle(indexItem.getVisibleName(app, app.getRegions())); + WorldRegion region = group.getRegion(); + if (region instanceof CustomRegion) { + CustomRegion customRegion = (CustomRegion) region; + int color = customRegion.getHeaderColor(); + if (color != -1) { + toolbar.setBackgroundColor(color); + } + } + description.setText(indexItem.getLocalizedDescription(app)); + buttonTextView.setText(indexItem.getWebButtonText(app)); final PicassoUtils picassoUtils = PicassoUtils.getPicasso(app); Picasso picasso = Picasso.get();