From ba1eb59e51c8f01a8fa479582f692c8a82ab5e0b Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 20 Oct 2023 14:23:24 +0300 Subject: [PATCH 01/96] Fix 16434 Highway shield steals numbers from the route/ref/name --- .../plus/routing/CurrentStreetName.java | 68 +++++++++++++++++-- .../plus/routing/RoutingHelperUtils.java | 36 +++++++--- .../mapwidgets/widgets/StreetNameWidget.java | 36 ++-------- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java index 902bd1b319fc..c7208dd3ae5c 100644 --- a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java +++ b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java @@ -1,6 +1,7 @@ package net.osmand.plus.routing; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import net.osmand.Location; import net.osmand.binary.RouteDataObject; @@ -15,7 +16,7 @@ public class CurrentStreetName { public String text; public TurnType turnType; public boolean showMarker; // turn type has priority over showMarker - public RouteDataObject shieldObject; + public RoadShield shield; public String exitRef; @NonNull @@ -41,9 +42,10 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel String rf = n.directionInfo.getRef(); String dn = n.directionInfo.getDestinationName(); isSet = !(Algorithms.isEmpty(nm) && Algorithms.isEmpty(rf) && Algorithms.isEmpty(dn)); - streetName.text = RoutingHelperUtils.formatStreetName(nm, rf, dn, "»"); + RouteDataObject routeDataObject = n.directionInfo.getRouteDataObject(); + streetName.shield = RoadShield.create(routeDataObject); + streetName.text = RoutingHelperUtils.formatStreetName(nm, rf, dn, "»", streetName.shield); streetName.turnType = n.directionInfo.getTurnType(); - streetName.shieldObject = n.directionInfo.getRouteDataObject(); if (streetName.turnType == null) { streetName.turnType = TurnType.valueOf(TurnType.C, false); } @@ -68,7 +70,7 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel isSet = true; } streetName.showMarker = true; - streetName.shieldObject = rs.getObject(); + streetName.shield = RoadShield.create(rs.getObject()); } } // 3. display next road street name if this one empty @@ -77,7 +79,7 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel if (rs != null) { streetName.text = getRouteSegmentStreetName(routingHelper, rs, false); streetName.turnType = TurnType.valueOf(TurnType.C, false); - streetName.shieldObject = rs.getObject(); + streetName.shield = RoadShield.create(rs.getObject()); } } if (streetName.turnType == null) { @@ -85,4 +87,60 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel } return streetName; } + + public static class RoadShield { + private final RouteDataObject rdo; + private String text; + private String nameTag; + private StringBuilder additional; + + public RoadShield(@NonNull RouteDataObject rdo) { + this.rdo = rdo; + StringBuilder additional = new StringBuilder(); + for (int i = 0; i < rdo.nameIds.length; i++) { + String key = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); + String val = rdo.names.get(rdo.nameIds[i]); + if (!key.endsWith("_ref") && !key.startsWith("route_road")) { + additional.append(key).append("=").append(val).append(";"); + } + } + for (int i = 0; i < rdo.nameIds.length; i++) { + String tag = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); + String val = rdo.names.get(rdo.nameIds[i]); + if (tag.startsWith("route_road") && tag.endsWith("_ref")) { + this.additional = additional; + this.nameTag = tag; + text = val; + break; + } + } + } + + public static RoadShield create(@Nullable RouteDataObject rdo) { + if (rdo != null && rdo.nameIds != null) { + return new RoadShield(rdo); + } + return null; + } + + public RouteDataObject getRdo() { + return rdo; + } + + public String getText() { + return text; + } + + public String getNameTag() { + return nameTag; + } + + public StringBuilder getAdditional() { + return additional; + } + + public boolean hasShield() { + return text != null; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index 6488c0432b9a..f25823f4fb33 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -1,5 +1,7 @@ package net.osmand.plus.routing; +import static net.osmand.plus.routing.CurrentStreetName.*; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -12,6 +14,7 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.Arrays; @@ -27,23 +30,40 @@ public class RoutingHelperUtils { @NonNull public static String formatStreetName(String name, String ref, String destination, String towards) { - String formattedStreetName = ""; - if (ref != null && ref.length() > 0) { - formattedStreetName = ref; + return formatStreetName(name, ref, destination, towards, null); + } + + @NonNull + public static String formatStreetName(String name, String originalRef, String destination, String towards, RoadShield shield) { + StringBuilder formattedStreetName = new StringBuilder(); + if (originalRef != null && originalRef.length() > 0) { + String[] refs = originalRef.split(";"); + for (String ref : refs) { + if (shield != null && !isRefEqualsShield(shield.getText(), ref)) { + if (formattedStreetName.length() > 0) { + formattedStreetName.append(" "); + } + formattedStreetName.append(ref); + } + } } if (name != null && name.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName = formattedStreetName + " "; + formattedStreetName.append(" "); } - formattedStreetName = formattedStreetName + name; + formattedStreetName.append(name); } if (destination != null && destination.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName = formattedStreetName + " "; + formattedStreetName.append(" "); } - formattedStreetName = formattedStreetName + towards + " " + destination; + formattedStreetName.append(towards).append(" ").append(destination); } - return formattedStreetName.replace(";", ", "); + return formattedStreetName.toString().replace(";", ", "); + } + + private static boolean isRefEqualsShield(String shieldText, String ref) { + return ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText); } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index 7ed2ab0f6936..7157a392e36d 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -39,6 +39,7 @@ import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.ShowAlongTheRouteBottomSheet; import net.osmand.plus.routing.CurrentStreetName; +import net.osmand.plus.routing.CurrentStreetName.RoadShield; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelperUtils; @@ -72,8 +73,6 @@ public class StreetNameWidget extends MapWidget { private final TurnDrawable turnDrawable; private int shadowRadius; private boolean showMarker; - private String roadShieldName; - @Override protected int getLayoutId() { @@ -129,20 +128,15 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, true); AndroidUiHelper.updateVisibility(addressTextShadow, shadowRadius > 0); - RouteDataObject shieldObject = streetName.shieldObject; - if (shieldObject != null && shieldObject.nameIds != null && setRoadShield(shieldObject)) { + RoadShield shield = streetName.shield; + if (shield != null && setRoadShield(shield)) { AndroidUiHelper.updateVisibility(shieldImage, true); int indexOf = streetName.text.indexOf("»"); if (indexOf > 0) { streetName.text = streetName.text.substring(indexOf); } - if (roadShieldName != null && streetName.text.startsWith(roadShieldName)) { - streetName.text = streetName.text.replaceFirst(roadShieldName, ""); - streetName.text = streetName.text.trim(); - } } else { AndroidUiHelper.updateVisibility(shieldImage, false); - roadShieldName = null; } if (Algorithms.isEmpty(streetName.exitRef)) { @@ -212,24 +206,9 @@ public boolean updateWaypoint() { } } - private boolean setRoadShield(@NonNull RouteDataObject object) { - StringBuilder additional = new StringBuilder(); - for (int i = 0; i < object.nameIds.length; i++) { - String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); - String val = object.names.get(object.nameIds[i]); - if (!key.endsWith("_ref") && !key.startsWith("route_road")) { - additional.append(key).append("=").append(val).append(";"); - } - } - for (int i = 0; i < object.nameIds.length; i++) { - String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); - String val = object.names.get(object.nameIds[i]); - if (key.startsWith("route_road") && key.endsWith("_ref")) { - boolean visible = setRoadShield(object, key, val, additional); - if (visible) { - return true; - } - } + private boolean setRoadShield(@NonNull RoadShield shield) { + if (shield.hasShield()) { + return setRoadShield(shield.getRdo(), shield.getNameTag(), shield.getText(), shield.getAdditional()); } return false; } @@ -268,13 +247,11 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n "drawable", app.getPackageName()); } if (shieldRes == -1) { - roadShieldName = null; return false; } Drawable shield = AppCompatResources.getDrawable(mapActivity, shieldRes); if (shield == null) { - roadShieldName = null; return false; } @@ -300,7 +277,6 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n textRenderer.drawWrappedText(canvas, text, 20f); shieldImage.setImageBitmap(bitmap); - roadShieldName = name; return true; } From d6f5bbc526366da23a259d17aa88bfe00fcccdbf Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 23 Oct 2023 13:05:39 +0300 Subject: [PATCH 02/96] Fix review --- OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index f25823f4fb33..8956874036fa 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -34,12 +34,13 @@ public static String formatStreetName(String name, String ref, String destinatio } @NonNull - public static String formatStreetName(String name, String originalRef, String destination, String towards, RoadShield shield) { + public static String formatStreetName(String name, String originalRef, String destination, String towards, + RoadShield shield) { StringBuilder formattedStreetName = new StringBuilder(); if (originalRef != null && originalRef.length() > 0) { String[] refs = originalRef.split(";"); for (String ref : refs) { - if (shield != null && !isRefEqualsShield(shield.getText(), ref)) { + if ((shield == null || !isRefEqualsShield(shield.getText(), ref))) { if (formattedStreetName.length() > 0) { formattedStreetName.append(" "); } From 1ad6233b1ccf683eeb4fdd72c07cc496f4f588cc Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Mon, 23 Oct 2023 18:39:53 +0300 Subject: [PATCH 03/96] Unit test for rendering --- .gitignore | 3 + OsmAnd-java/build.gradle | 3 + .../java/net/osmand/rendering/OpenGLTest.java | 516 ++++++++++++++++++ 3 files changed, 522 insertions(+) create mode 100644 OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java diff --git a/.gitignore b/.gitignore index 7386d5e61ec0..c8513fdeb0a1 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ Thumbs.db # Output files build + +#Rendering test files +OsmAnd-java/src/test/resources/rendering/* \ No newline at end of file diff --git a/OsmAnd-java/build.gradle b/OsmAnd-java/build.gradle index 1730242efe9f..f7a3f7a9f7d6 100644 --- a/OsmAnd-java/build.gradle +++ b/OsmAnd-java/build.gradle @@ -53,6 +53,9 @@ task collectTestResources(type: Copy) { from("../../resources/test-resources") { include "*" include "/search/*" + include "/rendering/*" + include "/rendering/maps/*" + include "/rendering/geotiffs/*" } from("../../resources/poi") { include "poi_types.xml" diff --git a/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java b/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java new file mode 100644 index 000000000000..9f8061cf16dd --- /dev/null +++ b/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java @@ -0,0 +1,516 @@ +package net.osmand.rendering; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.google.gson.stream.JsonReader; + +import net.osmand.PlatformUtil; +import net.osmand.data.LatLon; +import net.osmand.router.RouteResultPreparationTest; +import net.osmand.util.MapUtils; + +import org.apache.commons.logging.Log; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +public class OpenGLTest { + + private Map DISTANCES_TABLE; + private final int DISTANCE_ZOOM = 15; + private final int MAX_ZOOM = 21; + private final int MAX_DISTANCE_IN_METERS = 300;//for 15 zoom + protected Log log = PlatformUtil.getLog(OpenGLTest.class); + private final String PATH_TO_RESOURCES = "src/test/resources/rendering/"; + private final String TES_JSON = "/test_3d_rendering.json"; + private CummulativeException cummulativeException; + + @Test + public void testRendering() { + String eyepiecePath = System.getProperty("eyepiece"); + if (eyepiecePath == null) { + eyepiecePath = System.getenv("eyepiece"); + } + if (eyepiecePath == null || eyepiecePath.isEmpty()) { + return; + } + List commands = generateCommands(eyepiecePath); + for (String cmd : commands) { + try { + runCommand(cmd); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + initDistanceTable(); + try { + test(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + private void initDistanceTable() { + if (DISTANCES_TABLE == null) { + DISTANCES_TABLE = new HashMap<>(); + for (int i = 0; i <= MAX_ZOOM; i++) { + double coef = Math.pow(2, DISTANCE_ZOOM - i); + DISTANCES_TABLE.put(i, (int) (coef * MAX_DISTANCE_IN_METERS)); + } + } + } + + private List generateCommands(String eyepiecePath) { + Reader reader = new InputStreamReader(Objects.requireNonNull(RouteResultPreparationTest.class.getResourceAsStream(TES_JSON))); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonArray arr = gson.fromJson(reader, JsonArray.class); + LinkedList res = new LinkedList<>(); + for (int i = 0; i < arr.size(); i++) { + EyepieceParams params = new EyepieceParams(); + JsonObject o = (JsonObject) arr.get(i); + JsonObject center = o.getAsJsonObject("center"); + assert(center != null); + params.latitude = center.getAsJsonPrimitive("latitude").getAsDouble(); + params.longitude = center.getAsJsonPrimitive("longitude").getAsDouble(); + + parseVisibilityZoom(o.getAsJsonArray("icons"), params); + parseVisibilityZoom(o.getAsJsonArray("textOnPath"), params); + parseVisibilityZoom(o.getAsJsonArray("text"), params); + + JsonPrimitive eyepieceParams = o.getAsJsonPrimitive("eyepieceParams"); + if (eyepieceParams != null) { + params.commandParams = eyepieceParams.getAsString(); + } + + JsonPrimitive testName = o.getAsJsonPrimitive("testName"); + assert(testName != null); + params.testName = testName.getAsString(); + res.add(params.getCommand(eyepiecePath)); + } + return res; + } + + private void parseVisibilityZoom(JsonArray arr, EyepieceParams params) { + if (arr == null) { + return; + } + for (int i = 0; i < arr.size(); i++) { + JsonObject obj = (JsonObject) arr.get(i); + JsonObject zooms = obj.getAsJsonObject("visibilityZoom"); + Set> set = zooms.entrySet(); + for (Map.Entry s : set) { + int z = Integer.parseInt(s.getKey()); + params.registerZoom(z); + } + } + } + + private static String getMapName(String testName) { + String shortName = testName.substring(0, Math.min(testName.length(), 10)); + return shortName.replaceAll("[^a-zA-Z0-9\\.\\-]", "_"); + } + + private void runCommand(String cmd) throws IOException { + System.out.println("\n"); + System.out.println(cmd); + System.out.println("\n"); + Process proc = Runtime.getRuntime().exec(cmd); + BufferedReader stdInput = new BufferedReader(new + InputStreamReader(proc.getInputStream())); + + BufferedReader stdError = new BufferedReader(new + InputStreamReader(proc.getErrorStream())); + + String s = null; + while ((s = stdInput.readLine()) != null) { + System.out.println(s); + } + + StringBuilder errors = new StringBuilder(); + while ((s = stdError.readLine()) != null) { + System.out.println(s); + if (!s.startsWith("WARNING")) { + errors.append(s); + } + } + if (!errors.toString().isEmpty()) { + throw new RuntimeException(s); + } + } + + private void test() throws FileNotFoundException { + cummulativeException = new CummulativeException(); + Reader reader = new InputStreamReader(Objects.requireNonNull(RouteResultPreparationTest.class.getResourceAsStream(TES_JSON))); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonArray arr = gson.fromJson(reader, JsonArray.class); + for (int i = 0; i < arr.size(); i++) { + JsonObject o = (JsonObject) arr.get(i); + JsonPrimitive testNamePrimitive = o.getAsJsonPrimitive("testName"); + assert(testNamePrimitive != null); + String testName = testNamePrimitive.getAsString(); + cummulativeException.setCurrentTestName(testName); + List renderedInfo = parseRenderedJsonForMap(testName); + if (renderedInfo.size() == 0) { + throw new RuntimeException("File(s) is empty for test:" + testName); + } + List testInfo = parseTestJson(o); + compareTestAndRenderedInfo(testInfo, renderedInfo); + } + if (cummulativeException.hasExceptions()) { + throw new IllegalStateException(cummulativeException.getFormatExceptions()); + } + } + + private List parseRenderedJsonForMap(String testName) throws FileNotFoundException { + File jsonDir = new File(PATH_TO_RESOURCES + "/mapdata"); + assert(jsonDir.isDirectory()); + final String mapName = getMapName(testName); + File[] jsonFiles = jsonDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getName().endsWith(".json") && pathname.getName().startsWith(mapName); + } + }); + if (jsonFiles.length == 0) { + throw new RuntimeException("File(s) not found:" + mapName + "000x.json for test:" + testName); + } + List renderedInfo = new ArrayList<>(); + for (File f : jsonFiles) { + Gson gson = new Gson(); + JsonArray arr = gson.fromJson(new JsonReader(new FileReader(f)), JsonArray.class); + renderedInfo.addAll(parseRenderedJson(arr)); + } + return renderedInfo; + } + + private List parseRenderedJson(JsonArray arr) { + if (arr == null) { + return null; + } + List info = new ArrayList(); + for (int i = 0; i < arr.size(); i++) { + RenderedInfo ri = new RenderedInfo(); + JsonObject obj = (JsonObject) arr.get(i); + String cl = obj.getAsJsonPrimitive("class").getAsString(); + String type = obj.getAsJsonPrimitive("type").getAsString(); + ri.setType(cl, type); + ri.zoom = obj.getAsJsonPrimitive("zoom").getAsInt(); + ri.id = obj.getAsJsonPrimitive("id").getAsLong(); + double lat = obj.getAsJsonPrimitive("lat").getAsDouble(); + double lon = obj.getAsJsonPrimitive("lon").getAsDouble(); + ri.center = new LatLon(lat, lon); + + JsonObject start = obj.getAsJsonObject("startPoint"); + JsonObject end = obj.getAsJsonObject("endPoint"); + if (start != null && end != null) { + lat = start.getAsJsonPrimitive("lat").getAsDouble(); + lon = start.getAsJsonPrimitive("lon").getAsDouble(); + ri.startPoint = new LatLon(lat, lon); + lat = end.getAsJsonPrimitive("lat").getAsDouble(); + lon = end.getAsJsonPrimitive("lon").getAsDouble(); + ri.endPoint = new LatLon(lat, lon); + } + JsonPrimitive content = obj.getAsJsonPrimitive("content"); + if (content != null) { + ri.content = content.getAsString(); + } + info.add(ri); + } + return info; + } + + private List parseTestJson(JsonObject testJsonObj) { + List result = new ArrayList<>(); + parseTestJsonArr(testJsonObj.getAsJsonArray("icons"), result, RenderedType.ICON); + parseTestJsonArr(testJsonObj.getAsJsonArray("text"), result, RenderedType.TEXT_ON_POINT); + parseTestJsonArr(testJsonObj.getAsJsonArray("textOnPath"), result, RenderedType.TEXT_ON_LINE); + return result; + } + + private void parseTestJsonArr(JsonArray arr, List result, RenderedType type) { + if (arr == null) { + return; + } + for (int i = 0; i < arr.size(); i++) { + TestInfo testInfo = new TestInfo(); + JsonObject obj = (JsonObject) arr.get(i); + if (obj.getAsJsonPrimitive("osmId") == null) { + throw new RuntimeException("osmId not found"); + } + if (obj.getAsJsonObject("visibilityZoom") == null) { + throw new RuntimeException("visibilityZoom not found"); + } + + try { + testInfo.id = obj.getAsJsonPrimitive("osmId").getAsLong(); + } catch (NumberFormatException e) { + throw new RuntimeException("osmId is empty"); + } + JsonObject zooms = obj.getAsJsonObject("visibilityZoom"); + Set> set = zooms.entrySet(); + for (Map.Entry s : set) { + int z = Integer.parseInt(s.getKey()); + String v = s.getValue().getAsString(); + boolean visible = "true".equals(v) || "yes".equals(v); + if (visible) { + testInfo.addVisibleZoom(z); + } else { + testInfo.addInVisibleZoom(z); + } + } + + JsonPrimitive lat = obj.getAsJsonPrimitive("latitude"); + JsonPrimitive lon = obj.getAsJsonPrimitive("longitude"); + if (lat != null && lon != null) { + testInfo.center = new LatLon(lat.getAsDouble(), lon.getAsDouble()); + } + + lat = obj.getAsJsonPrimitive("lat"); + lon = obj.getAsJsonPrimitive("lon"); + if (lat != null && lon != null) { + testInfo.center = new LatLon(lat.getAsDouble(), lon.getAsDouble()); + } + + JsonPrimitive name = obj.getAsJsonPrimitive("name"); + if (name != null) { + testInfo.text = name.getAsString(); + } + + JsonObject startPoint = obj.getAsJsonObject("startPoint"); + JsonObject endPoint = obj.getAsJsonObject("endPoint"); + if (startPoint != null && endPoint != null) { + lat = startPoint.getAsJsonPrimitive("latitude"); + lon = startPoint.getAsJsonPrimitive("longitude"); + assert (lat != null && lon != null); + testInfo.startPoint = new LatLon(lat.getAsDouble(), lon.getAsDouble()); + lat = endPoint.getAsJsonPrimitive("latitude"); + lon = endPoint.getAsJsonPrimitive("longitude"); + assert (lat != null && lon != null); + testInfo.endPoint = new LatLon(lat.getAsDouble(), lon.getAsDouble()); + } + + testInfo.type = type; + + result.add(testInfo); + } + } + + private void compareTestAndRenderedInfo(List testInfo, List renderedInfo) { + for (TestInfo t : testInfo) { + checkOsmIdAndText(renderedInfo, t); + } + } + + private void checkOsmIdAndText(List renderedInfo, TestInfo testInfo) { + HashSet checkedZooms = testInfo.visibleZooms; + checkedZooms.addAll(testInfo.inVisibleZooms); + for (RenderedInfo info : renderedInfo) { + int zoom = info.zoom; + if (!checkedZooms.contains(zoom)) { + continue; + } + if (info.id == testInfo.id && testInfo.visibleZooms.contains(zoom)) { + checkedZooms.remove(zoom); + continue; + } + if (info.id == testInfo.id && testInfo.inVisibleZooms.contains(zoom)) { + cummulativeException.addException("osmId:" + testInfo.id + " must be not visible on zoom:" + zoom); + checkedZooms.remove(zoom); + continue; + } + if (testInfo.type == RenderedType.TEXT_ON_LINE || testInfo.type == RenderedType.TEXT_ON_POINT) { + if (info.content != null && info.content.equals(testInfo.text)) { + LatLon c = null; + LatLon c2 = null; + if (testInfo.center != null) { + c = testInfo.center; + } else if (testInfo.startPoint != null && testInfo.endPoint != null) { + c = MapUtils.calculateMidPoint(testInfo.startPoint, testInfo.endPoint); + } + if (info.startPoint != null && info.endPoint != null) { + c2 = MapUtils.calculateMidPoint(info.startPoint, info.endPoint); + } else if (info.center != null) { + c2 = info.center; + } + if (c != null && c2 != null) { + double dist = MapUtils.getDistance(c, c2); + if (dist <= DISTANCES_TABLE.get(zoom)) { + if (testInfo.inVisibleZooms.contains(zoom)) { + cummulativeException.addException("text:" + testInfo.text + " must be not visible on zoom:" + zoom); + } + } else { + cummulativeException.addException("text:" + testInfo.text + " is visible on zoom:" + zoom + + ", but too far from test location. Found location " + info.id + " " + c2.getLatitude() + " " + c2.getLongitude() + + ". Distance " + (int) dist + " meters"); + } + checkedZooms.remove(zoom); + } + } + } + if (checkedZooms.size() == 0) { + break; + } + } + checkedZooms.removeAll(testInfo.inVisibleZooms); + if (checkedZooms.size() > 0) { + String name = testInfo.text != null ? " name:\"" + testInfo.text + "\"" : ""; + cummulativeException.addException("osmId:" + testInfo.id + name + " must be visible on zooms:" + checkedZooms.toString()); + } + } + + private enum RenderedType { + ICON, + TEXT_ON_POINT, + TEXT_ON_LINE + } + + private class RenderedInfo { + RenderedType type; + String content; + long id; + LatLon center; + LatLon startPoint; + LatLon endPoint; + int zoom; + public void setType(String cl, String type) { + if (cl.equals("icon")) { + this.type = RenderedType.ICON; + } else if (cl.equals("caption")) { + if (type.equals("billboard")) { + this.type = RenderedType.TEXT_ON_POINT; + } else { + this.type = RenderedType.TEXT_ON_LINE; + } + } + } + } + + private class TestInfo { + long id; + LatLon center; + LatLon startPoint; + LatLon endPoint; + HashSet visibleZooms = new HashSet<>(); + HashSet inVisibleZooms = new HashSet<>(); + String text; + RenderedType type; + void addVisibleZoom(int zoom) { + visibleZooms.add(zoom); + } + void addInVisibleZoom(int zoom) { + inVisibleZooms.add(zoom); + } + } + + private class CummulativeException { + Map> exceptions; + String currentTestName = ""; + + void addException(String e) { + if (exceptions == null) { + exceptions = new HashMap<>(); + } + if (currentTestName.isEmpty()) { + throw new RuntimeException("Set test name"); + } + if (exceptions.get(currentTestName) == null) { + exceptions.put(currentTestName, new ArrayList()); + } + List explist = exceptions.get(currentTestName); + explist.add(e); + } + + void setCurrentTestName(String testName) { + currentTestName = testName; + } + + boolean hasExceptions() { + return exceptions.size() > 0; + } + + String getFormatExceptions() { + String res = "\n"; + for (Map.Entry> entry : exceptions.entrySet()) { + res += ">>>>" + entry.getKey() + "\n"; + for (String s : entry.getValue()) { + res += "\t\t" + s + "\n"; + } + res += "\n"; + } + return res; + } + } + + private class EyepieceParams { + String testName = ""; + int minZoom = 21; + int maxZoom = 0; + double latitude; + double longitude; + String commandParams = ""; + + void registerZoom(int zoom) { + minZoom = Math.min(minZoom, zoom); + maxZoom = Math.max(maxZoom, zoom); + } + + String getCommand(String eyepiecePath) { + assert(minZoom < maxZoom); + StringBuilder builder = new StringBuilder(); + builder.append(eyepiecePath + " -verbose "); + if (!commandParams.contains("-obfsPath")) { + builder.append("-obfsPath=" + PATH_TO_RESOURCES + "maps/ "); + } + if (!commandParams.contains("-geotiffPath")) { + builder.append("-geotiffPath=" + PATH_TO_RESOURCES + "geotiffs/ "); + } + if (!commandParams.contains("-cachePath")) { + builder.append("-cachePath=" + PATH_TO_RESOURCES + "cache/ "); + } + if (!commandParams.contains("-outputRasterWidth")) { + builder.append("-outputRasterWidth=1024 "); + } + if (!commandParams.contains("-outputRasterHeight")) { + builder.append("-outputRasterHeight=768 "); + } + if (!commandParams.contains("-outputImageFilename")) { + builder.append("-outputImageFilename=" + PATH_TO_RESOURCES + "mapimage/" + getMapName(testName) + " "); + } + if (!commandParams.contains("-outputJSONFilename")) { + builder.append("-outputJSONFilename=" + PATH_TO_RESOURCES + "mapdata/" + getMapName(testName) + " "); + } + if (!commandParams.contains("-latLon") && !commandParams.contains("-endLatLon")) { + builder.append("-latLon=" + latitude + ":" + longitude + " "); + } + if (!commandParams.contains("-zoom") && !commandParams.contains("-endZoom")) { + builder.append("-zoom=" + minZoom + " -endZoom=" + maxZoom + " "); + } + if (!commandParams.contains("-frames")) { + int frames = maxZoom - minZoom + 1; + builder.append("-frames=" + frames + " "); + } + builder.append(commandParams); + return builder.toString(); + } + } + +} From 85ac4e780ea653722bbeef3d2f74912738c97eb4 Mon Sep 17 00:00:00 2001 From: Sergey Kharchenko Date: Tue, 24 Oct 2023 00:37:29 +0300 Subject: [PATCH 04/96] #2159: Fixed import smart folders from cloud; fixed menu (https://github.com/osmandapp/OsmAnd-Issues/issues/2159) --- .../tracks/controller/SmartFolderOption.kt | 10 +-- .../SmartFolderOptionsController.kt | 4 +- .../SmartFolderOptionsListener.java | 2 +- .../dialogs/AvailableTracksFragment.java | 15 +++-- .../dialogs/BaseTrackFolderFragment.java | 2 +- .../tracks/dialogs/TracksFilterFragment.kt | 8 +-- .../tracks/filters/SmartFolderHelper.kt | 65 +++++++++++++++---- 7 files changed, 74 insertions(+), 32 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOption.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOption.kt index b0183a74ed7a..9c75e5b02410 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOption.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOption.kt @@ -21,16 +21,16 @@ internal enum class SmartFolderOption( REFRESH( R.string.shared_string_refresh, R.drawable.ic_action_update), - CHANGE_APPEARANCE( - R.string.change_default_appearance, - R.drawable.ic_action_appearance), + EDIT_FILTER( + R.string.edit_fiilter, + R.drawable.ic_action_filter_dark), EXPORT( R.string.shared_string_export, R.drawable.ic_action_upload), DELETE_FOLDER(R.string.delete_folder, R.drawable.ic_action_delete_dark); fun shouldShowBottomDivider(): Boolean { - return Algorithms.equalsToAny(this, SHOW_ALL_TRACKS, CHANGE_APPEARANCE) + return Algorithms.equalsToAny(this, SHOW_ALL_TRACKS, EDIT_FILTER, EXPORT) } companion object { @@ -40,7 +40,7 @@ internal enum class SmartFolderOption( SHOW_ALL_TRACKS, EDIT_NAME, REFRESH, - CHANGE_APPEARANCE, + EDIT_FILTER, EXPORT, DELETE_FOLDER) } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt index 711ca7a82eb0..68e2f1b47fef 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt @@ -82,7 +82,7 @@ class SmartFolderOptionsController( dialogManager.askRefreshDialogCompletely(PROCESS_ID) } - SmartFolderOption.CHANGE_APPEARANCE -> { + SmartFolderOption.EDIT_FILTER -> { showChangeAppearanceDialog(smartFolder) } @@ -139,7 +139,7 @@ class SmartFolderOptionsController( private fun showChangeAppearanceDialog(folder: SmartFolder) { dialogManager.askDismissDialog(PROCESS_ID) - optionsListener?.showChangeAppearanceDialog(folder) + optionsListener?.showEditFiltersDialog(folder) } private fun showExportDialog(folder: SmartFolder) { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsListener.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsListener.java index 0c378f2389aa..d677bae9e929 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsListener.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsListener.java @@ -15,6 +15,6 @@ default void showSmartFolderTracksOnMap(@NonNull SmartFolder folder) { default void showExportDialog(@NonNull SmartFolder folder) { } - default void showChangeAppearanceDialog(@NonNull SmartFolder trackFolder) { + default void showEditFiltersDialog(@NonNull SmartFolder trackFolder) { } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java index e269b97ab7c8..0e663801d7d9 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java @@ -28,6 +28,7 @@ import net.osmand.plus.myplaces.tracks.ItemsSelectionHelper; import net.osmand.plus.myplaces.tracks.SearchMyPlacesTracksFragment; import net.osmand.plus.myplaces.tracks.TrackFoldersHelper; +import net.osmand.plus.myplaces.tracks.TracksSearchFilter; import net.osmand.plus.myplaces.tracks.VisibleTracksGroup; import net.osmand.plus.myplaces.tracks.dialogs.viewholders.RecordingTrackViewHolder.RecordingTrackListener; import net.osmand.plus.myplaces.tracks.filters.SmartFolderUpdateListener; @@ -515,11 +516,15 @@ public void onSmartFoldersUpdated() { } @Override - public void showChangeAppearanceDialog(@NonNull SmartFolder folder) { - selectionHelper.setAllItems(folder.getTrackItems()); - selectionHelper.setSelectedItems(folder.getTrackItems()); - selectionHelper.setOriginalSelectedItems(folder.getTrackItems()); - super.showChangeAppearanceDialog(folder); + public void showEditFiltersDialog(@NonNull SmartFolder folder) { + FragmentManager manager = getFragmentManager(); + ArrayList trackItems = new ArrayList<>(); + trackItems.addAll(smartFolderHelper.getAllAvailableTrackItems()); + TracksSearchFilter filter = new TracksSearchFilter(app, trackItems); + filter.initSelectedFilters(folder.getFilters()); + if (manager != null) { + TracksFilterFragment.Companion.showInstance(app, manager, this, filter, null, folder, null); + } } @Override diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java index bb346d8dd4f5..111cdfe22861 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java @@ -473,7 +473,7 @@ public void showChangeAppearanceDialog(@NonNull TrackFolder folder) { } @Override - public void showChangeAppearanceDialog(@NonNull SmartFolder folder) { + public void showEditFiltersDialog(@NonNull SmartFolder folder) { FragmentActivity activity = getActivity(); if (activity != null) { TracksAppearanceFragment.showInstance(activity.getSupportFragmentManager(), this); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt index 5de4b016e795..41f5b3c13b82 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt @@ -48,7 +48,7 @@ class TracksFilterFragment : BaseOsmAndDialogFragment(), manager: FragmentManager, target: Fragment?, filter: TracksSearchFilter, - trackFiltersContainer: DialogClosedListener, + trackFiltersContainer: DialogClosedListener?, smartFolder: SmartFolder?, currentFolder: TrackFolder?) { manager.findFragmentByTag(TAG)?.let { foundFragment -> @@ -79,7 +79,7 @@ class TracksFilterFragment : BaseOsmAndDialogFragment(), private lateinit var smartFolderHelper: SmartFolderHelper private var smartFolder: SmartFolder? = null private var currentFolder: TrackFolder? = null - private lateinit var dialogClosedListener: DialogClosedListener + private var dialogClosedListener: DialogClosedListener? = null private lateinit var appBar: AppBarLayout override fun onCreate(savedInstanceState: Bundle?) { @@ -337,9 +337,7 @@ class TracksFilterFragment : BaseOsmAndDialogFragment(), override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - if (dialogClosedListener != null) { - dialogClosedListener.onDialogClosed() - } + dialogClosedListener?.onDialogClosed() } override fun onSmartFolderSaved(smartFolder: SmartFolder?) { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt index 5642f1a89d26..024054535274 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt @@ -1,9 +1,11 @@ package net.osmand.plus.myplaces.tracks.filters +import android.os.AsyncTask import androidx.annotation.WorkerThread import com.google.gson.Gson import com.google.gson.GsonBuilder import net.osmand.PlatformUtil +import net.osmand.StateChangedListener import net.osmand.plus.OsmandApplication import net.osmand.plus.configmap.tracks.TrackItem import net.osmand.plus.myplaces.tracks.TrackFiltersHelper @@ -12,13 +14,13 @@ import net.osmand.plus.track.data.SmartFolder import net.osmand.util.Algorithms import java.util.Date -class SmartFolderHelper(val app: OsmandApplication) { +class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener { private val LOG = PlatformUtil.getLog(SmartFolderHelper::class.java) private val preference: CommonPreference private val gson: Gson - private val smartFolderCollection: MutableList = ArrayList() + private var smartFolderCollection: MutableList = ArrayList() private val allAvailableTrackItems = HashSet() private val allAvailableFolders = HashSet() private val updateListeners = ArrayList() @@ -34,11 +36,16 @@ class SmartFolderHelper(val app: OsmandApplication) { preference = app.settings.registerStringPreference(TRACK_FILTERS_SETTINGS_PREF, "") .makeGlobal() .makeShared() + preference.addListener(this) readSettings() } + private fun onSettingsChanged() { + updateSmartFolderSettings() + } + private fun readSettings() { - smartFolderCollection.clear() + var newCollection = ArrayList() val settingsJson = preference.get() if (!Algorithms.isEmpty(settingsJson)) { TrackFilterList.parseFilters(settingsJson, this)?.let { savedFilters -> @@ -54,13 +61,19 @@ class SmartFolderHelper(val app: OsmandApplication) { smartFolder.filters = newFilters } } - smartFolderCollection.addAll(savedFilters) + newCollection.addAll(savedFilters) } } + smartFolderCollection = newCollection + } + + fun updateSmartFolderSettings() { + SmartFoldersUpdateTask(app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) } fun resetSmartFoldersItems() { - for (smartFolder in smartFolderCollection) { + val collection = ArrayList(smartFolderCollection) + for (smartFolder in collection) { smartFolder.trackItems.clear() } } @@ -140,7 +153,7 @@ class SmartFolderHelper(val app: OsmandApplication) { private fun writeSettings() { - val json = gson.toJson(smartFolderCollection) + val json = gson.toJson(ArrayList(smartFolderCollection)) preference.set(json) } @@ -165,7 +178,8 @@ class SmartFolderHelper(val app: OsmandApplication) { if (!allAvailableTrackItems.contains(item)) { allAvailableTrackItems.add(item) } - for (smartFolder in smartFolderCollection) { + val smartFolders = ArrayList(smartFolderCollection) + for (smartFolder in smartFolders) { var trackAccepted = true smartFolder.filters?.let { filtersValue -> for (filter in filtersValue) { @@ -184,7 +198,8 @@ class SmartFolderHelper(val app: OsmandApplication) { } private fun getSmartFolderByName(name: String): SmartFolder? { - for (folder in smartFolderCollection) { + val smartFolders = ArrayList(smartFolderCollection) + for (folder in smartFolders) { if (Algorithms.stringsEqual(folder.folderName, name)) { return folder } @@ -195,7 +210,7 @@ class SmartFolderHelper(val app: OsmandApplication) { fun getSmartFolders(): MutableList { val smartFolders = ArrayList() smartFolders.addAll(smartFolderCollection) - return smartFolderCollection + return smartFolders } @@ -207,7 +222,9 @@ class SmartFolderHelper(val app: OsmandApplication) { fun deleteSmartFolder(smartFolder: SmartFolder) { - smartFolderCollection.remove(smartFolder) + val smartFolders = ArrayList() + smartFolders.remove(smartFolder) + smartFolderCollection = smartFolders writeSettings() notifyUpdateListeners() } @@ -251,8 +268,30 @@ class SmartFolderHelper(val app: OsmandApplication) { } fun getAllAvailableTrackItems(): HashSet { - val items = HashSet() - items.addAll(allAvailableTrackItems) - return items + return HashSet(allAvailableTrackItems) + } + + private class SmartFoldersUpdateTask( + private val app: OsmandApplication, + ) : AsyncTask() { + + override fun doInBackground(vararg params: Void): Void? { + app.smartFolderHelper.run { + readSettings() + var smartFolders = ArrayList(smartFolderCollection) + for (folder in smartFolders) { + updateSmartFolderItems(folder) + } + notifyUpdateListeners() + } + return null + } + + override fun onPostExecute(result: Void?) { + } + } + + override fun stateChanged(p0: String?) { + onSettingsChanged() } } \ No newline at end of file From dbaf9ba8f4cb228a717eadab6800fc0a1dd5596f Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 24 Oct 2023 14:07:26 +0300 Subject: [PATCH 05/96] Add multiple shields --- OsmAnd/res/layout-land/street_name_widget.xml | 12 +++-- OsmAnd/res/layout/street_name_widget.xml | 15 +++--- .../plus/routing/CurrentStreetName.java | 33 +++++-------- .../plus/routing/RoutingHelperUtils.java | 12 +++-- .../mapwidgets/widgets/StreetNameWidget.java | 48 ++++++++++++------- 5 files changed, 68 insertions(+), 52 deletions(-) diff --git a/OsmAnd/res/layout-land/street_name_widget.xml b/OsmAnd/res/layout-land/street_name_widget.xml index 2c6dced7d248..9743948456af 100644 --- a/OsmAnd/res/layout-land/street_name_widget.xml +++ b/OsmAnd/res/layout-land/street_name_widget.xml @@ -35,12 +35,14 @@ android:layout_height="@dimen/map_widget_height" android:scaleType="fitCenter" /> - + android:layout_gravity="center" + android:gravity="center" + android:orientation="horizontal"> + - + + shieldTags = new LinkedHashMap<>(); private StringBuilder additional; public RoadShield(@NonNull RouteDataObject rdo) { @@ -102,17 +104,12 @@ public RoadShield(@NonNull RouteDataObject rdo) { String val = rdo.names.get(rdo.nameIds[i]); if (!key.endsWith("_ref") && !key.startsWith("route_road")) { additional.append(key).append("=").append(val).append(";"); + } else if (key.startsWith("route_road") && key.endsWith("_ref")) { + shieldTags.put(key, val); } } - for (int i = 0; i < rdo.nameIds.length; i++) { - String tag = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); - String val = rdo.names.get(rdo.nameIds[i]); - if (tag.startsWith("route_road") && tag.endsWith("_ref")) { - this.additional = additional; - this.nameTag = tag; - text = val; - break; - } + if (!shieldTags.isEmpty()) { + this.additional = additional; } } @@ -127,20 +124,16 @@ public RouteDataObject getRdo() { return rdo; } - public String getText() { - return text; - } - - public String getNameTag() { - return nameTag; - } - public StringBuilder getAdditional() { return additional; } + public Map getShieldTags() { + return shieldTags; + } + public boolean hasShield() { - return text != null; + return !shieldTags.isEmpty(); } } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index 8956874036fa..cb6126e9a3c1 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -40,7 +40,7 @@ public static String formatStreetName(String name, String originalRef, String de if (originalRef != null && originalRef.length() > 0) { String[] refs = originalRef.split(";"); for (String ref : refs) { - if ((shield == null || !isRefEqualsShield(shield.getText(), ref))) { + if (shield == null || !isRefEqualsShield(shield, ref)) { if (formattedStreetName.length() > 0) { formattedStreetName.append(" "); } @@ -63,8 +63,14 @@ public static String formatStreetName(String name, String originalRef, String de return formattedStreetName.toString().replace(";", ", "); } - private static boolean isRefEqualsShield(String shieldText, String ref) { - return ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText); + private static boolean isRefEqualsShield(RoadShield shield, String ref) { + for (Entry entry : shield.getShieldTags().entrySet()) { + String shieldText = entry.getValue(); + if (ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText)) { + return true; + } + } + return false; } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index 7157a392e36d..7ea725f9c0dc 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -14,6 +14,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.ColorRes; @@ -55,6 +56,7 @@ import net.osmand.util.Algorithms; import java.util.List; +import java.util.Map; public class StreetNameWidget extends MapWidget { @@ -66,7 +68,7 @@ public class StreetNameWidget extends MapWidget { private final TextView addressText; private final TextView addressTextShadow; private final TextView exitRefText; - private final ImageView shieldImage; + private final LinearLayout shieldImagesContainer; private final ImageView turnIcon; private final View waypointInfoBar; @@ -88,7 +90,7 @@ public StreetNameWidget(@NonNull MapActivity mapActivity) { addressTextShadow = view.findViewById(R.id.map_address_text_shadow); waypointInfoBar = view.findViewById(R.id.waypoint_info_bar); exitRefText = view.findViewById(R.id.map_exit_ref); - shieldImage = view.findViewById(R.id.map_shield_icon); + shieldImagesContainer = view.findViewById(R.id.map_shields_container); turnIcon = view.findViewById(R.id.map_turn_icon); turnDrawable = new TurnDrawable(mapActivity, true); @@ -118,7 +120,7 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, false); AndroidUiHelper.updateVisibility(addressTextShadow, false); AndroidUiHelper.updateVisibility(turnIcon, false); - AndroidUiHelper.updateVisibility(shieldImage, false); + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); AndroidUiHelper.updateVisibility(exitRefText, false); } else if (streetName == null) { updateVisibility(false); @@ -130,13 +132,13 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { RoadShield shield = streetName.shield; if (shield != null && setRoadShield(shield)) { - AndroidUiHelper.updateVisibility(shieldImage, true); + AndroidUiHelper.updateVisibility(shieldImagesContainer, true); int indexOf = streetName.text.indexOf("»"); if (indexOf > 0) { streetName.text = streetName.text.substring(indexOf); } } else { - AndroidUiHelper.updateVisibility(shieldImage, false); + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); } if (Algorithms.isEmpty(streetName.exitRef)) { @@ -208,13 +210,21 @@ public boolean updateWaypoint() { private boolean setRoadShield(@NonNull RoadShield shield) { if (shield.hasShield()) { - return setRoadShield(shield.getRdo(), shield.getNameTag(), shield.getText(), shield.getAdditional()); + boolean shieldSet = false; + shieldImagesContainer.removeAllViews(); + for (Map.Entry entry : shield.getShieldTags().entrySet()) { + String nameTag = entry.getKey(); + String text = entry.getValue(); + shieldSet |= setShieldImage(shield, nameTag, text); + } + return shieldSet; } return false; } - private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String nameTag, - @NonNull String name, @NonNull StringBuilder additional) { + private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, String name) { + RouteDataObject object = shield.getRdo(); + StringBuilder additional = shield.getAdditional(); int[] types = object.getTypes(); RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer(); RenderingRuleSearchRequest rreq = app.getResourceManager().getRenderer() @@ -250,22 +260,18 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n return false; } - Drawable shield = AppCompatResources.getDrawable(mapActivity, shieldRes); - if (shield == null) { + Drawable shieldDrawable = AppCompatResources.getDrawable(mapActivity, shieldRes); + if (shieldDrawable == null) { return false; } - float xSize = shield.getIntrinsicWidth(); - float ySize = shield.getIntrinsicHeight(); + float xSize = shieldDrawable.getIntrinsicWidth(); + float ySize = shieldDrawable.getIntrinsicHeight(); float xyRatio = xSize / ySize; //setting view proportions (height is fixed by toolbar size - 48dp); int viewHeightPx = AndroidUtils.dpToPx(app, 48); int viewWidthPx = (int) (viewHeightPx * xyRatio); - ViewGroup.LayoutParams params = shieldImage.getLayoutParams(); - params.width = viewWidthPx; - shieldImage.setLayoutParams(params); - Bitmap bitmap = Bitmap.createBitmap((int) xSize, (int) ySize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = setupTextPaint(app, textRenderer.getPaintText(), rreq); @@ -276,7 +282,15 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n textRenderer.drawShieldIcon(rc, canvas, text, text.getShieldResIcon()); textRenderer.drawWrappedText(canvas, text, 20f); - shieldImage.setImageBitmap(bitmap); + ImageView imageView = new ImageView(view.getContext()); + int viewSize = AndroidUtils.dpToPx(app, 40f); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(viewWidthPx, viewSize); + int padding = AndroidUtils.dpToPx(app, 4f); + imageView.setPadding(0, 0, 0, padding); + imageView.setLayoutParams(params); + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + imageView.setImageBitmap(bitmap); + shieldImagesContainer.addView(imageView); return true; } From 99c598c5f1f45af2094156ce4f895c7f50053497 Mon Sep 17 00:00:00 2001 From: Sergey Kharchenko Date: Wed, 25 Oct 2023 00:23:35 +0300 Subject: [PATCH 06/96] fixes after review; small refactoring and code improvements; implemented update track created time --- .../java/net/osmand/gpx/GPXUtilities.java | 14 ++++ .../tracks/TrackFolderLoaderTask.java | 13 ++- .../plus/configmap/tracks/TracksFragment.java | 1 - .../importfiles/tasks/SaveGpxAsyncTask.java | 2 + .../importfiles/tasks/SaveTracksTask.java | 9 ++- .../importfiles/ui/ImportTracksFragment.java | 2 +- .../tracks/filters/ColorTrackFilter.kt | 4 + .../tracks/filters/SmartFolderHelper.kt | 80 +++++++------------ .../tracks/filters/WidthTrackFilter.kt | 4 + .../viewholders/FilterColorViewHolder.kt | 2 +- .../viewholders/FilterRangeViewHolder.kt | 62 +++++++------- .../viewholders/FilterWidthViewHolder.kt | 2 +- .../net/osmand/plus/track/data/SmartFolder.kt | 19 ++++- .../plus/track/helpers/GpxReaderTask.java | 4 +- 14 files changed, 115 insertions(+), 103 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java index 7019ad99bd82..44e18588bc76 100644 --- a/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java @@ -1307,6 +1307,20 @@ public static long parseTime(String text, SimpleDateFormat format, SimpleDateFor return time; } + public static long getCreationTime(GPXFile gpxFile) { + long time = 0; + if (gpxFile != null) { + if (gpxFile.metadata != null && gpxFile.metadata.time > 0) { + time = gpxFile.metadata.time; + } else if (gpxFile.getLastPoint() != null && gpxFile.getLastPoint().time > 0) { + time = gpxFile.getLastPoint().time; + } else { + time = gpxFile.modifiedTime; + } + } + return 0; + } + private static SimpleDateFormat getTimeFormatter() { SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_PATTERN, Locale.US); format.setTimeZone(TimeZone.getTimeZone("UTC")); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java index c7934274fba1..16f205244ce8 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java @@ -1,9 +1,5 @@ package net.osmand.plus.configmap.tracks; -import static net.osmand.plus.track.helpers.GPXFolderUtils.getSubfolderTitle; -import static net.osmand.plus.track.helpers.GPXFolderUtils.listFilesSorted; -import static net.osmand.plus.track.helpers.GpxUiHelper.isGpxFile; - import android.os.AsyncTask; import androidx.annotation.NonNull; @@ -17,8 +13,10 @@ import net.osmand.plus.settings.enums.TracksSortByMode; import net.osmand.plus.track.data.TrackFolder; import net.osmand.plus.track.helpers.GPXDatabase.GpxDataItem; +import net.osmand.plus.track.helpers.GPXFolderUtils; import net.osmand.plus.track.helpers.GpxDbHelper; import net.osmand.plus.track.helpers.GpxDbHelper.GpxDataItemCallback; +import net.osmand.plus.track.helpers.GpxUiHelper; import org.apache.commons.logging.Log; @@ -64,14 +62,13 @@ protected TrackFolder doInBackground(Void... voids) { private void loadGPXFolder(@NonNull TrackFolder trackFolder, @NonNull String subfolder, boolean updateSmartFolder) { File folderFile = trackFolder.getDirFile(); - File[] files = listFilesSorted(sortByMode, folderFile); + File[] files = GPXFolderUtils.listFilesSorted(sortByMode, folderFile); for (File file : files) { if (file.isDirectory()) { TrackFolder folder = new TrackFolder(file, trackFolder); trackFolder.addSubFolder(folder); - loadGPXFolder(folder, getSubfolderTitle(file, subfolder), updateSmartFolder); - } else if (isGpxFile(file)) { - smartFolderHelper.addAvailableTrackFolder(subfolder); + loadGPXFolder(folder, GPXFolderUtils.getSubfolderTitle(file, subfolder), updateSmartFolder); + } else if (GpxUiHelper.isGpxFile(file)) { TrackItem trackItem = new TrackItem(file); trackItem.setDataItem(getDataItem(trackItem)); trackFolder.addTrackItem(trackItem); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksFragment.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksFragment.java index 3a7c4ffcfe3d..5f2e6f11c9b5 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksFragment.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksFragment.java @@ -537,7 +537,6 @@ public void onSaveComplete(boolean success, GPXFile gpxFile) { } private void addTrackItem(@NonNull TrackItem item) { - app.getSmartFolderHelper().addTrackItemToSmartFolder(item); selectedTracksHelper.addTrackItem(item); updateTrackTabs(); setSelectedTab("import"); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveGpxAsyncTask.java b/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveGpxAsyncTask.java index 56c6718670bb..db297a92f2f6 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveGpxAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveGpxAsyncTask.java @@ -14,6 +14,7 @@ import net.osmand.gpx.GPXUtilities.WptPt; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.configmap.tracks.TrackItem; import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.importfiles.SaveImportedGpxListener; import net.osmand.plus.track.helpers.GPXDatabase.GpxDataItem; @@ -92,6 +93,7 @@ protected String doInBackground(Void... nothing) { } GpxDataItem item = new GpxDataItem(resultFile, gpxFile); app.getGpxDbHelper().add(item); + app.getSmartFolderHelper().addTrackItemToSmartFolder(new TrackItem(resultFile)); warning = null; } else { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveTracksTask.java b/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveTracksTask.java index 9181bc47b92c..cee8aac3afad 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveTracksTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/tasks/SaveTracksTask.java @@ -8,6 +8,8 @@ import net.osmand.IndexConstants; import net.osmand.gpx.GPXFile; import net.osmand.gpx.GPXUtilities; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.configmap.tracks.TrackItem; import net.osmand.plus.importfiles.SaveImportedGpxListener; import net.osmand.plus.importfiles.ui.ImportTrackItem; @@ -17,13 +19,16 @@ public class SaveTracksTask extends AsyncTask> { + private final OsmandApplication app; private final File importDir; private final List items; private final SaveImportedGpxListener listener; - public SaveTracksTask(@NonNull List items, + public SaveTracksTask(@NonNull OsmandApplication app, + @NonNull List items, @NonNull File importDir, @Nullable SaveImportedGpxListener listener) { + this.app = app; this.items = items; this.importDir = importDir; this.listener = listener; @@ -52,6 +57,8 @@ protected List doInBackground(Void... params) { String error = warn != null ? warn.getMessage() : null; if (error != null) { warnings.add(error); + } else { + app.getSmartFolderHelper().addTrackItemToSmartFolder(new TrackItem(new File(gpxFile.path))); } if (listener != null) { listener.onGpxSaved(error, gpxFile); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ui/ImportTracksFragment.java b/OsmAnd/src/net/osmand/plus/importfiles/ui/ImportTracksFragment.java index a57409979249..ff25b038132f 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ui/ImportTracksFragment.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ui/ImportTracksFragment.java @@ -298,7 +298,7 @@ private boolean isCollectingTracks() { private void importTracks() { File folder = new File(selectedFolder); SaveImportedGpxListener saveGpxListener = getSaveGpxListener(() -> saveTracksTask = null); - saveTracksTask = new SaveTracksTask(new ArrayList<>(selectedTracks), folder, saveGpxListener); + saveTracksTask = new SaveTracksTask(app, new ArrayList<>(selectedTracks), folder, saveGpxListener); saveTracksTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/ColorTrackFilter.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/ColorTrackFilter.kt index 864bd979bd2e..ba2014bcd645 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/ColorTrackFilter.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/ColorTrackFilter.kt @@ -84,4 +84,8 @@ class ColorTrackFilter(filterChangedListener: FilterChangedListener?) : } return true } + + fun getTracksCountForColor(colorName: String): Int { + return allColorsCollection[colorName] ?: 0 + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt index 024054535274..9c8272cd2b1b 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt @@ -14,29 +14,30 @@ import net.osmand.plus.track.data.SmartFolder import net.osmand.util.Algorithms import java.util.Date -class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener { - private val LOG = PlatformUtil.getLog(SmartFolderHelper::class.java) +class SmartFolderHelper(val app: OsmandApplication) { - private val preference: CommonPreference - private val gson: Gson + private val preference: CommonPreference = + app.settings.registerStringPreference(TRACK_FILTERS_SETTINGS_PREF, "") + .makeGlobal() + .makeShared() + private val gson: Gson = GsonBuilder() + .excludeFieldsWithoutExposeAnnotation() + .create() private var smartFolderCollection: MutableList = ArrayList() private val allAvailableTrackItems = HashSet() - private val allAvailableFolders = HashSet() private val updateListeners = ArrayList() + private val settingsChangedListener = StateChangedListener { + onSettingsChanged() + } companion object { + private val LOG = PlatformUtil.getLog(SmartFolderHelper::class.java) private const val TRACK_FILTERS_SETTINGS_PREF = "track_filters_settings_pref" } init { - gson = GsonBuilder() - .excludeFieldsWithoutExposeAnnotation() - .create() - preference = app.settings.registerStringPreference(TRACK_FILTERS_SETTINGS_PREF, "") - .makeGlobal() - .makeShared() - preference.addListener(this) + preference.addListener(settingsChangedListener) readSettings() } @@ -45,7 +46,7 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener() + val newCollection = ArrayList() val settingsJson = preference.get() if (!Algorithms.isEmpty(settingsJson)) { TrackFilterList.parseFilters(settingsJson, this)?.let { savedFilters -> @@ -53,7 +54,7 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener = mutableListOf() for (filter in it) { - var newFilter = + val newFilter = TrackFiltersHelper.createFilter(app, filter.filterType, null) newFilter.initWithValue(filter) newFilters.add(newFilter) @@ -67,19 +68,19 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener?): ArrayList { - var enabledFilters = ArrayList() + private fun getEnabledFilters(filters: MutableList?): ArrayList { + val enabledFilters = ArrayList() filters?.let { for (filter in filters) { if (filter.isEnabled()) { @@ -91,7 +92,7 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener?) { - var enabledFilters = getEnabledFilters(filters) + val enabledFilters = getEnabledFilters(filters) smartFolder.filters = enabledFilters writeSettings() updateSmartFolderItems(smartFolder) @@ -99,12 +100,12 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener?) { - var enabledFilters = getEnabledFilters(filters) + val enabledFilters = getEnabledFilters(filters) val newFolder = SmartFolder(name) newFolder.creationTime = Date().time newFolder.filters = enabledFilters smartFolderCollection.add(newFolder) - updateSmartFolderItems(newFolder); + updateSmartFolderItems(newFolder) writeSettings() notifyFolderCreatedListeners(newFolder) } @@ -141,17 +142,16 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener { - val items = HashSet() - items.addAll(allAvailableFolders) - return items - } - fun addTrackItemToSmartFolder(item: TrackItem) { LOG.debug("addTrackItemToSmartFolder") if (!allAvailableTrackItems.contains(item)) { @@ -208,19 +196,15 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener { - val smartFolders = ArrayList() - smartFolders.addAll(smartFolderCollection) - return smartFolders + return ArrayList(smartFolderCollection) } - fun renameSmartFolder(smartFolder: SmartFolder, newName: String) { smartFolder.folderName = newName writeSettings() notifyFolderRenamedListeners(smartFolder) } - fun deleteSmartFolder(smartFolder: SmartFolder) { val smartFolders = ArrayList() smartFolders.remove(smartFolder) @@ -232,10 +216,10 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener() { + @Deprecated("Deprecated in Java") override fun doInBackground(vararg params: Void): Void? { app.smartFolderHelper.run { readSettings() - var smartFolders = ArrayList(smartFolderCollection) + val smartFolders = ArrayList(smartFolderCollection) for (folder in smartFolders) { updateSmartFolderItems(folder) } @@ -287,11 +272,8 @@ class SmartFolderHelper(val app: OsmandApplication) : StateChangedListener - if (filter != null && fromUser) { + RangeSlider.OnChangeListener { slider: RangeSlider, _: Float, fromUser: Boolean -> + if (fromUser) { val values = slider.values val valueFrom = floor(values[0]) val valueTo = ceil(values[1]) @@ -73,13 +72,11 @@ open class FilterRangeViewHolder( } override fun onStopTrackingTouch(slider: RangeSlider) { - filter?.let { - isSliderDragging = false - val values = slider.values - filter!!.setValueFrom(Math.round(values[0]).toFloat()) - filter!!.setValueTo(Math.round(values[1]).toFloat()) - updateValues() - } + isSliderDragging = false + val values = slider.values + filter.setValueFrom(Math.round(values[0]).toFloat()) + filter.setValueTo(Math.round(values[1]).toFloat()) + updateValues() } } @@ -93,7 +90,7 @@ open class FilterRangeViewHolder( explicitIndicator = itemView.findViewById(R.id.explicit_indicator) minMaxContainer = itemView.findViewById(R.id.min_max_container) titleContainer = itemView.findViewById(R.id.title_container) - titleContainer.setOnClickListener { v: View? -> + titleContainer.setOnClickListener { expanded = !expanded updateExpandState() } @@ -110,13 +107,11 @@ open class FilterRangeViewHolder( super.afterTextChanged(newText) if (!Algorithms.isEmpty(newText) && Algorithms.isInt(newText.toString())) { val newValue = newText.toString().toInt() - filter?.let { rangeFilter -> - if (rangeFilter.getDisplayValueFrom() != newValue - && newValue < rangeFilter.valueTo - && !isSliderDragging) { - rangeFilter.setValueFrom(newValue.toFloat()) - updateValues() - } + if (filter.getDisplayValueFrom() != newValue + && newValue < filter.valueTo + && !isSliderDragging) { + filter.setValueFrom(newValue.toFloat()) + updateValues() } } } @@ -127,13 +122,11 @@ open class FilterRangeViewHolder( super.afterTextChanged(newText) if (!Algorithms.isEmpty(newText) && Algorithms.isInt(newText.toString())) { val newValue = newText.toString().toInt() - filter?.let { rangeFilter -> - if (rangeFilter.getDisplayValueTo() != newValue - && newValue > rangeFilter.getDisplayValueFrom() - && !isSliderDragging) { - rangeFilter.setValueTo(newValue.toFloat()) - updateValues() - } + if (filter.getDisplayValueTo() != newValue + && newValue > filter.getDisplayValueFrom() + && !isSliderDragging) { + filter.setValueTo(newValue.toFloat()) + updateValues() } } } @@ -163,10 +156,10 @@ open class FilterRangeViewHolder( } private fun updateValues() { - val valueFrom = filter!!.getDisplayValueFrom() - val valueTo = filter!!.getDisplayValueTo() - val minValue = filter!!.getDisplayMinValue() - val maxValue = filter!!.getDisplayMaxValue() + val valueFrom = filter.getDisplayValueFrom() + val valueTo = filter.getDisplayValueTo() + val minValue = filter.getDisplayMinValue() + val maxValue = filter.getDisplayMaxValue() slider.valueTo = maxValue.toFloat() slider.valueFrom = minValue.toFloat() slider.setValues(valueFrom.toFloat(), valueTo.toFloat()) @@ -175,12 +168,12 @@ open class FilterRangeViewHolder( valueToInput.setText(valueTo.toString()) valueToInput.setSelection(valueToInput.length()) val minValuePrompt = - "${decimalFormat.format(minValue)} ${app.getString(filter!!.unitResId)}" + "${decimalFormat.format(minValue)} ${app.getString(filter.unitResId)}" val maxValuePrompt = - "${decimalFormat.format(maxValue)} ${app.getString(filter!!.unitResId)}" + "${decimalFormat.format(maxValue)} ${app.getString(filter.unitResId)}" minFilterValue.text = minValuePrompt maxFilterValue.text = maxValuePrompt - AndroidUiHelper.updateVisibility(selectedValue, filter!!.isEnabled()) + AndroidUiHelper.updateVisibility(selectedValue, filter.isEnabled()) updateSelectedValue(valueFrom, valueTo) } @@ -191,7 +184,6 @@ open class FilterRangeViewHolder( app.getString(R.string.track_filter_range_selected_format), fromTxt, toTxt, - app.getString( - filter!!.unitResId)) + app.getString(filter.unitResId)) } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/viewholders/FilterWidthViewHolder.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/viewholders/FilterWidthViewHolder.kt index 95b0364bd51b..39ec4c1177dd 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/viewholders/FilterWidthViewHolder.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/viewholders/FilterWidthViewHolder.kt @@ -125,7 +125,7 @@ class FilterWidthViewHolder(itemView: View, nightMode: Boolean) : updateSelectedValue(widthFilter) } holder.checkBox.isChecked = widthFilter.isWidthSelected(widthName) - holder.count.text = widthFilter.allWidthCollection[widthName].toString() + holder.count.text = widthFilter.getTracksCountForWidth(widthName).toString() } } } diff --git a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt index 1e7e63aec804..647c2d187748 100644 --- a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt +++ b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt @@ -23,25 +23,31 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { @Expose var filters: MutableList? = null - private lateinit var folderAnalysis: TrackFolderAnalysis + private var folderAnalysis: TrackFolderAnalysis? = null override fun getName(context: Context): String { return folderName } - override fun getTrackItems(): MutableList { + override fun getTrackItems(): List { return trackItems } fun addTrackItem(trackItem: TrackItem) { trackItems.add(trackItem) + folderAnalysis = null + } + + fun addAllTrackItem(trackItem: Collection) { + trackItems.addAll(trackItem) + folderAnalysis = null } override fun getFolderAnalysis(): TrackFolderAnalysis { - if (!this::folderAnalysis.isInitialized) { + if (folderAnalysis == null) { folderAnalysis = TrackFolderAnalysis(this) } - return folderAnalysis + return folderAnalysis!! } fun updateAnalysis() { @@ -55,4 +61,9 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { override fun lastModified(): Long { return creationTime } + + fun resetItems() { + trackItems.clear() + folderAnalysis = null + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GpxReaderTask.java b/OsmAnd/src/net/osmand/plus/track/helpers/GpxReaderTask.java index 8ac5feb0d047..943eed8549e7 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GpxReaderTask.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GpxReaderTask.java @@ -87,8 +87,8 @@ protected Void doInBackground(Void... voids) { } else { database.updateAnalysis(item, analysis, conn); } - if(item.getFileCreationTime() <= 0) { - database.updateCreateTime(item, gpxFile.metadata.time); + if (item.getFileCreationTime() <= 0) { + database.updateCreateTime(item, GPXUtilities.getCreationTime(gpxFile)); } } if (GpxDbHelper.isCitySearchNeeded(item)) { From 51023ee30a5b7d051530c6c0c4a4d85098c8c61a Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 25 Oct 2023 10:24:14 +0300 Subject: [PATCH 07/96] Fix shield blinking --- .../plus/routing/CurrentStreetName.java | 4 ++++ .../mapwidgets/widgets/StreetNameWidget.java | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java index 6926d7e075fb..2173a246ac9a 100644 --- a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java +++ b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java @@ -135,5 +135,9 @@ public Map getShieldTags() { public boolean hasShield() { return !shieldTags.isEmpty(); } + + public boolean equalsShield(@Nullable RoadShield roadShield) { + return roadShield != null && shieldTags.equals(roadShield.shieldTags); + } } } diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index 7ea725f9c0dc..fed4f6e42dd4 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -75,6 +75,7 @@ public class StreetNameWidget extends MapWidget { private final TurnDrawable turnDrawable; private int shadowRadius; private boolean showMarker; + private RoadShield cachedRoadShield; @Override protected int getLayoutId() { @@ -131,14 +132,20 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressTextShadow, shadowRadius > 0); RoadShield shield = streetName.shield; - if (shield != null && setRoadShield(shield)) { - AndroidUiHelper.updateVisibility(shieldImagesContainer, true); - int indexOf = streetName.text.indexOf("»"); - if (indexOf > 0) { - streetName.text = streetName.text.substring(indexOf); + if (shield != null && !shield.equalsShield(cachedRoadShield)) { + if (setRoadShield(shield)) { + AndroidUiHelper.updateVisibility(shieldImagesContainer, true); + int indexOf = streetName.text.indexOf("»"); + if (indexOf > 0) { + streetName.text = streetName.text.substring(indexOf); + } + } else { + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); } - } else { + cachedRoadShield = shield; + } else if (shield == null) { AndroidUiHelper.updateVisibility(shieldImagesContainer, false); + cachedRoadShield = null; } if (Algorithms.isEmpty(streetName.exitRef)) { From ed97069a437bda9e4048b42282143bd56c045c43 Mon Sep 17 00:00:00 2001 From: chumva Date: Wed, 25 Oct 2023 14:44:39 +0300 Subject: [PATCH 08/96] Fix #18359 --- .../layout/fragment_delete_backup_account.xml | 39 +------- OsmAnd/res/values/strings.xml | 1 + .../plus/backup/ui/DeleteAccountFragment.java | 92 ++++++------------- 3 files changed, 34 insertions(+), 98 deletions(-) diff --git a/OsmAnd/res/layout/fragment_delete_backup_account.xml b/OsmAnd/res/layout/fragment_delete_backup_account.xml index 6e6338d802d9..514302f00051 100644 --- a/OsmAnd/res/layout/fragment_delete_backup_account.xml +++ b/OsmAnd/res/layout/fragment_delete_backup_account.xml @@ -74,8 +74,7 @@ android:id="@+id/progress_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingTop="@dimen/dialog_content_margin"> + android:orientation="vertical"> - - - - - - - - - - + Deletion error Rows Show toast about pressed key The \"%1$s\" key is already assigned to another action: \"%2$s\" diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/DeleteAccountFragment.java b/OsmAnd/src/net/osmand/plus/backup/ui/DeleteAccountFragment.java index 6dc24e4b4839..1fb51e9a1aa1 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/DeleteAccountFragment.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/DeleteAccountFragment.java @@ -19,7 +19,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.core.view.ViewCompat; import androidx.fragment.app.FragmentActivity; @@ -34,25 +33,21 @@ import net.osmand.plus.backup.BackupError; import net.osmand.plus.backup.BackupHelper; import net.osmand.plus.backup.BackupListeners.OnDeleteAccountListener; -import net.osmand.plus.backup.BackupListeners.OnDeleteFilesListener; -import net.osmand.plus.backup.RemoteFile; import net.osmand.plus.backup.UserNotRegisteredException; import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.base.ProgressHelper; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.purchase.PurchasesFragment; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; import net.osmand.plus.utils.UiUtilities; +import net.osmand.plus.widgets.alert.AlertDialogData; +import net.osmand.plus.widgets.alert.CustomAlert; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; -import java.util.List; -import java.util.Map; - -public class DeleteAccountFragment extends BaseOsmAndFragment implements OnDeleteFilesListener, OnDeleteAccountListener { +public class DeleteAccountFragment extends BaseOsmAndFragment implements OnDeleteAccountListener { public static final String TAG = DeleteAccountFragment.class.getSimpleName(); @@ -63,7 +58,6 @@ public class DeleteAccountFragment extends BaseOsmAndFragment implements OnDelet private BackupHelper backupHelper; private CollapsingToolbarLayout toolbarLayout; - private TextView percentage; private TextView progressDescription; private ProgressBar progressBar; private View progressContainer; @@ -73,9 +67,9 @@ public class DeleteAccountFragment extends BaseOsmAndFragment implements OnDelet private View deleteButtonWarning; private String token; + @Nullable + private BackupError backupError; private DeletionStatus deletionStatus = NOT_STARTED; - private int progress; - private int maxProgress; @ColorRes public int getStatusBarColorId() { @@ -112,14 +106,12 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c public void onResume() { super.onResume(); updateContent(); - backupHelper.getBackupListeners().addDeleteFilesListener(this); backupHelper.getBackupListeners().addDeleteAccountListener(this); } @Override public void onPause() { super.onPause(); - backupHelper.getBackupListeners().removeDeleteFilesListener(this); backupHelper.getBackupListeners().removeDeleteAccountListener(this); } @@ -147,7 +139,6 @@ private void setupToolbar(@NonNull View view) { private void setupProgress(@NonNull View view) { progressContainer = view.findViewById(R.id.progress_container); - percentage = progressContainer.findViewById(R.id.percentage); progressBar = progressContainer.findViewById(R.id.progress_bar); progressDescription = progressContainer.findViewById(R.id.progress_description); updateProgress(); @@ -155,9 +146,12 @@ private void setupProgress(@NonNull View view) { private void updateContent() { if (isAdded()) { - toolbarLayout.setTitle(getString(deletionStatus.titleId)); + boolean hasError = backupError != null; + toolbarLayout.setTitle(getString(hasError ? R.string.deletion_error : deletionStatus.titleId)); - if (deletionStatus.descriptionId != -1) { + if (hasError) { + progressDescription.setText(backupError.getLocalizedError(app)); + } else if (deletionStatus.descriptionId != -1) { progressDescription.setText(deletionStatus.descriptionId); } updateProgress(); @@ -173,10 +167,8 @@ private void updateContent() { } private void updateProgress() { - if (isAdded() && progressBar != null && percentage != null) { - progressBar.setMax(maxProgress); - progressBar.setProgress(progress); - percentage.setText(ProgressHelper.normalizeProgressPercent(maxProgress != 0 ? progress * 100 / maxProgress : 0) + "%"); + if (isAdded() && progressBar != null) { + progressBar.setIndeterminate(deletionStatus != FINISHED); } } @@ -256,33 +248,27 @@ private void setupButtons(@NonNull View view) { closeButton.setOnClickListener(v -> { MapActivity activity = (MapActivity) getActivity(); if (activity != null) { - activity.dismissFragment(BackupCloudFragment.TAG); - BackupAuthorizationFragment.showInstance(activity.getSupportFragmentManager()); + if (backupError == null) { + activity.dismissFragment(BackupCloudFragment.TAG); + BackupAuthorizationFragment.showInstance(activity.getSupportFragmentManager()); + } else { + activity.onBackPressed(); + } } }); UiUtilities.setupDialogButton(nightMode, closeButton, SECONDARY, getString(R.string.shared_string_close)); } private void showConfirmationDialog(@NonNull View view) { - AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); - builder.setTitle(R.string.osmand_cloud_delete_account_confirmation); - builder.setMessage(R.string.osmand_cloud_delete_account_confirmation_descr); - builder.setNegativeButton(R.string.shared_string_cancel, null); - builder.setPositiveButton(R.string.shared_string_delete, (dialog, which) -> { - deletionStatus = RUNNING; - deleteAllFiles(); - }); - builder.show(); - } - - private void deleteAllFiles() { - try { - updateContent(); - backupHelper.deleteAllFiles(null); - } catch (UserNotRegisteredException e) { - updateContent(); - log.error(e); - } + AlertDialogData data = new AlertDialogData(view.getContext(), nightMode) + .setTitle(R.string.osmand_cloud_delete_account_confirmation) + .setNegativeButton(R.string.shared_string_cancel, null) + .setPositiveButton(R.string.shared_string_delete, (dialog, which) -> { + deletionStatus = RUNNING; + deleteAccount(); + }) + .setPositiveButtonTextColor(ColorUtilities.getColor(app, R.color.deletion_color_warning)); + CustomAlert.showSimpleMessage(data, R.string.osmand_cloud_delete_account_confirmation_descr); } private void deleteAccount() { @@ -295,31 +281,9 @@ private void deleteAccount() { } } - @Override - public void onFilesDeleteStarted(@NonNull List files) { - maxProgress = files.size(); - updateContent(); - } - - @Override - public void onFileDeleteProgress(@NonNull RemoteFile file, int progress) { - this.progress = progress; - updateProgress(); - } - - @Override - public void onFilesDeleteDone(@NonNull Map errors) { - deleteAccount(); - } - - @Override - public void onFilesDeleteError(int status, @NonNull String message) { - deleteAccount(); - } - @Override public void onDeleteAccount(int status, @Nullable String message, @Nullable BackupError error) { - progress = maxProgress; + backupError = error; deletionStatus = FINISHED; updateContent(); From 165fa0590fe65651c90dea661821b19dd25a4c13 Mon Sep 17 00:00:00 2001 From: chumva Date: Wed, 25 Oct 2023 17:13:04 +0300 Subject: [PATCH 09/96] Fix #18299 --- .../myplaces/tracks/dialogs/AvailableTracksFragment.java | 1 - .../myplaces/tracks/dialogs/BaseTrackFolderFragment.java | 8 ++++++-- .../plus/myplaces/tracks/dialogs/SmartFolderFragment.kt | 5 ----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java index 72be10d6bb81..313eedf8716b 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java @@ -134,7 +134,6 @@ public void onResume() { updateEnable = true; startHandler(); - restoreState(getArguments()); updateProgressVisibility(); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java index bb346d8dd4f5..80ebf9e34452 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java @@ -380,10 +380,14 @@ public void restoreState(Bundle bundle) { if (bundle != null && bundle.getInt(TAB_ID) == GPX_TAB) { preSelectedFolder = bundle.getString(SELECTED_FOLDER_KEY); selectedItemPath = bundle.getString(SELECTED_ITEM_PATH_KEY); - if (bundle.containsKey(SELECTED_SMART_FOLDER_KEY)) { - String smartFolderName = bundle.getString(SELECTED_SMART_FOLDER_KEY); + + String smartFolderName = bundle.getString(SELECTED_SMART_FOLDER_KEY); + if (smartFolderName != null) { smartFolder = app.getSmartFolderHelper().getSmartFolder(smartFolderName); } + bundle.remove(SELECTED_FOLDER_KEY); + bundle.remove(SELECTED_ITEM_PATH_KEY); + bundle.remove(SELECTED_SMART_FOLDER_KEY); } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/SmartFolderFragment.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/SmartFolderFragment.kt index 08fcd9b851ed..d7a62bd21bc8 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/SmartFolderFragment.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/SmartFolderFragment.kt @@ -1,6 +1,5 @@ package net.osmand.plus.myplaces.tracks.dialogs -import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager @@ -90,10 +89,6 @@ class SmartFolderFragment : TrackFolderFragment(), SmartFolderUpdateListener, return true } - override fun restoreState(bundle: Bundle?) { - super.restoreState(bundle) - } - private fun showTracksSelection( folder: TracksGroup, fragment: BaseTrackFolderFragment, trackItems: Set?, tracksGroups: Set?) { From aee7257d711303cd9f8e74360521ac942f1aa63e Mon Sep 17 00:00:00 2001 From: Sergey Kharchenko Date: Wed, 25 Oct 2023 17:15:33 +0300 Subject: [PATCH 10/96] refactored dublicated code (https://github.com/osmandapp/OsmAnd-Issues/issues/2159) --- .../tracks/filters/SmartFolderHelper.kt | 62 +++++++------------ .../net/osmand/plus/track/data/SmartFolder.kt | 11 ++-- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt index 9c8272cd2b1b..7451c3296626 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt @@ -161,30 +161,6 @@ class SmartFolderHelper(val app: OsmandApplication) { return getSmartFolderByName(name) != null } - fun addTrackItemToSmartFolder(item: TrackItem) { - LOG.debug("addTrackItemToSmartFolder") - if (!allAvailableTrackItems.contains(item)) { - allAvailableTrackItems.add(item) - } - val smartFolders = ArrayList(smartFolderCollection) - for (smartFolder in smartFolders) { - var trackAccepted = true - smartFolder.filters?.let { filtersValue -> - for (filter in filtersValue) { - if (filter.isEnabled() && !filter.isTrackAccepted(item)) { - trackAccepted = false - break - } - } - } - if (trackAccepted) { - if (!smartFolder.trackItems.contains(item)) { - smartFolder.addTrackItem(item) - } - } - } - } - private fun getSmartFolderByName(name: String): SmartFolder? { val smartFolders = ArrayList(smartFolderCollection) for (folder in smartFolders) { @@ -213,20 +189,24 @@ class SmartFolderHelper(val app: OsmandApplication) { notifyUpdateListeners() } - @WorkerThread - fun updateSmartFolderItems(smartFolder: SmartFolder) { - LOG.debug("updateSmartFolderItems ${smartFolder.folderName}") - smartFolder.resetItems() - val filters = smartFolder.filters - if (filters == null) { - smartFolder.addAllTrackItem(allAvailableTrackItems) - } else { - for (item in allAvailableTrackItems) { + fun addTrackItemToSmartFolder(item: TrackItem) { + LOG.debug("addTrackItemToSmartFolder") + if (!allAvailableTrackItems.contains(item)) { + allAvailableTrackItems.add(item) + } + addTracksToSmartFolders(arrayListOf(item), ArrayList(smartFolderCollection)) + } + + private fun addTracksToSmartFolders(items: List, smartFolders: List) { + for (item in items) { + for (smartFolder in smartFolders) { var trackAccepted = true - for (filter in filters) { - if (!filter.isTrackAccepted(item)) { - trackAccepted = false - break + smartFolder.filters?.let { smartFolderFilters -> + for (filter in smartFolderFilters) { + if (!filter.isTrackAccepted(item)) { + trackAccepted = false + break + } } } if (trackAccepted) { @@ -234,7 +214,13 @@ class SmartFolderHelper(val app: OsmandApplication) { } } } - smartFolder.updateAnalysis() + } + + @WorkerThread + fun updateSmartFolderItems(smartFolder: SmartFolder) { + LOG.debug("updateSmartFolderItems ${smartFolder.folderName}") + smartFolder.resetItems() + addTracksToSmartFolders(ArrayList(allAvailableTrackItems), arrayListOf(smartFolder)) notifyFolderUpdatedListeners(smartFolder) } diff --git a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt index 647c2d187748..682466f9418a 100644 --- a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt +++ b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt @@ -34,13 +34,10 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { } fun addTrackItem(trackItem: TrackItem) { - trackItems.add(trackItem) - folderAnalysis = null - } - - fun addAllTrackItem(trackItem: Collection) { - trackItems.addAll(trackItem) - folderAnalysis = null + if(!trackItems.contains(trackItem)) { + trackItems.add(trackItem) + folderAnalysis = null + } } override fun getFolderAnalysis(): TrackFolderAnalysis { From 902f3e9849f26ec27ea6798630226e1a43a8fd43 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 14:44:45 +0000 Subject: [PATCH 11/96] Translated using Weblate (Swedish) Currently translated at 95.2% (4715 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index 36f17ee32695..ae38a2c17cc0 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -5168,4 +5168,33 @@ Rapportera ett problem Spara kursen till varje spårpunkt vid inspelning Konfiguration + Basera din anpassade profil på en av appens standardprofiler, detta ställer in grunderna som måttenheter och widget-synlighet. Dessa är standardprofilerna, med exempel på anpassade profiler de är kopplade till: + Att klicka %1$s avfärdar alla dina ändringar. + Söker GPS + Rader + Dina OSM-anteckningar är i %1$s. + %1$d filer (%2$s) finns på den tidigare platsen \'%3$s\'. + Duplicera namn + Tryck på knappen på din enhet för att koppla den till vald åtgärd. + Vägen till fots är ca %1$s, och kan vara snabbare än kollektivtrafik + Knapp + Schweiz nationella rutnät (CH1903) + Snöpark + Kunde inte kopiera %1$d filer (%2$s). + Flytta kartor + Åtgärd + Koordinat-widget + Typ av kollektivtrafik + Tyvärr, kunde inte hitta en rutt som passar dina inställningar. + Flytta inte + \"%1$s\"-knappen har redan kopplats till en annan åtgärd: \"%2$s\" + För snöskoter, med särskilt avsedda vägar och skoterleder. + OsmAnds ruttberäkning + Beräkna rutt till fots + Navigering, loggningsnoggrannhet + Schweiz nationella rutnät plus (CH1903+) + Gräsarmering + En knapp för att göra skärmens mitt till startpunkt. Frågar därefter om destination eller påbörjar ruttberäkning. + Intervall för direktspårning + Tider för röstmeddelanden \ No newline at end of file From b914a8130ec240bd002c809a62cc2536566a37be Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Wed, 25 Oct 2023 11:47:56 +0000 Subject: [PATCH 12/96] Translated using Weblate (French) Currently translated at 99.7% (4935 of 4948 strings) --- OsmAnd/res/values-fr/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index f8c96364a14b..0b1ea79b2655 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -5502,4 +5502,28 @@ La corbeille est vide Corbeille Supprimer l\'élément + Zoomer + Modifier l\'orientation de la carte + Dossier racine + Lignes + Déplacer ver la gauche + Tous les dossiers + Déplacer vers la droite + Réduire + Bouton + Dossier + Êtes-vous certain de vouloir supprimer le type \"%1$s\" \? + Action + Ajouter un nouveau type + Déplacer vers le haut + Ouvrir la vue Recherche + Dézoomer + Afficher / masquer le menu latéral + La touche \"%1$s\" est déjà affectée à l\'action : \"%2$s\" + Ouvrir la vue Navigation + Atteindre ma position + Non spécifié + Interactions avec la carte + Déplacer vers le bas + Actions \ No newline at end of file From d1d1fc76be7a8cdce7c773646455555c57777b93 Mon Sep 17 00:00:00 2001 From: 99 efi Date: Wed, 25 Oct 2023 13:34:26 +0000 Subject: [PATCH 13/96] Translated using Weblate (Hungarian) Currently translated at 100.0% (4948 of 4948 strings) --- OsmAnd/res/values-hu/strings.xml | 36 ++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index e5c033e40d61..bff3e70ff96d 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -2973,7 +2973,7 @@ Alkalmazásprofilok Szánkó Terep - Külső beviteli eszköz + Külső beviteli eszközök Külső vezérlőeszköz (például általános billentyűzet vagy WunderLINQ) kijelölése. Nincs Billentyűzet @@ -5424,7 +5424,9 @@ Legnézettebb Adja meg a webcímet a következő paraméter szintaxissal: szélesség={0}, hosszúság={1}, időbélyeg={2}, hdop={3}, magasság={4}, sebesség={5}, irány={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. Hőmérséklet - • Siklási arány widget hozzáadva + • Külső beviteli eszközök billentyű hozzárendelés megváltoztatásának lehetősége hozzáadva +\n +\n • Siklási arány widget hozzáadva \n \n • Szűrők és okosmappák a nyomvonalakhoz hozzáadva \n @@ -5514,4 +5516,34 @@ Kevesebb mutatása Mappa Nem meghatározott + Nagyítás + Külső beviteli eszköz használatának engedélyezése az OsmAnd-nek + Térkép tájolás módosítása + Előző alkalmazásprofil + A lenyomott billentyű kijelzése + Mozgás balra + Nyomja meg a gombot a készüléken, hogy összekapcsolja azt a kiválasztott művelettel. + Mozgás jobbra + Gomb + Következő alkalmazásprofil + Billentyű hozzárendelés módosítása + Médiajegyzet felvétele + Művelet vissza megnyomva + Navigációs tippek adása + Biztosan eltávolítja a(z) \"%1$s\" típust\? + Művelet + Új típus hozzáadása + Mozgás fel + Keresési nézet megnyitása + Kicsinyítés + Oldalmenü be/ki + A(z) \"%1$s\" billentyű már hozzá van rendelve ehhez a művelethez: \"%2$s\" + Navigációs nézet megnyitása + Külső beviteli eszköz + Billentyű hozzárendelések + Ugrás a pozíciómra + Térképműveletek + Mozgás le + WunderLINQ Datagrid megnyitása + Műveletek \ No newline at end of file From 811d98cab3b354462c6595d834b2e35fce576af8 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Tue, 24 Oct 2023 19:19:18 +0000 Subject: [PATCH 14/96] Translated using Weblate (Spanish) Currently translated at 100.0% (4948 of 4948 strings) --- OsmAnd/res/values-es/strings.xml | 64 ++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index f476f3960d4a..94f04f20c827 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -707,7 +707,7 @@ Lo antes posible Público Identificable - Trazable / Practicable + Rastreable Privado Recoger el coche del aparcamiento Advertencia @@ -945,7 +945,7 @@ Mapa Hora de llegada Capa de sombreado - Información GPS + Información del GPS Navegación y Mapas OsmAnd Navegación y Mapas OsmAnd+ Nombre de calle @@ -1203,7 +1203,7 @@ Cargando %1$s… " \n -\nPulsación larga para ver en mapa" +\nToque prolongado para ver en el mapa" Iniciar automáticamente la navegación giro a giro marcado(s) Intervalo de división @@ -2272,7 +2272,7 @@ Curvas de profundidad náuticas Puntos de profundidad náuticos del hemisferio sur Puntos de profundidad náuticos del hemisferio norte - Isolíneas + Contorno de profundidad Mapas náuticos OsmAnd+ (Direcciones de navegación automatizadas OSM) es una aplicación de mapas y navegación con acceso a los datos OSM gratuitos, mundiales y de alta calidad. \n Disfruta de navegación por voz y óptica, visualización de POIs (puntos de interés), creación y gestión de tracks GPX, uso de visualización de curvas de nivel e información topográfica, elección entre modos de conducción, ciclismo, peatones, edición OSM y mucho más. @@ -3657,8 +3657,8 @@ Desinstalar y reiniciar Este dispositivo no tiene radares de velocidad. Patines en línea - Controla nivel de zoom con botones de volumen del dispositivo. - Botones de volumen + - zoom + Controla el nivel del zoom del mapa con los botones de volumen del dispositivo. + Botones del volumen como zoom Proporciona la longitud del vehículo, se pueden aplicar algunas restricciones de rutas para vehículos largos. Eliminar el próximo punto de destino Proporciona un nombre para el punto @@ -4282,7 +4282,7 @@ Calles expresamente autorizadas Vías expresamente autorizadas Ejemplo de Wikiviajes - Filtrar imágenes por fecha o tipo. Sólo activado en zoom cercano + Filtrar imágenes por fecha o por tipo. Sólo activo en el zoom de primer plano. Colorea la ruta o el trazado de la vía según la clasificación del camino. Proporciona información sobre la superficie física de los caminos y senderos. Clasificación con respecto a la usabilidad física de un camino para vehículos con ruedas, particularmente con respecto a la regularidad y planitud de la superficie. @@ -4493,7 +4493,7 @@ Muestra etiquetas que solicitan más atención (fixme) Etiquetas «note» (nota) Iconos en zoom bajo - Vista esquemática de iconos en zoom bajo + Visualización esquemática de los iconos con zooms bajos Túneles fluviales Un botón que inicia una ruta desde el centro de la pantalla. Marcar los puntos sugeridos @@ -4542,7 +4542,7 @@ Parar descarga Parar y salir completo - Mucha diferencia entre niveles de zoom, puede aumentar el tamaño de los datos descargados. + La gran diferencia entre los niveles del zoom puede aumentar el tamaño de los datos descargados. Tamaño estimado de descarga Número de teselas Elemento @@ -5427,21 +5427,23 @@ Especifica la dirección web con la sintaxis de los parámetros: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. Temperatura Muestra la temperatura del sensor - • Añadido el widget \"relación de planeo\" + • Capacidad añadida para cambiar enlaces de teclas para dispositivos de entrada externos \n -\n • Filtros y carpetas inteligentes para las pistas +\n • Añadido el widget \"Ratio de deslizamiento\" \n -\n • Añadidas filas para los paneles de widgets superior e inferior con soporte para todos los widgets +\n • Añadidos filtros y carpetas inteligentes para pistas \n -\n • Añadido el soporte para el widget de temperatura ANT +\n • Se han añadido filas para los paneles de widgets superior e inferior con soporte para todos los widgets \n -\n • Mejora la gestión de la memoria para grandes pistas GPX +\n • Añadido soporte fot ANT+ widget de temperatura \n -\n • Actualizada la gestión de recursos locales en las Descargas +\n • Mejora de la gestión de la memoria para grandes pistas GPX +\n +\n • Gestión actualizada de los recursos locales en Descargas \n \n • Añadido widget \"RAM disponible\" \n -\n • Solucionados los problemas con la barra de estado transparente +\n • Problemas fijos con barra de estado transparente \n \n Cochecito @@ -5517,4 +5519,34 @@ Mostrar menos Carpeta Sin especificar + Acercar + Habilitar el uso de un dispositivo de entrada externo con OsmAnd + Cambiar la orientación del mapa + Perfil anterior de la aplicación + Mostrar notificación del sistema sobre la tecla presionada + A la izquierda + Pulse el botón de su dispositivo para vincularlo a la acción elegida. + A la derecha + Botón + Perfil de la siguiente aplicación + Cambiar la vinculación de las teclas + Toma nota de los medios + Actividad pulsada de nuevo + Emitir una sugerencia para la navegación + ¿Está seguro de que desea eliminar el tipo \"%1$s\"\? + Acción + Añadir un nuevo tipo + Hacia arriba + Abrir la vista de búsqueda + Alejar + Mostrar/ocultar el menú lateral + La tecla \"%1$s\" ya está asignada a otra acción: \"%2$s\" + Abrir la vista de la navegación + Dispositivo de entrada externo + Vinculación de las teclas + Ir a Mi ubicación + Interacciones del mapa + Hacia abajo + Abrir la cuadrícula de datos WunderLINQ + Acciones \ No newline at end of file From 07fa74eef249105ffa6de131fe7c1fd896b2f757 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Tue, 24 Oct 2023 19:30:40 +0000 Subject: [PATCH 15/96] Translated using Weblate (Spanish) Currently translated at 100.0% (4635 of 4635 strings) --- OsmAnd/res/values-es/phrases.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/values-es/phrases.xml b/OsmAnd/res/values-es/phrases.xml index f8b4857f9120..317a7efd18fa 100644 --- a/OsmAnd/res/values-es/phrases.xml +++ b/OsmAnd/res/values-es/phrases.xml @@ -60,7 +60,7 @@ Tienda de informática Florería;Floristería Tienda de muebles - Centro de jardinería; Vivero (venta) + Centro de jardinería Venta de garrafas;Gas líquido Comercio Regalería;Tienda de regalos @@ -124,7 +124,7 @@ Metanol Hidrógeno líquido Electricidad - Estación de carga; Estación de carga de vehículos eléctricos; Punto de recarga eléctrica; Punto de carga; Estación de carga electrónica; Equipo de suministro de vehículos eléctricos + Estación de carga;Estación de carga para vehículos eléctricos;Estación de carga para VE;Punto de recarga eléctrica;Punto de carga;Estación de carga electrónica;Equipo de suministro para vehículos eléctricos Rampa de vehículos Aire comprimido Aparcamiento @@ -1848,7 +1848,7 @@ 91UL (sin plomo, para aviones) 100LL (con plomo, para aviones) Autogas (Etanol libre de plomo) - Combustible Jet A-1 + Combustible para aviones A-1 Aditivo para escapes de Diesel (AdBlue) Combustible: madera Combustible: carbón vegetal @@ -1911,7 +1911,7 @@ Femenino Deportivo Masculino - Ortopaedia + Ortopedia Mansión histórica Tipo de castillo: majestuoso Tipo de castillo: defensivo @@ -2755,7 +2755,7 @@ Tipo de cruce Pavimento táctil Estación de servicio - Sin cepillo + Sin escobillas Autoservicio Automatizado Tipo de aparcamiento @@ -2781,7 +2781,7 @@ Contenido Adicional Campamento de exploradores - Tipo de complejo + Tipo Dificultad de la pista Estado de la pista Género @@ -2801,8 +2801,8 @@ Característica del agua Superficie Nudismo - Dispensa - Travesía + Farmacia + Zona rural Accesible para sillas de rueda Wikipedia Tienda de especias @@ -2844,7 +2844,7 @@ Aspiradora Características Infraestructura de emergencias - Gasolinera náutica; Estación de combustible náutica + Estación de servicio para embarcaciones Vegetariana Vegana Libre de gluten @@ -4060,8 +4060,8 @@ Origen Sí;Tabaco;Cigarro;Cigarrillo Sí;Afiliación;Membresía - Ortopédico - Ortopedia + Ortopedia + Ortopédicas Movilidad Diagnóstico Respiratorio From 716087402d8c84de6a8254f1300a933108edf5dc Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:00:05 +0000 Subject: [PATCH 16/96] Translated using Weblate (Swedish) Currently translated at 95.2% (4414 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 9def5eefd57a..b60e63890b9d 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4415,4 +4415,6 @@ Tillträde för fartyg: destination Komposterbart Bälten + Omklädningsrum + Nöduppställningsplats \ No newline at end of file From 87572d1a5df1601bbfd91f2d56bff8cace253537 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 25 Oct 2023 03:19:55 +0000 Subject: [PATCH 17/96] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (4948 of 4948 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index a44c444d8e5d..86385541e900 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -5417,7 +5417,9 @@ 火車路線 使用參數語法指定網址:lat={0}、lon={1}、timestamp={2}、hdop={3}、altitude={4}、speed={5}、bearing={6}、 eta= {7}、etfa={8}、eda={9}、edfa={10}。 溫度 - • 新增「滑翔比」小工具 + • 新增變更外部輸入裝置按鍵綁定的功能 +\n +\n • 新增「滑翔比」小工具 \n \n • 新增軌跡的篩選條件與智慧型資料夾 \n @@ -5506,4 +5508,34 @@ 顯示較少 資料夾 未指定 + 放大 + 啟用以讓 OsmAnd 使用外部輸入裝置 + 變更地圖方向 + 上一個應用程式設定檔 + 顯示關於按下鍵的浮動式訊息 + 向左移動 + 在您的裝置上按下按鈕以將其與選定的動作連結。 + 向右移動 + 按鈕 + 下一個應用程式設定檔 + 變更按鍵綁定 + 記下媒體附註 + 按下返回活動 + 發出導航提示 + 您真的想要移除「%1$s」類型嗎? + 動作 + 新增類型 + 向上移動 + 開啟搜尋檢視 + 縮小 + 顯示/隱藏側邊選單 + 「%1$s」鍵已被分配給其他動作:「%2$s」 + 開啟導航檢視 + 外部輸入裝置 + 按鍵綁定 + 移動到我的位置 + 地圖互動 + 向下移動 + 開啟 WunderLINQ Datagrid + 動作 \ No newline at end of file From bf98fb3d9156bdeae191c86c8386c3a9ef36fa15 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:21:45 +0000 Subject: [PATCH 18/96] Translated using Weblate (Swedish) Currently translated at 95.3% (4716 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index ae38a2c17cc0..adf8a9509cba 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -5197,4 +5197,5 @@ En knapp för att göra skärmens mitt till startpunkt. Frågar därefter om destination eller påbörjar ruttberäkning. Intervall för direktspårning Tider för röstmeddelanden + Kunde inte tolka geo-identifieraren \'%s\'. \ No newline at end of file From 99c819ebce438f19becc6a1731935c50119351fc Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:22:21 +0000 Subject: [PATCH 19/96] Translated using Weblate (Swedish) Currently translated at 95.3% (4719 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index adf8a9509cba..0d83cea6cd88 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -4645,7 +4645,7 @@ Läge Med %1$s OsmAnd Live kollektivtrafik - + Enpersonsfordon Sektorer Duplicera CAI @@ -5198,4 +5198,6 @@ Intervall för direktspårning Tider för röstmeddelanden Kunde inte tolka geo-identifieraren \'%s\'. + Prova navigering till fots. + Monohjul \ No newline at end of file From 84160e40998a1ac851e911862f09523ba9458895 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:34:52 +0000 Subject: [PATCH 20/96] Translated using Weblate (Swedish) Currently translated at 95.2% (4415 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index b60e63890b9d..7832084ae334 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4417,4 +4417,5 @@ Bälten Omklädningsrum Nöduppställningsplats + Samlarobjekt \ No newline at end of file From 95de2342b9cd9b7a3c4e24838a6c009cc8645021 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:41:35 +0000 Subject: [PATCH 21/96] Translated using Weblate (Swedish) Currently translated at 95.2% (4416 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 7832084ae334..6539549a2253 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4418,4 +4418,5 @@ Omklädningsrum Nöduppställningsplats Samlarobjekt + Pornografiska böcker \ No newline at end of file From c78b6d9a5c0713ab70bc3337595497921846c793 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 15:44:36 +0000 Subject: [PATCH 22/96] Translated using Weblate (Swedish) Currently translated at 95.2% (4417 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 6539549a2253..25bd5b1d94d3 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4419,4 +4419,5 @@ Nöduppställningsplats Samlarobjekt Pornografiska böcker + Hämtningstider för postkontor \ No newline at end of file From 7bf1ed591be1bfbc66362712d9d7d918c59be5c7 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 16:02:21 +0000 Subject: [PATCH 23/96] Translated using Weblate (Swedish) Currently translated at 95.4% (4423 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 25bd5b1d94d3..b46a140258a5 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4420,4 +4420,10 @@ Samlarobjekt Pornografiska böcker Hämtningstider för postkontor + hbtq+ tillåts inte + hbtq+ enbart + Ingenjörsvetenskap + Flyg- och rymdteknik + Flygfart + Kommunikation och media \ No newline at end of file From 8aa1d3e94c4d4e0140b2de556a48536eccedab5b Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 16:02:50 +0000 Subject: [PATCH 24/96] Translated using Weblate (Swedish) Currently translated at 95.4% (4425 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index b46a140258a5..81dd332e73a1 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4426,4 +4426,6 @@ Flyg- och rymdteknik Flygfart Kommunikation och media + hbtq+ välkomna + hbtq+ : primär målgrupp \ No newline at end of file From 86f8aa24697c9f6872d594aef92c7073ca88559c Mon Sep 17 00:00:00 2001 From: chumva Date: Wed, 25 Oct 2023 19:23:16 +0300 Subject: [PATCH 25/96] Fix #16189 --- OsmAnd/res/layout/memory_usage_preference.xml | 18 +++ OsmAnd/res/xml/data_storage.xml | 2 +- .../plus/download/DownloadActivity.java | 2 +- .../dialogs/LocalCategoriesFragment.java | 26 +++-- .../ui/BannerAndDownloadFreeVersion.java | 11 +- .../plus/settings/backend/OsmandSettings.java | 110 +++++++++--------- .../datastorage/DataStorageFragment.java | 66 +---------- .../fragments/GlobalSettingsFragment.java | 24 ++-- 8 files changed, 115 insertions(+), 144 deletions(-) create mode 100644 OsmAnd/res/layout/memory_usage_preference.xml diff --git a/OsmAnd/res/layout/memory_usage_preference.xml b/OsmAnd/res/layout/memory_usage_preference.xml new file mode 100644 index 000000000000..a4c31d6184eb --- /dev/null +++ b/OsmAnd/res/layout/memory_usage_preference.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/xml/data_storage.xml b/OsmAnd/res/xml/data_storage.xml index 5edbedc57499..ffbc12e717c1 100644 --- a/OsmAnd/res/xml/data_storage.xml +++ b/OsmAnd/res/xml/data_storage.xml @@ -4,7 +4,7 @@ + android:layout="@layout/memory_usage_preference" /> categories; + private LocalItemsLoaderTask asyncLoader; private CategoriesAdapter adapter; @@ -76,15 +77,10 @@ private void setupRecyclerView(@NonNull View view) { private void updateAdapter() { if (categories != null) { List items = new ArrayList<>(); - List memoryItems = new ArrayList<>(); for (LocalCategory category : categories.values()) { items.add(category); - CategoryType type = category.getType(); - int color = ColorUtilities.getColor(app, type.getColorId()); - memoryItems.add(new MemoryItem(category.getName(app), category.getSize(), color)); - List groups = new ArrayList<>(category.getGroups().values()); Collections.sort(groups, (o1, o2) -> -Long.compare(o1.getSize(), o2.getSize())); @@ -92,7 +88,6 @@ private void updateAdapter() { items.add(group); } } - MemoryInfo memoryInfo = new MemoryInfo(memoryItems); if (memoryInfo.hasData()) { items.add(0, memoryInfo); } @@ -163,10 +158,27 @@ public void loadItemsStarted() { @Override public void loadItemsFinished(@NonNull Map categories) { this.categories = categories; + this.memoryInfo = createMemoryInfo(categories); + if (memoryInfo.hasData()) { + settings.OSMAND_USAGE_SPACE.set(memoryInfo.getSize()); + } updateAdapter(); + updateFragments(); updateProgressVisibility(false); + } + + @NonNull + private MemoryInfo createMemoryInfo(@NonNull Map categories) { + List items = new ArrayList<>(); + for (LocalCategory category : categories.values()) { + int color = ColorUtilities.getColor(app, category.getType().getColorId()); + items.add(new MemoryItem(category.getName(app), category.getSize(), color)); + } + return new MemoryInfo(items); + } + private void updateFragments() { DownloadActivity activity = getDownloadActivity(); if (activity != null) { LocalItemsFragment itemsFragment = activity.getFragment(LocalItemsFragment.TAG); diff --git a/OsmAnd/src/net/osmand/plus/download/ui/BannerAndDownloadFreeVersion.java b/OsmAnd/src/net/osmand/plus/download/ui/BannerAndDownloadFreeVersion.java index f8bf0640af2f..015b1472517c 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/BannerAndDownloadFreeVersion.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/BannerAndDownloadFreeVersion.java @@ -15,6 +15,7 @@ import com.ibm.icu.impl.IllegalIcuArgumentException; import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.base.BasicProgressAsyncTask; import net.osmand.plus.download.DownloadActivity; @@ -66,7 +67,7 @@ public void updateBannerInProgress() { if (isFinished) { progressLayout.setOnClickListener(null); - updateDescriptionTextWithSize(activity, progressLayout); + updateDescriptionTextWithSize(activity.getMyApplication(), progressLayout); freeVersionBanner.updateFreeVersionBanner(); } else { freeVersionBanner.setMinimizedFreeVersionBanner(true); @@ -88,18 +89,18 @@ public void updateBannerInProgress() { } } - public static void updateDescriptionTextWithSize(@NonNull DownloadActivity activity, @NonNull View view) { + public static void updateDescriptionTextWithSize(@NonNull OsmandApplication app, @NonNull View view) { TextView descriptionText = view.findViewById(R.id.rightTextView); TextView messageTextView = view.findViewById(R.id.leftTextView); ProgressBar sizeProgress = view.findViewById(R.id.progressBar); - File dir = activity.getMyApplication().getAppPath(null); + File dir = app.getAppPath(null); String size = ""; int percent = 0; if (dir.canRead()) { try { StatFs fs = new StatFs(dir.getAbsolutePath()); - size = AndroidUtils.formatSize(activity, (fs.getAvailableBlocksLong()) * fs.getBlockSizeLong()); + size = AndroidUtils.formatSize(app, (fs.getAvailableBlocksLong()) * fs.getBlockSizeLong()); percent = 100 - (int) (fs.getAvailableBlocksLong() * 100 / fs.getBlockCountLong()); } catch (IllegalIcuArgumentException e) { LOG.error(e); @@ -107,7 +108,7 @@ public static void updateDescriptionTextWithSize(@NonNull DownloadActivity activ } sizeProgress.setIndeterminate(false); sizeProgress.setProgress(percent); - String text = activity.getString(R.string.free, size); + String text = app.getString(R.string.free, size); descriptionText.setText(text); descriptionText.setMovementMethod(LinkMovementMethod.getInstance()); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 005066c6ed59..482d31d6a483 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1057,8 +1057,8 @@ public MetricsConstants getProfileDefaultValue(ApplicationMode mode) { public final OsmandPreference ANGULAR_UNITS = new EnumStringPreference(this, "angular_measurement", AngularConstants.DEGREES, AngularConstants.values()).makeProfile(); - public static final String LAST_START_LAT = "last_searched_lat"; //$NON-NLS-1$ - public static final String LAST_START_LON = "last_searched_lon"; //$NON-NLS-1$ + public static final String LAST_START_LAT = "last_searched_lat"; + public static final String LAST_START_LON = "last_searched_lon"; public LatLon getLastStartPoint() { if (settingsAPI.contains(globalPreferences, LAST_START_LAT) && settingsAPI.contains(globalPreferences, LAST_START_LON)) { @@ -1448,7 +1448,7 @@ public boolean isProxyEnabled() { public final CommonPreference USER_ANDROID_ID = new StringPreference(this, "user_android_id", "").makeGlobal(); public final CommonPreference USER_ANDROID_ID_EXPIRED_TIME = new LongPreference(this, "user_android_id_expired_time", 0).makeGlobal(); - public static final String SAVE_CURRENT_TRACK = "save_current_track"; //$NON-NLS-1$ + public static final String SAVE_CURRENT_TRACK = "save_current_track"; public final CommonPreference SAVE_GLOBAL_TRACK_TO_GPX = new BooleanPreference(this, "save_global_track_to_gpx", false).makeGlobal().cache(); public final CommonPreference SAVE_GLOBAL_TRACK_INTERVAL = new IntPreference(this, "save_global_track_interval", 5000).makeProfile().cache(); @@ -2089,17 +2089,17 @@ public Map getTileSourceEntries(boolean sqlite) { public final OsmandPreference SHARED_STORAGE_MIGRATION_FINISHED = new BooleanPreference(this, "shared_storage_migration_finished", false).makeGlobal(); - public static final String EXTERNAL_STORAGE_DIR = "external_storage_dir"; //$NON-NLS-1$ + public static final String EXTERNAL_STORAGE_DIR = "external_storage_dir"; - public static final String EXTERNAL_STORAGE_DIR_V19 = "external_storage_dir_V19"; //$NON-NLS-1$ - public static final String EXTERNAL_STORAGE_DIR_TYPE_V19 = "external_storage_dir_type_V19"; //$NON-NLS-1$ + public static final String EXTERNAL_STORAGE_DIR_V19 = "external_storage_dir_V19"; + public static final String EXTERNAL_STORAGE_DIR_TYPE_V19 = "external_storage_dir_type_V19"; public static final int EXTERNAL_STORAGE_TYPE_DEFAULT = 0; // Environment.getExternalStorageDirectory() public static final int EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE = 1; // ctx.getExternalFilesDirs(null) public static final int EXTERNAL_STORAGE_TYPE_INTERNAL_FILE = 2; // ctx.getFilesDir() public static final int EXTERNAL_STORAGE_TYPE_OBB = 3; // ctx.getObbDirs public static final int EXTERNAL_STORAGE_TYPE_SPECIFIED = 4; - public final OsmandPreference OSMAND_USAGE_SPACE = new LongPreference(this, "osmand_usage_space", 0).makeGlobal(); + public final OsmandPreference OSMAND_USAGE_SPACE = new LongPreference(this, "osmand_usage_space", 0).makeGlobal(); public void freezeExternalStorageDirectory() { int type = settingsAPI.getInt(globalPreferences, EXTERNAL_STORAGE_DIR_TYPE_V19, -1); @@ -2256,15 +2256,15 @@ public Object getGlobalPreferences() { // This value is a key for saving last known location shown on the map - public static final String LAST_KNOWN_MAP_LAT = "last_known_map_lat"; //$NON-NLS-1$ - public static final String LAST_KNOWN_MAP_LON = "last_known_map_lon"; //$NON-NLS-1$ - public static final String LAST_KNOWN_MAP_ZOOM = "last_known_map_zoom"; //$NON-NLS-1$ + public static final String LAST_KNOWN_MAP_LAT = "last_known_map_lat"; + public static final String LAST_KNOWN_MAP_LON = "last_known_map_lon"; + public static final String LAST_KNOWN_MAP_ZOOM = "last_known_map_zoom"; public static final String LAST_KNOWN_MAP_ZOOM_FLOAT_PART = "last_known_map_zoom_float_part"; - public static final String MAP_LABEL_TO_SHOW = "map_label_to_show"; //$NON-NLS-1$ - public static final String MAP_LAT_TO_SHOW = "map_lat_to_show"; //$NON-NLS-1$ - public static final String MAP_LON_TO_SHOW = "map_lon_to_show"; //$NON-NLS-1$ - public static final String MAP_ZOOM_TO_SHOW = "map_zoom_to_show"; //$NON-NLS-1$ + public static final String MAP_LABEL_TO_SHOW = "map_label_to_show"; + public static final String MAP_LAT_TO_SHOW = "map_lat_to_show"; + public static final String MAP_LON_TO_SHOW = "map_lon_to_show"; + public static final String MAP_ZOOM_TO_SHOW = "map_zoom_to_show"; public LatLon getLastKnownMapLocation() { float lat = settingsAPI.getFloat(globalPreferences, LAST_KNOWN_MAP_LAT, 0); @@ -2432,26 +2432,26 @@ public void setLastKnownMapElevation(@NonNull ApplicationMode appMode, float ele LAST_KNOWN_MAP_ELEVATION.setModeValue(appMode, elevation); } - public static final String POINT_NAVIGATE_LAT = "point_navigate_lat"; //$NON-NLS-1$ - public static final String POINT_NAVIGATE_LON = "point_navigate_lon"; //$NON-NLS-1$ - public static final String POINT_NAVIGATE_ROUTE = "point_navigate_route_integer"; //$NON-NLS-1$ + public static final String POINT_NAVIGATE_LAT = "point_navigate_lat"; + public static final String POINT_NAVIGATE_LON = "point_navigate_lon"; + public static final String POINT_NAVIGATE_ROUTE = "point_navigate_route_integer"; public static final int NAVIGATE = 1; - public static final String POINT_NAVIGATE_DESCRIPTION = "point_navigate_description"; //$NON-NLS-1$ - public static final String START_POINT_LAT = "start_point_lat"; //$NON-NLS-1$ - public static final String START_POINT_LON = "start_point_lon"; //$NON-NLS-1$ - public static final String START_POINT_DESCRIPTION = "start_point_description"; //$NON-NLS-1$ - - public static final String INTERMEDIATE_POINTS = "intermediate_points"; //$NON-NLS-1$ - public static final String INTERMEDIATE_POINTS_DESCRIPTION = "intermediate_points_description"; //$NON-NLS-1$ - - public static final String POINT_NAVIGATE_LAT_BACKUP = "point_navigate_lat_backup"; //$NON-NLS-1$ - public static final String POINT_NAVIGATE_LON_BACKUP = "point_navigate_lon_backup"; //$NON-NLS-1$ - public static final String POINT_NAVIGATE_DESCRIPTION_BACKUP = "point_navigate_description_backup"; //$NON-NLS-1$ - public static final String START_POINT_LAT_BACKUP = "start_point_lat_backup"; //$NON-NLS-1$ - public static final String START_POINT_LON_BACKUP = "start_point_lon_backup"; //$NON-NLS-1$ - public static final String START_POINT_DESCRIPTION_BACKUP = "start_point_description_backup"; //$NON-NLS-1$ - public static final String INTERMEDIATE_POINTS_BACKUP = "intermediate_points_backup"; //$NON-NLS-1$ - public static final String INTERMEDIATE_POINTS_DESCRIPTION_BACKUP = "intermediate_points_description_backup"; //$NON-NLS-1$ + public static final String POINT_NAVIGATE_DESCRIPTION = "point_navigate_description"; + public static final String START_POINT_LAT = "start_point_lat"; + public static final String START_POINT_LON = "start_point_lon"; + public static final String START_POINT_DESCRIPTION = "start_point_description"; + + public static final String INTERMEDIATE_POINTS = "intermediate_points"; + public static final String INTERMEDIATE_POINTS_DESCRIPTION = "intermediate_points_description"; + + public static final String POINT_NAVIGATE_LAT_BACKUP = "point_navigate_lat_backup"; + public static final String POINT_NAVIGATE_LON_BACKUP = "point_navigate_lon_backup"; + public static final String POINT_NAVIGATE_DESCRIPTION_BACKUP = "point_navigate_description_backup"; + public static final String START_POINT_LAT_BACKUP = "start_point_lat_backup"; + public static final String START_POINT_LON_BACKUP = "start_point_lon_backup"; + public static final String START_POINT_DESCRIPTION_BACKUP = "start_point_description_backup"; + public static final String INTERMEDIATE_POINTS_BACKUP = "intermediate_points_backup"; + public static final String INTERMEDIATE_POINTS_DESCRIPTION_BACKUP = "intermediate_points_description_backup"; public static final String MY_LOC_POINT_LAT = "my_loc_point_lat"; public static final String MY_LOC_POINT_LON = "my_loc_point_lon"; public static final String MY_LOC_POINT_DESCRIPTION = "my_loc_point_description"; @@ -2742,15 +2742,15 @@ public boolean moveImpassableRoad(LatLon latLonEx, LatLon latLonNew) { * the location of a parked car */ - public static final String LAST_SEARCHED_REGION = "last_searched_region"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_CITY = "last_searched_city"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_CITY_NAME = "last_searched_city_name"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_POSTCODE = "last_searched_postcode"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_STREET = "last_searched_street"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_BUILDING = "last_searched_building"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_INTERSECTED_STREET = "last_searched_intersected_street"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_LAT = "last_searched_lat"; //$NON-NLS-1$ - public static final String LAST_SEARCHED_LON = "last_searched_lon"; //$NON-NLS-1$ + public static final String LAST_SEARCHED_REGION = "last_searched_region"; + public static final String LAST_SEARCHED_CITY = "last_searched_city"; + public static final String LAST_SEARCHED_CITY_NAME = "last_searched_city_name"; + public static final String LAST_SEARCHED_POSTCODE = "last_searched_postcode"; + public static final String LAST_SEARCHED_STREET = "last_searched_street"; + public static final String LAST_SEARCHED_BUILDING = "last_searched_building"; + public static final String LAST_SEARCHED_INTERSECTED_STREET = "last_searched_intersected_street"; + public static final String LAST_SEARCHED_LAT = "last_searched_lat"; + public static final String LAST_SEARCHED_LON = "last_searched_lon"; public LatLon getLastSearchedPoint() { if (settingsAPI.contains(globalPreferences, LAST_SEARCHED_LAT) && settingsAPI.contains(globalPreferences, LAST_SEARCHED_LON)) { @@ -2774,15 +2774,15 @@ public boolean setLastSearchedPoint(double lat, double lon) { } public String getLastSearchedRegion() { - return settingsAPI.getString(globalPreferences, LAST_SEARCHED_REGION, ""); //$NON-NLS-1$ + return settingsAPI.getString(globalPreferences, LAST_SEARCHED_REGION, ""); } public boolean setLastSearchedRegion(String region, LatLon l) { SettingsEditor edit = settingsAPI.edit(globalPreferences).putString(LAST_SEARCHED_REGION, region).putLong(LAST_SEARCHED_CITY, -1). putString(LAST_SEARCHED_CITY_NAME, "").putString(LAST_SEARCHED_POSTCODE, ""). - putString(LAST_SEARCHED_STREET, "").putString(LAST_SEARCHED_BUILDING, ""); //$NON-NLS-1$ //$NON-NLS-2$ + putString(LAST_SEARCHED_STREET, "").putString(LAST_SEARCHED_BUILDING, ""); //$NON-NLS-2$ if (settingsAPI.contains(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET)) { - edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); //$NON-NLS-1$ + edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); } boolean res = edit.commit(); setLastSearchedPoint(l); @@ -2794,10 +2794,10 @@ public String getLastSearchedPostcode() { } public boolean setLastSearchedPostcode(String postcode, LatLon point) { - SettingsEditor edit = settingsAPI.edit(globalPreferences).putLong(LAST_SEARCHED_CITY, -1).putString(LAST_SEARCHED_STREET, "") //$NON-NLS-1$ - .putString(LAST_SEARCHED_BUILDING, "").putString(LAST_SEARCHED_POSTCODE, postcode); //$NON-NLS-1$ + SettingsEditor edit = settingsAPI.edit(globalPreferences).putLong(LAST_SEARCHED_CITY, -1).putString(LAST_SEARCHED_STREET, "") + .putString(LAST_SEARCHED_BUILDING, "").putString(LAST_SEARCHED_POSTCODE, postcode); if (settingsAPI.contains(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET)) { - edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); //$NON-NLS-1$ + edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); } boolean res = edit.commit(); setLastSearchedPoint(point); @@ -2814,10 +2814,10 @@ public String getLastSearchedCityName() { public boolean setLastSearchedCity(Long cityId, String name, LatLon point) { SettingsEditor edit = settingsAPI.edit(globalPreferences).putLong(LAST_SEARCHED_CITY, cityId).putString(LAST_SEARCHED_CITY_NAME, name). - putString(LAST_SEARCHED_STREET, "").putString(LAST_SEARCHED_BUILDING, "").putString(LAST_SEARCHED_POSTCODE, ""); //$NON-NLS-1$ + putString(LAST_SEARCHED_STREET, "").putString(LAST_SEARCHED_BUILDING, "").putString(LAST_SEARCHED_POSTCODE, ""); //edit.remove(LAST_SEARCHED_POSTCODE); if (settingsAPI.contains(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET)) { - edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); //$NON-NLS-1$ + edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); } boolean res = edit.commit(); setLastSearchedPoint(point); @@ -2825,13 +2825,13 @@ public boolean setLastSearchedCity(Long cityId, String name, LatLon point) { } public String getLastSearchedStreet() { - return settingsAPI.getString(globalPreferences, LAST_SEARCHED_STREET, ""); //$NON-NLS-1$ + return settingsAPI.getString(globalPreferences, LAST_SEARCHED_STREET, ""); } public boolean setLastSearchedStreet(String street, LatLon point) { - SettingsEditor edit = settingsAPI.edit(globalPreferences).putString(LAST_SEARCHED_STREET, street).putString(LAST_SEARCHED_BUILDING, ""); //$NON-NLS-1$ + SettingsEditor edit = settingsAPI.edit(globalPreferences).putString(LAST_SEARCHED_STREET, street).putString(LAST_SEARCHED_BUILDING, ""); if (settingsAPI.contains(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET)) { - edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); //$NON-NLS-1$ + edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); } boolean res = edit.commit(); setLastSearchedPoint(point); @@ -2839,7 +2839,7 @@ public boolean setLastSearchedStreet(String street, LatLon point) { } public String getLastSearchedBuilding() { - return settingsAPI.getString(globalPreferences, LAST_SEARCHED_BUILDING, ""); //$NON-NLS-1$ + return settingsAPI.getString(globalPreferences, LAST_SEARCHED_BUILDING, ""); } public boolean setLastSearchedBuilding(String building, LatLon point) { @@ -2852,7 +2852,7 @@ public String getLastSearchedIntersectedStreet() { if (!settingsAPI.contains(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET)) { return null; } - return settingsAPI.getString(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET, ""); //$NON-NLS-1$ + return settingsAPI.getString(globalPreferences, LAST_SEARCHED_INTERSECTED_STREET, ""); } public boolean setLastSearchedIntersectedStreet(String street, LatLon l) { diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java index ee9b9b40b773..63a8439f8337 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java @@ -19,7 +19,6 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.AsyncTask; -import android.os.AsyncTask.Status; import android.os.Bundle; import android.text.BidiFormatter; import android.util.Pair; @@ -40,24 +39,13 @@ import androidx.preference.PreferenceViewHolder; import androidx.recyclerview.widget.RecyclerView; -import com.github.mikephil.charting.charts.HorizontalBarChart; -import com.github.mikephil.charting.data.BarData; - import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandActionBarActivity; import net.osmand.plus.activities.RestartActivity; -import net.osmand.plus.charts.ChartUtils; import net.osmand.plus.download.DownloadActivity; -import net.osmand.plus.download.local.CategoryType; -import net.osmand.plus.download.local.LocalCategory; -import net.osmand.plus.download.local.LocalItemsLoaderTask; -import net.osmand.plus.download.local.LocalItemsLoaderTask.LoadItemsListener; -import net.osmand.plus.download.local.dialogs.MemoryInfo; -import net.osmand.plus.download.local.dialogs.MemoryInfo.MemoryItem; -import net.osmand.plus.download.local.dialogs.viewholders.MemoryViewHolder.MemoryChartAdapter; -import net.osmand.plus.download.local.dialogs.viewholders.MemoryViewHolder.RoundedChartRenderer; +import net.osmand.plus.download.ui.BannerAndDownloadFreeVersion; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet; import net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet; @@ -77,12 +65,11 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class DataStorageFragment extends BaseSettingsFragment implements FilesCollectListener, - StorageMigrationRestartListener, MoveFilesStopListener, LoadItemsListener { + StorageMigrationRestartListener, MoveFilesStopListener { public static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 500; @@ -96,8 +83,6 @@ public class DataStorageFragment extends BaseSettingsFragment implements FilesCo private String tmpManuallySpecifiedPath; private DataStorageHelper dataStorageHelper; - private MemoryInfo memoryInfo; - private LocalItemsLoaderTask asyncLoader; private OsmandActionBarActivity activity; private boolean storageMigration; private boolean firstUsage; @@ -147,7 +132,7 @@ protected void setupPreferences() { dataStorageRadioButtonsGroup.add(preference); } Preference preference = findPreference(MEMORY_USAGE); - preference.setVisible(!storageMigration && !firstUsage && memoryInfo != null); + preference.setVisible(!storageMigration && !firstUsage); changeButton = new Preference(app); changeButton.setKey(CHANGE_DIRECTORY_BUTTON); @@ -290,23 +275,7 @@ protected void onBindPreferenceViewHolder(Preference preference, PreferenceViewH icon.setVisibility(View.INVISIBLE); title.setText(R.string.shared_string_change); } else if (key.equals(MEMORY_USAGE)) { - if (memoryInfo != null) { - HorizontalBarChart chart = itemView.findViewById(R.id.horizontal_chart); - ChartUtils.setupHorizontalGPXChart(app, chart, 0, 0, 0, false, isNightMode()); - chart.getAxisRight().setDrawLabels(false); - chart.setRenderer(new RoundedChartRenderer(chart)); - - MemoryChartAdapter adapter = new MemoryChartAdapter(app, chart, true); - adapter.setBottomInfoContainer(itemView.findViewById(R.id.legend)); - - BarData barData = ChartUtils.buildStatisticChart(app, chart, memoryInfo, isNightMode()); - adapter.updateContent(barData, memoryInfo); - - TextView size = itemView.findViewById(R.id.size); - size.setText(AndroidUtils.formatSize(app, memoryInfo.getSize())); - - AndroidUiHelper.updateVisibility(itemView.findViewById(R.id.bottom_divider), false); - } + BannerAndDownloadFreeVersion.updateDescriptionTextWithSize(app, itemView); } } @@ -428,29 +397,6 @@ public void onFilesCollectingFinished(@Nullable String error, } } - @Override - public void loadItemsFinished(@NonNull Map categories) { - List items = new ArrayList<>(); - for (LocalCategory category : categories.values()) { - int color = ColorUtilities.getColor(app, category.getType().getColorId()); - items.add(new MemoryItem(category.getName(app), category.getSize(), color)); - } - memoryInfo = new MemoryInfo(items); - app.getSettings().OSMAND_USAGE_SPACE.set(memoryInfo.getSize()); - - updateSetting(MEMORY_USAGE); - } - - @Override - public void onDestroy() { - if (!activity.isChangingConfigurations()) { - if (asyncLoader != null && asyncLoader.getStatus() == Status.RUNNING) { - asyncLoader.cancel(false); - } - } - super.onDestroy(); - } - private void updateView(String key) { //selection set up for (CheckBoxPreference preference : dataStorageRadioButtonsGroup) { @@ -526,10 +472,6 @@ private void confirm(OsmandApplication app, OsmandActionBarActivity activity, St private void refreshDataInfo() { dataStorageHelper = new DataStorageHelper(app); - if (!storageMigration && !firstUsage) { - asyncLoader = new LocalItemsLoaderTask(app, this); - asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java index 2151379e58ee..6fdcb629716c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java @@ -21,9 +21,9 @@ import net.osmand.plus.activities.RestartActivity; import net.osmand.plus.dialogs.LocationSourceBottomSheet; import net.osmand.plus.dialogs.MapRenderingEngineDialog; +import net.osmand.plus.dialogs.SpeedCamerasBottomSheet; import net.osmand.plus.feedback.SendAnalyticsBottomSheetDialogFragment; import net.osmand.plus.feedback.SendAnalyticsBottomSheetDialogFragment.OnSendAnalyticsPrefsUpdate; -import net.osmand.plus.dialogs.SpeedCamerasBottomSheet; import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.profiles.SelectDefaultProfileBottomSheet; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; @@ -231,12 +231,13 @@ private void setupPreferredLocalePref() { } private void setupExternalStorageDirPref() { - Preference externalStorageDir = findPreference(OsmandSettings.EXTERNAL_STORAGE_DIR); - externalStorageDir.setIcon(getContentIcon(R.drawable.ic_action_folder)); + Preference preference = findPreference(OsmandSettings.EXTERNAL_STORAGE_DIR); + preference.setIcon(getContentIcon(R.drawable.ic_action_folder)); + + DataStorageHelper storageHelper = new DataStorageHelper(app); + StorageItem currentStorage = storageHelper.getCurrentStorage(); - DataStorageHelper holder = new DataStorageHelper(app); - StorageItem currentStorage = holder.getCurrentStorage(); - long totalUsed = app.getSettings().OSMAND_USAGE_SPACE.get(); + long totalUsed = settings.OSMAND_USAGE_SPACE.get(); if (totalUsed > 0) { String[] usedMemoryFormats = { getString(R.string.shared_string_memory_used_kb_desc), @@ -244,14 +245,11 @@ private void setupExternalStorageDirPref() { getString(R.string.shared_string_memory_used_gb_desc), getString(R.string.shared_string_memory_used_tb_desc) }; - String sTotalUsed = DataStorageHelper.getFormattedMemoryInfo(totalUsed, usedMemoryFormats); - String summary = String.format(getString(R.string.data_storage_preference_summary), - currentStorage.getTitle(), - sTotalUsed); - summary = summary.replaceAll(" • ", " • "); - externalStorageDir.setSummary(summary); + String usedSpace = DataStorageHelper.getFormattedMemoryInfo(totalUsed, usedMemoryFormats); + String summary = getString(R.string.data_storage_preference_summary, currentStorage.getTitle(), usedSpace); + preference.setSummary(summary.replaceAll(" • ", " • ")); } else { - externalStorageDir.setSummary(currentStorage.getTitle()); + preference.setSummary(currentStorage.getTitle()); } } From 47509f520911e5c0e27fb7bca33816ce3e3fdee6 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 16:26:37 +0000 Subject: [PATCH 26/96] Translated using Weblate (Swedish) Currently translated at 95.4% (4723 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index 0d83cea6cd88..e015d3193144 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -2617,7 +2617,7 @@ Gör inte Gör Endast på Wi-Fi - Hämta bilder + Ladda ner bilder Bilder från artiklar kan laddas ner för användning frånkopplad. \nDu kan alltid ändra inställningen i \"Utforska\" → \"Alternativ\". Endast på Wi-Fi @@ -3218,12 +3218,12 @@ sek Passerar Närma sig - Långt förberedan - Förbereda - Av rutten - Anländer till destinationen + Lång förberedelse + Förbered + Utanför rutten + Ankomst till destinationen Sväng - Tid- och avstånds-intervaller + Tids- och avståndsintervaller Meddelandetid för olika röstmeddelanden beror på typ, aktuell navigationshastighet och standardnavigeringshastighet. Meddelandetid Starta inspelning @@ -3376,7 +3376,7 @@ \n \n Uppdatera alla kartor som lagts till i %1$s\? - Utgångsnummer + Avfartsnummer Meddela när den överskrids Användarpunkter Utgång @@ -4273,7 +4273,7 @@ Dessa widgetar visar information om kommande soluppgång och solnedgång. Dela kraschlogg Stor - Höjd: kartcentrum + Höjd: kartans mitt Externa sensorer Åtkomst till externa sensorer för att läsa av t.ex. din puls, cykelhastighet, cykeleffekt eller kadens. Kräver att din enhet är ansluten till respektive sensor via det trådlösa personliga nätverksprotokollet ANT+. Visar cyklistens effekt, den kraft som genereras för att flytta cykeln framåt @@ -5200,4 +5200,14 @@ Kunde inte tolka geo-identifieraren \'%s\'. Prova navigering till fots. Monohjul + Föredra taktil beläggning + Föredra taktil beläggning + Fartkameror + I några länder och regioner är det förbjudet att använda funktioner som varnar för fartkameror. +\n +\nDu behöver göra ett val beroende på lagstiftningen i ditt land. +\n +\nVälj %1$s så kan du få information och varningar om fartkameror. +\n +\nVälj %2$s så kommer all data om fartkameror raderas (varningar, objekt i kartan etc) tills OsmAnd ominstalleras helt. \ No newline at end of file From 8a769cb987ff31dcf0a84e45d3cd6c12440a8d8d Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Wed, 25 Oct 2023 16:13:05 +0000 Subject: [PATCH 27/96] Translated using Weblate (Spanish) Currently translated at 100.0% (4949 of 4949 strings) --- OsmAnd/res/values-es/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 94f04f20c827..a4e3d5bcdb97 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -5443,7 +5443,7 @@ \n \n • Añadido widget \"RAM disponible\" \n -\n • Problemas fijos con barra de estado transparente +\n • Problemas solucionados con barra de estado transparente \n \n Cochecito @@ -5549,4 +5549,5 @@ Hacia abajo Abrir la cuadrícula de datos WunderLINQ Acciones + Error en la eliminación \ No newline at end of file From 93c6a613fadb498809966cb7e2672f6c50ce9211 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 25 Oct 2023 16:07:38 +0000 Subject: [PATCH 28/96] Translated using Weblate (Swedish) Currently translated at 95.5% (4427 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 81dd332e73a1..8ec7aafbff37 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -4428,4 +4428,6 @@ Kommunikation och media hbtq+ välkomna hbtq+ : primär målgrupp + Andning och respiration + Ortoser \ No newline at end of file From dedaafd07e28009660bfc66e05032023fe1a660e Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Wed, 25 Oct 2023 22:33:27 +0300 Subject: [PATCH 29/96] Use POJO for rendering test --- .../java/net/osmand/rendering/OpenGLTest.java | 276 +++++++++--------- 1 file changed, 146 insertions(+), 130 deletions(-) diff --git a/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java b/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java index 9f8061cf16dd..0d2993ddaddf 100644 --- a/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java +++ b/OsmAnd-java/src/test/java/net/osmand/rendering/OpenGLTest.java @@ -2,10 +2,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; +import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import net.osmand.PlatformUtil; @@ -31,14 +28,13 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; public class OpenGLTest { private Map DISTANCES_TABLE; private final int DISTANCE_ZOOM = 15; private final int MAX_ZOOM = 21; - private final int MAX_DISTANCE_IN_METERS = 300;//for 15 zoom + private final int MAX_DISTANCE_IN_METERS = 400;//for 15 zoom protected Log log = PlatformUtil.getLog(OpenGLTest.class); private final String PATH_TO_RESOURCES = "src/test/resources/rendering/"; private final String TES_JSON = "/test_3d_rendering.json"; @@ -82,44 +78,38 @@ private void initDistanceTable() { private List generateCommands(String eyepiecePath) { Reader reader = new InputStreamReader(Objects.requireNonNull(RouteResultPreparationTest.class.getResourceAsStream(TES_JSON))); Gson gson = new GsonBuilder().setPrettyPrinting().create(); - JsonArray arr = gson.fromJson(reader, JsonArray.class); + TestEntry[] arr = gson.fromJson(reader, TestEntry[].class); LinkedList res = new LinkedList<>(); - for (int i = 0; i < arr.size(); i++) { + for (TestEntry testEntry : arr) { EyepieceParams params = new EyepieceParams(); - JsonObject o = (JsonObject) arr.get(i); - JsonObject center = o.getAsJsonObject("center"); - assert(center != null); - params.latitude = center.getAsJsonPrimitive("latitude").getAsDouble(); - params.longitude = center.getAsJsonPrimitive("longitude").getAsDouble(); + assert(testEntry.center != null); + params.latitude = testEntry.center.latitude; + params.longitude = testEntry.center.longitude; - parseVisibilityZoom(o.getAsJsonArray("icons"), params); - parseVisibilityZoom(o.getAsJsonArray("textOnPath"), params); - parseVisibilityZoom(o.getAsJsonArray("text"), params); + parseVisibilityZoom(testEntry.icons, params); + parseVisibilityZoom(testEntry.textOnPath, params); + parseVisibilityZoom(testEntry.text, params); - JsonPrimitive eyepieceParams = o.getAsJsonPrimitive("eyepieceParams"); - if (eyepieceParams != null) { - params.commandParams = eyepieceParams.getAsString(); + if (testEntry.eyepieceParams != null) { + params.commandParams = testEntry.eyepieceParams; } - - JsonPrimitive testName = o.getAsJsonPrimitive("testName"); - assert(testName != null); - params.testName = testName.getAsString(); + assert(testEntry.testName != null); + params.testName = testEntry.testName; res.add(params.getCommand(eyepiecePath)); } return res; } - private void parseVisibilityZoom(JsonArray arr, EyepieceParams params) { - if (arr == null) { + private void parseVisibilityZoom(List unitList, EyepieceParams params) { + if (unitList == null) { return; } - for (int i = 0; i < arr.size(); i++) { - JsonObject obj = (JsonObject) arr.get(i); - JsonObject zooms = obj.getAsJsonObject("visibilityZoom"); - Set> set = zooms.entrySet(); - for (Map.Entry s : set) { - int z = Integer.parseInt(s.getKey()); - params.registerZoom(z); + for (TestEntryUnit testEntryUnit : unitList) { + if (testEntryUnit.visibilityZoom == null) { + continue; + } + for (Map.Entry entry : testEntryUnit.visibilityZoom.entrySet()) { + params.registerZoom(entry.getKey()); } } } @@ -161,18 +151,15 @@ private void test() throws FileNotFoundException { cummulativeException = new CummulativeException(); Reader reader = new InputStreamReader(Objects.requireNonNull(RouteResultPreparationTest.class.getResourceAsStream(TES_JSON))); Gson gson = new GsonBuilder().setPrettyPrinting().create(); - JsonArray arr = gson.fromJson(reader, JsonArray.class); - for (int i = 0; i < arr.size(); i++) { - JsonObject o = (JsonObject) arr.get(i); - JsonPrimitive testNamePrimitive = o.getAsJsonPrimitive("testName"); - assert(testNamePrimitive != null); - String testName = testNamePrimitive.getAsString(); - cummulativeException.setCurrentTestName(testName); - List renderedInfo = parseRenderedJsonForMap(testName); + TestEntry[] arr = gson.fromJson(reader, TestEntry[].class); + for (TestEntry testEntry : arr) { + assert(testEntry.testName != null); + cummulativeException.setCurrentTestName(testEntry.testName); + List renderedInfo = parseRenderedJsonForMap(testEntry.testName); if (renderedInfo.size() == 0) { - throw new RuntimeException("File(s) is empty for test:" + testName); + throw new RuntimeException("File(s) is empty for test:" + testEntry.testName); } - List testInfo = parseTestJson(o); + List testInfo = parseTestJson(testEntry); compareTestAndRenderedInfo(testInfo, renderedInfo); } if (cummulativeException.hasExceptions()) { @@ -196,81 +183,58 @@ public boolean accept(File pathname) { List renderedInfo = new ArrayList<>(); for (File f : jsonFiles) { Gson gson = new Gson(); - JsonArray arr = gson.fromJson(new JsonReader(new FileReader(f)), JsonArray.class); + RenderEntry[] arr = gson.fromJson(new JsonReader(new FileReader(f)), RenderEntry[].class); renderedInfo.addAll(parseRenderedJson(arr)); } return renderedInfo; } - private List parseRenderedJson(JsonArray arr) { + private List parseRenderedJson(RenderEntry[] arr) { if (arr == null) { return null; } List info = new ArrayList(); - for (int i = 0; i < arr.size(); i++) { + for (RenderEntry renderEntry : arr) { RenderedInfo ri = new RenderedInfo(); - JsonObject obj = (JsonObject) arr.get(i); - String cl = obj.getAsJsonPrimitive("class").getAsString(); - String type = obj.getAsJsonPrimitive("type").getAsString(); - ri.setType(cl, type); - ri.zoom = obj.getAsJsonPrimitive("zoom").getAsInt(); - ri.id = obj.getAsJsonPrimitive("id").getAsLong(); - double lat = obj.getAsJsonPrimitive("lat").getAsDouble(); - double lon = obj.getAsJsonPrimitive("lon").getAsDouble(); - ri.center = new LatLon(lat, lon); - - JsonObject start = obj.getAsJsonObject("startPoint"); - JsonObject end = obj.getAsJsonObject("endPoint"); - if (start != null && end != null) { - lat = start.getAsJsonPrimitive("lat").getAsDouble(); - lon = start.getAsJsonPrimitive("lon").getAsDouble(); - ri.startPoint = new LatLon(lat, lon); - lat = end.getAsJsonPrimitive("lat").getAsDouble(); - lon = end.getAsJsonPrimitive("lon").getAsDouble(); - ri.endPoint = new LatLon(lat, lon); - } - JsonPrimitive content = obj.getAsJsonPrimitive("content"); - if (content != null) { - ri.content = content.getAsString(); - } + assert(renderEntry.cl != null && renderEntry.type != null); + ri.setType(renderEntry.cl, renderEntry.type); + ri.zoom = renderEntry.zoom; + ri.id = renderEntry.id; + ri.center = new LatLon(renderEntry.lat, renderEntry.lon); + if (renderEntry.startPoint != null && renderEntry.endPoint != null) { + ri.startPoint = new LatLon(renderEntry.startPoint.lat, renderEntry.startPoint.lon); + ri.endPoint = new LatLon(renderEntry.endPoint.lat, renderEntry.endPoint.lon); + } + ri.content = renderEntry.content; info.add(ri); } return info; } - private List parseTestJson(JsonObject testJsonObj) { + private List parseTestJson(TestEntry testEntry) { List result = new ArrayList<>(); - parseTestJsonArr(testJsonObj.getAsJsonArray("icons"), result, RenderedType.ICON); - parseTestJsonArr(testJsonObj.getAsJsonArray("text"), result, RenderedType.TEXT_ON_POINT); - parseTestJsonArr(testJsonObj.getAsJsonArray("textOnPath"), result, RenderedType.TEXT_ON_LINE); + parseTestJsonArr(testEntry.icons, result, RenderedType.ICON); + parseTestJsonArr(testEntry.text, result, RenderedType.TEXT_ON_POINT); + parseTestJsonArr(testEntry.textOnPath, result, RenderedType.TEXT_ON_LINE); return result; } - private void parseTestJsonArr(JsonArray arr, List result, RenderedType type) { - if (arr == null) { + private void parseTestJsonArr(List unitList, List result, RenderedType type) { + if (unitList == null) { return; } - for (int i = 0; i < arr.size(); i++) { + for (TestEntryUnit testEntryUnit : unitList) { TestInfo testInfo = new TestInfo(); - JsonObject obj = (JsonObject) arr.get(i); - if (obj.getAsJsonPrimitive("osmId") == null) { - throw new RuntimeException("osmId not found"); - } - if (obj.getAsJsonObject("visibilityZoom") == null) { + if (testEntryUnit.visibilityZoom == null) { throw new RuntimeException("visibilityZoom not found"); } - try { - testInfo.id = obj.getAsJsonPrimitive("osmId").getAsLong(); - } catch (NumberFormatException e) { - throw new RuntimeException("osmId is empty"); - } - JsonObject zooms = obj.getAsJsonObject("visibilityZoom"); - Set> set = zooms.entrySet(); - for (Map.Entry s : set) { - int z = Integer.parseInt(s.getKey()); - String v = s.getValue().getAsString(); - boolean visible = "true".equals(v) || "yes".equals(v); + if (testEntryUnit.osmId != null) { + testInfo.id = testEntryUnit.osmId; + } + for (Map.Entry entry : testEntryUnit.visibilityZoom.entrySet()) { + int z = entry.getKey(); + boolean visible = entry.getValue(); if (visible) { testInfo.addVisibleZoom(z); } else { @@ -278,34 +242,14 @@ private void parseTestJsonArr(JsonArray arr, List result, RenderedType } } - JsonPrimitive lat = obj.getAsJsonPrimitive("latitude"); - JsonPrimitive lon = obj.getAsJsonPrimitive("longitude"); - if (lat != null && lon != null) { - testInfo.center = new LatLon(lat.getAsDouble(), lon.getAsDouble()); - } - - lat = obj.getAsJsonPrimitive("lat"); - lon = obj.getAsJsonPrimitive("lon"); - if (lat != null && lon != null) { - testInfo.center = new LatLon(lat.getAsDouble(), lon.getAsDouble()); - } - - JsonPrimitive name = obj.getAsJsonPrimitive("name"); - if (name != null) { - testInfo.text = name.getAsString(); + if (testEntryUnit.latitude != null && testEntryUnit.longitude != null) { + testInfo.center = new LatLon(testEntryUnit.latitude, testEntryUnit.longitude); } - JsonObject startPoint = obj.getAsJsonObject("startPoint"); - JsonObject endPoint = obj.getAsJsonObject("endPoint"); - if (startPoint != null && endPoint != null) { - lat = startPoint.getAsJsonPrimitive("latitude"); - lon = startPoint.getAsJsonPrimitive("longitude"); - assert (lat != null && lon != null); - testInfo.startPoint = new LatLon(lat.getAsDouble(), lon.getAsDouble()); - lat = endPoint.getAsJsonPrimitive("latitude"); - lon = endPoint.getAsJsonPrimitive("longitude"); - assert (lat != null && lon != null); - testInfo.endPoint = new LatLon(lat.getAsDouble(), lon.getAsDouble()); + testInfo.text = testEntryUnit.name; + if (testEntryUnit.startPoint != null && testEntryUnit.endPoint != null) { + testInfo.startPoint = new LatLon(testEntryUnit.startPoint.latitude, testEntryUnit.startPoint.longitude); + testInfo.endPoint = new LatLon(testEntryUnit.endPoint.latitude, testEntryUnit.endPoint.longitude); } testInfo.type = type; @@ -323,6 +267,8 @@ private void compareTestAndRenderedInfo(List testInfo, List renderedInfo, TestInfo testInfo) { HashSet checkedZooms = testInfo.visibleZooms; checkedZooms.addAll(testInfo.inVisibleZooms); + String name = testInfo.text != null ? " name:\"" + testInfo.text + "\"" : ""; + String type = testInfo.type == RenderedType.ICON ? "icon " : "text "; for (RenderedInfo info : renderedInfo) { int zoom = info.zoom; if (!checkedZooms.contains(zoom)) { @@ -333,7 +279,7 @@ private void checkOsmIdAndText(List renderedInfo, TestInfo testInf continue; } if (info.id == testInfo.id && testInfo.inVisibleZooms.contains(zoom)) { - cummulativeException.addException("osmId:" + testInfo.id + " must be not visible on zoom:" + zoom); + cummulativeException.addException(type + "osmId:" + testInfo.id + name + " must be not visible on zoom:" + zoom); checkedZooms.remove(zoom); continue; } @@ -355,14 +301,19 @@ private void checkOsmIdAndText(List renderedInfo, TestInfo testInf double dist = MapUtils.getDistance(c, c2); if (dist <= DISTANCES_TABLE.get(zoom)) { if (testInfo.inVisibleZooms.contains(zoom)) { - cummulativeException.addException("text:" + testInfo.text + " must be not visible on zoom:" + zoom); + cummulativeException.addException("text \"" + testInfo.text + "\" must be not visible on zoom:" + zoom); } } else { - cummulativeException.addException("text:" + testInfo.text + " is visible on zoom:" + zoom + - ", but too far from test location. Found location " + info.id + " " + c2.getLatitude() + " " + c2.getLongitude() + - ". Distance " + (int) dist + " meters"); + cummulativeException.addException("text \"" + testInfo.text + "\" is visible on zoom:" + zoom + + ", but too far from test location. Found location " + + String.format("%,.5f", c2.getLatitude()) + " " + String.format("%,.5f", c2.getLongitude()) + + " (" + info.id + ") " + + ". Distance " + (int) dist + " meters. Maximum distance for zoom=" + zoom + " is " + DISTANCES_TABLE.get(zoom) + " meters"); } checkedZooms.remove(zoom); + } else if (c == null) { + //lat and lon is not set in the test, just check visibility + checkedZooms.remove(zoom); } } } @@ -372,8 +323,7 @@ private void checkOsmIdAndText(List renderedInfo, TestInfo testInf } checkedZooms.removeAll(testInfo.inVisibleZooms); if (checkedZooms.size() > 0) { - String name = testInfo.text != null ? " name:\"" + testInfo.text + "\"" : ""; - cummulativeException.addException("osmId:" + testInfo.id + name + " must be visible on zooms:" + checkedZooms.toString()); + cummulativeException.addException(type + "osmId:" + testInfo.id + name + " must be visible on zooms:" + checkedZooms.toString()); } } @@ -405,7 +355,7 @@ public void setType(String cl, String type) { } private class TestInfo { - long id; + long id = -1; LatLon center; LatLon startPoint; LatLon endPoint; @@ -422,13 +372,10 @@ void addInVisibleZoom(int zoom) { } private class CummulativeException { - Map> exceptions; + Map> exceptions = new HashMap<>(); String currentTestName = ""; void addException(String e) { - if (exceptions == null) { - exceptions = new HashMap<>(); - } if (currentTestName.isEmpty()) { throw new RuntimeException("Set test name"); } @@ -513,4 +460,73 @@ String getCommand(String eyepiecePath) { } } + private class TestEntry { + @SerializedName("testName") + public String testName; + @SerializedName("description") + public String description; + @SerializedName("center") + public Coordinates center; + @SerializedName("icons") + public List icons; + @SerializedName("text") + public List text; + @SerializedName("textOnPath") + public List textOnPath; + @SerializedName("eyepieceParams") + public String eyepieceParams; + } + + private class TestEntryUnit { + @SerializedName("osmId") + public Long osmId; + @SerializedName("name") + public String name; + @SerializedName("latitude") + public Double latitude; + @SerializedName("longitude") + public Double longitude; + @SerializedName("visibilityZoom") + Map visibilityZoom; + @SerializedName("startPoint") + Coordinates startPoint; + @SerializedName("endPoint") + Coordinates endPoint; + } + + private class Coordinates { + @SerializedName("latitude") + public Double latitude; + @SerializedName("longitude") + public Double longitude; + } + + private class Coords { + @SerializedName("lat") + public Double lat; + @SerializedName("lon") + public Double lon; + } + + private class RenderEntry { + @SerializedName("class") + public String cl; + @SerializedName("type") + public String type; + @SerializedName("zoom") + public Integer zoom; + @SerializedName("id") + public Long id; + @SerializedName("lat") + public Double lat; + @SerializedName("lon") + public Double lon; + @SerializedName("startPoint") + public Coords startPoint; + @SerializedName("endPoint") + public Coords endPoint; + @SerializedName("content") + public String content; + } + } From a6a7b4d30944bb9f5a1a2324c1691cbae40913ee Mon Sep 17 00:00:00 2001 From: whatismoss Date: Wed, 25 Oct 2023 19:43:25 +0000 Subject: [PATCH 30/96] Translated using Weblate (Catalan) Currently translated at 77.3% (3829 of 4949 strings) --- OsmAnd/res/values-ca/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index b4d01c1390b9..991bb2810e88 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -4315,4 +4315,17 @@ Mostra el nivell RSSI del vostre dispositiu extern. RSSI Segur que voleu suprimir la carpeta\? + Bicicleta + Files + Error de supressió + Compte + MGRS + A peu + Iniciar sessió + Vehicle + Subtipus + MGRS + Cotxe + Viatge + Cotxe \ No newline at end of file From e5041ea645b78623456fe4931e2c6aad6df6dbe4 Mon Sep 17 00:00:00 2001 From: whatismoss Date: Wed, 25 Oct 2023 19:11:43 +0000 Subject: [PATCH 31/96] Translated using Weblate (French) Currently translated at 99.9% (4947 of 4949 strings) --- OsmAnd/res/values-fr/strings.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 0b1ea79b2655..65d3e1b12fa7 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -5418,7 +5418,9 @@ Spécifiez l\'adresse web avec la syntaxe de paramètre suivants : lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. Température Affiche la température fournie par le capteur - • Ajout du gadget \"finesse de l\'aile\" + • Ajout de la possibilité de changer les assignements de touches pour les périphériques externes +\n +\n• Ajout du gadget \"finesse de l\'aile\" \n \n• Ajout de filtres et de dossiers intelligents pour les traces \n @@ -5526,4 +5528,15 @@ Interactions avec la carte Déplacer vers le bas Actions + Activer pour utiliser l\'appareil d\'entrée externe avec OsmAnd + Profile d\'application précédent + Appuyez sur le bouton de votre appareil pour le lier à l\'action choisie. + Erreur de suppression + Profil d\'application suivant + Changer l\'assignement de touche + Prendre une note média + Émettre un indice de guidage + Périphériques d\'entrée externes + Assignements des touches + Open WunderLINQ Datagrid \ No newline at end of file From 8d9fa75b9f34e01c30dfeb3f250808abdbf77262 Mon Sep 17 00:00:00 2001 From: SC Date: Wed, 25 Oct 2023 17:26:59 +0000 Subject: [PATCH 32/96] Translated using Weblate (Portuguese) Currently translated at 100.0% (4635 of 4635 strings) --- OsmAnd/res/values-pt/phrases.xml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index 23051e82d446..3796190d48ff 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -3293,7 +3293,7 @@ Tomadas: NEMA 5-20: amperes Tomadas: NEMA 5-20: watts Tomadas: NEMA 14-30 - Tomads: NEMA 14-30: amperes + Tomadas: NEMA 14-30: amperes Tomadas: NEMA 14-30: watts Tomadas: NEMA 14-50 Tomadas: NEMA 14-50: amperes @@ -4412,8 +4412,8 @@ Saída para cabo de tomada tipo 2 Saída da tomada tipo 3a Saída da tomada tipo 3c - Tomadas: cabo Tipo 2:corrente - Tomadas: cabo Tipo 2: saída + Tomadas: cabo Tipo 2: amperes + Tomadas: cabo Tipo 2: watts Tomadas: Tipo 3a: voltagem Tomadas: Tipo 3c: corrente Tomadas: Tipo 3c: saída @@ -4604,7 +4604,7 @@ Alergia Alta Alta - Tomada: Tipo E + Tomadas: Tipo E Baixa Reumatologia Fertilidade @@ -4617,16 +4617,22 @@ Comunidade Cirurgia cardíaca Média - Haematologia + Hematologia Geriatria Perda de peso Doenças infeciosas Voltagem da tomada tipo E - Tomada: Tipo E: corrente - Checkpoint de ciclismo + Tomadas: Tipo E: amperes + Posto de controlo de ciclismo Tipo E Saída da tomada tipo E - Intenso + Cuidados intensivos Tomadas: Tipo E: voltagem - Tomada: Tipo E: saída + Tomadas: Tipo E: watts + Periodontia + Vestiário + Análises sanguíneas + Área de emergência + Cirurgia pediátrica + Odontopediatria \ No newline at end of file From 8f17be1e7b62178f41099ec5f04727b4605267bd Mon Sep 17 00:00:00 2001 From: Dmitry <31807095+Dima-1@users.noreply.github.com> Date: Thu, 26 Oct 2023 01:45:39 -0700 Subject: [PATCH 33/96] Fix 16434 Highway shield steals numbers from the route/ref/name (#18392) * Fix 16434 Highway shield steals numbers from the route/ref/name * Fix review * Add multiple shields * Fix shield blinking --- OsmAnd/res/layout-land/street_name_widget.xml | 12 ++- OsmAnd/res/layout/street_name_widget.xml | 15 +-- .../plus/routing/CurrentStreetName.java | 65 ++++++++++++- .../plus/routing/RoutingHelperUtils.java | 43 +++++++-- .../mapwidgets/widgets/StreetNameWidget.java | 95 +++++++++---------- 5 files changed, 156 insertions(+), 74 deletions(-) diff --git a/OsmAnd/res/layout-land/street_name_widget.xml b/OsmAnd/res/layout-land/street_name_widget.xml index 2c6dced7d248..9743948456af 100644 --- a/OsmAnd/res/layout-land/street_name_widget.xml +++ b/OsmAnd/res/layout-land/street_name_widget.xml @@ -35,12 +35,14 @@ android:layout_height="@dimen/map_widget_height" android:scaleType="fitCenter" /> - + android:layout_gravity="center" + android:gravity="center" + android:orientation="horizontal"> + - + + shieldTags = new LinkedHashMap<>(); + private StringBuilder additional; + + public RoadShield(@NonNull RouteDataObject rdo) { + this.rdo = rdo; + StringBuilder additional = new StringBuilder(); + for (int i = 0; i < rdo.nameIds.length; i++) { + String key = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); + String val = rdo.names.get(rdo.nameIds[i]); + if (!key.endsWith("_ref") && !key.startsWith("route_road")) { + additional.append(key).append("=").append(val).append(";"); + } else if (key.startsWith("route_road") && key.endsWith("_ref")) { + shieldTags.put(key, val); + } + } + if (!shieldTags.isEmpty()) { + this.additional = additional; + } + } + + public static RoadShield create(@Nullable RouteDataObject rdo) { + if (rdo != null && rdo.nameIds != null) { + return new RoadShield(rdo); + } + return null; + } + + public RouteDataObject getRdo() { + return rdo; + } + + public StringBuilder getAdditional() { + return additional; + } + + public Map getShieldTags() { + return shieldTags; + } + + public boolean hasShield() { + return !shieldTags.isEmpty(); + } + + public boolean equalsShield(@Nullable RoadShield roadShield) { + return roadShield != null && shieldTags.equals(roadShield.shieldTags); + } + } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index 6488c0432b9a..cb6126e9a3c1 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -1,5 +1,7 @@ package net.osmand.plus.routing; +import static net.osmand.plus.routing.CurrentStreetName.*; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -12,6 +14,7 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.Arrays; @@ -27,23 +30,47 @@ public class RoutingHelperUtils { @NonNull public static String formatStreetName(String name, String ref, String destination, String towards) { - String formattedStreetName = ""; - if (ref != null && ref.length() > 0) { - formattedStreetName = ref; + return formatStreetName(name, ref, destination, towards, null); + } + + @NonNull + public static String formatStreetName(String name, String originalRef, String destination, String towards, + RoadShield shield) { + StringBuilder formattedStreetName = new StringBuilder(); + if (originalRef != null && originalRef.length() > 0) { + String[] refs = originalRef.split(";"); + for (String ref : refs) { + if (shield == null || !isRefEqualsShield(shield, ref)) { + if (formattedStreetName.length() > 0) { + formattedStreetName.append(" "); + } + formattedStreetName.append(ref); + } + } } if (name != null && name.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName = formattedStreetName + " "; + formattedStreetName.append(" "); } - formattedStreetName = formattedStreetName + name; + formattedStreetName.append(name); } if (destination != null && destination.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName = formattedStreetName + " "; + formattedStreetName.append(" "); } - formattedStreetName = formattedStreetName + towards + " " + destination; + formattedStreetName.append(towards).append(" ").append(destination); } - return formattedStreetName.replace(";", ", "); + return formattedStreetName.toString().replace(";", ", "); + } + + private static boolean isRefEqualsShield(RoadShield shield, String ref) { + for (Entry entry : shield.getShieldTags().entrySet()) { + String shieldText = entry.getValue(); + if (ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText)) { + return true; + } + } + return false; } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index c48a47638220..5170b00c3624 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -14,6 +14,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.ColorRes; @@ -39,6 +40,7 @@ import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.ShowAlongTheRouteBottomSheet; import net.osmand.plus.routing.CurrentStreetName; +import net.osmand.plus.routing.CurrentStreetName.RoadShield; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelperUtils; @@ -54,6 +56,7 @@ import net.osmand.util.Algorithms; import java.util.List; +import java.util.Map; public class StreetNameWidget extends MapWidget { @@ -65,15 +68,14 @@ public class StreetNameWidget extends MapWidget { private final TextView addressText; private final TextView addressTextShadow; private final TextView exitRefText; - private final ImageView shieldImage; + private final LinearLayout shieldImagesContainer; private final ImageView turnIcon; private final View waypointInfoBar; private final TurnDrawable turnDrawable; private int shadowRadius; private boolean showMarker; - private String roadShieldName; - + private RoadShield cachedRoadShield; @Override protected int getLayoutId() { @@ -89,7 +91,7 @@ public StreetNameWidget(@NonNull MapActivity mapActivity) { addressTextShadow = view.findViewById(R.id.map_address_text_shadow); waypointInfoBar = view.findViewById(R.id.waypoint_info_bar); exitRefText = view.findViewById(R.id.map_exit_ref); - shieldImage = view.findViewById(R.id.map_shield_icon); + shieldImagesContainer = view.findViewById(R.id.map_shields_container); turnIcon = view.findViewById(R.id.map_turn_icon); turnDrawable = new TurnDrawable(mapActivity, true); @@ -119,7 +121,7 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, false); AndroidUiHelper.updateVisibility(addressTextShadow, false); AndroidUiHelper.updateVisibility(turnIcon, false); - AndroidUiHelper.updateVisibility(shieldImage, false); + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); AndroidUiHelper.updateVisibility(exitRefText, false); } else if (streetName == null) { updateVisibility(false); @@ -129,20 +131,21 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, true); AndroidUiHelper.updateVisibility(addressTextShadow, shadowRadius > 0); - RouteDataObject shieldObject = streetName.shieldObject; - if (shieldObject != null && shieldObject.nameIds != null && setRoadShield(shieldObject)) { - AndroidUiHelper.updateVisibility(shieldImage, true); - int indexOf = streetName.text.indexOf("»"); - if (indexOf > 0) { - streetName.text = streetName.text.substring(indexOf); - } - if (roadShieldName != null && streetName.text.startsWith(roadShieldName)) { - streetName.text = streetName.text.replaceFirst(roadShieldName, ""); - streetName.text = streetName.text.trim(); + RoadShield shield = streetName.shield; + if (shield != null && !shield.equalsShield(cachedRoadShield)) { + if (setRoadShield(shield)) { + AndroidUiHelper.updateVisibility(shieldImagesContainer, true); + int indexOf = streetName.text.indexOf("»"); + if (indexOf > 0) { + streetName.text = streetName.text.substring(indexOf); + } + } else { + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); } - } else { - AndroidUiHelper.updateVisibility(shieldImage, false); - roadShieldName = null; + cachedRoadShield = shield; + } else if (shield == null) { + AndroidUiHelper.updateVisibility(shieldImagesContainer, false); + cachedRoadShield = null; } if (Algorithms.isEmpty(streetName.exitRef)) { @@ -212,30 +215,23 @@ public boolean updateWaypoint() { } } - private boolean setRoadShield(@NonNull RouteDataObject object) { - StringBuilder additional = new StringBuilder(); - for (int i = 0; i < object.nameIds.length; i++) { - String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); - String val = object.names.get(object.nameIds[i]); - if (!key.endsWith("_ref") && !key.startsWith("route_road")) { - additional.append(key).append("=").append(val).append(";"); - } - } - for (int i = 0; i < object.nameIds.length; i++) { - String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); - String val = object.names.get(object.nameIds[i]); - if (key.startsWith("route_road") && key.endsWith("_ref")) { - boolean visible = setRoadShield(object, key, val, additional); - if (visible) { - return true; - } + private boolean setRoadShield(@NonNull RoadShield shield) { + if (shield.hasShield()) { + boolean shieldSet = false; + shieldImagesContainer.removeAllViews(); + for (Map.Entry entry : shield.getShieldTags().entrySet()) { + String nameTag = entry.getKey(); + String text = entry.getValue(); + shieldSet |= setShieldImage(shield, nameTag, text); } + return shieldSet; } return false; } - private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String nameTag, - @NonNull String name, @NonNull StringBuilder additional) { + private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, String name) { + RouteDataObject object = shield.getRdo(); + StringBuilder additional = shield.getAdditional(); int[] types = object.getTypes(); RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer(); RenderingRuleSearchRequest rreq = app.getResourceManager().getRenderer() @@ -268,27 +264,21 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n "drawable", app.getPackageName()); } if (shieldRes == -1) { - roadShieldName = null; return false; } - Drawable shield = AppCompatResources.getDrawable(mapActivity, shieldRes); - if (shield == null) { - roadShieldName = null; + Drawable shieldDrawable = AppCompatResources.getDrawable(mapActivity, shieldRes); + if (shieldDrawable == null) { return false; } - float xSize = shield.getIntrinsicWidth(); - float ySize = shield.getIntrinsicHeight(); + float xSize = shieldDrawable.getIntrinsicWidth(); + float ySize = shieldDrawable.getIntrinsicHeight(); float xyRatio = xSize / ySize; //setting view proportions (height is fixed by toolbar size - 48dp); int viewHeightPx = AndroidUtils.dpToPx(app, 48); int viewWidthPx = (int) (viewHeightPx * xyRatio); - ViewGroup.LayoutParams params = shieldImage.getLayoutParams(); - params.width = viewWidthPx; - shieldImage.setLayoutParams(params); - Bitmap bitmap = Bitmap.createBitmap((int) xSize, (int) ySize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = setupTextPaint(app, textRenderer.getPaintText(), rreq); @@ -299,8 +289,15 @@ private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String n textRenderer.drawShieldIcon(rc, canvas, text, text.getShieldResIcon()); textRenderer.drawWrappedText(canvas, text, 20f); - shieldImage.setImageBitmap(bitmap); - roadShieldName = name; + ImageView imageView = new ImageView(view.getContext()); + int viewSize = AndroidUtils.dpToPx(app, 40f); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(viewWidthPx, viewSize); + int padding = AndroidUtils.dpToPx(app, 4f); + imageView.setPadding(0, 0, 0, padding); + imageView.setLayoutParams(params); + imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); + imageView.setImageBitmap(bitmap); + shieldImagesContainer.addView(imageView); return true; } From 236624534931c6da2dd36d28f2e67a42d18ade75 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 26 Oct 2023 13:06:14 +0300 Subject: [PATCH 34/96] Revert "Fix 16434 Highway shield steals numbers from the route/ref/name (#18392)" This reverts commit 8f17be1e7b62178f41099ec5f04727b4605267bd. --- OsmAnd/res/layout-land/street_name_widget.xml | 12 +-- OsmAnd/res/layout/street_name_widget.xml | 15 ++- .../plus/routing/CurrentStreetName.java | 65 +------------ .../plus/routing/RoutingHelperUtils.java | 43 ++------- .../mapwidgets/widgets/StreetNameWidget.java | 95 ++++++++++--------- 5 files changed, 74 insertions(+), 156 deletions(-) diff --git a/OsmAnd/res/layout-land/street_name_widget.xml b/OsmAnd/res/layout-land/street_name_widget.xml index 9743948456af..2c6dced7d248 100644 --- a/OsmAnd/res/layout-land/street_name_widget.xml +++ b/OsmAnd/res/layout-land/street_name_widget.xml @@ -35,14 +35,12 @@ android:layout_height="@dimen/map_widget_height" android:scaleType="fitCenter" /> - - + android:scaleType="fitCenter" + tools:src="@drawable/h_white_pillow_2_road_shield" /> - - + shieldTags = new LinkedHashMap<>(); - private StringBuilder additional; - - public RoadShield(@NonNull RouteDataObject rdo) { - this.rdo = rdo; - StringBuilder additional = new StringBuilder(); - for (int i = 0; i < rdo.nameIds.length; i++) { - String key = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); - String val = rdo.names.get(rdo.nameIds[i]); - if (!key.endsWith("_ref") && !key.startsWith("route_road")) { - additional.append(key).append("=").append(val).append(";"); - } else if (key.startsWith("route_road") && key.endsWith("_ref")) { - shieldTags.put(key, val); - } - } - if (!shieldTags.isEmpty()) { - this.additional = additional; - } - } - - public static RoadShield create(@Nullable RouteDataObject rdo) { - if (rdo != null && rdo.nameIds != null) { - return new RoadShield(rdo); - } - return null; - } - - public RouteDataObject getRdo() { - return rdo; - } - - public StringBuilder getAdditional() { - return additional; - } - - public Map getShieldTags() { - return shieldTags; - } - - public boolean hasShield() { - return !shieldTags.isEmpty(); - } - - public boolean equalsShield(@Nullable RoadShield roadShield) { - return roadShield != null && shieldTags.equals(roadShield.shieldTags); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index cb6126e9a3c1..6488c0432b9a 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -1,7 +1,5 @@ package net.osmand.plus.routing; -import static net.osmand.plus.routing.CurrentStreetName.*; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -14,7 +12,6 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; -import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import java.util.Arrays; @@ -30,47 +27,23 @@ public class RoutingHelperUtils { @NonNull public static String formatStreetName(String name, String ref, String destination, String towards) { - return formatStreetName(name, ref, destination, towards, null); - } - - @NonNull - public static String formatStreetName(String name, String originalRef, String destination, String towards, - RoadShield shield) { - StringBuilder formattedStreetName = new StringBuilder(); - if (originalRef != null && originalRef.length() > 0) { - String[] refs = originalRef.split(";"); - for (String ref : refs) { - if (shield == null || !isRefEqualsShield(shield, ref)) { - if (formattedStreetName.length() > 0) { - formattedStreetName.append(" "); - } - formattedStreetName.append(ref); - } - } + String formattedStreetName = ""; + if (ref != null && ref.length() > 0) { + formattedStreetName = ref; } if (name != null && name.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName.append(" "); + formattedStreetName = formattedStreetName + " "; } - formattedStreetName.append(name); + formattedStreetName = formattedStreetName + name; } if (destination != null && destination.length() > 0) { if (formattedStreetName.length() > 0) { - formattedStreetName.append(" "); + formattedStreetName = formattedStreetName + " "; } - formattedStreetName.append(towards).append(" ").append(destination); + formattedStreetName = formattedStreetName + towards + " " + destination; } - return formattedStreetName.toString().replace(";", ", "); - } - - private static boolean isRefEqualsShield(RoadShield shield, String ref) { - for (Entry entry : shield.getShieldTags().entrySet()) { - String shieldText = entry.getValue(); - if (ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText)) { - return true; - } - } - return false; + return formattedStreetName.replace(";", ", "); } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index 5170b00c3624..c48a47638220 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -14,7 +14,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.ColorRes; @@ -40,7 +39,6 @@ import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.ShowAlongTheRouteBottomSheet; import net.osmand.plus.routing.CurrentStreetName; -import net.osmand.plus.routing.CurrentStreetName.RoadShield; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelperUtils; @@ -56,7 +54,6 @@ import net.osmand.util.Algorithms; import java.util.List; -import java.util.Map; public class StreetNameWidget extends MapWidget { @@ -68,14 +65,15 @@ public class StreetNameWidget extends MapWidget { private final TextView addressText; private final TextView addressTextShadow; private final TextView exitRefText; - private final LinearLayout shieldImagesContainer; + private final ImageView shieldImage; private final ImageView turnIcon; private final View waypointInfoBar; private final TurnDrawable turnDrawable; private int shadowRadius; private boolean showMarker; - private RoadShield cachedRoadShield; + private String roadShieldName; + @Override protected int getLayoutId() { @@ -91,7 +89,7 @@ public StreetNameWidget(@NonNull MapActivity mapActivity) { addressTextShadow = view.findViewById(R.id.map_address_text_shadow); waypointInfoBar = view.findViewById(R.id.waypoint_info_bar); exitRefText = view.findViewById(R.id.map_exit_ref); - shieldImagesContainer = view.findViewById(R.id.map_shields_container); + shieldImage = view.findViewById(R.id.map_shield_icon); turnIcon = view.findViewById(R.id.map_turn_icon); turnDrawable = new TurnDrawable(mapActivity, true); @@ -121,7 +119,7 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, false); AndroidUiHelper.updateVisibility(addressTextShadow, false); AndroidUiHelper.updateVisibility(turnIcon, false); - AndroidUiHelper.updateVisibility(shieldImagesContainer, false); + AndroidUiHelper.updateVisibility(shieldImage, false); AndroidUiHelper.updateVisibility(exitRefText, false); } else if (streetName == null) { updateVisibility(false); @@ -131,21 +129,20 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, true); AndroidUiHelper.updateVisibility(addressTextShadow, shadowRadius > 0); - RoadShield shield = streetName.shield; - if (shield != null && !shield.equalsShield(cachedRoadShield)) { - if (setRoadShield(shield)) { - AndroidUiHelper.updateVisibility(shieldImagesContainer, true); - int indexOf = streetName.text.indexOf("»"); - if (indexOf > 0) { - streetName.text = streetName.text.substring(indexOf); - } - } else { - AndroidUiHelper.updateVisibility(shieldImagesContainer, false); + RouteDataObject shieldObject = streetName.shieldObject; + if (shieldObject != null && shieldObject.nameIds != null && setRoadShield(shieldObject)) { + AndroidUiHelper.updateVisibility(shieldImage, true); + int indexOf = streetName.text.indexOf("»"); + if (indexOf > 0) { + streetName.text = streetName.text.substring(indexOf); } - cachedRoadShield = shield; - } else if (shield == null) { - AndroidUiHelper.updateVisibility(shieldImagesContainer, false); - cachedRoadShield = null; + if (roadShieldName != null && streetName.text.startsWith(roadShieldName)) { + streetName.text = streetName.text.replaceFirst(roadShieldName, ""); + streetName.text = streetName.text.trim(); + } + } else { + AndroidUiHelper.updateVisibility(shieldImage, false); + roadShieldName = null; } if (Algorithms.isEmpty(streetName.exitRef)) { @@ -215,23 +212,30 @@ public boolean updateWaypoint() { } } - private boolean setRoadShield(@NonNull RoadShield shield) { - if (shield.hasShield()) { - boolean shieldSet = false; - shieldImagesContainer.removeAllViews(); - for (Map.Entry entry : shield.getShieldTags().entrySet()) { - String nameTag = entry.getKey(); - String text = entry.getValue(); - shieldSet |= setShieldImage(shield, nameTag, text); + private boolean setRoadShield(@NonNull RouteDataObject object) { + StringBuilder additional = new StringBuilder(); + for (int i = 0; i < object.nameIds.length; i++) { + String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); + String val = object.names.get(object.nameIds[i]); + if (!key.endsWith("_ref") && !key.startsWith("route_road")) { + additional.append(key).append("=").append(val).append(";"); + } + } + for (int i = 0; i < object.nameIds.length; i++) { + String key = object.region.routeEncodingRules.get(object.nameIds[i]).getTag(); + String val = object.names.get(object.nameIds[i]); + if (key.startsWith("route_road") && key.endsWith("_ref")) { + boolean visible = setRoadShield(object, key, val, additional); + if (visible) { + return true; + } } - return shieldSet; } return false; } - private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, String name) { - RouteDataObject object = shield.getRdo(); - StringBuilder additional = shield.getAdditional(); + private boolean setRoadShield(@NonNull RouteDataObject object, @NonNull String nameTag, + @NonNull String name, @NonNull StringBuilder additional) { int[] types = object.getTypes(); RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer(); RenderingRuleSearchRequest rreq = app.getResourceManager().getRenderer() @@ -264,21 +268,27 @@ private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, Strin "drawable", app.getPackageName()); } if (shieldRes == -1) { + roadShieldName = null; return false; } - Drawable shieldDrawable = AppCompatResources.getDrawable(mapActivity, shieldRes); - if (shieldDrawable == null) { + Drawable shield = AppCompatResources.getDrawable(mapActivity, shieldRes); + if (shield == null) { + roadShieldName = null; return false; } - float xSize = shieldDrawable.getIntrinsicWidth(); - float ySize = shieldDrawable.getIntrinsicHeight(); + float xSize = shield.getIntrinsicWidth(); + float ySize = shield.getIntrinsicHeight(); float xyRatio = xSize / ySize; //setting view proportions (height is fixed by toolbar size - 48dp); int viewHeightPx = AndroidUtils.dpToPx(app, 48); int viewWidthPx = (int) (viewHeightPx * xyRatio); + ViewGroup.LayoutParams params = shieldImage.getLayoutParams(); + params.width = viewWidthPx; + shieldImage.setLayoutParams(params); + Bitmap bitmap = Bitmap.createBitmap((int) xSize, (int) ySize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = setupTextPaint(app, textRenderer.getPaintText(), rreq); @@ -289,15 +299,8 @@ private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, Strin textRenderer.drawShieldIcon(rc, canvas, text, text.getShieldResIcon()); textRenderer.drawWrappedText(canvas, text, 20f); - ImageView imageView = new ImageView(view.getContext()); - int viewSize = AndroidUtils.dpToPx(app, 40f); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(viewWidthPx, viewSize); - int padding = AndroidUtils.dpToPx(app, 4f); - imageView.setPadding(0, 0, 0, padding); - imageView.setLayoutParams(params); - imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); - imageView.setImageBitmap(bitmap); - shieldImagesContainer.addView(imageView); + shieldImage.setImageBitmap(bitmap); + roadShieldName = name; return true; } From 52265253602c99d5f0b43ec387969f68fb5290f6 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Thu, 26 Oct 2023 13:28:16 +0300 Subject: [PATCH 35/96] Fix "No enum class ZoomLevel with value -2" --- .../net/osmand/plus/views/OsmandMapTileView.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index ceaee53b0e50..e5e55f8a3b55 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -1299,6 +1299,7 @@ private void setZoomAndAnimationImpl(int zoom, double zoomAnimation, double zoom } private void setZoomAndAnimationImpl(int zoom, double zoomAnimation, double zoomFloatPart, int centerX, int centerY) { + zoom = getZoomInLimits(zoom); MapRendererView mapRenderer = getMapRenderer(); if (mapRenderer != null) { int centerX31Before = 0; @@ -1621,12 +1622,25 @@ public boolean onGenericMotionEvent(MotionEvent event) { double lat = tb.getLatFromPixel(event.getX(), event.getY()); double lon = tb.getLonFromPixel(event.getX(), event.getY()); int zoomDir = event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0 ? -1 : 1; - getAnimatedDraggingThread().startMoving(lat, lon, getZoom() + zoomDir, true); + int endZoom = getZoomInLimits(getZoom() + zoomDir); + getAnimatedDraggingThread().startMoving(lat, lon, endZoom, true); return true; } return false; } + private int getZoomInLimits(int targetZoom) { + int minZoom = getMinZoom(); + int maxZoom = getMaxZoom(); + Zoom zoom = new Zoom(targetZoom, getZoomFloatPart(), minZoom, maxZoom); + if (!zoom.isZoomOutAllowed()) { + return minZoom; + } else if (!zoom.isZoomInAllowed()) { + return maxZoom; + } + return targetZoom; + } + private void findFirstTouchMapLocation(float touchPointX, float touchPointY) { MapRendererView mapRenderer = getMapRenderer(); if (mapRenderer != null) { From 3611396104a626c853911df7ef79bc2cbfc80a54 Mon Sep 17 00:00:00 2001 From: Sergey Kharchenko Date: Thu, 26 Oct 2023 13:45:21 +0300 Subject: [PATCH 36/96] Fixes after review --- .../tracks/TrackFolderLoaderTask.java | 1 - .../tracks/filters/SmartFolderHelper.kt | 35 ++++++++++--------- .../net/osmand/plus/track/data/SmartFolder.kt | 6 +--- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java index 16f205244ce8..205a1fa771fd 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java @@ -44,7 +44,6 @@ protected void onPreExecute() { if (listener != null) { listener.loadTracksStarted(); } - smartFolderHelper.resetSmartFoldersItems(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt index 7451c3296626..343357b7c41b 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt @@ -25,8 +25,9 @@ class SmartFolderHelper(val app: OsmandApplication) { .create() private var smartFolderCollection: MutableList = ArrayList() - private val allAvailableTrackItems = HashSet() - private val updateListeners = ArrayList() + private var allAvailableTrackItems = HashSet() + private var updateListeners: MutableList = mutableListOf() + private var isWritingSettings = false private val settingsChangedListener = StateChangedListener { onSettingsChanged() } @@ -42,7 +43,9 @@ class SmartFolderHelper(val app: OsmandApplication) { } private fun onSettingsChanged() { - updateSmartFolderSettings() + if (!isWritingSettings) { + updateSmartFolderSettings() + } } private fun readSettings() { @@ -142,19 +145,21 @@ class SmartFolderHelper(val app: OsmandApplication) { fun addUpdateListener(listener: SmartFolderUpdateListener) { if (!updateListeners.contains(listener)) { - Algorithms.addToList(updateListeners, listener) + updateListeners = Algorithms.addToList(updateListeners, listener) } } fun removeUpdateListener(listener: SmartFolderUpdateListener) { if (updateListeners.contains(listener)) { - Algorithms.removeFromList(updateListeners, listener) + updateListeners = Algorithms.removeFromList(updateListeners, listener) } } private fun writeSettings() { - val json = gson.toJson(ArrayList(smartFolderCollection)) + isWritingSettings = true + val json = gson.toJson(smartFolderCollection) preference.set(json) + isWritingSettings = false } fun isSmartFolderPresent(name: String): Boolean { @@ -162,8 +167,7 @@ class SmartFolderHelper(val app: OsmandApplication) { } private fun getSmartFolderByName(name: String): SmartFolder? { - val smartFolders = ArrayList(smartFolderCollection) - for (folder in smartFolders) { + for (folder in smartFolderCollection) { if (Algorithms.stringsEqual(folder.folderName, name)) { return folder } @@ -182,19 +186,17 @@ class SmartFolderHelper(val app: OsmandApplication) { } fun deleteSmartFolder(smartFolder: SmartFolder) { - val smartFolders = ArrayList() - smartFolders.remove(smartFolder) - smartFolderCollection = smartFolders + smartFolderCollection = Algorithms.removeFromList(smartFolderCollection, smartFolder) writeSettings() notifyUpdateListeners() } fun addTrackItemToSmartFolder(item: TrackItem) { LOG.debug("addTrackItemToSmartFolder") - if (!allAvailableTrackItems.contains(item)) { - allAvailableTrackItems.add(item) - } - addTracksToSmartFolders(arrayListOf(item), ArrayList(smartFolderCollection)) + val newSet = HashSet(allAvailableTrackItems) + newSet.add(item) + allAvailableTrackItems = newSet + addTracksToSmartFolders(arrayListOf(item), smartFolderCollection) } private fun addTracksToSmartFolders(items: List, smartFolders: List) { @@ -249,8 +251,7 @@ class SmartFolderHelper(val app: OsmandApplication) { override fun doInBackground(vararg params: Void): Void? { app.smartFolderHelper.run { readSettings() - val smartFolders = ArrayList(smartFolderCollection) - for (folder in smartFolders) { + for (folder in smartFolderCollection) { updateSmartFolderItems(folder) } notifyUpdateListeners() diff --git a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt index 682466f9418a..c523df8f41bf 100644 --- a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt +++ b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt @@ -47,10 +47,6 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { return folderAnalysis!! } - fun updateAnalysis() { - folderAnalysis = TrackFolderAnalysis(this) - } - override fun getDirName(): String { return folderName } @@ -60,7 +56,7 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { } fun resetItems() { - trackItems.clear() + trackItems = ArrayList() folderAnalysis = null } } \ No newline at end of file From 16edb8521ff22edb86ae8b355b66d54082669c5e Mon Sep 17 00:00:00 2001 From: chumva Date: Thu, 26 Oct 2023 18:01:20 +0300 Subject: [PATCH 37/96] Fix #18359 --- .../net/osmand/plus/backup/BackupHelper.java | 7 ++ .../osmand/plus/backup/BackupListeners.java | 32 +++++- .../backup/commands/CheckCodeCommand.java | 97 +++++++++++++++++++ .../plus/backup/ui/AuthorizeFragment.java | 75 ++++++++++---- 4 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/backup/commands/CheckCodeCommand.java diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java index 4866906e398e..1db7e0a11f65 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java @@ -27,6 +27,7 @@ import net.osmand.plus.backup.BackupListeners.OnUpdateSubscriptionListener; import net.osmand.plus.backup.BackupListeners.OnUploadFileListener; import net.osmand.plus.backup.PrepareBackupTask.OnPrepareBackupListener; +import net.osmand.plus.backup.commands.CheckCodeCommand; import net.osmand.plus.backup.commands.DeleteAccountCommand; import net.osmand.plus.backup.commands.DeleteAllFilesCommand; import net.osmand.plus.backup.commands.DeleteFilesCommand; @@ -101,6 +102,7 @@ public class BackupHelper { public static final String DELETE_FILE_VERSION_URL = SERVER_URL + "/userdata/delete-file-version"; public static final String ACCOUNT_DELETE_URL = SERVER_URL + "/userdata/delete-account"; public static final String SEND_CODE_URL = SERVER_URL + "/userdata/send-code"; + public static final String CHECK_CODE_URL = SERVER_URL + "/userdata/auth/confirm-code"; private static final String BACKUP_TYPE_PREFIX = "backup_type_"; private static final String VERSION_HISTORY_PREFIX = "save_version_history_"; @@ -689,6 +691,11 @@ public void deleteAccount(@NonNull String email, @NonNull String token) throws U executor.runCommand(new DeleteAccountCommand(this, email, token)); } + public void checkCode(@NonNull String email, @NonNull String token) throws UserNotRegisteredException { + checkRegistered(); + executor.runCommand(new CheckCodeCommand(this, email, token)); + } + public void sendCode(@NonNull String email, @NonNull String action) throws UserNotRegisteredException { checkRegistered(); executor.runCommand(new SendCodeCommand(this, email, action)); diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupListeners.java b/OsmAnd/src/net/osmand/plus/backup/BackupListeners.java index 6b05befd00cf..ff46e82cdb12 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupListeners.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupListeners.java @@ -13,16 +13,21 @@ public class BackupListeners { private final List registerUserListeners = new ArrayList<>(); private final List registerDeviceListeners = new ArrayList<>(); private final List sendCodeListeners = new ArrayList<>(); + private final List checkCodeListeners = new ArrayList<>(); private final List deleteAccountListeners = new ArrayList<>(); public interface OnDeleteFilesListener { - default void onFilesDeleteStarted(@NonNull List files) { } + default void onFilesDeleteStarted(@NonNull List files) { + } - default void onFileDeleteProgress(@NonNull RemoteFile file, int progress) { } + default void onFileDeleteProgress(@NonNull RemoteFile file, int progress) { + } - default void onFilesDeleteDone(@NonNull Map errors) { } + default void onFilesDeleteDone(@NonNull Map errors) { + } - default void onFilesDeleteError(int status, @NonNull String message) { } + default void onFilesDeleteError(int status, @NonNull String message) { + } } public interface OnRegisterUserListener { @@ -41,6 +46,10 @@ public interface OnSendCodeListener { void onSendCode(int status, @Nullable String message, @Nullable BackupError error); } + public interface OnCheckCodeListener { + void onCheckCode(@NonNull String token, int status, @Nullable String message, @Nullable BackupError error); + } + public interface OnDeleteAccountListener { void onDeleteAccount(int status, @Nullable String message, @Nullable BackupError error); } @@ -139,6 +148,21 @@ public void removeSendCodeListener(@NonNull OnSendCodeListener listener) { sendCodeListeners.remove(listener); } + @NonNull + public List getCheckCodeListeners() { + return checkCodeListeners; + } + + public void addCheckCodeListener(@NonNull OnCheckCodeListener listener) { + if (!checkCodeListeners.contains(listener)) { + checkCodeListeners.add(listener); + } + } + + public void removeCheckCodeListener(@NonNull OnCheckCodeListener listener) { + checkCodeListeners.remove(listener); + } + @NonNull public List getDeleteAccountListeners() { return deleteAccountListeners; diff --git a/OsmAnd/src/net/osmand/plus/backup/commands/CheckCodeCommand.java b/OsmAnd/src/net/osmand/plus/backup/commands/CheckCodeCommand.java new file mode 100644 index 000000000000..bc36eef3ff43 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/backup/commands/CheckCodeCommand.java @@ -0,0 +1,97 @@ +package net.osmand.plus.backup.commands; + +import static net.osmand.plus.backup.BackupHelper.CHECK_CODE_URL; +import static net.osmand.plus.backup.BackupHelper.STATUS_EMPTY_RESPONSE_ERROR; +import static net.osmand.plus.backup.BackupHelper.STATUS_SERVER_ERROR; +import static net.osmand.plus.backup.BackupHelper.STATUS_SUCCESS; + +import androidx.annotation.NonNull; + +import net.osmand.OperationLog; +import net.osmand.plus.backup.BackupCommand; +import net.osmand.plus.backup.BackupError; +import net.osmand.plus.backup.BackupHelper; +import net.osmand.plus.backup.BackupListeners.OnCheckCodeListener; +import net.osmand.plus.utils.AndroidNetworkUtils; +import net.osmand.plus.utils.AndroidNetworkUtils.OnRequestResultListener; +import net.osmand.util.Algorithms; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.HttpURLConnection; +import java.util.List; + +public class CheckCodeCommand extends BackupCommand { + + private final String email; + private final String token; + + public CheckCodeCommand(@NonNull BackupHelper helper, @NonNull String email, @NonNull String token) { + super(helper); + this.email = email; + this.token = token; + } + + @NonNull + public List getListeners() { + return getHelper().getBackupListeners().getCheckCodeListeners(); + } + + + @Override + protected Object doInBackground(Object... objects) { + String body = getBody(); + OnRequestResultListener listener = getRequestListener(); + AndroidNetworkUtils.sendRequest(getApp(), CHECK_CODE_URL, body, "Check code", + "application/json", true, true, listener); + return null; + } + + @NonNull + private String getBody() { + JSONObject json = new JSONObject(); + try { + json.put("username", email); + json.put("password", JSONObject.NULL); + json.put("token", token); + } catch (JSONException e) { + + } + return json.toString(); + } + + @NonNull + private OnRequestResultListener getRequestListener() { + OperationLog operationLog = createOperationLog("checkCode"); + + return (result, error, resultCode) -> { + int status; + String message = null; + BackupError backupError = null; + if (!Algorithms.isEmpty(error)) { + backupError = new BackupError(error); + message = "Check code error: " + backupError + "\nEmail=" + email + "\nDeviceId=" + getHelper().getDeviceId(); + status = STATUS_SERVER_ERROR; + } else if (resultCode != null && resultCode == HttpURLConnection.HTTP_OK) { + message = result; + status = STATUS_SUCCESS; + } else { + message = "Check code error: empty response"; + status = STATUS_EMPTY_RESPONSE_ERROR; + } + publishProgress(status, message, backupError); + operationLog.finishOperation(status + " " + message); + }; + } + + @Override + protected void onProgressUpdate(Object... values) { + for (OnCheckCodeListener listener : getListeners()) { + int status = (Integer) values[0]; + String message = (String) values[1]; + BackupError backupError = (BackupError) values[2]; + listener.onCheckCode(token, status, message, backupError); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/AuthorizeFragment.java b/OsmAnd/src/net/osmand/plus/backup/ui/AuthorizeFragment.java index e6654e2bde46..f6f78713e899 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/AuthorizeFragment.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/AuthorizeFragment.java @@ -36,6 +36,7 @@ import com.google.android.material.appbar.AppBarLayout; +import net.osmand.CallbackWithObject; import net.osmand.PlatformUtil; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -43,6 +44,7 @@ import net.osmand.plus.backup.BackupError; import net.osmand.plus.backup.BackupHelper; import net.osmand.plus.backup.BackupListeners; +import net.osmand.plus.backup.BackupListeners.OnCheckCodeListener; import net.osmand.plus.backup.BackupListeners.OnRegisterDeviceListener; import net.osmand.plus.backup.BackupListeners.OnRegisterUserListener; import net.osmand.plus.backup.BackupListeners.OnSendCodeListener; @@ -60,7 +62,8 @@ import org.apache.commons.logging.Log; -public class AuthorizeFragment extends BaseOsmAndFragment implements OnRegisterUserListener, OnRegisterDeviceListener, OnSendCodeListener { +public class AuthorizeFragment extends BaseOsmAndFragment implements OnRegisterUserListener, + OnRegisterDeviceListener, OnSendCodeListener, OnCheckCodeListener { private static final Log LOG = PlatformUtil.getLog(AuthorizeFragment.class); @@ -164,6 +167,7 @@ public void onResume() { super.onResume(); BackupListeners listeners = backupHelper.getBackupListeners(); listeners.addSendCodeListener(this); + listeners.addCheckCodeListener(this); listeners.addRegisterUserListener(this); listeners.addRegisterDeviceListener(this); } @@ -173,6 +177,7 @@ public void onPause() { super.onPause(); BackupListeners listeners = backupHelper.getBackupListeners(); listeners.removeSendCodeListener(this); + listeners.removeCheckCodeListener(this); listeners.removeRegisterUserListener(this); listeners.removeRegisterDeviceListener(this); } @@ -310,10 +315,10 @@ private void setupVerifyEmailContainer(@NonNull View view) { } private void resendCode() { - if (startingDialogType != DELETE_ACCOUNT) { - registerUser(true); - } else { + if (startingDialogType == DELETE_ACCOUNT) { sendCodeForDeletion(settings.BACKUP_USER_EMAIL.get()); + } else { + registerUser(true); } } @@ -360,29 +365,32 @@ public void setToken(@NonNull String token) { } private void tokenSelected(@NonNull String token) { - if (startingDialogType != DELETE_ACCOUNT) { - registerDevice(token); + CallbackWithObject callback; + if (startingDialogType == DELETE_ACCOUNT) { + callback = result -> { + try { + backupHelper.checkCode(settings.BACKUP_USER_EMAIL.get(), token); + } catch (UserNotRegisteredException e) { + progressBar.setVisibility(View.INVISIBLE); + LOG.error(e); + } + return false; + }; } else { - MapActivity activity = (MapActivity) getActivity(); - if (AndroidUtils.isActivityNotDestroyed(activity)) { - activity.dismissFragment(TAG); - AndroidUtils.hideSoftKeyboard(activity, editText); - } - openDeletionScreen(token); - } - } - - private void openDeletionScreen(@NonNull String token) { - FragmentManager fragmentManager = getFragmentManager(); - if (fragmentManager != null) { - DeleteAccountFragment.showInstance(fragmentManager, token); + callback = result -> { + backupHelper.registerDevice(token); + return false; + }; } + performActionWithToken(token, callback); } - private void registerDevice(@Nullable String token) { + private void performActionWithToken(@NonNull String token, @NonNull CallbackWithObject callback) { if (!Algorithms.isEmpty(token) && BackupHelper.isTokenValid(token)) { progressBar.setVisibility(View.VISIBLE); - backupHelper.registerDevice(token); + + callback.processResult(null); + Activity activity = getActivity(); if (AndroidUtils.isActivityNotDestroyed(activity)) { AndroidUtils.hideSoftKeyboard(activity, editText); @@ -469,6 +477,7 @@ public void onSendCode(int status, @Nullable String message, @Nullable BackupErr FragmentActivity activity = getActivity(); if (AndroidUtils.isActivityNotDestroyed(activity)) { progressBar.setVisibility(View.INVISIBLE); + if (status == BackupHelper.STATUS_SUCCESS) { lastTimeCodeSent = System.currentTimeMillis(); setDialogType(VERIFY_EMAIL); @@ -479,6 +488,30 @@ public void onSendCode(int status, @Nullable String message, @Nullable BackupErr } } + @Override + public void onCheckCode(@NonNull String token, int status, @Nullable String message, @Nullable BackupError error) { + MapActivity activity = (MapActivity) getActivity(); + if (AndroidUtils.isActivityNotDestroyed(activity)) { + progressBar.setVisibility(View.INVISIBLE); + + if (status == BackupHelper.STATUS_SUCCESS) { + activity.dismissFragment(TAG); + AndroidUtils.hideSoftKeyboard(activity, editText); + + openDeletionScreen(token); + } else { + processError(message, error); + } + } + } + + private void openDeletionScreen(@NonNull String token) { + FragmentManager manager = getFragmentManager(); + if (manager != null) { + DeleteAccountFragment.showInstance(manager, token); + } + } + private void processError(@Nullable String message, @Nullable BackupError error) { boolean choosePlanVisible = false; if (error != null) { From 6ceb5fb4b092a3f997bd3e9f05ea0e34c3e62934 Mon Sep 17 00:00:00 2001 From: whatismoss Date: Wed, 25 Oct 2023 20:09:22 +0000 Subject: [PATCH 38/96] Translated using Weblate (Catalan) Currently translated at 80.1% (3967 of 4949 strings) --- OsmAnd/res/values-ca/strings.xml | 138 +++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index 991bb2810e88..157a379f8a21 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -4328,4 +4328,142 @@ Cotxe Viatge Cotxe + En línia + Muntar a cavall + Tot terreny + Descens + Camió + lliures + Watts + Moto de neu + Velocitat + Carpetes + Cache + quilograms + Extern + Sectors + Segur + Discussió + Hivern + Educació + Parella + SAC + Element + + Intermèdia + Itinerari + Dit + iardes + TTS + Original + Expert + Buit + ppm + Connexió + Regal + Bateria + General + Botó + Senderisme + Comprovat + Evitar + Principiant + Connecta\'t + Codi promocional + Peu + Carpeta + Creat + Velocitat + Cancel·lat + Diastòlic + Giny + Rutes + Parapent + Avançada + Santali + Cadència + Distància + Giny. + Símbol + Oblida\'t + Orientació + Acció + Explosius + Botons + Exigent + Motocicleta + Ciclisme + Sistòlic + Eix X + Pujant + Buscant + Cotxe + Desconnectat + Distància + CarPlay + S\'ha copiat + seg + Caducat + Bateria + mini + Reinicia + Escúter + Atribut + Industrial + Petit + RPM + Bicicleta de muntanya + Aigua + Inclòs + Senderisme + Velocitat + Ascens + polzades + Predefinit + Mode + Eix Y + ANT + S’està carregant + en + Inclou + Reenviar + Progrés + Filtre + Gira + Sortida + Comença + Comprat + Vehicles pesants + Fora de línia + CAI + Autoritza + Migració + Canell + S\'està suprimint + Desconnecta + Connectat + lbs + Divers + Cadira de rodes + BRouter + Córrer + Pit + Relació + Resolució de problemes + Cistella + BLE + A peu + Classe + A peu + Gasos + Accions + Temperatura + Emmagatzematge + Temperatura + peus + Ciclomotor + Conflictes + Informació + Més proper + Configuració \ No newline at end of file From 3a3dac1899bdccf967ab7a214e17e683fe21536e Mon Sep 17 00:00:00 2001 From: Cosmin Date: Thu, 26 Oct 2023 05:27:57 +0000 Subject: [PATCH 39/96] Translated using Weblate (Romanian) Currently translated at 98.8% (4892 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index dd9bf8da8684..2b04e5fd70f1 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -45,7 +45,7 @@ Folosește busola Fără autostrăzi Nivel de zoom în funcție de viteza dumneavoastră (în timp ce harta este sincronizată cu poziția curentă). - Zoom hartă automat + Zoom automat hartă Poziționează pe drum Vizualizare și navigare pe hartă mobilă globală pentru hărți OSM offline și online OsmAnd (Indicații automate de navigație OSM) @@ -443,11 +443,11 @@ Hartă vectorială offline prezentă pentru această locație. \n\t \n\tPentru a o utiliza, activați \'Menu\' → \'Configure map\' → \'Map Source…\' → \'Offline vector maps\'. - Canal voce de ghidare + Ieșire audio pentru ghidare Selectați difuzorul pentru ghidare vocală. - Apeluri telefonice audio (pentru a întrerupe sistemele stereo Bluetooth ale mașinilor) - Canal audio notificări de sistem - Media/navigare audio + Canal apeluri telefonice (va întrerupe sistemul audio Bluetooth al mașinilor) + Canal notificări de sistem + Canal multimedia/navigare audio Aplicația nu poate descărca stratul de hartă %1$s, reinstalarea acesteia ar putea ajuta. Reglați transparența suprapunerii. Transparență strat @@ -956,7 +956,7 @@ Reține alegerea și sau - La mărire maximă + La apropiere maximă Mărire hartă Harta de bază a lumii Versiune: @@ -1457,7 +1457,7 @@ Informații favorite Oprește simularea poziției tale. Simulează utilizând o rută calculată sau o înregistrare GPX. - Adresa căutată + Se caută adresa Frysk Albaneză (Tosk) geo: @@ -1618,7 +1618,7 @@ Lat %1$s \nLun %2$s Întrebări frecvente, schimbări recente și altele. - Setări de navigație + Setare navigație Setări generale Nu folosiți @@ -1695,7 +1695,7 @@ Citește articolul Toate punctele grupului Deschide de la - Deschide până + Deschis până la Închide la Se deschide la Deschide la @@ -2082,7 +2082,7 @@ Devreme Normal Târziu - În ultimii metri + Foarte târziu Anunţ de sosire Europa - Olanda Repetare instrucțiuni de navigație @@ -2094,7 +2094,7 @@ Redeschide Trebuie să fiți online pentru a instala acest plugin. Obțineți - Re-calcularea rutei inteligente + Recalculare inteligentă a rutei Îți place OsmAnd? Opinia și feedback-ul dumneavoastră sunt apreciate. Evaluați această aplicație @@ -2174,7 +2174,7 @@ Selectați tipurile de transport public evitate la navigare: %s mod Evitați tipurile de transport… - Mergi + Mergeți Aflați mai multe despre modul în care OsmAnd calculează rutele în blogul nostru. În prezent, navigația pentru transportul public este în testare beta, așteptați erori și inexactități. Adăugați punct intermediar @@ -2226,11 +2226,11 @@ Activați modificările OsmAnd Live pentru transportul public. Transport public OsmAnd Live Ora din zi - După %1$s + Cu %1$s Pas cu pas Tipuri drum Coborâre la - Urcați la stația + Urcare la stația Schimbați Afișați mai multe Trasee afișate @@ -2533,7 +2533,7 @@ Utilizați senzorul de proximitate Dispozitive externe de intrare Tastatură - Luați în considerare limitările temporare + Ține cont de limitările temporare Setări pentru rutare în profilul selectat \"%1$s\". Unități & formate Aspect hartă @@ -2553,7 +2553,7 @@ Anunțuri vocale Alerte ecran Configurați parametrii rutei - Parametrii rutei + Parametri rută Lățime Specificați limita permisă pentru lățimea vehiculului pe rute. Dialoguri și notificări @@ -2703,7 +2703,7 @@ Nu s-a putut copia fișierele %1$d (%2$s). fișierele %1$d (%2$s) sunt prezente în locația anterioară \' %3$s \'. Traseul pe jos este de aproximativ %1$s, și poate fi mai rapid decât transportul public - Din păcate, OsmAnd nu a putut găsi un traseu potrivit pentru setările dumneavoastră. + Din păcate OsmAnd nu a găsit un traseu potrivit pentru setările dumneavoastră. Widget coordonate Permiteți ca OsmAnd să colecteze și să proceseze date anonime despre utilizarea aplicației. Nu sunt colectate date despre poziția dumneavoastră sau despre locațiile pe care le vizualizați pe hartă. \n @@ -3103,7 +3103,7 @@ Scuter cu motor Scaun cu rotile înainte Kart - Ruta între puncte + Rutare între puncte Selectați intervalul la care vor fi afișate marcajele cu distanța sau timpul de pe traseu. Selectați opțiunea de împărțire dorită: în funcție de timp sau de distanță. Selectează un fișier traseu pentru a-l deschide. @@ -3395,13 +3395,13 @@ Trecere Abordare Pregătire lungă - Pregătiți-vă + Pregătire În afara traseului Ajungeți la destinație Întoarceți Intervale de timp și distanță - Timpul de anunțare al diferitelor mesaje vocale depinde de tipul de mesaj, de viteza de navigație curentă și de viteza de navigație implicită. - Ora anunțului + Momentul anunțării diferitelor mesaje vocale depinde de tipul de mesaj, de viteza de navigație curentă și de viteza de navigație implicită. + Momentul anunțului Pornește înregistrarea Arată traseul pe hartă Scaun cu rotile @@ -3570,8 +3570,8 @@ Datele segmentului: %1$s Descărcabile: %1$s Niveluri de mărire descărcate: %1$s - La mărire minimă - La mărire medie + La apropiere minimă + La apropiere medie Fără zoom automat Pentru distanțe lungi: adăugați destinații intermediare dacă nu se găsește nicio rută în 10 minute. Selectați profilurile afișate. @@ -4032,7 +4032,7 @@ Observație: verificarea vitezei > 0: Majoritatea chipseturilor GPS raportează o valoare a vitezei numai dacă algoritmul determină că sunteți în mișcare, iar dacă nu sunteți în mișcare, nu raportează nicio valoare. Prin urmare, utilizarea setării > 0 în acest filtru utilizează într-un fel detectarea mișcării de către chipset-ul GPS. Dar, chiar dacă nu este filtrată aici în momentul înregistrării, folosim în continuare această funcție în analiza GPX pentru a determina Distanța corectată, adică valoarea afișată în acest câmp este distanța înregistrată în timpul mișcării. Recomandare: Încercați să utilizați mai întâi detectarea mișcării prin intermediul filtrului de înregistrare a deplasării minime (B), deoarece poate produce rezultate mai bune și veți pierde mai puține date. Dacă piesele dvs. rămân zgomotoase la viteze mici, încercați valori diferite de zero aici. Rețineți că este posibil ca unele măsurători să nu raporteze nicio valoare a vitezei (unele metode bazate pe rețea), caz în care nu veți înregistra nimic. Efect secundar: Pe traseul dvs. vor lipsi toate secțiunile în care nu a fost respectat criteriul de viteză minimă (de exemplu, atunci când împingeți bicicleta pe un deal abrupt). De asemenea, nu vor exista informații despre perioadele de repaus, cum ar fi pauzele. Acest lucru are efecte asupra oricărei analize sau post-procesări, cum ar fi atunci când încercați să determinați lungimea totală a călătoriei, timpul petrecut în mișcare sau viteza dvs. medie. - Acesta este un filtru de întrerupere a vitezei scăzute pentru a nu înregistra punctele sub o anumită viteză. Acest lucru poate face ca traseele înregistrate să pară mai netede atunci când sunt vizualizate pe hartă. + Acesta este un filtru pentru viteze mici, ca să nu se înregistreze puncte sub o anumită viteză. Acest lucru poate face ca traseele înregistrate să pară mai netede atunci când sunt vizualizate pe hartă. Selectați în schimb un fișier cu extensia %1$s acceptat. Nu există reguli de rutare în \'%1$s\'. Alegeți un alt fișier. Verificați și partajați jurnalele detaliate ale aplicației @@ -4547,7 +4547,7 @@ Dificil Randează cărări conform dificultății traseelor pentru cai Critic - Bara de marcaje a hărții + Bară de marcaje a hărții Rute de monorail Selectați partea ecranului pentru a adăuga sau rearanja widgeturi. Panou superior @@ -4570,7 +4570,7 @@ Rute de navetă Arată ora curentă așa cum este pe dispozitivul dumneavoastră. Obține informații despre elevație - Luați în considerare autorizațiile de acces pentru vehiculele ușoare de marfă (mărfuri) + Ține cont de permisiunile de acces pentru vehiculele ușoare de marfă (mărfuri) Folosește numele latin dacă lipsește Importați ca un singur traseu Selectați categoria aplicabilă. @@ -4618,7 +4618,7 @@ Permite accesul privat (camion) Evită autostrăzi Coborâș - Categoria de materiale periculoase / Luați în considerare permisiunile de acces pentru materiale periculoase + Categorie materiale periculoase / Ține cont de permisiunile de acces pentru materiale periculoase Busolă pe cercuri Evită drumuri potrivite doar vehiculelor 4WD Parte a pluginului %1$s. @@ -5312,7 +5312,7 @@ Un traseu montan, echipat cu cabluri fixe, stâlpi, scări și poduri. Evită Backup gratuit al setărilor - Mergi liber + Deplasare liberă %1$s • %2$s • %3$s Clasificare dificultate CAI From 3f7149cffe42269f39b6b141585e0c72c2642e90 Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 26 Oct 2023 16:21:51 +0000 Subject: [PATCH 40/96] Translated using Weblate (Swedish) Currently translated at 95.5% (4728 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index e015d3193144..23c6741d869a 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -163,8 +163,7 @@ em fm Parkeringsplats - Låter dig spara var din bil är parkerad, inklusive hur mycket parkeringstid som finns kvar. -\nBåde plats och tid är synliga både på instrumentpanelen och i en kartwidget. En larmpåminnelse kan läggas till i Android-kalendern. + Markera var din bil är parkerad, och sätt en avisering i kalendern när parkeringstiden tar slut. För att sätta ut markören, välj en plats i kartan, gå till \'Åtgärder\' och tryck \'Lägg till parkering\'. Parkeringsplats Markera som parkeringsplats Ta bort parkeringsmarkör @@ -4869,21 +4868,23 @@ %s - %s, %s %s - %s Genomsnittligt glidtal - • Ny widget för \"Glidtal\" + • Möjligt att anpassa snabbknappar/tangentgenvägar för externa inmatningsenheter \n -\n • Filter och smarta mappar för spår tillagda +\n• Ny widget för \"Glidtal\" \n -\n • Nya rader för övre och nedre widgetpanel med stöd för alla widgetar +\n• Filter och smarta mappar för spår tillagda \n -\n • Stöd för ANT+ temperatur widget +\n• Nya rader för övre och nedre widgetpanel med stöd för alla widgetar \n -\n • Förbättrad minneshantering för stora gpx-spår +\n• Stöd för ANT+ temperatur widget \n -\n • Uppdaterad resurshantering i Nedladdningar +\n• Förbättrad minneshantering för stora gpx-spår \n -\n • Ny widget \"Tillgängligt minne\" +\n• Uppdaterad resurshantering i Nedladdningar \n -\n • Löst problem med genomskinligt statusfält +\n• Ny widget \"Tillgängligt minne\" +\n +\n• Löst problem med genomskinligt statusfält \n \n Kartvy under navigering From 8ea0259c8a94230bd756008e8b0b420725c5dd0e Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Wed, 25 Oct 2023 19:54:19 +0000 Subject: [PATCH 41/96] Translated using Weblate (French) Currently translated at 99.9% (4947 of 4949 strings) --- OsmAnd/res/values-fr/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 65d3e1b12fa7..1f77b6461138 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -5528,15 +5528,15 @@ Interactions avec la carte Déplacer vers le bas Actions - Activer pour utiliser l\'appareil d\'entrée externe avec OsmAnd - Profile d\'application précédent - Appuyez sur le bouton de votre appareil pour le lier à l\'action choisie. + Activer pour utiliser le périphérique d\'entrée externe avec OsmAnd + Profil d\'application précédent + Appuyez sur le bouton de votre appareil pour l’affecter à l\'action sélectionnée. Erreur de suppression Profil d\'application suivant - Changer l\'assignement de touche - Prendre une note média + Modifier l\'affectation des touches + Créer une note média Émettre un indice de guidage Périphériques d\'entrée externes - Assignements des touches + Affectation des touches Open WunderLINQ Datagrid \ No newline at end of file From 10478ac1bc9213ac5ddd81e30a66c80c71fe3106 Mon Sep 17 00:00:00 2001 From: mcliquid Date: Thu, 26 Oct 2023 07:15:48 +0000 Subject: [PATCH 42/96] Translated using Weblate (German) Currently translated at 99.7% (4937 of 4949 strings) --- OsmAnd/res/values-de/strings.xml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 4ce15b53cc58..7f02210523b1 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -5452,7 +5452,9 @@ Navigieren nach Markierungen Intelligenter Ordner gespeichert Markierungs-Widgets - • Widget „Gleitzahl“ hinzugefügt + • Möglichkeit zum Ändern der Tastenbelegung für externe Eingabegeräte hinzugefügt +\n +\n• Widget „Gleitzahl“ hinzugefügt \n \n• Filter und intelligente Ordner für Tracks hinzugefügt \n @@ -5520,4 +5522,23 @@ Weniger anzeigen Verzeichnis Nicht angegeben + Hereinzoomen + Kartenorientierung ändern + Drücke die Taste auf deinem Gerät, um sie mit der ausgewählten Aktion zu verknüpfen. + Löschungsfehler + Schaltfläche + Tastenbelegung ändern + Mediennotiz aufnehmen + Aktion + Neuen Typ ergänzen + Suche öffnen + Herauszoomen + Zeige/verberge das Seitenmenü + Der Schlüssel \"%1$s\" ist bereits einer anderen Aktion zugeordnet: \"%2$s\" + Navigationsansicht öffnen + Externes Eingabegerät + Tastenbelegung + Karteninteraktionen + Öffne das WunderLINQ-Datenraster + Aktionen \ No newline at end of file From 5f8fb88b9da01759ecaa44676387131accbf98c7 Mon Sep 17 00:00:00 2001 From: 99 efi Date: Thu, 26 Oct 2023 13:56:47 +0000 Subject: [PATCH 43/96] Translated using Weblate (Hungarian) Currently translated at 100.0% (4949 of 4949 strings) --- OsmAnd/res/values-hu/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index bff3e70ff96d..6f154cac27b2 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -5546,4 +5546,5 @@ Mozgás le WunderLINQ Datagrid megnyitása Műveletek + Hiba törléskor \ No newline at end of file From 5202b8cf05675ba4fccce85ac7eac0a01a486ef0 Mon Sep 17 00:00:00 2001 From: Franco Date: Wed, 25 Oct 2023 23:00:06 +0000 Subject: [PATCH 44/96] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (4947 of 4949 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 928ecba2e25d..607c24c23f0d 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -5440,7 +5440,9 @@ Copiar versión de la complicación Widgets de información Indica la dirección web con sintaxis de parámetros : lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. - • Se ha añadido el widget «Relación de planeo». + • Se ha añadido la capacidad de cambiar los atajos de teclado para dispositivos de entrada externos. +\n +\n• Se ha añadido el widget «Relación de planeo». \n \n• Se añadieron filtros y carpetas inteligentes para las trazas \n @@ -5532,4 +5534,35 @@ Mostrar menos Carpeta Sin especificar + Acercar + Activar para usar un dispositivo de entrada externo con OsmAnd + Cambiar orientación del mapa + Perfil de aplicación anterior + Mostrar notificación sobre la tecla pulsada + Mover a la izquierda + Pulsa el botón en el dispositivo para vincularlo con la acción elegida. + Error de borrado + Mover a la derecha + Botón + Perfil de aplicación siguiente + Cambiar vinculación de tecla + Crear nota multimedia + Actividad atrás pulsada + Emitir sugerencia de navegación + ¿Quitar el tipo «%1$s»\? + Acción + Añadir nuevo tipo + Mover arriba + Abrir vista de búsqueda + Alejar + Mostrar/ocultar menú lateral + La tecla «%1$s» ya se ha asignado a otra acción: «%2$s» + Abrir vista de navegación + Dispositivo de entrada externo + Atajos de teclado + Mover a mi ubicación + Interacciones del mapa + Mover abajo + Abrir cuadrícula de datos de WunderLINQ + Acciones \ No newline at end of file From 7c4e6d46ed2172818e1b83a6d5eed6db70dfe21e Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 26 Oct 2023 14:50:40 +0000 Subject: [PATCH 45/96] Translated using Weblate (Swedish) Currently translated at 96.3% (4468 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 53 ++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index 8ec7aafbff37..c40848a0c037 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -3813,22 +3813,22 @@ Keramik Golvbutik Låg - Medium + Medel Hög Låg - Medium + Medel Hög Låg - Medium + Medel Hög Låg - Medium + Medel Hög Låg - Medium + Medel Hög Låg - Medium + Medel Hög AS/NZS 3112 BS 1363 @@ -4430,4 +4430,45 @@ hbtq+ : primär målgrupp Andning och respiration Ortoser + Medel + Medel + Låg + Medel + Medel + Hög + Låg + Hög + Hög + Hög + Hög + Medel + Låg + Låg + Låg + Medel + Hög + Låg + Låg + Medel + Oljegrus + Låg + Hög + Hög + Hög + Medel + Medel + Hög + Låg + Medel + Låg + Låg + Hög + Hög + Låg + Medel + Medel + Kilhinder + Medel + Låg + Hög \ No newline at end of file From 132ba24b59dbcdf8bee6de216897a11ece527a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=86Verdulo?= Date: Wed, 25 Oct 2023 21:28:28 +0000 Subject: [PATCH 46/96] Translated using Weblate (Esperanto) Currently translated at 98.7% (4885 of 4949 strings) --- OsmAnd/res/values-eo/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index f8dd8c9fd46c..0bef71ade8e4 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -5458,4 +5458,11 @@ landnomo (Z → A) Ĉu vi certe volas forigi la mapon: %1$s\? Mapoj kaj rimedoj + Montri sciigon pri premita klavo + Vicoj + Premu butonon sur via aparato por asigni ĝin al la elektita ago. + Eraro pri forigo + Butono + Ago + La klavo “%1$s” estas jam agordita por alia ago: “%2$s” \ No newline at end of file From bea7f12932e8e78eb09f670046db11819e38ce64 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 26 Oct 2023 02:31:53 +0000 Subject: [PATCH 47/96] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (4949 of 4949 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 86385541e900..17e10cb84705 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -5538,4 +5538,5 @@ 向下移動 開啟 WunderLINQ Datagrid 動作 + 刪除錯誤 \ No newline at end of file From 5c6812fcd1f0048883a4371b873f7d61fd0ddccd Mon Sep 17 00:00:00 2001 From: Cosmin Date: Thu, 26 Oct 2023 10:11:31 +0000 Subject: [PATCH 48/96] Translated using Weblate (Romanian) Currently translated at 99.9% (4632 of 4635 strings) --- OsmAnd/res/values-ro/phrases.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ro/phrases.xml b/OsmAnd/res/values-ro/phrases.xml index 25beecdb4ba4..ae7356ea5656 100644 --- a/OsmAnd/res/values-ro/phrases.xml +++ b/OsmAnd/res/values-ro/phrases.xml @@ -1018,7 +1018,7 @@ Grătar Apă potabilă Food court - Tavernă + Bar Bar Fast food Restaurant @@ -3497,7 +3497,7 @@ Centru de transfuzie sanguină Laborator medical Magazin en-gros - Producția de produse de cofetărie + Cofetărie Colectarea pe teren Manometru de inspecție Grup de supape From 8b8e5cfb2423727eb3ba00307eb8e5414a1bde4b Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Fri, 27 Oct 2023 07:59:02 +0300 Subject: [PATCH 49/96] Improve naming --- OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index e5e55f8a3b55..a1314ae13783 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -1299,7 +1299,7 @@ private void setZoomAndAnimationImpl(int zoom, double zoomAnimation, double zoom } private void setZoomAndAnimationImpl(int zoom, double zoomAnimation, double zoomFloatPart, int centerX, int centerY) { - zoom = getZoomInLimits(zoom); + zoom = normalizeZoomWithLimits(zoom); MapRendererView mapRenderer = getMapRenderer(); if (mapRenderer != null) { int centerX31Before = 0; @@ -1622,14 +1622,14 @@ public boolean onGenericMotionEvent(MotionEvent event) { double lat = tb.getLatFromPixel(event.getX(), event.getY()); double lon = tb.getLonFromPixel(event.getX(), event.getY()); int zoomDir = event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0 ? -1 : 1; - int endZoom = getZoomInLimits(getZoom() + zoomDir); + int endZoom = normalizeZoomWithLimits(getZoom() + zoomDir); getAnimatedDraggingThread().startMoving(lat, lon, endZoom, true); return true; } return false; } - private int getZoomInLimits(int targetZoom) { + private int normalizeZoomWithLimits(int targetZoom) { int minZoom = getMinZoom(); int maxZoom = getMaxZoom(); Zoom zoom = new Zoom(targetZoom, getZoomFloatPart(), minZoom, maxZoom); From acd28cfd7792b38e7f7d57884d2bc0f50576d393 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 27 Oct 2023 11:16:43 +0300 Subject: [PATCH 50/96] Fix bicycle private --- .../java/net/osmand/binary/RouteDataObject.java | 16 +++++++++------- .../net/osmand/router/RoutePlannerFrontEnd.java | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index 73e3c65aa8aa..58af6079dda5 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -1,5 +1,7 @@ package net.osmand.binary; +import static net.osmand.router.GeneralRouter.*; + import java.util.Arrays; @@ -827,15 +829,15 @@ public String getHighway() { return getHighway(types, region); } - public boolean hasPrivateAccess() { + public boolean hasPrivateAccess(GeneralRouterProfile profile) { int sz = types.length; for (int i = 0; i < sz; i++) { - RouteTypeRule r = region.quickGetEncodingRule(types[i]); - if ("motorcar".equals(r.getTag()) - || "motor_vehicle".equals(r.getTag()) - || "vehicle".equals(r.getTag()) - || "access".equals(r.getTag())) { - if (r.getValue().equals("private")) { + RouteTypeRule rule = region.quickGetEncodingRule(types[i]); + String tag = rule.getTag(); + if ("vehicle".equals(tag) || "access".equals(tag) + || (profile == GeneralRouterProfile.CAR && ("motorcar".equals(tag) || "motor_vehicle".equals(tag))) + || (profile == GeneralRouterProfile.BICYCLE && ("bicycle".equals(tag)))) { + if (rule.getValue().equals("private")) { return true; } } diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java index 42e6371dbcf2..351e56a7778d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java @@ -745,7 +745,7 @@ private boolean needRequestPrivateAccessRouting(RoutingContext ctx, List for (LatLon latLon : points) { RouteSegmentPoint rp = findRouteSegment(latLon.getLatitude(), latLon.getLongitude(), ctx, null); if (rp != null && rp.road != null) { - if (rp.road.hasPrivateAccess()) { + if (rp.road.hasPrivateAccess(ctx.config.router.getProfile())) { res = true; break; } From 9e5ad8b90834ea537ceda7019765cf71dc6a4e62 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Fri, 27 Oct 2023 11:46:56 +0300 Subject: [PATCH 51/96] Fix "Critical Issue with editing track with duplicated name" --- .../net/osmand/aidlapi/gpx/HideGpxParams.java | 20 ++++++++- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 9 ++-- .../net/osmand/aidl/OsmandAidlService.java | 2 +- .../net/osmand/aidl/OsmandAidlServiceV2.java | 2 +- .../helpers/SelectGpxTrackBottomSheet.java | 6 ++- .../plus/mapcontextmenu/MapContextMenu.java | 42 +++++++++---------- .../MeasurementToolFragment.java | 23 +++++----- .../SelectFileBottomSheet.java | 10 ++--- .../StartPlanRouteBottomSheet.java | 8 ++-- .../FollowTrackFragment.java | 5 ++- .../cards/HistoryCard.java | 34 +++++++-------- .../net/osmand/plus/track/data/GPXInfo.java | 5 +++ .../track/fragments/TrackMenuFragment.java | 3 +- .../track/helpers/GpxSelectionHelper.java | 8 +++- .../plus/track/helpers/GpxUiHelper.java | 7 ++-- .../WikivoyageArticleDialogFragment.java | 37 ++++++++-------- 16 files changed, 125 insertions(+), 96 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/gpx/HideGpxParams.java b/OsmAnd-api/src/net/osmand/aidlapi/gpx/HideGpxParams.java index 9f1f3d18974e..f9f4a8e3a89f 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/gpx/HideGpxParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/gpx/HideGpxParams.java @@ -3,13 +3,23 @@ import android.os.Bundle; import android.os.Parcel; +import androidx.annotation.Nullable; + import net.osmand.aidlapi.AidlParams; public class HideGpxParams extends AidlParams { + @Nullable + private String filePath; + @Nullable private String fileName; - public HideGpxParams(String fileName) { + public HideGpxParams(@Nullable String fileName) { + this(null, fileName); + } + + public HideGpxParams(@Nullable String filePath, @Nullable String fileName) { + this.filePath = filePath; this.fileName = fileName; } @@ -29,17 +39,25 @@ public HideGpxParams[] newArray(int size) { } }; + @Nullable public String getFileName() { return fileName; } + @Nullable + public String getFilePath() { + return filePath; + } + @Override public void writeToBundle(Bundle bundle) { bundle.putString("fileName", fileName); + bundle.putString("filePath", filePath); } @Override protected void readFromBundle(Bundle bundle) { fileName = bundle.getString("fileName"); + filePath = bundle.getString("filePath"); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 9b1ca5f39555..f5cc86e4190b 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -1264,7 +1264,7 @@ private void finishGpxImport(boolean destinationExists, File destination, String } } GpxSelectionHelper helper = app.getSelectedGpxHelper(); - SelectedGpxFile selectedGpx = helper.getSelectedFileByName(destination.getName()); + SelectedGpxFile selectedGpx = helper.getSelectedFileByPath(destination.getAbsolutePath()); if (selectedGpx != null) { if (show) { new AsyncTask() { @@ -1443,9 +1443,12 @@ protected void onPostExecute(GPXFile gpx) { return false; } - boolean hideGpx(String fileName) { + boolean hideGpx(String filePath, String fileName) { if (!Algorithms.isEmpty(fileName)) { - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); + GpxSelectionHelper selectionHelper = app.getSelectedGpxHelper(); + SelectedGpxFile selectedGpxFile = filePath != null + ? selectionHelper.getSelectedFileByPath(filePath) + : selectionHelper.getSelectedFileByName(fileName); if (selectedGpxFile != null) { GpxSelectionParams params = GpxSelectionParams.newInstance() .hideFromMap().syncGroup().saveSelection(); diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index c11222fa1058..9f68dd02a0b9 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -541,7 +541,7 @@ public boolean hideGpx(HideGpxParams params) { try { if (params != null && params.getFileName() != null) { OsmandAidlApi api = getApi("hideGpx"); - return api != null && api.hideGpx(params.getFileName()); + return api != null && api.hideGpx(null, params.getFileName()); } return false; } catch (Exception e) { diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 912197c2be99..753b6a945d6d 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -559,7 +559,7 @@ public boolean hideGpx(HideGpxParams params) { try { if (params != null && params.getFileName() != null) { OsmandAidlApi api = getApi("hideGpx"); - return api != null && api.hideGpx(params.getFileName()); + return api != null && api.hideGpx(params.getFilePath(), params.getFileName()); } return false; } catch (Exception e) { diff --git a/OsmAnd/src/net/osmand/plus/helpers/SelectGpxTrackBottomSheet.java b/OsmAnd/src/net/osmand/plus/helpers/SelectGpxTrackBottomSheet.java index 7c38810e9df5..fd75ddb824e6 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/SelectGpxTrackBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/helpers/SelectGpxTrackBottomSheet.java @@ -63,9 +63,11 @@ private void onItemClick(int position) { callbackWithObject.processResult(null); app.getSettings().LAST_SELECTED_GPX_TRACK_FOR_NEW_POINT.set(null); } else { - String fileName = gpxInfoList.get(position).getFileName(); + GPXInfo gpxInfo = gpxInfoList.get(position); + String fileName = gpxInfo.getFileName(); + String filePath = gpxInfo.getFilePath(); app.getSettings().LAST_SELECTED_GPX_TRACK_FOR_NEW_POINT.set(fileName); - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); + SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(filePath); if (selectedGpxFile != null) { callbackWithObject.processResult(new GPXFile[] {selectedGpxFile.getGpxFile()}); } else { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java index 12ef7893314e..57e9b854b9fd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java @@ -1234,30 +1234,30 @@ public boolean processResult(GPXFile[] result) { public void addNewWptToGPXFile(@Nullable String title, @Nullable Amenity amenity) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { - CallbackWithObject callbackWithObject = new CallbackWithObject() { - @Override - public boolean processResult(GPXFile[] result) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - GPXFile gpxFile; - if (result != null && result.length > 0) { - gpxFile = result[0]; - } else { - gpxFile = mapActivity.getMyApplication().getSavingTrackHelper().getCurrentGpx(); - } - WptPtEditor wptPtPointEditor = getWptPtPointEditor(); - if (wptPtPointEditor != null) { - wptPtPointEditor.add(gpxFile, getLatLon(), title, amenity); - } - } - return true; - } - }; - - GpxUiHelper.selectSingleGPXFile(mapActivity, true, callbackWithObject); + addNewWptToGPXFileImpl(mapActivity, title, amenity); } } + private void addNewWptToGPXFileImpl(@NonNull MapActivity mapActivity, + @Nullable String title, @Nullable Amenity amenity) { + GpxUiHelper.selectSingleGPXFile(mapActivity, true, result -> { + MapActivity activity = getMapActivity(); + if (activity != null) { + GPXFile gpxFile; + if (result != null && result.length > 0) { + gpxFile = result[0]; + } else { + gpxFile = activity.getMyApplication().getSavingTrackHelper().getCurrentGpx(); + } + WptPtEditor wptPtPointEditor = getWptPtPointEditor(); + if (wptPtPointEditor != null) { + wptPtPointEditor.add(gpxFile, getLatLon(), title, amenity); + } + } + return true; + }); + } + @Nullable public PointDescription getPointDescriptionForTarget() { MapActivity mapActivity = getMapActivity(); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 115a5bfed6d2..2c1de460921d 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -193,7 +193,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route private OnBackPressedCallback onBackPressedCallback; private OnGlobalLayoutListener widgetsLayoutListener; - private String fileName; + private String filePath; private boolean showSnapWarning; private boolean adjustMapPosition = true; @@ -575,8 +575,8 @@ public void onSelectProfileIcon(int startPointPos) { GpxData gpxData = editingCtx.getGpxData(); initMeasurementMode(gpxData, savedInstanceState == null); if (savedInstanceState == null) { - if (fileName != null) { - getGpxFile(fileName, gpxFile -> { + if (filePath != null) { + getGpxFile(filePath, gpxFile -> { addNewGpxData(gpxFile); return true; }); @@ -1395,9 +1395,9 @@ private SelectFileListener createAddToTrackFileListener() { MapActivity mapActivity = getMapActivity(); return new SelectFileListener() { @Override - public void selectFileOnCLick(String gpxFileName) { + public void selectFileOnCLick(String filePath) { if (mapActivity != null) { - getGpxFile(gpxFileName, gpxFile -> { + getGpxFile(filePath, gpxFile -> { SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxFile.path); boolean showOnMap = selectedGpxFile != null; saveExistingGpx(gpxFile, showOnMap, false, true, FinalSaveAction.SHOW_IS_SAVED_FRAGMENT); @@ -1412,15 +1412,14 @@ public void dismissButtonOnClick() { }; } - private void getGpxFile(@Nullable String gpxFileName, @NonNull CallbackWithObject callback) { - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(gpxFileName); - if (gpxFileName == null) { + private void getGpxFile(@Nullable String filePath, @NonNull CallbackWithObject callback) { + SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(filePath); + if (filePath == null) { callback.processResult(app.getSavingTrackHelper().getCurrentGpx()); } else if (selectedGpxFile != null) { callback.processResult(selectedGpxFile.getGpxFile()); } else { - File file = new File(app.getAppPath(GPX_INDEX_DIR), gpxFileName); - GpxFileLoaderTask.loadGpxFile(file, getActivity(), callback); + GpxFileLoaderTask.loadGpxFile(new File(filePath), getActivity(), callback); } } @@ -2152,9 +2151,9 @@ public static boolean showInstance(FragmentManager fragmentManager, LatLon initi return showFragment(fragment, fragmentManager); } - public static boolean showInstance(FragmentManager fragmentManager, String fileName, boolean adjustMapPosition) { + public static boolean showInstance(FragmentManager fragmentManager, String filePath, boolean adjustMapPosition) { MeasurementToolFragment fragment = new MeasurementToolFragment(); - fragment.fileName = fileName; + fragment.filePath = filePath; fragment.adjustMapPosition = adjustMapPosition; fragment.setMode(PLAN_ROUTE_MODE, true); return showFragment(fragment, fragmentManager); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java index 8132ecf8d2aa..44586e128f99 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectFileBottomSheet.java @@ -144,14 +144,14 @@ public void createMenuItems(Bundle savedInstanceState) { adapter.setAdapterListener(position -> { List gpxList = adapter.getGpxInfoList(); if (position != RecyclerView.NO_POSITION && position < gpxList.size()) { - String fileName; + String filePath; if (isShowCurrentGpx() && position == 0) { - fileName = null; + filePath = null; } else { - fileName = gpxList.get(position).getFileName(); + filePath = gpxList.get(position).getFilePath(); } if (listener != null) { - listener.selectFileOnCLick(fileName); + listener.selectFileOnCLick(filePath); } } dismiss(); @@ -349,7 +349,7 @@ protected void onDismissButtonClickAction() { interface SelectFileListener { - void selectFileOnCLick(String fileName); + void selectFileOnCLick(String filePath); void dismissButtonOnClick(); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java index ed2a64684f10..a64d9bb7a075 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java @@ -123,10 +123,10 @@ protected int getPeekHeight() { private void onItemClick(int position, List gpxInfoList) { if (position != RecyclerView.NO_POSITION && position < gpxInfoList.size()) { - String fileName = gpxInfoList.get(position).getFileName(); + String filePath = gpxInfoList.get(position).getFilePath(); FragmentActivity activity = getActivity(); if (activity != null) { - MeasurementToolFragment.showInstance(activity.getSupportFragmentManager(), fileName, true); + MeasurementToolFragment.showInstance(activity.getSupportFragmentManager(), filePath, true); } } dismiss(); @@ -165,11 +165,11 @@ void finishImport(boolean success) { private SelectFileListener createSelectFileListener() { return new SelectFileListener() { @Override - public void selectFileOnCLick(String fileName) { + public void selectFileOnCLick(String filePath) { dismiss(); MapActivity mapActivity = (MapActivity) getActivity(); if (mapActivity != null) { - MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), fileName, true); + MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), filePath, true); } } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index 202fcac23628..1a8b9d65e657 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -389,8 +389,8 @@ private void loadAndFollowTrack(TracksToFollowCard card, int index) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null && index < card.getGpxInfoList().size()) { GPXInfo gpxInfo = card.getGpxInfoList().get(index); - String fileName = gpxInfo.getFileName(); - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); + String filePath = gpxInfo.getFilePath(); + SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(filePath); if (selectedGpxFile != null) { GPXFile gpxFile = selectedGpxFile.getGpxFile(); selectTrackToFollow(gpxFile, true); @@ -404,6 +404,7 @@ private void loadAndFollowTrack(TracksToFollowCard card, int index) { } return true; }; + String fileName = gpxInfo.getFileName(); File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); GpxUiHelper.loadGPXFileInDifferentThread(mapActivity, callback, dir, null, fileName); } diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/HistoryCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/HistoryCard.java index e8c472cab5c8..67fea55ffd7a 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/HistoryCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/HistoryCard.java @@ -85,25 +85,23 @@ protected void updateContent() { ImageView icon = view.findViewById(R.id.icon); icon.setImageDrawable(UiUtilities.tintDrawable(listItem.getIcon(), iconColor)); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + view.setOnClickListener(v -> { + String filePath = gpxInfo.getFilePath(); + SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(filePath); + if (selectedGpxFile != null) { + GPXFile gpxFile = selectedGpxFile.getGpxFile(); + mapActivity.getMapRouteInfoMenu().selectTrack(gpxFile, true); + } else { + CallbackWithObject callback = result -> { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + mapActivity.getMapRouteInfoMenu().selectTrack(result[0], true); + } + return true; + }; String fileName = gpxInfo.getFileName(); - SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); - if (selectedGpxFile != null) { - GPXFile gpxFile = selectedGpxFile.getGpxFile(); - mapActivity.getMapRouteInfoMenu().selectTrack(gpxFile, true); - } else { - CallbackWithObject callback = result -> { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - mapActivity.getMapRouteInfoMenu().selectTrack(result[0], true); - } - return true; - }; - File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); - GpxUiHelper.loadGPXFileInDifferentThread(mapActivity, callback, dir, null, fileName); - } + File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + GpxUiHelper.loadGPXFileInDifferentThread(mapActivity, callback, dir, null, fileName); } }); } else { diff --git a/OsmAnd/src/net/osmand/plus/track/data/GPXInfo.java b/OsmAnd/src/net/osmand/plus/track/data/GPXInfo.java index a4853d1eeebe..45d7e0a1ccb0 100644 --- a/OsmAnd/src/net/osmand/plus/track/data/GPXInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/data/GPXInfo.java @@ -37,6 +37,11 @@ public String getFileName() { return fileName; } + @Nullable + public String getFilePath() { + return file != null ? file.getAbsolutePath() : null; + } + public long getLastModified() { return lastModified; } diff --git a/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java index 035fada04f4f..7c664f3a42d9 100644 --- a/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java @@ -1128,8 +1128,7 @@ public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) { GpxSelectionParams params = GpxSelectionParams.newInstance().showOnMap(); selectedGpxFile = gpxSelectionHelper.selectGpxFile(gpxFile, params); dismiss(); - String fileName = Algorithms.getFileWithoutDirs(gpxFile.path); - MeasurementToolFragment.showInstance(fragmentManager, fileName, false); + MeasurementToolFragment.showInstance(fragmentManager, gpxFile.path, false); } else if (buttonIndex == RENAME_BUTTON_INDEX) { FileUtils.renameFile(mapActivity, new File(gpxFile.path), this, true); } else if (buttonIndex == CHANGE_FOLDER_BUTTON_INDEX) { diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/track/helpers/GpxSelectionHelper.java index 205643bd4756..50d17819913d 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GpxSelectionHelper.java @@ -175,8 +175,7 @@ public SelectedGpxFile getSelectedGPXFile(@NonNull WptPt point) { @Nullable public SelectedGpxFile getSelectedFileByPath(String path) { - List newList = new ArrayList<>(selectedGPXFiles); - for (SelectedGpxFile selectedGpxFile : newList) { + for (SelectedGpxFile selectedGpxFile : selectedGPXFiles) { if (selectedGpxFile.getGpxFile().path.equals(path)) { return selectedGpxFile; } @@ -184,6 +183,11 @@ public SelectedGpxFile getSelectedFileByPath(String path) { return null; } + + /** + * @deprecated + * Use the {@link #getSelectedFileByPath(String filePath)} method. + */ @Nullable public SelectedGpxFile getSelectedFileByName(String fileName) { for (SelectedGpxFile selectedGpxFile : selectedGPXFiles) { diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java index dee65f47b82e..a6125621f826 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java @@ -520,12 +520,13 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) { if (showCurrentGpx && position == 0) { callbackWithObject.processResult(null); } else { - String fileName = gpxInfoList.get(position).getFileName(); - SelectedGpxFile selectedGpxFile = - app.getSelectedGpxHelper().getSelectedFileByName(fileName); + GPXInfo gpxInfo = gpxInfoList.get(position); + String filePath = gpxInfo.getFilePath(); + SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(filePath); if (selectedGpxFile != null) { callbackWithObject.processResult(new GPXFile[] {selectedGpxFile.getGpxFile()}); } else { + String fileName = gpxInfo.getFileName(); loadGPXFileInDifferentThread(activity, callbackWithObject, dir, null, fileName); } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java index 556e34b0a059..541d23e73bb1 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/article/WikivoyageArticleDialogFragment.java @@ -146,25 +146,7 @@ public void onClick(View v) { trackButton.setCompoundDrawablesWithIntrinsicBounds( getActiveIcon(R.drawable.ic_action_markers_dark), null, null, null ); - trackButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity activity = getActivity(); - FragmentManager fm = getFragmentManager(); - if (article == null || activity == null || fm == null) { - return; - } - if (activity instanceof WikivoyageExploreActivity) { - WikivoyageExploreActivity exploreActivity = (WikivoyageExploreActivity) activity; - exploreActivity.setArticle(article); - } - TravelHelper travelHelper = app.getTravelHelper(); - File file = travelHelper.createGpxFile(article); - boolean temporarySelected = app.getSelectedGpxHelper().getSelectedFileByName(file.getAbsolutePath()) == null; - TrackMenuFragment.openTrack(activity, new File(file.getAbsolutePath()), null, - getString(R.string.icon_group_travel), TrackMenuTab.POINTS, temporarySelected); - } - }); + trackButton.setOnClickListener(v -> openTrack()); trackButton.setVisibility(View.GONE); gpxProgress = mainView.findViewById(R.id.gpx_progress); gpxProgress.setVisibility(View.GONE); @@ -244,6 +226,23 @@ public void onResume() { } } + private void openTrack() { + FragmentActivity activity = getActivity(); + FragmentManager fm = getFragmentManager(); + if (article == null || activity == null || fm == null) { + return; + } + if (activity instanceof WikivoyageExploreActivity) { + WikivoyageExploreActivity exploreActivity = (WikivoyageExploreActivity) activity; + exploreActivity.setArticle(article); + } + TravelHelper travelHelper = app.getTravelHelper(); + File file = travelHelper.createGpxFile(article); + boolean temporarySelected = app.getSelectedGpxHelper().getSelectedFileByPath(file.getAbsolutePath()) == null; + TrackMenuFragment.openTrack(activity, new File(file.getAbsolutePath()), null, + getString(R.string.icon_group_travel), TrackMenuTab.POINTS, temporarySelected); + } + private void updateSaveButton() { if (article != null) { TravelHelper helper = app.getTravelHelper(); From 74c72bb7eae00603b4af305480987baeca7e4f38 Mon Sep 17 00:00:00 2001 From: chumva Date: Fri, 27 Oct 2023 12:18:42 +0300 Subject: [PATCH 52/96] Code cleanup --- .../osmand/plus/MapPoiTypesTranslator.java | 5 +- .../net/osmand/plus/NavigationService.java | 14 ++-- .../osmand/plus/OsmAndLocationSimulation.java | 8 +- .../net/osmand/plus/OsmandApplication.java | 75 +++++-------------- .../plus/configmap/ConfigureMapUtils.java | 2 +- .../plus/download/DownloadIndexesThread.java | 12 ++- .../osmand/plus/download/DownloadService.java | 11 ++- .../plus/feedback/ExceptionHandler.java | 47 ++++++++++++ .../osmand/plus/feedback/FeedbackHelper.java | 63 +++++----------- .../notifications/NotificationHelper.java | 14 ++-- .../plugins/monitoring/DashTrackFragment.java | 9 ++- .../plus/track/helpers/GpxUiHelper.java | 4 +- .../net/osmand/plus/utils/AndroidUtils.java | 28 +++---- .../plus/wikipedia/WikipediaPlugin.java | 2 +- 14 files changed, 147 insertions(+), 147 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/feedback/ExceptionHandler.java diff --git a/OsmAnd/src/net/osmand/plus/MapPoiTypesTranslator.java b/OsmAnd/src/net/osmand/plus/MapPoiTypesTranslator.java index 189c1a3294ab..56f4a1455a7e 100644 --- a/OsmAnd/src/net/osmand/plus/MapPoiTypesTranslator.java +++ b/OsmAnd/src/net/osmand/plus/MapPoiTypesTranslator.java @@ -7,6 +7,7 @@ import net.osmand.PlatformUtil; import net.osmand.osm.AbstractPoiType; import net.osmand.osm.MapPoiTypes.PoiTranslator; +import net.osmand.plus.utils.AndroidUtils; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -30,7 +31,7 @@ public String getTranslation(AbstractPoiType type) { AbstractPoiType baseLangType = type.getBaseLangType(); if (baseLangType != null) { String translation = getTranslation(baseLangType); - String langTranslation = " (" + app.getLangTranslation(type.getLang()).toLowerCase() + ")"; + String langTranslation = " (" + AndroidUtils.getLangTranslation(app, type.getLang()).toLowerCase() + ")"; if (translation != null) { return translation + langTranslation; } else { @@ -101,7 +102,7 @@ public String getAllLanguagesTranslationSuffix() { public String getEnTranslation(AbstractPoiType type) { AbstractPoiType baseLangType = type.getBaseLangType(); if (baseLangType != null) { - return getEnTranslation(baseLangType) + " (" + app.getLangTranslation(type.getLang()).toLowerCase() + ")"; + return getEnTranslation(baseLangType) + " (" + AndroidUtils.getLangTranslation(app, type.getLang()).toLowerCase() + ")"; } return getEnTranslation(type.getIconKeyName()); } diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index 232d7be87fe3..a8520c616b1c 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -12,7 +12,6 @@ import androidx.annotation.Nullable; import androidx.car.app.CarContext; import androidx.car.app.CarToast; -import androidx.car.app.ScreenManager; import androidx.car.app.navigation.NavigationManager; import androidx.car.app.navigation.NavigationManagerCallback; import androidx.car.app.navigation.model.Destination; @@ -83,7 +82,7 @@ public void addUsageIntent(int usageIntent) { usedBy |= usageIntent; } - public void stopIfNeeded(Context ctx, int usageIntent) { + public void stopIfNeeded(@NonNull Context context, int usageIntent) { if ((usedBy & usageIntent) > 0) { usedBy -= usageIntent; } @@ -94,8 +93,7 @@ public void stopIfNeeded(Context ctx, int usageIntent) { setCarContext(null); } if (usedBy == 0) { - Intent serviceIntent = new Intent(ctx, NavigationService.class); - ctx.stopService(serviceIntent); + context.stopService(new Intent(context, NavigationService.class)); } else { OsmandApplication app = getApp(); app.getNotificationHelper().updateTopNotification(); @@ -166,8 +164,7 @@ public void onDestroy() { public void onTaskRemoved(Intent rootIntent) { OsmandApplication app = getApp(); app.getNotificationHelper().removeNotifications(false); - if (app.getNavigationService() != null && - app.getSettings().DISABLE_RECORDING_ONCE_APP_KILLED.get()) { + if (app.getNavigationService() != null && app.getSettings().DISABLE_RECORDING_ONCE_APP_KILLED.get()) { stopSelf(); } } @@ -240,8 +237,9 @@ public void onStopNavigation() { public void onAutoDriveEnabled() { CarToast.makeText(carContext, "Auto drive enabled", CarToast.LENGTH_LONG).show(); OsmAndLocationSimulation sim = getApp().getLocationProvider().getLocationSimulation(); - RoutingHelper routingHelper = getApp().getRoutingHelper(); - if (!sim.isRouteAnimating() && routingHelper.isFollowingMode() && routingHelper.isRouteCalculated() && !routingHelper.isRouteBeingCalculated()) { + RoutingHelper helper = getApp().getRoutingHelper(); + if (!sim.isRouteAnimating() && helper.isFollowingMode() + && helper.isRouteCalculated() && !helper.isRouteBeingCalculated()) { sim.startStopRouteAnimation(null); } } diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java index 0318f59fea82..29766094a2d0 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java @@ -4,7 +4,6 @@ import static net.osmand.plus.SimulationProvider.SIMULATED_PROVIDER; import static net.osmand.plus.SimulationProvider.SIMULATED_PROVIDER_GPX; -import android.app.Activity; import android.os.AsyncTask; import android.view.View; import android.widget.TextView; @@ -13,6 +12,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ContextThemeWrapper; +import androidx.fragment.app.FragmentActivity; import com.google.android.material.slider.Slider; @@ -111,7 +111,7 @@ private void notifyListeners(boolean simulating) { // } // } - public void startStopRouteAnimation(@Nullable Activity activity, boolean useGpx, Runnable runnable) { + public void startStopRouteAnimation(@Nullable FragmentActivity activity, boolean useGpx, Runnable runnable) { if (!isRouteAnimating()) { if (useGpx) { if (activity == null) { @@ -211,11 +211,11 @@ private void stopLoadLocationsTask() { loadLocationsTask = null; } - public void startStopRouteAnimation(@Nullable Activity activity) { + public void startStopRouteAnimation(@Nullable FragmentActivity activity) { startStopRouteAnimation(activity, false, null); } - public void startStopGpxAnimation(@Nullable Activity activity) { + public void startStopGpxAnimation(@Nullable FragmentActivity activity) { startStopRouteAnimation(activity, true, null); } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 8b8d9cd469f0..c9810174b861 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -2,11 +2,12 @@ import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.plus.settings.backend.ApplicationMode.valueOfStringKey; +import static net.osmand.plus.settings.enums.MetricsConstants.KILOMETERS_AND_METERS; +import static net.osmand.plus.settings.enums.MetricsConstants.MILES_AND_FEET; +import static net.osmand.plus.settings.enums.MetricsConstants.MILES_AND_METERS; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -29,6 +30,7 @@ import net.osmand.data.LatLon; import net.osmand.map.OsmandRegions; import net.osmand.map.WorldRegion; +import net.osmand.map.WorldRegion.RegionParams; import net.osmand.osm.MapPoiTypes; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.AppInitializer.AppInitializeListener; @@ -664,11 +666,12 @@ public void refreshCarScreen() { } } + @Nullable public DownloadService getDownloadService() { return downloadService; } - public void setDownloadService(DownloadService downloadService) { + public void setDownloadService(@Nullable DownloadService downloadService) { this.downloadService = downloadService; } @@ -820,8 +823,8 @@ public void applyTheme(@NonNull Context context) { public IBRouterService reconnectToBRouter() { try { bRouterServiceConnection = BRouterServiceConnection.connect(this); - // a delay is necessary as the service process needs time to start.. - Thread.sleep(800); + // a delay is necessary as the service process needs time to start.. + Thread.sleep(800); if (bRouterServiceConnection != null) { return bRouterServiceConnection.getBrouterService(); } @@ -934,24 +937,6 @@ public boolean systemAccessibilityEnabled() { return ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled(); } - public String getVersionName() { - try { - PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0); - return info.versionName; - } catch (NameNotFoundException e) { - return ""; - } - } - - public int getVersionCode() { - try { - PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0); - return info.versionCode; - } catch (NameNotFoundException e) { - return 0; - } - } - public void startNavigationService(int intent) { Intent serviceIntent = new Intent(this, NavigationService.class); if (getNavigationService() != null) { @@ -967,47 +952,25 @@ public void startNavigationService(int intent) { //getNotificationHelper().showNotifications(); } - public void startDownloadService() { - Intent serviceIntent = new Intent(this, DownloadService.class); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(serviceIntent); - } else { - startService(serviceIntent); - } - } - - public String getLangTranslation(String l) { - try { - java.lang.reflect.Field f = R.string.class.getField("lang_" + l); - if (f != null) { - Integer in = (Integer) f.get(null); - return getString(in); - } - } catch (Exception e) { - System.err.println(e.getMessage()); - } - return l; - } - - public void setupDrivingRegion(WorldRegion reg) { - DrivingRegion drg = null; - WorldRegion.RegionParams params = reg.getParams(); + public void setupDrivingRegion(@NonNull WorldRegion worldRegion) { + DrivingRegion drivingRegion = null; + RegionParams params = worldRegion.getParams(); // boolean americanSigns = "american".equals(params.getRegionRoadSigns()); boolean leftHand = "yes".equals(params.getRegionLeftHandDriving()); - MetricsConstants mc1 = "miles".equals(params.getRegionMetric()) ? MetricsConstants.MILES_AND_FEET : MetricsConstants.KILOMETERS_AND_METERS; - MetricsConstants mc2 = "miles".equals(params.getRegionMetric()) ? MetricsConstants.MILES_AND_METERS : MetricsConstants.KILOMETERS_AND_METERS; - for (DrivingRegion r : DrivingRegion.values()) { - if (r.leftHandDriving == leftHand && (r.defMetrics == mc1 || r.defMetrics == mc2)) { - drg = r; + MetricsConstants mc1 = "miles".equals(params.getRegionMetric()) ? MILES_AND_FEET : KILOMETERS_AND_METERS; + MetricsConstants mc2 = "miles".equals(params.getRegionMetric()) ? MILES_AND_METERS : KILOMETERS_AND_METERS; + for (DrivingRegion region : DrivingRegion.values()) { + if (region.leftHandDriving == leftHand && (region.defMetrics == mc1 || region.defMetrics == mc2)) { + drivingRegion = region; break; } } - if (drg != null) { - settings.DRIVING_REGION.set(drg); + if (drivingRegion != null) { + settings.DRIVING_REGION.set(drivingRegion); } } + @NonNull public String getUserAndroidId() { String userAndroidId = settings.USER_ANDROID_ID.get(); if (Algorithms.isEmpty(userAndroidId) || isUserAndroidIdExpired()) { diff --git a/OsmAnd/src/net/osmand/plus/configmap/ConfigureMapUtils.java b/OsmAnd/src/net/osmand/plus/configmap/ConfigureMapUtils.java index 9cc7d8b0203c..00bfc47da588 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/ConfigureMapUtils.java +++ b/OsmAnd/src/net/osmand/plus/configmap/ConfigureMapUtils.java @@ -36,7 +36,7 @@ public static Map getSorterMapLanguages(@NonNull OsmandApplicati boolean localNames = Algorithms.isEmpty(mapLanguageId); String mapLanguageName = localNames ? app.getString(R.string.local_map_names) - : app.getLangTranslation(mapLanguageId); + : AndroidUtils.getLangTranslation(app, mapLanguageId); mapLanguages.put(mapLanguageId, mapLanguageName); } diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 7a9913bd0800..1c2ae7040ce8 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -112,11 +112,21 @@ public void resetUiActivity(DownloadEvents uiActivity) { protected void downloadHasStarted() { boolean shouldStartService = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || uiActivity != null; if (app.getDownloadService() == null && shouldStartService) { - app.startDownloadService(); + startDownloadService(); } updateNotification(); } + private void startDownloadService() { + Intent intent = new Intent(app, DownloadService.class); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + app.startForegroundService(intent); + } else { + app.startService(intent); + } + } + @UiThread protected void downloadInProgress() { if (uiActivity != null) { diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadService.java b/OsmAnd/src/net/osmand/plus/download/DownloadService.java index 5c7cfbd78132..e5726cbd7134 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadService.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadService.java @@ -9,7 +9,10 @@ import android.os.Binder; import android.os.IBinder; +import androidx.annotation.NonNull; + import net.osmand.plus.OsmandApplication; +import net.osmand.plus.notifications.NotificationHelper; import net.osmand.plus.notifications.OsmandNotification.NotificationType; @@ -26,9 +29,8 @@ public IBinder onBind(Intent intent) { return binder; } - public void stopService(Context ctx) { - Intent serviceIntent = new Intent(ctx, DownloadService.class); - ctx.stopService(serviceIntent); + public void stopService(@NonNull Context context) { + context.stopService(new Intent(context, DownloadService.class)); } @Override @@ -36,7 +38,8 @@ public int onStartCommand(Intent intent, int flags, int startId) { OsmandApplication app = (OsmandApplication) getApplication(); app.setDownloadService(this); - Notification notification = app.getNotificationHelper().buildDownloadNotification(); + NotificationHelper notificationHelper = app.getNotificationHelper(); + Notification notification = notificationHelper.buildDownloadNotification(); startForeground(DOWNLOAD_NOTIFICATION_SERVICE_ID, notification); app.getNotificationHelper().refreshNotification(NotificationType.DOWNLOAD); diff --git a/OsmAnd/src/net/osmand/plus/feedback/ExceptionHandler.java b/OsmAnd/src/net/osmand/plus/feedback/ExceptionHandler.java new file mode 100644 index 000000000000..57a59d22caf7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/feedback/ExceptionHandler.java @@ -0,0 +1,47 @@ +package net.osmand.plus.feedback; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; + +import androidx.annotation.NonNull; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; + +import java.lang.Thread.UncaughtExceptionHandler; + +class ExceptionHandler implements UncaughtExceptionHandler { + + private final OsmandApplication app; + private final PendingIntent pendingIntent; + private final UncaughtExceptionHandler exceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + + public ExceptionHandler(@NonNull OsmandApplication app) { + this.app = app; + Context context = app.getBaseContext(); + Intent intent = new Intent(context, app.getAppCustomization().getMapActivity()); + pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE); + } + + @Override + public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) { + try { + app.getFeedbackHelper().saveException(thread, throwable); + if (app.getRoutingHelper().isFollowingMode()) { + AlarmManager manager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); + manager.setExact(AlarmManager.RTC, System.currentTimeMillis() + 2000, pendingIntent); + System.exit(2); + } + if (exceptionHandler != null) { + exceptionHandler.uncaughtException(thread, throwable); + } + } catch (Exception e) { + // swallow all exceptions + android.util.Log.e(PlatformUtil.TAG, "Exception while handle other exception", e); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/feedback/FeedbackHelper.java b/OsmAnd/src/net/osmand/plus/feedback/FeedbackHelper.java index e8b713c93888..b554cb97b48e 100644 --- a/OsmAnd/src/net/osmand/plus/feedback/FeedbackHelper.java +++ b/OsmAnd/src/net/osmand/plus/feedback/FeedbackHelper.java @@ -1,8 +1,5 @@ package net.osmand.plus.feedback; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; @@ -86,21 +83,18 @@ public String getDeviceInfo() { text.append("\nBuild : ").append(Build.DISPLAY); text.append("\nVersion : ").append(Build.VERSION.RELEASE); text.append("\nApp Version : ").append(Version.getAppName(app)); - try { - PackageInfo info = app.getPackageManager().getPackageInfo(app.getPackageName(), 0); - if (info != null) { - text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode); - } - } catch (NameNotFoundException e) { - log.error(e); + + PackageInfo info = getPackageInfo(); + if (info != null) { + text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode); } return text.toString(); } public void setExceptionHandler() { UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); - if (!(uncaughtExceptionHandler instanceof DefaultExceptionHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler()); + if (!(uncaughtExceptionHandler instanceof ExceptionHandler)) { + Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(app)); } } @@ -112,7 +106,7 @@ public void saveExceptionSilent(@NonNull Thread thread, @NonNull Throwable throw } } - private void saveException(@NonNull Thread thread, @NonNull Throwable throwable) throws IOException { + public void saveException(@NonNull Thread thread, @NonNull Throwable throwable) throws IOException { File file = app.getAppPath(EXCEPTION_PATH); ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(out); @@ -122,12 +116,10 @@ private void saveException(@NonNull Thread thread, @NonNull Throwable throwable) .append(Version.getFullVersion(app)) .append("\n") .append(DateFormat.format("dd.MM.yyyy h:mm:ss", System.currentTimeMillis())); - try { - PackageInfo info = app.getPackageManager().getPackageInfo(app.getPackageName(), 0); - if (info != null) { - msg.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode); - } - } catch (Throwable e) { + + PackageInfo info = getPackageInfo(); + if (info != null) { + msg.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode); } msg.append("\n") .append("Exception occurred in thread ") @@ -142,32 +134,13 @@ private void saveException(@NonNull Thread thread, @NonNull Throwable throwable) } } - private class DefaultExceptionHandler implements UncaughtExceptionHandler { - - private final UncaughtExceptionHandler defaultHandler; - private final PendingIntent intent; - - public DefaultExceptionHandler() { - defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); - intent = PendingIntent.getActivity(app.getBaseContext(), 0, - new Intent(app.getBaseContext(), - app.getAppCustomization().getMapActivity()), PendingIntent.FLAG_IMMUTABLE); - } - - @Override - public void uncaughtException(@NonNull Thread thread, @NonNull Throwable ex) { - try { - saveException(thread, ex); - if (app.getRoutingHelper().isFollowingMode()) { - AlarmManager mgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - mgr.setExact(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent); - System.exit(2); - } - defaultHandler.uncaughtException(thread, ex); - } catch (Exception e) { - // swallow all exceptions - android.util.Log.e(PlatformUtil.TAG, "Exception while handle other exception", e); - } + @Nullable + public PackageInfo getPackageInfo() { + try { + return app.getPackageManager().getPackageInfo(app.getPackageName(), 0); + } catch (NameNotFoundException e) { + log.error(e); + return null; } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/notifications/NotificationHelper.java b/OsmAnd/src/net/osmand/plus/notifications/NotificationHelper.java index 9d9607938f20..e47dd8f99f96 100644 --- a/OsmAnd/src/net/osmand/plus/notifications/NotificationHelper.java +++ b/OsmAnd/src/net/osmand/plus/notifications/NotificationHelper.java @@ -6,6 +6,11 @@ import android.app.NotificationManager; import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat.Builder; +import androidx.core.app.NotificationManagerCompat; + import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.auto.CarAppNotification; @@ -14,11 +19,6 @@ import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat.Builder; -import androidx.core.app.NotificationManagerCompat; - public class NotificationHelper { public static final String NOTIFICATION_CHANEL_ID = "osmand_background_service"; @@ -31,7 +31,7 @@ public class NotificationHelper { private ErrorNotification errorNotification; private final List all = new ArrayList<>(); - public NotificationHelper(OsmandApplication app) { + public NotificationHelper(@NonNull OsmandApplication app) { this.app = app; init(); } @@ -48,6 +48,7 @@ private void init() { all.add(carAppNotification); } + @Nullable public Notification buildTopNotification() { OsmandNotification notification = acquireTopNotification(); if (notification != null) { @@ -69,6 +70,7 @@ public Notification buildDownloadNotification() { return downloadNotification.buildNotification(false).build(); } + @NonNull public Notification buildErrorNotification() { removeNotification(errorNotification.getType()); setTopNotification(errorNotification); diff --git a/OsmAnd/src/net/osmand/plus/plugins/monitoring/DashTrackFragment.java b/OsmAnd/src/net/osmand/plus/plugins/monitoring/DashTrackFragment.java index 7427cd3288a3..a1108a8b771d 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/monitoring/DashTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/plugins/monitoring/DashTrackFragment.java @@ -14,6 +14,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; import net.osmand.IndexConstants; import net.osmand.gpx.GPXFile; @@ -185,9 +186,9 @@ public static void createCurrentTrackView(View v) { v.findViewById(R.id.check_item).setVisibility(View.GONE); } - public static void updateCurrentTrack(View v, Activity ctx, OsmandApplication app) { + public static void updateCurrentTrack(View v, @Nullable FragmentActivity activity, OsmandApplication app) { OsmandMonitoringPlugin plugin = PluginsHelper.getActivePlugin(OsmandMonitoringPlugin.class); - if (v == null || ctx == null || app == null || plugin == null) { + if (v == null || activity == null || app == null || plugin == null) { return; } boolean isRecording = app.getSettings().SAVE_GLOBAL_TRACK_TO_GPX.get(); @@ -204,8 +205,8 @@ public static void updateCurrentTrack(View v, Activity ctx, OsmandApplication ap public void onClick(View v) { if (isRecording) { plugin.stopRecording(); - } else if (app.getLocationProvider().checkGPSEnabled(ctx)) { - plugin.startGPXMonitoring(ctx); + } else if (app.getLocationProvider().checkGPSEnabled(activity)) { + plugin.startGPXMonitoring(activity); } } }); diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java index dee65f47b82e..9c667f2e834c 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java @@ -195,7 +195,7 @@ private static List listGpxInfo(OsmandApplication app, List sel return allGpxList; } - public static AlertDialog selectGPXFile(Activity activity, boolean showCurrentGpx, + public static AlertDialog selectGPXFile(@NonNull FragmentActivity activity, boolean showCurrentGpx, boolean multipleChoice, CallbackWithObject callbackWithObject, boolean nightMode) { @@ -359,7 +359,7 @@ public void onGpxDataItemReady(@NonNull GpxDataItem item) { } } - private static AlertDialog createDialog(Activity activity, + private static AlertDialog createDialog(@NonNull FragmentActivity activity, boolean showCurrentGpx, boolean multipleChoice, CallbackWithObject callbackWithObject, diff --git a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java index 8a5d7446d80b..48a018079bda 100644 --- a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java @@ -5,12 +5,12 @@ import static android.Manifest.permission.BLUETOOTH_ADMIN; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_SCAN; -import static android.content.Context.POWER_SERVICE; import static android.graphics.Paint.ANTI_ALIAS_FLAG; import static android.graphics.Paint.FILTER_BITMAP_FLAG; import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static android.util.TypedValue.COMPLEX_UNIT_SP; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.KeyguardManager; @@ -29,7 +29,6 @@ import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ClipDrawable; import android.graphics.drawable.Drawable; @@ -41,7 +40,6 @@ import android.os.Build; import android.os.Bundle; import android.os.IBinder; -import android.os.PowerManager; import android.os.StatFs; import android.text.Spannable; import android.text.SpannableString; @@ -52,7 +50,6 @@ import android.text.format.DateFormat; import android.text.style.CharacterStyle; import android.text.style.ImageSpan; -import android.text.style.StyleSpan; import android.text.style.URLSpan; import android.util.DisplayMetrics; import android.util.TypedValue; @@ -86,6 +83,7 @@ import androidx.core.text.TextUtilsCompat; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; @@ -1200,12 +1198,16 @@ public static String getStringRouteInfoPropertyDescription(Context ctx, String p return value != null ? value : propertyValue; } - public static String getActivityTypeStringPropertyName(Context ctx, String propertyName, String defValue) { String value = getStringByProperty(ctx, "activity_type_" + propertyName + "_name"); return value != null ? value : defValue; } + public static String getLangTranslation(@NonNull Context context, @NonNull String lang) { + String value = getStringByProperty(context, "lang_" + lang); + return value != null ? value : lang; + } + @Nullable public static String getStringByProperty(@NonNull Context ctx, @NonNull String property) { try { @@ -1269,30 +1271,30 @@ public static boolean hasBLEPermission(@NonNull Context context) { private static final int BLUETOOTH_CONNECT_REQUEST_CODE = 5; public static boolean requestBLEPermissions(@NonNull Activity activity) { - ArrayList neededPermissions = new ArrayList<>(); + List permissions = new ArrayList<>(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (!AndroidUtils.hasPermission(activity, BLUETOOTH_SCAN)) { - neededPermissions.add(BLUETOOTH_SCAN); + permissions.add(BLUETOOTH_SCAN); } if (!AndroidUtils.hasPermission(activity, BLUETOOTH_CONNECT)) { - neededPermissions.add(BLUETOOTH_CONNECT); + permissions.add(BLUETOOTH_CONNECT); } } else { if (!AndroidUtils.hasPermission(activity, BLUETOOTH)) { - neededPermissions.add(BLUETOOTH); + permissions.add(BLUETOOTH); } if (!AndroidUtils.hasPermission(activity, BLUETOOTH_ADMIN)) { - neededPermissions.add(BLUETOOTH_ADMIN); + permissions.add(BLUETOOTH_ADMIN); } } - if (!Algorithms.isEmpty(neededPermissions)) { + if (!Algorithms.isEmpty(permissions)) { ActivityCompat.requestPermissions( activity, - neededPermissions.toArray(new String[0]), + permissions.toArray(new String[0]), BLUETOOTH_CONNECT_REQUEST_CODE); } - return Algorithms.isEmpty(neededPermissions); + return Algorithms.isEmpty(permissions); } @Nullable diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java index c40eed9e84e8..cb5a8079822c 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java @@ -297,7 +297,7 @@ public void updateWikipediaState() { } public String getWikiLanguageTranslation(String locale) { - String translation = app.getLangTranslation(locale); + String translation = AndroidUtils.getLangTranslation(app, locale); if (translation.equalsIgnoreCase(locale)) { translation = getTranslationFromPhrases(locale); } From 31ecc65de2c28cbfbf23f8e6238161c3ebe4afe0 Mon Sep 17 00:00:00 2001 From: chumva Date: Fri, 27 Oct 2023 13:22:34 +0300 Subject: [PATCH 53/96] Fix #18350 --- OsmAnd/AndroidManifest.xml | 1 + OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 1 + .../net/osmand/plus/OsmandApplication.java | 18 +++---- .../plus/activities/MapActivityActions.java | 2 +- .../osmand/plus/auto/NavigationSession.java | 9 +--- .../dashboard/DashNavigationFragment.java | 29 +++++------ .../plus/download/DownloadIndexesThread.java | 9 +++- .../plus/helpers/ExternalApiHelper.java | 1 + .../plus/helpers/LauncherShortcutsHelper.java | 2 +- .../plus/helpers/NavigateGpxHelper.java | 1 + .../plus/helpers/RestoreNavigationHelper.java | 2 + .../monitoring/OsmandMonitoringPlugin.java | 43 +++++++++-------- .../monitoring/TripRecordingBottomSheet.java | 31 +++++++----- .../TripRecordingStartingBottomSheet.java | 48 +++++++++++-------- .../actions/NavResumePauseAction.java | 2 + .../net/osmand/plus/utils/AndroidUtils.java | 12 +++++ .../plus/views/layers/MapControlsLayer.java | 7 ++- 17 files changed, 127 insertions(+), 91 deletions(-) diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index c60833efd4bf..1bc87dd2e611 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -18,6 +18,7 @@ + diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 9b1ca5f39555..3bbd55754c37 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -771,6 +771,7 @@ public void onReceive(Context context, Intent intent) { if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) { routingHelper.setRoutePlanningMode(false); routingHelper.setFollowingMode(true); + AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); } } } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index c9810174b861..b0b6d7b14e2a 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -937,19 +937,19 @@ public boolean systemAccessibilityEnabled() { return ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled(); } - public void startNavigationService(int intent) { - Intent serviceIntent = new Intent(this, NavigationService.class); - if (getNavigationService() != null) { - intent |= getNavigationService().getUsedBy(); - getNavigationService().stopSelf(); + public void startNavigationService(int usageIntent) { + NavigationService service = getNavigationService(); + if (service != null) { + usageIntent |= service.getUsedBy(); + service.stopSelf(); } - serviceIntent.putExtra(NavigationService.USAGE_INTENT, intent); + Intent intent = new Intent(this, NavigationService.class); + intent.putExtra(NavigationService.USAGE_INTENT, usageIntent); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(serviceIntent); + startForegroundService(intent); } else { - startService(serviceIntent); + startService(intent); } - //getNotificationHelper().showNotifications(); } public void setupDrivingRegion(@NonNull WorldRegion worldRegion) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 55a4c722fa34..74eedfd2f0cd 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -554,7 +554,7 @@ private ContextMenuAdapter createNormalOptionsMenu(OsmandApplication app, Contex if (monitoringPlugin.hasDataToSave() || monitoringPlugin.wasTrackMonitored()) { TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); } else { - TripRecordingStartingBottomSheet.showTripRecordingDialog(mapActivity.getSupportFragmentManager(), app); + TripRecordingStartingBottomSheet.showTripRecordingDialog(app, mapActivity); } return true; })); diff --git a/OsmAnd/src/net/osmand/plus/auto/NavigationSession.java b/OsmAnd/src/net/osmand/plus/auto/NavigationSession.java index f55fe93dac57..8cc1cec903e9 100644 --- a/OsmAnd/src/net/osmand/plus/auto/NavigationSession.java +++ b/OsmAnd/src/net/osmand/plus/auto/NavigationSession.java @@ -24,8 +24,6 @@ import androidx.lifecycle.LifecycleOwner; import net.osmand.Location; -import net.osmand.data.QuadRect; -import net.osmand.data.RotatedTileBox; import net.osmand.data.ValueHolder; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; @@ -34,12 +32,9 @@ import net.osmand.plus.auto.RequestPermissionScreen.LocationPermissionCheckCallback; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.routing.IRouteInformationListener; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.enums.CompassMode; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.views.MapLayers; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.OsmandMapTileView; -import net.osmand.plus.views.layers.base.OsmandMapLayer; import java.util.List; @@ -117,7 +112,7 @@ private OsmandApplication getApp() { @Override public void onStart(@NonNull LifecycleOwner owner) { getApp().getRoutingHelper().addListener(this); - MapLayers mapLayers = getApp().getOsmandMap().getMapLayers(); + OsmandSettings settings = getApp().getSettings(); defaultAppMode = settings.getApplicationMode(); if (!isAppModeDerivedFromCar(defaultAppMode)) { diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java b/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java index f5e1cd2b042e..776811053a49 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashNavigationFragment.java @@ -18,6 +18,7 @@ import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.routepreparationmenu.ChooseRouteFragment; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.utils.AndroidUtils; /** */ @@ -115,23 +116,19 @@ private void updatePlayButton(RoutingHelper routingHelper, MapActivity map, Imag ); play.setContentDescription(getString(toContinueNavigation ? R.string.continue_navigation : R.string.pause_navigation)); - play.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - if(routingHelper.isRoutePlanningMode()) { - routingHelper.setRoutePlanningMode(false); - routingHelper.setFollowingMode(true); - } else { - routingHelper.setRoutePlanningMode(true); - routingHelper.setFollowingMode(false); - routingHelper.setPauseNavigation(true); - } - updatePlayButton(routingHelper, map, play); - map.getMapViewTrackingUtilities().switchRoutePlanningMode(); - map.refreshMap(); + play.setOnClickListener(v -> { + if(routingHelper.isRoutePlanningMode()) { + routingHelper.setRoutePlanningMode(false); + routingHelper.setFollowingMode(true); + } else { + routingHelper.setRoutePlanningMode(true); + routingHelper.setFollowingMode(false); + routingHelper.setPauseNavigation(true); } + updatePlayButton(routingHelper, map, play); + AndroidUtils.requestNotificationPermissionIfNeeded(map); + map.getMapViewTrackingUtilities().switchRoutePlanningMode(); + map.refreshMap(); }); } - } diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 1c2ae7040ce8..6e304ccb7601 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -111,8 +111,13 @@ public void resetUiActivity(DownloadEvents uiActivity) { @UiThread protected void downloadHasStarted() { boolean shouldStartService = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || uiActivity != null; - if (app.getDownloadService() == null && shouldStartService) { - startDownloadService(); + if (shouldStartService) { + if (app.getDownloadService() == null) { + startDownloadService(); + } + if (uiActivity instanceof FragmentActivity) { + AndroidUtils.requestNotificationPermissionIfNeeded((FragmentActivity) uiActivity); + } } updateNotification(); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java index 146334eb8ac0..23062c48bccb 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ExternalApiHelper.java @@ -389,6 +389,7 @@ public void onDismiss(DialogInterface dialog) { if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) { routingHelper.setRoutePlanningMode(false); routingHelper.setFollowingMode(true); + AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); resultCode = Activity.RESULT_OK; } } else if (API_CMD_STOP_NAVIGATION.equals(cmd)) { diff --git a/OsmAnd/src/net/osmand/plus/helpers/LauncherShortcutsHelper.java b/OsmAnd/src/net/osmand/plus/helpers/LauncherShortcutsHelper.java index e9b07fa8cd08..c5c270a50034 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/LauncherShortcutsHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/LauncherShortcutsHelper.java @@ -136,7 +136,7 @@ public void parseIntent(@NonNull MapActivity mapActivity, @NonNull Intent intent navigateTo(mapActivity, work); } } else if (Shortcut.START_RECORDING.id.equals(shortcutId)) { - TripRecordingStartingBottomSheet.showTripRecordingDialog(mapActivity.getSupportFragmentManager(), app); + TripRecordingStartingBottomSheet.showTripRecordingDialog(app, mapActivity); } else if (Shortcut.SEARCH.id.equals(shortcutId)) { mapActivity.showQuickSearch(ShowQuickSearchMode.NEW_IF_EXPIRED, false); } else if (Shortcut.MY_PLACES.id.equals(shortcutId)) { diff --git a/OsmAnd/src/net/osmand/plus/helpers/NavigateGpxHelper.java b/OsmAnd/src/net/osmand/plus/helpers/NavigateGpxHelper.java index 8761259b3806..d763568149c0 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/NavigateGpxHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/NavigateGpxHelper.java @@ -210,6 +210,7 @@ private static void startNavigation(@NonNull MapActivity mapActivity, @Nullable mapViewTrackingUtilities.switchRoutePlanningMode(); routingHelper.notifyIfRouteIsCalculated(); routingHelper.setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false); + AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); } if (checkLocationPermission) { OsmAndLocationProvider.requestFineLocationPermissionIfNeeded(mapActivity); diff --git a/OsmAnd/src/net/osmand/plus/helpers/RestoreNavigationHelper.java b/OsmAnd/src/net/osmand/plus/helpers/RestoreNavigationHelper.java index b375b5aa9514..9d5597b96fc8 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/RestoreNavigationHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/RestoreNavigationHelper.java @@ -22,6 +22,7 @@ import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.utils.AndroidUtils; import org.apache.commons.logging.Log; @@ -201,6 +202,7 @@ public void enterRoutingMode(@Nullable GPXRouteParamsBuilder gpxRoute) { if (mapActivity.getDashboard().isVisible()) { mapActivity.getDashboard().hideDashboard(); } + AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); } private void notRestoreRoutingMode() { diff --git a/OsmAnd/src/net/osmand/plus/plugins/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/plugins/monitoring/OsmandMonitoringPlugin.java index 9e0ba25ad05b..e8008433d1f5 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/plugins/monitoring/OsmandMonitoringPlugin.java @@ -7,7 +7,6 @@ import static net.osmand.plus.views.mapwidgets.WidgetType.TRIP_RECORDING_TIME; import static net.osmand.plus.views.mapwidgets.WidgetType.TRIP_RECORDING_UPHILL; -import android.app.Activity; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; @@ -16,18 +15,16 @@ import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import net.osmand.gpx.GPXFile; import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.data.ValueHolder; +import net.osmand.gpx.GPXFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndTaskManager.OsmAndTaskRunnable; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.dashboard.tools.DashFragmentData; -import net.osmand.plus.track.helpers.GpxUiHelper; -import net.osmand.plus.track.data.GPXInfo; import net.osmand.plus.plugins.OsmandPlugin; import net.osmand.plus.plugins.monitoring.widgets.TripRecordingDistanceWidget; import net.osmand.plus.plugins.monitoring.widgets.TripRecordingElevationWidget.TripRecordingDownhillWidget; @@ -37,13 +34,15 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.WidgetsAvailabilityHelper; import net.osmand.plus.settings.fragments.SettingsScreenType; +import net.osmand.plus.track.data.GPXInfo; import net.osmand.plus.track.fragments.TrackMenuFragment; +import net.osmand.plus.track.helpers.GpxUiHelper; import net.osmand.plus.track.helpers.SelectedGpxFile; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.views.mapwidgets.MapWidgetInfo; -import net.osmand.plus.views.mapwidgets.WidgetInfoCreator; import net.osmand.plus.views.mapwidgets.WidgetGroup; +import net.osmand.plus.views.mapwidgets.WidgetInfoCreator; import net.osmand.plus.views.mapwidgets.WidgetType; import net.osmand.plus.views.mapwidgets.WidgetsPanel; import net.osmand.plus.views.mapwidgets.widgets.MapWidget; @@ -237,12 +236,12 @@ public boolean hasDataToSave() { return app.getSavingTrackHelper().hasDataToSave(); } - public void showTripRecordingDialog(@NonNull Activity activity) { - FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager(); + public void showTripRecordingDialog(@NonNull FragmentActivity activity) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); if (hasDataToSave() || wasTrackMonitored()) { TripRecordingBottomSheet.showInstance(fragmentManager); } else { - TripRecordingStartingBottomSheet.showTripRecordingDialog(fragmentManager, app); + TripRecordingStartingBottomSheet.showTripRecordingDialog(app, activity); } } @@ -364,24 +363,28 @@ public boolean isLiveMonitoringEnabled() { return liveMonitoringHelper.isLiveMonitoringEnabled(); } - public void startGPXMonitoring(Activity activity) { + public void startGPXMonitoring(@Nullable FragmentActivity activity) { ValueHolder vs = new ValueHolder<>(); ValueHolder choice = new ValueHolder<>(); + vs.value = settings.SAVE_GLOBAL_TRACK_INTERVAL.get(); choice.value = settings.SAVE_GLOBAL_TRACK_REMEMBER.get(); - Runnable runnable = () -> { - app.getSavingTrackHelper().startNewSegment(); - settings.SAVE_GLOBAL_TRACK_INTERVAL.set(vs.value); - settings.SAVE_GLOBAL_TRACK_TO_GPX.set(true); - settings.SAVE_GLOBAL_TRACK_REMEMBER.set(choice.value); - app.startNavigationService(NavigationService.USED_BY_GPX); - }; + if (choice.value || activity == null) { + Runnable runnable = () -> { + app.getSavingTrackHelper().startNewSegment(); + settings.SAVE_GLOBAL_TRACK_INTERVAL.set(vs.value); + settings.SAVE_GLOBAL_TRACK_TO_GPX.set(true); + settings.SAVE_GLOBAL_TRACK_REMEMBER.set(choice.value); + + if (activity != null) { + AndroidUtils.requestNotificationPermissionIfNeeded(activity); + } + app.startNavigationService(NavigationService.USED_BY_GPX); + }; runnable.run(); - } else if (activity instanceof FragmentActivity) { - FragmentActivity fragmentActivity = (FragmentActivity) activity; - FragmentManager manager = fragmentActivity.getSupportFragmentManager(); - TripRecordingStartingBottomSheet.showTripRecordingDialog(manager, app); + } else { + TripRecordingStartingBottomSheet.showTripRecordingDialog(app, activity); } } diff --git a/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingBottomSheet.java index 5c7c23e45056..7aabec7c1d20 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingBottomSheet.java @@ -1,5 +1,13 @@ package net.osmand.plus.plugins.monitoring; +import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_ALTITUDE; +import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_GENERAL; +import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_SPEED; +import static net.osmand.plus.myplaces.tracks.dialogs.GPXItemPagerAdapter.createGpxTabsView; +import static net.osmand.plus.utils.AndroidUtils.setPadding; +import static net.osmand.plus.utils.ColorUtilities.getActiveTransparentColorId; +import static net.osmand.plus.utils.UiUtilities.CompoundButtonType.GLOBAL; + import android.app.Activity; import android.app.Dialog; import android.content.Context; @@ -30,28 +38,28 @@ import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.RecyclerView; -import net.osmand.gpx.GPXFile; -import net.osmand.gpx.GPXUtilities.TrkSegment; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; +import net.osmand.gpx.GPXFile; +import net.osmand.gpx.GPXUtilities.TrkSegment; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.SideMenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; -import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.charts.TrackChartPoints; -import net.osmand.plus.myplaces.tracks.dialogs.GPXItemPagerAdapter; +import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.myplaces.tracks.GPXTabItemType; +import net.osmand.plus.myplaces.tracks.dialogs.GPXItemPagerAdapter; import net.osmand.plus.myplaces.tracks.dialogs.SegmentActionsListener; import net.osmand.plus.plugins.PluginsHelper; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.track.GpxBlockStatisticsBuilder; import net.osmand.plus.track.GpxSelectionParams; import net.osmand.plus.track.fragments.TrackAppearanceFragment; -import net.osmand.plus.track.helpers.GpxSelectionHelper; import net.osmand.plus.track.helpers.GpxDisplayItem; +import net.osmand.plus.track.helpers.GpxSelectionHelper; import net.osmand.plus.track.helpers.SelectedGpxFile; import net.osmand.plus.track.helpers.TrackDisplayHelper; import net.osmand.plus.utils.AndroidUtils; @@ -68,14 +76,6 @@ import java.util.Arrays; import java.util.List; -import static net.osmand.plus.myplaces.tracks.dialogs.GPXItemPagerAdapter.createGpxTabsView; -import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_ALTITUDE; -import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_GENERAL; -import static net.osmand.plus.myplaces.tracks.GPXTabItemType.GPX_TAB_ITEM_SPEED; -import static net.osmand.plus.utils.AndroidUtils.setPadding; -import static net.osmand.plus.utils.ColorUtilities.getActiveTransparentColorId; -import static net.osmand.plus.utils.UiUtilities.CompoundButtonType.GLOBAL; - public class TripRecordingBottomSheet extends SideMenuBottomSheetDialogFragment implements SegmentActionsListener { public static final String TAG = TripRecordingBottomSheet.class.getSimpleName(); @@ -210,6 +210,11 @@ private void setupResumePauseButton(View container) { } else { app.getSettings().SAVE_GLOBAL_TRACK_TO_GPX.set(true); app.startNavigationService(NavigationService.USED_BY_GPX); + + FragmentActivity activity = getMapActivity(); + if (activity != null) { + AndroidUtils.requestNotificationPermissionIfNeeded(activity); + } } updateStatus(); createItem(resumePauseButton, !isRecordingTrack ? ItemType.PAUSE : ItemType.RESUME); diff --git a/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingStartingBottomSheet.java b/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingStartingBottomSheet.java index 65eeee1d4ea5..374c2955e237 100644 --- a/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingStartingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/plugins/monitoring/TripRecordingStartingBottomSheet.java @@ -1,5 +1,12 @@ package net.osmand.plus.plugins.monitoring; +import static net.osmand.plus.plugins.monitoring.OsmandMonitoringPlugin.MINUTES; +import static net.osmand.plus.plugins.monitoring.OsmandMonitoringPlugin.SECONDS; +import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createItem; +import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createItemActive; +import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createShowTrackItem; +import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.updateTrackIcon; + import android.app.Dialog; import android.content.Context; import android.graphics.Typeface; @@ -11,13 +18,18 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.cardview.widget.CardView; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + import com.google.android.material.slider.RangeSlider; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.utils.AndroidUtils; -import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.SideMenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; @@ -27,23 +39,12 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.settings.fragments.SettingsScreenType; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatImageView; -import androidx.cardview.widget.CardView; -import androidx.fragment.app.FragmentManager; - -import static net.osmand.plus.plugins.monitoring.OsmandMonitoringPlugin.MINUTES; -import static net.osmand.plus.plugins.monitoring.OsmandMonitoringPlugin.SECONDS; -import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createItem; -import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createItemActive; -import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.createShowTrackItem; -import static net.osmand.plus.plugins.monitoring.TripRecordingBottomSheet.updateTrackIcon; +import net.osmand.plus.utils.AndroidUtils; +import net.osmand.plus.utils.UiUtilities; public class TripRecordingStartingBottomSheet extends SideMenuBottomSheetDialogFragment { public static final String TAG = TripRecordingStartingBottomSheet.class.getSimpleName(); - public static final String UPDATE_LOGGING_INTERVAL = "update_logging_interval"; private OsmandApplication app; private OsmandSettings settings; @@ -63,14 +64,15 @@ public static void showInstance(@NonNull FragmentManager fragmentManager) { } } - public static void showTripRecordingDialog(@NonNull FragmentManager fragmentManager, OsmandApplication app) { - if (!fragmentManager.isStateSaved()) { + public static void showTripRecordingDialog(@NonNull OsmandApplication app, @NonNull FragmentActivity activity) { + FragmentManager manager = activity.getSupportFragmentManager(); + if (!manager.isStateSaved()) { OsmandSettings settings = app.getSettings(); boolean showStartDialog = settings.SHOW_TRIP_REC_START_DIALOG.get(); if (showStartDialog) { - showInstance(fragmentManager); + showInstance(manager); } else { - startRecording(app); + startRecording(app, activity); } } } @@ -220,14 +222,18 @@ private void updateUpDownBtn() { upDownBtn.setImageDrawable(getContentIcon(iconId)); } - private static void startRecording(OsmandApplication app) { + private static void startRecording(@NonNull OsmandApplication app, @Nullable FragmentActivity activity) { app.getSavingTrackHelper().startNewSegment(); app.getSettings().SAVE_GLOBAL_TRACK_TO_GPX.set(true); app.startNavigationService(NavigationService.USED_BY_GPX); + + if (activity != null) { + AndroidUtils.requestNotificationPermissionIfNeeded(activity); + } } private void startRecording() { - startRecording(app); + startRecording(app, getActivity()); MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java index 9acde38161b3..b6e2609b3f58 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/NavResumePauseAction.java @@ -16,6 +16,7 @@ import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.utils.AndroidUtils; public class NavResumePauseAction extends QuickAction { @@ -45,6 +46,7 @@ public void execute(@NonNull MapActivity mapActivity) { routingHelper.setFollowingMode(false); routingHelper.setPauseNavigation(true); } + AndroidUtils.requestNotificationPermissionIfNeeded(mapActivity); mapActivity.getMapViewTrackingUtilities().switchRoutePlanningMode(); mapActivity.refreshMap(); } diff --git a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java index 48a018079bda..7d1649ded783 100644 --- a/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/AndroidUtils.java @@ -1297,6 +1297,18 @@ public static boolean requestBLEPermissions(@NonNull Activity activity) { return Algorithms.isEmpty(permissions); } + public static final int POST_NOTIFICATIONS_REQUEST_CODE = 6; + + public static void requestNotificationPermissionIfNeeded(@NonNull FragmentActivity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (!AndroidUtils.hasPermission(activity, Manifest.permission.POST_NOTIFICATIONS)) { + ActivityCompat.requestPermissions(activity, + new String[] {Manifest.permission.POST_NOTIFICATIONS}, + POST_NOTIFICATIONS_REQUEST_CODE); + } + } + } + @Nullable public static T getSerializable(@NonNull Bundle bundle, @NonNull String key, @NonNull Class clazz) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index f9481a8b7d89..d585035c0bf7 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -29,6 +29,7 @@ import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import com.google.android.material.slider.Slider; @@ -37,6 +38,7 @@ import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.RotatedTileBox; +import net.osmand.gpx.GPXFile; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; @@ -76,7 +78,6 @@ import net.osmand.plus.views.corenative.NativeCoreContext; import net.osmand.plus.views.layers.base.OsmandMapLayer; import net.osmand.plus.views.mapwidgets.WidgetsVisibilityHelper; -import net.osmand.gpx.GPXFile; import net.osmand.util.Algorithms; import java.util.ArrayList; @@ -604,6 +605,10 @@ public void startNavigation() { sim.startStopRouteAnimation(getMapActivity()); } } + FragmentActivity activity = getMapActivity(); + if (activity != null) { + AndroidUtils.requestNotificationPermissionIfNeeded(activity); + } } } } From 1520e0ec2437cbca82c1596be1a101747d19f681 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 27 Oct 2023 13:29:34 +0300 Subject: [PATCH 54/96] Fix review --- .../net/osmand/binary/RouteDataObject.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index 58af6079dda5..bd0c1bcddd8d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -830,16 +830,19 @@ public String getHighway() { } public boolean hasPrivateAccess(GeneralRouterProfile profile) { - int sz = types.length; - for (int i = 0; i < sz; i++) { - RouteTypeRule rule = region.quickGetEncodingRule(types[i]); + for (int type : types) { + RouteTypeRule rule = region.quickGetEncodingRule(type); String tag = rule.getTag(); - if ("vehicle".equals(tag) || "access".equals(tag) - || (profile == GeneralRouterProfile.CAR && ("motorcar".equals(tag) || "motor_vehicle".equals(tag))) - || (profile == GeneralRouterProfile.BICYCLE && ("bicycle".equals(tag)))) { - if (rule.getValue().equals("private")) { - return true; - } + boolean checkPrivate = false; + if ("vehicle".equals(tag) || "access".equals(tag)) { + checkPrivate = true; + } else if (profile == GeneralRouterProfile.CAR) { + checkPrivate = "motorcar".equals(tag) || "motor_vehicle".equals(tag); + } else if (profile == GeneralRouterProfile.BICYCLE) { + checkPrivate = "bicycle".equals(tag); + } + if (checkPrivate && rule.getValue().equals("private")) { + return true; } } return false; From 475e89cc7b8a1a261e95b9c1ca24bc856ecd52cb Mon Sep 17 00:00:00 2001 From: Sergey Kharchenko Date: Fri, 27 Oct 2023 15:49:38 +0300 Subject: [PATCH 55/96] fixes after review --- .../src/main/java/net/osmand/gpx/GPXUtilities.java | 10 ++++++++-- .../osmand/plus/activities/MapActivityActions.java | 2 ++ .../mapmarkers/CoordinateInputDialogFragment.java | 2 ++ .../controller/SmartFolderOptionsController.kt | 4 ++-- .../tracks/dialogs/AvailableTracksFragment.java | 12 ------------ .../tracks/dialogs/BaseTrackFolderFragment.java | 10 +++++++--- .../myplaces/tracks/filters/SmartFolderHelper.kt | 12 +++++------- .../myplaces/tracks/filters/TrackFolderFilter.kt | 8 ++------ .../myplaces/tracks/tasks/SaveCurrentTrackTask.java | 2 ++ OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt | 10 ++++++---- .../net/osmand/plus/track/helpers/GPXDatabase.java | 11 +++++++++++ 11 files changed, 47 insertions(+), 36 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java index 44e18588bc76..24f2ec067464 100644 --- a/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/gpx/GPXUtilities.java @@ -1314,11 +1314,14 @@ public static long getCreationTime(GPXFile gpxFile) { time = gpxFile.metadata.time; } else if (gpxFile.getLastPoint() != null && gpxFile.getLastPoint().time > 0) { time = gpxFile.getLastPoint().time; - } else { + } else if (gpxFile.modifiedTime > 0) { time = gpxFile.modifiedTime; } } - return 0; + if (time == 0) { + time = System.currentTimeMillis(); + } + return time; } private static SimpleDateFormat getTimeFormatter() { @@ -1740,6 +1743,9 @@ public static GPXFile loadGPXFile(InputStream stream, GPXExtensionsReader extens if (addGeneralTrack) { gpxFile.addGeneralTrack(); } + if (gpxFile.metadata.time == 0) { + gpxFile.metadata.time = getCreationTime(gpxFile); + } } catch (Exception e) { gpxFile.error = e; log.error("Error reading gpx", e); //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 55a4c722fa34..1cba27b9b83c 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -68,6 +68,7 @@ import net.osmand.plus.Version; import net.osmand.plus.backup.ui.BackupAuthorizationFragment; import net.osmand.plus.backup.ui.BackupCloudFragment; +import net.osmand.plus.configmap.tracks.TrackItem; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dialogs.SpeedCamerasBottomSheet; import net.osmand.plus.download.IndexItem; @@ -208,6 +209,7 @@ protected GPXFile doInBackground(File... params) { String fileName = Algorithms.getFileNameWithoutExtension(file); GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName); gpx.error = GPXUtilities.writeGpxFile(file, gpx); + app.getSmartFolderHelper().addTrackItemToSmartFolder(new TrackItem(app, gpx)); return gpx; } return null; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java index fd8152fff734..dd39fd1a896a 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java @@ -65,6 +65,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; +import net.osmand.plus.configmap.tracks.TrackItem; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapmarkers.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener; import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM; @@ -1462,6 +1463,7 @@ protected Void doInBackground(Void... params) { } else { GPXUtilities.writeGpxFile(new File(gpx.path), gpx); } + app.getSmartFolderHelper().addTrackItemToSmartFolder(new TrackItem(app, gpx)); return null; } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt index 68e2f1b47fef..a28281012ce7 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/SmartFolderOptionsController.kt @@ -83,7 +83,7 @@ class SmartFolderOptionsController( } SmartFolderOption.EDIT_FILTER -> { - showChangeAppearanceDialog(smartFolder) + showEditFiltersDialog(smartFolder) } SmartFolderOption.EXPORT -> { @@ -137,7 +137,7 @@ class SmartFolderOptionsController( dialogManager.askRefreshDialogCompletely(PROCESS_ID) } - private fun showChangeAppearanceDialog(folder: SmartFolder) { + private fun showEditFiltersDialog(folder: SmartFolder) { dialogManager.askDismissDialog(PROCESS_ID) optionsListener?.showEditFiltersDialog(folder) } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java index 0e663801d7d9..636e79444d04 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/AvailableTracksFragment.java @@ -515,18 +515,6 @@ public void onSmartFoldersUpdated() { updateContent(); } - @Override - public void showEditFiltersDialog(@NonNull SmartFolder folder) { - FragmentManager manager = getFragmentManager(); - ArrayList trackItems = new ArrayList<>(); - trackItems.addAll(smartFolderHelper.getAllAvailableTrackItems()); - TracksSearchFilter filter = new TracksSearchFilter(app, trackItems); - filter.initSelectedFilters(folder.getFilters()); - if (manager != null) { - TracksFilterFragment.Companion.showInstance(app, manager, this, filter, null, folder, null); - } - } - @Override public void showChangeAppearanceDialog(@NonNull TrackFolder folder) { selectionHelper.setAllItems(folder.getFlattenedTrackItems()); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java index 111cdfe22861..4c56e1edd57b 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java @@ -43,6 +43,7 @@ import net.osmand.plus.myplaces.favorites.dialogs.FragmentStateHolder; import net.osmand.plus.myplaces.tracks.ItemsSelectionHelper.SelectionHelperProvider; import net.osmand.plus.myplaces.tracks.TrackFoldersHelper; +import net.osmand.plus.myplaces.tracks.TracksSearchFilter; import net.osmand.plus.myplaces.tracks.controller.SmartFolderOptionsController; import net.osmand.plus.myplaces.tracks.controller.SmartFolderOptionsListener; import net.osmand.plus.myplaces.tracks.controller.TrackFolderOptionsController; @@ -474,9 +475,12 @@ public void showChangeAppearanceDialog(@NonNull TrackFolder folder) { @Override public void showEditFiltersDialog(@NonNull SmartFolder folder) { - FragmentActivity activity = getActivity(); - if (activity != null) { - TracksAppearanceFragment.showInstance(activity.getSupportFragmentManager(), this); + FragmentManager manager = getFragmentManager(); + ArrayList trackItems = new ArrayList<>(smartFolderHelper.getAllAvailableTrackItems()); + TracksSearchFilter filter = new TracksSearchFilter(app, trackItems); + filter.initSelectedFilters(folder.getFilters()); + if (manager != null) { + TracksFilterFragment.Companion.showInstance(app, manager, this, filter, null, folder, null); } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt index 343357b7c41b..dc073bba292e 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/SmartFolderHelper.kt @@ -243,24 +243,22 @@ class SmartFolderHelper(val app: OsmandApplication) { return HashSet(allAvailableTrackItems) } - private class SmartFoldersUpdateTask( + private inner class SmartFoldersUpdateTask( private val app: OsmandApplication, ) : AsyncTask() { @Deprecated("Deprecated in Java") override fun doInBackground(vararg params: Void): Void? { - app.smartFolderHelper.run { - readSettings() - for (folder in smartFolderCollection) { - updateSmartFolderItems(folder) - } - notifyUpdateListeners() + readSettings() + for (folder in smartFolderCollection) { + updateSmartFolderItems(folder) } return null } @Deprecated("Deprecated in Java") override fun onPostExecute(result: Void?) { + notifyUpdateListeners() } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/TrackFolderFilter.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/TrackFolderFilter.kt index 3e8ef243fb12..760c4b310556 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/TrackFolderFilter.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/filters/TrackFolderFilter.kt @@ -7,7 +7,6 @@ import net.osmand.plus.configmap.tracks.TrackItem import net.osmand.plus.myplaces.tracks.filters.FilterType.FOLDER import net.osmand.plus.track.data.TrackFolder import net.osmand.util.Algorithms -import java.io.File class TrackFolderFilter(filterChangedListener: FilterChangedListener) : BaseTrackFilter(R.string.folder, FOLDER, filterChangedListener) { @@ -69,11 +68,8 @@ class TrackFolderFilter(filterChangedListener: FilterChangedListener) : if (!Algorithms.isEmpty(selectedFolders)) { for (folder in selectedFolders) { trackItem.dataItem?.let { gpxDataItem -> - gpxDataItem.file.parent?.let { parentFolderName -> - var parent = File(parentFolderName).name - if (Algorithms.stringsEqual(parent, folder)) { - return true - } + if (Algorithms.stringsEqual(gpxDataItem.containingFolder, folder)) { + return true } } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/SaveCurrentTrackTask.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/SaveCurrentTrackTask.java index eed7053299cb..83f9b68a0007 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/SaveCurrentTrackTask.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/SaveCurrentTrackTask.java @@ -8,6 +8,7 @@ import net.osmand.gpx.GPXFile; import net.osmand.IndexConstants; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.configmap.tracks.TrackItem; import net.osmand.plus.plugins.monitoring.SavingTrackHelper; import net.osmand.plus.track.helpers.save.SaveGpxListener; @@ -54,6 +55,7 @@ protected Boolean doInBackground(Void... params) { Exception exception = GPXUtilities.writeGpxFile(fout, gpx); if (exception == null) { app.getSavingTrackHelper().setLastTimeFileSaved(fout.lastModified()); + app.getSmartFolderHelper().addTrackItemToSmartFolder(new TrackItem(app, gpx)); } } return shouldClearPath; diff --git a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt index c523df8f41bf..ad97940cbf41 100644 --- a/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt +++ b/OsmAnd/src/net/osmand/plus/track/data/SmartFolder.kt @@ -34,17 +34,19 @@ class SmartFolder(folderName: String) : TracksGroup, ComparableTracksGroup { } fun addTrackItem(trackItem: TrackItem) { - if(!trackItems.contains(trackItem)) { + if (!trackItems.contains(trackItem)) { trackItems.add(trackItem) folderAnalysis = null } } override fun getFolderAnalysis(): TrackFolderAnalysis { - if (folderAnalysis == null) { - folderAnalysis = TrackFolderAnalysis(this) + var analysis = folderAnalysis + if (analysis == null) { + analysis = TrackFolderAnalysis(this) + folderAnalysis = analysis } - return folderAnalysis!! + return analysis } override fun getDirName(): String { diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/track/helpers/GPXDatabase.java index 744d48b406e8..85acbf12f5b2 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GPXDatabase.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GPXDatabase.java @@ -315,6 +315,7 @@ public static class GpxDataItem { private double minFilterAltitude = Double.NaN; private double maxFilterAltitude = Double.NaN; private double maxFilterHdop = Double.NaN; + private String containingFolder = ""; public GpxDataItem(File file, GPXTrackAnalysis analysis) { this.file = file; @@ -463,6 +464,15 @@ public double getMaxFilterHdop() { return maxFilterHdop; } + @NonNull + public String getContainingFolder() { + if (containingFolder == null) { + return ""; + } else { + return containingFolder; + } + } + @Nullable public String getNearestCityName() { return nearestCityName; @@ -1224,6 +1234,7 @@ private GpxDataItem readItem(SQLiteCursor query) { dir = new File(app.getAppPath(GPX_INDEX_DIR), fileDir); } GpxDataItem item = new GpxDataItem(new File(dir, fileName), analysis); + item.containingFolder = fileDir; item.color = GPXUtilities.parseColor(color, 0); item.fileLastModifiedTime = fileLastModifiedTime; item.fileLastUploadedTime = fileLastUploadedTime; From cca079df7233b5f9f964ffaefd961eca6f52b4c6 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 27 Oct 2023 19:03:58 +0300 Subject: [PATCH 56/96] Fix review --- .../plus/routing/CurrentStreetName.java | 79 +++++++++++-------- .../plus/routing/RoutingHelperUtils.java | 17 ++-- .../mapwidgets/widgets/StreetNameWidget.java | 39 +++++---- 3 files changed, 76 insertions(+), 59 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java index 2173a246ac9a..71ec0ca516ba 100644 --- a/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java +++ b/OsmAnd/src/net/osmand/plus/routing/CurrentStreetName.java @@ -12,14 +12,15 @@ import net.osmand.router.TurnType; import net.osmand.util.Algorithms; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; public class CurrentStreetName { public String text; public TurnType turnType; public boolean showMarker; // turn type has priority over showMarker - public RoadShield shield; + public List shields = new ArrayList<>(); public String exitRef; @NonNull @@ -46,8 +47,8 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel String dn = n.directionInfo.getDestinationName(); isSet = !(Algorithms.isEmpty(nm) && Algorithms.isEmpty(rf) && Algorithms.isEmpty(dn)); RouteDataObject routeDataObject = n.directionInfo.getRouteDataObject(); - streetName.shield = RoadShield.create(routeDataObject); - streetName.text = RoutingHelperUtils.formatStreetName(nm, rf, dn, "»", streetName.shield); + streetName.shields = RoadShield.create(routeDataObject); + streetName.text = RoutingHelperUtils.formatStreetName(nm, rf, dn, "»", streetName.shields); streetName.turnType = n.directionInfo.getTurnType(); if (streetName.turnType == null) { streetName.turnType = TurnType.valueOf(TurnType.C, false); @@ -73,7 +74,7 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel isSet = true; } streetName.showMarker = true; - streetName.shield = RoadShield.create(rs.getObject()); + streetName.shields = RoadShield.create(rs.getObject()); } } // 3. display next road street name if this one empty @@ -82,7 +83,7 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel if (rs != null) { streetName.text = getRouteSegmentStreetName(routingHelper, rs, false); streetName.turnType = TurnType.valueOf(TurnType.C, false); - streetName.shield = RoadShield.create(rs.getObject()); + streetName.shields = RoadShield.create(rs.getObject()); } } if (streetName.turnType == null) { @@ -93,31 +94,37 @@ public static CurrentStreetName getCurrentName(@NonNull RoutingHelper routingHel public static class RoadShield { private final RouteDataObject rdo; - private final Map shieldTags = new LinkedHashMap<>(); + private final String tag; + private final String value; private StringBuilder additional; - public RoadShield(@NonNull RouteDataObject rdo) { + public RoadShield(@NonNull RouteDataObject rdo, @NonNull String tag, @NonNull String value) { this.rdo = rdo; - StringBuilder additional = new StringBuilder(); - for (int i = 0; i < rdo.nameIds.length; i++) { - String key = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); - String val = rdo.names.get(rdo.nameIds[i]); - if (!key.endsWith("_ref") && !key.startsWith("route_road")) { - additional.append(key).append("=").append(val).append(";"); - } else if (key.startsWith("route_road") && key.endsWith("_ref")) { - shieldTags.put(key, val); - } - } - if (!shieldTags.isEmpty()) { - this.additional = additional; - } + this.tag = tag; + this.value = value; } - public static RoadShield create(@Nullable RouteDataObject rdo) { + @NonNull + public static List create(@Nullable RouteDataObject rdo) { + List shields = new ArrayList<>(); if (rdo != null && rdo.nameIds != null) { - return new RoadShield(rdo); + StringBuilder additional = new StringBuilder(); + for (int i = 0; i < rdo.nameIds.length; i++) { + String tag = rdo.region.routeEncodingRules.get(rdo.nameIds[i]).getTag(); + String val = rdo.names.get(rdo.nameIds[i]); + if (!tag.endsWith("_ref") && !tag.startsWith("route_road")) { + additional.append(tag).append("=").append(val).append(";"); + } else if (tag.startsWith("route_road") && tag.endsWith("_ref")) { + shields.add(new RoadShield(rdo, tag, val)); + } + } + if (!shields.isEmpty()) { + for (RoadShield shield : shields) { + shield.additional = additional; + } + } } - return null; + return shields; } public RouteDataObject getRdo() { @@ -128,16 +135,26 @@ public StringBuilder getAdditional() { return additional; } - public Map getShieldTags() { - return shieldTags; + public String getTag() { + return tag; + } + + public String getValue() { + return value; } - public boolean hasShield() { - return !shieldTags.isEmpty(); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RoadShield shield = (RoadShield) o; + return Objects.equals(tag, shield.tag) + && Objects.equals(value, shield.value); } - public boolean equalsShield(@Nullable RoadShield roadShield) { - return roadShield != null && shieldTags.equals(roadShield.shieldTags); + @Override + public int hashCode() { + return Objects.hash(tag, value); } } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index cb6126e9a3c1..4715f6e684fd 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -29,18 +29,19 @@ public class RoutingHelperUtils { public static final int MAX_BEARING_DEVIATION = 160; @NonNull - public static String formatStreetName(String name, String ref, String destination, String towards) { + public static String formatStreetName(@Nullable String name, @Nullable String ref, @Nullable String destination, + @NonNull String towards) { return formatStreetName(name, ref, destination, towards, null); } @NonNull - public static String formatStreetName(String name, String originalRef, String destination, String towards, - RoadShield shield) { + public static String formatStreetName(@Nullable String name, @Nullable String originalRef, @Nullable String destination, + @NonNull String towards, @Nullable List shields) { StringBuilder formattedStreetName = new StringBuilder(); if (originalRef != null && originalRef.length() > 0) { String[] refs = originalRef.split(";"); for (String ref : refs) { - if (shield == null || !isRefEqualsShield(shield, ref)) { + if (shields == null || !isRefEqualsShield(shields, ref)) { if (formattedStreetName.length() > 0) { formattedStreetName.append(" "); } @@ -63,10 +64,10 @@ public static String formatStreetName(String name, String originalRef, String de return formattedStreetName.toString().replace(";", ", "); } - private static boolean isRefEqualsShield(RoadShield shield, String ref) { - for (Entry entry : shield.getShieldTags().entrySet()) { - String shieldText = entry.getValue(); - if (ref.equals(shieldText) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldText)) { + private static boolean isRefEqualsShield(@NonNull List shields, @NonNull String ref) { + for (RoadShield shield : shields) { + String shieldValue = shield.getValue(); + if (ref.equals(shieldValue) || String.valueOf(Algorithms.extractIntegerNumber(ref)).equals(shieldValue)) { return true; } } diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index fed4f6e42dd4..1563a78a8b3c 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -56,7 +56,6 @@ import net.osmand.util.Algorithms; import java.util.List; -import java.util.Map; public class StreetNameWidget extends MapWidget { @@ -75,7 +74,7 @@ public class StreetNameWidget extends MapWidget { private final TurnDrawable turnDrawable; private int shadowRadius; private boolean showMarker; - private RoadShield cachedRoadShield; + private List cachedRoadShields; @Override protected int getLayoutId() { @@ -131,9 +130,9 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { AndroidUiHelper.updateVisibility(addressText, true); AndroidUiHelper.updateVisibility(addressTextShadow, shadowRadius > 0); - RoadShield shield = streetName.shield; - if (shield != null && !shield.equalsShield(cachedRoadShield)) { - if (setRoadShield(shield)) { + List shields = streetName.shields; + if (!shields.isEmpty() && !shields.equals(cachedRoadShields)) { + if (setRoadShield(shields)) { AndroidUiHelper.updateVisibility(shieldImagesContainer, true); int indexOf = streetName.text.indexOf("»"); if (indexOf > 0) { @@ -142,10 +141,10 @@ public void updateInfo(@Nullable DrawSettings drawSettings) { } else { AndroidUiHelper.updateVisibility(shieldImagesContainer, false); } - cachedRoadShield = shield; - } else if (shield == null) { + cachedRoadShields = shields; + } else if (shields.isEmpty()) { AndroidUiHelper.updateVisibility(shieldImagesContainer, false); - cachedRoadShield = null; + cachedRoadShields = null; } if (Algorithms.isEmpty(streetName.exitRef)) { @@ -215,23 +214,23 @@ public boolean updateWaypoint() { } } - private boolean setRoadShield(@NonNull RoadShield shield) { - if (shield.hasShield()) { - boolean shieldSet = false; + private boolean setRoadShield(@NonNull List shields) { + if (!Algorithms.isEmpty(shields)) { + boolean isShieldSet = false; shieldImagesContainer.removeAllViews(); - for (Map.Entry entry : shield.getShieldTags().entrySet()) { - String nameTag = entry.getKey(); - String text = entry.getValue(); - shieldSet |= setShieldImage(shield, nameTag, text); + for (RoadShield shield : shields) { + isShieldSet |= setShieldImage(shield); } - return shieldSet; + return isShieldSet; } return false; } - private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, String name) { + private boolean setShieldImage(@NonNull RoadShield shield) { RouteDataObject object = shield.getRdo(); StringBuilder additional = shield.getAdditional(); + String shieldValue = shield.getValue(); + String shieldTag = shield.getTag(); int[] types = object.getTypes(); RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer(); RenderingRuleSearchRequest rreq = app.getResourceManager().getRenderer() @@ -248,14 +247,14 @@ private boolean setShieldImage(@NonNull RoadShield shield, String nameTag, Strin } } - rreq.setIntFilter(rreq.ALL.R_TEXT_LENGTH, name.length()); - rreq.setStringFilter(rreq.ALL.R_NAME_TAG, nameTag); + rreq.setIntFilter(rreq.ALL.R_TEXT_LENGTH, shieldValue.length()); + rreq.setStringFilter(rreq.ALL.R_NAME_TAG, shieldTag); rreq.setStringFilter(rreq.ALL.R_ADDITIONAL, additional.toString()); rreq.search(RenderingRulesStorage.TEXT_RULES); RenderingContext rc = new RenderingContext(app); TextRenderer textRenderer = new TextRenderer(app); - TextDrawInfo text = new TextDrawInfo(name); + TextDrawInfo text = new TextDrawInfo(shieldValue); int shieldRes = -1; if (rreq.isSpecified(rreq.ALL.R_TEXT_SHIELD)) { From 907cf96c17ae4140cf3379c8094f308c2a8a295b Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sat, 28 Oct 2023 10:50:21 +0300 Subject: [PATCH 57/96] Use secondary status bar color in appropriate places --- .../keyevent/fragments/EditKeyBindingFragment.java | 2 +- .../fragments/ExternalInputDeviceFragment.java | 7 +++++++ .../plus/keyevent/fragments/SelectKeyCodeFragment.java | 2 +- .../fragments/inputdevices/InputDevicesFragment.java | 2 +- .../fragments/keybindings/KeyBindingsFragment.java | 2 +- .../myplaces/tracks/dialogs/TracksFilterFragment.kt | 6 ++---- OsmAnd/src/net/osmand/plus/utils/ColorUtilities.java | 10 ++++++++++ .../plus/wikipedia/WikiArticleBaseDialogFragment.java | 4 +++- .../osmand/plus/wikivoyage/WikiBaseDialogFragment.java | 4 +++- .../wikivoyage/explore/WikivoyageExploreActivity.java | 4 +++- 10 files changed, 32 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java index 8b3ea5b5a935..fbd02481d82c 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java @@ -234,7 +234,7 @@ private void setupSelectableBackground(@NonNull View view, @ColorInt int color) @Override public int getStatusBarColorId() { AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); - return ColorUtilities.getListBgColorId(nightMode); + return ColorUtilities.getStatusBarSecondaryColorId(nightMode); } public static void showInstance(@NonNull FragmentManager manager, diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/ExternalInputDeviceFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/ExternalInputDeviceFragment.java index b4f6d3cfd6bf..0e95b9a767b5 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/ExternalInputDeviceFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/ExternalInputDeviceFragment.java @@ -156,6 +156,13 @@ private boolean isInputDeviceEnabled() { return deviceHelper.getEnabledDevice(getSelectedAppMode()) != null; } + @Override + public int getStatusBarColorId() { + boolean nightMode = isNightMode(); + AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); + return ColorUtilities.getStatusBarSecondaryColorId(nightMode); + } + @ColorRes protected int getBackgroundColorRes() { return ColorUtilities.getActivityBgColorId(isNightMode()); diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java index 578bde7baddd..a905070e1aef 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java @@ -269,7 +269,7 @@ private void dismiss() { @Override public int getStatusBarColorId() { AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); - return ColorUtilities.getListBgColorId(nightMode); + return ColorUtilities.getStatusBarSecondaryColorId(nightMode); } public static void showInstance(@NonNull FragmentManager manager, diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java index 48e9703b8794..163e5ef761fa 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java @@ -127,7 +127,7 @@ private MapActivity getMapActivity() { @Override public int getStatusBarColorId() { AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); - return ColorUtilities.getListBgColorId(nightMode); + return ColorUtilities.getStatusBarSecondaryColorId(nightMode); } public static void showInstance(@NonNull FragmentManager manager, diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java index 4697b3f3fbd5..106871ce2e18 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java @@ -125,7 +125,7 @@ private MapActivity getMapActivity() { @Override public int getStatusBarColorId() { AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); - return ColorUtilities.getListBgColorId(nightMode); + return ColorUtilities.getStatusBarSecondaryColorId(nightMode); } public static void showInstance(@NonNull FragmentManager manager, diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt index 5de4b016e795..f2920c784308 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/TracksFilterFragment.kt @@ -35,6 +35,7 @@ import net.osmand.plus.myplaces.tracks.filters.SmartFolderUpdateListener import net.osmand.plus.track.data.SmartFolder import net.osmand.plus.track.data.TrackFolder import net.osmand.plus.utils.AndroidUtils +import net.osmand.plus.utils.ColorUtilities.getStatusBarSecondaryColor import net.osmand.plus.widgets.dialogbutton.DialogButton import net.osmand.util.Algorithms @@ -107,10 +108,7 @@ class TracksFilterFragment : BaseOsmAndDialogFragment(), private fun updateStatusBarColor(window: Window?) { window?.let { - val statusBarColor = - if (nightMode) R.color.status_bar_secondary_dark else R.color.status_bar_secondary_light - ContextCompat.getColor(requireContext(), statusBarColor) - window.statusBarColor = ContextCompat.getColor(requireContext(), statusBarColor) + window.statusBarColor = getStatusBarSecondaryColor(requireContext(), nightMode) } } diff --git a/OsmAnd/src/net/osmand/plus/utils/ColorUtilities.java b/OsmAnd/src/net/osmand/plus/utils/ColorUtilities.java index f6b5e3c12743..f997051c83c2 100644 --- a/OsmAnd/src/net/osmand/plus/utils/ColorUtilities.java +++ b/OsmAnd/src/net/osmand/plus/utils/ColorUtilities.java @@ -352,6 +352,16 @@ public static int getStatusBarActiveColorId(boolean nightMode) { return nightMode ? R.color.status_bar_selection_color_dark : R.color.status_bar_selection_color_light; } + @ColorInt + public static int getStatusBarSecondaryColor(@NonNull Context context, boolean nightMode) { + return getColor(context, getStatusBarSecondaryColorId(nightMode)); + } + + @ColorRes + public static int getStatusBarSecondaryColorId(boolean nightMode) { + return nightMode ? R.color.status_bar_secondary_dark : R.color.status_bar_secondary_light; + } + @ColorInt public static int getLinksColor(@NonNull Context ctx, boolean nightMode) { return getColor(ctx, getLinksColorId(nightMode)); diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java index 91791db8662d..81ff8a36a635 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikiArticleBaseDialogFragment.java @@ -1,5 +1,7 @@ package net.osmand.plus.wikipedia; +import static net.osmand.plus.utils.ColorUtilities.getStatusBarSecondaryColorId; + import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; @@ -145,7 +147,7 @@ protected Drawable getSelectedLangIcon() { @Override @ColorRes protected int getStatusBarColor() { - return nightMode ? R.color.status_bar_secondary_dark : R.color.status_bar_secondary_light; + return getStatusBarSecondaryColorId(nightMode); } protected abstract void showPopupLangMenu(View view, String langSelected); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikiBaseDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikiBaseDialogFragment.java index 77513834b115..834b99ea7bd6 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikiBaseDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikiBaseDialogFragment.java @@ -1,5 +1,7 @@ package net.osmand.plus.wikivoyage; +import static net.osmand.plus.utils.ColorUtilities.getStatusBarSecondaryColorId; + import android.app.Dialog; import android.graphics.drawable.Drawable; import android.os.Build; @@ -64,7 +66,7 @@ protected Drawable getActiveIcon(@DrawableRes int iconId) { @ColorRes protected int getStatusBarColor() { - return nightMode ? R.color.status_bar_secondary_dark : R.color.status_bar_secondary_light; + return getStatusBarSecondaryColorId(nightMode); } @ColorInt diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index 4baa7012992f..fd2a12c36652 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -1,5 +1,7 @@ package net.osmand.plus.wikivoyage.explore; +import static net.osmand.plus.utils.ColorUtilities.getStatusBarSecondaryColorId; + import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; @@ -277,7 +279,7 @@ protected Drawable getIcon(@DrawableRes int id, @ColorRes int colorId) { @ColorRes protected int getStatusBarColor() { - return nightMode ? R.color.status_bar_secondary_dark : R.color.status_bar_secondary_light; + return getStatusBarSecondaryColorId(nightMode); } @ColorInt From ca11209dd1587e6196969e1e2fec7f7ffd42c390 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sat, 28 Oct 2023 11:19:28 +0300 Subject: [PATCH 58/96] Close Type screen after change of type --- .../plus/keyevent/InputDeviceHelper.java | 27 +++++++++---------- .../plus/keyevent/callbacks/EventType.java | 9 +++++++ .../callbacks/InputDeviceHelperCallback.java | 7 +++++ .../callbacks/OnKeyCodeSelectedCallback.java | 5 ++++ .../fragments/EditKeyBindingFragment.java | 4 +-- .../fragments/SelectKeyCodeFragment.java | 6 ++--- .../inputdevices/InputDevicesFragment.java | 24 ++++++++++------- .../keybindings/KeyBindingsFragment.java | 11 +++++--- .../interfaces/OnKeyCodeSelected.java | 5 ---- 9 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/keyevent/callbacks/EventType.java create mode 100644 OsmAnd/src/net/osmand/plus/keyevent/callbacks/InputDeviceHelperCallback.java create mode 100644 OsmAnd/src/net/osmand/plus/keyevent/callbacks/OnKeyCodeSelectedCallback.java delete mode 100644 OsmAnd/src/net/osmand/plus/keyevent/interfaces/OnKeyCodeSelected.java diff --git a/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java b/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java index 2cdbd6d834de..536bae5d48e7 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java @@ -7,12 +7,13 @@ import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.keyevent.commands.KeyEventCommand; import net.osmand.plus.keyevent.devices.CustomInputDeviceProfile; import net.osmand.plus.keyevent.devices.InputDeviceProfile; import net.osmand.plus.keyevent.devices.KeyboardDeviceProfile; import net.osmand.plus.keyevent.devices.ParrotDeviceProfile; import net.osmand.plus.keyevent.devices.WunderLINQDeviceProfile; +import net.osmand.plus.keyevent.callbacks.EventType; +import net.osmand.plus.keyevent.callbacks.InputDeviceHelperCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -44,7 +45,7 @@ public class InputDeviceHelper { private final List defaultDevices = Arrays.asList(KEYBOARD, PARROT, WUNDER_LINQ); private final List customDevices; private final Map cachedDevices = new HashMap<>(); - private final List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); public InputDeviceHelper(@NonNull OsmandApplication app) { this.app = app; @@ -64,17 +65,17 @@ public List getAvailableDevices() { return result; } - public void addListener(@NonNull InputDeviceHelperListener listener) { + public void addListener(@NonNull InputDeviceHelperCallback listener) { listeners.add(listener); } - public void removeListener(@NonNull InputDeviceHelperListener listener) { + public void removeListener(@NonNull InputDeviceHelperCallback listener) { listeners.remove(listener); } public void selectInputDevice(@NonNull ApplicationMode appMode, @NonNull String deviceId) { settings.EXTERNAL_INPUT_DEVICE.setModeValue(appMode, deviceId); - notifyListeners(); + notifyListeners(EventType.SELECT_DEVICE); } public void createAndSaveCustomDevice(@NonNull String newName) { @@ -88,7 +89,7 @@ public void createAndSaveDeviceDuplicate(@NonNull InputDeviceProfile device) { public void renameCustomDevice(@NonNull CustomInputDeviceProfile device, @NonNull String newName) { device.setCustomName(newName); syncSettings(); - notifyListeners(); + notifyListeners(EventType.RENAME_DEVICE); } @NonNull @@ -127,7 +128,7 @@ private void saveCustomDevice(@NonNull InputDeviceProfile device) { customDevices.add(device); cachedDevices.put(device.getId(), device); syncSettings(); - notifyListeners(); + notifyListeners(EventType.ADD_NEW_DEVICE); } public void removeCustomDevice(@NonNull String deviceId) { @@ -137,7 +138,7 @@ public void removeCustomDevice(@NonNull String deviceId) { cachedDevices.remove(deviceId); syncSettings(); resetSelectedDeviceIfNeeded(); - notifyListeners(); + notifyListeners(EventType.DELETE_DEVICE); } } @@ -221,9 +222,9 @@ public boolean hasNameDuplicate(@NonNull String newName) { return false; } - private void notifyListeners() { - for (InputDeviceHelperListener listener : listeners) { - listener.onInputDeviceHelperEvent(); + private void notifyListeners(@NonNull EventType event) { + for (InputDeviceHelperCallback listener : listeners) { + listener.processInputDeviceHelperEvent(event); } } @@ -272,8 +273,4 @@ public static void writeToJson(@NonNull JSONObject json, } json.put("items", jsonArray); } - - public interface InputDeviceHelperListener { - void onInputDeviceHelperEvent(); - } } diff --git a/OsmAnd/src/net/osmand/plus/keyevent/callbacks/EventType.java b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/EventType.java new file mode 100644 index 000000000000..74d053e3af30 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/EventType.java @@ -0,0 +1,9 @@ +package net.osmand.plus.keyevent.callbacks; + +public enum EventType { + SELECT_DEVICE, + RENAME_DEVICE, + ADD_NEW_DEVICE, + DELETE_DEVICE, + UPDATE_KEYBINDING +} diff --git a/OsmAnd/src/net/osmand/plus/keyevent/callbacks/InputDeviceHelperCallback.java b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/InputDeviceHelperCallback.java new file mode 100644 index 000000000000..1d3d7098a991 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/InputDeviceHelperCallback.java @@ -0,0 +1,7 @@ +package net.osmand.plus.keyevent.callbacks; + +import androidx.annotation.NonNull; + +public interface InputDeviceHelperCallback { + void processInputDeviceHelperEvent(@NonNull EventType event); +} diff --git a/OsmAnd/src/net/osmand/plus/keyevent/callbacks/OnKeyCodeSelectedCallback.java b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/OnKeyCodeSelectedCallback.java new file mode 100644 index 000000000000..34a3fd4e1278 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/keyevent/callbacks/OnKeyCodeSelectedCallback.java @@ -0,0 +1,5 @@ +package net.osmand.plus.keyevent.callbacks; + +public interface OnKeyCodeSelectedCallback { + void onKeyCodeSelected(int newKeyCode); +} diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java index fbd02481d82c..5c597716d3b4 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java @@ -29,7 +29,7 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.keyevent.InputDeviceHelper; import net.osmand.plus.keyevent.keybinding.KeyBinding; -import net.osmand.plus.keyevent.interfaces.OnKeyCodeSelected; +import net.osmand.plus.keyevent.callbacks.OnKeyCodeSelectedCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; @@ -41,7 +41,7 @@ import studio.carbonylgroup.textfieldboxes.ExtendedEditText; -public class EditKeyBindingFragment extends BaseOsmAndFragment implements OnKeyCodeSelected { +public class EditKeyBindingFragment extends BaseOsmAndFragment implements OnKeyCodeSelectedCallback { public static final String TAG = EditKeyBindingFragment.class.getSimpleName(); diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java index a905070e1aef..adb3b8f1d2d8 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java @@ -31,7 +31,7 @@ import net.osmand.plus.keyevent.commands.KeyEventCommand; import net.osmand.plus.keyevent.devices.InputDeviceProfile; import net.osmand.plus.keyevent.keybinding.KeyBinding; -import net.osmand.plus.keyevent.interfaces.OnKeyCodeSelected; +import net.osmand.plus.keyevent.callbacks.OnKeyCodeSelectedCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; @@ -121,8 +121,8 @@ private void setupApplyButton(@NonNull View view) { applyButton = view.findViewById(R.id.dismiss_button); applyButton.setOnClickListener(v -> { Fragment target = getTargetFragment(); - if (target instanceof OnKeyCodeSelected) { - ((OnKeyCodeSelected) target).onKeyCodeSelected(keyCode); + if (target instanceof OnKeyCodeSelectedCallback) { + ((OnKeyCodeSelectedCallback) target).onKeyCodeSelected(keyCode); } dismiss(); }); diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java index 163e5ef761fa..c88d6a7f1d1a 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/inputdevices/InputDevicesFragment.java @@ -23,12 +23,13 @@ import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.keyevent.InputDeviceHelper; -import net.osmand.plus.keyevent.InputDeviceHelper.InputDeviceHelperListener; +import net.osmand.plus.keyevent.callbacks.EventType; +import net.osmand.plus.keyevent.callbacks.InputDeviceHelperCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; -public class InputDevicesFragment extends BaseOsmAndFragment implements InputDeviceHelperListener { +public class InputDevicesFragment extends BaseOsmAndFragment implements InputDeviceHelperCallback { public static final String TAG = InputDevicesFragment.class.getSimpleName(); @@ -70,12 +71,7 @@ private void setupToolbar(@NonNull View view) { ImageView closeButton = toolbar.findViewById(R.id.close_button); closeButton.setImageResource(R.drawable.ic_action_close); - closeButton.setOnClickListener(v -> { - FragmentActivity activity = getActivity(); - if (activity != null) { - activity.onBackPressed(); - } - }); + closeButton.setOnClickListener(v -> dismiss()); TextView title = toolbar.findViewById(R.id.toolbar_title); title.setText(getString(R.string.shared_string_type)); @@ -91,8 +87,11 @@ private void setupToolbar(@NonNull View view) { } @Override - public void onInputDeviceHelperEvent() { + public void processInputDeviceHelperEvent(@NonNull EventType event) { updateViewContent(); + if (event == EventType.SELECT_DEVICE) { + dismiss(); + } } private void updateViewContent() { @@ -119,6 +118,13 @@ public void onPause() { deviceHelper.removeListener(this); } + private void dismiss() { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.onBackPressed(); + } + } + @Nullable private MapActivity getMapActivity() { return (MapActivity) getActivity(); diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java index 106871ce2e18..f2c46020574c 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsFragment.java @@ -23,12 +23,13 @@ import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.keyevent.InputDeviceHelper; -import net.osmand.plus.keyevent.InputDeviceHelper.InputDeviceHelperListener; +import net.osmand.plus.keyevent.callbacks.EventType; +import net.osmand.plus.keyevent.callbacks.InputDeviceHelperCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; -public class KeyBindingsFragment extends BaseOsmAndFragment implements InputDeviceHelperListener { +public class KeyBindingsFragment extends BaseOsmAndFragment implements InputDeviceHelperCallback { public static final String TAG = KeyBindingsFragment.class.getSimpleName(); @@ -87,8 +88,10 @@ private void setupToolbar(@NonNull View view) { } @Override - public void onInputDeviceHelperEvent() { - updateViewContent(); + public void processInputDeviceHelperEvent(@NonNull EventType event) { + if (event == EventType.UPDATE_KEYBINDING) { + updateViewContent(); + } } private void updateViewContent() { diff --git a/OsmAnd/src/net/osmand/plus/keyevent/interfaces/OnKeyCodeSelected.java b/OsmAnd/src/net/osmand/plus/keyevent/interfaces/OnKeyCodeSelected.java deleted file mode 100644 index 5d32494a889d..000000000000 --- a/OsmAnd/src/net/osmand/plus/keyevent/interfaces/OnKeyCodeSelected.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.osmand.plus.keyevent.interfaces; - -public interface OnKeyCodeSelected { - void onKeyCodeSelected(int newKeyCode); -} From c93a07e624cee059bddbbdbc5cc193ad93ef445e Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sat, 28 Oct 2023 11:56:55 +0300 Subject: [PATCH 59/96] Fix "Different shadow below AppBar" --- OsmAnd/res/layout/fragment_edit_key_action.xml | 6 ------ OsmAnd/res/layout/fragment_select_key_code.xml | 6 ------ 2 files changed, 12 deletions(-) diff --git a/OsmAnd/res/layout/fragment_edit_key_action.xml b/OsmAnd/res/layout/fragment_edit_key_action.xml index fef5132e4058..2db3e5fe484c 100644 --- a/OsmAnd/res/layout/fragment_edit_key_action.xml +++ b/OsmAnd/res/layout/fragment_edit_key_action.xml @@ -81,12 +81,6 @@ - - - - Date: Sat, 28 Oct 2023 12:32:13 +0300 Subject: [PATCH 60/96] Fix "Change button" screen after 1st UI Review --- .../res/layout/fragment_select_key_code.xml | 32 +++++++++++-------- OsmAnd/res/values/strings.xml | 3 +- .../fragments/SelectKeyCodeFragment.java | 16 +++++++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/layout/fragment_select_key_code.xml b/OsmAnd/res/layout/fragment_select_key_code.xml index b7449c0087e7..49f5c68f8e5b 100644 --- a/OsmAnd/res/layout/fragment_select_key_code.xml +++ b/OsmAnd/res/layout/fragment_select_key_code.xml @@ -46,7 +46,7 @@ android:orientation="vertical"> + android:textColor="?android:textColorPrimary" + tools:text="@string/press_button_to_link_with_action" /> + + + + - + - + - + - + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index d9231cfe63de..b12f2523b1ab 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -10,11 +10,12 @@ - For wording and consistency, please note https://docs.osmand.net/docs/technical/contributions/translating-osmand Thx - Hardy --> + Change button Deletion error Rows Show toast about pressed key The \"%1$s\" key is already assigned to another action: \"%2$s\" - Press the button on your device to link it with the chosen action. + Press the button on your device to bind it with the action: %1$s Button Action Change key binding diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java index adb3b8f1d2d8..f8aec7af9a0c 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/SelectKeyCodeFragment.java @@ -1,9 +1,12 @@ package net.osmand.plus.keyevent.fragments; +import static android.graphics.Typeface.BOLD; import static net.osmand.plus.settings.fragments.BaseSettingsFragment.APP_MODE_KEY; import static net.osmand.plus.utils.ColorUtilities.getPrimaryIconColor; +import static net.osmand.plus.utils.UiUtilities.createSpannableString; import android.os.Bundle; +import android.text.SpannableString; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -86,6 +89,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c View view = themedInflater.inflate(R.layout.fragment_select_key_code, container, false); AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view); setupToolbar(view); + setupDescription(view); setupApplyButton(view); return view; } @@ -109,6 +113,16 @@ private void setupToolbar(@NonNull View view) { }); } + private void setupDescription(@NonNull View view) { + KeyEventCommand command = inputDevice.findCommand(initialKeyCode); + if (command != null) { + String action = command.toHumanString(app); + String message = getString(R.string.press_button_to_link_with_action, action); + TextView description = view.findViewById(R.id.description); + description.setText(createSpannableString(message, BOLD, action)); + } + } + private void startPulseAnimation(@NonNull View view) { AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); animation.setDuration(PULSE_DELAY_MS); @@ -171,7 +185,7 @@ private void updateErrorMessageState(@NonNull View view) { String keyLabel = KeySymbolMapper.getKeySymbol(keyCode); String actionName = commandDuplicate.toHumanString(app); String message = getString(R.string.key_is_already_assigned_error, keyLabel, actionName); - errorMessage.setText(message); + errorMessage.setText(createSpannableString(message, BOLD, keyLabel, actionName)); } else { AndroidUiHelper.updateVisibility(warning, false); } From 2610e4e7a4d5c52f5e836ba1631cafe32e5520d8 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Sat, 28 Oct 2023 17:58:42 +0000 Subject: [PATCH 61/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4910 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 2b04e5fd70f1..d0b1447ab50b 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5500,4 +5500,22 @@ %1$d (%2$d trasee) %1$d (%2$d de trasee) + Zoom interior + Afișează toastul despre tasta apăsată + Rânduri + Apăsați butonul de pe dispozitiv pentru a-l lega de acțiunea aleasă. + Eroare de ștergere + Mutați-vă la dreapta + Buton + Schimbarea legăturii cheilor + Luați notă de presă + Activitate înapoi apăsat + Emiteți indicii de navigare + Acțiune + Zoom în afară + Afișați / ascundeți meniul lateral + Tasta \"%1$s\" este deja atribuită unei alte acțiuni: \"%2$s\" + Harta interacțiunilor + Deschideți WunderLINQ Datagrid + Acțiuni \ No newline at end of file From 70df303ed88ff3588b359906b37eb51cbed25321 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Sat, 28 Oct 2023 10:48:18 +0000 Subject: [PATCH 62/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4910 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index d0b1447ab50b..b9bd8d751563 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -1044,8 +1044,8 @@ Fotografiere Fotografiază Utilizați track-ul afișat pentru navigație\? - Adăugați ca destinație subsecventă - Selectează pe hartă + Adăugă ca destinație subsecventă + Selectare pe hartă Favorită Preferă autostrăzi Preferă autostrăzi @@ -1618,7 +1618,7 @@ Lat %1$s \nLun %2$s Întrebări frecvente, schimbări recente și altele. - Setare navigație + Setări navigație Setări generale Nu folosiți @@ -1669,7 +1669,7 @@ Permisiuni Instalați Adaugă poze - Faceți din aceasta punctul de început + Setează acesta ca punct de plecare Actual Adaugă o oprire intermediară Adaugă oprirea inițială @@ -2229,7 +2229,7 @@ Cu %1$s Pas cu pas Tipuri drum - Coborâre la + Coborâre la stația Urcare la stația Schimbați Afișați mai multe @@ -2534,7 +2534,7 @@ Dispozitive externe de intrare Tastatură Ține cont de limitările temporare - Setări pentru rutare în profilul selectat \"%1$s\". + Setări de rutare pentru profilul selectat \"%1$s\". Unități & formate Aspect hartă Plugin-uri instalate @@ -4018,7 +4018,7 @@ Icon afișat în timpul navigației sau deplasării. Traseele înregistrate se află în %1$s sau în folderul OsmAnd. Permite partajarea locației curente folosindu-se de înregistrarea călătoriei. - Importul fișierului de rutare + Importă fișier de rutare Împărțire înregistrare Resetază configurația pluginului la valorile implicite Buffer de timp From 7051d54340a43d9aadc16be8e4915cf0914f61e1 Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 26 Oct 2023 17:08:54 +0000 Subject: [PATCH 63/96] Translated using Weblate (Portuguese) Currently translated at 100.0% (4949 of 4949 strings) --- OsmAnd/res/values-pt/strings.xml | 230 +++++++++++++++++++++++++++++-- 1 file changed, 222 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index 6385167ef6b3..50cf7ea668de 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -1919,7 +1919,7 @@ Alterar cor Editar nome Animar deslocação no mapa - Ativar animação da deslocação do mapa da \"Minha posição\" durante a navegação. + Desloca suavemente o mapa quando em movimento. Introduz um ligeiro atraso. Visão geral Selecionar rua em %1$s @@ -2605,7 +2605,7 @@ Adiantado Normal Atrasado - Nos últimos metros + Muito tarde Buffer de tempo para rastreamento online Especificar um buffer de tempo para manter locais a enviar sem ligação à Internet Europa - Países Baixos @@ -4665,7 +4665,7 @@ Modo Santáli Ter em conta as paragens - Especifique o intervalo de tempo para calcular a velocidade média. + Especifique o intervalo de tempo para calcular a média da velocidade. Mostra a velocidade média da viagem atual. Velocidade média Considerar permissões de acesso a veículos ligeiros de mercadorias @@ -4767,7 +4767,7 @@ Larga Toque no mapa para ver a distância entre a sua localização atual e o ponto tocado. \nToque com 2 dedos no mapa para ver a distância entre os pontos - Especifique o intervalo de tempo para o qual a velocidade média será medida para calcular a hora prevista de chegada. + Especifique o intervalo de tempo para o qual a velocidade média será medida para calcular o tempo estimado de chegada. Ir para a localização do marcador Modo de alternância Clique no widget @@ -4778,12 +4778,12 @@ Coordenadas: centro do mapa Coordenadas: localização atual Um alternador para mostrar ou esconder o widget do centro do mapa no mapa. - Mostra o ângulo de inclinação da câmara no modo de perspetiva. A inclinação predefinida é de 90° (sem inclinação). + Mostra o ângulo de inclinação da câmara no modo de perspetiva. O padrão é 90° (sem inclinação). Nível de ampliação Elevação da câmara Widgets de desenvolvimento Mostra a distância entre a câmara e o local de destino. - Mostra o nível atual de zoom do mapa. + Mostra o nível de ampliação (zoom) do mapa atual. Inclinação da câmara Não foi possível encontrar o serviço \"%1$s\". \nTem de instalar ou atualizar o Serviço de Plugins ANT+. @@ -4823,7 +4823,7 @@ Coordenadas: localização atual Elevação: centro do mapa Mostra a altitude acima do nível do mar da geolocalização atual. - Mostra a rapidez com que o mapa e os elementos do mapa são mostrados e atualizados expresso em fotogramas por segundo (FPS). + Mostra a rapidez com que o mapa e os elementos do mapa são mostrados e atualizados, expressos em fotogramas por segundo (FPS). Simular a localização por GPX A simulação ignora os primeiros metros Velocidade da simulação @@ -5229,7 +5229,7 @@ RPM Watts Fechar o ecrã - Mapa do terreno (3D) + Mapa de terreno (3D) Relevo 3D Possua e observe o modelo do seu bairro ou de todo o continente. Temos de verificar a sua conta antes de a apagar. @@ -5340,4 +5340,218 @@ CAI %1$s disponível como parte do plano %2$s Incluído + Quer mesmo eliminar permanentemente todos os itens do lixo\? Esta ação não pode ser desfeita. + Aproximar + Nenhum trilho correspondente + Circunferência da roda + Abrir problema no GitHub + Sobre o OsmAnd + Permite usar um dispositivo de entrada externo com o OsmAnd + Mapas de terreno (3D) + Alterar orientação do mapa + Guia do utilizador + Essa pasta inteligente já existe + Roteamento em linha reta (aeronave) + Roteamento de comboio + Pasta de raiz + Roteamento de transporte público + Ficheiro de registo detalhado + Cache + Especifique o intervalo de tempo para cálculo da média do planar. + Perfil da aplicação anterior + Mostrar notificação do sistema sobre a tecla pressionada + Pesquisar coordenadas + Navegar por marcadores + Pontos no mapa + Todos os trilhos correspondentes aparecerão automaticamente aqui + Com pontos de rotas + Linhas + Mover para a esquerda + Configurar o filtro + Contém apenas informações sobre falhas + Introduzir coordenadas + Restaurar do lixo + Todas as pastas + Mapas vetoriais (estilos de mapa) + Menu principal + Mostra a memória disponível atribuída ao OsmAnd. + Pressione o botão no seu dispositivo para vinculá-lo à ação escolhida. + Contacte-nos + Rácio de planar para o alvo + Erro ao eliminar + Tamanho grande primeiro + Pasta inteligente guardada + Widgets de marcadores + Mover para a direita + Eliminar mapa + Oferta + Primeiros passos + Pesquisar POI + %s - %s, %s + Mapas padrão + Mostrar menos + Geral + Botão + Perfil da aplicação seguinte + Descarregue e instale a versão gratuita do OsmAnd + Altitude máxima + Avisos por voz / notificações + %s - %s + Pasta + Eliminar todos os itens + Alterar vinculação das teclas + Rácio médio de planar + Criado + Versões gratuitas + Faça perguntas, sugira funcionalidades + Tirar nota de mídia + Atividade de retorno pressionada + Discussão no GitHub + • Adicionada capacidade de alterar os atalhos de teclas para dispositivos de entrada externos +\n +\n• Adicionado widget \"Rácio de planar\" +\n +\n• Filtros adicionados e pastas inteligentes para trilhos +\n +\n• Linhas adicionadas aos painéis de widgets no topo e em baixo com suporte para todos os widgets +\n +\n• Adicionado suporte a ANT + widget de temperatura +\n +\n• Melhor gestão de memória para trilhos GPX grandes +\n +\n• Gestão de recursos locais atualizada em \"Descarregamentos\" +\n +\n• Adicionado widget \"RAM disponível\" +\n +\n• Problemas corrigidos com a barra de estado transparente +\n +\n + Trilhos e rotas + Parapente + Mais visto + Roteamento direto ao ponto (barco) + Ecrã do mapa durante a navegação + Transporte de bebé + Filtrar por nome + Emitir uma sugestão de navegação + Repor tudo + Quer mesmo remover o tipo \"%1$s\"\? + Não configurado + Guia + Ação + Perfis (configurações) + Roteamento de carro (camião, motocicleta) + Mapas e dados + Detalhes da rota + Os ficheiros removidos do OsmAnd Cloud estarão disponíveis aqui durante %1$s dias. + Preparação da rota + Adicionar novo tipo + Wikipédia e mapas de viagens + Mover para cima + Os widgets mostram o rácio de planar em relação ao alvo ou o rácio de planar médio para a viagem atual. + + %1$d (%2$d trilho) + %1$d (%2$d trilhos) + %1$d (%2$d trilhos) + + Roteamento a pé + %1$s : %2$s + Navegar por trilho + Roteamento online + Menu de contexto do mapa + Mostra o rácio de planar médio para o intervalo definido. + Adicionar pasta inteligente + Nome vazio + Editar filtro + Abrir vista de pesquisa + Copiar versão de compilação + CarPlay + Importar / exportar + Estilos de renderização + Filtrar: %d + Nome do país: A – Z + Régua radial e régua + \"%1$s\" será eliminado permanentemente. Tem a certeza\? +\n +\nEsta ação não pode ser desfeita. + Gravar viagem + Especificar o endereço web com a sintaxe de parâmetros lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. + Estilo de mapa náutico + Descartar alterações do filtro + Rácio de planar + Asa-delta + Afastar + Mostrar / ocultar menu lateral + Planear rota + Guardar como pasta inteligente + Botões do mapa + Mostra o rácio de planar necessário para atingir o ponto alvo. + Previsão meteorológica online + Menu de contexto de trilhos + Data da criação + A tecla \"%1$s\" já está atribuída a outra ação:: \"%2$s\" + Abrir vista de navegação + Esvaziar o lixo + Mostrar ícone + Estilo de mapa do OsmAnd + O mapa %1$s está atualizado. + Mostra a temperatura do sensor + Eliminar imediatamente + A carregar + Android Auto + Isto eliminará a pasta inteligente \"%1$s\". + %1$s foi eliminado. + Tamanho pequeno primeiro + Widgets informativos + %1$s é restaurado da Cloud. + Os itens no lixo serão eliminados após %1$s dias. + Aparelho externo de entrada + Roteamento de cavalo + Filtro + Sombras de relevo, declives + Nome do sensor + Quer mesmo repor todos os filtros\? + Atalhos de teclado + As pastas inteligentes permitem agrupar trilhos por filtros + RAM disponível + O lixo está vazio + Mover para minha localização + Roteamento de esqui + Não especificado + Widgets do mapa + Meus dados + Compras Android + Junte-se a uma das nossas salas de conversação local do Telegram. + Reportar problema + Conversação no Telegram + Planeador de rotas na internet + BRouter + Interações do mapa + Parâmetros de rota + Roteamento de ciclomotor + Mover para baixo + Mapas de terreno + Abrir grelha de dados WunderLINQ + Roteamento de barco + Lixo + A carregar novamente os trilhos + Eliminar item + Começar com o OsmAnd + Compras iOS + Rotas de bicicleta (MTB) + Widgets de navegação + Interagir com o mapa + Ações + Mapas rasterizados (online / offline) + Pesquisar tudo + Registos de falhas + Temperatura + Armazenamento + Nome do país: Z – A + Quer mesmo eliminar o mapa %1$s\? + Pesquisar todos os trilhos correspondentes + Estilo de mapa de esqui + Mapas e recursos + Sobre o roteamento do OsmAnd + Configuração \ No newline at end of file From a0bc506808ae904f0d83be1d1fba65204c62f01b Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 26 Oct 2023 20:19:04 +0000 Subject: [PATCH 64/96] Translated using Weblate (Swedish) Currently translated at 96.4% (4773 of 4948 strings) --- OsmAnd/res/values-sv/strings.xml | 69 +++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index 23c6741d869a..d6057a5092b5 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -4731,7 +4731,7 @@ Föredra obelagda vägar %1$s GB ledigt (av %2$s GB) Angivna %1$s, finns redan i OsmAnd. - Nuvarande poster kommer att ersättas med poster från filen + Nuvarande objekt kommer att ersättas med objekt från filen Online spårning Grad 4 App-standard (%s) @@ -4762,7 +4762,7 @@ Inkludera rutter enbart preparerade för skejtskidor/fristil, utan spår för klassisk stil. Horisontell precision: %s Snabbåtgärder - Importerade poster kommer att läggas till med ett prefix + Objekten kommer att importeras med ett prefix Mapp för lagring av inspelade spår %1$s GB använt Föredra obelagda vägar @@ -5211,4 +5211,69 @@ \nVälj %1$s så kan du få information och varningar om fartkameror. \n \nVälj %2$s så kommer all data om fartkameror raderas (varningar, objekt i kartan etc) tills OsmAnd ominstalleras helt. + Lägg till en ny anpassad kategori genom att välja en eller fler kategorier. + Åtgärdsknappen växlar mellan valda profiler. + Betalningen dras från ditt Google Play-konto när köpet bekräftas. +\n +\nDen förnyas automatiskt om du inte avbryter innan nästa vald förnyelseperiod. +\n +\nHantera eller avbryt dina prenumerationer när som helst från dina Google Play-inställningar. + Återställ förvald sortering + Ytterligare kartor behövs för att via Wikipedias intressepunkter på kartan. + Ange ett namn för onlinekartan. + Återgå till redigering + Att dölja inställningar återställer dem till deras ursprungliga tillstånd. + Stänger av skärmen enligt enhetens systeminställningar. + Har bara fyra knappar. + Lutningskartor använder färger för att visualisera hur brant terrängen är (lutningsgrad). + Huvudmeny-objekt, kontextmeny + Ytterligare kartor krävs för att visa terränglutning på kartan. + Anpassa mängden objekt i \'Huvudmenyn\', \'Konfigurera kartan\' och \'Kontextmeny\'. +\n +\nDeaktivera oanvända insticksmoduler för att dölja alla deras inställningar och reglage. %1$s. + Primära åtgärder + Importerade alla data från %1$s. Använd knapparna nedan för att öppna någon del av appen för att hantera den. + Åtgärden %1$s stöds inte + OsmAnd skannar %1$s för dubbletter med befintliga objekt i appen. +\n +\nDet kan ta lite tid. + Öppna dessa åtgärder genom att klicka på \"%1$s\"-knappen. + Välj hur nedladdade raster-rutor ska lagras. + Objekt nedanför denna punkt åtskiljs med en avgränsare. + Åtgärder i kontextmenyn + Förfallotid + OsmAnd har redan objekt med samma namn som några av de som importeras. +\n +\nVälj en åtgärd. + Rensa inspelad data + Flytta om eller dölj objekt från %1$s. + Alla profilinställningar återställs till ursprungliga förval vid profilens skapande eller import. + Läs mer om terränglutningskartor på %1$s. + Parkeringsplats-positioner + Påverkar kartvisningen olika om den används som huvudkarta eller över-/underläggskarta. +\n +\n%1$s: visning är begränsad helt till angivet zoomnivå-intervall. +\n +\n%2$s är nivåerna där kartan visas som original, men skalas upp/ner utanför angivna värden. + OsmAnd + Mapillary + Typen stöds inte + Några objekt finns redan + Ange minsta och maximala zoomnivån där lagrets ska visas. + Ange hur länge skärmen är på efter väckning. (\"%1$s\" innebär ingen tidsgräns.) + Förfallotid i minuter. Cachelagrade raster-rutor läses om efter angiven tid. Lämna tomt för att aldrig läsa om rutor för den här källan. +\n +\nEn dag är 1440 minuter. +\nEn vecka är 10 080 minuter. +\nEn månad är ca 43 800 minuter. + Välj en fil som stöds med filändelsen %1$s istället. + Exportera eller importera snabbåtgärder med app-profilerna. + %1$s / %2$s + %1$s av %2$s + Ta bort alla\? + Använd enhetens skärmavstängningstid + Huvudmeny + Hittade inte en sådan profil. + Denna insticksmodul är en separat app, deaktivering tar inte bort den. +\n +\nDen kan avinstalleras i Androids inställningar under \'Appar\'. \ No newline at end of file From 5c97c6317e81d754212867793a182925182c873e Mon Sep 17 00:00:00 2001 From: Evgenii Martynenko Date: Sat, 28 Oct 2023 10:03:54 +0000 Subject: [PATCH 65/96] Translated using Weblate (Russian) Currently translated at 96.9% (4800 of 4949 strings) --- OsmAnd/res/values-ru/strings.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index e3afbc9e2ff0..93a5b62e921c 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -5485,4 +5485,26 @@ Перезагрузка треков Искать все подходящие треки %1$s удалено. + Включите использование внешнего устройства ввода с OsmAnd. + Сменить ориентацию карты + Предыдущий профиль + Показывать всплывающее сообщение о нажатой клавише + Сдвиг влево + Нажмите кнопку на своем устройстве, чтобы связать ее с выбранным действием. + Сдвиг вправо + Кнопка + Следующий профиль + Изменить привязку клавиш + Вы уверены, что хотите удалить тип \"%1$s\"\? + Действие + Добавить новый тип + Сдвиг вверх + Экран поиска + Экран навигации + Внешнее устройство ввода + Привязки клавиш + Моё местоположение + Взаимодействие с картой + Сдвиг вниз + Действия \ No newline at end of file From 847066b1212f1b1c74e8bae6742b7bab6681626f Mon Sep 17 00:00:00 2001 From: "AndyRn.t.me" Date: Thu, 26 Oct 2023 17:19:08 +0000 Subject: [PATCH 66/96] Translated using Weblate (Italian) Currently translated at 99.5% (4927 of 4949 strings) --- OsmAnd/res/values-it/strings.xml | 33 +++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index bbe02aac244f..43b8cfd47418 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -5483,7 +5483,7 @@ Con punti intermedi Recupera dal cestino Elimina tutti gli elementi - I file rimossi dal OsmAnd Cloud saranno disponibili qui per altri %1$s giorni. + I file rimossi da OsmAnd Cloud saranno disponibili qui per altri %1$s giorni. %1$d (%2$d traccia) %1$d (%2$d tracce) @@ -5503,4 +5503,35 @@ Cestino Cancella oggetto Archiviazione + Ingrandisci + Abilita l\'uso del dispositivo di input esterno con OsmAnd + Cambia l\'orientamento della mappa + Cartella principale + Profilo dell\'applicazione precedente + Righe + Vai a sinistra + Tutte le cartelle + Premi il pulsante sul tuo dispositivo per associarlo all\'azione scelta. + Errore di cancellazione + Vai a destra + Mostra meno + Pulsante + Profilo dell\'applicazione successivo + Cartella + Cambia l\'associazione dei tasti + Prendi nota dei media + Sei sicuro di voler rimuovere \"%1$s\"\? + Azione + Aggiungi nuovo tipo + Vai su + Riduci + Mostra/nascondi il menu laterale + Il tasto \"%1$s\" è già assegnato a un\'altra azione: \"%2$s\" + Dispositivo di input esterno + Associazioni dei tasti + Vai alla mia posizione + Non specificato + Interazioni sulla mappa + Vai giù + Azioni \ No newline at end of file From bc8fdec3e129226c40328938360f1443afde3ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliaksandr=20Tru=C5=A1?= Date: Fri, 27 Oct 2023 07:47:40 +0000 Subject: [PATCH 67/96] Translated using Weblate (Belarusian) Currently translated at 88.7% (4394 of 4949 strings) --- OsmAnd/res/values-be/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 87897d3722df..0bafcf3189ac 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -5068,4 +5068,9 @@ \n– Датчык актываваны \n– Гэта прылада знаходзіцца побач з датчыкам ANT + Радкі + Кнопка + Дзеянне + Сметніца + Дзеянні \ No newline at end of file From e771ab77f990a181771d2bc433575503c24c298f Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 26 Oct 2023 18:02:42 +0000 Subject: [PATCH 68/96] Translated using Weblate (Portuguese (Brazil)) Currently translated at 98.7% (4887 of 4949 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index f44fec373ede..bfb8cbf0a0ee 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -5357,7 +5357,7 @@ Primeiros passos Pesquisar POI %s - %s, %s - Mapas padrões + Mapas padrão Geral Baixe e instale a versão gratuita do OsmAnd Altitude máxima @@ -5381,7 +5381,7 @@ Mapas e dados Detalhes da rota Preparação de rota - Wikipedia e mapas de viagens + Wikipédia e mapas de viagens Os widgets mostram a razão de planeio em relação ao alvo ou a razão de planeio média para a viagem atual. Roteamento de pedestres %1$s : %2$s @@ -5427,7 +5427,7 @@ Roteamento de ciclomotor O e-mail não corresponde ao nome de usuário de login Mapas de terreno - Rota de barco + Roteamento de barco Começando com OsmAnd Compras no iOS Rotas de bicicleta (MTB) @@ -5443,7 +5443,7 @@ Sobre o roteamento do OsmAnd Configuração Circunferência da roda - Abrir problema noGitHub + Abrir problema no GitHub Arquivo de registro detalhado Com pontos de trajeto Adicionar pasta inteligente From 8d9b8f07ac0b00ab49a21851dac965cba1b919b3 Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 26 Oct 2023 20:42:59 +0000 Subject: [PATCH 69/96] Translated using Weblate (Swedish) Currently translated at 96.3% (4468 of 4635 strings) --- OsmAnd/res/values-sv/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index c40848a0c037..fd5d6f243545 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -2732,7 +2732,7 @@ Gata Underjord Brandpoststil: wsh - Huvud + Primär Damm Vattendrag I tjänst: Ja From 444b1bc85340a76f9fca915a00b0fdbc70003304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=86Verdulo?= Date: Fri, 27 Oct 2023 21:51:59 +0000 Subject: [PATCH 70/96] Translated using Weblate (Esperanto) Currently translated at 100.0% (4949 of 4949 strings) --- OsmAnd/res/values-eo/strings.xml | 85 ++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 0bef71ade8e4..123538b85f20 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -5017,7 +5017,7 @@ kilogramoj jardoj Apliki ŝanĝojn - Ĉu ŝanĝi aspekton de %1$s spuroj\? + Ĉu ŝanĝi aspekton de %1$s spuro(j)\? Antaŭe vidigitaj %1$s Elektu spurojn por vidigi ilin sur la mapo. Neniu spuro sur la mapo @@ -5420,11 +5420,21 @@ Kopii version de kompilaĵo Ofte legataj Transporto de beboj - • nova fenestraĵo: glisrilato + • eblo ŝanĝi klav-asignojn por eksteraj enigaj aparatoj \n -\n• aldonis fenestraĵon ANT+: temperaturo +\n • nova fenestraĵo: Glisrilato \n -\n• pli bona mastrumado de memoro por grandaj GPX-spuroj +\n • filtriloj kaj inteligantaj dosierujoj por spuroj +\n +\n • aldonis vicojn por spura kaj malsupra paneloj de fenestraĵoj kun subteno por ĉiuj fenestraĵoj +\n +\n • aldonis fenestraĵon ANT+: temperaturo +\n +\n • pli bona mastrumado de memoro por grandaj GPX-spuroj +\n +\n • nova fenestraĵo: Disponebla RAM +\n +\n • riparitaj problemoj pri travideblaj stataj strioj \n \n Difini la retadreson uzante la jenajn argumentojn: latitudo={0}, longitudo={1}, tempomarko={2}, hdop(horizontala diluo de precizo)={3}, altitudo={4}, rapido={5}, direkto={6}, eta(alvena tempo)={7}, etfa(alvena tempo al intercelo)={8}, eda(distanco)={9}, edfa(distanco al intercelo)={10}. @@ -5465,4 +5475,71 @@ Butono Ago La klavo “%1$s” estas jam agordita por alia ago: “%2$s” + Ĉu vi certe volas por ĉiam forigi ĉiujn objektojn el la rubujo\? Tiu ĉi ago estas nemalfarebla. + Pligrandigi + Neniu kongrua spuro + Aktivigu por uzi eksterajn enigajn aparatojn kun OsmAnd + Ŝanĝi map-orientiĝon + Inteligenta dosierujo kun tiu ĉi nomo jam ekzistas + Ĉefdosierujo + Antaŭa aplikaĵa profilo + Ĉiuj kongruaj spuroj aŭtomate montriĝos tie ĉi + Movi maldekstren + Agordi filtrilon + Restarigi el rubujo + Ĉiuj dosierujoj + Inteligenta dosierujo konservita + Movi dekstren + Montri malpli + Sekva aplikaĵa profilo + Dosierujo + Forigi ĉiujn objektojn + Ŝanĝi klav-asignon + Fari aŭdvidan noton + Premi agon “malfari” + Montri navigan konsilon + Ĉu vi certe volas forigi la specon “%1$s”\? + Neagordita + Dosieroj forigitaj el OsmAnd-Nubo estos disponeblaj tie ĉi ankoraŭ dum %1$s tagoj. + Aldoni novan specon + Movi supren + + %1$d (%2$d spuro) + %1$d (%2$d spuroj) + + Nova inteligenta dosierujo + Malplena nomo + Redakti filtrilon + Malfermi vidon “serĉi” + “%1$s” estos forigita por ĉiam. Ĉui vi certas\? +\n +\nTiu ĉi ago estas neinversigebla. + Rezigni ŝanĝi filtrilon + Malgrandigi + Montri/kaŝi flankan menuon + Konservi kiel inteligentan dosierujon + Malfermi vidon “navigi” + Malplenigi rubujon + Montri emblemon + Forigi senprokraste + Ŝargado + Tio ĉi forigos la inteligentan dosierujon “%1$s”. + %1$s estas forigita. + %1$s estas restarigita al OsmAnd-Nubo. + Objektoj en la rubujo estos forigitaj post %1$s tagoj. + Ekstera eniga aparato + Ĉu vi certe volas reagordi ĉiujn filtrilojn\? + Klav-asignoj + Inteligentaj dosierujoj ebligas grupigi spurojn laŭ aplikitaj filtriloj + Rubujo estas malplena + Centrigi al mia pozicio + Neprecizigita + Mapaj agoj + Movi malsupren + Malfermi datum-menuon de WunderLINQ + Rubujo + Reŝargado de spuroj + Forigi objekton + Agoj + Serĉi ĉiujn kongruajn spurojn \ No newline at end of file From c594973ec221740aef720f199435dabeb15e3eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=86Verdulo?= Date: Sat, 28 Oct 2023 17:43:44 +0000 Subject: [PATCH 71/96] Translated using Weblate (Esperanto) Currently translated at 100.0% (4635 of 4635 strings) --- OsmAnd/res/values-eo/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index 251361cd185a..a88cc88ec528 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -4633,4 +4633,6 @@ infekt-malsan-scienco tipo E Biciklada kontrolpunkto + Vestejo + Kriokaza golfo \ No newline at end of file From 081a0af38daab1daaff01d4a07a1d178ff787be5 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 26 Oct 2023 19:32:48 +0000 Subject: [PATCH 72/96] Translated using Weblate (Irish) Currently translated at 41.8% (2071 of 4949 strings) --- OsmAnd/res/values-ga/strings.xml | 229 ++++++++++++++++++++++++++++++- 1 file changed, 225 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ga/strings.xml b/OsmAnd/res/values-ga/strings.xml index 5ef9a0d61466..3a1c847ea522 100644 --- a/OsmAnd/res/values-ga/strings.xml +++ b/OsmAnd/res/values-ga/strings.xml @@ -2,7 +2,7 @@ Mar réamhshocrú, úsáideann OsmAnd suiteáilte ó Google Play %1$s chun do shuíomh a fháil amach. \n -\nMá fhaigheann tú eolas suímh mhíchruinn nó tá tú ag úsáid gléas gan %2$s, bain triail as athrú go dtí \"%3$s\". +\nMá fhaigheann tú eolas suímh mhíchruinn nó tá tú ag úsáid gléas gan %2$s, bain triail as athrú go dtí \"%3$s\" Déanta Ar líne Cairde @@ -236,7 +236,7 @@ Folamh Áiteanna Teocht - bpm + buillí sa nóiméad Léargas Sonraí Leagan 2 (OpenGL) @@ -911,7 +911,7 @@ Gnáth Domhanleithead Foirgnimh - lbs + punt Taispeáin an treo ó thuaidh. Físeán An tSeapáin @@ -921,7 +921,7 @@ Méarchlár I gcónaí Taispeánann - Tuairiscigh fadhbanna + Tuairiscigh fadhb Comhráite ar Telegram Eile Cathaoir rothaí @@ -1876,4 +1876,225 @@ Na cathracha is gaire Stop an t-ionsamhlú Comhrianta doimhneachta + Sábháil agus stop an taifeadadh + Roghnaigh catagóir nó cruthaigh ceann nua + Zúmáil isteach + Scamall OsmAnd + Taispeánann sé an t-am faoi láthair mar atá sé ar do ghléas. + Léigh iomlán + Breosla úsáidte ag an inneall + Roghnaigh an cineál breosla d\'inneall d\'fheithicle, tá sé ag teastáil chun an astaíocht CO₂ a mheas. + Gléas nua / cuntas nua + Athraigh treo-uillinn na léarscáile + Déan cóip chúltaca mar chomhad + Rothaíocht leictreach + Taispeánann sé an t-achar idir lár an scáileáin go dtí d\'áit pháirceála. + Cuir isteach paraiméadar + Tá nuashonrú ar fáil + Pioc gníomh. + Tá fuaim níos fearr ar ghuth taifeadta a úsáid, ach níl sé in ann ach frásaí atá réamhthaifeadta a rá: ar nós treoracha casaidh. Ní féidir leis ainmneacha sráide nó áiteanna a rá. + Roghnaigh an teanga is fearr leat agus an cineál don ghuth-threorú. + Tá an seoladh r-phoist seo cláraithe cheana. + Tá cuntas agam cheana + Am teachta ag an gceann scríbe. + Seachtrach + Déan cóip chúltaca nó aischuir sonraí ó chomhad áitiúil. + Baineadh an t-alt + Treoirleabhair thaistil + Seachain áthanna + Roghnaigh aidhm na tiomána chun bealach níos giorra, níos tapa nó níos sábháilte a fháil + Roghnaigh na grúpaí a iompórtálfar. + Taispeáin íomhánna + An cúltaca deireanach + Roghnaigh na sonraí agus na fillteáin don chúltaca. + Taispeánann sé leibhéal chadhnra do ghléis. + Níl aon sonraí luais ag an gconair seo. + Ní bhfuair mé cód fíorúcháin + Earráid leis an bhfreastalaí: %1$s + Íocaíocht aonuaire + Garmhéid an chomhaid + Rónna + Bog ar chlé + Síntiús trí mhí + Ceadaigh sruthanna agus draenacha + Is fearr bealaí siúltóireachta + Rothaíocht sléibhe + %1$d as %2$d uaslódáilte + Cuardaigh tuilleadh… + Lean an nasc seo má tá aon fhadhb agat leis na ceannacháin. + Taispeáin an chonair ar an léarscáil + Cúltaca áitiúil + Bain na seanleaganacha + Aerárthach éadrom + Déan cóip chúltaca anois + Síntiús bliantúil + Taisce íomhá + Gach réigiún + An nuashonrú d\'OpenStreetMap is deireanaí atá ar fáil: + Níorbh fhéidir roinnt comhaid a uaslódáil don fhreastalaí mar tá leagan níos nuaí stóráilte air cheana féin. + Tá an t-ainm sin ann cheana + Deimhnigh an seoladh r-phoist + Taispeáin anaclann dúlra, ceantair chosanta agus páirceanna náisiúnta. + Brúigh ar an gcnaipe ar do ghléas chun é a nascadh leis an ngníomh a roghnaíodh. + %1$s %2$s %3$s + Seachain ceantair astaíochtaí ísle + Tharla earráid leis an scrios + Ailt leabharmharcáilte + Tosaigh ag cur in eagar + Sonraí an chúltaca + Anaclann dúlra + Scrios nuashonruithe + Bog ar dheis + Roghnaigh plean + Vicipéid as líne + %1$s * %2$s + Cnaipe + Caomhnófar leaganacha reatha do shonraí ar Scamall OsmAnd + Iompórtáil mar chonair amháin + Roghnaigh na sonraí le heaspórtáil sa chomhad. + Rothar sléibhe + An t-am i nóiméid nó uaire ag teastáil leis an gceann scríbe a shroich. + Fillteán + Uaslódáil críochnaithe + Síntiús míosúil + Astaíocht CO₂ + Cóipeáil seoladh + Tá tú ar tí gach sonraí a uaslódáladh chuig Scamall OsmAnd roimhe seo, stair na leaganacha san áireamh. +\n +\nNí féidir na sonraí scriosta a athshlánú. + Foireann OsmAnd + Athainmnigh conair + Tá na hathruithe OSM déanta go dtí %1$s san áireamh. + Níl ach %1$s saor ar do ghléas. Cuir spás ar fáil nó díroghnaigh roinnt mír atá le heaspórtáil. + Athnuaigh síntiús + Roghnaigh pictiúr + Aischuir ó chomhad + Treoirleabhair thaistil + Cuir grianghraf leis + Cruthaigh cuntas nua + An bhfuil tú cinnte gur mian leat an cineál \"%1$s\" a bhaint\? + Stair chuardaigh + Gníomh + Isilínte teochta + Úsáid an t-ainm laidine muna bhfuil sé ann + Scriosfar gach sonraí ar Scamall OsmAnd. Beidh na leaganacha áitiúla slán. + Treoirleabhar taistil + Tá, scrios gach ceann + Scrios treoirphointí + Seiceáiltear na nuashonruithe don léarscáil go seachtainiúil. + Íoslódáil an comhad + Níorbh fhéidir an t-íomhá a uaslódáil, triail arís é níos déanaí + Sábháil agus lean ar aghaidh + Cuir cineál nua leis + Bog suas + Próifíl an úsáideora + Roghnaigh an leagan. Chun an fhormáid a athrú, caithfidh tú an comhad a íoslódáil arís. + Cúltacaigh ⁊ Aischuir + Ar feitheamh + Cuir conair in eagar + An bhfuil cabhair uait\? Téigh i dteagmháil linn ag %1$s + Bris i ndiaidh + Seachain ceantair astaíochtaí ísle + Líne an bhealaigh + Wikivoyage as líne + Minicíocht an nuashonraithe + Taispeánann giuirléid don bharra ag an mbarr an t-achar go dtí an chéad mharcóir eile ar an léarscáil ó do shuíomh. Is féidir an ghiuirléid a shocrú chun marcóir amháin nó dhá mharcóir a thaispeáint. + Scrios mo shonraí ar fad + Roghnaigh cineál datha eile. + Zúmáil amach + Taispeáin/folaigh an taobh-roghchlár + Seiceáiltear na nuashonruithe don léarscáil gach uair. + Crios contúirteach + Úsáid teanga an chórais + Ar sos + Tá seans go dtógfaidh sé 10 nóiméad. Bain úsáid as an gcnaipe thíos muna bhfuil sé i d\'fhillteán turscair. + Rothar rásaíochta + Tá an eochair \"%1$s\" sannta go gníomh eile cheana: \"%2$s\" + Roghnaigh fillteán + Níor an seoladh r-phoist cláraithe do Scamall OsmAnd + Níl aon sonraí airde ag an gconair seo. + Íosairde + Seiceáil do nasc idirlín agus íoslódáil arís. + Tosaigh ag taifeadadh + Uimhir na slí amach + Seachain mótarbhealaí + Níl a dhóthain spáis ann + OsmAnd Beo + Bain úsáid as dev.openstreetmap.org + Taispeáin an fána + Cuir isteach do sheoladh r-phoist. Seolfar cód fíorúcháin chuige, +\nagus beidh do shonraí nasctha leis. + Caillfear gach sonraí nach bhfuil sábháilte. + Cuir le Mapillary + Seiceáiltear na nuashonruithe don léarscáil go laethúil. + Caithfear an aip a atosú chun socruithe áirithe a chur i bhfeidhm. + Taispeánann sé leagan amach na lánaí ar na bóithre agus aibhsíonn sé na cinn le tógáil agus tú ag taistil. + Cuir isteach an seoladh r-phoist a úsáid tú chun clárú. Seolfar pasfhocal aonuaire chuige. + Achar + Nuashonraigh gach léarscáil a cuireadh i %1$s\? + Logáil isteach ag úsáid an modh OAuth, nó le d\'ainm úsáideora OSM agus do phasfhocal. + Ag uaslódáil %1$d as %2$d + Uasairde + Íoslódáil íomhánna + Tástáil ríomh an bhealaigh + Má tá aon cheisteanna agat, téigh i dteagmháil linn ag %1$s. + Bris roimh + Úsáid an dath réamhshocraithe do stíl na léarscáile (%1$s). + Seachain áthanna + Ceadaigh sruthanna agus draenacha + Ceadaíonn fillteáin chliste na conairí a ghrúpáil de réir na scagairí a úsáidtear + Socruithe na gciorcal + Aip ar íocaíocht + URL an fhreastalaí + Tá tú ar tí stair na n-athruithe a bhí ann roimhe seo a scriosadh. +\n +\nSábhálfar leagan reatha na sonraí ar an bhfreastalaí, ach ní bheidh tú in ann filleadh ar na hathruithe a rinneadh roimhe seo. + Bog chuig mo shuíomh + Gan a bheith sonraithe + Ceadaigh rochtain phríobháideach (leoraí) + Uaslódáil an leagan áitiúil + Eochair an API + Tá a lán athruithe ar an ngléas seo, déan cóip chúltaca de na sonraí seo sa chaoi is nach gcaillfear iad. + Fógra nuair a sháraítear é + Cuireann OsmAnd sonraí na gcomhrianta ar fáil i méadair agus i dtroithe. Chun an fhormáid a athrú, caithfidh tú an comhad a íoslódáil arís. + Tá an chóip cúltaca críochnaithe + Íoslódáil leagan an fhreastalaí + Atosaigh an aip + Treoirleabhair thaistil + Amharc ar choinbhleachtaí + Cuir an cur síos in eagar + Roghnaigh fillteán nó cruthaigh ceann nua + Íoslódáil íomhánna + Nuashonraithe: %s + Mar pháirt den bhreiseán %1$s. + Breiseán ar íocaíocht + Ceannachán ionaipe + Cuir isteach pasfhocal aonuaire + Taispeántar imlíne na hairde agus na fána don conair reatha. + Bog síos + Leoraí beag + Oscail WunderLINQ Datagrid + Gnáthrothaíocht + Stop ag taifeadadh\? +\nCaillfear gach sonraí nach bhfuil sábháilte. + An chéad nuashonrú eile ar a %1$s. + Dáta an chéad bhilleála eile: %1$s + An chéad nuashonrú eile ar an %1$s ar %2$s. + Athraigh formáid na gcomhordanáidí ag %1$s – %2$s – %3$s. + Seoladh an cód fíorúcháin chuig %1$s. Cuir isteach é sa réimse thíos. + Stop gan sábháil + Cuir gach rud ar sos + Scrios %1$d comhad\? + Chun na sonraí %1$s a fháil, ceangail do chonair leis na bóithre nó ríomh é ar líne. + Folaigh an fána + Gníomhartha + Athraigh formáid na sonraí a úsáidtear ag: %1$s – %2$s – %3$s. + Curtha ar fáil ag %1$s + Dún an nóta OSM + Athraigh fillteán + Déan cóip chúltaca + Próifíl OsmAnd + Níl aon cheannacháin agat + Íoslódálacha gan teorainn + Uaslódáil go hOpenStreetMap \ No newline at end of file From 00511ccfbf7e42a21847b52e2c6a36e15e195156 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Sat, 28 Oct 2023 18:29:17 +0000 Subject: [PATCH 73/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4910 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index b9bd8d751563..5ad65d88fe5b 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5500,7 +5500,7 @@ %1$d (%2$d trasee) %1$d (%2$d de trasee) - Zoom interior + Mărire Afișează toastul despre tasta apăsată Rânduri Apăsați butonul de pe dispozitiv pentru a-l lega de acțiunea aleasă. From 688000b700ec2730e92447d8f937e3ea10881614 Mon Sep 17 00:00:00 2001 From: chumva Date: Sun, 29 Oct 2023 17:23:46 +0200 Subject: [PATCH 74/96] Cloud trash fixes --- OsmAnd/res/layout/card_trash_alert.xml | 45 ---------------- OsmAnd/res/layout/list_item_trash_item.xml | 1 + OsmAnd/res/values/strings.xml | 1 + .../net/osmand/plus/backup/BackupHelper.java | 10 ++-- .../plus/backup/ui/ConflictsTabFragment.java | 1 - .../backup/ui/trash/CloudTrashAdapter.java | 10 ++-- .../backup/ui/trash/CloudTrashController.java | 54 ++++++------------- .../backup/ui/trash/CloudTrashFragment.java | 28 ++++++++-- .../trash/CloudTrashItemMenuController.java | 23 ++++++-- .../ui/trash/viewholder/AlertViewHolder.java | 25 --------- .../ui/trash/viewholder/ItemViewHolder.java | 4 +- 11 files changed, 73 insertions(+), 129 deletions(-) delete mode 100644 OsmAnd/res/layout/card_trash_alert.xml delete mode 100644 OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/AlertViewHolder.java diff --git a/OsmAnd/res/layout/card_trash_alert.xml b/OsmAnd/res/layout/card_trash_alert.xml deleted file mode 100644 index 008f98508d66..000000000000 --- a/OsmAnd/res/layout/card_trash_alert.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/layout/list_item_trash_item.xml b/OsmAnd/res/layout/list_item_trash_item.xml index 7450e6133490..538c3bab8e48 100644 --- a/OsmAnd/res/layout/list_item_trash_item.xml +++ b/OsmAnd/res/layout/list_item_trash_item.xml @@ -24,6 +24,7 @@ android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding" + android:tint="?attr/secondary_icon_color" tools:srcCompat="@drawable/ic_map" /> + Download to device Deletion error Rows Show toast about pressed key diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java index 1db7e0a11f65..2daa25a92328 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java @@ -612,7 +612,7 @@ public boolean isInterrupted() { } public void deleteFiles(@NonNull List remoteFiles, boolean byVersion, - @Nullable OnDeleteFilesListener listener) throws UserNotRegisteredException { + @Nullable OnDeleteFilesListener listener) throws UserNotRegisteredException { checkRegistered(); executor.runCommand(new DeleteFilesCommand(this, remoteFiles, byVersion, listener)); } @@ -731,10 +731,12 @@ String downloadFile(@NonNull File file, @NonNull RemoteFile remoteFile, params.put("accessToken", getAccessToken()); params.put("name", fileName); params.put("type", type); - StringBuilder sb = new StringBuilder(DOWNLOAD_FILE_URL); + params.put("updatetime", String.valueOf(remoteFile.getUpdatetimems())); + + StringBuilder builder = new StringBuilder(DOWNLOAD_FILE_URL); boolean firstParam = true; for (Entry entry : params.entrySet()) { - sb.append(firstParam ? "?" : "&").append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")); + builder.append(firstParam ? "?" : "&").append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")); firstParam = false; } IProgress iProgress = new AbstractProgress() { @@ -780,7 +782,7 @@ public void finishTask() { } }; iProgress.startWork(remoteFile.getFilesize() / 1024); - error = AndroidNetworkUtils.downloadFile(sb.toString(), file, true, iProgress); + error = AndroidNetworkUtils.downloadFile(builder.toString(), file, true, iProgress); } catch (UnsupportedEncodingException e) { error = "UnsupportedEncodingException"; } diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/ConflictsTabFragment.java b/OsmAnd/src/net/osmand/plus/backup/ui/ConflictsTabFragment.java index 43c945e56be7..920b9fc21686 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/ConflictsTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/ConflictsTabFragment.java @@ -33,7 +33,6 @@ public List generateData() { BackupInfo info = backup.getBackupInfo(); if (info != null) { for (Pair pair : info.filteredFilesToMerge) { - String key = pair.first.getTypeFileName(); CloudChangeItem changeItem = createChangeItem(SYNC_OPERATION_NONE, pair.first, pair.second); if (changeItem != null) { // FIXME diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashAdapter.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashAdapter.java index ddd9e11e5061..d1d78edd55d0 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashAdapter.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashAdapter.java @@ -15,10 +15,9 @@ import net.osmand.plus.R; import net.osmand.plus.backup.SyncBackupTask.OnBackupSyncListener; import net.osmand.plus.backup.ui.status.StatusViewHolder; -import net.osmand.plus.backup.ui.trash.viewholder.AlertViewHolder; -import net.osmand.plus.backup.ui.trash.viewholder.ItemViewHolder; import net.osmand.plus.backup.ui.trash.viewholder.EmptyBannerViewHolder; import net.osmand.plus.backup.ui.trash.viewholder.HeaderViewHolder; +import net.osmand.plus.backup.ui.trash.viewholder.ItemViewHolder; import net.osmand.plus.settings.backend.backup.SettingsItemType; import net.osmand.plus.settings.backend.backup.items.SettingsItem; import net.osmand.plus.utils.UiUtilities; @@ -30,9 +29,8 @@ public class CloudTrashAdapter extends RecyclerView.Adapter implements OnBackupSyncListener { public static final int HEADER_TYPE = 1; - public static final int ALERT_CARD_TYPE = 2; - public static final int TRASH_ITEM_TYPE = 3; - public static final int EMPTY_BANNER_TYPE = 4; + public static final int TRASH_ITEM_TYPE = 2; + public static final int EMPTY_BANNER_TYPE = 3; private final List items = new ArrayList<>(); private final LayoutInflater themedInflater; @@ -57,8 +55,6 @@ public void setItems(@NonNull List items) { @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { switch (viewType) { - case ALERT_CARD_TYPE: - return new AlertViewHolder(themedInflater.inflate(R.layout.card_trash_alert, parent, false), controller); case BACKUP_STATUS_TYPE: return new StatusViewHolder(themedInflater.inflate(R.layout.backup_status_header, parent, false), nightMode); case HEADER_TYPE: diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashController.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashController.java index 6272a5a98bcd..4b8e265b5f7e 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashController.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashController.java @@ -19,6 +19,7 @@ import net.osmand.plus.backup.BackupListeners.OnDeleteFilesListener; import net.osmand.plus.backup.NetworkSettingsHelper; import net.osmand.plus.backup.PrepareBackupResult; +import net.osmand.plus.backup.PrepareBackupResult.RemoteFilesType; import net.osmand.plus.backup.RemoteFile; import net.osmand.plus.backup.UserNotRegisteredException; import net.osmand.plus.settings.bottomsheets.ConfirmationBottomSheet; @@ -30,7 +31,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -63,13 +63,10 @@ public Map collectTrashGroups() { List items = collectTrashItems(); if (!Algorithms.isEmpty(items)) { - Calendar calendar = Calendar.getInstance(); Collections.sort(items, (i1, i2) -> -Long.compare(i1.getTime(), i2.getTime())); for (TrashItem item : items) { - updateCalendarTime(calendar, item); - - long time = calendar.getTimeInMillis(); + long time = item.getTime(); String name = Algorithms.capitalizeFirstLetter(GROUP_DATE_FORMAT.format(time)); TrashGroup group = groups.get(name); @@ -83,15 +80,6 @@ public Map collectTrashGroups() { return groups; } - private void updateCalendarTime(@NonNull Calendar calendar, @NonNull TrashItem item) { - calendar.setTimeInMillis(item.getTime()); - calendar.set(Calendar.DAY_OF_MONTH, 0); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - } - @NonNull public List collectTrashItems() { List items = new ArrayList<>(); @@ -141,34 +129,26 @@ public void deleteItem(@NonNull TrashItem item) { } } + public void downloadItem(@NonNull TrashItem item) { + if (item.getSettingsItem() == null) { + log.error("Failed to download item: " + item.oldFile.getName() + ", SettingsItem is null"); + return; + } + RemoteFilesType type = item.isLocalDeletion() ? UNIQUE : OLD; + settingsHelper.syncSettingsItems(item.oldFile.getName(), null, item.oldFile, type, SYNC_OPERATION_DOWNLOAD); + } + public void restoreItem(@NonNull TrashItem item) { if (item.getSettingsItem() == null) { log.error("Failed to restore item: " + item.oldFile.getName() + ", SettingsItem is null"); return; } - if (item.isLocalDeletion()) { - settingsHelper.syncSettingsItems(item.oldFile.getName(), null, item.oldFile, UNIQUE, SYNC_OPERATION_DOWNLOAD); - } else { - try { - List files = Collections.singletonList(item.deletedFile); - backupHelper.deleteFiles(files, true, new TrashDeletionListener(null) { - @Override - public void onFilesDeleteDone(@NonNull Map errors) { - if (Algorithms.isEmpty(errors)) { - settingsHelper.syncSettingsItems(item.oldFile.getName(), null, item.oldFile, OLD, SYNC_OPERATION_DOWNLOAD); - } - if (!Algorithms.isEmpty(errors)) { - String message = AndroidUtils.formatWarnings(errors.values()).toString(); - app.showToastMessage(new BackupError(message).getLocalizedError(app)); - } else { - fragment.showSnackbar(app.getString(R.string.cloud_item_restored, item.getName(app))); - } - fragment.updateProgressVisibility(false); - } - }); - } catch (UserNotRegisteredException e) { - log.error(e); - } + try { + List files = Collections.singletonList(item.deletedFile); + String message = app.getString(R.string.cloud_item_restored, item.getName(app)); + backupHelper.deleteFiles(files, true, new TrashDeletionListener(message)); + } catch (UserNotRegisteredException e) { + log.error(e); } } diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashFragment.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashFragment.java index b79fb94a1a1d..8667e2854407 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashFragment.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashFragment.java @@ -1,7 +1,6 @@ package net.osmand.plus.backup.ui.trash; import static net.osmand.plus.backup.ui.ChangesAdapter.BACKUP_STATUS_TYPE; -import static net.osmand.plus.backup.ui.trash.CloudTrashAdapter.ALERT_CARD_TYPE; import static net.osmand.plus.backup.ui.trash.CloudTrashAdapter.EMPTY_BANNER_TYPE; import static net.osmand.plus.backup.ui.trash.CloudTrashController.CONFIRM_EMPTY_TRASH_ID; @@ -38,6 +37,9 @@ import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; import net.osmand.plus.utils.UiUtilities; +import net.osmand.plus.widgets.popup.PopUpMenu; +import net.osmand.plus.widgets.popup.PopUpMenuDisplayData; +import net.osmand.plus.widgets.popup.PopUpMenuItem; import net.osmand.util.Algorithms; import java.util.ArrayList; @@ -104,6 +106,28 @@ private void setupToolbar(@NonNull View view) { activity.onBackPressed(); } }); + ImageView actionButton = toolbar.findViewById(R.id.action_button); + actionButton.setOnClickListener(this::showOptionsMenu); + actionButton.setImageDrawable(getIcon(R.drawable.ic_overflow_menu_white)); + actionButton.setContentDescription(getString(R.string.shared_string_more)); + AndroidUiHelper.updateVisibility(actionButton, true); + } + + private void showOptionsMenu(@NonNull View view) { + List items = new ArrayList<>(); + + items.add(new PopUpMenuItem.Builder(view.getContext()) + .setTitleId(R.string.shared_string_empty_trash) + .setIcon(getContentIcon(R.drawable.ic_action_delete_outlined)) + .setOnClickListener(v -> controller.showClearConfirmationDialog()) + .create()); + + PopUpMenuDisplayData displayData = new PopUpMenuDisplayData(); + displayData.anchorView = view; + displayData.menuItems = items; + displayData.nightMode = nightMode; + displayData.layoutId = R.layout.simple_popup_menu_item; + PopUpMenu.show(displayData); } private void setupRecyclerView(@NonNull View view) { @@ -129,8 +153,6 @@ private void updateAdapter() { items.add(EMPTY_BANNER_TYPE); } } else { - items.add(ALERT_CARD_TYPE); - for (TrashGroup group : groups.values()) { items.add(group); items.addAll(group.getItems()); diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashItemMenuController.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashItemMenuController.java index 5a65dbc4df62..4f1983f977cd 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashItemMenuController.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/trash/CloudTrashItemMenuController.java @@ -30,8 +30,9 @@ public class CloudTrashItemMenuController extends BaseDialogController implement public static final String PROCESS_ID = "trash_item_options_menu"; - private static final int ACTION_RESTORE_ID = 0; - private static final int ACTION_DELETE_ID = 1; + private static final int ACTION_DELETE_ID = 0; + private static final int ACTION_RESTORE_ID = 1; + private static final int ACTION_DOWNLOAD_ID = 2; private final TrashItem item; private final CloudTrashController controller; @@ -66,11 +67,20 @@ public DisplayData getDisplayData(@NonNull String processId) { .setLayoutId(R.layout.bottom_sheet_item_with_descr_72dp) .setShowBottomDivider(true, 0)); + if (!item.isLocalDeletion()) { + displayData.addDisplayItem(new DisplayItem() + .setTitle(getString(R.string.restore_from_trash)) + .setLayoutId(R.layout.bottom_sheet_item_simple_56dp_padding_32dp) + .setIcon(uiUtilities.getIcon(R.drawable.ic_action_history, activeColorId)) + .setTag(ACTION_RESTORE_ID)); + } + displayData.addDisplayItem(new DisplayItem() - .setTitle(getString(R.string.restore_from_trash)) + .setTitle(getString(R.string.download_to_device)) .setLayoutId(R.layout.bottom_sheet_item_simple_56dp_padding_32dp) - .setIcon(uiUtilities.getIcon(R.drawable.ic_action_history, activeColorId)) - .setTag(ACTION_RESTORE_ID)); + .setIcon(uiUtilities.getIcon(R.drawable.ic_action_device_download, activeColorId)) + .setShowBottomDivider(true, app.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_divider_margin_start)) + .setTag(ACTION_DOWNLOAD_ID)); displayData.addDisplayItem(new DisplayItem() .setTitle(getString(R.string.shared_string_delete_immediately)) @@ -89,6 +99,9 @@ public void onDialogItemClicked(@NonNull String processId, @NonNull DisplayItem if (actionId == ACTION_RESTORE_ID) { controller.restoreItem(item); dismiss(); + } else if (actionId == ACTION_DOWNLOAD_ID) { + controller.downloadItem(item); + dismiss(); } else if (actionId == ACTION_DELETE_ID) { showDeleteConfirmationDialog(); } diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/AlertViewHolder.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/AlertViewHolder.java deleted file mode 100644 index 5cffc1d2f4ff..000000000000 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/AlertViewHolder.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.osmand.plus.backup.ui.trash.viewholder; - -import static net.osmand.plus.backup.ui.trash.CloudTrashController.DAYS_FOR_TRASH_CLEARING; - -import android.content.Context; -import android.view.View; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import net.osmand.plus.R; -import net.osmand.plus.backup.ui.trash.CloudTrashController; - -public class AlertViewHolder extends RecyclerView.ViewHolder { - - public AlertViewHolder(@NonNull View itemView, @NonNull CloudTrashController controller) { - super(itemView); - - Context context = itemView.getContext(); - TextView title = itemView.findViewById(R.id.title); - title.setText(context.getString(R.string.trash_alert_card_desc, String.valueOf(DAYS_FOR_TRASH_CLEARING))); - itemView.findViewById(R.id.action_button).setOnClickListener(v -> controller.showClearConfirmationDialog()); - } -} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/ItemViewHolder.java b/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/ItemViewHolder.java index eeab0152d7b7..3d2934a409c8 100644 --- a/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/ItemViewHolder.java +++ b/OsmAnd/src/net/osmand/plus/backup/ui/trash/viewholder/ItemViewHolder.java @@ -67,12 +67,12 @@ public void bindView(@NonNull TrashItem item, boolean lastItem, boolean hideDivi description.setText(item.getDescription(app)); int iconId = item.getIconId(); - icon.setImageDrawable(iconId != -1 ? uiUtilities.getThemedIcon(iconId) : null); + icon.setImageDrawable(iconId != -1 ? uiUtilities.getIcon(iconId) : null); setupProgress(item); itemView.setEnabled(!isSyncing(item)); itemView.setOnClickListener(v -> controller.showItemMenu(item)); - secondIcon.setImageDrawable(uiUtilities.getThemedIcon(R.drawable.ic_action_cloud_done)); + secondIcon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_cloud_done)); AndroidUiHelper.updateVisibility(secondIcon, item.synced); AndroidUiHelper.updateVisibility(cloudIcon, !item.isLocalDeletion()); From 7d3435d107aff423382c3946e183e848fdcc04ea Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 30 Oct 2023 09:29:31 +0200 Subject: [PATCH 75/96] Fix "Edit key binding" screen after 1st UI Review +add custom name for action --- .../res/layout/fragment_edit_key_action.xml | 42 +---- .../plus/keyevent/InputDeviceHelper.java | 16 +- .../keyevent/devices/InputDeviceProfile.java | 10 +- .../devices/PredefinedInputDeviceProfile.java | 2 +- .../fragments/EditKeyBindingFragment.java | 171 +++++++++++------- .../keybindings/KeyBindingsAdapter.java | 2 +- .../plus/keyevent/keybinding/KeyBinding.java | 32 +++- 7 files changed, 155 insertions(+), 120 deletions(-) diff --git a/OsmAnd/res/layout/fragment_edit_key_action.xml b/OsmAnd/res/layout/fragment_edit_key_action.xml index 2db3e5fe484c..5f189e5ad406 100644 --- a/OsmAnd/res/layout/fragment_edit_key_action.xml +++ b/OsmAnd/res/layout/fragment_edit_key_action.xml @@ -1,6 +1,7 @@ - - - - - + - - - - - - - - + osmand:titleMarginStart="0dp" + tools:title="My location"> diff --git a/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java b/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java index 536bae5d48e7..3bff5e4d3e1c 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/InputDeviceHelper.java @@ -14,6 +14,7 @@ import net.osmand.plus.keyevent.devices.WunderLINQDeviceProfile; import net.osmand.plus.keyevent.callbacks.EventType; import net.osmand.plus.keyevent.callbacks.InputDeviceHelperCallback; +import net.osmand.plus.keyevent.keybinding.KeyBinding; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -157,19 +158,18 @@ public void resetSelectedDeviceIfNeeded(@NonNull ApplicationMode appMode) { } } - public void updateKeyBinding(@NonNull String deviceId, - @NonNull String commandId, - int oldKeyCode, int newKeyCode) { + public void updateKeyBinding(@NonNull String deviceId, int originalKeyCode, + @NonNull KeyBinding newKeyBinding) { InputDeviceProfile device = getDeviceById(deviceId); if (device == null) { return; } - if (newKeyCode == KeyEvent.KEYCODE_UNKNOWN) { - device.removeKeyBinding(oldKeyCode); - } else if (oldKeyCode == KeyEvent.KEYCODE_UNKNOWN) { - device.addKeyBinding(newKeyCode, commandId); + if (newKeyBinding.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) { + device.removeKeyBinding(originalKeyCode); + } else if (originalKeyCode == KeyEvent.KEYCODE_UNKNOWN) { + device.addKeyBinding(newKeyBinding); } else { - device.updateKeyBinding(oldKeyCode, newKeyCode, commandId); + device.updateKeyBinding(originalKeyCode, newKeyBinding); } syncSettings(); } diff --git a/OsmAnd/src/net/osmand/plus/keyevent/devices/InputDeviceProfile.java b/OsmAnd/src/net/osmand/plus/keyevent/devices/InputDeviceProfile.java index 424762701970..0842f204122f 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/devices/InputDeviceProfile.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/devices/InputDeviceProfile.java @@ -55,20 +55,18 @@ public void removeKeyBinding(int keyCode) { syncKeyBindingsCache(); } - public void addKeyBinding(int keyCode, @NonNull String commandId) { - KeyBinding keyBinding = new KeyBinding(keyCode, commandId); + public void addKeyBinding(@NonNull KeyBinding keyBinding) { keyBindings = Algorithms.addToList(keyBindings, keyBinding); syncKeyBindingsCache(); } - public void updateKeyBinding(int oldKeyCode, int newKeyCode, @NonNull String commandId) { - KeyBinding oldKeyBinding = keyBindingsCache.remove(oldKeyCode); - KeyBinding newKeyBinding = new KeyBinding(newKeyCode, commandId); + public void updateKeyBinding(int originalKeyCode, @NonNull KeyBinding newKeyBinding) { + KeyBinding oldKeyBinding = keyBindingsCache.remove(originalKeyCode); if (oldKeyBinding != null) { int index = keyBindings.indexOf(oldKeyBinding); keyBindings = Algorithms.setInList(keyBindings, index, newKeyBinding); } else { - addKeyBinding(newKeyCode, commandId); + addKeyBinding(newKeyBinding); } syncKeyBindingsCache(); } diff --git a/OsmAnd/src/net/osmand/plus/keyevent/devices/PredefinedInputDeviceProfile.java b/OsmAnd/src/net/osmand/plus/keyevent/devices/PredefinedInputDeviceProfile.java index 466403d91263..cbb0ae8d33be 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/devices/PredefinedInputDeviceProfile.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/devices/PredefinedInputDeviceProfile.java @@ -27,7 +27,7 @@ public void requestBindCommand(int keyCode, @NonNull String commandId) { } public void bindCommand(int keyCode, @NonNull String commandId) { - KeyBinding keyBinding = new KeyBinding(keyCode, commandId); + KeyBinding keyBinding = new KeyBinding(keyCode, commandId, null); keyBindings.add(keyBinding); keyBindingsCache.put(keyCode, keyBinding); } diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java index 5c597716d3b4..60033f3eebd4 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/EditKeyBindingFragment.java @@ -2,15 +2,16 @@ import static net.osmand.plus.settings.fragments.BaseSettingsFragment.APP_MODE_KEY; import static net.osmand.plus.utils.AndroidUtils.setBackground; +import static net.osmand.plus.utils.ColorUtilities.getActiveColor; import static net.osmand.plus.utils.ColorUtilities.getPrimaryIconColor; import static net.osmand.plus.utils.UiUtilities.getColoredSelectableDrawable; import android.graphics.Typeface; import android.os.Bundle; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.EditText; import android.widget.TextView; import androidx.annotation.ColorInt; @@ -23,64 +24,50 @@ import com.google.android.material.appbar.AppBarLayout; +import net.osmand.CallbackWithObject; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.keyevent.InputDeviceHelper; -import net.osmand.plus.keyevent.keybinding.KeyBinding; import net.osmand.plus.keyevent.callbacks.OnKeyCodeSelectedCallback; +import net.osmand.plus.keyevent.keybinding.KeyBinding; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; -import net.osmand.plus.widgets.OsmandTextFieldBoxes; -import net.osmand.plus.widgets.dialogbutton.DialogButton; -import net.osmand.plus.widgets.dialogbutton.DialogButtonType; +import net.osmand.plus.widgets.alert.AlertDialogData; +import net.osmand.plus.widgets.alert.AlertDialogExtra; +import net.osmand.plus.widgets.alert.CustomAlert; +import net.osmand.util.Algorithms; -import java.util.Objects; +import org.json.JSONException; +import org.json.JSONObject; -import studio.carbonylgroup.textfieldboxes.ExtendedEditText; +import java.util.Objects; public class EditKeyBindingFragment extends BaseOsmAndFragment implements OnKeyCodeSelectedCallback { public static final String TAG = EditKeyBindingFragment.class.getSimpleName(); - private static final String ATTR_KEY_CODE = "attr_key_code"; - private static final String ATTR_COMMAND_ID = "attr_command_id"; private static final String ATTR_DEVICE_ID = "attr_device_id"; + private static final String ATTR_KEY_BINDING = "attr_keybinding"; private ApplicationMode appMode; private InputDeviceHelper deviceHelper; - private DialogButton applyButton; - private KeyBinding keyBinding; - private int initialKeyCode = KeyEvent.KEYCODE_UNKNOWN; - private String initialCommandId; private String deviceId; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); deviceHelper = app.getInputDeviceHelper(); - Bundle arguments = requireArguments(); - initialKeyCode = arguments.getInt(ATTR_KEY_CODE); - initialCommandId = arguments.getString(ATTR_COMMAND_ID); deviceId = arguments.getString(ATTR_DEVICE_ID); String appModeKey = arguments.getString(APP_MODE_KEY); appMode = ApplicationMode.valueOfStringKey(appModeKey, settings.getApplicationMode()); - - int keyCode; - String commandId; - if (savedInstanceState != null) { - keyCode = savedInstanceState.getInt(ATTR_KEY_CODE); - commandId = savedInstanceState.getString(ATTR_COMMAND_ID); - } else { - keyCode = initialKeyCode; - commandId = initialCommandId; - } - keyBinding = new KeyBinding(keyCode, commandId); + keyBinding = readKeyBinding(savedInstanceState); + keyBinding = keyBinding == null ? readKeyBinding(arguments) : keyBinding; } @Nullable @@ -94,14 +81,26 @@ public View onCreateView(@NonNull LayoutInflater inflater, setupToolbar(view); if (keyBinding != null) { - setupActionNameRow(view); - setupActionTypeRow(view); - setupActionKeyRow(view); - setupApplyButton(view); + updateViewContent(view); } return view; } + @Nullable + private KeyBinding readKeyBinding(@Nullable Bundle bundle) { + KeyBinding keyBinding = null; + if (bundle != null && bundle.containsKey(ATTR_KEY_BINDING)) { + String jsonStr = bundle.getString(ATTR_KEY_BINDING); + try { + JSONObject jsonObject = new JSONObject(jsonStr); + keyBinding = new KeyBinding(jsonObject); + } catch (JSONException e) { + // ignore + } + } + return keyBinding; + } + private void setupToolbar(@NonNull View view) { AppBarLayout appBar = view.findViewById(R.id.appbar); appBar.setExpanded(AndroidUiHelper.isOrientationPortrait(requireActivity())); @@ -116,10 +115,48 @@ private void setupToolbar(@NonNull View view) { } private void setupActionNameRow(@NonNull View view) { - OsmandTextFieldBoxes textBox = view.findViewById(R.id.text_box); - textBox.setEnabled(false); - ExtendedEditText editText = view.findViewById(R.id.edit_text); - editText.setText(keyBinding.getCommandTitle(app)); + View customNameButton = view.findViewById(R.id.custom_name_button); + TextView title = customNameButton.findViewById(R.id.title); + title.setText(R.string.shared_string_name); + + String actionName = keyBinding.getName(app); + TextView summary = customNameButton.findViewById(R.id.description); + summary.setText(actionName); + + customNameButton.setOnClickListener(v -> showEnterNameDialog(actionName, newName -> { + onNameEntered(newName); + return true; + })); + View backgroundView = customNameButton.findViewById(R.id.selectable_list_item); + setupSelectableBackground(backgroundView, appMode.getProfileColor(nightMode)); + } + + private void showEnterNameDialog(@Nullable String oldName, + @NonNull CallbackWithObject callback) { + FragmentActivity activity = getActivity(); + if (activity == null) { + return; + } + + AlertDialogData dialogData = new AlertDialogData(activity, nightMode) + .setTitle(getString(R.string.shared_string_name)) + .setControlsColor(getActiveColor(activity, nightMode)) + .setNegativeButton(R.string.shared_string_cancel, null); + + dialogData.setPositiveButton(R.string.shared_string_apply, (dialog, which) -> { + Object extra = dialogData.getExtra(AlertDialogExtra.EDIT_TEXT); + if (extra instanceof EditText) { + EditText editText = (EditText) extra; + String newName = editText.getText().toString(); + if (Algorithms.isBlank(newName)) { + app.showToastMessage(R.string.empty_name); + } else { + callback.processResult(newName.trim()); + } + } + }); + String caption = activity.getString(R.string.shared_string_name); + CustomAlert.showInput(dialogData, activity, oldName, caption); } private void setupActionTypeRow(@NonNull View view) { @@ -134,11 +171,12 @@ private void setupActionKeyRow(@NonNull View view) { View keyButton = view.findViewById(R.id.key_button); TextView title = keyButton.findViewById(R.id.title); title.setText(R.string.shared_string_button); + TextView summary = keyButton.findViewById(R.id.description); summary.setText(keyBinding.getKeySymbol()); + summary.setTextColor(getActiveColor(app, nightMode)); summary.setTypeface(summary.getTypeface(), Typeface.BOLD); - View backgroundView = keyButton.findViewById(R.id.selectable_list_item); - setupSelectableBackground(backgroundView, appMode.getProfileColor(nightMode)); + keyButton.setOnClickListener(v -> { FragmentActivity activity = getActivity(); if (activity != null) { @@ -147,47 +185,48 @@ private void setupActionKeyRow(@NonNull View view) { SelectKeyCodeFragment.showInstance(fm, thisFragment, appMode, deviceId, keyBinding); } }); + View backgroundView = keyButton.findViewById(R.id.selectable_list_item); + setupSelectableBackground(backgroundView, appMode.getProfileColor(nightMode)); AndroidUiHelper.updateVisibility(keyButton.findViewById(R.id.bottom_divider), false); } - private void setupApplyButton(@NonNull View view) { - applyButton = view.findViewById(R.id.dismiss_button); - applyButton.setOnClickListener(v -> { - int newKeyCode = keyBinding.getKeyCode(); - String commandId = keyBinding.getCommandId(); - deviceHelper.updateKeyBinding(deviceId, commandId, initialKeyCode, newKeyCode); - dismiss(); - }); - applyButton.setButtonType(DialogButtonType.PRIMARY); - applyButton.setTitleId(R.string.shared_string_save); - enableDisableApplyButton(); - } - - private void enableDisableApplyButton() { - applyButton.setEnabled(hasAnyChanges()); - } - - private boolean hasAnyChanges() { - return keyBinding != null - && (initialKeyCode != keyBinding.getKeyCode() - || !Objects.equals(initialCommandId, keyBinding.getCommandId())); + private void onNameEntered(@NonNull String newName) { + String originalName = keyBinding.getName(app); + if (!Objects.equals(originalName, newName)) { + keyBinding = new KeyBinding(newName, keyBinding); + deviceHelper.updateKeyBinding(deviceId, keyBinding.getKeyCode(), keyBinding); + View view = getView(); + if (view != null) { + updateViewContent(view); + } + } } @Override public void onKeyCodeSelected(int newKeyCode) { - View view = getView(); - keyBinding = new KeyBinding(newKeyCode, keyBinding.getCommandId()); - if (view != null) { - updateViewContent(view); + int originalKeyCode = keyBinding.getKeyCode(); + if (newKeyCode != originalKeyCode) { + keyBinding = new KeyBinding(newKeyCode, keyBinding); + deviceHelper.updateKeyBinding(deviceId, originalKeyCode, keyBinding); + View view = getView(); + if (view != null) { + updateViewContent(view); + } } } private void updateViewContent(@NonNull View view) { + updateToolbarTitle(view); setupActionNameRow(view); setupActionTypeRow(view); setupActionKeyRow(view); } + private void updateToolbarTitle(@NonNull View view) { + Toolbar toolbar = view.findViewById(R.id.toolbar); + toolbar.setTitle(keyBinding.getName(app)); + } + @Override public void onResume() { super.onResume(); @@ -210,8 +249,7 @@ public void onPause() { public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (keyBinding != null) { - outState.putInt(ATTR_KEY_CODE, keyBinding.getKeyCode()); - outState.putString(ATTR_COMMAND_ID, keyBinding.getCommandId()); + outState.putString(ATTR_KEY_BINDING, keyBinding.toJsonString()); } } @@ -244,10 +282,9 @@ public static void showInstance(@NonNull FragmentManager manager, if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { EditKeyBindingFragment fragment = new EditKeyBindingFragment(); Bundle arguments = new Bundle(); - arguments.putString(APP_MODE_KEY, appMode.getStringKey()); - arguments.putString(ATTR_COMMAND_ID, keyBinding.getCommandId()); arguments.putString(ATTR_DEVICE_ID, deviceId); - arguments.putInt(ATTR_KEY_CODE, keyBinding.getKeyCode()); + arguments.putString(APP_MODE_KEY, appMode.getStringKey()); + arguments.putString(ATTR_KEY_BINDING, keyBinding.toJsonString()); fragment.setArguments(arguments); manager.beginTransaction() .replace(R.id.fragmentContainer, fragment, TAG) diff --git a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsAdapter.java b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsAdapter.java index 9816f127e3a3..6e32c4d7ff1c 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/fragments/keybindings/KeyBindingsAdapter.java @@ -99,7 +99,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) { h.buttonView.setOnClickListener(isEditable()? v -> { controller.askEditKeyAction(keyBinding); }: null); - h.actionName.setText(keyBinding.getCommandTitle(app)); + h.actionName.setText(keyBinding.getName(app)); h.keyName.setText(keyBinding.getKeySymbol()); ScreenItem nextItem = position < screenItems.size() - 1 ? screenItems.get(position + 1) : null; diff --git a/OsmAnd/src/net/osmand/plus/keyevent/keybinding/KeyBinding.java b/OsmAnd/src/net/osmand/plus/keyevent/keybinding/KeyBinding.java index 3441b3a8ab54..05b3c9ff48bf 100644 --- a/OsmAnd/src/net/osmand/plus/keyevent/keybinding/KeyBinding.java +++ b/OsmAnd/src/net/osmand/plus/keyevent/keybinding/KeyBinding.java @@ -15,16 +15,34 @@ public class KeyBinding { private final int keyCode; private final String commandId; + private final String customName; private KeyEventCommand cachedCommand; - public KeyBinding(int keyCode, @NonNull String commandId) { + public KeyBinding(int keyCode, @NonNull KeyBinding keyBinding) { + this(keyCode, keyBinding.commandId, keyBinding.customName); + } + + public KeyBinding(@NonNull String customName, @NonNull KeyBinding keyBinding) { + this(keyBinding.keyCode, keyBinding.commandId, customName); + } + + public KeyBinding(int keyCode, @NonNull String commandId, @Nullable String customName) { this.keyCode = keyCode; this.commandId = commandId; + this.customName = customName; } public KeyBinding(@NonNull JSONObject jsonObject) throws JSONException { this.keyCode = jsonObject.getInt("keycode"); this.commandId = jsonObject.getString("commandId"); + this.customName = jsonObject.has("customName") + ? jsonObject.getString("customName") + : null; + } + + @Nullable + public String getName(@NonNull OsmandApplication context) { + return customName != null ? customName : getCommandTitle(context); } @Nullable @@ -55,11 +73,23 @@ public int getKeyCode() { return keyCode; } + @Nullable + public String toJsonString() { + try { + return toJson().toString(); + } catch (JSONException e) { + return null; + } + } + @NonNull public JSONObject toJson() throws JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("keycode", keyCode); jsonObject.put("commandId", commandId); + if (customName != null) { + jsonObject.put("customName", customName); + } return jsonObject; } } From 418c8676b30a671c727cae5573fd884bad984f53 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 30 Oct 2023 11:09:10 +0200 Subject: [PATCH 76/96] Fix review --- .../plus/views/mapwidgets/widgets/StreetNameWidget.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java index e433055a227e..695dd890a372 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/StreetNameWidget.java @@ -3,6 +3,8 @@ import static net.osmand.plus.render.OsmandRenderer.RenderingContext; import static net.osmand.plus.views.mapwidgets.WidgetType.STREET_NAME; +import static java.lang.Math.min; + import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; @@ -60,6 +62,7 @@ public class StreetNameWidget extends MapWidget { private static final int MAX_MARKER_DISTANCE = 50; + public static final int MAX_SHIELDS_QUANTITY = 3; private final WaypointHelper waypointHelper; private LocationPointWrapper lastPoint; @@ -218,7 +221,9 @@ private boolean setRoadShield(@NonNull List shields) { if (!Algorithms.isEmpty(shields)) { boolean isShieldSet = false; shieldImagesContainer.removeAllViews(); - for (RoadShield shield : shields) { + int maxShields = min(shields.size(), MAX_SHIELDS_QUANTITY); + for (int i = 0; i < maxShields; i++) { + RoadShield shield = shields.get(i); isShieldSet |= setShieldImage(shield); } return isShieldSet; From 985ddfe93816860c81a542c443b5e1a0379bc50c Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 27 Oct 2023 15:17:32 +0300 Subject: [PATCH 77/96] Fix review --- .../net/osmand/binary/RouteDataObject.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index bd0c1bcddd8d..53b9fd776c75 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -833,16 +833,14 @@ public boolean hasPrivateAccess(GeneralRouterProfile profile) { for (int type : types) { RouteTypeRule rule = region.quickGetEncodingRule(type); String tag = rule.getTag(); - boolean checkPrivate = false; - if ("vehicle".equals(tag) || "access".equals(tag)) { - checkPrivate = true; - } else if (profile == GeneralRouterProfile.CAR) { - checkPrivate = "motorcar".equals(tag) || "motor_vehicle".equals(tag); - } else if (profile == GeneralRouterProfile.BICYCLE) { - checkPrivate = "bicycle".equals(tag); - } - if (checkPrivate && rule.getValue().equals("private")) { - return true; + if (rule.getValue().equals("private")) { + if ("vehicle".equals(tag) || "access".equals(tag)) { + return true; + } else if (profile == GeneralRouterProfile.CAR) { + return "motorcar".equals(tag) || "motor_vehicle".equals(tag); + } else if (profile == GeneralRouterProfile.BICYCLE) { + return "bicycle".equals(tag); + } } } return false; From 3569685918d92c01e3ec2233f6bb666735c3e72d Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Mon, 30 Oct 2023 15:36:27 +0200 Subject: [PATCH 78/96] Add propagateToNodesPrefix --- .../src/main/java/net/osmand/osm/MapRenderingTypes.java | 9 +++++++++ 1 file changed, 9 insertions(+) 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 7b3f670d892b..bf88a6d04305 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapRenderingTypes.java @@ -296,6 +296,10 @@ protected MapRulType parseBaseRuleType(XmlPullParser parser, MapRulType parentCa rtype.propagateToNodes = MapRulType.PropagateToNodesType.CENTER; } } + String propagateToNodesPrefix = parser.getAttributeValue("", "propagateToNodesPrefix"); + if (propagateToNodesPrefix != null) { + rtype.propagateToNodesPrefix = propagateToNodesPrefix; + } String order = parser.getAttributeValue("", "order"); if(!Algorithms.isEmpty(order)) { @@ -547,6 +551,7 @@ public static class MapRulType { protected Map relationGroupNameTags; protected Map relationGroupAdditionalTags; protected PropagateToNodesType propagateToNodes = PropagateToNodesType.NONE; + protected String propagateToNodesPrefix; protected TagValuePattern tagValuePattern; protected boolean additional; @@ -740,6 +745,10 @@ public PropagateToNodesType getPropagateToNodesType() { return propagateToNodes; } + public String getPropagateToNodesPrefix() { + return propagateToNodesPrefix; + } + public enum PropagateToNodesType { NONE, ALL, From 4a57a40965beab71379fdd4c778ca8c2c3520e78 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 06:45:03 +0000 Subject: [PATCH 79/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4911 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 5ad65d88fe5b..ca84d8e928ee 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -1517,7 +1517,7 @@ Deschise acum OSM maper asistent Info A-GPS - Administrează + Administrare Editează Locații Căutare @@ -1792,7 +1792,7 @@ Mută tot la istoric Indicație distanță Păstrează afișarea pe hartă - Ieșiți fără să salvați\? + Ieșiți fără a salva\? Salvează ca puncte ale rutei Salvează ca linie Punct de rută @@ -2455,7 +2455,7 @@ excursie pe jos Conexiune traseu pentru skiori - Coborâș + Coborâre la Nord Tipul pistei Incepator @@ -4445,8 +4445,8 @@ Setați valoarea maximă acceptată pentru HDOP. \nPunctele cu o valoare mai mare vor fi ascunse. Distanță între puncte - Urcuș - Coborâș + Urcare + Coborâre Doar punctele traseului ce corespund intervalului setat vor apărea pe grafic și pe hartă, iar restul vor fi ascunse. Setați distanța minimă între puncte. \nPunctele care nu se află la cel puțin această distanță de ultimul punct vizibil vor fi ascunse. @@ -4617,7 +4617,7 @@ Transportul de materiale periculoase Permite accesul privat (camion) Evită autostrăzi - Coborâș + Coborâre Categorie materiale periculoase / Ține cont de permisiunile de acces pentru materiale periculoase Busolă pe cercuri Evită drumuri potrivite doar vehiculelor 4WD @@ -4667,7 +4667,7 @@ Permite accesul camioanelor în zonele private. Curbe izobare Evită autostrăzi - Urcuș + Urcare Puteți modifica formatul de date utilizat în: %1$s - %2$s - %3$s. Widgeturile de navigație sunt activate în timpul navigației pentru a afișa informații precum distanța, ora de sosire sau durata, următoarele viraje, direcția, numele străzii curente, informații despre benzi, viteza maximă, alerte de apropiere, puncte de interes, puncte intermediare. Arată configurația benzilor de circulație și le evidențiază pe cele ce trebuie urmate în timpul navigației. From 8e2a0f47c289dbbeeb4f74260c781062db62b0e4 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 12:53:16 +0000 Subject: [PATCH 80/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4911 of 4949 strings) --- OsmAnd/res/values-ro/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index ca84d8e928ee..c33b9f600644 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5518,4 +5518,5 @@ Harta interacțiunilor Deschideți WunderLINQ Datagrid Acțiuni + Mutarea la stânga \ No newline at end of file From f6c4a666fed7ae3a58e43e6e92c2aef8f9895eea Mon Sep 17 00:00:00 2001 From: avantdill Date: Mon, 30 Oct 2023 09:53:14 +0000 Subject: [PATCH 81/96] Translated using Weblate (Russian) Currently translated at 96.9% (4800 of 4949 strings) --- OsmAnd/res/values-ru/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 93a5b62e921c..1e7eb3ad8369 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -5507,4 +5507,8 @@ Взаимодействие с картой Сдвиг вниз Действия + Увеличить масштаб + Ошибка удаления + Уменьшить масштаб + Показать/скрыть боковое меню \ No newline at end of file From 750f4b3d8f33e7b4bf2ea96f7ca01434f0ef31b1 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 15:15:34 +0000 Subject: [PATCH 82/96] Translated using Weblate (Romanian) Currently translated at 99.2% (4914 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index c33b9f600644..cfdf77903a81 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5503,7 +5503,7 @@ Mărire Afișează toastul despre tasta apăsată Rânduri - Apăsați butonul de pe dispozitiv pentru a-l lega de acțiunea aleasă. + Apăsați butonul de pe dispozitiv pentru a-l lega cu acțiunea: %1$s Eroare de ștergere Mutați-vă la dreapta Buton @@ -5519,4 +5519,7 @@ Deschideți WunderLINQ Datagrid Acțiuni Mutarea la stânga + Mutați-vă în sus + Descărcați pe dispozitiv + Mutarea în jos \ No newline at end of file From 7120f535435926fdb0502426f6105301044d561f Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 17:00:02 +0000 Subject: [PATCH 83/96] Translated using Weblate (Romanian) Currently translated at 99.4% (4926 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 42 ++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index cfdf77903a81..2eeda9d9dfc7 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -847,7 +847,7 @@ Nu s-a putut efectua acțiunea {0}. Eroare de I/O în timpul efectuării acțiunii {0}. Informațiile despre POI nu a fost încărcate - Deschide + Deschis Comentarii Editare POI Toate celelalte etichete sunt păstrate @@ -1380,8 +1380,8 @@ Distanța: Timp: Rute echitație - Nici o adresă determinată - Apropiere + Nu s-a determinat adresa + Aproape de Ascunde Calitate slabă Calitate mare @@ -2868,7 +2868,7 @@ Gata Suprascrie traseu Salvează ca traseu nou - Inversează rută + Inversează ruta Tot traseul Segmentul următor Profil navigație @@ -3661,10 +3661,10 @@ Notifică numai atunci când se schimbă direcția spre punctul țintă. Anunț automat inteligent Fără recalcularea traseului în timp ce vă deplasați în direcția opusă. - Nici o recalculare a traseului pentru direcția opusă + Fără recalcularea traseului pentru direcția opusă Nu se recalculează traseul după ce se iese din traseu. Poziție relativă - Nici o recalculare a traseului după părăsirea acestuia + Fără recalcularea traseului după părăsirea acestuia Direcție magnetică Activați navigarea pentru modificările din OsmAnd Live. Indicați direcția punctului țintă prin vibrații. @@ -5503,23 +5503,29 @@ Mărire Afișează toastul despre tasta apăsată Rânduri - Apăsați butonul de pe dispozitiv pentru a-l lega cu acțiunea: %1$s + Apăsați butonul de pe dispozitiv pentru a-l asocia cu acțiunea: %1$s Eroare de ștergere - Mutați-vă la dreapta + Mută la dreapta Buton - Schimbarea legăturii cheilor - Luați notă de presă + Schimbă asocierea tastelor + Înregistrează notă media Activitate înapoi apăsat - Emiteți indicii de navigare + Emite indicii de navigare Acțiune - Zoom în afară - Afișați / ascundeți meniul lateral + Micșorează + Arată/ascunde meniul lateral Tasta \"%1$s\" este deja atribuită unei alte acțiuni: \"%2$s\" Harta interacțiunilor - Deschideți WunderLINQ Datagrid + Deschide WunderLINQ Datagrid Acțiuni - Mutarea la stânga - Mutați-vă în sus - Descărcați pe dispozitiv - Mutarea în jos + Mută la stânga + Mută în sus + Descarcă pe dispozitiv + Mută în jos + Schimbă orientare hartă + Profilul anterior de aplicație + Profilul următor de aplicație + Deschide fereastra Căutare + Deschide fereastra Navigație + Mută la \"Locația mea\" \ No newline at end of file From 36a5022c8f43ff916e6bce25c615663067813ec8 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 19:56:39 +0000 Subject: [PATCH 84/96] Translated using Weblate (Romanian) Currently translated at 99.4% (4926 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 2eeda9d9dfc7..f04ecca2eeee 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5528,4 +5528,13 @@ Deschide fereastra Căutare Deschide fereastra Navigație Mută la \"Locația mea\" + \"%1$s\" va fi șters definitiv. Sunteți sigur\? +\n +\nAceastă acțiune nu poate fi anulată. + %1$s este șters. + %1$s este restaurat în Cloud. + Dispozitiv de intrare extern + Legături de chei + Nespecificat + Ștergeți elementul \ No newline at end of file From 94f9511518c99286709138dd8a665b9775788da3 Mon Sep 17 00:00:00 2001 From: "AndyRn.t.me" Date: Mon, 30 Oct 2023 16:34:50 +0000 Subject: [PATCH 85/96] Translated using Weblate (Italian) Currently translated at 99.6% (4932 of 4951 strings) --- OsmAnd/res/values-it/strings.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 43b8cfd47418..c595d8da8e98 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -5413,7 +5413,9 @@ Righello radiale e righello Nome del sensore Mostra la temperatura dal sensore - • Aggiunto widget \"Rapporto di planata\". + • Aggiunta la possibilità di modificare le associazioni dei tasti per i dispositivi di input esterni +\n +\n• Aggiunto widget \"Rapporto di planata\". \n \n• Aggiunti filtri e cartelle intelligenti per le tracce \n @@ -5495,7 +5497,7 @@ \nQuesta azione non può essere cancellata. Specifica l\'indirizzo web con la sintassi parametrica: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}, eta={7}, etfa={8}, eda={9}, edfa={10}. Svuota il cestino - Cancella subito + Cancella immediatamente %1$s è cancellato. %1$s è ripristinato nel Cloud. Gli elementi nel cestino verranno eliminati dopo %1$s giorni. @@ -5511,7 +5513,7 @@ Righe Vai a sinistra Tutte le cartelle - Premi il pulsante sul tuo dispositivo per associarlo all\'azione scelta. + Premi il pulsante sul tuo dispositivo per associarlo all\'azione: %1$s Errore di cancellazione Vai a destra Mostra meno @@ -5534,4 +5536,8 @@ Interazioni sulla mappa Vai giù Azioni + Cambia il pulsante + Mostra la notifica sul tasto premuto + Dai un suggerimento di navigazione + Scarica sul dispositivo \ No newline at end of file From 7fccda6dbbd748315cf585c0b0e9af4d891d97b7 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 18:33:08 +0000 Subject: [PATCH 86/96] Translated using Weblate (Romanian) Currently translated at 99.9% (4632 of 4635 strings) --- OsmAnd/res/values-ro/phrases.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/values-ro/phrases.xml b/OsmAnd/res/values-ro/phrases.xml index ae7356ea5656..e64a6c67f1c3 100644 --- a/OsmAnd/res/values-ro/phrases.xml +++ b/OsmAnd/res/values-ro/phrases.xml @@ -149,7 +149,7 @@ Magazin de cafea Magazin de ciocolată Magazin de brânzeturi - Magazin de spirtoase + Magazine de spirtoase Brutărie Sit paleontologic Definit de utilizator @@ -160,12 +160,12 @@ Finanțe Artizanat Servicii - Cafenea și restaurant + Cafenele și restaurante Mâncare Club Timp liber Acces la internet - Cazare + Cazări Obiectiv turistic Turism Sport @@ -193,9 +193,9 @@ Obstacol rutier Transport Infrastructura de urgență - Urgență - Magazin de cartier și supermarket - Magazin + Urgențe + Magazine de cartier și supermarketuri + Magazine Adăpost Campare permanentă Autentificare nenecesară @@ -692,7 +692,7 @@ Aeronave istorice Piatră de hotar Câmpul de luptă - Situl arheologic + Sit arheologic Lucrări de artă Memorial Muzeu @@ -747,7 +747,7 @@ Intrare metrou Stație de cale ferată;Stație de tren;Stație de cale ferată;Stație de cale ferată;Stație de tren;Gară Platformă de cale ferată;Platformă de tren - Stație auto;Stație de cale ferată;Stație de tren + Stație de cale ferată;Stație de tren Stație de autobuz Stație de transport public Stație de tramvai @@ -828,7 +828,7 @@ Lopată antiincendiu Extinctor de incendiu Hidrant de incendiu - Telefon de urgență + Telefon de urgențe Stație de pompieri Poliție Produse religioase @@ -1393,7 +1393,7 @@ Cap Piatră remarcabilă Rapide - Flux + Pârâu Râu Cascadă Dolină @@ -2627,7 +2627,7 @@ Tip cabinet: telecom Tipul de cabinet: putere În serviciu: da - Flux + Pârâu Iaz Principal Stilul hidrantului: wsh From 7f26157f92a5fb21ec5932061f2ccdf6c6ba4fbe Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 19:58:11 +0000 Subject: [PATCH 87/96] Translated using Weblate (Romanian) Currently translated at 99.6% (4935 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index f04ecca2eeee..77234db16213 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5537,4 +5537,13 @@ Legături de chei Nespecificat Ștergeți elementul + Sunteți sigur că doriți să ștergeți definitiv toate elementele din Coșul de gunoi\? Această acțiune nu poate fi anulată. + Restaurare din coșul de gunoi + Ștergeți toate elementele + Fișierele eliminate din OsmAnd Cloud vor fi disponibile aici timp de %1$s zile după. + Goliți coșul de gunoi + Ștergeți imediat + Elementele din coșul de gunoi vor fi șterse după %1$s zile. + Coșul de gunoi este gol + Coș de gunoi \ No newline at end of file From cbbdd4f67236c349e4d17607615ea21b4813b99d Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 19:56:45 +0000 Subject: [PATCH 88/96] Translated using Weblate (Romanian) Currently translated at 99.6% (4935 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 77234db16213..f6b80189c000 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5534,7 +5534,7 @@ %1$s este șters. %1$s este restaurat în Cloud. Dispozitiv de intrare extern - Legături de chei + Asignări de taste Nespecificat Ștergeți elementul Sunteți sigur că doriți să ștergeți definitiv toate elementele din Coșul de gunoi\? Această acțiune nu poate fi anulată. From 4c88d3e52f766e19bacba40e585f39accdbdbc66 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 20:01:54 +0000 Subject: [PATCH 89/96] Translated using Weblate (Romanian) Currently translated at 99.7% (4939 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index f6b80189c000..0ea2e5512cc8 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5546,4 +5546,8 @@ Elementele din coșul de gunoi vor fi șterse după %1$s zile. Coșul de gunoi este gol Coș de gunoi + Folderul root + Toate folderele + Arată mai puțin + Folderul \ No newline at end of file From 4a74b10eb187ced8163dceb3f3f2446958529985 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 20:02:00 +0000 Subject: [PATCH 90/96] Translated using Weblate (Romanian) Currently translated at 99.7% (4939 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 0ea2e5512cc8..9c1cb6ec001c 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5539,9 +5539,9 @@ Ștergeți elementul Sunteți sigur că doriți să ștergeți definitiv toate elementele din Coșul de gunoi\? Această acțiune nu poate fi anulată. Restaurare din coșul de gunoi - Ștergeți toate elementele - Fișierele eliminate din OsmAnd Cloud vor fi disponibile aici timp de %1$s zile după. - Goliți coșul de gunoi + Șterge toate elementele + Fișierele eliminate din OsmAnd Cloud vor fi disponibile aici timp de %1$s zile. + Golește coșul de gunoi Ștergeți imediat Elementele din coșul de gunoi vor fi șterse după %1$s zile. Coșul de gunoi este gol From f2a6700be885f5a2e9ccdf24c8bdcfc901105f7a Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 20:05:03 +0000 Subject: [PATCH 91/96] Translated using Weblate (Romanian) Currently translated at 99.8% (4943 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 9c1cb6ec001c..64550bc55aff 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5532,22 +5532,22 @@ \n \nAceastă acțiune nu poate fi anulată. %1$s este șters. - %1$s este restaurat în Cloud. + %1$s s-a restaurat în Cloud. Dispozitiv de intrare extern Asignări de taste Nespecificat - Ștergeți elementul + Șterge elementul Sunteți sigur că doriți să ștergeți definitiv toate elementele din Coșul de gunoi\? Această acțiune nu poate fi anulată. Restaurare din coșul de gunoi Șterge toate elementele Fișierele eliminate din OsmAnd Cloud vor fi disponibile aici timp de %1$s zile. Golește coșul de gunoi - Ștergeți imediat + Șterge imediat Elementele din coșul de gunoi vor fi șterse după %1$s zile. Coșul de gunoi este gol Coș de gunoi Folderul root Toate folderele Arată mai puțin - Folderul + Folder \ No newline at end of file From be18e1862fd31f5f209c4c37a84f936bfef78ee3 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 20:31:51 +0000 Subject: [PATCH 92/96] Translated using Weblate (Romanian) Currently translated at 99.8% (4943 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 64550bc55aff..9b01c0bc58c2 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5353,21 +5353,23 @@ %1$s : %2$s Rata medie de planare Stil de hartă nautică - • Adăugat \"Glide Ratio\" widget + • A fost adăugată posibilitatea de a schimba legăturile de chei pentru dispozitivele de intrare externe \n -\n• Adăugat filtre și foldere inteligente pentru piese +\n • A fost adăugat widgetul \"Glide Ratio\" \n -\n• Adăugate rânduri pentru panourile widget de sus și de jos cu suport pentru toate widgeturile +\n • Au fost adăugate filtre și foldere inteligente pentru piese \n -\n• Adăugat suport pentru widgetul de temperatură ANT+ +\n • Au fost adăugate rânduri pentru panourile de widget-uri de sus și de jos, cu suport pentru toate widget-urile \n -\n• Gestionare îmbunătățită a memoriei pentru piesele GPX mari +\n • A adăugat suport pentru widget-ul de temperatură ANT+ \n -\n• Gestionare actualizată a resurselor locale în Descărcări +\n • Gestionarea îmbunătățită a memoriei pentru piesele GPX mari \n -\n• A fost adăugat widgetul \"RAM disponibil\" +\n • Gestionarea actualizată a resurselor locale în Descărcări \n -\n• Au fost rezolvate problemele legate de bara de stare transparentă +\n • A fost adăugat widget-ul \"RAM disponibil\" +\n +\n • Probleme rezolvate cu bara de stare transparentă \n \n Transportul bebelușilor @@ -5456,7 +5458,7 @@ Copiază versiunea build-ului Rigla pentru rază și Rigla Participă la una dintre discuțiile noastre locale prin Telegram. - Raportează o problemă + Raportează un issue Discuții pe Telegram Widgeturi de navigație Configurează From 92a166281fcdf4e1148ef54465cd2e1fe7d25e05 Mon Sep 17 00:00:00 2001 From: Simona Iacob Date: Mon, 30 Oct 2023 20:42:07 +0000 Subject: [PATCH 93/96] Translated using Weblate (Romanian) Currently translated at 99.8% (4946 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 9b01c0bc58c2..9aea0e0f6d5d 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -1946,7 +1946,7 @@ Apă Ascunde apa Oraș sau regiune - Încarcă punct de interes + Încărcați POI Calcularea rutei Adaugă mai multe… Notificări @@ -4476,7 +4476,7 @@ Iconuri la niveluri mici de zoom Afișare schematică a iconurilor la niveluri reduse de zoom Tuneluri navigabile - Nu ascunde tunelurile căilor navigabile + Nu ascundeți tunelurile de căi navigabile Etichete note Etichete Fixme OpenStreetMap From 90439aa4829310eeae24f18d459568c663b5fa19 Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 20:37:32 +0000 Subject: [PATCH 94/96] Translated using Weblate (Romanian) Currently translated at 99.8% (4946 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 9aea0e0f6d5d..3eec77d56108 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -5458,7 +5458,7 @@ Copiază versiunea build-ului Rigla pentru rază și Rigla Participă la una dintre discuțiile noastre locale prin Telegram. - Raportează un issue + Raportează o problemă Discuții pe Telegram Widgeturi de navigație Configurează From 2eab9a60e5f06ffc19e1fb1c92c7a5382d5a392f Mon Sep 17 00:00:00 2001 From: Cosmin Date: Mon, 30 Oct 2023 20:59:55 +0000 Subject: [PATCH 95/96] Translated using Weblate (Romanian) Currently translated at 99.8% (4946 of 4951 strings) --- OsmAnd/res/values-ro/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ro/strings.xml b/OsmAnd/res/values-ro/strings.xml index 3eec77d56108..44b0db6e5ac4 100644 --- a/OsmAnd/res/values-ro/strings.xml +++ b/OsmAnd/res/values-ro/strings.xml @@ -1946,7 +1946,7 @@ Apă Ascunde apa Oraș sau regiune - Încărcați POI + Încărcă punct de interes Calcularea rutei Adaugă mai multe… Notificări @@ -4476,7 +4476,7 @@ Iconuri la niveluri mici de zoom Afișare schematică a iconurilor la niveluri reduse de zoom Tuneluri navigabile - Nu ascundeți tunelurile de căi navigabile + Nu ascunde tunelurile căilor navigabile Etichete note Etichete Fixme OpenStreetMap From cbf715ad5cff2a37edcf88bc52af2fbc0ee98546 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 31 Oct 2023 03:40:27 +0000 Subject: [PATCH 96/96] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (4951 of 4951 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 17e10cb84705..27f393d304a2 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -5514,7 +5514,7 @@ 上一個應用程式設定檔 顯示關於按下鍵的浮動式訊息 向左移動 - 在您的裝置上按下按鈕以將其與選定的動作連結。 + 在您的裝置上按下按鈕以將其連結至動作:%1$s 向右移動 按鈕 下一個應用程式設定檔 @@ -5539,4 +5539,6 @@ 開啟 WunderLINQ Datagrid 動作 刪除錯誤 + 變更按鈕 + 下載到裝置 \ No newline at end of file