diff --git a/OsmAnd-java/src/main/java/net/osmand/map/OsmandRegions.java b/OsmAnd-java/src/main/java/net/osmand/map/OsmandRegions.java index 07ed57126c..033beb3789 100644 --- a/OsmAnd-java/src/main/java/net/osmand/map/OsmandRegions.java +++ b/OsmAnd-java/src/main/java/net/osmand/map/OsmandRegions.java @@ -29,6 +29,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -54,6 +55,8 @@ public class OsmandRegions { private BinaryMapIndexReader reader; private String locale = "en"; + // locale including region + private String locale2 = null; private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmandRegions.class); WorldRegion worldRegion = new WorldRegion(WorldRegion.WORLD); @@ -73,6 +76,7 @@ public class OsmandRegions { Integer nameEnType = null; Integer nameType = null; Integer nameLocaleType = null; + Integer nameLocale2Type = null; Integer langType = null; Integer metricType = null; Integer leftHandDrivingType = null; @@ -374,7 +378,19 @@ public class OsmandRegions { } public void setLocale(String locale) { + setLocale(locale, null); + } + + public void setLocale(String locale, String country) { this.locale = locale; + // Check locale and give 2 locale names + if("zh".equals(locale)) { + if("TW".equalsIgnoreCase(country)) { + this.locale2 = "zh-hant"; + } else if("CN".equalsIgnoreCase(country)) { + this.locale2 = "zh-hans"; + } + } } @@ -427,7 +443,12 @@ public class OsmandRegions { parentRelations.put(rd.regionFullName, rd.regionParentFullName); } rd.regionName = mapIndexFields.get(mapIndexFields.nameType, object); - rd.regionNameLocale = mapIndexFields.get(mapIndexFields.nameLocaleType, object); + if(mapIndexFields.nameLocale2Type != null) { + rd.regionNameLocale = mapIndexFields.get(mapIndexFields.nameLocale2Type, object); + } + if (rd.regionNameLocale == null) { + rd.regionNameLocale = mapIndexFields.get(mapIndexFields.nameLocaleType, object); + } rd.regionNameEn = mapIndexFields.get(mapIndexFields.nameEnType, object); rd.params.regionLang = mapIndexFields.get(mapIndexFields.langType, object); rd.params.regionLeftHandDriving = mapIndexFields.get(mapIndexFields.leftHandDrivingType, object); @@ -543,6 +564,9 @@ public class OsmandRegions { mapIndexFields.nameType = object.getMapIndex().getRule(FIELD_NAME, null); mapIndexFields.nameEnType = object.getMapIndex().getRule(FIELD_NAME_EN, null); mapIndexFields.nameLocaleType = object.getMapIndex().getRule(FIELD_NAME + ":" + locale, null); + if(locale2 != null) { + mapIndexFields.nameLocale2Type = object.getMapIndex().getRule(FIELD_NAME + ":" + locale2, null); + } mapIndexFields.parentFullName = object.getMapIndex().getRule(FIELD_REGION_PARENT_NAME, null); mapIndexFields.fullNameType = object.getMapIndex().getRule(FIELD_REGION_FULL_NAME, null); mapIndexFields.langType = object.getMapIndex().getRule(FIELD_LANG, null); @@ -565,9 +589,15 @@ public class OsmandRegions { String nm = b.getNameByType(or.mapIndexFields.nameEnType); if (nm == null) { nm = b.getName(); + System.out.println(or.getLocaleName(or.getDownloadName(b), false)); } if (or.isDownloadOfType(b, MAP_TYPE)) { found.add(nm.toLowerCase()); + String localName = b.getNameByType(or.mapIndexFields.nameLocaleType); + if(or.mapIndexFields.nameLocale2Type != null) { + localName = b.getNameByType(or.mapIndexFields.nameLocale2Type); + } + System.out.println(String.format("Region %s %s", b.getName(), localName)); } } @@ -580,6 +610,9 @@ public class OsmandRegions { public static void main(String[] args) throws IOException { OsmandRegions or = new OsmandRegions(); + Locale tw = Locale.CHINA; + or.setLocale(tw.getLanguage(), null); +// or.setLocale(tw.getLanguage(), tw.getCountry()); or.prepareFile("/Users/victorshcherb/osmand/repos/resources/countries-info/regions.ocbf"); LinkedList lst = new LinkedList(); lst.add(or.getWorldRegion()); @@ -592,20 +625,20 @@ public class OsmandRegions { // lst.addAll(wd.getSubregions()); } - + or.cacheAllCountries(); // long t = System.currentTimeMillis(); // or.cacheAllCountries(); // System.out.println("Init " + (System.currentTimeMillis() - t)); - //testCountry(or, 15.8, 23.09, "chad"); - testCountry(or, 52.10, 4.92, "the netherlands", "utrecht"); - testCountry(or, 52.15, 7.50, "north rhine-westphalia"); - testCountry(or, 28.8056, 29.9858, "egypt"); + testCountry(or, 53.8820, 27.5726, "belarus", "minsk"); +// testCountry(or, 52.10, 4.92, "the netherlands", "utrecht"); +// testCountry(or, 52.15, 7.50, "north rhine-westphalia"); +// testCountry(or, 28.8056, 29.9858, "egypt"); // testCountry(or, 40.0760, 9.2807, "italy", "sardinia"); - testCountry(or, 35.7521, 139.7887, "japan"); - testCountry(or, 46.5145, 102.2580, "mongolia"); - testCountry(or, 62.54, 43.36, "arkhangelsk oblast", "northwestern federal district"); +// testCountry(or, 35.7521, 139.7887, "japan"); +// testCountry(or, 46.5145, 102.2580, "mongolia"); +// testCountry(or, 62.54, 43.36, "arkhangelsk oblast", "northwestern federal district"); } diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java b/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java index ab6b21fcd4..22121c301d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java @@ -26,7 +26,7 @@ public abstract class MapRenderingTypes { private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class); public static final String[] langs = new String[] { "af", "als", "ar", "az", "be", "bg", "bn", "bpy", "br", "bs", "ca", "ceb", "cs", "cy", "da", "de", "el", "eo", "es", "et", "eu", "fa", "fi", "fr", "fy", "ga", "gl", "he", "hi", "hsb", - "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh" }; + "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh", "zh-hans", "zh-hant", }; public final static byte RESTRICTION_NO_RIGHT_TURN = 1; diff --git a/OsmAnd-telegram/res/values-el/strings.xml b/OsmAnd-telegram/res/values-el/strings.xml index 84862a65ec..ce8aec1832 100644 --- a/OsmAnd-telegram/res/values-el/strings.xml +++ b/OsmAnd-telegram/res/values-el/strings.xml @@ -43,4 +43,14 @@ Επιλογές Ενεργοποιημένο Μονάδες μέτρησης & φορμά + Έξοδος + γδ + πδ + μλ + μαω + Μίλια/πόδια + Μίλια/γιάρδες + Χιλιόμετρα/μέτρα + Αλλαγή απόστασης που μετριέται. + Μονάδες μήκους \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_item_btn_with_icon_and_text.xml b/OsmAnd/res/layout/bottom_sheet_item_btn_with_icon_and_text.xml index 6adcae70ac..82139e9df9 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_btn_with_icon_and_text.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_btn_with_icon_and_text.xml @@ -8,7 +8,7 @@ android:gravity="center_vertical" android:orientation="horizontal"> - + + + + + + + diff --git a/OsmAnd/res/layout/dialog_live_updates_item_settings.xml b/OsmAnd/res/layout/dialog_live_updates_item_settings.xml index 75dbd3b9e4..f51fa41641 100644 --- a/OsmAnd/res/layout/dialog_live_updates_item_settings.xml +++ b/OsmAnd/res/layout/dialog_live_updates_item_settings.xml @@ -121,7 +121,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" - android:text="@string/update" + android:text="@string/shared_string_update" android:textColor="?android:attr/textColorPrimary" android:textSize="16sp"/> diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index f72650603d..08bc07c093 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -2785,7 +2785,7 @@ أسلوب الملاحة مع التباين العالي والحد الأعلى من التفاصيل. يتضمن كل خيارات النمط الافتراضي OsmAnd ، مع عرض أكبر قدر ممكن من التفاصيل ، ولا سيما الطرق والمسارات وطرق السفر الأخرى. التمييز الواضح بين \"جولة الأطلس\" بين أنواع الطرق. مناسبة للاستخدام النهاري والليلي وفي الهواء الطلق. أسلوب الغرض العام. تقديم نظافة مبسطة في المدن المكتظة بالسكان. الملامح الرئيسية: خطوط الكنتور ، والطرق ، وجودة السطح ، والقيود المفروضة على الوصول ، ودروع الطريق ، والمسارات التي تظهر وفقًا لمقياس SAC ، وميزات رياضة الماء الأبيض. قم بتنزيل أدلة السفر هذه من ويكي الرحلات لعرض مقالات حول الأماكن في العالم بدون إنترنت. - دليل السفر حاليا على أساس wikivoyage.اختبار كافة الميزات أثناء اختبار بيتا المفتوحة مجانا.بعد ذلك، وأدلة السفر ستكون متاحة للمشتركين في osmand محدود و اصحاب osmand +. + دليل السفر حاليا على أساس Wikivoyage. اختبار كافة الميزات أثناء اختبار بيتا المفتوحة مجانا.بعد ذلك، وأدلة السفر ستكون متاحة للمشتركين في osmand غير المحدود و اصحاب +osmand. ملف GPX مع الإحداثيات والبيانات من الملاحظات المحددة. ملف GPX مع الإحداثيات والبيانات من كافة الملاحظات. + Straight to point routing + + • Profiles: now you can change order, set icon for map, change all setting for base profiles and restore them back to defaults\n\n + • Added exit number in the navigation\n\n + • Reworked plugin settings\n\n + • Reworked Settings screen for quick access to all profiles\n\n + • Added option to copy settings from another profile\n\n + • Added ability to change an order or hide POI categories in Search\n\n + • Correctly aligned POI icons on the map\n\n + • Added Sunset / Sunrise data to Configure Map\n\n + • Added Home/Work icons on the map\n\n + • Added support for multiline description in Settings\n\n + • Added correct transliteration into the map of Japan\n\n + • Added Antarctica map\n\n + + Copy coordinates Reset to default will reset sort order to the default state after installation. Use system screen timeout Disabled by default, if OsmAnd running on foreground, the screen doesn’t time out.\n\nIf enabled OsmAnd will use system timeout settings. @@ -3380,7 +3396,6 @@ Use menu Dashboard or menu control A choice is offered to primarily control the app via the flexible dashboard or a static menu. Your choice can always be changed in the dashboard settings. - Update Only download on Wi-Fi Live update Update now diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 4598765a46..9f0a4c4add 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -56,7 +56,6 @@ import android.widget.TextView; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.download.DownloadActivity; import net.osmand.util.Algorithms; import java.io.File; @@ -264,6 +263,17 @@ public class AndroidUtils { lightNormal, lightChecked, darkNormal, darkChecked); } + public static ColorStateList createEnabledColorStateList(Context ctx, @ColorRes int normal, @ColorRes int pressed) { + return createEnabledColorStateList(ctx, false, normal, pressed, 0, 0); + } + + public static ColorStateList createEnabledColorStateList(Context ctx, boolean night, + @ColorRes int lightNormal, @ColorRes int lightPressed, + @ColorRes int darkNormal, @ColorRes int darkPressed) { + return createColorStateList(ctx, night, android.R.attr.state_enabled, + lightNormal, lightPressed, darkNormal, darkPressed); + } + public static ColorStateList createPressedColorStateList(Context ctx, @ColorRes int normal, @ColorRes int pressed) { return createPressedColorStateList(ctx, false, normal, pressed, 0, 0); } diff --git a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java index b207bd853c..74166b9ec9 100644 --- a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java +++ b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java @@ -184,6 +184,13 @@ public class ConnectedApp implements Comparable { TextInfoWidget createWidgetControl(final MapActivity mapActivity, final String widgetId) { TextInfoWidget control = new TextInfoWidget(mapActivity) { + + private boolean init = true; + private String cachedTxt; + private String cachedSubtext; + private Boolean cachedNight; + private Integer cachedIcon; + @Override public boolean updateInfo(OsmandMapLayer.DrawSettings drawSettings) { AidlMapWidgetWrapper widget = widgets.get(widgetId); @@ -192,15 +199,28 @@ public class ConnectedApp implements Comparable { String subtext = widget.getDescription(); boolean night = drawSettings != null && drawSettings.isNightMode(); int icon = AndroidUtils.getDrawableId(mapActivity.getMyApplication(), night ? widget.getDarkIconName() : widget.getLightIconName()); - setText(txt, subtext); - if (icon != 0) { - setImageDrawable(icon); - } else { - setImageDrawable(null); + if (init || !Algorithms.objectEquals(txt, cachedTxt) || !Algorithms.objectEquals(subtext, cachedSubtext) + || !Algorithms.objectEquals(night, cachedNight) || !Algorithms.objectEquals(icon, cachedIcon)) { + init = false; + cachedTxt = txt; + cachedSubtext = subtext; + cachedNight = night; + cachedIcon = icon; + + setText(txt, subtext); + if (icon != 0) { + setImageDrawable(icon); + } else { + setImageDrawable(null); + } + return true; } + return false; + } else { + setText(null, null); + setImageDrawable(null); return true; } - return false; } }; control.updateInfo(null); diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index ce7bb80b77..cff34c8eec 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -107,7 +107,7 @@ public class AppInitializer implements IProgress { private static final String VERSION_INSTALLED = "VERSION_INSTALLED"; //$NON-NLS-1$ private static final String EXCEPTION_FILE_SIZE = "EXCEPTION_FS"; //$NON-NLS-1$ - public static final String LATEST_CHANGES_URL = "https://osmand.net/blog/osmand-3-5-released"; + public static final String LATEST_CHANGES_URL = "https://osmand.net/blog/osmand-3-6-released"; // public static final String LATEST_CHANGES_URL = null; // not enough to read public static final int APP_EXIT_CODE = 4; public static final String APP_EXIT_KEY = "APP_EXIT_KEY"; @@ -567,7 +567,7 @@ public class AppInitializer implements IProgress { return null; } }); - app.regions.setLocale(app.getLanguage()); + app.regions.setLocale(app.getLanguage(), app.getCountry()); } diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index 71a255bae4..743b79f472 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -1,16 +1,32 @@ package net.osmand.plus; +import android.Manifest; import android.app.Activity; -import android.location.GnssNavigationMessage; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.hardware.GeomagneticField; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.location.GnssStatus; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.GpsStatus.Listener; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v7.app.AlertDialog; +import android.util.Log; import net.osmand.GeoidAltitudeCorrection; import net.osmand.PlatformUtil; @@ -22,31 +38,16 @@ import net.osmand.data.LatLon; import net.osmand.data.QuadPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.routing.RoutingHelper.RouteSegmentSearchResult; import net.osmand.router.RouteSegmentResult; import net.osmand.util.MapUtils; -import android.Manifest; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.hardware.GeomagneticField; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.location.GpsSatellite; -import android.location.GpsStatus; -import android.location.GpsStatus.Listener; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.support.annotation.Nullable; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AlertDialog; -import android.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; public class OsmAndLocationProvider implements SensorEventListener { @@ -146,30 +147,17 @@ public class OsmAndLocationProvider implements SensorEventListener { this.roads = roads; startLocation = new net.osmand.Location(currentLocation); long ms = System.currentTimeMillis(); - if (ms - startLocation.getTime() > 5000 || - ms < startLocation.getTime()) { + if (ms - startLocation.getTime() > 5000 || ms < startLocation.getTime()) { startLocation.setTime(ms); } - currentRoad = -1; - int px = MapUtils.get31TileNumberX(currentLocation.getLongitude()); - int py = MapUtils.get31TileNumberY(currentLocation.getLatitude()); - double dist = 1000; - for (int i = 0; i < roads.size(); i++) { - RouteSegmentResult road = roads.get(i); - boolean plus = road.getStartPointIndex() < road.getEndPointIndex(); - for (int j = road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) { - RouteDataObject obj = road.getObject(); - QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j - 1), obj.getPoint31YTile(j - 1), - obj.getPoint31XTile(j), obj.getPoint31YTile(j)); - double dd = MapUtils.squareRootDist31((int) proj.x, (int) proj.y, px, py); - if (dd < dist) { - dist = dd; - currentRoad = i; - currentSegment = j; - currentPoint = proj; - } - j += plus ? 1 : -1; - } + RouteSegmentSearchResult searchResult = + RoutingHelper.searchRouteSegment(currentLocation.getLatitude(), currentLocation.getLongitude(), -1, roads); + if (searchResult != null) { + currentRoad = searchResult.getRoadIndex(); + currentSegment = searchResult.getSegmentIndex(); + currentPoint = searchResult.getPoint(); + } else { + currentRoad = -1; } } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 9fea8ac65a..7f729ca523 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -775,6 +775,16 @@ public class OsmandApplication extends MultiDexApplication { } } } + + public String getCountry() { + String country; + if (preferredLocale != null) { + country = preferredLocale.getCountry(); + } else { + country = Locale.getDefault().getCountry(); + } + return country; + } public String getLanguage() { String lang; diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index e55bf36d49..4a8540f633 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -1261,7 +1261,7 @@ public class OsmandSettings { public final CommonPreference WIKI_ARTICLE_SHOW_IMAGES = new EnumIntPreference<>("wikivoyage_show_imgs", WikiArticleShowImages.OFF, WikiArticleShowImages.values()).makeGlobal(); public final CommonPreference SELECT_MARKER_ON_SINGLE_TAP = new BooleanPreference("select_marker_on_single_tap", false).makeProfile(); - public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference("keep_passed_markers_on_map", false).makeProfile(); + public final CommonPreference KEEP_PASSED_MARKERS_ON_MAP = new BooleanPreference("keep_passed_markers_on_map", true).makeProfile(); public final CommonPreference COORDS_INPUT_USE_RIGHT_SIDE = new BooleanPreference("coords_input_use_right_side", true).makeGlobal(); public final OsmandPreference COORDS_INPUT_FORMAT = new EnumIntPreference<>("coords_input_format", Format.DD_MM_MMM, Format.values()).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/SettingsHelper.java index 4c75032ce0..ddbcd94dea 100644 --- a/OsmAnd/src/net/osmand/plus/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/SettingsHelper.java @@ -906,6 +906,7 @@ public class SettingsHelper { private File file; private String latestChanges; + private boolean askBeforeImport; private int version; private SettingsImportListener listener; @@ -915,11 +916,13 @@ public class SettingsHelper { private SettingsItem currentItem; private AlertDialog dialog; - ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) { + ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, boolean askBeforeImport, + @Nullable SettingsImportListener listener) { this.file = settingsFile; this.listener = listener; this.latestChanges = latestChanges; this.version = version; + this.askBeforeImport = askBeforeImport; importer = new SettingsImporter(app); } @@ -992,7 +995,7 @@ public class SettingsHelper { break; } } else { - if (item.getType() == SettingsItemType.PROFILE) { + if (item.getType() == SettingsItemType.PROFILE && askBeforeImport) { String title = activity.getString(R.string.add_new_profile_q, item.getPublicName(app)); dialog = showConfirmDialog(item, title, latestChanges); } else { @@ -1128,8 +1131,9 @@ public class SettingsHelper { } } - public void importSettings(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) { - new ImportAsyncTask(settingsFile, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + public void importSettings(@NonNull File settingsFile, String latestChanges, int version, + boolean askBeforeImport, @Nullable SettingsImportListener listener) { + new ImportAsyncTask(settingsFile, latestChanges, version, askBeforeImport, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } public void exportSettings(@NonNull File fileDir, @NonNull String fileName, diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 909fac0b92..8de45d0011 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -26,6 +26,7 @@ import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentManager.BackStackEntry; import android.support.v4.content.ContextCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AlertDialog; @@ -136,6 +137,7 @@ import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab; import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType; import net.osmand.plus.settings.BaseSettingsFragment; import net.osmand.plus.settings.BaseSettingsFragment.SettingsScreenType; +import net.osmand.plus.settings.ConfigureProfileFragment; import net.osmand.plus.settings.DataStorageFragment; import net.osmand.plus.settings.ProfileAppearanceFragment; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; @@ -2509,6 +2511,17 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return getFragment(QuickActionListFragment.TAG); } + public void backToConfigureProfileFragment() { + FragmentManager fragmentManager = getSupportFragmentManager(); + int backStackEntryCount = fragmentManager.getBackStackEntryCount(); + if (backStackEntryCount > 0) { + BackStackEntry entry = fragmentManager.getBackStackEntryAt(backStackEntryCount - 1); + if (ConfigureProfileFragment.TAG.equals(entry.getName())) { + fragmentManager.popBackStack(); + } + } + } + T getFragment(String fragmentTag){ Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag); return fragment != null && !fragment.isDetached() && !fragment.isRemoving() ? (T) fragment : null; diff --git a/OsmAnd/src/net/osmand/plus/activities/actions/ShareDialog.java b/OsmAnd/src/net/osmand/plus/activities/actions/ShareDialog.java index 45371aef6e..475286525c 100644 --- a/OsmAnd/src/net/osmand/plus/activities/actions/ShareDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/actions/ShareDialog.java @@ -216,7 +216,7 @@ public class ShareDialog { public static void sendToClipboard(Activity activity, String text) { ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE); clipboard.setText(text); - Toast.makeText(activity, R.string.copied_to_clipboard, Toast.LENGTH_LONG) + Toast.makeText(activity, activity.getString(R.string.copied_to_clipboard) + "\n" + text, Toast.LENGTH_LONG) .show(); } } diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index ef138846b8..5b3d0d0b83 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -1041,22 +1041,22 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo public boolean onBackPressed() { if (isVisible()) { - return backPressed(); + backPressed(); + return true; } return false; } - private boolean backPressed() { + private void backPressed() { if (previousVisibleType != visibleType && previousVisibleType != null) { if (visibleType == DashboardType.MAPILLARY) { hideKeyboard(); } visibleType = null; setDashboardVisibility(true, previousVisibleType); - return true; } else { hideDashboard(); - return false; + mapActivity.backToConfigureProfileFragment(); } } diff --git a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java index 7808406222..a17eabae3c 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestVoiceActivity.java @@ -169,10 +169,12 @@ public class TestVoiceActivity extends OsmandActionBarActivity { addButton(ll, "\u25BA (3.4) After 3100m turn right onto 'SR 80' toward 'Rome'", builder(p).prepareTurn(AbstractPrologCommandPlayer.A_RIGHT, 3100, street(p, "SR 80", "", "Rome"))); addButton(ll, "\u25BA (3.5) In 370m turn slightly right onto 'Route 23' 'Main Street', then bear left", builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SL, 370, street(p, "Route 23", "Main Street", "")).then().bearLeft(street(p, ""))); addButton(ll, "\u25BA (3.6) Turn sharply right onto 'Dr.-Quinn-Stra"+"\u00df"+"e'", builder(p).turn(AbstractPrologCommandPlayer.A_RIGHT_SH, street(p, "", "Dr.-Quinn-Straße", ""))); - addButton(ll, "\u25BA (3.7) Turn slightly right to exit 6 onto 'Amsterdam-Osdorp'", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, "6", 6, street(p, "", "Amsterdam-Osdorp", ""))); - addButton(ll, "\u25BA (3.8) In 350m turn slightly right to exit 6 onto 'Amsterdam-Osdorp'", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, 350, "6", 6, street(p, "", "Amsterdam-Osdorp", ""))); - addButton(ll, "\u25BA (3.9) Turn slightly right to exit 260B ", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, "260 B", 260, street(p, "", "", ""))); - addButton(ll, "\u25BA (3.10) Turn slightly left to exit 15B ", builder(p).takeExit(AbstractPrologCommandPlayer.A_LEFT_SL, "15 B", 15, street(p, "", "", ""))); + addButton(ll, "\u25BA (3.7) Turn slightly right onto exit 6 onto 'Amsterdam-Osdorp'", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, "6", 6, street(p, "", "Amsterdam-Osdorp", ""))); + addButton(ll, "\u25BA (3.8) In 350m turn slightly right onto exit 6, 'Amsterdam-Osdorp'", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, 350, "6", 6, street(p, "", "Amsterdam-Osdorp", ""))); + addButton(ll, "\u25BA (3.9) In 350m turn slightly right onto exit 6, 'Amsterdam-Osdorp' towards Osdorp", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, 350, "6", 6, street(p, "", "Amsterdam-Osdorp", "Osdorp"))); + addButton(ll, "\u25BA (3.10) In 350m turn slightly right to exit 6 towards 'Osdorp'", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, 350, "6", 6, street(p, "", "", "Osdorp"))); + addButton(ll, "\u25BA (3.11) Turn slightly right to exit 260B ", builder(p).takeExit(AbstractPrologCommandPlayer.A_RIGHT_SL, "260 B", 260, street(p, "", "", ""))); + addButton(ll, "\u25BA (3.12) Turn slightly left to exit 15B ", builder(p).takeExit(AbstractPrologCommandPlayer.A_LEFT_SL, "15 B", 15, street(p, "", "", ""))); addButton(ll, "Keep left/right: prepareTurn, makeTurnIn, turn:", builder(p)); addButton(ll, "\u25BA (4.1) After 1810m keep left ' '", builder(p).prepareTurn(AbstractPrologCommandPlayer.A_LEFT_KEEP, 1810, street(p, ""))); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/WhatsNewDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/WhatsNewDialogFragment.java index be0597a633..f7d697444b 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/WhatsNewDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/WhatsNewDialogFragment.java @@ -28,7 +28,7 @@ public class WhatsNewDialogFragment extends DialogFragment { final OsmandApplication osmandApplication = (OsmandApplication) getActivity().getApplication(); final String appVersion = Version.getAppVersion(osmandApplication); builder.setTitle(getString(R.string.whats_new) + " " + appVersion) - .setMessage(getString(R.string.release_3_5)) + .setMessage(getString(R.string.release_3_6)) .setNegativeButton(R.string.shared_string_close, null); if (AppInitializer.LATEST_CHANGES_URL != null) { builder.setPositiveButton(R.string.read_more, new DialogInterface.OnClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index f2c1626c31..f829e35ee2 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -161,7 +161,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download dialog.setTitle(R.string.update_all_maps); dialog.setMessage(getString(R.string.update_all_maps_q, indexItems.size())); dialog.setNegativeButton(R.string.shared_string_cancel, null); - dialog.setPositiveButton(R.string.update, new DialogInterface.OnClickListener() { + dialog.setPositiveButton(R.string.shared_string_update, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getMyActivity().startDownload(indexItems.toArray(new IndexItem[indexItems.size()])); diff --git a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java index bee1b4fdf4..d8cc1f4def 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java +++ b/OsmAnd/src/net/osmand/plus/helpers/AvoidSpecificRoads.java @@ -23,6 +23,8 @@ import net.osmand.ResultMatcher; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.QuadPoint; +import net.osmand.data.RotatedTileBox; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -31,15 +33,20 @@ import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.routing.RoutingHelper.RouteSegmentSearchResult; import net.osmand.plus.views.ContextMenuLayer; +import net.osmand.router.RouteSegmentResult; import net.osmand.util.MapUtils; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; public class AvoidSpecificRoads { + private static final float MAX_AVOID_ROUTE_SEARCH_RADIUS_DP = 32f; + private OsmandApplication app; private Map impassableRoads = new LinkedHashMap<>(); @@ -206,7 +213,7 @@ public class AvoidSpecificRoads { }); } - public void addImpassableRoad(@Nullable final MapActivity activity, + public void addImpassableRoad(@Nullable final MapActivity mapActivity, @NonNull final LatLon loc, final boolean showDialog, final boolean skipWritingSettings) { @@ -215,16 +222,34 @@ public class AvoidSpecificRoads { ll.setLongitude(loc.getLongitude()); ApplicationMode appMode = app.getRoutingHelper().getAppMode(); + List roads = app.getRoutingHelper().getRoute().getOriginalRoute(); + if (mapActivity != null && roads != null) { + RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); + float maxDistPx = MAX_AVOID_ROUTE_SEARCH_RADIUS_DP * tb.getDensity(); + RouteSegmentSearchResult searchResult = + RoutingHelper.searchRouteSegment(loc.getLatitude(), loc.getLongitude(), maxDistPx / tb.getPixDensity(), roads); + if (searchResult != null) { + QuadPoint point = searchResult.getPoint(); + LatLon newLoc = new LatLon(MapUtils.get31LatitudeY((int) point.y), MapUtils.get31LongitudeX((int) point.x)); + ll.setLatitude(newLoc.getLatitude()); + ll.setLongitude(newLoc.getLongitude()); + addImpassableRoadInternal(roads.get(searchResult.getRoadIndex()).getObject(), ll, showDialog, mapActivity, newLoc); + if (!skipWritingSettings) { + app.getSettings().addImpassableRoad(newLoc.getLatitude(), newLoc.getLongitude()); + } + return; + } + } app.getLocationProvider().getRouteSegment(ll, appMode, false, new ResultMatcher() { @Override public boolean publish(RouteDataObject object) { if (object == null) { - if (activity != null) { - Toast.makeText(activity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show(); + if (mapActivity != null) { + Toast.makeText(mapActivity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show(); } } else { - addImpassableRoadInternal(object, ll, showDialog, activity, loc); + addImpassableRoadInternal(object, ll, showDialog, mapActivity, loc); } return true; } @@ -299,7 +324,7 @@ public class AvoidSpecificRoads { showDialog(activity); } MapContextMenu menu = activity.getContextMenu(); - if (menu.isActive() && menu.getLatLon().equals(loc)) { + if (menu.isActive()) { menu.close(); } activity.refreshMap(); diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index 44adb57ca9..ecdfdf49aa 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -182,7 +182,7 @@ public class ImportHelper { } else if (fileName != null && fileName.endsWith(IndexConstants.SQLITE_EXT)) { handleSqliteTileImport(intentUri, fileName); } else if (fileName != null && fileName.endsWith(OSMAND_SETTINGS_FILE_EXT)) { - handleOsmAndSettingsImport(intentUri, fileName, extras, null); + handleOsmAndSettingsImport(intentUri, fileName, extras, true, null); } else if (fileName != null && fileName.endsWith(ROUTING_FILE_EXT)) { handleRoutingFileImport(intentUri, fileName, null); } else { @@ -606,7 +606,7 @@ public class ImportHelper { }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) { + public void chooseFileToImport(final ImportType importType, final boolean askBeforeImport, final CallbackWithObject callback) { final MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { return; @@ -644,7 +644,7 @@ public class ImportHelper { if (fileName.endsWith(importType.getExtension())) { if (importType.equals(ImportType.SETTINGS)) { - handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), callback); + handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), askBeforeImport, callback); } else if (importType.equals(ImportType.ROUTING)){ handleRoutingFileImport(data, fileName, callback); } @@ -733,20 +733,19 @@ public class ImportHelper { } } - private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, - CallbackWithObject> callback) { + private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, boolean askBeforeImport, CallbackWithObject> callback) { if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); - handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); + handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, askBeforeImport, callback); } else { - handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); + handleOsmAndSettingsImport(intentUri, fileName, null, -1, askBeforeImport, callback); } } @SuppressLint("StaticFieldLeak") - private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, - final CallbackWithObject> callback) { + private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, + final boolean askBeforeImport, final CallbackWithObject> callback) { final AsyncTask settingsImportTask = new AsyncTask() { ProgressDialog progress; @@ -771,7 +770,7 @@ public class ImportHelper { File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); File file = new File(tempDir, name); if (error == null && file.exists()) { - app.getSettingsHelper().importSettings(file, latestChanges, version, new SettingsImportListener() { + app.getSettingsHelper().importSettings(file, latestChanges, version, askBeforeImport, new SettingsImportListener() { @Override public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List items) { if (isActivityNotDestroyed(activity)) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java index 957468c8de..84b444490a 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java @@ -9,6 +9,9 @@ import android.support.v4.view.ViewCompat; import android.widget.Toast; import net.osmand.data.LatLon; +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.actions.ShareDialog; @@ -33,6 +36,7 @@ public class ShareMenu extends BaseMenuController { MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send), CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy), NAME(R.drawable.ic_action_copy, R.string.copy_location_name), + COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates), GEO(R.drawable.ic_world_globe_dark, R.string.share_geo), QR_CODE(R.drawable.ic_action_qrcode, R.string.shared_string_qr_code); @@ -62,6 +66,7 @@ public class ShareMenu extends BaseMenuController { list.add(ShareItem.MESSAGE); list.add(ShareItem.CLIPBOARD); list.add(ShareItem.NAME); + list.add(ShareItem.COORDINATES); list.add(ShareItem.GEO); list.add(ShareItem.QR_CODE); return list; @@ -124,6 +129,12 @@ public class ShareMenu extends BaseMenuController { Toast.LENGTH_LONG).show(); } break; + case COORDINATES: + OsmandSettings st = ((OsmandApplication) mapActivity.getApplicationContext()).getSettings(); + int f = st.COORDINATES_FORMAT.get(); + ShareDialog.sendToClipboard(mapActivity, + OsmAndFormatter.getFormattedCoordinates(latLon.getLatitude(), latLon.getLongitude(), f)); + break; case GEO: Intent mapIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUrl)); mapActivity.startActivity(mapIntent); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java index 409eb695ea..cabf945875 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/MonitoringSettingsFragment.java @@ -9,7 +9,6 @@ import android.support.v7.preference.Preference; import android.text.SpannableString; import android.text.SpannableStringBuilder; -import net.osmand.AndroidUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndAppCustomization; import net.osmand.plus.OsmandPlugin; @@ -222,7 +221,7 @@ public class MonitoringSettingsFragment extends BaseSettingsFragment private void setupLiveMonitoringPref() { Drawable disabled = getContentIcon(R.drawable.ic_action_offline); Drawable enabled = getActiveIcon(R.drawable.ic_world_globe_dark); - Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + Drawable icon = getPersistentPrefIcon(enabled, disabled); SwitchPreferenceEx liveMonitoring = (SwitchPreferenceEx) findPreference(settings.LIVE_MONITORING.getId()); liveMonitoring.setDescription(getString(R.string.live_monitoring_m_descr)); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java index 4b37a68d6e..3a4c67b1fb 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingFragment.java @@ -12,7 +12,6 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; -import net.osmand.AndroidUtils; import net.osmand.plus.OsmAndAppCustomization; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -71,7 +70,7 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer private void setupOfflineEditingPref() { Drawable disabled = getContentIcon(R.drawable.ic_action_offline); Drawable enabled = getActiveIcon(R.drawable.ic_world_globe_dark); - Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + Drawable icon = getPersistentPrefIcon(enabled, disabled); SwitchPreferenceEx offlineEditingPref = (SwitchPreferenceEx) findPreference(settings.OFFLINE_EDITION.getId()); offlineEditingPref.setDescription(getString(R.string.offline_edition_descr)); diff --git a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java index b7c3759003..f051507c2f 100644 --- a/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java +++ b/OsmAnd/src/net/osmand/plus/parkingpoint/ParkingPositionPlugin.java @@ -443,7 +443,7 @@ public class ParkingPositionPlugin extends OsmandPlugin { net.osmand.Location.distanceBetween(view.getLatitude(), view.getLongitude(), parkingPoint.getLatitude(), parkingPoint.getLongitude(), calculations); d = (int) calculations[0]; } - if (distChanged(cachedMeters, d)) { + if (isUpdateNeeded() || distChanged(cachedMeters, d)) { cachedMeters = d; if (cachedMeters <= 20) { cachedMeters = 0; @@ -465,8 +465,13 @@ public class ParkingPositionPlugin extends OsmandPlugin { return true; } return false; - } - + } + + @Override + public boolean isMetricSystemDepended() { + return true; + } + /** * Utility method. * @param oldDist diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java index 9d0bf40a12..2402506548 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java @@ -1,8 +1,9 @@ package net.osmand.plus.profiles; import android.support.annotation.ColorRes; +import android.support.annotation.NonNull; -public class ProfileDataObject { +public class ProfileDataObject implements Comparable { private String name; private String description; @@ -47,4 +48,9 @@ public class ProfileDataObject { @ColorRes public int getIconColor(boolean isNightMode) { return iconColor.getColor(isNightMode); } + + @Override + public int compareTo(@NonNull ProfileDataObject another) { + return this.name.compareToIgnoreCase(another.name); + } } diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java index 27b7c3eb65..d0166a7c33 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java @@ -1,7 +1,6 @@ package net.osmand.plus.profiles; import android.app.Activity; -import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; @@ -11,18 +10,20 @@ import android.support.v4.app.FragmentManager; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.widget.CompoundButton; import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; import net.osmand.CallbackWithObject; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.SettingsHelper.*; +import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; -import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; -import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; @@ -36,7 +37,6 @@ import java.util.ArrayList; import java.util.List; import static net.osmand.plus.helpers.ImportHelper.ImportType.ROUTING; -import static net.osmand.plus.helpers.ImportHelper.ImportType.SETTINGS; public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { @@ -68,14 +68,7 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo if (args != null && args.get(DIALOG_TYPE) != null) { type = args.getString(DIALOG_TYPE); selectedItemKey = args.getString(SELECTED_KEY, null); - if (type.equals(TYPE_NAV_PROFILE)) { - profiles.addAll(NavigationFragment.getRoutingProfiles(app).values()); - } else if (type.equals(TYPE_BASE_APP_PROFILE)) { - profiles.addAll(NavigationFragment.getBaseProfiles(app)); - } else { - LOG.error("Check intent data!"); - dismiss(); - } + refreshProfiles(app); } } @@ -89,22 +82,11 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo dismiss(); } }); - - if (type.equals(TYPE_NAV_PROFILE) || type.equals(TYPE_BASE_APP_PROFILE)) { - for (BaseBottomSheetItem item : items) { - View bottomDivider = item.getView().findViewById(R.id.divider_bottom); - if (bottomDivider != null) { - bottomDivider.setVisibility(View.INVISIBLE); - } - } - } } @Override public void createMenuItems(Bundle savedInstanceState) { - int activeColorRes = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; - int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; - OsmandApplication app = getMyApplication(); + OsmandApplication app = requiredMyApplication(); View bottomSpaceView = new View(app); int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top); @@ -114,154 +96,173 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo items.add(new TitleItem(getString(R.string.select_base_profile_dialog_title))); items.add(new LongDescriptionItem(getString(R.string.select_base_profile_dialog_message))); for (int i = 0; i < profiles.size(); i++) { - final int pos = i; - final ProfileDataObject profile = profiles.get(i); - final boolean isSelected = profile.getStringKey().equals(selectedItemKey); - final Drawable drawableIcon; - if (isSelected) { - drawableIcon = getMyApplication().getUIUtilities() - .getIcon(profile.getIconRes(), activeColorRes); - } else { - drawableIcon = getMyApplication().getUIUtilities() - .getIcon(profile.getIconRes(), R.color.icon_color_default_light); - } - - items.add(new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(activeColorRes) - .setChecked(isSelected) - .setButtonTintList(isSelected - ? ColorStateList.valueOf(getResolvedColor(getActiveColorId())) - : null) - .setDescription(profile.getDescription()) - .setTitle(profile.getName()) - .setIcon(drawableIcon) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_radio_btn) - .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (listener == null) { - getListener(); - } - Bundle args = new Bundle(); - args.putString(PROFILE_KEY_ARG, profile.getStringKey()); - listener.onSelectedType(args); - dismiss(); - } - }) - .create()); + ProfileDataObject profile = profiles.get(i); + addProfileItem(profile, false); } - items.add(new DividerItem(app)); - items.add(new SimpleBottomSheetItem.Builder() - .setTitle(app.getString(R.string.import_from_file)) - .setIcon(app.getUIUtilities().getIcon(R.drawable.ic_action_folder, iconDefaultColorResId)) - .setLayoutId(R.layout.bottom_sheet_item_simple) - .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity == null) { - return; - } - mapActivity.getImportHelper().chooseFileToImport(SETTINGS, new CallbackWithObject>() { - @Override - public boolean processResult(List result) { - for (SettingsItem item : result) { - if (SettingsItemType.PROFILE.equals(item.getType())) { - if (listener == null) { - getListener(); - } - Bundle args = new Bundle(); - args.putString(PROFILE_KEY_ARG, item.getName()); - args.putBoolean(IS_PROFILE_IMPORTED_ARG, true); - listener.onSelectedType(args); - dismiss(); - break; - } - } - return false; - } - }); + /*items.add(new DividerItem(app)); + addButtonItem(R.string.import_from_file, R.drawable.ic_action_folder, new OnClickListener() { + + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity == null) { + return; } - }) - .create()); + mapActivity.getImportHelper().chooseFileToImport(SETTINGS, false, + new CallbackWithObject>() { + @Override + public boolean processResult(List result) { + for (SettingsItem item : result) { + if (SettingsItemType.PROFILE.equals(item.getType())) { + if (listener == null) { + getListener(); + } + Bundle args = new Bundle(); + args.putString(PROFILE_KEY_ARG, item.getName()); + args.putBoolean(IS_PROFILE_IMPORTED_ARG, true); + listener.onSelectedType(args); + dismiss(); + break; + } + } + return false; + } + }); + } + }); items.add(new BaseBottomSheetItem.Builder() .setCustomView(bottomSpaceView) - .create()); + .create());*/ - } else if (type.equals(TYPE_NAV_PROFILE)){ + } else if (type.equals(TYPE_NAV_PROFILE)) { items.add(new TitleItem(getString(R.string.select_nav_profile_dialog_title))); items.add(new LongDescriptionItem(getString(R.string.select_nav_profile_dialog_message))); for (int i = 0; i < profiles.size(); i++) { - final ProfileDataObject profile = profiles.get(i); - final boolean isSelected = profile.getStringKey().equals(selectedItemKey); - final Drawable drawableIcon; - if (isSelected) { - drawableIcon = getMyApplication().getUIUtilities() - .getIcon(profile.getIconRes(), activeColorRes); - } else { - drawableIcon = getMyApplication().getUIUtilities() - .getIcon(profile.getIconRes(), R.color.icon_color_default_light); + final RoutingProfileDataObject profile = (RoutingProfileDataObject) profiles.get(i); + boolean showBottomDivider = false; + if (i < profiles.size() - 1) { + RoutingProfileDataObject nextProfile = (RoutingProfileDataObject) profiles.get(i + 1); + if (profile.getFileName() == null) { + showBottomDivider = nextProfile.getFileName() != null; + } else { + showBottomDivider = !profile.getFileName().equals(nextProfile.getFileName()); + } } - - items.add(new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(activeColorRes) - .setChecked(isSelected) - .setButtonTintList(isSelected - ? ColorStateList.valueOf(getResolvedColor(getActiveColorId())) - : null) - .setDescription(profile.getDescription()) - .setTitle(profile.getName()) - .setIcon(drawableIcon) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_radio_btn) - .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (listener == null) { - getListener(); - } - Bundle args = new Bundle(); - args.putString(PROFILE_KEY_ARG, profile.getStringKey()); - listener.onSelectedType(args); - dismiss(); - } - }) - .create()); + addProfileItem(profile, showBottomDivider); } items.add(new DividerItem(app)); items.add(new LongDescriptionItem(app.getString(R.string.osmand_routing_promo))); - items.add(new SimpleBottomSheetItem.Builder() - .setTitle(app.getString(R.string.import_routing_file)) - .setIcon(app.getUIUtilities().getIcon(R.drawable.ic_action_folder, iconDefaultColorResId)) - .setLayoutId(R.layout.bottom_sheet_item_simple) - .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity == null) { - return; - } - mapActivity.getImportHelper().chooseFileToImport(ROUTING, new CallbackWithObject() { + addButtonItem(R.string.import_routing_file, R.drawable.ic_action_folder, new OnClickListener() { + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity == null) { + return; + } + mapActivity.getImportHelper().chooseFileToImport(ROUTING, false, + new CallbackWithObject() { @Override public boolean processResult(String profileKey) { - if (listener == null) { - getListener(); - } - Bundle args = new Bundle(); - args.putString(PROFILE_KEY_ARG, profileKey); - args.putBoolean(IS_PROFILE_IMPORTED_ARG, true); - listener.onSelectedType(args); - dismiss(); + refreshView(); return false; } }); - } - }) - .create()); + } + }); items.add(new BaseBottomSheetItem.Builder() .setCustomView(bottomSpaceView) .create()); } } + + private void addProfileItem(final ProfileDataObject profile, boolean showBottomDivider) { + OsmandApplication app = requiredMyApplication(); + + int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; + int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + + View itemView = View.inflate(getContext(), R.layout.bottom_sheet_item_with_descr_and_radio_btn, null); + TextView tvTitle = itemView.findViewById(R.id.title); + TextView tvDescription = itemView.findViewById(R.id.description); + ImageView ivIcon = itemView.findViewById(R.id.icon); + CompoundButton compoundButton = itemView.findViewById(R.id.compound_button); + View bottomDivider = itemView.findViewById(R.id.divider_bottom); + + tvTitle.setText(profile.getName()); + tvDescription.setText(profile.getDescription()); + + final boolean isSelected = profile.getStringKey().equals(selectedItemKey); + final Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(), + isSelected ? activeColorResId : iconDefaultColorResId); + ivIcon.setImageDrawable(drawableIcon); + compoundButton.setChecked(isSelected); + UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL); + bottomDivider.setVisibility(showBottomDivider ? View.VISIBLE : View.INVISIBLE); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(itemView) + .setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (listener == null) { + getListener(); + } + Bundle args = new Bundle(); + args.putString(PROFILE_KEY_ARG, profile.getStringKey()); + listener.onSelectedType(args); + dismiss(); + } + }) + .create()); + } + + private void addButtonItem(int titleId, int iconId, OnClickListener listener) { + OsmandApplication app = requiredMyApplication(); + + int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; + + View buttonView = View.inflate(app, R.layout.bottom_sheet_item_preference_btn, null); + TextView tvTitle = buttonView.findViewById(R.id.title); + tvTitle.setText(app.getString(titleId)); + + ImageView ivIcon = buttonView.findViewById(R.id.icon); + ivIcon.setImageDrawable(app.getUIUtilities().getIcon(iconId, activeColorResId)); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(buttonView) + .setOnClickListener(listener) + .create()); + } + + private void refreshProfiles(OsmandApplication app) { + if (type.equals(TYPE_NAV_PROFILE)) { + profiles.addAll(NavigationFragment.getSortedRoutingProfiles(app)); + } else if (type.equals(TYPE_BASE_APP_PROFILE)) { + profiles.addAll(NavigationFragment.getBaseProfiles(app)); + } else { + LOG.error("Check data type!"); + dismiss(); + } + } + + private void refreshView() { + Activity activity = getActivity(); + View mainView = getView(); + refreshProfiles(getMyApplication()); + if (activity != null && mainView != null) { + LinearLayout itemsContainer = (LinearLayout) mainView.findViewById(useScrollableItemsContainer() + ? R.id.scrollable_items_container : R.id.non_scrollable_items_container); + if (itemsContainer != null) { + itemsContainer.removeAllViews(); + } + items.clear(); + createMenuItems(null); + for (BaseBottomSheetItem item : items) { + item.inflate(activity, itemsContainer, nightMode); + } + setupHeightAndBackground(mainView); + } + } private void getListener() { FragmentActivity activity = getActivity(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index ea528de0f8..1e829f7abd 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -1,12 +1,14 @@ package net.osmand.plus.routing; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.ValueHolder; +import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; +import net.osmand.data.QuadPoint; import net.osmand.plus.ApplicationMode; -import net.osmand.GPXUtilities.GPXFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.OsmAndFormatter; @@ -1257,5 +1259,54 @@ public class RoutingHelper { } } + public static class RouteSegmentSearchResult { + private int roadIndex; + private int segmentIndex; + private QuadPoint point; + private RouteSegmentSearchResult(int roadIndex, int segmentIndex, QuadPoint point) { + this.roadIndex = roadIndex; + this.segmentIndex = segmentIndex; + this.point = point; + } + + public int getRoadIndex() { + return roadIndex; + } + + public int getSegmentIndex() { + return segmentIndex; + } + + public QuadPoint getPoint() { + return point; + } + } + + public static RouteSegmentSearchResult searchRouteSegment(double latitude, double longitude, double maxDist, List roads) { + int roadIndex = -1; + int segmentIndex = -1; + QuadPoint point = null; + int px = MapUtils.get31TileNumberX(longitude); + int py = MapUtils.get31TileNumberY(latitude); + double dist = maxDist < 0 ? 1000 : maxDist; + for (int i = 0; i < roads.size(); i++) { + RouteSegmentResult road = roads.get(i); + int startPointIndex = road.getStartPointIndex() < road.getEndPointIndex() ? road.getStartPointIndex() : road.getEndPointIndex(); + int endPointIndex = road.getEndPointIndex() > road.getStartPointIndex() ? road.getEndPointIndex() : road.getStartPointIndex(); + RouteDataObject obj = road.getObject(); + for (int j = startPointIndex + 1; j <= endPointIndex; j++) { + QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j - 1), obj.getPoint31YTile(j - 1), + obj.getPoint31XTile(j), obj.getPoint31YTile(j)); + double dd = MapUtils.squareRootDist31((int) proj.x, (int) proj.y, px, py); + if (dd < dist) { + dist = dd; + roadIndex = i; + segmentIndex = j; + point = proj; + } + } + } + return roadIndex != -1 ? new RouteSegmentSearchResult(roadIndex, segmentIndex, point) : null; + } } diff --git a/OsmAnd/src/net/osmand/plus/settings/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/BaseSettingsFragment.java index d53bb0cd81..322316d88b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/BaseSettingsFragment.java @@ -3,6 +3,7 @@ package net.osmand.plus.settings; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; @@ -18,6 +19,7 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.ViewCompat; import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.ListPreference; @@ -730,7 +732,19 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl protected Drawable getPersistentPrefIcon(@DrawableRes int iconId) { Drawable disabled = UiUtilities.createTintedDrawable(app, iconId, ContextCompat.getColor(app, R.color.icon_color_default_light)); Drawable enabled = UiUtilities.createTintedDrawable(app, iconId, getActiveProfileColor()); - return AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + return getPersistentPrefIcon(enabled, disabled); + } + + protected Drawable getPersistentPrefIcon(Drawable enabled, Drawable disabled) { + Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + + if (Build.VERSION.SDK_INT < 21) { + ColorStateList colorStateList = AndroidUtils.createEnabledColorStateList(app, R.color.icon_color_default_light, getActiveProfileColorRes()); + icon = DrawableCompat.wrap(icon); + DrawableCompat.setTintList(icon, colorStateList); + return icon; + } + return icon; } public SwitchPreferenceCompat createSwitchPreference(OsmandSettings.OsmandPreference b, int title, int summary, int layoutId) { diff --git a/OsmAnd/src/net/osmand/plus/settings/GeneralProfileSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/GeneralProfileSettingsFragment.java index 1eba881215..c9b3959867 100644 --- a/OsmAnd/src/net/osmand/plus/settings/GeneralProfileSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/GeneralProfileSettingsFragment.java @@ -21,7 +21,6 @@ import android.widget.ArrayAdapter; import android.widget.CompoundButton; import android.widget.TextView; -import net.osmand.AndroidUtils; import net.osmand.data.PointDescription; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandSettings; @@ -127,7 +126,7 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment impleme private void setupCenterPositionOnMapPref() { Drawable disabled = getContentIcon(R.drawable.ic_action_display_position_bottom); Drawable enabled = getActiveIcon(R.drawable.ic_action_display_position_center); - Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + Drawable icon = getPersistentPrefIcon(enabled, disabled); SwitchPreferenceCompat centerPositionOnMap = (SwitchPreferenceCompat) findPreference(settings.CENTER_POSITION_ON_MAP.getId()); centerPositionOnMap.setIcon(icon); diff --git a/OsmAnd/src/net/osmand/plus/settings/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/MainSettingsFragment.java index 80ae2ae4ab..8c7c50a435 100644 --- a/OsmAnd/src/net/osmand/plus/settings/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/MainSettingsFragment.java @@ -125,7 +125,7 @@ public class MainSettingsFragment extends BaseSettingsFragment { } else if (IMPORT_PROFILE.equals(prefId)) { final MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { - mapActivity.getImportHelper().chooseFileToImport(SETTINGS, new CallbackWithObject>() { + mapActivity.getImportHelper().chooseFileToImport(SETTINGS, false, new CallbackWithObject>() { @Override public boolean processResult(List result) { diff --git a/OsmAnd/src/net/osmand/plus/settings/NavigationFragment.java b/OsmAnd/src/net/osmand/plus/settings/NavigationFragment.java index b18e8c6bd8..2d37b1970c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/NavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/NavigationFragment.java @@ -8,7 +8,6 @@ import android.support.v7.preference.SwitchPreferenceCompat; import android.view.LayoutInflater; import android.view.View; -import net.osmand.AndroidUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -23,6 +22,8 @@ import net.osmand.router.GeneralRouter; import net.osmand.util.Algorithms; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ public class NavigationFragment extends BaseSettingsFragment { public static final String TAG = NavigationFragment.class.getSimpleName(); public static final String NAVIGATION_TYPE = "navigation_type"; + public static final String OSMAND_NAVIGATION = "osmand_navigation"; private SelectProfileBottomSheetDialogFragment.SelectProfileListener navTypeListener; private Map routingProfileDataObjects; @@ -88,7 +90,7 @@ public class NavigationFragment extends BaseSettingsFragment { private void setupSpeakRoutingAlarmsPref() { Drawable disabled = getContentIcon(R.drawable.ic_action_volume_mute); Drawable enabled = getActiveIcon(R.drawable.ic_action_volume_up); - Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + Drawable icon = getPersistentPrefIcon(enabled, disabled); SwitchPreferenceCompat speakRoutingAlarms = (SwitchPreferenceCompat) findPreference(settings.VOICE_MUTE.getId()); speakRoutingAlarms.setIcon(icon); @@ -155,6 +157,8 @@ public class NavigationFragment extends BaseSettingsFragment { RouteProvider.RouteService routeService; if (profileKey.equals(RoutingProfilesResources.STRAIGHT_LINE_MODE.name())) { routeService = RouteProvider.RouteService.STRAIGHT; + } else if (profileKey.equals(RoutingProfilesResources.STRAIGHT_TO_LINE_MODE.name())){ + routeService = RouteProvider.RouteService.STRAIGHT_TO; } else if (profileKey.equals(RoutingProfilesResources.BROUTER_MODE.name())) { routeService = RouteProvider.RouteService.BROUTER; } else { @@ -164,6 +168,41 @@ public class NavigationFragment extends BaseSettingsFragment { appMode.setRoutingProfile(profileKey); } + public static List getSortedRoutingProfiles(OsmandApplication app) { + List result = new ArrayList<>(); + Map> routingProfilesByFileNames = getRoutingProfilesByFileNames(app); + List fileNames = new ArrayList<>(routingProfilesByFileNames.keySet()); + Collections.sort(fileNames, new Comparator() { + @Override + public int compare(String s, String t1) { + return s.equals(OSMAND_NAVIGATION) ? -1 : t1.equals(OSMAND_NAVIGATION) ? 1 : s.compareToIgnoreCase(t1); + } + }); + for (String fileName : fileNames) { + List routingProfilesFromFile = routingProfilesByFileNames.get(fileName); + if (routingProfilesFromFile != null) { + Collections.sort(routingProfilesFromFile); + result.addAll(routingProfilesFromFile); + } + } + return result; + } + + public static Map> getRoutingProfilesByFileNames(OsmandApplication app) { + Map> result = new HashMap<>(); + for (final RoutingProfileDataObject profile : getRoutingProfiles(app).values()) { + String fileName = profile.getFileName() != null ? profile.getFileName() : OSMAND_NAVIGATION; + if (result.containsKey(fileName)) { + result.get(fileName).add(profile); + } else { + result.put(fileName, new ArrayList() { + { add(profile); } + }); + } + } + return result; + } + public static Map getRoutingProfiles(OsmandApplication context) { Map profilesObjects = new HashMap<>(); profilesObjects.put(RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), new RoutingProfileDataObject( @@ -172,6 +211,12 @@ public class NavigationFragment extends BaseSettingsFragment { context.getString(R.string.special_routing_type), RoutingProfilesResources.STRAIGHT_LINE_MODE.getIconRes(), false, null)); + profilesObjects.put(RoutingProfilesResources.STRAIGHT_TO_LINE_MODE.name(), new RoutingProfileDataObject( + RoutingProfilesResources.STRAIGHT_TO_LINE_MODE.name(), + context.getString(RoutingProfilesResources.STRAIGHT_TO_LINE_MODE.getStringRes()), + context.getString(R.string.special_routing_type), + RoutingProfilesResources.STRAIGHT_TO_LINE_MODE.getIconRes(), + false, null)); if (context.getBRouterService() != null) { profilesObjects.put(RoutingProfilesResources.BROUTER_MODE.name(), new RoutingProfileDataObject( RoutingProfilesResources.BROUTER_MODE.name(), diff --git a/OsmAnd/src/net/osmand/plus/settings/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/RouteParametersFragment.java index 7c79ff8e9f..43ff4efddc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/RouteParametersFragment.java @@ -9,7 +9,6 @@ import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceViewHolder; import android.widget.ImageView; -import net.osmand.AndroidUtils; import net.osmand.StateChangedListener; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; @@ -391,7 +390,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP case GeneralRouter.ALLOW_MOTORWAYS: Drawable disabled = getContentIcon(R.drawable.ic_action_avoid_motorways); Drawable enabled = getActiveIcon(R.drawable.ic_action_motorways); - return AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + return getPersistentPrefIcon(enabled, disabled); case GeneralRouter.USE_HEIGHT_OBSTACLES: case RELIEF_SMOOTHNESS_FACTOR: return getPersistentPrefIcon(R.drawable.ic_action_elevation); diff --git a/OsmAnd/src/net/osmand/plus/settings/VoiceAnnouncesFragment.java b/OsmAnd/src/net/osmand/plus/settings/VoiceAnnouncesFragment.java index 9c22486c5a..ef9c6e38f2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/VoiceAnnouncesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/VoiceAnnouncesFragment.java @@ -175,7 +175,7 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment { Drawable disabled = getContentIcon(R.drawable.ic_action_volume_mute); Drawable enabled = getActiveIcon(R.drawable.ic_action_volume_up); - Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); + Drawable icon = getPersistentPrefIcon(enabled, disabled); ListPreferenceEx voiceProvider = (ListPreferenceEx) findPreference(settings.VOICE_PROVIDER.getId()); voiceProvider.setEntries(entries); @@ -240,11 +240,14 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment { protected void onBindPreferenceViewHolder(Preference preference, PreferenceViewHolder holder) { super.onBindPreferenceViewHolder(preference, holder); if (settings.VOICE_PROVIDER.getId().equals(preference.getKey()) && preference instanceof ListPreferenceEx) { + TextView titleView = (TextView) holder.findViewById(android.R.id.title); + if (titleView != null) { + titleView.setTextColor(preference.isEnabled() ? getActiveTextColor() : getDisabledTextColor()); + } ImageView imageView = (ImageView) holder.findViewById(android.R.id.icon); if (imageView != null) { Object currentValue = ((ListPreferenceEx) preference).getValue(); - boolean enabled = preference.isEnabled() && !OsmandSettings.VOICE_PROVIDER_NOT_USE.equals(currentValue); - imageView.setEnabled(enabled); + imageView.setEnabled(preference.isEnabled() && !OsmandSettings.VOICE_PROVIDER_NOT_USE.equals(currentValue)); } } } diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java index 49a0824c89..7b56728c37 100644 --- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java @@ -947,9 +947,9 @@ public class ContextMenuLayer extends OsmandMapLayer { if (selectOnMap != null) { LatLon latlon = tileBox.getLatLonFromPixel(point.x, point.y); + menu.init(latlon, null, null); CallbackWithObject cb = selectOnMap; cb.processResult(latlon); - menu.init(latlon, null, null); selectOnMap = null; return true; } diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index 7f9bac6381..57a3b70766 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -102,7 +102,7 @@ public class MapInfoWidgetsFactory { Location loc = map.getMyApplication().getLocationProvider().getLastKnownLocation(); if (loc != null && loc.hasAltitude()) { double compAlt = loc.getAltitude(); - if (cachedAlt != (int) compAlt) { + if (isUpdateNeeded() || cachedAlt != (int) compAlt) { cachedAlt = (int) compAlt; String ds = OsmAndFormatter.getFormattedAlt(cachedAlt, map.getMyApplication()); int ls = ds.lastIndexOf(' '); @@ -120,6 +120,11 @@ public class MapInfoWidgetsFactory { } return false; } + + @Override + public boolean isMetricSystemDepended() { + return true; + } }; altitudeControl.setText(null, null); altitudeControl.setIcons(R.drawable.widget_altitude_day, R.drawable.widget_altitude_night); @@ -136,7 +141,7 @@ public class MapInfoWidgetsFactory { @Override public boolean updateInfo(DrawSettings d) { GPSInfo gpsInfo = loc.getGPSInfo(); - if (gpsInfo.usedSatellites != u || gpsInfo.foundSatellites != f) { + if (isUpdateNeeded() || gpsInfo.usedSatellites != u || gpsInfo.foundSatellites != f) { u = gpsInfo.usedSatellites; f = gpsInfo.foundSatellites; setText(gpsInfo.usedSatellites + "/" + gpsInfo.foundSatellites, ""); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java index 7c0619e11e..4f1ebd953d 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java @@ -337,7 +337,7 @@ public class MapMarkersWidgetsFactory { } boolean res = false; int d = getDistance(); - if (cachedMeters != d) { + if (isUpdateNeeded() || cachedMeters != d) { cachedMeters = d; String ds = OsmAndFormatter.getFormattedDistance(cachedMeters, view.getApplication()); int ls = ds.lastIndexOf(' '); @@ -364,6 +364,11 @@ public class MapMarkersWidgetsFactory { return res; } + @Override + public boolean isMetricSystemDepended() { + return true; + } + public LatLon getPointToNavigate() { MapMarker marker = getMarker(); if (marker != null) { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java index 366c215a48..1f3c3bb76a 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java @@ -342,7 +342,7 @@ public class RouteInfoWidgetsFactory { @Override public boolean updateInfo(DrawSettings drawSettings) { long time = System.currentTimeMillis(); - if(time - cachedLeftTime > 5000) { + if (isUpdateNeeded() || time - cachedLeftTime > 5000) { cachedLeftTime = time; if (DateFormat.is24HourFormat(ctx)) { setText(DateFormat.format("k:mm", time).toString(), null); //$NON-NLS-1$ @@ -372,7 +372,7 @@ public class RouteInfoWidgetsFactory { @Override public boolean updateInfo(DrawSettings drawSettings) { long time = System.currentTimeMillis(); - if (time - cachedLeftTime > 1000) { + if (isUpdateNeeded() || time - cachedLeftTime > 1000) { cachedLeftTime = time; Intent batteryIntent = ctx.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); @@ -418,7 +418,7 @@ public class RouteInfoWidgetsFactory { } else { mx = 0f; } - if (cachedSpeed != mx) { + if (isUpdateNeeded() || cachedSpeed != mx) { cachedSpeed = mx; if (cachedSpeed == 0) { setText(null, null); @@ -437,6 +437,11 @@ public class RouteInfoWidgetsFactory { } return false; } + + @Override + public boolean isMetricSystemDepended() { + return true; + } }; speedControl.setIcons(R.drawable.widget_max_speed_day, R.drawable.widget_max_speed_night); speedControl.setText(null, null); @@ -463,7 +468,7 @@ public class RouteInfoWidgetsFactory { if (cachedSpeed < 6) { minDelta = .015f; } - if (Math.abs(loc.getSpeed() - cachedSpeed) > minDelta) { + if (isUpdateNeeded() || Math.abs(loc.getSpeed() - cachedSpeed) > minDelta) { cachedSpeed = loc.getSpeed(); String ds = OsmAndFormatter.getFormattedSpeed(cachedSpeed, app); int ls = ds.lastIndexOf(' '); @@ -481,6 +486,11 @@ public class RouteInfoWidgetsFactory { } return false; } + + @Override + public boolean isMetricSystemDepended() { + return true; + } }; speedControl.setIcons(R.drawable.widget_speed_day, R.drawable.widget_speed_night); speedControl.setText(null, null); @@ -521,7 +531,7 @@ public class RouteInfoWidgetsFactory { @Override public boolean updateInfo(DrawSettings drawSettings) { int d = getDistance(); - if (distChanged(cachedMeters, d)) { + if (isUpdateNeeded() || distChanged(cachedMeters, d)) { cachedMeters = d; if (cachedMeters <= 20) { cachedMeters = 0; @@ -540,6 +550,11 @@ public class RouteInfoWidgetsFactory { return false; } + @Override + public boolean isMetricSystemDepended() { + return true; + } + public abstract LatLon getPointToNavigate(); public int getDistance() { @@ -664,17 +679,6 @@ public class RouteInfoWidgetsFactory { final TextInfoWidget bearingControl = new TextInfoWidget(map) { private int cachedDegrees; private float MIN_SPEED_FOR_HEADING = 1f; - private boolean angularUnitTypeChanged = false; - private StateChangedListener listener = new StateChangedListener() { - @Override - public void stateChanged(OsmandSettings.AngularConstants change) { - angularUnitTypeChanged = true; - } - }; - - { - getOsmandApplication().getSettings().ANGULAR_UNITS.addListener(listener); - } private LatLon getNextTargetPoint() { List points = getOsmandApplication().getTargetPointsHelper().getIntermediatePointsWithTarget(); @@ -687,8 +691,7 @@ public class RouteInfoWidgetsFactory { boolean modeChanged = setIcons(relative ? relativeBearingResId : bearingResId, relative ? relativeBearingNightResId : bearingNightResId); setContentTitle(relative ? R.string.map_widget_bearing : R.string.map_widget_magnetic_bearing); int b = getBearing(relative); - if (angularUnitTypeChanged || degreesChanged(cachedDegrees, b) || modeChanged) { - angularUnitTypeChanged = false; + if (isUpdateNeeded() || degreesChanged(cachedDegrees, b) || modeChanged) { cachedDegrees = b; if (b != -1000) { setText(OsmAndFormatter.getFormattedAzimuth(b, getOsmandApplication()) + (relative ? "" : " M"), null); @@ -700,6 +703,11 @@ public class RouteInfoWidgetsFactory { return false; } + @Override + public boolean isAngularUnitsDepended() { + return true; + } + public int getBearing(boolean relative) { int d = -1000; Location myLocation = getOsmandApplication().getLocationProvider().getLastKnownLocation(); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/TextInfoWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/TextInfoWidget.java index d32166e041..ff9cb8a325 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/TextInfoWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/TextInfoWidget.java @@ -38,6 +38,8 @@ public class TextInfoWidget { private boolean isNight; private ViewGroup bottomLayout; + private Integer cachedMetricSystem = null; + private Integer cachedAngularUnits = null; public TextInfoWidget(Activity activity) { app = (OsmandApplication) activity.getApplication(); @@ -191,6 +193,29 @@ public class TextInfoWidget { return false; } + public boolean isUpdateNeeded() { + boolean res = false; + if (isMetricSystemDepended()) { + int metricSystem = app.getSettings().METRIC_SYSTEM.get().ordinal(); + res |= cachedMetricSystem == null || cachedMetricSystem != metricSystem; + cachedMetricSystem = metricSystem; + } + if (isAngularUnitsDepended()) { + int angularUnits = app.getSettings().ANGULAR_UNITS.get().ordinal(); + res |= cachedAngularUnits == null || cachedAngularUnits != angularUnits; + cachedAngularUnits = angularUnits; + } + return res; + } + + public boolean isMetricSystemDepended() { + return false; + } + + public boolean isAngularUnitsDepended() { + return false; + } + public void setOnClickListener(OnClickListener onClickListener) { view.setOnClickListener(onClickListener); }