From 4aa877f7f65b2b28566c7d5476466dceb992e3c6 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 29 Jan 2021 10:50:05 +0200 Subject: [PATCH 001/398] Travel - vehicle mode --- .../main/java/net/osmand/data/Amenity.java | 20 ++++ .../main/java/net/osmand/osm/MapPoiTypes.java | 8 +- .../res/layout/wikivoyage_travel_gpx_card.xml | 92 ++++++++++++++----- .../plus/wikivoyage/data/TravelGpx.java | 2 + .../plus/wikivoyage/data/TravelObfHelper.java | 2 + .../explore/travelcards/TravelGpxCard.java | 16 +++- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java index 861a7c9b93..48e15df815 100644 --- a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java +++ b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java @@ -179,6 +179,26 @@ public class Amenity extends MapObject { } } + public void addProfileTag(Entry e) { + if (getAdditionalInfo("profile") == null) { + if (e.getKey().startsWith("tag_")) { + switch (e.getValue().trim()) { + case "bicycle": + case "cycling": + case "mtb": + setAdditionalInfo("profile", "bicycle"); + break; + case "hiking": + case "hike": + case "walking": + case "walk": + setAdditionalInfo("profile", "pedestrian"); + break; + } + } + } + } + @Override public String toStringEn() { return super.toStringEn() + ": " + type.getKeyName() + ":" + subType; diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java index e273fa4e7f..70d35e24ae 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java @@ -915,14 +915,18 @@ public class MapPoiTypes { if (!otag.equals(tag) && !otag.equals("name")) { PoiType pat = poiTypesByTag.get(otag + "/" + e.getValue()); if (pat == null) { - for(String splValue : e.getValue().split(";")) { + for (String splValue : e.getValue().split(";")) { PoiType ps = poiTypesByTag.get(otag + "/" + splValue.trim()); - if(ps != null) { + if (ps != null) { a.setAdditionalInfo(ps.getKeyName(), splValue.trim()); } } pat = poiTypesByTag.get(otag); + if (pat == null && otag.startsWith("tag_")) { + a.addProfileTag(e); + } } + if (pat != null && pat.isAdditional()) { a.setAdditionalInfo(pat.getKeyName(), e.getValue()); } diff --git a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml index 44077a0dcd..2e11585264 100644 --- a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml +++ b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml @@ -139,31 +139,82 @@ - + android:background="?attr/btn_border_bg" + android:layout_marginLeft="@dimen/content_padding_half" + android:layout_marginStart="@dimen/content_padding_half"> + + + + + + + + + + + + @@ -172,7 +223,6 @@ diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java index 185fdc922c..91d404510d 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelGpx.java @@ -6,8 +6,10 @@ public class TravelGpx extends TravelArticle { public static final String DIFF_ELE_UP = "diff_ele_up"; public static final String DIFF_ELE_DOWN = "diff_ele_down"; public static final String USER = "user"; + public static final String PROFILE = "profile"; public String user; + public String profile; public float totalDistance = 0; public double diffElevationUp = 0; public double diffElevationDown = 0; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index f230929f1d..8622ed0996 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -58,6 +58,7 @@ import static net.osmand.plus.helpers.GpxUiHelper.getGpxTitle; import static net.osmand.plus.wikivoyage.data.TravelGpx.DIFF_ELE_DOWN; import static net.osmand.plus.wikivoyage.data.TravelGpx.DIFF_ELE_UP; import static net.osmand.plus.wikivoyage.data.TravelGpx.DISTANCE; +import static net.osmand.plus.wikivoyage.data.TravelGpx.PROFILE; import static net.osmand.plus.wikivoyage.data.TravelGpx.USER; import static net.osmand.util.Algorithms.capitalizeFirstLetter; @@ -203,6 +204,7 @@ public class TravelObfHelper implements TravelHelper { LOG.debug(e.getMessage(), e); } res.user = Algorithms.emptyIfNull(amenity.getTagContent(USER)); + res.profile = Algorithms.emptyIfNull(amenity.getTagContent(PROFILE)); articles.put("en", res); return articles; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 1bc2409621..efd81315d3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -2,16 +2,17 @@ package net.osmand.plus.wikivoyage.explore.travelcards; import android.graphics.drawable.Drawable; import android.view.View; +import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; -import net.osmand.AndroidUtils; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.profiles.ProfileIcons; import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; @@ -40,10 +41,11 @@ public class TravelGpxCard extends BaseTravelCard { if (viewHolder instanceof TravelGpxVH) { final TravelGpxVH holder = (TravelGpxVH) viewHolder; holder.title.setText(article.getTitle()); - Drawable icon = getActiveIcon(R.drawable.ic_action_user_account_16); - holder.user.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); + holder.userIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_user_account_16)); holder.user.setText(article.user); - AndroidUtils.setBackground(app, holder.user, nightMode, R.drawable.btn_border_bg_light, R.drawable.btn_border_bg_dark); + ProfileIcons profileRes = ProfileIcons.valueOf(article.profile.toUpperCase()); + holder.profileIcon.setImageDrawable(getActiveIcon(profileRes.getResId())); + holder.profile.setText(profileRes.getTitleId()); holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); holder.diffElevationDown.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationDown, app)); @@ -92,6 +94,9 @@ public class TravelGpxCard extends BaseTravelCard { public final TextView title; public final TextView user; + public final ImageView userIcon; + public final TextView profile; + public final ImageView profileIcon; public final TextView distance; public final TextView diffElevationUp; public final TextView diffElevationDown; @@ -104,6 +109,9 @@ public class TravelGpxCard extends BaseTravelCard { super(itemView); title = itemView.findViewById(R.id.title); user = itemView.findViewById(R.id.user_name); + userIcon = itemView.findViewById(R.id.user_icon); + profile = itemView.findViewById(R.id.profile); + profileIcon = itemView.findViewById(R.id.profile_icon); distance = itemView.findViewById(R.id.distance); diffElevationUp = itemView.findViewById(R.id.diff_ele_up); diffElevationDown = itemView.findViewById(R.id.diff_ele_down); From 30c5fda90ab673fbf7d5540cc609e71138f0ed9f Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 29 Jan 2021 11:45:54 +0200 Subject: [PATCH 002/398] Fix UI --- .../res/layout/wikivoyage_travel_gpx_card.xml | 1 + .../explore/SavedArticlesRvAdapter.java | 26 ++++++++++++------- .../explore/travelcards/TravelGpxCard.java | 12 ++++++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml index 2e11585264..b3aaf7e849 100644 --- a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml +++ b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml @@ -184,6 +184,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="?attr/btn_border_bg" + android:visibility="gone" android:layout_marginLeft="@dimen/content_padding_half" android:layout_marginStart="@dimen/content_padding_half"> diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index a01de6e6cb..7d1531d5e0 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -18,12 +18,12 @@ import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; import com.squareup.picasso.RequestCreator; -import net.osmand.AndroidUtils; import net.osmand.PicassoUtils; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.profiles.ProfileIcons; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.tools.CropCircleTransformation; import net.osmand.plus.wikipedia.WikiArticleHelper; @@ -31,11 +31,13 @@ import net.osmand.plus.wikivoyage.WikivoyageUtils; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; -import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; +import net.osmand.util.Algorithms; import java.util.ArrayList; import java.util.List; +import static net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.*; + public class SavedArticlesRvAdapter extends RecyclerView.Adapter { private static final int HEADER_TYPE = 0; @@ -81,7 +83,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Fri, 29 Jan 2021 13:40:01 +0200 Subject: [PATCH 003/398] refactoring --- .../main/java/net/osmand/data/Amenity.java | 20 ------- .../main/java/net/osmand/osm/MapPoiTypes.java | 4 -- .../net/osmand/osm/edit/EntityParser.java | 56 +++++++++++++------ 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java index 48e15df815..861a7c9b93 100644 --- a/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java +++ b/OsmAnd-java/src/main/java/net/osmand/data/Amenity.java @@ -179,26 +179,6 @@ public class Amenity extends MapObject { } } - public void addProfileTag(Entry e) { - if (getAdditionalInfo("profile") == null) { - if (e.getKey().startsWith("tag_")) { - switch (e.getValue().trim()) { - case "bicycle": - case "cycling": - case "mtb": - setAdditionalInfo("profile", "bicycle"); - break; - case "hiking": - case "hike": - case "walking": - case "walk": - setAdditionalInfo("profile", "pedestrian"); - break; - } - } - } - } - @Override public String toStringEn() { return super.toStringEn() + ": " + type.getKeyName() + ":" + subType; diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java index 70d35e24ae..77507de50c 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java @@ -922,11 +922,7 @@ public class MapPoiTypes { } } pat = poiTypesByTag.get(otag); - if (pat == null && otag.startsWith("tag_")) { - a.addProfileTag(e); } - } - if (pat != null && pat.isAdditional()) { a.setAdditionalInfo(pat.getKeyName(), e.getValue()); } diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java index 9caa54b55c..9fb55fd64d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java @@ -21,7 +21,7 @@ import net.osmand.osm.edit.Relation.RelationMember; import net.osmand.util.Algorithms; public class EntityParser { - + public static void parseMapObject(MapObject mo, Entity e, Map tags) { mo.setId(e.getId()); if(mo instanceof Amenity) { @@ -123,7 +123,7 @@ public class EntityParser { mo.setName(ref); } } - + private static void setNameFromBrand(MapObject mo, Map tags) { String ref = tags.get(OSMTagKey.BRAND.getValue()); if(ref != null){ @@ -140,7 +140,7 @@ public class EntityParser { op += " [" + ref + "]"; mo.setName(op); } - + private static String getWebSiteURL(Map tagValues, boolean checkWikipedia) { String siteUrl = null; @@ -170,14 +170,14 @@ public class EntityParser { } return siteUrl; } - - + + public static List parseAmenities(MapPoiTypes poiTypes, Entity entity, Map tags, List amenitiesList) { amenitiesList.clear(); // it could be collection of amenities boolean relation = entity instanceof Relation; - boolean purerelation = relation && + boolean purerelation = relation && !("multipolygon".equals(tags.get("type")) || "boundary".equals(tags.get("type"))); Collection> it = MapRenderingTypes.splitTagsIntoDifferentObjects(tags); for (Map ts : it) { @@ -193,6 +193,10 @@ public class EntityParser { if (wbs != null) { am.setAdditionalInfo("wikipedia", wbs); } + String tagCategory = getTagCategory(entity); + if (tagCategory != null) { + am.setAdditionalInfo("profile", tagCategory); + } if (checkAmenitiesToAdd(am, amenitiesList) && !"no".equals(am.getSubType())) { amenitiesList.add(am); } @@ -201,9 +205,27 @@ public class EntityParser { } return amenitiesList; } - - - + + private static String getTagCategory(Entity e) { + Map tags = e.getTags(); + for (String key : tags.keySet()) { + if (key.startsWith("tag_")) { + switch (tags.get(key).trim()) { + case "bicycle": + case "cycling": + case "mtb": + return "bicycle"; + case "hiking": + case "hike": + case "walking": + case "walk": + return "pedestrian"; + } + } + } + return null; + } + private static boolean checkAmenitiesToAdd(Amenity a, List amenitiesList){ // check amenity for duplication for(Amenity b : amenitiesList){ @@ -212,9 +234,9 @@ public class EntityParser { } } return true; - + } - + public static Building parseBuilding(Entity e){ Building b = new Building(); parseMapObject(b, e, e.getTags()); @@ -228,7 +250,7 @@ public class EntityParser { List nodes = ((Way) e).getNodes(); for(int i = 0; i < nodes.size(); i++) { Node node = nodes.get(i); - if(node != null && "yes".equals(node.getTag(OSMTagKey.ENTRANCE)) && + if(node != null && "yes".equals(node.getTag(OSMTagKey.ENTRANCE)) && !Algorithms.isEmpty(node.getTag(OSMTagKey.REF))) { b.addEntrance(node.getTag(OSMTagKey.REF), node.getLatLon()); } @@ -236,11 +258,11 @@ public class EntityParser { } return b; } - + public static City parseCity(Node el) { return parseCity(el, CityType.valueFromString(el.getTag(OSMTagKey.PLACE.getValue()))); } - + public static City parseCity(Entity el, CityType t) { if(t == null) { return null; @@ -252,15 +274,15 @@ public class EntityParser { c.setIsin(isin); return c; } - - + + public static TransportRoute parserRoute(Relation r, String ref){ TransportRoute rt = new TransportRoute(); parseMapObject(rt, r, r.getTags()); rt.setRef(ref); return rt; } - + public static TransportStop parseTransportStop(Entity e){ TransportStop st = new TransportStop(); parseMapObject(st, e, e.getTags()); From 2ae5bb6301d52328a1e4eb42a127ebaafbd083dd Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 29 Jan 2021 13:45:09 +0200 Subject: [PATCH 004/398] refactoring --- OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java index 77507de50c..e273fa4e7f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/MapPoiTypes.java @@ -915,14 +915,14 @@ public class MapPoiTypes { if (!otag.equals(tag) && !otag.equals("name")) { PoiType pat = poiTypesByTag.get(otag + "/" + e.getValue()); if (pat == null) { - for (String splValue : e.getValue().split(";")) { + for(String splValue : e.getValue().split(";")) { PoiType ps = poiTypesByTag.get(otag + "/" + splValue.trim()); - if (ps != null) { + if(ps != null) { a.setAdditionalInfo(ps.getKeyName(), splValue.trim()); } } pat = poiTypesByTag.get(otag); - } + } if (pat != null && pat.isAdditional()) { a.setAdditionalInfo(pat.getKeyName(), e.getValue()); } From e150d39c61fe9597c8ecac4dee2611b8ae76f353 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 29 Jan 2021 13:56:10 +0200 Subject: [PATCH 005/398] rename --- .../src/main/java/net/osmand/osm/edit/EntityParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java index 9fb55fd64d..e21927477a 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java @@ -193,9 +193,9 @@ public class EntityParser { if (wbs != null) { am.setAdditionalInfo("wikipedia", wbs); } - String tagCategory = getTagCategory(entity); - if (tagCategory != null) { - am.setAdditionalInfo("profile", tagCategory); + String profileName = getProfileName(entity); + if (profileName != null) { + am.setAdditionalInfo("profile", profileName); } if (checkAmenitiesToAdd(am, amenitiesList) && !"no".equals(am.getSubType())) { amenitiesList.add(am); @@ -206,7 +206,7 @@ public class EntityParser { return amenitiesList; } - private static String getTagCategory(Entity e) { + private static String getProfileName(Entity e) { Map tags = e.getTags(); for (String key : tags.keySet()) { if (key.startsWith("tag_")) { From 09f94a8848272c9546c482e4d663dacfcc34a2ea Mon Sep 17 00:00:00 2001 From: max-klaus Date: Fri, 29 Jan 2021 18:46:27 +0300 Subject: [PATCH 006/398] Fix travel in free version --- OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java index aaac5e6f9e..298e3fc287 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java @@ -292,10 +292,6 @@ public class DownloadActivityType { public IndexItem parseIndexItem(OsmandApplication ctx, XmlPullParser parser) { - if (TRAVEL_FILE == this && !Version.isDeveloperVersion(ctx)) { - //todo remove "if" when .travel.obf will be used in production - return null; - } String name = parser.getAttributeValue(null, "name"); //$NON-NLS-1$ if (!isAccepted(name)) { return null; From 24c69f0a878c48b972bed241ea4e446d077ce7ec Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Jan 2021 18:29:54 +0200 Subject: [PATCH 007/398] Added image for OpenPlaceReviews plugins screen --- .../img_plugin_openplacereviews.webp | Bin 0 -> 23698 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp diff --git a/OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp b/OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp new file mode 100644 index 0000000000000000000000000000000000000000..97e0b2e58ddc623cb109bbf0ca08ef656e52a8d7 GIT binary patch literal 23698 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 Date: Fri, 29 Jan 2021 09:16:26 +0000 Subject: [PATCH 008/398] Translated using Weblate (French) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-fr/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index e9c1c87b65..381fbfddb3 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3996,4 +3996,9 @@ Lire la suite Modifier la description Supprimer les points de passage + Envoi %1$d sur %2$d + Sélectionnez les modifications à envoyer + %1$d sur %2$d envoyé + Envoi en cours + Envoi terminé \ No newline at end of file From f6043222c4d8a91de1956500faf2bfce8d30f486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 29 Jan 2021 04:40:44 +0000 Subject: [PATCH 009/398] Translated using Weblate (Turkish) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-tr/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 02664a0a1e..1f9d208ac4 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -2332,7 +2332,7 @@ Otomatik-sesli-bildirim periyodu Uğranacak-ara-noktalar bulunamadı İspanyolca (Amerikan) - Hareket Zamanı + Hareket halindeki zaman Plan seçin Çevrim dışı seyahat rehberi işlevselliğini almak için aşağıdakilerden birini satın alın: Uygun ögeyi seçin @@ -4007,4 +4007,9 @@ Bu çevrim içi yönlendirme motoru silinsin mi\? Tamamını oku Açıklamayı düzenle + Karşıya yükleniyor + Karşıya yükleme tamamlandı + %1$d / %2$d karşıya yükleniyor + %1$d / %2$d karşıya yüklendi + Karşıya yüklenecek düzenlemeleri seçin \ No newline at end of file From 97c06d99c080fabb353638bc475104617a95aad6 Mon Sep 17 00:00:00 2001 From: Tymofij Lytvynenko Date: Fri, 29 Jan 2021 07:50:28 +0000 Subject: [PATCH 010/398] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-uk/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index f180654a56..f724876c74 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -2436,7 +2436,7 @@ Середнє %1$d зі %2$d Підйом/спуск - Час руху + Час у русі Макс/мін Мін/макс Напівпрозорий рожевий @@ -4005,4 +4005,9 @@ Видалити маршрутні точки Копіювати до позначок мапи Копіювати до закладок + Вивантаження + Вивантаження завершено + Вивантаження %1$d з %2$d + Вивантажено %1$d з %2$d + Виберіть зміни для вивантаження \ No newline at end of file From dbdfe6151ccf18c05b2564dca74bf30abe5835fc Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Fri, 29 Jan 2021 17:50:53 +0000 Subject: [PATCH 011/398] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 44ac4e79b6..023809b5ae 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4001,4 +4001,9 @@ Copiar para favoritos Excluir este mecanismo de roteamento online\? Ler na íntegra + Carregando + Carreamento concluído + Carregando %1$d de %2$d + Carregado %1$d de %2$d + Selecione as edições para carregamento \ No newline at end of file From dadc703d486f3962e7f5ffbdaa89698d70c29f0b Mon Sep 17 00:00:00 2001 From: Verdulo Date: Fri, 29 Jan 2021 15:03:25 +0000 Subject: [PATCH 012/398] Translated using Weblate (Esperanto) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-eo/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 349175b810..219a59ae10 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -2433,7 +2433,7 @@ Mezumo %1$d el %2$d Supreniroj/malsupreniroj - Movada tempo + Tempo dum movo Maks./min. Min./maks. Rozkolora diafana @@ -4006,4 +4006,9 @@ Redakti priskribon Forigi navigadpunktojn Kopii al map‑markoj + Sendado + Sendado finita + Sendado de %1$d el %2$d + Sendis %1$d el %2$d + Elektu redaktojn por sendi \ No newline at end of file From c81f05ea7f905c71ba001c644c12aa9fffa51ab5 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Fri, 29 Jan 2021 09:42:33 +0000 Subject: [PATCH 013/398] Translated using Weblate (Arabic) Currently translated at 92.9% (3606 of 3881 strings) --- OsmAnd/res/values-ar/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ar/phrases.xml b/OsmAnd/res/values-ar/phrases.xml index 2b880e83d6..9338e3e669 100644 --- a/OsmAnd/res/values-ar/phrases.xml +++ b/OsmAnd/res/values-ar/phrases.xml @@ -3678,4 +3678,5 @@ نفق خفافيش جسر خفافيش معبر الحيوانات البرية + شريط التمرير \ No newline at end of file From c11be07b0b39067d036bc47edcb3639037bedd14 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 29 Jan 2021 01:32:23 +0000 Subject: [PATCH 014/398] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index c092cb961b..9b601f4c19 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -2430,7 +2430,7 @@ 平均 %1$d 的 %2$d 上升/下降 - 移動時間 + 運動時間 最大/最小 最小/最大 半透明粉紅色 @@ -3999,4 +3999,9 @@ 刪除航點 複製到地圖標記 複製到收藏 + 正在上傳 + 已完成上傳 + 正在上傳 %1$d,共 %2$d + 已上傳 %1$d,共 %2$d + 選取要上傳的檔案 \ No newline at end of file From 446860082b8d846cc4068cb3ae0d620e60c04215 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Fri, 29 Jan 2021 20:59:02 +0000 Subject: [PATCH 015/398] Translated using Weblate (French) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 381fbfddb3..c963ab462e 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3996,7 +3996,7 @@ Lire la suite Modifier la description Supprimer les points de passage - Envoi %1$d sur %2$d + Envoi de %1$d sur %2$d Sélectionnez les modifications à envoyer %1$d sur %2$d envoyé Envoi en cours From cfac0c352dbb5f0d5eb88d6c45eb204a28fc44e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Fri, 29 Jan 2021 21:51:09 +0000 Subject: [PATCH 016/398] Translated using Weblate (Hungarian) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-hu/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index d883e7189b..5355241d87 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -4000,4 +4000,9 @@ Útpontok törlése Másolás a térképjelölők közé Másolás a kedvencek közé + Felöltés folyamatban + Feltöltés befejezve + %1$d / %2$d feltöltés alatt + %1$d / %2$d feltöltve + Szerkesztések kijelölése feltöltéshez \ No newline at end of file From 82a02ca5596ac5f1931c80b7125a42f31b02664b Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Fri, 29 Jan 2021 23:04:00 +0000 Subject: [PATCH 017/398] Translated using Weblate (Hebrew) Currently translated at 99.9% (3654 of 3656 strings) --- OsmAnd/res/values-iw/strings.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 4915811995..737272e2e5 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -1528,7 +1528,7 @@ מרחק ממוצע %1$d מתוך %2$d - זמן תנועה + זמן בתנועה מרבי/מזערי מזערי/מרבי סיורים @@ -4001,4 +4001,16 @@ מחיקת נקודות דרך העתקה לסמני המפה העתקה למועדפים + שנ׳ + מעבר + הגעה + הכנה ממושכת + הכנה + פנייה + הפרשי זמן ומרחק + מתבצעת שליחה + השליחה הושלמה + נשלחות %1$d מתוך %2$d + נשלחו %1$d מתוך %2$d + נא לבחור עריכות לשליחה \ No newline at end of file From d8ff9fb1e7e29becba9ce394feff12cb09bac0d5 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Sat, 30 Jan 2021 17:02:37 +0200 Subject: [PATCH 018/398] Add route activity type --- .../net/osmand/osm/edit/EntityParser.java | 24 ------------------- .../res/layout/wikivoyage_travel_gpx_card.xml | 6 ++--- .../plus/wikivoyage/data/TravelGpx.java | 4 ++-- .../plus/wikivoyage/data/TravelObfHelper.java | 4 ++-- .../explore/SavedArticlesRvAdapter.java | 10 ++++---- .../explore/travelcards/TravelGpxCard.java | 22 ++++++++--------- 6 files changed, 23 insertions(+), 47 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java index e21927477a..bd37de6ba0 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/edit/EntityParser.java @@ -193,10 +193,6 @@ public class EntityParser { if (wbs != null) { am.setAdditionalInfo("wikipedia", wbs); } - String profileName = getProfileName(entity); - if (profileName != null) { - am.setAdditionalInfo("profile", profileName); - } if (checkAmenitiesToAdd(am, amenitiesList) && !"no".equals(am.getSubType())) { amenitiesList.add(am); } @@ -206,26 +202,6 @@ public class EntityParser { return amenitiesList; } - private static String getProfileName(Entity e) { - Map tags = e.getTags(); - for (String key : tags.keySet()) { - if (key.startsWith("tag_")) { - switch (tags.get(key).trim()) { - case "bicycle": - case "cycling": - case "mtb": - return "bicycle"; - case "hiking": - case "hike": - case "walking": - case "walk": - return "pedestrian"; - } - } - } - return null; - } - private static boolean checkAmenitiesToAdd(Amenity a, List amenitiesList){ // check amenity for duplication for(Amenity b : amenitiesList){ diff --git a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml index b3aaf7e849..963c27c9f3 100644 --- a/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml +++ b/OsmAnd/res/layout/wikivoyage_travel_gpx_card.xml @@ -180,7 +180,7 @@ Date: Sat, 30 Jan 2021 15:18:55 +0000 Subject: [PATCH 019/398] Translated using Weblate (Slovak) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-sk/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 2da9b2324b..84b80a03a8 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -2434,7 +2434,7 @@ Priemer %1$d z %2$d Stúpanie/Klesanie - Trvanie presunu + Čas v pohybe Max/Min Pozastaviť/pokračovať navigáciu Tlačidlo pre pozastavenie alebo pokračovanie navigácie. @@ -4001,4 +4001,9 @@ Odstrániť body trasy Skopírovať do mapových značiek Skopírovať do obľúbených + Odosielanie + Odoslanie dokončené + Odosiela sa %1$d z %2$d + Odoslané %1$d z %2$d + Zvoľte úpravy na odoslanie \ No newline at end of file From 9d94820aa3064f5331c102ed8a9415eb9f71c0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Sat, 30 Jan 2021 07:12:16 +0000 Subject: [PATCH 020/398] Translated using Weblate (Czech) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-cs/strings.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 404ec25431..738a4e98fe 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -2314,7 +2314,7 @@ Průměr %1$d z %2$d Stoupání/Klesání - Čas pohybu + Doba pohybu Max/Min Min/Max Pozastavit/pokračovat v navigaci @@ -4000,4 +4000,15 @@ Horské kolo Chyba serveru: %1$s Název již existuje + Odstranit tuto online navigační službu\? + Přečíst celé + Upravit popis + Odstranit body trasy + Kopírovat do mapových značek + Kopírovat do oblíbených + Nahrávání + Nahrávání dokončeno + Nahrávám %1$d z %2$d + Nahráno %1$d z %2$d + Vyberte úpravy pro nahrání \ No newline at end of file From 5d82bbcd27282a1e43cdfc978bdca20536ffe771 Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 30 Jan 2021 17:17:26 +0000 Subject: [PATCH 021/398] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (3655 of 3656 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 56f6940aae..18a479e18b 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -2438,7 +2438,7 @@ Promedio %1$d de %2$d Ascenso/Descenso - Tiempo moviéndose + Tiempo en movimiento Máx/Min Min/Máx Rosa translúcido @@ -4009,4 +4009,9 @@ Borrar puntos de referencia Copiar a «Marcadores del mapa» Copiar a favoritos + Subiendo + Subida completa + Subiendo %1$d de %2$d + Se subieron %1$d de %2$d + Marcar ediciones a subir \ No newline at end of file From fc7466ab94781864a83c39f034aebd2cf455054f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20=C3=87akmak?= Date: Sat, 30 Jan 2021 17:09:06 +0000 Subject: [PATCH 022/398] Translated using Weblate (Turkish) Currently translated at 83.3% (3234 of 3881 strings) --- OsmAnd/res/values-tr/phrases.xml | 152 +++++++++++++++++++++++++------ 1 file changed, 124 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 2fe8bccf32..b76cd1cada 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -299,14 +299,14 @@ Kağıt Giyim Kutular - Cam şişeler + Cam şişeleri Plastik Hurda metal Piller Plastik şişeler Yeşil atık Atık (siyah çanta) - Plastik Ambalaj + Plastik ambalaj Gazete Kartonlar Mukavva @@ -316,11 +316,11 @@ Ahşap Kitaplar Ayakkabı - alüminyum + Alüminyum Organik İçecek kartonları Bahçe atıkları - Düşük enerji Ampüller + Düşük enerjili ampüller Floresan tüpler Metal Elektrik ögeleri @@ -329,16 +329,16 @@ Motor yağı Plastik torbalar Tehlikeli atık - Cep telefonları + Cep telefonu Cıva Bilgisayarlar - Lastikler + Araba lastiği TV, monitör Karton kutu Moloz CD Atık yağ - Şişe + Şişeler Tıpa Yazıcı kartuşları Sac metal @@ -349,7 +349,7 @@ Gübre Zor Noel ağaçları - Işık Ampülleri + Ampüller Sunta Polyester Alçıpan @@ -584,7 +584,7 @@ İbadethane Hristiyanlık Yahudilik - İslami + İslam Sih dini Budizm Hinduizm @@ -823,9 +823,9 @@ Muhasebeci Bitcoin ödeme Mağara girişi - Dağın tepesi + Zirve Eyer - Volkan + Yanardağ Krater Sırt Buzul @@ -896,13 +896,13 @@ İbranice wiki Hintçe wiki Hırvatça wiki - Haiti dilinde wiki + Haitice wiki Macarca wiki Endonezyaca wiki İtalyanca wiki Letonca wiki Malayca wiki - Newar dilinde wiki + Nevarca wiki Flemenkçe wiki Norveççe Nynorsk wiki Norveççe wiki @@ -1385,7 +1385,7 @@ Enerji kaynağı: dizel Uluslararası isim Ulusal isim - Bölgesel isim + Yerel ad Yerel isim Eski isim Alternatif isim @@ -1679,12 +1679,12 @@ Sadece glutensiz Glutensiz Glutensiz diyet: hayır - Sadece kosher + Sadece koşer Kosher - Kosher diyet: hayır + Koşer gıda: hayır Sadece helal Helal - Helal diyet: hayır + Helal gıda: hayır Sadece laktozsuz Laktozsuz Laktozsuz diyet: hayır @@ -1718,7 +1718,7 @@ Vejetaryen Vegan Glutensiz - Kosher + Koşer Helal Laktozsuz Evet @@ -1902,7 +1902,7 @@ FAA kodu Sanat eseri türü: heykel İnternet erişimi var - Nakit para çekme + Nakit çekme Salıncak kapı Kent at arabası boşluğu Rüzgar tarafından düşürülen @@ -2283,7 +2283,7 @@ Uygarlık: nuragic (MÖ 18. yy – MS 2. yy) Uygarlık: etrüsk (MÖ 12. – 6. yy) Uygarlık: tarih öncesi - Uygarlık: antik yunan + Uygarlık: eski yunan Uygarlık: roma Uygarlık: bizans (MS 285 – MS 1453) Uygarlık: çin imparatorluğu (MÖ 221 – MS 1911) @@ -2291,7 +2291,7 @@ Uygarlık: kelt Uygarlık: batı roma (MS 285 – MS 476) Uygarlık: miken - Uygarlık: dacian + Uygarlık: daçya Uygarlık: hernici Uygarlık: yunan mısırı (MÖ 332 – MÖ 30) Uygarlık: roma ve bizans mısırı @@ -2309,10 +2309,10 @@ SMS Durum Tür - Tarihi çağ: kalkolitik (MÖ 4.–3. milenyum) - Tarihi çağ: neolitik - Tarihi çağ: mezolitik - Tarihi çağ: paleolitik (günümüzden 2,6 milyon yıl önce – 10000 yıl önce) + Tarihi çağ: bakır taş (MÖ 4.–3. milenyum) + Tarihi çağ: cilalı taş + Tarihi çağ: orta taş + Tarihi çağ: yontma taş (günümüzden 2,6 milyon yıl önce – 10000 yıl önce) Tarihi dönem: imparatorluk (dönem V, MS 900 – MS 1200 Tarihi dönem: klasik (dönem IV, MS 374 – MS 900) Tarihi dönem: kentsel (dönem III, MS 133 – MS 374) @@ -2892,18 +2892,18 @@ Waffle Krep Falafel - Taco + Tako Kantin Tuzlu krep Kızarmış tavuk Kuskus Fırın Bistro - Kızarmış yiyecekler + Kızartma Dondurulmuş yoğurt Şarküteri Turta - Çay dükkanı + Çaycı Sağlık çalışanının rolü: büyücü Sağlık çalışanının rolü: teknisyen Sağlık çalışanının rolü: doktor asistanı @@ -3138,4 +3138,100 @@ Ağır yük aracı erişimi: tarım Ağır yük aracı erişimi: hayır Ağır yük aracı erişimi: özel + Göl + Irmak + Kuyu + Aşılama: Kovid-19 + Hemşire + Hayır + Evet + Hayır + Evet + Hayır + Evet + Çerezci + Arı kovanı + Sadece yürümeye izin verildiğinde + İnternet erişimi: müşteriler + Püskürme sayısı + Son püskürme + Mezar + Girocard + Nakit çekme ücreti: hayır + Nakit çekme ücreti: evet + Nakit çekme para birimi + Nakit çekme + Nakit çekme: evet + Evet + Evet + Evet + Evet + Evet + Serbest + Evet + Evet + Evet + Evet + Evet + Serbest + Evet + Taksi erişimi: hayır + Taksi erişimi: evet + Tarım aracı erişimi: hayır + Tarım aracı erişimi: evet + Kar arabası erişimi: hayır + Kar arabası erişimi: özel + Otobüs erişimi: hayır + Karavan erişimi: hayır + Yaya erişimi: müşteriler + Yaya erişimi: serbest + Yaya erişimi: hayır + Yaya erişimi: özel + Yaya erişimi: evet + At erişimi: serbest + At erişimi: özel + Bisiklet erişimi: müşteriler + Bisiklet erişimi: serbest + Bisiklet erişimi: özel + Moped erişimi: hayır + Motorsiklet erişimi: özel + Araç erişimi: askerî + Araç erişimi: müşteriler + Araç erişimi: serbset + Araç erişimi: hayır + Araç erişimi: özel + Araç erişimi: evet + Metro + Tıp laboratuvarı + Kalıntılar + Temassız kabul edilmiyor + Temassız + Lastikler + Araba parçaları + Tarım mağazası + Tür: otlak + Tırmanma güzergahları + Buz: hayır + Buz: evet + Spor: hayır + Spor: evet + Para gönderme + Konum: köprü + Kano: hayır + Kano: evet + Kayaklar: hayır + Kayaklar: evet + Kuşçuluk + Safari parkı + Lokomotif + Gıdon + Trafik aynası + Yazıt: KD + Yazıt: D + Yazıt: GD + Yazıt: G + Yazıt: GB + Yazıt: B + Yazıt: KB + Yazıt: K \ No newline at end of file From b00df8b5ea073a2375f58374af858cdc362f45bd Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 30 Jan 2021 19:21:23 +0000 Subject: [PATCH 023/398] Translated using Weblate (Polish) Currently translated at 99.2% (3630 of 3656 strings) --- OsmAnd/res/values-pl/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 04170526ec..dc7dcf24c9 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -2345,7 +2345,7 @@ Średnia %1$d z %2$d Podjazd/zjazd - Czas w ruchu + Czas poruszania Maks./min. Zatrzymaj/wznów nawigację Przycisk do wstrzymania lub wznowienia nawigacji. @@ -3998,4 +3998,14 @@ Taka nazwa już istnieje Silnik wyznaczania tras online Silniki wyznaczania tras online + Przeczytaj całość + Edytuj opis + Usuń punkty trasy + Skopiuj do znaczników mapy + Skopiuj do ulubionych + Wysyłanie + Przesyłanie zakończone + Przesyłanie %1$d z %2$d + Przesłano %1$d z %2$d + Wybierz zmiany do przesłania \ No newline at end of file From 8bc2679e917463aa572a122a12a28c9836e95de7 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Sat, 30 Jan 2021 21:07:33 +0000 Subject: [PATCH 024/398] Translated using Weblate (Sardinian) Currently translated at 99.4% (3636 of 3656 strings) --- OsmAnd/res/values-sc/strings.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index c0caa235d6..020b6b3915 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3982,4 +3982,21 @@ MTB (motosilurante) Errore de su serbidore: %1$s Su nùmene esistit giai + Analiza pro intervallos (intervallu fratzionadu) + Càrriga in OpenStreetMap + Modìfica sa rasta + Modìfica su nùmene de sa rasta + Càmbia sa cartella + seg + Iscantzellare custu motore de càrculu in lìnia\? + Leghe totu + Modìfica sa descritzione + Iscantzella sos puntos de coladòrgiu + Còpia in sos marcadores de sa mapa + Còpia in sos preferidos + Carrighende + Carrigamentu acabadu + Carrighende %1$d de %2$d + %1$d de %2$d carrigados + Ischerta modìficas de carrigare \ No newline at end of file From a335ce8c10bcc4731534ac96c1c8f4f80866341e Mon Sep 17 00:00:00 2001 From: Hardy Date: Sun, 31 Jan 2021 09:01:39 +0100 Subject: [PATCH 025/398] shorten string --- OsmAnd/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 2c3358dda4..bbf5028d03 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -55,7 +55,7 @@ Rename track Edit track Upload to OpenStreetMap - Analyze by intervals (split interval) + Analyze split intervals Empty Select folder or add new one Select folder From 77c69183e02192ed94cf08a2fc139c035f07506e Mon Sep 17 00:00:00 2001 From: Hardy Date: Sun, 31 Jan 2021 09:09:24 +0100 Subject: [PATCH 026/398] shorten string --- OsmAnd/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 620e4a10ea..063f7f7df3 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3972,7 +3972,7 @@ Ordner auswählen Ordner auswählen oder neuen hinzufügen Leer - Nach Intervallen auswerten (geteiltes Intervall) + Nach Intervallen auswerten Hochladen zu OpenStreetMap Track editieren Track umbenennen @@ -4008,4 +4008,4 @@ Wegpunkte löschen In Favoriten kopieren In Kartenmarkierungen kopieren - \ No newline at end of file + From 99ae414d1d36cad58759bdc98bb28f205509da09 Mon Sep 17 00:00:00 2001 From: Nekromanser <78290702+Nekromanser@users.noreply.github.com> Date: Mon, 1 Feb 2021 10:17:32 +0000 Subject: [PATCH 027/398] Update phrases.xml Improved finnish translation and fixed typos. --- OsmAnd/res/values-fi/phrases.xml | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/values-fi/phrases.xml b/OsmAnd/res/values-fi/phrases.xml index 7751c5bb95..6453253dd4 100644 --- a/OsmAnd/res/values-fi/phrases.xml +++ b/OsmAnd/res/values-fi/phrases.xml @@ -17,7 +17,7 @@ Bussipysäkki Trollibussin pysäkki Raitiovaunupysäkki - Piknic paikka + Piknik-paikka Merkittävä kivi Ankkurointipaikka Majakka/linjavalo @@ -311,8 +311,8 @@ Ei Visa Electron -kortteja Shekit Shekkejä ei hyväksytä - Visa Debit -kortit - Ei Visa Debit -kortteja + Visa Debit-kortit + Ei Visa Debit-kortteja Muut Muita maksutapoja ei hyväksytä Bancomat @@ -1139,28 +1139,28 @@ Ei MasterCard-kortteja Maestro-kortit Ei Maestro-kortteja - Ei American Express (AMEX) -kortteja - Ei Diners Club -kortteja + Ei American Express (AMEX)-kortteja + Ei Diners Club-kortteja Ei DKV-kortteja Ei UTA-kortteja Ei Efectivo-maksua Ei Girocard-kortteja Discover Card - Ei Discover Card -kortteja + Ei Discover Card-kortteja Ei Litecoinia Ei PIKEPASS-maksua Ei kryptovaluuttaa - Ei Routex -tankkauskortteja - Ei IC Stored Fare -kortteja + Ei Routex-tankkauskortteja + Ei IC Stored Fare-kortteja Ei JCB-kortteja Ei Laser-kortteja Ei Quick-kortteja Ei Eurowag-kortteja - Ei E-ZPass -maksua + Ei E-ZPass-maksua Ei Euroshell-tankkauskortteja Ei KITCard-maksua Ei Westfalen-kortteja - Ei V PAY -kortteja + Ei V PAY-kortteja Ei Dogecoinia Ei Cibus-kortteja Ei maksua tilisiirrolla @@ -1172,7 +1172,7 @@ Ei Minipay-maksua Ei MiniCash-maksua Ei Moneo-maksua - Ei Monedero 4B -maksua + Ei Monedero 4B-maksua Ei Monedero-maksua Ei BankAxess-maksua Ei Coinkite-maksua @@ -1182,20 +1182,20 @@ Ei tekstiviestimaksua Ei Oyster-kortteja Ei SUBE-kortteja - Ei Via Verde -maksua + Ei Via Verde-maksua Lounassetelit Ei lounasseteleitä Ei PayPal-maksua - Ei U-Key -maksua + Ei U-Key-maksua Poletit Ei poletteja Ei lahjakorttimaksua - Ei Golden Crown -kortteja + Ei Golden Crown-kortteja Ei PRO100-kortteja - Ei Union Card -kortteja + Ei Union Card-kortteja Ei MTS-Money -maksua - Ei Yandex.Money -maksua - Ei OV-Chipkaart -kortteja + Ei Yandex.Money-maksua + Ei OV-Chipkaart-kortteja Tapahtumapaikka Vain kasvisruokaa Kasvisruokaa @@ -1245,9 +1245,9 @@ Sisätilat Ulkona Ei wc-tiloja - Inva-wc: kyllä - Inva-wc: ei - Asiakas-wc + Inva-WC: kyllä + Inva-WC: ei + Asiakas-WC WC:n käyttö: yhteisö WC:n käyttö: julkinen Vauvan vaihtopöytä @@ -1522,4 +1522,4 @@ Vieras talo Majapaikka Vuoristorata - \ No newline at end of file + From 016320795c0a0ba066df4948c62154d8f487c794 Mon Sep 17 00:00:00 2001 From: Kseniia Date: Mon, 1 Feb 2021 19:31:47 +0200 Subject: [PATCH 028/398] fix search --- .../osmand/binary/BinaryMapIndexReader.java | 79 ++++++++++++++- .../binary/BinaryMapPoiReaderAdapter.java | 95 ++++++++++++++----- 2 files changed, 146 insertions(+), 28 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java index 8743940a74..9fbf00ed4e 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java @@ -2161,7 +2161,7 @@ public class BinaryMapIndexReader { private static boolean testAddressSearch = false; private static boolean testAddressSearchName = false; private static boolean testAddressJustifySearch = false; - private static boolean testPoiSearch = false; + private static boolean testPoiSearch = true; private static boolean testPoiSearchOnPath = false; private static boolean testTransportSearch = true; @@ -2177,7 +2177,7 @@ public class BinaryMapIndexReader { public static void main(String[] args) throws IOException { File fl = new File(System.getProperty("maps") + "/Synthetic_test_rendering.obf"); - fl = new File("/home/madwasp79/OsmAnd-maps/Poly_center2.obf"); + fl = new File("/Users/plotva/work/osmand/maps/Wikivoyage.obf"); RandomAccessFile raf = new RandomAccessFile(fl, "r"); @@ -2325,7 +2325,7 @@ public class BinaryMapIndexReader { private static void testPoiSearchByName(BinaryMapIndexReader reader) throws IOException { println("Searching by name..."); - SearchRequest req = buildSearchPoiRequest(0, 0, "Art", + SearchRequest req = buildSearchPoiRequest(0, 0, "central ukraine", 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, null); reader.searchPoiByName(req); @@ -2385,6 +2385,79 @@ public class BinaryMapIndexReader { } + int readIndexedStringTable(Collator instance, String query, String prefix, HashMap map, int charMatches) throws IOException { + String key = null; + while (true) { + int t = codedIS.readTag(); + int tag = WireFormat.getTagFieldNumber(t); + switch (tag) { + case 0: + return charMatches; + case OsmandOdb.IndexedStringTable.KEY_FIELD_NUMBER : + key = codedIS.readString(); + if(prefix.length() > 0){ + key = prefix + key; + } + // check query is part of key (the best matching) + if(CollatorStringMatcher.cmatches(instance, key, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + if(query.length() >= charMatches){ + if(query.length() > charMatches){ + charMatches = query.length(); + map.clear(); + } + } else { + key = null; + } + // check key is part of query + } else if (CollatorStringMatcher.cmatches(instance, query, key, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { + if (key.length() >= charMatches) { + if (key.length() > charMatches) { + charMatches = key.length(); + map.clear(); + } + } else { + key = null; + } + } else { + key = null; + } + break; + case OsmandOdb.IndexedStringTable.VAL_FIELD_NUMBER: + int val = readInt(); + if (key != null) { + String[] words = query.split(" "); + String keyByWord = null; + for (String w : words) { + if (instance.equals(w.substring(0, charMatches), key)) { + keyByWord = w; + } + } + if (map.containsKey(keyByWord)) { + map.get(keyByWord).add(val); + } else { + TIntArrayList list = new TIntArrayList(); + list.add(val); + map.put(keyByWord, list); + } + } + break; + case OsmandOdb.IndexedStringTable.SUBTABLES_FIELD_NUMBER : + int len = codedIS.readRawVarint32(); + int oldLim = codedIS.pushLimit(len); + if (key != null) { + charMatches = readIndexedStringTable(instance, query, key, map, charMatches); + } else { + codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); + } + codedIS.popLimit(oldLim); + break; + default: + skipUnknownField(t); + break; + } + } + } + int readIndexedStringTable(Collator instance, String query, String prefix, TIntArrayList list, int charMatches) throws IOException { String key = null; while (true) { diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java index cb348cf9b4..190576454c 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -9,8 +9,11 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map.Entry; import net.osmand.Collator; import net.osmand.CollatorStringMatcher; @@ -293,6 +296,7 @@ public class BinaryMapPoiReaderAdapter { } protected void searchPoiByName(PoiRegion region, SearchRequest req) throws IOException { + HashMap offsetsMap = new HashMap<>(); TIntLongHashMap offsets = new TIntLongHashMap(); String query = normalizeSearchPoiByNameQuery(req.nameQuery); CollatorStringMatcher matcher = new CollatorStringMatcher(query, @@ -312,18 +316,48 @@ public class BinaryMapPoiReaderAdapter { int length = readInt(); int oldLimit = codedIS.pushLimit(length); // here offsets are sorted by distance - offsets = readPoiNameIndex(matcher.getCollator(), query, req); + offsetsMap = readPoiNameIndex(matcher.getCollator(), query, req); codedIS.popLimit(oldLimit); break; case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER: // also offsets can be randomly skipped by limit Integer[] offKeys = new Integer[offsets.size()]; - if (offsets.size() > 0) { - int[] keys = offsets.keys(); - for (int i = 0; i < keys.length; i++) { - offKeys[i] = keys[i]; + if (offsetsMap.size() > 0) { + List> setKeys = new ArrayList<>(); + for (Entry item : offsetsMap.entrySet()) { + TIntLongHashMap sets = item.getValue(); + + Integer[] offKeysFinal = new Integer[sets.size()]; + int[] keys = sets.keys(); + for (int i = 0; i < keys.length; i++) { + offKeysFinal[i] = keys[i]; + } + offsets.putAll(sets); + HashSet generalSet = new HashSet(Arrays.asList(offKeysFinal)); + setKeys.add(generalSet); + } + HashSet firstSet = new HashSet(); + HashSet secondSet = new HashSet(); + HashSet finalSet = new HashSet(); + for (HashSet keySet : setKeys) { + if (setKeys.size() == 1) { + finalSet.addAll(keySet); + } else { + if (firstSet.size() == 0) { + firstSet.addAll(keySet); + } else { + secondSet.addAll(firstSet); + secondSet.retainAll(keySet); + finalSet.addAll(secondSet); + } + } } final TIntLongHashMap foffsets = offsets; + offKeys = finalSet.toArray(new Integer[finalSet.size()]); + for (Integer key : offKeys) { + foffsets.put(key, offsets.get(key)); + } + Arrays.sort(offKeys, new Comparator() { @Override public int compare(Integer object1, Integer object2) { @@ -332,7 +366,7 @@ public class BinaryMapPoiReaderAdapter { }); int p = BUCKET_SEARCH_BY_NAME * 3; if (p < offKeys.length) { - for (int i = p + BUCKET_SEARCH_BY_NAME; ; i += BUCKET_SEARCH_BY_NAME) { + for (int i = p + BUCKET_SEARCH_BY_NAME;; i += BUCKET_SEARCH_BY_NAME) { if (i > offKeys.length) { Arrays.sort(offKeys, p, offKeys.length); break; @@ -344,7 +378,6 @@ public class BinaryMapPoiReaderAdapter { } } - LOG.info("Searched poi structure in " + (System.currentTimeMillis() - time) + "ms. Found " + offKeys.length + " subtrees"); for (int j = 0; j < offKeys.length; j++) { @@ -368,42 +401,54 @@ public class BinaryMapPoiReaderAdapter { } } - private TIntLongHashMap readPoiNameIndex(Collator instance, String query, SearchRequest req) throws IOException { - TIntLongHashMap offsets = new TIntLongHashMap(); - TIntArrayList dataOffsets = null; + private HashMap readPoiNameIndex(Collator instance, String query, SearchRequest req) throws IOException { + HashMap dataOffsetsMap = null; + HashMap offsetsMap = new HashMap<>(); int offset = 0; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: - return offsets; + return offsetsMap; case OsmandOdb.OsmAndPoiNameIndex.TABLE_FIELD_NUMBER: { int length = readInt(); int oldLimit = codedIS.pushLimit(length); - dataOffsets = new TIntArrayList(); + dataOffsetsMap = new HashMap<>(); offset = codedIS.getTotalBytesRead(); - map.readIndexedStringTable(instance, query, "", dataOffsets, 0); + map.readIndexedStringTable(instance, query, "", dataOffsetsMap, 0); codedIS.popLimit(oldLimit); break; } case OsmandOdb.OsmAndPoiNameIndex.DATA_FIELD_NUMBER: { - if (dataOffsets != null) { - dataOffsets.sort(); // 1104125 - for (int i = 0; i < dataOffsets.size(); i++) { - codedIS.seek(dataOffsets.get(i) + offset); - int len = codedIS.readRawVarint32(); - int oldLim = codedIS.pushLimit(len); - readPoiNameIndexData(offsets, req); - codedIS.popLimit(oldLim); - if (req.isCancelled()) { - codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); - return offsets; + offsetsMap = new HashMap<>(); + if (dataOffsetsMap != null) { + for (Entry item : dataOffsetsMap.entrySet()) { + TIntLongHashMap offsets = new TIntLongHashMap(); + TIntArrayList dataOffsets = item.getValue(); + String word = item.getKey(); + dataOffsets.sort(); // 1104125 + for (int i = 0; i < dataOffsets.size(); i++) { + codedIS.seek(dataOffsets.get(i) + offset); + int len = codedIS.readRawVarint32(); + int oldLim = codedIS.pushLimit(len); + readPoiNameIndexData(offsets, req); + codedIS.popLimit(oldLim); + + if (offsetsMap.containsKey(word)) { + offsetsMap.get(word).putAll(offsets); + } else { + TIntLongHashMap map = new TIntLongHashMap(); + map.putAll(offsets); + offsetsMap.put(word, map); + } } } + codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); + return offsetsMap; } codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); - return offsets; + return offsetsMap; } default: skipUnknownField(t); From 3cb9ab9eff8c35c951a0ca3db3c7e995f09849ab Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 1 Feb 2021 19:47:20 +0100 Subject: [PATCH 029/398] Try to separate how we read & search poi by exact multiword --- .../binary/BinaryMapAddressReaderAdapter.java | 5 +- .../osmand/binary/BinaryMapIndexReader.java | 147 ++++++------------ .../binary/BinaryMapPoiReaderAdapter.java | 120 ++++++-------- 3 files changed, 100 insertions(+), 172 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java index 18f7b2549e..8722c96acb 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java @@ -8,6 +8,7 @@ import gnu.trove.set.hash.TIntHashSet; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -627,7 +628,9 @@ public class BinaryMapAddressReaderAdapter { indexOffset = codedIS.getTotalBytesRead(); int oldLimit = codedIS.pushLimit(length); // here offsets are sorted by distance - map.readIndexedStringTable(stringMatcher.getCollator(), req.nameQuery, "", loffsets, 0); + TIntArrayList charsList = new TIntArrayList(); + charsList.add(0); + map.readIndexedStringTable(stringMatcher.getCollator(), Collections.singletonList(req.nameQuery), "", Collections.singletonList(loffsets), charsList); codedIS.popLimit(oldLimit); break; case OsmAndAddressNameIndexData.ATOM_FIELD_NUMBER: diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java index 9fbf00ed4e..d00bbcd09f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java @@ -2385,127 +2385,76 @@ public class BinaryMapIndexReader { } - int readIndexedStringTable(Collator instance, String query, String prefix, HashMap map, int charMatches) throws IOException { + void readIndexedStringTable(Collator instance, List queries, String prefix, List listOffsets, TIntArrayList charMatchesList) throws IOException { String key = null; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: - return charMatches; + return; case OsmandOdb.IndexedStringTable.KEY_FIELD_NUMBER : key = codedIS.readString(); - if(prefix.length() > 0){ + if (prefix.length() > 0) { key = prefix + key; } - // check query is part of key (the best matching) - if(CollatorStringMatcher.cmatches(instance, key, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ - if(query.length() >= charMatches){ - if(query.length() > charMatches){ - charMatches = query.length(); - map.clear(); + for (int i = 0; i < queries.size(); i++) { + int charMatches = charMatchesList.get(i); + if (charMatches < 0) { + continue; + } + String query = queries.get(i); + // check query is part of key (the best matching) + if (CollatorStringMatcher.cmatches(instance, key, query, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { + if (query.length() >= charMatches) { + if (query.length() > charMatches) { + charMatchesList.set(i, query.length()); + listOffsets.get(i).clear(); + } + } else { + charMatchesList.set(i, -1); + } + // check key is part of query + } else if (CollatorStringMatcher.cmatches(instance, query, key, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { + if (key.length() >= charMatches) { + if (key.length() > charMatches) { + charMatchesList.set(i, key.length()); + listOffsets.get(i).clear(); + } + } else { + charMatchesList.set(i, -1); } } else { - key = null; + charMatchesList.set(i, -1); } - // check key is part of query - } else if (CollatorStringMatcher.cmatches(instance, query, key, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { - if (key.length() >= charMatches) { - if (key.length() > charMatches) { - charMatches = key.length(); - map.clear(); - } - } else { - key = null; - } - } else { - key = null; - } - break; - case OsmandOdb.IndexedStringTable.VAL_FIELD_NUMBER: - int val = readInt(); - if (key != null) { - String[] words = query.split(" "); - String keyByWord = null; - for (String w : words) { - if (instance.equals(w.substring(0, charMatches), key)) { - keyByWord = w; - } - } - if (map.containsKey(keyByWord)) { - map.get(keyByWord).add(val); - } else { - TIntArrayList list = new TIntArrayList(); - list.add(val); - map.put(keyByWord, list); - } - } - break; - case OsmandOdb.IndexedStringTable.SUBTABLES_FIELD_NUMBER : - int len = codedIS.readRawVarint32(); - int oldLim = codedIS.pushLimit(len); - if (key != null) { - charMatches = readIndexedStringTable(instance, query, key, map, charMatches); - } else { - codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); - } - codedIS.popLimit(oldLim); - break; - default: - skipUnknownField(t); - break; - } - } - } - - int readIndexedStringTable(Collator instance, String query, String prefix, TIntArrayList list, int charMatches) throws IOException { - String key = null; - while (true) { - int t = codedIS.readTag(); - int tag = WireFormat.getTagFieldNumber(t); - switch (tag) { - case 0: - return charMatches; - case OsmandOdb.IndexedStringTable.KEY_FIELD_NUMBER : - key = codedIS.readString(); - if(prefix.length() > 0){ - key = prefix + key; - } - // check query is part of key (the best matching) - if(CollatorStringMatcher.cmatches(instance, key, query, StringMatcherMode.CHECK_ONLY_STARTS_WITH)){ - if(query.length() >= charMatches){ - if(query.length() > charMatches){ - charMatches = query.length(); - list.clear(); - } - } else { - key = null; - } - // check key is part of query - } else if (CollatorStringMatcher.cmatches(instance, query, key, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { - if (key.length() >= charMatches) { - if (key.length() > charMatches) { - charMatches = key.length(); - list.clear(); - } - } else { - key = null; - } - } else { - key = null; } break; case OsmandOdb.IndexedStringTable.VAL_FIELD_NUMBER : int val = readInt(); - if (key != null) { - list.add(val); + for (int i = 0; i < queries.size(); i++) { + if (charMatchesList.get(i) >= 0) { + listOffsets.get(i).add(val); + } } break; case OsmandOdb.IndexedStringTable.SUBTABLES_FIELD_NUMBER : int len = codedIS.readRawVarint32(); int oldLim = codedIS.pushLimit(len); - if (key != null) { - charMatches = readIndexedStringTable(instance, query, key, list, charMatches); + boolean shouldWeReadSubtable = false; + for (int i = 0; i < queries.size(); i++) { + if (charMatchesList.get(i) >= 0) { + shouldWeReadSubtable = true; + } + } + if (shouldWeReadSubtable && key != null) { + TIntArrayList subcharMatchesList = new TIntArrayList(charMatchesList); + readIndexedStringTable(instance, queries, key, listOffsets, subcharMatchesList); + // looks like true + for (int i = 0; i < queries.size(); i++) { + if (subcharMatchesList.get(i) >= charMatchesList.get(i)) { + charMatchesList.set(i, subcharMatchesList.get(i)); + } + } } else { codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); } diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java index 190576454c..1b959a8cf9 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -1,20 +1,21 @@ package net.osmand.binary; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.TIntLongHashMap; -import gnu.trove.set.hash.TLongHashSet; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map.Entry; +import org.apache.commons.logging.Log; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.WireFormat; + +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.TIntLongHashMap; +import gnu.trove.set.hash.TLongHashSet; import net.osmand.Collator; import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; @@ -29,11 +30,6 @@ import net.osmand.osm.MapPoiTypes; import net.osmand.osm.PoiCategory; import net.osmand.util.MapUtils; -import org.apache.commons.logging.Log; - -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.WireFormat; - public class BinaryMapPoiReaderAdapter { private static final Log LOG = PlatformUtil.getLog(BinaryMapPoiReaderAdapter.class); @@ -41,7 +37,7 @@ public class BinaryMapPoiReaderAdapter { private static final int CATEGORY_MASK = (1 << SHIFT_BITS_CATEGORY) - 1; private static final int ZOOM_TO_SKIP_FILTER_READ = 6; private static final int ZOOM_TO_SKIP_FILTER = 3; - private static final int BUCKET_SEARCH_BY_NAME = 5; + private static final int BUCKET_SEARCH_BY_NAME = 15; // should be bigger 100? public static class PoiSubType { public boolean text; @@ -296,7 +292,6 @@ public class BinaryMapPoiReaderAdapter { } protected void searchPoiByName(PoiRegion region, SearchRequest req) throws IOException { - HashMap offsetsMap = new HashMap<>(); TIntLongHashMap offsets = new TIntLongHashMap(); String query = normalizeSearchPoiByNameQuery(req.nameQuery); CollatorStringMatcher matcher = new CollatorStringMatcher(query, @@ -316,48 +311,18 @@ public class BinaryMapPoiReaderAdapter { int length = readInt(); int oldLimit = codedIS.pushLimit(length); // here offsets are sorted by distance - offsetsMap = readPoiNameIndex(matcher.getCollator(), query, req); + offsets = readPoiNameIndex(matcher.getCollator(), query, req); codedIS.popLimit(oldLimit); break; case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER: // also offsets can be randomly skipped by limit Integer[] offKeys = new Integer[offsets.size()]; - if (offsetsMap.size() > 0) { - List> setKeys = new ArrayList<>(); - for (Entry item : offsetsMap.entrySet()) { - TIntLongHashMap sets = item.getValue(); - - Integer[] offKeysFinal = new Integer[sets.size()]; - int[] keys = sets.keys(); - for (int i = 0; i < keys.length; i++) { - offKeysFinal[i] = keys[i]; - } - offsets.putAll(sets); - HashSet generalSet = new HashSet(Arrays.asList(offKeysFinal)); - setKeys.add(generalSet); - } - HashSet firstSet = new HashSet(); - HashSet secondSet = new HashSet(); - HashSet finalSet = new HashSet(); - for (HashSet keySet : setKeys) { - if (setKeys.size() == 1) { - finalSet.addAll(keySet); - } else { - if (firstSet.size() == 0) { - firstSet.addAll(keySet); - } else { - secondSet.addAll(firstSet); - secondSet.retainAll(keySet); - finalSet.addAll(secondSet); - } - } + if (offsets.size() > 0) { + int[] keys = offsets.keys(); + for (int i = 0; i < keys.length; i++) { + offKeys[i] = keys[i]; } final TIntLongHashMap foffsets = offsets; - offKeys = finalSet.toArray(new Integer[finalSet.size()]); - for (Integer key : offKeys) { - foffsets.put(key, offsets.get(key)); - } - Arrays.sort(offKeys, new Comparator() { @Override public int compare(Integer object1, Integer object2) { @@ -401,54 +366,65 @@ public class BinaryMapPoiReaderAdapter { } } - private HashMap readPoiNameIndex(Collator instance, String query, SearchRequest req) throws IOException { - HashMap dataOffsetsMap = null; - HashMap offsetsMap = new HashMap<>(); + private TIntLongHashMap readPoiNameIndex(Collator instance, String query, SearchRequest req) throws IOException { + TIntLongHashMap offsets = new TIntLongHashMap(); + List listOffsets = null; + List listOfSepOffsets = new ArrayList(); int offset = 0; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: - return offsetsMap; + return offsets; case OsmandOdb.OsmAndPoiNameIndex.TABLE_FIELD_NUMBER: { int length = readInt(); int oldLimit = codedIS.pushLimit(length); - dataOffsetsMap = new HashMap<>(); offset = codedIS.getTotalBytesRead(); - map.readIndexedStringTable(instance, query, "", dataOffsetsMap, 0); + List queries = Arrays.asList(query.split(" ")); + TIntArrayList charsList = new TIntArrayList(queries.size()); + listOffsets = new ArrayList(queries.size()); + while(listOffsets.size() < queries.size()) { + charsList.add(0); + listOffsets.add(new TIntArrayList()); + } + map.readIndexedStringTable(instance, queries, "", listOffsets, charsList); codedIS.popLimit(oldLimit); break; } case OsmandOdb.OsmAndPoiNameIndex.DATA_FIELD_NUMBER: { - offsetsMap = new HashMap<>(); - if (dataOffsetsMap != null) { - for (Entry item : dataOffsetsMap.entrySet()) { - TIntLongHashMap offsets = new TIntLongHashMap(); - TIntArrayList dataOffsets = item.getValue(); - String word = item.getKey(); + if (listOffsets != null) { + for (TIntArrayList dataOffsets : listOffsets) { + TIntLongHashMap offsetMap = new TIntLongHashMap(); + listOfSepOffsets.add(offsetMap); dataOffsets.sort(); // 1104125 for (int i = 0; i < dataOffsets.size(); i++) { codedIS.seek(dataOffsets.get(i) + offset); int len = codedIS.readRawVarint32(); int oldLim = codedIS.pushLimit(len); - readPoiNameIndexData(offsets, req); + readPoiNameIndexData(offsetMap, req); codedIS.popLimit(oldLim); - - if (offsetsMap.containsKey(word)) { - offsetsMap.get(word).putAll(offsets); - } else { - TIntLongHashMap map = new TIntLongHashMap(); - map.putAll(offsets); - offsetsMap.put(word, map); + if (req.isCancelled()) { + codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); + return offsets; + } + } + } + } + if (listOfSepOffsets.size() > 0) { + offsets.putAll(listOfSepOffsets.get(0)); + for (int j = 1; j < listOfSepOffsets.size(); j++) { + TIntLongHashMap mp = listOfSepOffsets.get(j); + // offsets.retainAll(mp); -- calculate intresection of mp & offsets + for (int chKey : offsets.keys()) { + if (!mp.containsKey(chKey)) { + offsets.remove(chKey); } } } - codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); - return offsetsMap; } codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); - return offsetsMap; + return offsets; } default: skipUnknownField(t); From 5d3d9500bf5393039fd68ef25dc42186550cd965 Mon Sep 17 00:00:00 2001 From: solokot Date: Mon, 1 Feb 2021 18:47:04 +0000 Subject: [PATCH 030/398] Translated using Weblate (Russian) Currently translated at 99.5% (3639 of 3656 strings) --- OsmAnd/res/values-ru/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index a0a8f5fdea..5747a78d85 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3986,4 +3986,10 @@ Читать полностью Редактировать описание Удалить путевые точки + HGV + Отправка + Отправка завершена + Отправка %1$d из %2$d + Отправлено %1$d из %2$d + Выберите правки для отправки \ No newline at end of file From 601e8c36702d86178891b604436c7ae0022615b6 Mon Sep 17 00:00:00 2001 From: Matej U Date: Sun, 31 Jan 2021 17:24:39 +0000 Subject: [PATCH 031/398] Translated using Weblate (Slovenian) Currently translated at 74.1% (2710 of 3656 strings) --- OsmAnd/res/values-sl/strings.xml | 53 ++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-sl/strings.xml b/OsmAnd/res/values-sl/strings.xml index 0cb17c35f4..b453cd4b40 100644 --- a/OsmAnd/res/values-sl/strings.xml +++ b/OsmAnd/res/values-sl/strings.xml @@ -3275,14 +3275,14 @@ Izberi mapo Izberi mapo ali dodaj novo Prazno - Analiziraj po intervalih (razdelitveni interval) + Preuči po intervalih (razdelitveni interval) Naloži v OpenStreetMap Uredi sled Preimenuj sled Spremeni mapo sek Pristop - Pripravi se + Pripravljanje Izven poti Prihod na cilj Zavoj @@ -3296,7 +3296,7 @@ Električno kolesarjenje Gorsko kolesarjenje Cestno kolesarjenje - Redno kolesarjenje + Mestno kolesarjenje Težko tovorno vozilo Majhno tovorno vozilo Tovorno vozilo @@ -3309,4 +3309,51 @@ Uredi opis Brisanje točk Kopiraj na oznake na zemljevidu + Na napravi ni dovolj prostora. + Izbor skupin za uvoz. + Izbor predmetov za uvoz. + Dodaj na Mapillary + Dodaj na OpenPlaceReviews + Za preizkušanje pošiljanja sporočil, točk in sledi GPX preklopi iz openstreetmap.org na preizkusni dev.openstreetmap.org. + Uporabi dev.openstreetmap.org + Program podpira prikaz fotografij različnih virov: +\nOpenPlaceReviews – fotografije točk POI; +\nMapillary – ulična fotografija; +\nSplet / Wikimedia – fotografije točk POI in OpenStreetMap. + %1$s * %2$s + Dodaj nov del poti + Lahko letalo + Združi dele poti + Razdeli pred + Razdeli po + Profil OsmAnd + Uporabniški profil + Obrni vse točke + Izbor profila, ki bo prikazan ob zagonu programa. + Nazadnje uporabljeno + Podvrsta + Vozilo + Ključ API + Naslov URL strežnika + Vpis parametrov + Naslov URL z vsemi parametri bo zapisan kot: + Preizkusi izračun poti + Vožnja + Hoja + Kolo + Avto + Kopiraj naslov + Dolgo pripravljanje + Pokaži sled na zemljevidu + Raven približanja + Prosojnost + Legenda + Prikaz višinskega senčenja na zemljevidu. Več o tem je mogoče prebrati na spletni strani programa. + Senčenje + Kopiraj med priljubljene + Poteka pošiljanje + Pošiljanje je končano + Poteka pošiljanje %1$d od %2$d + Poslano %1$d od %2$d + Izbor sprememb za pošiljanje \ No newline at end of file From 4baed45334b62d3b3fde3314c23cfff6ea6a38da Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 31 Jan 2021 09:45:16 +0000 Subject: [PATCH 032/398] Translated using Weblate (German) Currently translated at 99.9% (3653 of 3656 strings) --- OsmAnd/res/values-de/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 620e4a10ea..6fec463772 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4008,4 +4008,9 @@ Wegpunkte löschen In Favoriten kopieren In Kartenmarkierungen kopieren + Lade hoch + Hochladen abgeschlossen + Lade %1$d von %2$d hoch + %1$d von %2$d hochgeladen + Bearbeitungen zum Hochladen auswählen \ No newline at end of file From cb59ac4589a3cde374e2de13bfea162f22ddbff8 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Sun, 31 Jan 2021 18:52:23 +0000 Subject: [PATCH 033/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-ar/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 4b91263f2d..d12d0a4de4 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4069,4 +4069,9 @@ حذف نقاط الطريق نسخ لعلامات الخريطة نسخ للمفضلة + يتم الرفع + اكتمال الرفع + رفع %1$d من %2$d + تم رفع %1$d من %2$d + تحديد التعديلات للتحميل \ No newline at end of file From 9dc5d32c06f336e36911e17b44541c846d0c48f0 Mon Sep 17 00:00:00 2001 From: Jukefox Date: Sun, 31 Jan 2021 19:12:35 +0000 Subject: [PATCH 034/398] Translated using Weblate (Finnish) Currently translated at 63.8% (2334 of 3656 strings) --- OsmAnd/res/values-fi/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OsmAnd/res/values-fi/strings.xml b/OsmAnd/res/values-fi/strings.xml index 95df84bf3e..c188b64182 100644 --- a/OsmAnd/res/values-fi/strings.xml +++ b/OsmAnd/res/values-fi/strings.xml @@ -2739,4 +2739,15 @@ Jos pidät OsmAndista ja OSMsta ja haluat tukea niitä, on tämä täydellinen t Kävely Polkupyörä Auto + Palvelimen virhe: %1$s + Nimi on jo käytössä + Lue kaikki + Muokkaa kuvausta + Kopioi karttamerkkeihin + Kopioi suosikkeihin + Lähetetään + Lähetys valmis + Lähetetty %1$d muutosta %2$d muutoksesta + Lähetettiin %1$d muutosta %2$d muutoksesta + Valitse lähetettävät muutokset \ No newline at end of file From 870efe218392c4826b29f9c2633d2de2214d954c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Sun, 31 Jan 2021 22:27:22 +0000 Subject: [PATCH 035/398] Translated using Weblate (Hungarian) Currently translated at 99.9% (3878 of 3881 strings) --- OsmAnd/res/values-hu/phrases.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml index 488f760a80..b4ca7f9b08 100644 --- a/OsmAnd/res/values-hu/phrases.xml +++ b/OsmAnd/res/values-hu/phrases.xml @@ -708,7 +708,7 @@ Autó Kerékpár Radioaktívhulladék-lerakó - Vízgyűjtő + Vízgyűjtő medence Megfigyelőállomás Daru Építkezés @@ -2633,7 +2633,7 @@ Lottózó Szerencsejáték-helyszín Típus - Lottózó + Lottó Játékgépek Fogadás E-cigaretta-bolt @@ -3446,7 +3446,7 @@ Motorszerelés Biztosítás Gumiszerelés - Kötélpálya + Csúszópálya Kalandpark Via ferrata (vasalt út) Sodronyok száma @@ -3524,7 +3524,7 @@ akadémiai gyermekkönyv Atoll - Útdíjellenőrző kapu + Automatikus útdíjbeszedő kapu Gyermekgondozás (bölcsőde) Természeti emlék Tájékozódási pont From 7454c740653c15f71369b9084cd4979759c4dd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 1 Feb 2021 17:56:18 +0000 Subject: [PATCH 036/398] Translated using Weblate (Estonian) Currently translated at 98.1% (3590 of 3656 strings) --- OsmAnd/res/values-et/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index 3bd15abafa..1375440bb8 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3948,4 +3948,9 @@ Viimati kasutatud Serveri viga: %1$s Selline nimi on juba olemas + Vali tehtud muudatused üleslaadimiseks + Üleslaaditud %1$d/%2$d + Laadin üles muudatusi %1$d/%2$d + Sai üleslaaditud + Laadin üles \ No newline at end of file From e4f99aeacee3bd3cf78a6dc19912e1c91a8d23d2 Mon Sep 17 00:00:00 2001 From: eol Date: Mon, 1 Feb 2021 17:35:59 +0000 Subject: [PATCH 037/398] Translated using Weblate (Dutch) Currently translated at 96.1% (3517 of 3656 strings) --- OsmAnd/res/values-nl/strings.xml | 51 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index c9d8e87306..6d4c127831 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -931,7 +931,7 @@ %1$d resterende bestanden %1$d resterende bestanden nog te downloaden Volledige versie - Annuleer route + Annuleer route \? Stop navigatie Bestemming wissen Gebruik magnetische sensor in plaats van oriëntatiesensor voor het kompas. @@ -3726,31 +3726,31 @@ Plan een route Gebruik de twee-fase A* route berekening methode Grafiek - Wacht op de herberekening van de route. -\nDe grafiek is beschikbaar na herberekening. + Wacht totdat route herberekend is. +\nNa herberekening is de grafiek zichtbaar. %1$s — %2$s Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat. Onderbreking Aangepast Voer een OAuth-login uit om osm edit functies te gebruiken - "• Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. + • Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. \n -\n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen +\n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen \n -\n • Donkere thema-fixes +\n • Donkere thema-fixes \n -\n • Verschillende routeringsproblemen over de hele wereld opgelost +\n • Verschillende routeringsproblemen over de hele wereld opgelost \n -\n • Bijgewerkte basiskaart met meer gedetailleerd wegennet +\n • Bijgewerkte basiskaart met meer gedetailleerd wegennet \n -\n • Vaste overstroomde gebieden over de hele wereld +\n • Vaste overstroomde gebieden over de hele wereld \n -\n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails +\n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails \n -\n • Andere bugs opgelost +\n • Andere bugs opgelost \n -\n" - "• Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen +\n + • Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen \n \n • Exitnummer toegevoegd in de navigatie \n @@ -3758,23 +3758,23 @@ \n \n • Herwerkt instellingenscherm voor snelle toegang tot alle profielen \n -\n • Optie toegevoegd om instellingen van een ander profiel te kopiëren +\n • Optie toegevoegd om instellingen van een ander profiel te kopiëren \n -\n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen +\n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen \n -\n • Correct uitgelijnde POI-pictogrammen op de kaart +\n • Correct uitgelijnde POI-pictogrammen op de kaart \n -\n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren +\n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren \n -\n • Thuis/werk-pictogrammen toegevoegd op de kaart +\n • Thuis/werk-pictogrammen toegevoegd op de kaart \n -\n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen +\n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen \n \n • Correcte transliteratie toegevoegd aan de kaart van Japan \n -\n • Antarctica-kaart toegevoegd +\n • Antarctica-kaart toegevoegd \n -\n" +\n Wat is er nieuw Voor sneeuwscooter, rijden met speciale wegen en tracks. Stel aantal werkdagen in om door te gaan @@ -3837,7 +3837,7 @@ Uitloggen gelukt Bestand is reeds geïmporteerd in OsmAnd Lokale kaarten - Aangenaam + Voorziening Speciaal Transport Onderhoud @@ -3856,7 +3856,7 @@ U moet inloggen om wijzigingen te uploaden. \n \nU kunt inloggen met de veilige OAuth-methode of uw loginnaam en wachtwoord gebruiken. - Inloggen met gebruikersnaam en wachtwoord. + Inloggen met gebruikersnaam en wachtwoord Account Gebruikersnaam Abonnement beheren @@ -3993,4 +3993,9 @@ Waypoints verwijderen Kopiëren naar Markeervlaggetjes Kopiëren naar Favorieten + Opladen + Opladen voltooid + Aan het opladen %1$d van %2$d + Opgeladen %1$d van %2$d + Selecteer de op te laden wijzigingen \ No newline at end of file From 816ed5722b2ec8c629dadb85eb150da80a7f4321 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 1 Feb 2021 19:49:06 +0100 Subject: [PATCH 038/398] Don't allow empty words --- .../java/net/osmand/binary/BinaryMapPoiReaderAdapter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java index 1b959a8cf9..fd6fe7bce9 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -381,7 +381,12 @@ public class BinaryMapPoiReaderAdapter { int length = readInt(); int oldLimit = codedIS.pushLimit(length); offset = codedIS.getTotalBytesRead(); - List queries = Arrays.asList(query.split(" ")); + List queries = new ArrayList<>(); + for (String word : query.split(" ")) { + if (word.trim().length() > 0) { + queries.add(word.trim()); + } + } TIntArrayList charsList = new TIntArrayList(queries.size()); listOffsets = new ArrayList(queries.size()); while(listOffsets.size() < queries.size()) { From c517b730e4beeaa07dad52695bb72a7aaafaf6b8 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 1 Feb 2021 23:40:35 +0200 Subject: [PATCH 039/398] Fix piste type --- .../main/java/net/osmand/router/RouteStatisticsHelper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteStatisticsHelper.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteStatisticsHelper.java index 4fe500de2b..43022a1a37 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteStatisticsHelper.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteStatisticsHelper.java @@ -367,8 +367,9 @@ public class RouteStatisticsHelper { RouteDataObject obj = segment.obj; for (int type : obj.getTypes()) { BinaryMapRouteReaderAdapter.RouteTypeRule tp = obj.region.quickGetEncodingRule(type); - if (tp.getTag().equals("highway") || tp.getTag().equals("route") || - tp.getTag().equals("railway") || tp.getTag().equals("aeroway") || tp.getTag().equals("aerialway")) { + if (tp.getTag().equals("highway") || tp.getTag().equals("route") + || tp.getTag().equals("railway") || tp.getTag().equals("aeroway") + || tp.getTag().equals("aerialway") || tp.getTag().equals("piste:type")) { if (!mainTagAdded) { req.setStringFilter(rrs.PROPS.R_TAG, tp.getTag()); req.setStringFilter(rrs.PROPS.R_VALUE, tp.getValue()); From 56e8f85c04510ea75fb8ab242860b18a9533d639 Mon Sep 17 00:00:00 2001 From: nnngrach Date: Tue, 2 Feb 2021 04:02:43 +0300 Subject: [PATCH 040/398] add default profile name for unnamed or missing improted profiles --- .../settings/backend/backup/ProfileSettingsItem.java | 3 ++- .../settings/fragments/DuplicatesSettingsAdapter.java | 7 ++++++- .../plus/settings/fragments/ExportItemsBottomSheet.java | 9 ++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java index b0bfd5be61..5590d306c6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java @@ -26,6 +26,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; public class ProfileSettingsItem extends OsmandSettingsItem { @@ -124,7 +125,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem { if (Algorithms.isEmpty(modeBean.userProfileName)) { ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); if (appMode != null) { - modeBean.userProfileName = app.getString(appMode.getNameKeyResource()); + modeBean.userProfileName = appMode.toHumanString(); } } int number = 0; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 5d9e3af28a..7e7e52f340 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -33,6 +33,7 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.util.Algorithms; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import java.io.File; @@ -91,7 +92,11 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter Date: Tue, 2 Feb 2021 04:03:51 +0300 Subject: [PATCH 041/398] Revert "add default profile name for unnamed or missing improted profiles" This reverts commit 56e8f85c04510ea75fb8ab242860b18a9533d639. --- .../settings/backend/backup/ProfileSettingsItem.java | 3 +-- .../settings/fragments/DuplicatesSettingsAdapter.java | 7 +------ .../plus/settings/fragments/ExportItemsBottomSheet.java | 9 +-------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java index 5590d306c6..b0bfd5be61 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java @@ -26,7 +26,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; public class ProfileSettingsItem extends OsmandSettingsItem { @@ -125,7 +124,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem { if (Algorithms.isEmpty(modeBean.userProfileName)) { ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); if (appMode != null) { - modeBean.userProfileName = appMode.toHumanString(); + modeBean.userProfileName = app.getString(appMode.getNameKeyResource()); } } int number = 0; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 7e7e52f340..5d9e3af28a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -33,7 +33,6 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.util.Algorithms; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import java.io.File; @@ -92,11 +91,7 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter Date: Tue, 2 Feb 2021 04:04:07 +0300 Subject: [PATCH 042/398] Revert "Merge branch 'master' of https://github.com/osmandapp/Osmand" This reverts commit c2a88ef523a02b5708f68c350f0c407bf038a5fc, reversing changes made to 56e8f85c04510ea75fb8ab242860b18a9533d639. --- OsmAnd/res/values-fi/phrases.xml | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/values-fi/phrases.xml b/OsmAnd/res/values-fi/phrases.xml index 6453253dd4..7751c5bb95 100644 --- a/OsmAnd/res/values-fi/phrases.xml +++ b/OsmAnd/res/values-fi/phrases.xml @@ -17,7 +17,7 @@ Bussipysäkki Trollibussin pysäkki Raitiovaunupysäkki - Piknik-paikka + Piknic paikka Merkittävä kivi Ankkurointipaikka Majakka/linjavalo @@ -311,8 +311,8 @@ Ei Visa Electron -kortteja Shekit Shekkejä ei hyväksytä - Visa Debit-kortit - Ei Visa Debit-kortteja + Visa Debit -kortit + Ei Visa Debit -kortteja Muut Muita maksutapoja ei hyväksytä Bancomat @@ -1139,28 +1139,28 @@ Ei MasterCard-kortteja Maestro-kortit Ei Maestro-kortteja - Ei American Express (AMEX)-kortteja - Ei Diners Club-kortteja + Ei American Express (AMEX) -kortteja + Ei Diners Club -kortteja Ei DKV-kortteja Ei UTA-kortteja Ei Efectivo-maksua Ei Girocard-kortteja Discover Card - Ei Discover Card-kortteja + Ei Discover Card -kortteja Ei Litecoinia Ei PIKEPASS-maksua Ei kryptovaluuttaa - Ei Routex-tankkauskortteja - Ei IC Stored Fare-kortteja + Ei Routex -tankkauskortteja + Ei IC Stored Fare -kortteja Ei JCB-kortteja Ei Laser-kortteja Ei Quick-kortteja Ei Eurowag-kortteja - Ei E-ZPass-maksua + Ei E-ZPass -maksua Ei Euroshell-tankkauskortteja Ei KITCard-maksua Ei Westfalen-kortteja - Ei V PAY-kortteja + Ei V PAY -kortteja Ei Dogecoinia Ei Cibus-kortteja Ei maksua tilisiirrolla @@ -1172,7 +1172,7 @@ Ei Minipay-maksua Ei MiniCash-maksua Ei Moneo-maksua - Ei Monedero 4B-maksua + Ei Monedero 4B -maksua Ei Monedero-maksua Ei BankAxess-maksua Ei Coinkite-maksua @@ -1182,20 +1182,20 @@ Ei tekstiviestimaksua Ei Oyster-kortteja Ei SUBE-kortteja - Ei Via Verde-maksua + Ei Via Verde -maksua Lounassetelit Ei lounasseteleitä Ei PayPal-maksua - Ei U-Key-maksua + Ei U-Key -maksua Poletit Ei poletteja Ei lahjakorttimaksua - Ei Golden Crown-kortteja + Ei Golden Crown -kortteja Ei PRO100-kortteja - Ei Union Card-kortteja + Ei Union Card -kortteja Ei MTS-Money -maksua - Ei Yandex.Money-maksua - Ei OV-Chipkaart-kortteja + Ei Yandex.Money -maksua + Ei OV-Chipkaart -kortteja Tapahtumapaikka Vain kasvisruokaa Kasvisruokaa @@ -1245,9 +1245,9 @@ Sisätilat Ulkona Ei wc-tiloja - Inva-WC: kyllä - Inva-WC: ei - Asiakas-WC + Inva-wc: kyllä + Inva-wc: ei + Asiakas-wc WC:n käyttö: yhteisö WC:n käyttö: julkinen Vauvan vaihtopöytä @@ -1522,4 +1522,4 @@ Vieras talo Majapaikka Vuoristorata - + \ No newline at end of file From a0d57b39cf8dbc4bb7ca4020043c8e887b930669 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 2 Feb 2021 13:28:19 +0200 Subject: [PATCH 043/398] hillshade/terrain toggle fix --- OsmAnd/res/layout/center_button_container.xml | 2 +- OsmAnd/res/layout/custom_radio_buttons.xml | 5 +++-- OsmAnd/res/layout/left_button_container.xml | 2 +- OsmAnd/res/layout/right_button_container.xml | 2 +- OsmAnd/src/net/osmand/plus/UiUtilities.java | 21 +++++++++++-------- .../plus/myplaces/GPXItemPagerAdapter.java | 6 +++++- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/layout/center_button_container.xml b/OsmAnd/res/layout/center_button_container.xml index 99858650dc..05fa83eae0 100644 --- a/OsmAnd/res/layout/center_button_container.xml +++ b/OsmAnd/res/layout/center_button_container.xml @@ -8,7 +8,7 @@ android:layout_weight="1"> @@ -22,7 +22,8 @@ layout="@layout/center_button_container" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_weight="1" /> + android:layout_weight="1" + android:visibility="gone" /> Date: Tue, 2 Feb 2021 13:43:45 +0100 Subject: [PATCH 044/398] clean up setup files --- .gitignore | 3 ++- plugins/Osmand-Nautical/.classpath | 9 ------- plugins/Osmand-Nautical/.project | 33 ------------------------- plugins/Osmand-ParkingPlugin/.classpath | 9 ------- plugins/Osmand-ParkingPlugin/.project | 33 ------------------------- plugins/Osmand-SRTMPlugin/.classpath | 9 ------- plugins/Osmand-SRTMPlugin/.project | 33 ------------------------- plugins/Osmand-Skimaps/.classpath | 9 ------- plugins/Osmand-Skimaps/.project | 33 ------------------------- 9 files changed, 2 insertions(+), 169 deletions(-) delete mode 100644 plugins/Osmand-Nautical/.classpath delete mode 100644 plugins/Osmand-Nautical/.project delete mode 100644 plugins/Osmand-ParkingPlugin/.classpath delete mode 100644 plugins/Osmand-ParkingPlugin/.project delete mode 100644 plugins/Osmand-SRTMPlugin/.classpath delete mode 100644 plugins/Osmand-SRTMPlugin/.project delete mode 100644 plugins/Osmand-Skimaps/.classpath delete mode 100644 plugins/Osmand-Skimaps/.project diff --git a/.gitignore b/.gitignore index 33e746a3d6..7386d5e61e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,8 @@ OsmAndCore_*.aar *.iml .settings .idea -.project +**/.project +**/.classpath out/ # Huawei diff --git a/plugins/Osmand-Nautical/.classpath b/plugins/Osmand-Nautical/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-Nautical/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-Nautical/.project b/plugins/Osmand-Nautical/.project deleted file mode 100644 index 69d5b60769..0000000000 --- a/plugins/Osmand-Nautical/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-Nautical - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-ParkingPlugin/.classpath b/plugins/Osmand-ParkingPlugin/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-ParkingPlugin/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-ParkingPlugin/.project b/plugins/Osmand-ParkingPlugin/.project deleted file mode 100644 index 1c708327e5..0000000000 --- a/plugins/Osmand-ParkingPlugin/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-ParkingPlugin - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-SRTMPlugin/.classpath b/plugins/Osmand-SRTMPlugin/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-SRTMPlugin/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-SRTMPlugin/.project b/plugins/Osmand-SRTMPlugin/.project deleted file mode 100644 index 6c3b83059d..0000000000 --- a/plugins/Osmand-SRTMPlugin/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-SRTMPlugin - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-Skimaps/.classpath b/plugins/Osmand-Skimaps/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-Skimaps/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-Skimaps/.project b/plugins/Osmand-Skimaps/.project deleted file mode 100644 index 852dfb35a5..0000000000 --- a/plugins/Osmand-Skimaps/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-SkiMaps - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - From bb9a05766593a4f05f702801944be496ed7ba484 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 2 Feb 2021 15:40:48 +0100 Subject: [PATCH 045/398] Add route activity type class --- .../net/osmand/osm/RouteActivityType.java | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java new file mode 100644 index 0000000000..28c9b11551 --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -0,0 +1,218 @@ +package net.osmand.osm; + +public enum RouteActivityType { + WATER("Water", "yellow"), WINTER("Winter", "yellow"), SNOWMOBILE("Snowmobile", "yellow"), RIDING("Riding", "yellow"), RACING("Racing", "yellow"), + MOUNTAINBIKE("Mountainbike", "blue"), CYCLING("Cycling", "blue"), + HIKING("Hiking", "orange"), RUNNING("Running", "orange"), WALKING("Walking", "orange"), + OFFROAD("Off-road", "yellow"), + MOTORBIKE("Motorbike", "green"), CAR("Car", "green"); + // less specific bottom order + + String name; + String color; + + private RouteActivityType(String nm, String clr) { + this.name = nm; + this.color = clr; + } + + public String getName() { + return name; + } + + public String getColor() { + return color; + } + + public static RouteActivityType getTypeFromTags(String[] tags) { + RouteActivityType activityType = null; + for (String tg : tags) { + RouteActivityType rat = RouteActivityType.convertFromOsmGPXTag(tg); + if (rat != null) { + if (activityType == null || activityType.ordinal() > rat.ordinal()) { + activityType = rat; + } + } + } + return activityType; + } + + public static RouteActivityType convertFromOsmGPXTag(String tg) { + String t = tg.toLowerCase(); + if ("mountain hiking".equalsIgnoreCase(t)) { + return HIKING; + } + if ("motorcar".equalsIgnoreCase(t)) { + return CAR; + } + if ("laufen".equalsIgnoreCase(t)) { + return RUNNING; + } + if ("pedestrian".equalsIgnoreCase(t)) { + return WALKING; + } + switch (t) { + case "mountainbiking": + case "mtb": + case "mountainbike": + case "mountain bike": + case "mountain biking": + case "mountbarker": + case "mtb-tour": + case "ciclismo-mtb-gravel": + case "vtt": + case "btt": + case "vth": + case "mtb ride": + return MOUNTAINBIKE; + case "hiking": + case "route=hiking": + case "mountain hiking": + case "hiking trail": + case "wandern": + case "hike": + case "randonnée": + case "trekking": + case "climbing": + return HIKING; + case "bike": + case "biking": + case "bicycling": + case "bicycle": + case "cycling": + case "cycle": + case "cycleway": + case "cykel": + case "handcycle": + case "cyclotourisme": + case "route=bicycle": + case "cyclotourism": + case "fietsen": + case "вело": + case "велосипед": + case "rower": + case "trasa rowerem": + case "vélo": + case "velo": + case "radtour": + case "bici": + case "fiets": + case "fahrrad": + case "ncn": + case "icn": + case "lcn": + case "network=ncn": + case "network=icn": + case "network=lcn": + return CYCLING; + case "car": + case "motorcar": + case "by car": + case "auto": + case "автомобиль": + case "automobile": + case "autós": + case "driving": + case "drive": + case "van": + case "авто": + case "на автомобиле": + case "bus": + case "truck": + case "taxi": + return CAR; + case "running": + case "run": + case "rungis": + case "trail running": + case "trailrunning": + case "бег": + case "laufen": + case "langlauf": + case "lauf": + case "course": + case "jogging": + case "fitotrack": + return RUNNING; + case "wanderung": + case "walking": + case "walk": + case "nightwalk": + case "walkway": + case "пешком": + case "пеший": + case "pěšky": + case "marche": + case "pedestrian": + case "foot": + case "footing": + case "on_foot": + case "byfoot": + case "onfoot": + case "sightseeing": + case "geocaching": + case "etnanatura": + case "etna": + case "iwn": + case "lwn": + case "rwn": + case "network=iwn": + case "network=lwn": + case "network=rwn": + return WALKING; + case "ling-moto": + case "motorbiking": + case "motorcycle": + case "motorrad": + case "motorbike": + case "motor bike": + case "FVbike": + case "Motorrad": + return MOTORBIKE; + case "offroad": + case "off-road": + case "off road": + case "4x4": + case "terrain": + case "quad": + case "enduro": + case "feldwege": + case "feldweg": + return OFFROAD; + case "boat": + case "water": + case "boating": + case "kayak": + case "river": + case "lake": + case "lakes": + case "canal": + return WATER; + case "ski": + case "skiing": + case "skating": + case "skitour": + case "winter": + case "wintersports": + case "snowboard": + case "лыжи": + case "лыжня": + case "nordic": + case "piste": + return WINTER; + case "snowmobile=designated": + case "snowmobile=permissive": + case "snowmobile=yes": + case "snowmobile": + return SNOWMOBILE; + case "ride": + case "horse": + case "horse trail": + return RIDING; + case "racing": + return RACING; + } + return null; + } + +} \ No newline at end of file From 055c681f4b62df4ac51333dcc6f2b62bc0af7201 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 2 Feb 2021 23:34:57 +0200 Subject: [PATCH 046/398] Add activity types --- .../net/osmand/osm/RouteActivityType.java | 50 +++++++++++++++---- OsmAnd/res/values/strings.xml | 13 +++++ .../explore/travelcards/TravelGpxCard.java | 21 +++++--- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index 28c9b11551..06471b933f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -1,29 +1,58 @@ package net.osmand.osm; public enum RouteActivityType { - WATER("Water", "yellow"), WINTER("Winter", "yellow"), SNOWMOBILE("Snowmobile", "yellow"), RIDING("Riding", "yellow"), RACING("Racing", "yellow"), - MOUNTAINBIKE("Mountainbike", "blue"), CYCLING("Cycling", "blue"), - HIKING("Hiking", "orange"), RUNNING("Running", "orange"), WALKING("Walking", "orange"), - OFFROAD("Off-road", "yellow"), - MOTORBIKE("Motorbike", "green"), CAR("Car", "green"); + WATER("Water", "yellow", "ic_action_motorboat", "activity_type_water"), + WINTER("Winter", "yellow", "ic_action_skiing", "activity_type_winter"), + SNOWMOBILE("Snowmobile", "yellow", "ic_action_snowmobile", "activity_type_snowmobile"), + RIDING("Riding", "yellow", "ic_action_horse", "activity_type_riding"), + RACING("Racing", "yellow", "ic_action_point_destination", "activity_type_racing"), + MOUNTAINBIKE("Mountainbike", "blue", "ic_action_bicycle_dark", "activity_type_mountainbike"), + CYCLING("Cycling", "blue", "ic_action_bicycle_dark", "activity_type_cycling"), + HIKING("Hiking", "orange", "ic_action_trekking_dark", "activity_type_hiking"), + RUNNING("Running", "orange", "ic_action_pedestrian_dark", "activity_type_running"), + WALKING("Walking", "orange", "ic_action_pedestrian_dark", "activity_type_walking"), + OFFROAD("Off-road", "yellow", "ic_action_offroad", "activity_type_offroad"), + MOTORBIKE("Motorbike", "green", "ic_action_motorcycle_dark", "activity_type_motorbike"), + CAR("Car", "green", "ic_action_car_dark", "activity_type_car"); // less specific bottom order String name; String color; + String icon; + String title; - private RouteActivityType(String nm, String clr) { + RouteActivityType(String nm, String clr, String icon, String title) { this.name = nm; this.color = clr; + this.icon = icon; + this.title = title; } - + public String getName() { return name; } - + public String getColor() { return color; } - + + public String getIcon() { + return icon; + } + + public String getTitle() { + return title; + } + + public static RouteActivityType getTypeFromName(String name) { + for (RouteActivityType rat : values()) { + if (rat.name().equalsIgnoreCase(name)) { + return rat; + } + } + return null; + } + public static RouteActivityType getTypeFromTags(String[] tags) { RouteActivityType activityType = null; for (String tg : tags) { @@ -36,7 +65,7 @@ public enum RouteActivityType { } return activityType; } - + public static RouteActivityType convertFromOsmGPXTag(String tg) { String t = tg.toLowerCase(); if ("mountain hiking".equalsIgnoreCase(t)) { @@ -214,5 +243,4 @@ public enum RouteActivityType { } return null; } - } \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 1d23e9db07..f17e06d46f 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,19 @@ --> + Car + Motorbike + Off-road + Walking + Running + Hiking + Cycling + Mountainbike + Racing + Riding + Snowmobile + Winter + Water Hillshade / Slope / Contour lines Select edits for upload Uploaded %1$d of %2$d diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 3677da0f41..c602f02a03 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -9,14 +9,13 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; +import net.osmand.osm.RouteActivityType; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.profiles.ProfileIcons; import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.wikivoyage.data.TravelGpx; import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; -import net.osmand.util.Algorithms; import java.io.File; @@ -44,10 +43,10 @@ public class TravelGpxCard extends BaseTravelCard { holder.title.setText(article.getTitle()); holder.userIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_user_account_16)); holder.user.setText(article.user); - if (!Algorithms.isEmpty(article.activityType)) { - ProfileIcons profileRes = ProfileIcons.valueOf(article.activityType.toUpperCase()); - holder.activityTypeIcon.setImageDrawable(getActiveIcon(profileRes.getResId())); - holder.activityType.setText(profileRes.getTitleId()); + RouteActivityType activityType = RouteActivityType.getTypeFromName(article.activityType); + if (activityType != null) { + holder.activityTypeIcon.setImageDrawable(getActivityTypeIcon(activityType)); + holder.activityType.setText(getActivityTypeName(activityType)); holder.activityTypeLabel.setVisibility(View.VISIBLE); } holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); @@ -72,6 +71,16 @@ public class TravelGpxCard extends BaseTravelCard { } } + private Drawable getActivityTypeIcon(RouteActivityType activityType) { + int iconId = app.getResources().getIdentifier(activityType.getIcon(), "drawable", app.getPackageName()); + return getActiveIcon(iconId > 0 ? iconId : R.drawable.ic_action_route_distance); + } + + private int getActivityTypeName(RouteActivityType activityType) { + int titleId = app.getResources().getIdentifier(activityType.getTitle(), "string", app.getPackageName()); + return titleId > 0 ? titleId : R.string.layer_route; + } + private void updateSaveButton(final TravelGpxVH holder) { if (article != null) { final TravelLocalDataHelper helper = app.getTravelHelper().getBookmarksHelper(); From 0672f140aff60eb727954001436c345daaf6fa61 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 3 Feb 2021 11:24:22 +0200 Subject: [PATCH 047/398] Check resource --- .../explore/travelcards/TravelGpxCard.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index c602f02a03..69772bac1c 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -5,7 +5,9 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; @@ -45,9 +47,13 @@ public class TravelGpxCard extends BaseTravelCard { holder.user.setText(article.user); RouteActivityType activityType = RouteActivityType.getTypeFromName(article.activityType); if (activityType != null) { - holder.activityTypeIcon.setImageDrawable(getActivityTypeIcon(activityType)); - holder.activityType.setText(getActivityTypeName(activityType)); - holder.activityTypeLabel.setVisibility(View.VISIBLE); + int iconId = getActivityTypeIcon(activityType); + int titleId = getActivityTypeTitle(activityType); + if (iconId > 0 && titleId > 0) { + holder.activityTypeIcon.setImageDrawable(getActiveIcon(iconId)); + holder.activityType.setText(titleId); + holder.activityTypeLabel.setVisibility(View.VISIBLE); + } } holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); @@ -71,14 +77,14 @@ public class TravelGpxCard extends BaseTravelCard { } } - private Drawable getActivityTypeIcon(RouteActivityType activityType) { - int iconId = app.getResources().getIdentifier(activityType.getIcon(), "drawable", app.getPackageName()); - return getActiveIcon(iconId > 0 ? iconId : R.drawable.ic_action_route_distance); + @DrawableRes + private int getActivityTypeIcon(RouteActivityType activityType) { + return app.getResources().getIdentifier(activityType.getIcon(), "drawable", app.getPackageName()); } - private int getActivityTypeName(RouteActivityType activityType) { - int titleId = app.getResources().getIdentifier(activityType.getTitle(), "string", app.getPackageName()); - return titleId > 0 ? titleId : R.string.layer_route; + @StringRes + private int getActivityTypeTitle(RouteActivityType activityType) { + return app.getResources().getIdentifier(activityType.getTitle(), "string", app.getPackageName()); } private void updateSaveButton(final TravelGpxVH holder) { From 6b92f064ecd69edc0fa0988df9aaca2086c1de9a Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 2 Feb 2021 10:31:08 +0000 Subject: [PATCH 048/398] Translated using Weblate (Chinese (Simplified)) Currently translated at 67.7% (2476 of 3656 strings) --- OsmAnd/res/values-zh-rCN/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 6b188df900..c21fc6f733 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -1219,7 +1219,7 @@ 显示缩放等级:%1$s 在线地图 仅道路 - 设备内存 + 设备储存 初次使用 常见问题、最近修改和其它内容。 常见问题 From 70e8472c6b9447e12c679b91e24675285e0d0fcc Mon Sep 17 00:00:00 2001 From: max-klaus Date: Wed, 3 Feb 2021 14:44:21 +0300 Subject: [PATCH 049/398] Added annotations --- OsmAnd/src/net/osmand/plus/OsmandApplication.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 6b9aa4d0a4..b794a5bc0a 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -24,6 +24,8 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDelegate; import androidx.multidex.MultiDex; @@ -910,6 +912,7 @@ public class OsmandApplication extends MultiDexApplication { return customRoutingConfigs.get(key); } + @NonNull public RoutingConfiguration.Builder getRoutingConfigForMode(ApplicationMode mode) { RoutingConfiguration.Builder builder = null; String routingProfileKey = mode.getRoutingProfile(); @@ -923,11 +926,13 @@ public class OsmandApplication extends MultiDexApplication { return builder != null ? builder : getDefaultRoutingConfig(); } + @Nullable public GeneralRouter getRouter(ApplicationMode mode) { Builder builder = getRoutingConfigForMode(mode); return getRouter(builder, mode); } + @Nullable public GeneralRouter getRouter(Builder builder, ApplicationMode am) { GeneralRouter router = builder.getRouter(am.getRoutingProfile()); if (router == null && am.getParent() != null) { From 93a642d3225e452761f9f5c507a6f2ed97d97f26 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 3 Feb 2021 15:16:07 +0200 Subject: [PATCH 050/398] Select segment bottom sheet --- .../layout/bottom_sheet_select_segment.xml | 70 +++++++++ OsmAnd/res/layout/gpx_segment_list_item.xml | 96 ++++++++++++ OsmAnd/res/values/strings.xml | 3 + .../helpers/TrackSelectSegmentAdapter.java | 144 ++++++++++++++++++ .../track/TrackSelectSegmentBottomSheet.java | 74 +++++++++ 5 files changed, 387 insertions(+) create mode 100644 OsmAnd/res/layout/bottom_sheet_select_segment.xml create mode 100644 OsmAnd/res/layout/gpx_segment_list_item.xml create mode 100644 OsmAnd/src/net/osmand/plus/helpers/TrackSelectSegmentAdapter.java create mode 100644 OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_select_segment.xml b/OsmAnd/res/layout/bottom_sheet_select_segment.xml new file mode 100644 index 0000000000..de758bc182 --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_select_segment.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/gpx_segment_list_item.xml b/OsmAnd/res/layout/gpx_segment_list_item.xml new file mode 100644 index 0000000000..f591d86e50 --- /dev/null +++ b/OsmAnd/res/layout/gpx_segment_list_item.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 2c3358dda4..bde3e4040a 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -14,6 +14,9 @@ Select edits for upload Uploaded %1$d of %2$d + Segment %1$d + %1$s contains more than one segment, you need to select the needed part for the navigation. + Select segments Uploading %1$d of %2$d Upload completed Uploading diff --git a/OsmAnd/src/net/osmand/plus/helpers/TrackSelectSegmentAdapter.java b/OsmAnd/src/net/osmand/plus/helpers/TrackSelectSegmentAdapter.java new file mode 100644 index 0000000000..0ca79ab891 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/TrackSelectSegmentAdapter.java @@ -0,0 +1,144 @@ +package net.osmand.plus.helpers; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.GPXUtilities.TrkSegment; +import net.osmand.GPXUtilities.WptPt; +import net.osmand.plus.GPXDatabase; +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.measurementtool.MeasurementEditingContext; +import net.osmand.util.MapUtils; + +import java.util.List; + +public class TrackSelectSegmentAdapter extends RecyclerView.Adapter { + private final OsmandApplication app; + private final LayoutInflater themedInflater; + private final UiUtilities iconsCache; + private GpxTrackAdapter.OnItemClickListener onItemClickListener; + + private final List segments; + + public TrackSelectSegmentAdapter(Context ctx, List segments) { + app = (OsmandApplication) ctx.getApplicationContext(); + themedInflater = UiUtilities.getInflater(ctx, app.getDaynightHelper().isNightModeForMapControls()); + iconsCache = app.getUIUtilities(); + this.segments = segments; + } + + @NonNull + @Override + public TrackSelectSegmentAdapter.TrackViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = themedInflater.inflate(R.layout.gpx_segment_list_item, parent, false); + ImageView distanceIcon = view.findViewById(R.id.distance_icon); + distanceIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval)); + ImageView timeIcon = view.findViewById(R.id.time_icon); + timeIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_moving_16)); + return new TrackSelectSegmentAdapter.TrackViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull final TrackSelectSegmentAdapter.TrackViewHolder holder, final int position) { + holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval)); + + TrkSegment segment = segments.get(position); + + String segmentTitle = app.getResources().getString(R.string.segments_count, position + 1); + holder.name.setText(segmentTitle); + + double distance = getDistance(segment); + long time = getSegmentTime(segment); + holder.time.setText(OsmAndFormatter.getFormattedDurationShort((int) (time / 1000))); + holder.distance.setText(OsmAndFormatter.getFormattedDistance((float) distance, app)); +// updateTrackSegmentInfoView(holder, info, gpxSegmentList, dataItem, app); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onItemClickListener != null) { + onItemClickListener.onItemClick(holder.getAdapterPosition()); + } + } + }); + } + + private long getSegmentTime(TrkSegment segment) { + long segmentTime; + long startTime = Long.MAX_VALUE; + long endTime = Long.MIN_VALUE; + for (int i = 0; i < segment.points.size(); i++) { + WptPt point = segment.points.get(i); + long time = point.time; + if (time != 0) { + startTime = Math.min(startTime, time); + endTime = Math.max(endTime, time); + } + } + segmentTime = endTime - startTime; + + return segmentTime; + } + + private double getDistance(TrkSegment segment) { + double distance = 0; + WptPt prevPoint = null; + for (int i = 0; i < segment.points.size(); i++) { + WptPt point = segment.points.get(i); + if (prevPoint != null) { + distance += MapUtils.getDistance(prevPoint.getLatitude(), prevPoint.getLongitude(), point.getLatitude(), point.getLongitude()); + } + prevPoint = point; + } + + return distance; + } + + @Override + public int getItemCount() { + return segments.size(); + } + + private void updateTrackSegmentInfoView(TrackSelectSegmentAdapter.TrackViewHolder holder, MeasurementEditingContext info, GpxSelectionHelper.SelectedGpxFile gpxSegmentList, + GPXDatabase.GpxDataItem dataItem, + OsmandApplication app) { + + } + + + public void setAdapterListener(GpxTrackAdapter.OnItemClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + } + + public interface OnItemClickListener { + + void onItemClick(int position); + + } + + static class TrackViewHolder extends RecyclerView.ViewHolder { + + ImageView icon; + TextView name; + TextView distance; + TextView time; + + TrackViewHolder(View itemView) { + super(itemView); + icon = itemView.findViewById(R.id.icon); + name = itemView.findViewById(R.id.name); + distance = itemView.findViewById(R.id.distance); + time = itemView.findViewById(R.id.time_interval); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java new file mode 100644 index 0000000000..199e30c1cd --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java @@ -0,0 +1,74 @@ +package net.osmand.plus.track; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.GPXUtilities.TrkSegment; +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.helpers.GpxTrackAdapter; +import net.osmand.plus.helpers.TrackSelectSegmentAdapter; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.util.Algorithms; + +import java.util.List; + +public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = TrackSelectSegmentBottomSheet.class.getSimpleName(); + protected TrackSelectSegmentAdapter adapterSegments; + private GpxSelectionHelper.SelectedGpxFile file; + + public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull GpxSelectionHelper.SelectedGpxFile file) { + if (!fragmentManager.isStateSaved()) { + TrackSelectSegmentBottomSheet fragment = new TrackSelectSegmentBottomSheet(); + fragment.file = file; + fragment.show(fragmentManager, TAG); + } + } + + @Override + public void createMenuItems(Bundle savedInstanceState) { + Context context = requireContext(); + + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View itemView = inflater.inflate(R.layout.bottom_sheet_select_segment, null, false); + String titleGpxTrack = Algorithms.getFileWithoutDirs(file.getGpxFile().path); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(getString(R.string.select_segments_description, titleGpxTrack)) + .setCustomView(itemView) + .create()); + + OsmandApplication app = getMyApplication(); + if (app == null) { + return; + } + TextViewEx titleGpxTrackView = itemView.findViewById(R.id.title_gpx_track); + titleGpxTrackView.setText(titleGpxTrack); + + final RecyclerView recyclerView = itemView.findViewById(R.id.gpx_segment_list); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setNestedScrollingEnabled(false); + List segments = file.getPointsToDisplay(); + adapterSegments = new TrackSelectSegmentAdapter(requireContext(), segments); + adapterSegments.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() { + @Override + public void onItemClick(int position) { + } + }); + recyclerView.setAdapter(adapterSegments); + + } +} From 5608f2de2a3db1085d17c9aa8105c4edebcca415 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 3 Feb 2021 15:45:38 +0200 Subject: [PATCH 051/398] Added image for Mapillary plugin --- .../drawable-xxhdpi/img_plugin_mapillary.webp | Bin 0 -> 26974 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 OsmAnd/res/drawable-xxhdpi/img_plugin_mapillary.webp diff --git a/OsmAnd/res/drawable-xxhdpi/img_plugin_mapillary.webp b/OsmAnd/res/drawable-xxhdpi/img_plugin_mapillary.webp new file mode 100644 index 0000000000000000000000000000000000000000..c7ac5d1d25f702b7fc8b8a19631fe2c10cbbabe3 GIT binary patch literal 26974 zcmY&7--Z?%1}SbZpzUZQDu5wr$(CjobU%XP-V#549!iP~)U$`(6>k|a= zpDo}a87_D43kKb$K4c%u`_Ek_L@ywBGCAJ*-=n*#_HI3n-C444J{8^%yiMNRK9sM} zU&EiQPm)_XAJ^;Ce%)UA;DZuD#Da&c9yIfWBfrA*#qKOk3@I2d%muHLZ1c3x{cS0T#i4! zueDdYi@tlmWQXz6eXidEJt7{@S9aguVouPmw|71czM7xv7rq;}dU)qLUcVc6yPvz? zaC>s5e1^YP-@CtC4|1Lm-f;W4slGjZzTcZ7anMden|SNP11i)+H=LipRtzpG6IxOqv=QgqT6eav0J-mMh89{=y!wY9Nt#J?u?l}(kS!KQscjWoa&ZCyV zK{tzN>0{ED!`P0R_TtMpqpL#dcIcTl>m3?l@ULJS1HC8bSDCPK(OQ3kS!0LgjKBFZ zX5^(V@6>b|7`VlS4o&Z(Ug%W&VjVgCXdLs6&u)+Ll6(h7|DWk`GS7ua-Prm#ax*of z>6dVMTb9EAHy`XE`>7*9ArwdSC}-hP$b@|ZT%KapqVPE*;DfrKdcRC^r@2gL2|ktK zIvhJuL}S6j;{-@GJ+*G;Ee@vsdHs!b0g=wKf4v0?#DCIAS;llP^CZu{>v*O2QZouw z01^K+$`U=TUbLK(k^|p}ZC(ah@CTUL?U;P zqryAZD^!I0pLM?2E09cB{*%A*^?wulg)r=F}Erd8F*s zQ52dv`A&C_~e#8UmB@n10ht%FNA zc+)1@vB(2h)*ky+X}Yx|N8!ajHrzv`V615zk4|D&r~d5JuRyQX;3wm6yXC`q2K54R z_0Kw_jym~-D_=*$);<$_G5@W|f9edy>&X-cI8c!f8ZSms6Ti3N zDGEusq0Hj;8aFUt#()XCSsG-DtTL)ZgP!utcZM(&@>4AO-}O>S-R(j1FNE?V^HDWP zm7y7Z8MId1<4o$LUj5vYemwxZD%@?zYc+34;fjaTq>u(swp{m8k{H>Jhq7OQyw^=8 zgKfM1#(?g2v0&AeI0BS3{LKlk2?}HdctYO+oQ6)WSfm|@S+~(^t%v@#2Xd(X%iu0m zHj7-5XSO;gu%4O6yD0}@*)(|au0Uxv`IAGAF{#Sc)vJIqbrh-}}M=hw}bCr*{>c$XjLMNvU0!h=De0P$~?q znmrKp0wQff`A1*nQnuMy0U~q$qwoyD6|_uaW46MSX#aR5Pq-&Us=o;!B0NFqLYTdr zV3wb&+I!ft?`DShz{kIIy-~ZvB$ORLwEAzVtgEl{(hj-6LZ*>n*Ia+tS%mTQyh-FP zEex|_^mWOI5wdDn{~015bd2(4Nb``p7SaEz;ROBeDbkmfWuhesY(ZO6)D$tUJx{uR zJ89mi$mzW8j0tb$t^t{~xGY#8n>OSpl0%+`#q0DV_$QQXa@Ya>?1tdtpQ{|lsX{($ zI`DArYDj-p={^XG$CFL>&#gjIln{eu)fZXsMGM92x28-fz^$d?ze#0;M{;~7UCL|p z&5WNy=WaYWB&!wikoJ>mSW4cfwe`} zx%K7l`tU%6ztuLPsCI?JKotWq3;8*vr~D6Ljc`APSoDsy;kA{HzPvIK-PUT7vE9g* z>!s&94yc!g0{0F$eB({L=Hw|Vg?bz8@)=Z1rw1Eg$^DV*F6s80BvTjOTUPVIhSh*C zKY8#B`43vnKZYGtx8`raQM`&d31^%vAU|_}`-kGXc9F%@1`TuX$tTcFN!2db8H6Bq zxryNT4h$7p7NaP_s!J}(v<4fUJzc3dK%{yECf*O=acE$9D+d@vuF{jl{r@XwFx-t- zf1e{NS;QEqKYx~j`L)nplJYMRGa#=Yl1`D{#9IIA+{Y}Gu@|;8Je3i)yu*dPfXs8U zhI0gRhfjq)iL?jS5wr_U&YGbCGO0$8`Xwgko|@(64f*PVsn{HaDEuGUY*d;)`B95( zn=Q)?=W9FQAFTMvJvL7nYftJNSy%Bh6l$&e0(K<$0s|!Ny587f%i4AqTQ2^|AF26&Db=G9GYLC5D5&%T{hGYd?{ z(-_>59EplTUV5QYLW}VPGEXhJJ>t)D8T(qwVkUY`fHs%!`V&U{N3<=CJM|mSG|-0m zH=(NoF`RBV1Pn`96o1Rr8b_8!K3bhtd(jd*KdH{g7|DqNPvgXBcP^lK3n4=bP`pKv zf^Y88#s4JN(!?`*>&sIL*ZoP0ed|M@pEWkLMd1V3al)IUJpr$Qu7 zeU(BPO&j*`2x6<1tko?44TTdnkxq>#t36Ljd1De-ugP~Bp~NESb5-h+qPAc|B*t0K zGc!Yy1vT2TV>U2>zE5Zz@j&{-{fKaqv_YoJ>H1?%gCb;KbEE7ZKcclMG}yP=;poz@ z!YiLibfI56xa@EpD|AqT11}z#rE;B8FEYuCR?iuw;gG7BahQC#cMJ|0PV*lzuC0^9 zVL^AoedQ|UEh*!asJf*B&3v)F5G67pR8D0$DckMI^1JSY(pNW&=2%pD@ig=IjK|0% zU;;aZL_6?O7uo*yq-qJOEfm}HR<>gO4_}m z>`3$@ny>~F@%*4W^IlTz8BuedAe7#dfLkuun`9_p9cBL?*5dJ8&o|x%Hsbgc)T)Vm zwqLl+Od!*6L%bN@yI825DH-2G2A>uRgwl5Yuc7;uIai7bGBxc=QVF`jj~58U#*}0} znOm6Tk0tt*TbhtHKNk9kXycRUH_0LzHjYrN*Fa2w_45|-*5tv(O}j?^>65=N{eSW) z5X#YYOQ5FV>S!E$VMk$eO!=?6{zrHJ!e=((fg3Gg3WQ(Rj3g&omO!ubtt=hd1(;<| zl6(P@ri+U=pZQdrC$WV-ALK0)4GUrBXK9E3Jby1t@1R&h=e+`4%Zm!Gm5*?hOK8_W za{e2~p=N+=P*$%2>`7dlq0i&s{}@s47;(2BQC`!A97!l!`YHn{8oV`sZnD5t3<^xl z8g_y+=c9Blv*$T5y_>epeW^Qtpu;#$TH>`=@sntCF8{}`1&cngQvG9a$rh`0B&Fua z%)2LCn7s{JWVtBgS+I6~j=@J2_U6)foT9MAyB_vO>&;$U92P97ZuF;jod9bykUv*D z{O;e3NuSt?v?3{tJ<{%N)H&iz?`GIoe2rGRQZ*#K9{*PAan$tkb=6V#NsUcST^Pu? zk1onrRH#YawiK+h+9CPTb!ao(I?6M1UpX!-Iim0RR0;MW00({Mi_JxD+ALaLy%qL2 z!>N^-uSvwHJswgc37^OHZUUk7Y}RGb zzH}Krky?gyao=;YBHXEdsalfB0LE=EoZdPAD$KrWt}D<|`le2H2HgXd;8dNkV!f$D zIXJjxmuH4Oh8N!?Z^5@AJpl!`@zxP-KsZcA{7Q50po0Djv{AI4WXeM2xc03x`O8r-KlWy=HzJvQYI01n>$nNSNLyGeZW%;O_o1dG#iGLw5&P-_$w-$2b$Pkxs*B zJ_6V4g>lBj|3J;%B%adokDZt|x(9x?=2S3a7Ea?=`(Vb=|MS}38QZD}=f>Q`@)4;t zMvIdMW#I7S8s{5I&m zsp~|2UirIrbD*2mXIY@i4B~HS0RGKFUBv}d?Kvy;@PU}s7(uiTQNJvRqrrEbVU=1h zc>o91EWgZGH?oYC_0aE*?7->KVhTVRn8|z8INb$eK$$Ofieytf#2`64Gv?ZOz zHKoFmAFCUqwieh#_`6q#F_FwP?Q0Y-^n&!hGCns~)avka^Wwt z@cIJ2zSa2v$bLxaMZ70Z7E9P26ur9f&Nj12$G}9J_Byf1o%{IKI!eaJKA%r;AJ*NA zR0h@+LDiX(&o@Q<>=TH~U!b%?sakj0KiKwh~WI-Cl1Jd zwHnO`p3fABBpLDFarF(LAZIf^0KiiYSPWcTz)8x04 zgF@7ROdP@*By$WJQVx4(glMDB+6-qEZS?``=EkNeChHBUhi4?e9icWL>5nLH@V#Mz z9+pG*M~U=S0hk24by0RH01y!hJBJO+&2PehS03+2njz|KaJ%a! zh=XX0%r>K-fo{2w0ssqO)?$hs#7Z$D7f2kv1qXilfZIC!q7<1hBVbD-`93kl#Gd0P zuX+>yhJnCb38#9hB$^iChM^)WbT}wustMKlErtk87(OUvdYHtZ`{)V)j<1{DI7w7t zC9vv>xy*u>-v6=~ApV{tH}&Uq-;$|sI}%zYsL;n|LxYv7ZLBnX=!(R>7C?~6ENN|E z@EyN!8b<~Hz**zBI(GM6(A-D42}O-^GjlC>PZ2|d>Mop~p784bz~kjb*3s(uW$c|h zi1<@upbIj{Tnu~JWIAhJ#w(ENMc^K|vS62kx-tQG^|XI<{c@&zhly*1rvZ+ZD%}?< z7D8ifRzmyiB%9*~v2eGklL34Bg|_)LN>qZFWhHwpMi_gQtqPeIL!gSm;d(y~Aw_^1 zKfzU)cSb~B?0lCTX_6w9Bt@}bre*I;e{XzTN461^OetDAi*Uk zB%f-9?@oVVgePL(d`LO*Pp}pax53F2oCD#sghzYY9`og}s(z6> z+SPs$=(dLj+4ipV=04E8^-1;Keo+6%={nehrYvp&O&rbg*M$2`i4z>L6i1GM;P0W%#dK16uPcbwF!LcTRiFs|1-PQmc8+~Yq3 zB7DZTl@3`@oL?u3FTFhtHNe}7CQ-CwUeR}&c!9cGGwpz$d6X7HhrS9H0 zGkw)?56iuVXjs-L<4li)sCRq;!VRebD*{xvxirD6f1Cxayx-}ZHtci}K+_sFeOvfO zh?7n2GD`BJOZ9^s8V{AD?dHba&YMfkH8Oh*Y8oj^>8z<^k!4t8NWqfLf74~8FI^Yq z^img@=X-GvGaiY&7ABZL;zydT2umLZC$uuP$4bZL#$B#r(wjWHzVcMu-{~yyae~d7 zsmXi&F5&8P6#PbgVD}x2r1n;&@+AGC`MFYZLa3hJ97Zm;H5MCvy4f-;IASB{`JzVB z7!0cIrKeoZdg6u?S%VEvPQVj}-?6t*gbj;vD!_JR%q7qLv*NCy%Ld&21G=U9H%R(c zH{vdLtyvJ2QxZ1OvdGZR95M>prkz#Q){1}ct4I|;Chq;izMnVx6YDXB^6(yF1mybQ z&(3D z^|FTH1fA!R1TEC*6%8};FMI^ZO~8z!KJKn}Q;NVAOT}lH=!TOJNS5=5YOYY%QE~vF%)*~T9kD16X-7wy42#z(a(PDS*YuA} zw&8zN%wxn|a2WXw6(D z$Q$b2BbdCvs8U`IYomWQgmPQ~@mN9#erSxjgrQZ&{}5&lA#*@?Hmy8$PgivR9^aZw zilgE*f(A9u8&5(o@ip7W-h^GP_68GBzKvwTcUrD0PqK*G`nF`HOzUJuHd1WBZyoKD zw>d7D#x=9Wm}KJbcaAO)KSDi9j`X|D;kAsF!nO-%$PBB5-=uQj0*%``sW_l~FRKgi zDuAZ)^vp0yYS)988%#`>%0CbSG)j>UkUR@=n`DT$Aq4#B6lHfr|5DH3pg8!z)F$VT zSV0zZR+Vi)0Np$e6F(#Tb4Mm2^;}og6^VCEOx^vVaYs#2Mt*iW*NMz5%^6lIg&?0X zCo>Qcfns6`Dg6<3P|p*^iuSujCku5Ag`_8H)Tm7Oc=A@<^Tc)wOyBPpoq=IZZVJq0 z6q(e~^HbKC-jIXHj_a$_jgFJZ*`N?YGu2?zgF*GndAz8OhGm&1_(wLL>aX)<(^Knr zSvcEbZI1dTjKb*DY$Fh|4y-Wr#MQ;!&yt==Q$Cm=k)t_Ws7$V1FVZBSl`xt&9*^@- zU(mzr`VJ&JDC%ulomNNOxRCbCL8_~Jl-iP)+1A=(Q%{1)ZS)Y(;dgA)@GFhPLM9?u z+6(YvZpbfFIryHD{Bn^w2Ep&Csxr^0(X-4qgwyjHBR&939|gHdA^@;kWx3gOJ(qEe zHJ}w3;5*WzL>)8B#DB)N03jzu#r;cGCcQiw%{s*`tr{76;x?d>b%EvbB=XDd1L}AM z$be#Z0DkApUO^~iwN3z%)|*40s-=hP#CTLW@21RQ0gHOR0DF^02187G@bk)sd5n%? zI)97h`cF03mHtv*nFAI!YgVJBy$^>=d2eg~_i$v1xX)1xF8c>kgM#G5rb(wDjD)Ot=5 zn7__0LD|R26M5Fz^;-P+rh@R*b|h~8rAn2`VH1tvwXC?Wzlp-!S2Bn<)71QWo{X64 zA$Q&x7`FGZ^mK^3e-e0E35KI6YboTZc~@2I4bu!M8${wmT6+V;K)ys2BIyadeTmPM z1|L&Lm9%_GR^YI!xRQ!0lN+kROrh1fNHqG!u2NT8jg-q~&tEVi1Ui-vcoHRQU$<+5`G8{qU7y8ND zc~n86F!=HtCjBP1{F+}BHumU+VA4T{0Lw|3v@S%vexeK=>uKyX;I>j(mwVt5C>jEf z0`77Nisx6bb7quTtXBQbvCM$|`owZ{YMA$ZHG<0sBFQ$BOi`V@mbhhj|>q$rTQS@#H%teb(1Q)s1roTn;{iOuElDB#qTa2dwrBxp8 z+3nH(TKYouV3m+S$;Cw>UBKh_V8VCGOOk z?DtVVQo@0ggG3581GT*7S$(8x8$T|2M=QRu?T=R_fuC|9m{HN#NjYldr;*P#%7iI| zTBUtU!jFideX?R9eGD_PaxhiV5*f(r94+8u4t%7@tU)7sXI@XK+J%K_=5t|ST(GQ> zB;ZY4KLASRr%_pX(Hy@S9UzJjm@Y!}&z~Bc{8rY(`3aAvj+7LoVla=tXI-rF+;u!GI4G@wm$FRf_MLA>#_N~WaI-pBzU9CWPjlWoyVY$^ znP@FmhRHhh$6C(ok$(xO&VdYmtzx#et4R6?^w{65ZvX(OGlV7?*jL5vd!spJ^Ow^G zxD816pTc^dvQrn1*OMj|g9?$l7%UTkq(?#m!}?QCjitvo>+v)|rmVr6ou)>7&fGh* zF3U^oR`nZA3AHJE{QS0F--drXG;o8{Q6JZ5eW|?nAWQvO>Qp&qt(A9iKW%GRqbOO3 zUVd_99s8!=OFvMPSYFWyoA2uh6)=Nqsrf1D`Nf(l6sqi%;V}!AFnTq&+n+XyADb@#k25=C)&3)X$)``@N(c|5wozQ?u~T}Y;82P#9$~o zEqih`Un`EE!fR6! zX~)NX`9#z79ZW3L#e@@i6aMa#^GP^#=yltF3LZE3e6IX7D056zb0HzWh4f5Li5!@a z>m>py-wCX4-^^#Gz9g5?RSw`O{h1#}L@d8Ls|>o*PL7xrD#<-e1HBM|;i5qVr%D90 z*$Xf-NSF+XSZ#IuUhSw2;eina z>r44pe#PTU*tyLFfBcYgdfqZWJ{TAjy;9Lo|H*$olMI8@79``PE5I<>YTvXevSQ_5 zYHSBWIftCnzSe}hbcvj-QWyf`Y!e}8$~9TX@oQ<$Q-!MOku4vkkd_UEA8=b&;y_`{ z{q;sV70Of$Y~vF0WzlqajY^W1s|4naGmYVLt@WqQyhFi4x5X)ijkV!I9Lj-JX^=&C zY-L+h_7!ZptMv)|=cw%h>-YR|wl=yf-%%C(JVYPCS8)(URiw=y`%4LC#5jX=L@(DG z06#a)PDLAw2dr~@FoEwlqG2XIX+CItoReRCmet8mc7KjTL=vdXT8E77)Y75*Z?CCc zEPn5W1M;6RxAj}JYWvVn<}f~VLbOGXnAsR*WjFzXLb;KBsR*_L<+|nZUv;4jLcf&b z^ZsrxG*>;-!X823ek-tXhQiSbG?_LZqWn9PD8wtf#x4@INr5 zFn)B;1@b#wc);h4Lb=|6Q~Bg0K#7Vn#=ze`hv+BrS(F_+Eysp?+$9JrqrgFsY+6mc zv@5I#d%_!(DLLIm?&d zqAvMX<{c}+5l(pJN#|#G-1!1iqu+fN1NtVcSu;5Z)fgMZUw7RGpkHzOg=Ks^@~(8N z`Q01C`hp!vk=dwNCuz*GrTaQL zhKA=dZ4fFmZd`k#>E3(m+o>fb)_AvRTlR}^<5g|Gq5TFVK!L;!Nl1-OY0+lbe)@Pr@i^&ul_697OM z@?<~^t#H$UL_eBMN)PoU75pcX>mpyy4+ZKkIyc6Kzyl7cZV>FXraq1__>7aXt}odT&X(!^~4o zHlm1*eB6tjpqTaR*SO8r0_mjU&cqEg*u7I*1BLUn9W7#e?(0;?Y=t2R3t4^fxMrpv z6@T`{rP`y27$IvWxhW|#IXd=>0daW>Em@+?IT4*k?^?G z6YUDXuX}~zA8QG3n;!`eeWGMEu(!Mgln}x1B-|7 z&(m7Ms1%7gpykpii-kORnT5*QGX>2K&}I{57ZuXJh5s@*|8wO@WH22{A`%?Oh^zU9 zV$sc%M;9@6p>T$8~V^*M!xcXTWo6l zk(x+%|ET38mI0KUckvmsNaOB)kM5kd2~7EXRbUM{i)>XN{^R+SbQ1*J2&|wV zi)AoHjE-k&*~x}ly8NLTdl|T!l1;@mjU90%sW$3}Xiw}Z#TSANf(hGkeT3FeO zjNr6+fm2-*>i4qnkjIO0-uxl+!ks++C$bgvsR|%5`{&uGgSdTCZO=pZN$P&UCU`Vn zbO*IQEavkOHy4u6sUI=UTET>^XQlC-z1$OzdxSh52dp!h{g7TIA+I|^gU z*vChE9l2DrPQ(PzpYC$O1aEE9Y`DWBUTxyMRWlJpy(mtJpWMcbQgrA#<{abu>)k^^ znNqk_lonGSTI`SOF_%a>1$RZ9n&4D>AT&OFB%*2C$AasSt1*pgbYDHKON5fw7lf0N z)?H(B2`?G!MtNavSwH&LYXM1t!@JgP7a*bB`!c@3TI9kYChOI?`bdzoKTsXbw+<=H zqL)u-h@T@Kfe^f(5WXtwlIyE~T7QZ9V2h&!QNf~f>3&WaA#RtY?$)>>Nlx{KU`u20 zJ7BqAnx}5Hbl*v;n+swW@st|4ST?^trA9rYgmfE|G(fSmZELr>BJ}d-zr)NyLqic8 zjL$HpR4b`MWVr5tC|3d+`3KzKi>KpBBnz(F7S~(4DtotAcERb8JV2 z?bP>-@3Kg4Z*DC(g7_gT6i=_sCg0kR!nY z6{6O4fJVTVwRvE0&;wp9DqueS1Co|(VD(7EfF5IyBw_?ADOkN9D>E}N^y+m$f1#K4 z-k|2DZp4g0ca40KM?tnAj`lhQJM%sf=3a{chtCZ8mYEkIq>>?^9JGnI^7t`&+eR}fotN8kRwqKdq#$LEC+ zBg;n)a@20-6`rZa6gb$BT2Gcv$@ih%ok}_HVmJFOnBr9a5tLc2i)Ruu6bKvxCzt(v zqPS%31`UxuT{;Bq4E-lAY@i37;}X`|oco*C*=P!pHd;g=8^kxbAd?mHe724D4DIvv zQ>~Z5Ce{-NvADX=P@m5=(6CGMG;}?`8`De zI+mrIuam1;flsx!4Iw`T-=&BpGncZD(7^rS^R8IVXoU3i0j`bcWBL{73%~BG`i@v* z$RMIz()~zIak}d<41UY5Z*P^*+f?de1o|dQ2V5KkZK&LrgjDjTC8v^VA0vIusEW}w z80Vv`OKpBkkzFHeehCFQC;qP(V&|g<#Sjs*uO~y}ocxsCfrE$BeYvr)spE?fJ}-6b zXcbfa>dHf%8r5c|h%+8V(s-txKY~U>AMHu^XMQrhU+vBG5%N zcx`xQG3&;Zj+9Daz??ABOA&Kp-tmlv{fs6JZw{tDBT)*>UoZn4yno$`bhq`Flm-U` zInbiAv*%&GPl?1yNXwgbyYng*h#e~5)n?n>L+6;!9_`oIiG+UCF(Ks7Se;n2a2!qe zqM-vE#~GUP*a=ey?E1-DhXB3b%q?bcJ9P26dCNiAAPCMUQ9OH93k(E>Y1}^1OQztP z{JS)QLWRfuVmLcQ&W<*LzUG9NU0)L--VoP5pv-H1+TZ&<2VqdBZXpfVJLO&1Hs6DI zPrNXh4B^za2QP_#B#-T0XIgJzTdnI1h zb;h%QP%!0k#F%N<{H)>&o?j4E_gk_7Qr@g?mcfMK80$Vcl-9d;USJ!8@P(mYsy;YP zcHg9we0Np=4@#C`eOH0?V~e?N7JSZ=;>~yr17;4^W|L0Io+t@& zz4CMSY#lLIn8=O$`|aysBUfrPFI}*Q^+6LK%>oO27vtv9 zYmkJnWmtIM88Lk*L*>gu`VQhRsN0R>W5pVO{}G-!)MbBp{-&=VG>ytdNIm%_3)j2Y zsXHFP63m8`Xa_S9Eba^&CKiSz) zjO}xX0Nzs~W#ZmtdJ;iYtxLT!k+$g!nis4kWB6!Ft8TKuB%yePjbfAz1l5wtS7^T~ zNeNZ14jO0~0M?g>bFfgGy)wW*-PViD&=@33y*H~Z1UK*uzBE+7l2t_{;_1%-Q7wVJ zorX=riWC~iI8)xvu|`=2HS^z5qz@Y9eaxTXlG(<>*PGh@J5zlmGK_wU39 zBkj8%0q&YNqBKvniw%Kmk{MeB4UdRRx=tBA$}Sd{^TGa8TMqUXDSo@V)f6aoWFo33 z9`WSQtRFdCRkZK=p-0BOun9IBKXaNG`er8!PQjNp4Aa&SOyob#Q2?6*8yPR<<0qAZ%wbCX;bOd`$JlCjFA++fGZ0LP;&KjR8 zv&rKY_pK_OFkrDP3^U@wf!cQUdi?W?j>%lLzNS>#U&-qd&g;3<-Kpnm75Rk$@EM>T zvEeK*`n!sG*X+H+0Hsj}SM>)ILhU8I=TD*!PGt4@WtAV8d*|0o=-MTdRsE)E(Rjf$ z^7so=e}Yfplog~dIZk&bo3uZ`YUZE+s6QCrd}+WN_gw(1?5(uwUcdu6yOH8cress6 z_AI?G$m;;SZ3?qpav{qbw0ipl$cLqG2USaIi+Dj}3J5Lp-3Pi$>ev2~Mczdw1#Z?QW&tF$tJMM= z?`RZ;8AumwT!$9)kMWeY*U{o{4cnN$Y@I@T2J?%*ckO_TG)-dRYD2Yj=8x4RY_Zih z1m2V}18>6m74+ndmdC$mlb3CvOX84k&p)PJ$^APGMA;%~A4Q_cysz18CF0x75-CfF z+;}=DB3+uk%#GT3x#v+|l2j3-V(7Cb;pWN_TeQ~I>+D~!-@nILuo*A(v*RBPA?B!G zL}IxZ^G?doS3XLv^o}W5_&Hxj9^P})!rm8CCn}OR!$D$pcGV++Jpr5Fwu2LVBEf5G zr9!mXgo7y|N*W4Y98$5#q6shV%qb+8co^x>`|}_u^ER#X2?>+MV(D?pbT>HzT;G%X zzezRm$f76P^qMN%_&}L&ze$r2qY0Jke=ZF1-L;dNIWtLz*9&&0)BXY_XVf@~Bqt)O zeLQOHF8{?TMV~HZT2Qi5Dty8Icdr8)&KCdxxm5!OqJ@R<`@1I^#K_~OfAc3qwAB^w z=>GWq@UUapIXPV}jlH4Fq>n5Cca+zNJj`jBluodgHtfut;yae??&w>mC0&kNa@Uct zoRbpc5ufLJmfOK5;G=D1=$`Qsaq10<0ocs;EQk)DQr-G0gSmWzLo{^B-%DAd(zchLTR4t_mdlT4M!pZ~ZDxc!1C`!j0CcUJ zHqW$-=@y&M9O$?he0 zFm{mbN8J^gSpf3xM#c@pVDhqfACeS1DsD-qN4Cm`{&T?r_G&zgEHEKLn78uG{V0p!L4mE$NK zyI=-T^9TYpx%0Sm$;K6AJXj{AXHbpx`7VlQOw{imXk2;i4={Y{X=v1O5&I=6H>nl9SG*x=6=d8Q&HSK6lGS&h0?WPQ0Owx&o5nUHqo&m5FKhek*fN%- z-&%C}b0M5iO?B&17T>JwvSLaZ7Bp2USrlQ9pVUi|i26W+9)3^_7HdeJrzjafHsxLz z`%AKSK&ydgzs-d#wdd1T2}bOr1_(C zv5ees_1UTYk2$c0B7__uUI>PS0kXDqgpsn_pB_ucEA7l7q65%h8RsO}~X8z{s|#Ib3PPWFw7ANz*w9@_6w$ zEqs{Rc99;yU-{^$bF$A9z3Vv@i9S-0&E~C*ps66%zyTYDdIy9asok;7tlXoT#6*!u zo0^*nE?FI90QS7Q{B7;GVKHLCbMw#~#U2Z}tt*Q5>3ZI_UJ?eoiS2oQj8iS+G`MJW zpoy5&yA`SM7FX?AtdOfThw6)3`g%Xg>zz7H$U^`SmlD~0M{M{aHTdyP&STZ{nBP9! z-uJy`I?`vc4(iL0SwrT+I>Y8+Zo#MoUke7NIvRd`OB+4!&~LUR%{mO+AMnx)xZ-x7 z-X4UVgRPo8R7RLtZZ3rbFKiBDsoJ|E&K0hBVH2M9ehQtg^mGA+P~YDyQJ6a5%P>%y5AEIS?SFf>9$ZL+cSyptjJV<1#La_@*+cK2gk`b{q(O9ngd zK~RWBTW+9JQ1q{s+C~uqn?bXC0(T^KFC-|EJp8-#=+P&~^SL#!lo2|VcPA>X(L((i zkAx0qT{fGV1B3_tksyWfq1J6ds(k1ic{S%S5&Bl6SJ%$rJE4ZH3aSd>_+>2Nd_Q@o zO{pxFv3Q5GBz9Zq!tXf&f%K&sNA0q=f0P2Q`Gj2uIgWT1o$_wz$OaG!ZfQ? zTqcOM>|P8D`OIBpx&VOBUDuyEjg&orJ2rbV{?=GOSSc-in%-xeq5Tr7rUw=Iiy7cYF3+ zQzg2E4R<5^pd7kp&Z$+QzF|#8((ng}OzEID30>*qk8r92s|>BF;gtzAYlL`+`e2jb za9MvVu?xSv&|rG*$E+MTD&-BLLS@?hbY9%6uD^R9O9b~*Qp+bsKEI?(<*Hd;-XrQi z_Qg7O0`>cV6^A9_w@%jlsU99gQ$iC2C;mLanStP*?nya~?*Zs!U&99(yw<-rB)u`4jXRvw?g{LjaZnpUz>|!^F!b!62P<5 zMe;&Rktu3DBqwFiqLTN+D#dHz{gs){Bj^0I_T%Y@J`^KeAm{{5D_K@^e<$%5-9Y3l zbG@4EJXp#O(azMWjJczkkD9sJIEybv>@g!L)<@WNXS_w7I|HgDBL!f~4AXSO5C$cX1@&v9TmyG~zC~d9Re#$N$uZgRx04vQ0rCVxH;hgR z>CCtLUIUf9J>;vp#=5~FHidU;r$bR)F>U=clX$DEHajxghRWhTj|ADO4yAAN4z&aY zn*P-CkvK*i7DW*$gNOm}%KWP;-w5D7WpeA6ELF@D^%!y2HC4g?Pqx;Bt73~fk5Fs`q z!Y>QhPI5`T*_A6jFaDUK$c?3(Z$_$#JQ7T3vdaXjDb|JLu59XM?OGR8)|tJix{U=*DsocX3*Wh@2@$e zJDF9$s+7fr*~T?>zYJcb^%ja2wGmcX%jU-UkF#}cKl-}1uYVn4zP#%}qAa{&9tgn6 z6Xw&;kor{313n;@@DwW!>saRB=QJ(Ej@wAX!DgPk{FohtE8{*!?}JFD%C)jWd#fY= z01L8^br3j&8_ase7PGgk@NO{&xtF3|w|8fDO@DNgK9~bNq6p`&$0Yk-=s?>+Bd~GF z+j-M=OQeztb!7LT<`m6}dER-b1x*`g{V6p~j--|8x$q|`wqzTTi5RpvBhDC^5)7aw zhi&RN)Op;U7I2M33wMBI%&HGL_*wr$*`163ptn&Z^C%4pC$7k}xmWkmCJx(VK4U4d zbOc(^A;8J4F{WM;8QF~`&jV{=be#wY@f?r$3k$S=Mu{72`3g;*u=PNud=v~gbKUfTr!1S0O~>H~WfmjfgYCC!G-g#J zcL9GxG~2uOH)}U>>mCbF_yqyJ{;Z><(D`?O}l>WPWL9RL=O82xXNTqC(-Mc`ZP}b-s+a(V;ZKa}hr9N&gXzt{}AJ z^m90G^3~RKLeiDnqAQChQfDs=`ul(XNS$+fw$!}yb*eTG);HVm+2)_xk=LT(U!lCzeDZlL@2TGm|hfsiD4YZr%+Gkit5>#iT)+F>oA5SG~2 z5JRMqZmiCV3V>P9dh~fk46^4cZkv^OgZDsoKBgCCs&4Cv2|U|`EebdlP*h4>8U~wD zR}XKSJqBozAd`gX&91-1jXa)Sz?kPjNtX;q5u!@yPIDdV=qztKH9onpT?4p8zm$aHF95wC$$Pu z&k;xhho2%+HQ$Uhxr2{ZKFuFn(sP>3!=nuY^Zb9cyi;%{O!Vy?+nLxlp4hfEv2EK< zCZ5=~ZJQI@cJfT@oO%CM-*@Vq`?IgR_v-4sZn~=151nc*F3pYsrI%9FHe9&W9F~7+ zGd8wPT~xdWcNe)fDFx7Hc7DMalRkb`yBc^|cWcCCyI#d%p+ALqP<=M9;H_$!m5gS) zZt{gUN$avr87VsEKtWoovZnjHY%>m^W>{NKexvsjxuH-`d6*8i!1ICI*hG-H#>wUj z2oig)Cs!zk60kDdCR5tKLj;$5IF!J2xTn=BaFP zMsw=&S!2^Km%(-v7w2M{J%;Hkf(GB!Pie^U+=((@pDfw;qyWC{W-Oz5f2J}_VQ0#D zfbrx^7JcqFZsA3iIFFm2nvq`^?dRMGpLumZ8q3{*(TiER*#Mes@Ki9k z{+hjF#HM3+cND+KsckC!6e*q$GeO2X_80kx=ssEIoqXt6y(5I^OpnYnubU)FBwRe zdoDooZH#S<^0F&OItfDaULAteBe7-V+or}=!noNMy76($hA-v4t=CzO1Ww~^XO`eL_-d$nsTP0LWO$w#! zLKluvoJ|p}3Osww#?Yf9;eKLJMmn?Gb%EmAJS13ptHP|DP&L+-LRsC0fN+QU4NTV! zKW^V`@rqFZB7)ZVeR5^rq64&xLin zoQYkg@IDiLowlNdlqm;|N}qfW2dzH^eH<0vS1haA^pXR4Vq=Z9XMq)JTC|XMoPc1r z`dyZ$PDU$EVZ@HgkAV&=qC0bxIDt#md11ET6;2l*o>8aZ!`mcDXK3E)&eleh zFld?2s!)KLjVY$uMJ&}suRZbF_dQJ6(qFNv-r3fmW>^WoE!#1RWTUCiE7LuoM&INw zIPEECDif)M0HK1P8?UFp9-q(r! z#-tBVZP$Kv&RytCtE~GJmPkj=;q}TG%hDv}xeIeLXfMP-y)D?qTH%n+g{=+Y^O49z zBSxRBm$x+&NDQg{6nlP^`mJF;A$vmDjjC<6Z{wC6DZ8&HGwYGEhrQBFy4lwU&4Mg% za_sKsj_J#!QFvmJ{BV^^*g2}(&f90sw z7)m{bpq(Km&=11h%QunK8u94sy(UZ15FKP}>-W=tnVkIF32D84d`i zDbz^h;P4KCfzNx+wo;ZaWR4=#eDTLIg-ccy0!b>@Or?q9nd4o6gse_8Zg!}4VoQnBCVmrd@muIx&J(8DNO*55aqlP9R+>Vx-{zKV&aGu~c#v>0$bnD=MOFI3OW+xy8u&R;y+4dUC(R$ zA{b>PvuJhX@0VzB>3yYv1!B1n6a=nyOv}?+!(^v8olo@xwpVkkhNbTn8vV=!7d0$l zAO;?~{Qh(nZhDBufyQ-0l;b8S*tuECW)0g8AJO!?C`Dr8iJu>rT8Kr>U%rpRqOPzb z@~aUBx>xJvFwe=1e@WXAp#&f(N}D>2j_NN!NFyV@9Cg~WF~J7elrm`9EZrr|Tt+`Y z;QRqAoNhc-Ov9qu$;Xnc8;VEQ8XrsD9!85pCtT2%7jI}>?1;YB;&F`?sB}vV8L*$8 zR%YVBvd|3)r=cQpsW82gx#rwcWb4lfdI!#oor*p{ZPMt#F&5+Ft8;>go!zsiIBlB4 ziDtM1!8DTrf4y62yZ1ycw2dM#*tK&pP^?N?fTQvj!^HQ{bceGrzA5PqU8}glv!umg zC~R{z&J3c%LB=}RUeKiMWT}FzQBf{*rFA8!55L9_$9{6vBfLrHy5X#C>9buBK;p&s zfiC?EY6MnwFVGj*t43_#+OgcDtqeHnmx!5Q;wtO$EAmN9UnH6@$YI zQ?v?;Dqq_6l;O;lBIj!02NxTTnH3F<-j%F^IBszMO`Wt^)F-LO`z4Qp=2PZ9l9ac5 zu-=n_mAcaB9e{FE#`;=mdz)ptNQC9@5)llY6#|unfEBe24bnA&q+U{S+hUcnx1Ep5 zj-WEMR-#qGhnsm*Cxj@Uz~LOt7WPV8SAf5c{b>pL8TnrT*q3p^ZvAlcuc$9 zO^};y=WyaX?IFTcs?7RJf{=71Nr0Vo8sk)5Cp!9wd?yV%p`;rIti(%pF>PX>jZk`? zK|iW3xn%AFv+kAQ?YRE-IyQkmv$p*w04Rp7uEm?E3Q6@eI5iYSnoM*k@KFD!vOUDl z6rlt5v=PZsda}#s0k;1FImo1O5YLrq@N%O(IUsH#Tbcif&gQd@^S0n4Ba=&8ILNn4 zzxF4(tTJ(s-e_yl-lhtAZ}K3BEw7@;WeMAjF0LtFr?K8SJ1&cvjFJvKLs|jV6HDpD zjR9A6kFvv-WhE6*LZ%!v47)U6_$UGnL;(b3W0PXK&k0&`rvt0v!_#H@;5@5zJJKzV zjcQSDi)@2};tCT%^4y>n$3az3NOIK6F2;f=T(C{;IKQq(4$sYAnwRW7#dLYsn=_wN zZSHy{H5y&NU$~9-vz|fTHe;dW%G{D9S-JhEp-OWdWLvvnk}spQl9gZDB%8 z{}^$Y$A^@D?U7XlbIwf*#G(T4LQC4Z$CYP=sJ_Q0I^tRS&MX!FjgH$zjmooc;@9@X zJHeag6&z1GLS#D8z9_PBMB+~nrO*?4@?|V4_l4xX%x5ukgl_fv&L2I?Y`M(X&x(HX ziPyN*Lrq12`39Ap81M7y`jmv4WhK6bJHfaH))D7iaF7paD6!JO7W$U3E)@?uB$93V z+_#f=%$7gD*3H6YjnJ*8FAftjo?`lxhi-EgY)|7##E%MyJ+9Q%^WtN>2Y#P?=wGr7 zy9STC| zt3%rPZbV8W{Ca+|z9A>O1HKv3MR>g?wnxD2>$@< zeneiu>xPIE{wRhmzM-=8!SnsBndtUda4BMNgAEblldxH&S49NY>%@yo4yI6+tGDbh zkoa(s6vV2e%tA7i%fs`6b=Wke;MUJkdlOGD(}2^!)*B3hWT)lQzu&-^J(HHy3}*HD zkdvr#pAjZFmRbz$x!40D6B9lk+ok^UWATT!SmUcYK7>D8OtfF4>A0xrOrCD|0MhZ4 z#N+`cisWh34<0u*M7#&#sss4c}jNK_7R%*d!90X3!UZmt81u|Ok#dx&~7-IU!Hty!ok2i%N z>%3&IoRk%QPyk+#*t$OApM%VO^wg?mgnzMe2ro;P1wY~>o&xi!q{;6+m*1u!9cc-irwjiSx~d~dNys=7=%g`kFlllmbJeo z6B<)XB^vnN2j&;Bza>r1ub06NW7zaY;~I@t2nUlO6ro7;A852i6dUr_!+m||H+6d- z-iRQuMM=SHQDiGEtp2uYlxM+mLi)hnBv_eTIeRpN4e{F2*q-hqYqTok$jl@(5Rzr} z5PH;08zbm&o6WW&_vVR}TTnQ)nWmN>z-TgsbLLF4Saowsya)qdI=?-g*8~f9r@mpp z+oDD{R1u+vzh|=u7$$pj|B4QEdO@J!uX(Mbr8beEkeESmjUW655~$y-p9ojNxyPG^Rm0!m!W~rMU%|- zU2<{+XUU4&9f|AVWE}cRW6p?D*l}E8N`lZI9rQP|sI&dlSd{ylBVu@I{U}ox8*449 z5VF|_j3(Q$B@pr<7|4z-+-2+AzHarykhBlB=eis5DbiQj?IwziKb)u++UMLUWOF7B z)7&uJbM6LxQAO1Td@GOq=+!$=a7K52Ja*a@8=LBQ2$k8rC^5KDXj)~>cD`_0PR;`; zm_H{U<$#KWsEKW<(Ysa%U3C78*W#wq`Y~(_qPV!@?X`3r#%JXf0)>Rvn=MCYgOyD$ zc*hgsg#85Qo9s#n$e$adSS}i|l>nI7|7}4j*pjq^vp=VCe&et>-O|{$nn6DEyznU~ zGUX3(U+xZgw#>wM*E{NYmNmA2aGWh+WOdX4k%E7Jkm-2Z<7e|M;+!=u$hXg8OCV+~ z4Re(G-GnRh(W-W%CZv!@)pZKj1({=V%J!+r-~7CWYEN>LTZ!-*xQ3<$@d2U+h0h?o zW(CU~d2%NASg?T^9}itJmh1a>I-mA)%E_%ZqIBN? z2uwH~lLyWb$CVpBlKO}}Qq#cVZ|3v=AskJ@c+c1#_J_S~xc!SEYU42h&}D5ROk0Tb ztjC4kQvgwsFcjHidixRcvnke^jvhMjrm;mY-2Y=~CpXKyt zTGJfPFCw3{Vn(uer*bRh;-N_>A0$k-wZ`&P{CpirM)c_3#K#J7h0bzHv|WfpJ*K2) zMgIN~BOPrd4vj*piih{4L~V815>xeuYiKb$!RchOE0_jaqWzeK zFrP*?Pv(9Ts+4ARdL0gMw0)Jcy~x%ast$Xx%b?GQhkK99@=jhPQye*gI?0rItJ+GS zQ>pqLT|N0@M3$_J7#3PScF@EVar%`I<|mclf!|8%ey9Fz6wMMuEM(W~Y_U8G6r68Q?y;3|ahg4j+^9G|um>mv!IH3j^B)U-b zyX$9K#1Y>K0X6|KiI6LBr+m%}uJ0QS2!9(Y(zMVIvh2e}vg00?t_hx`-p;c#34q*| zhJ4nDn~}o2<2v_9g?zp=OpsGdvgjf2j6~4>UJ4)$)Za1l>U^*2ss@b4t;}*;s=q6r z97XR|%uhIg6E+K-DMN|N%A!~rMxOgGd^-T%q%os;YWb*@$h`K5~)?3nY&X*hEC9xoEzK|Ee@drJwkv^&vN;n;$s6yoCcRT4ag;icWhr;8D(qc3Uf~t1*S9| z4EV8BcXG?7;<%!ib0R{8OzLl&;WDEfjb8{1vdzvZ=m}6DQKfVstF5VJiD%7G0Nl!9 z3Eh-OrOYB{#xBh~(UFMW#sU>{kql`Tqt-ca$9L*A%y2p9^)q&D>PbpK`1IG?NaWzZ z??xV-Ou(@&YJ}mth?-3#6xt|igLT7PU=4ouU-@LYzMxFkipwAcn-9V|y&Gfq1y&85 zqF+;u^yM?f=5<5PyIejV{_#7VB*E%BNy#zu!^i8Gayer=eV_1XO+Ov(uK{>5ftvSZ zUNV>kO`|=J9n$6u3P!uN2XsUdgI;+YNfZe3fjGOJ(V(5wBFu)TW{uHFyrJqkL)bk* z))g)j+(SDvcRn`y)*lb_GJiyr+~N^f1Sx9NIUjdn8TjR#${11ly#i2FkJhikSLcYR z4*CRlz28W}X#|qWz;jcf8J9y_hWAEp+x}BDfiljKXX-}e(_}=<#|>7L*VsnNSs#y| z^Zf-WAfG#K=La{Ob;<2&W*;rFPmlQ5ZU5z|GuRnCR?MCS)MPsLm|9!DRpe7ADO2)_ z83u=9>Y8WucbuZ&;Jg#(T$TtDewF`wvg2c}8+NHG`wMIH&w(e$jSz#HMr2=T?Cd2k zkM;rWB+kDO&fE+B5$YbE576yv<-s%>!V5}?(|+WCTHB$TW7A|Kb^CkL@`#A%X-fZ4 zTPMz}u2d_^IDWQi_04Abw7ya?5KHzN{)4g!7k4+28|p>rBOrPums^wk!PgAFeXV=y z)g3>f?wp_j{5d-L{Q?rlHPjx)3BDcT^;mhRY(K`MhEc$p0+gdbI`jrrzEl0MP)11r z?i~Bs31etqEAOKh8D|A1lR-oUsLKp$A2=F6Z>~CF#5aTh6iU-}pmOQ4pypp{AaXO? zGQ)5&0=nLO+C%L~^8l{BBdK-r=R+E?1k^`bzWMzZaA23~liLf{m_=Wy&pZp?rFX%1 zp<^?2t7+Wb{;BnWTG&FJYc=hW+R^O>(ggL|A#)ing1d%jY1&_u*8Qpfsmmu9$N=t+ zy>+%OWxul4{-0QgMR$#NUF5m6B8&CyzDP-2y-Ur#OsiJLtV3aZ7lPdlP@3B8x3!lS z2-U4Tn*AoY$7SN@andygWTMFgMb~4Jwm>s`G@o)ON&_vIU_IN;f0jvJz<{^dq)#TP zGbb`j*>C?pJYDdA-2#pr@Judh2@+V>SgM5njdsJ$70@^(;ExzEP;1$}{CcLDl35jy zXBD|+3O1I3H>os=kjs8sGbszOc0u~|K-GK;05TP|BS8e$fXLQb2^S7cIuEko84zXL z_tt8;%TIkxHv5t22xG+#c$jPTZYt^!$8DEN#QgmiiQK1xCctRwH1WDDf6!<{x z^J{0W9_xr+Z!t=4-2xNZGqG@e9+>yp{HZb$Me!eyF5AWvtQ5jbt@;g7juH8x*cJu9 zdnEk~vfhiLv06<4#dptM=Q=8Z+ViHd1q~o|dO+}3CiRYQBBxz@8;EhPT*u^Hh;J*= zpDi=~8EvtwhXDVcXT&BJ7P z{&%~os)$6#(s%lwO@9i>_Gd^4$@o;OWr~hpZ1J0x%5Xd{?^hr0fSW$Rj=$dYQhX#k zMaIV|!rw4^!G@VsRnI!2@3FI@CUb;dN|#+YU5=E#AiFWwi;2$WRN#{WEt`s2*|dj2 zm#jm#PluZ9p#VE`%v0>0o}!i$QP9@CNEPpolU^l?9E!;UFJ#hgmY*f?CFZUqz0G4!p(vI13rbi$2&_i9uw%G%IAss^| z;;d}Ny*V@A`u_lT!sLei@QxqH9%Pt(bH^w2V`Tlf#K}E2CC}tsu>oYSz;`-r8ZMXX zlGk|}MY-c~r{T1Ny_h^N(|+epEOo;R({1N?yNr?%re5@*E9)PllX@OOIpX!KYurH> zRKWul;~9TbCElR}d(@!8o~+9uH!0=~D%~A^RD|DTY&r~=KNId1ONun*U%({eklJa1 z#Th2x{?Ba3vW(2HuEWO}5I9`~`qs7kjI2;6i~q;xhqubX$gI-qLj*9@ycpMm-PTm1wBfb(feMS-sqE;eLR4Fo*xd zDcH?ER&hr<$wA7V41Dr_6W>RLj9%TOB+5QY(1D=?Kda>xty?k~8+{BM>hqD}W8UK> zy+PwV%SkEH`Iur>{nAY|V9)KhREXmFJwdSTaHik<5iIt+{&Hoq?lTl4gv}pFD@Xp$ zj@1X731$TU3Oxc+wc7$BIlYzH)ECp|D1*fh8^AiR>mH$@eL4L)$iQR9tJ9V@4?3mmM2v_tm1hmdizRb2>)RTGiY99q2SP;(B)Bl#?uP%v=S-GD2^FuB)O3ds z=Q?;hiC^E`w+3cJ4(e~@G-OVnJLSB<+(Q*H&z?85()pNYFd{?>^ZGC07%^Nk zt~ndFWj)>&`gg$CL5BD+ufvsv=U74!TfSbKh6sm#*V;HJCY0k9wh9-&m zkhbb+@~C|ohbDQ9!R^H^ou48c!Fl72-tc};V6^J|`4oRefC474=aXRwBrkJ>>t!gtP)_7<~o&9xWqYh2(ZiKx;U-K z7ZJI<^p*0Rk+#T{+rOb+NcH&hb?4v1(=!g^zLQX1R5}S2=wA9Isth4c7hu+as})!K zRpm?H_)-Vxqw5V1gGx))7SAMJ$tbkwVQlDt@Qn5oj~hUI+dy7%N(luid8SiHpfHy5 zDUgCt_z4h9W+RSGO_)LsfF{g`z@S7-Kq`tr$5wy|Yc2@DKJx~4Ao?tO(?H04@&<&7 zF3H1sS)D{J)4~gtR5lVVNm0kpjgl3N8n~*CYv5Y>c@0hkNj7o`53JB`lxyv3>d~bN(fvJHPoK=phN8{4e+;$); zlZ4O->=#wbx7Ck*Vc)-06iG{PU$9!cgMv434KK9&fC%$NL?-RMidtmh%0@vRv6ezC zz5XJUVNCr}BR^*S9|pdsIK)N@B7c%9T9UQ1tA$|51O7))CP;f}&ZdpG0 z^5GEz5X`lT+b%msElel^ zEn?_d>%DQyn;00d@f#c0wy1(;Wqc!Zs0#MzqHRm^LhEdlZ(>6jQaZ#GTnp0|#)Z7? z)EgBAK|ryxyhZk{)7F$%y~Q)6%^7mRPpy zb{xo=!&6BON}1v51Xaq>DqbK5J@7lu%mht;q@y1|cRO9NT7Vws8hR6voVZj%M3q=S z8Tk5B5dZU|$-u!&p|o#D^9tjbujuPzD=E{xFFn8RaqkNCxG1wEShh+cf8Ri?@=+C| z14m((b&sCSXccSDyNdR1*G0r#7p=}-e9JCG>+}5RgzaI?dM3iZ4 zg2C2zuJZ;GJ7NdLsXNsZ(o@;*KHKykKo6crq0GtEea_@;9;(ySz;-Aa6od!|HbfJa}G%iTN=q9tRf}Ht1rxHW(3PCc;+W#T~ zLCThG%lNbVAiu?!UG;rp;S{IE1CMlfpH+`md(0nO$;7#N26*q4$nG{DG1dG+m+=Oc zsu)t4=T5oOoPc<<1j_ou2>21I(704Or`7w;C;z>2<5^&m(tSoXwa?+echZB20sTAkW4p?aTKt#)}$4+Qjs|Hp#gy7zcuYRUepXUytV*@rSUt z&A5BPCE1y^OhIi-*#R1JlNWbiJ0`tFiZ`|FTzjMccOC=-<-eqeRc!J@S*Qg2cUE>; zF)-Rq8nvrXK;VjC^5SuNV`sx$MkWbEOFN$93bvo!RbF;<11psX5J1?H+7Sy%#KGi}&m_?W}iL zFv#^f!4CWN+Om`VpDt1>Qxks0I#WIb$tCh)2m4^-2PUmt?3GLGj*|6B$Be+idf{QQ zHVT=+*Uc~}8G}(6mS-m$j~dy}D>n!524nyenvcPA*aCP>a1r}2vgCLqZZNqBFZBW5 zT=T7)(ER^2q^@0|<4%7Yw0Tg7ArWsk(8)RQ__nccX&8NyFkt4RHfmX*V;lJ_+ZJGG P^uj)L3VY-K+x5Qyr-`X; literal 0 HcmV?d00001 From e9b02ae74bb32b9151740c595ab6dfa0f355c79a Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 3 Feb 2021 16:52:24 +0200 Subject: [PATCH 052/398] Renew activity icon --- .../net/osmand/osm/RouteActivityType.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index 06471b933f..e7a7a0600a 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -1,19 +1,19 @@ package net.osmand.osm; public enum RouteActivityType { - WATER("Water", "yellow", "ic_action_motorboat", "activity_type_water"), - WINTER("Winter", "yellow", "ic_action_skiing", "activity_type_winter"), - SNOWMOBILE("Snowmobile", "yellow", "ic_action_snowmobile", "activity_type_snowmobile"), - RIDING("Riding", "yellow", "ic_action_horse", "activity_type_riding"), - RACING("Racing", "yellow", "ic_action_point_destination", "activity_type_racing"), - MOUNTAINBIKE("Mountainbike", "blue", "ic_action_bicycle_dark", "activity_type_mountainbike"), - CYCLING("Cycling", "blue", "ic_action_bicycle_dark", "activity_type_cycling"), - HIKING("Hiking", "orange", "ic_action_trekking_dark", "activity_type_hiking"), - RUNNING("Running", "orange", "ic_action_pedestrian_dark", "activity_type_running"), - WALKING("Walking", "orange", "ic_action_pedestrian_dark", "activity_type_walking"), - OFFROAD("Off-road", "yellow", "ic_action_offroad", "activity_type_offroad"), - MOTORBIKE("Motorbike", "green", "ic_action_motorcycle_dark", "activity_type_motorbike"), - CAR("Car", "green", "ic_action_car_dark", "activity_type_car"); + WATER("Water", "yellow", "mx_special_kayak", "activity_type_water"), + WINTER("Winter", "yellow", "mx_special_skiing", "activity_type_winter"), + SNOWMOBILE("Snowmobile", "yellow", "mx_special_snowmobile", "activity_type_snowmobile"), + RIDING("Riding", "yellow", "mx_special_horse", "activity_type_riding"), + RACING("Racing", "yellow", "mx_raceway", "activity_type_racing"), + MOUNTAINBIKE("Mountainbike", "blue", "mx_sport_cycling", "activity_type_mountainbike"), + CYCLING("Cycling", "blue", "mx_special_bicycle", "activity_type_cycling"), + HIKING("Hiking", "orange", "mx_special_trekking", "activity_type_hiking"), + RUNNING("Running", "orange", "mx_running", "activity_type_running"), + WALKING("Walking", "orange", " mx_special_walking", "activity_type_walking"), + OFFROAD("Off-road", "yellow", "mx_special_offroad", "activity_type_offroad"), + MOTORBIKE("Motorbike", "green", "mx_special_motorcycle", "activity_type_motorbike"), + CAR("Car", "green", "mx_shop_car", "activity_type_car"); // less specific bottom order String name; From 0ebaff76e78d3193f4028f5214129f594b223847 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 3 Feb 2021 17:02:39 +0100 Subject: [PATCH 053/398] Sample photos before load --- .../net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index cf0587e06f..e552cb1373 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -180,7 +180,9 @@ public class UploadPhotosAsyncTask extends AsyncTask { private byte[] compressImageToJpeg(InputStream image) { BufferedInputStream bufferedInputStream = new BufferedInputStream(image); - Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream); + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inSampleSize = 4; + Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream, null, opts); ByteArrayOutputStream os = new ByteArrayOutputStream(); int h = bmp.getHeight(); int w = bmp.getWidth(); From 2f464549b059ea4767036e4f7cf91ccb108be687 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 3 Feb 2021 17:09:29 +0100 Subject: [PATCH 054/398] Clean up code --- .../osmand/plus/openplacereviews/IPFSImageCard.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/openplacereviews/IPFSImageCard.java b/OsmAnd/src/net/osmand/plus/openplacereviews/IPFSImageCard.java index e1ba5d2e0c..d19dcb7fab 100644 --- a/OsmAnd/src/net/osmand/plus/openplacereviews/IPFSImageCard.java +++ b/OsmAnd/src/net/osmand/plus/openplacereviews/IPFSImageCard.java @@ -20,16 +20,17 @@ public class IPFSImageCard extends ImageCard { public IPFSImageCard(MapActivity mapActivity, JSONObject imageObject) { super(mapActivity, imageObject); - url = mapActivity.getString(R.string.opr_base_url) + "api/ipfs/image?"; try { - url += "cid=" + (String) imageObject.getString("cid"); - url += "&hash=" + (String) imageObject.getString("hash"); - url += "&ext=" + (String) imageObject.getString("extension"); + String calcImageUrl = mapActivity.getString(R.string.opr_base_url) + "api/ipfs/image?"; + calcImageUrl += "cid=" + (String) imageObject.getString("cid"); + calcImageUrl += "&hash=" + (String) imageObject.getString("hash"); + calcImageUrl += "&ext=" + (String) imageObject.getString("extension"); + url = calcImageUrl; + imageHiresUrl = url; + imageUrl = url; } catch (JSONException e) { LOG.error(e); } - imageHiresUrl = url; - imageUrl = url; icon = ContextCompat.getDrawable(getMyApplication(), R.drawable.ic_logo_openplacereview); if (!Algorithms.isEmpty(getUrl())) { View.OnClickListener onClickListener = new View.OnClickListener() { From f55c64159e9b8a86e28a445cba5253b6164261e1 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 4 Feb 2021 11:43:53 +0200 Subject: [PATCH 055/398] Show all available obf travel files in the card to download --- .../layout/travel_download_update_card.xml | 198 -------------- OsmAnd/res/layout/travel_needed_maps_card.xml | 34 ++- .../wikivoyage/explore/ExploreRvAdapter.java | 7 +- .../explore/ExploreTabFragment.java | 167 ++++++------ .../travelcards/TravelDownloadUpdateCard.java | 250 ++---------------- .../travelcards/TravelNeededMapsCard.java | 32 ++- 6 files changed, 166 insertions(+), 522 deletions(-) delete mode 100644 OsmAnd/res/layout/travel_download_update_card.xml diff --git a/OsmAnd/res/layout/travel_download_update_card.xml b/OsmAnd/res/layout/travel_download_update_card.xml deleted file mode 100644 index 8ad3bb7779..0000000000 --- a/OsmAnd/res/layout/travel_download_update_card.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OsmAnd/res/layout/travel_needed_maps_card.xml b/OsmAnd/res/layout/travel_needed_maps_card.xml index c562b1fdd3..1a5aedcb7d 100644 --- a/OsmAnd/res/layout/travel_needed_maps_card.xml +++ b/OsmAnd/res/layout/travel_needed_maps_card.xml @@ -18,16 +18,34 @@ android:layout_margin="@dimen/content_padding" android:orientation="vertical"> - + android:layout_marginBottom="@dimen/bottom_sheet_content_padding_small"> + + + + + + mainIndexItems = new ArrayList<>(); private final List neededIndexItems = new ArrayList<>(); private boolean waitForIndexes; @@ -199,17 +196,24 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv } private void removeRedundantCards() { - if (mainIndexItem != null && mainIndexItem.isDownloaded() && !mainIndexItem.isOutdated()) { - removeDownloadUpdateCard(); - } - boolean allMapsDownloaded = true; - for (IndexItem item : neededIndexItems) { + boolean allTravelGuideDownloaded = true; + for (IndexItem item : mainIndexItems) { if (!item.isDownloaded()) { - allMapsDownloaded = false; + allTravelGuideDownloaded = false; break; } } - if (allMapsDownloaded) { + if (allTravelGuideDownloaded) { + removeDownloadUpdateCard(); + } + boolean neededMapsDownloaded = true; + for (IndexItem item : neededIndexItems) { + if (!item.isDownloaded()) { + neededMapsDownloaded = false; + break; + } + } + if (neededMapsDownloaded) { removeNeededMapsCard(); } } @@ -218,8 +222,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv new ProcessIndexItemsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - private void addIndexItemCards(IndexItem mainIndexItem, List neededIndexItems) { - this.mainIndexItem = mainIndexItem; + private void addIndexItemCards(List mainIndexItem, List neededIndexItems) { + this.mainIndexItems.clear(); + this.mainIndexItems.addAll(mainIndexItem); this.neededIndexItems.clear(); this.neededIndexItems.addAll(neededIndexItems); addDownloadUpdateCard(); @@ -228,53 +233,58 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv private void addDownloadUpdateCard() { final OsmandApplication app = getMyApplication(); - if (app != null) { - final DownloadIndexesThread downloadThread = app.getDownloadThread(); - - boolean outdated = mainIndexItem != null && mainIndexItem.isOutdated(); - boolean needsDownloading = mainIndexItem != null && !mainIndexItem.isDownloaded(); - - if (!app.getTravelHelper().isAnyTravelBookPresent() || needsDownloading || (outdated && SHOW_TRAVEL_UPDATE_CARD)) { - boolean showOtherMaps = false; - if (needsDownloading) { - List items = downloadThread.getIndexes().getWikivoyageItems(); - showOtherMaps = items != null && items.size() > 1; + if (app != null && !mainIndexItems.isEmpty() && SHOW_TRAVEL_UPDATE_CARD) { + boolean outdated = isMapsOutdated(); + downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, mainIndexItems, !outdated); + downloadUpdateCard.setListener(new TravelDownloadUpdateCard.CardListener() { + @Override + public void onPrimaryButtonClick() { + if (downloadManager != null) { + downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(mainIndexItems)); + adapter.updateDownloadUpdateCard(false); + } } - downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, !outdated); - downloadUpdateCard.setShowOtherMapsBtn(showOtherMaps); - downloadUpdateCard.setListener(new TravelDownloadUpdateCard.ClickListener() { - @Override - public void onPrimaryButtonClick() { - if (mainIndexItem != null && downloadManager != null) { - downloadManager.startDownload(getMyActivity(), mainIndexItem); - adapter.updateDownloadUpdateCard(false); - } + @Override + public void onSecondaryButtonClick() { + if (downloadUpdateCard.isDownloading()) { + app.getDownloadThread().cancelDownload(mainIndexItems); + adapter.updateDownloadUpdateCard(false); + } else { + SHOW_TRAVEL_UPDATE_CARD = false; + removeDownloadUpdateCard(); } + } - @Override - public void onSecondaryButtonClick() { - if (downloadUpdateCard.isLoading()) { - downloadThread.cancelDownload(mainIndexItem); - adapter.updateDownloadUpdateCard(false); - } else if (!downloadUpdateCard.isDownload()) { - SHOW_TRAVEL_UPDATE_CARD = false; - removeDownloadUpdateCard(); - } else if (downloadUpdateCard.isShowOtherMapsBtn()) { - Activity activity = getActivity(); - if (activity != null) { - Intent newIntent = new Intent(activity, - ((OsmandApplication) activity.getApplication()).getAppCustomization().getDownloadActivity()); - newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - activity.startActivity(newIntent); - } + @Override + public void onIndexItemClick(IndexItem item) { + if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE && !Version.isPaidVersion(app)) { + FragmentManager fm = getFragmentManager(); + if (fm != null) { + ChoosePlanDialogFragment.showWikipediaInstance(fm); } + } else { + DownloadIndexesThread downloadThread = app.getDownloadThread(); + if (downloadThread.isDownloading(item)) { + downloadThread.cancelDownload(item); + } else if (!item.isDownloaded() && downloadManager != null) { + downloadManager.startDownload(getMyActivity(), item); + } + adapter.updateDownloadUpdateCard(false); } - }); - downloadUpdateCard.setIndexItem(mainIndexItem); - adapter.addDownloadUpdateCard(downloadUpdateCard); + } + }); + adapter.addDownloadUpdateCard(downloadUpdateCard); + } + } + + private boolean isMapsOutdated() { + for (IndexItem indexItem : mainIndexItems) { + if (indexItem.isOutdated()) { + return true; } } + return false; } private void addNeededMapsCard() { @@ -285,7 +295,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv @Override public void onPrimaryButtonClick() { if (downloadManager != null) { - downloadManager.startDownload(getMyActivity(), getAllItemsForDownload()); + downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(neededIndexItems)); adapter.updateNeededMapsCard(false); } } @@ -323,10 +333,10 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv } } - private IndexItem[] getAllItemsForDownload() { + private IndexItem[] getAllItemsForDownload(List indexItems) { boolean paidVersion = Version.isPaidVersion(getMyApplication()); ArrayList res = new ArrayList<>(); - for (IndexItem item : neededIndexItems) { + for (IndexItem item : indexItems) { if (!item.isDownloaded() && (paidVersion || item.getType() != DownloadActivityType.WIKIPEDIA_FILE)) { res.add(item); } @@ -344,7 +354,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv neededMapsCard = null; } - private static class ProcessIndexItemsTask extends AsyncTask>> { + private static class ProcessIndexItemsTask extends AsyncTask, List>> { private static final DownloadActivityType[] types = new DownloadActivityType[]{ DownloadActivityType.NORMAL_FILE, @@ -354,40 +364,41 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv private final OsmandApplication app; private final WeakReference weakFragment; - private final String fileName; - ProcessIndexItemsTask(ExploreTabFragment fragment) { app = fragment.getMyApplication(); weakFragment = new WeakReference<>(fragment); - fileName = app != null ? app.getTravelHelper().getWikivoyageFileName() : null; } @Override - protected Pair> doInBackground(Void... voids) { - if (fileName != null) { - IndexItem mainItem = app.getDownloadThread().getIndexes().getWikivoyageItem(fileName); - - List neededItems = new ArrayList<>(); - for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) { - LatLon latLon = new LatLon(article.getLat(), article.getLon()); - try { - for (DownloadActivityType type : types) { - IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type); - if (item != null && !item.isDownloaded() && !neededItems.contains(item)) { - neededItems.add(item); - } - } - } catch (IOException e) { - // ignore + protected Pair, List> doInBackground(Void... voids) { + List mainItems = new ArrayList<>(); + List allWikivoyageItems = app.getDownloadThread().getIndexes().getWikivoyageItems(); + if (allWikivoyageItems != null) { + for (IndexItem item : allWikivoyageItems) { + if (!item.isDownloaded() && !mainItems.contains(item)) { + mainItems.add(item); } } - return new Pair<>(mainItem, neededItems); } - return null; + List neededItems = new ArrayList<>(); + for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) { + LatLon latLon = new LatLon(article.getLat(), article.getLon()); + try { + for (DownloadActivityType type : types) { + IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type); + if (item != null && !item.isDownloaded() && !neededItems.contains(item)) { + neededItems.add(item); + } + } + } catch (IOException e) { + // ignore + } + } + return new Pair<>(mainItems, neededItems); } @Override - protected void onPostExecute(Pair> res) { + protected void onPostExecute(Pair, List> res) { ExploreTabFragment fragment = weakFragment.get(); if (res != null && fragment != null && fragment.isResumed()) { fragment.addIndexItemCards(res.first, res.second); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java index d7aaa23bb7..f4a20a83f7 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java @@ -1,257 +1,47 @@ package net.osmand.plus.wikivoyage.explore.travelcards; -import android.graphics.drawable.Drawable; -import android.view.View; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.recyclerview.widget.RecyclerView; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.download.IndexItem; -import java.lang.ref.WeakReference; -import java.text.DateFormat; +import java.util.List; -public class TravelDownloadUpdateCard extends BaseTravelCard { +public class TravelDownloadUpdateCard extends TravelNeededMapsCard { public static final int TYPE = 50; - private boolean download; - private boolean showOtherMapsBtn; - private WeakReference ref; + private final boolean download; - private ClickListener listener; - - @Nullable - private IndexItem indexItem; - - private DateFormat dateFormat; - - public boolean isDownload() { - return download; - } - - public boolean isShowOtherMapsBtn() { - return showOtherMapsBtn; - } - - public void setShowOtherMapsBtn(boolean showOtherMapsBtn) { - this.showOtherMapsBtn = showOtherMapsBtn; - } - - public void setListener(ClickListener listener) { - this.listener = listener; - } - - public void setIndexItem(@Nullable IndexItem indexItem) { - this.indexItem = indexItem; - } - - public TravelDownloadUpdateCard(OsmandApplication app, boolean nightMode, boolean download) { - super(app, nightMode); + public TravelDownloadUpdateCard(@NonNull OsmandApplication app, boolean nightMode, @NonNull List items, + boolean download) { + super(app, nightMode, items); this.download = download; - dateFormat = android.text.format.DateFormat.getMediumDateFormat(app); + } + + public int getTitle() { + if (isDownloading()) { + return R.string.shared_string_downloading; + } + return download ? R.string.download_file : R.string.update_is_available; } @Override - public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { - if (viewHolder instanceof DownloadUpdateVH) { - boolean loading = isLoading(); - DownloadUpdateVH holder = (DownloadUpdateVH) viewHolder; - this.ref = new WeakReference(holder); - holder.title.setText(getTitle(loading)); - holder.icon.setImageResource(getIconRes()); - holder.description.setText(getDescription()); - if (indexItem == null) { - holder.fileDataContainer.setVisibility(View.GONE); - } else { - holder.fileDataContainer.setVisibility(View.VISIBLE); - holder.fileIcon.setImageDrawable(getFileIcon()); - holder.fileTitle.setText(getFileTitle()); - holder.fileDescription.setText(getFileDescription()); - holder.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE); - updateProgressBar(holder); - } - boolean primaryBtnVisible = updatePrimaryButton(holder, loading); - boolean secondaryBtnVisible = updateSecondaryButton(holder, loading); - holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE); - } - } - - public void updateProgresBar() { - if(ref != null) { - DownloadUpdateVH holder = ref.get(); - if (holder != null && holder.itemView.isShown()) { - updateProgressBar(holder); - } + public int getDescription() { + if (!isInternetAvailable()) { + return R.string.no_index_file_to_download; } + return download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr; } - private void updateProgressBar(DownloadUpdateVH holder) { - if (isLoadingInProgress()) { - int progress = app.getDownloadThread().getCurrentDownloadingItemProgress(); - holder.progressBar.setProgress(progress < 0 ? 0 : progress); - } else { - holder.progressBar.setProgress(0); - } + @Override + public int getIconRes() { + return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon; } @Override public int getCardType() { return TYPE; } - - @NonNull - private String getTitle(boolean loading) { - if (loading) { - return app.getString(R.string.shared_string_downloading); - } - return app.getString(download ? R.string.download_file : R.string.update_is_available); - } - - private int getIconRes() { - return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon; - } - - @NonNull - private String getDescription() { - if (!isInternetAvailable()) { - return app.getString(R.string.no_index_file_to_download); - } - return app.getString(download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr); - } - - @NonNull - private String getFileTitle() { - return indexItem == null ? "" : indexItem.getVisibleName(app, app.getRegions(), false); - } - - @NonNull - private String getFileDescription() { - StringBuilder sb = new StringBuilder(); - if (indexItem != null) { - sb.append(app.getString(R.string.file_size_in_mb, indexItem.getArchiveSizeMB())); - sb.append(" • "); - sb.append(indexItem.getRemoteDate(dateFormat)); - } - return sb.toString(); - } - - private Drawable getFileIcon() { - return getActiveIcon(R.drawable.ic_action_read_article); - } - - /** - * @return true if button is visible, false otherwise. - */ - private boolean updateSecondaryButton(DownloadUpdateVH vh, boolean loading) { - if (loading || !download || showOtherMapsBtn) { - vh.secondaryBtnContainer.setVisibility(View.VISIBLE); - vh.secondaryBtn.setText(getSecondaryBtnTextId(loading)); - vh.secondaryBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (listener != null) { - listener.onSecondaryButtonClick(); - } - } - }); - return true; - } - vh.secondaryBtnContainer.setVisibility(View.GONE); - return false; - } - - @StringRes - private int getSecondaryBtnTextId(boolean loading) { - if (loading) { - return R.string.shared_string_cancel; - } - if (!download) { - return R.string.later; - } - return R.string.download_select_map_types; - } - - /** - * @return true if button is visible, false otherwise. - */ - private boolean updatePrimaryButton(DownloadUpdateVH vh, boolean loading) { - if (!loading) { - boolean enabled = isInternetAvailable(); - vh.primaryBtnContainer.setVisibility(View.VISIBLE); - vh.primaryBtnContainer.setBackgroundResource(getPrimaryBtnBgRes(enabled)); - vh.primaryButton.setTextColor(getResolvedColor(getPrimaryBtnTextColorRes(enabled))); - vh.primaryButton.setEnabled(enabled); - vh.primaryButton.setText(download ? R.string.shared_string_download : R.string.shared_string_update); - vh.primaryButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (listener != null) { - listener.onPrimaryButtonClick(); - } - } - }); - return true; - } - vh.primaryBtnContainer.setVisibility(View.GONE); - return false; - } - - public boolean isLoading() { - return indexItem != null && app.getDownloadThread().isDownloading(indexItem); - } - - private boolean isLoadingInProgress() { - IndexItem current = app.getDownloadThread().getCurrentDownloadingItem(); - return indexItem != null && current != null && indexItem == current; - } - - public interface ClickListener { - - void onPrimaryButtonClick(); - - void onSecondaryButtonClick(); - } - - public static class DownloadUpdateVH extends RecyclerView.ViewHolder { - - final TextView title; - final ImageView icon; - final TextView description; - final View fileDataContainer; - final ImageView fileIcon; - final TextView fileTitle; - final TextView fileDescription; - final ProgressBar progressBar; - final View secondaryBtnContainer; - final TextView secondaryBtn; - final View buttonsDivider; - final View primaryBtnContainer; - final TextView primaryButton; - - @SuppressWarnings("RedundantCast") - public DownloadUpdateVH(View itemView) { - super(itemView); - title = (TextView) itemView.findViewById(R.id.title); - icon = (ImageView) itemView.findViewById(R.id.icon); - description = (TextView) itemView.findViewById(R.id.description); - fileDataContainer = itemView.findViewById(R.id.file_data_container); - fileIcon = (ImageView) itemView.findViewById(R.id.file_icon); - fileTitle = (TextView) itemView.findViewById(R.id.file_title); - fileDescription = (TextView) itemView.findViewById(R.id.file_description); - progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar); - secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container); - secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button); - buttonsDivider = itemView.findViewById(R.id.buttons_divider); - primaryBtnContainer = itemView.findViewById(R.id.primary_btn_container); - primaryButton = (TextView) itemView.findViewById(R.id.primary_button); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java index 505a2095f6..900c80f1a2 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelNeededMapsCard.java @@ -9,7 +9,9 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import androidx.recyclerview.widget.RecyclerView; import net.osmand.plus.OsmandApplication; @@ -60,8 +62,12 @@ public class TravelNeededMapsCard extends BaseTravelCard { if (viewHolder instanceof NeededMapsVH) { NeededMapsVH holder = (NeededMapsVH) viewHolder; ref = new WeakReference(holder); - holder.description.setText(isInternetAvailable() - ? R.string.maps_you_need_descr : R.string.no_index_file_to_download); + holder.title.setText(getTitle()); + holder.description.setText(getDescription()); + int iconRes = getIconRes(); + if (iconRes > 0) { + holder.icon.setImageResource(iconRes); + } adjustChildCount(holder.itemsContainer); updateView(holder); @@ -71,7 +77,23 @@ public class TravelNeededMapsCard extends BaseTravelCard { holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE); } } - + + @StringRes + public int getTitle() { + return R.string.maps_you_need; + } + + @StringRes + public int getDescription() { + return isInternetAvailable() + ? R.string.maps_you_need_descr : R.string.no_index_file_to_download; + } + + @DrawableRes + public int getIconRes() { + return 0; + } + public void updateView() { if (ref != null) { NeededMapsVH holder = ref.get(); @@ -227,7 +249,9 @@ public class TravelNeededMapsCard extends BaseTravelCard { public static class NeededMapsVH extends RecyclerView.ViewHolder { + final TextView title; final TextView description; + final ImageView icon; final LinearLayout itemsContainer; final View secondaryBtnContainer; final TextView secondaryBtn; @@ -238,7 +262,9 @@ public class TravelNeededMapsCard extends BaseTravelCard { @SuppressWarnings("RedundantCast") public NeededMapsVH(View itemView) { super(itemView); + title = (TextView) itemView.findViewById(R.id.title); description = (TextView) itemView.findViewById(R.id.description); + icon = (ImageView) itemView.findViewById(R.id.icon); itemsContainer = (LinearLayout) itemView.findViewById(R.id.items_container); secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container); secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button); From 1c8fcefcc0d5966be27365c7e1ced4e523f027fc Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 4 Feb 2021 12:13:05 +0200 Subject: [PATCH 056/398] add bottom sheet for track recording process --- .../layout/bottom_sheet_button_with_icon.xml | 59 +++++ OsmAnd/res/layout/item_gpx_stat_block.xml | 2 + .../layout/trip_recording_active_fragment.xml | 155 +++++++++++ OsmAnd/res/values/strings.xml | 1 + .../monitoring/OsmandMonitoringPlugin.java | 4 +- .../TripRecordingActiveBottomSheet.java | 244 ++++++++++++++++++ 6 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_button_with_icon.xml create mode 100644 OsmAnd/res/layout/trip_recording_active_fragment.xml create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml new file mode 100644 index 0000000000..ba24cc289c --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/item_gpx_stat_block.xml b/OsmAnd/res/layout/item_gpx_stat_block.xml index dd0ed2a571..f180bdb73f 100644 --- a/OsmAnd/res/layout/item_gpx_stat_block.xml +++ b/OsmAnd/res/layout/item_gpx_stat_block.xml @@ -31,6 +31,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:background="@null" + android:letterSpacing="@dimen/description_letter_spacing" android:lines="1" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/default_desc_text_size" @@ -61,6 +62,7 @@ android:layout_height="wrap_content" android:background="@null" android:ellipsize="end" + android:letterSpacing="@dimen/description_letter_spacing" android:lines="1" android:maxWidth="@dimen/grid_menu_item_width" android:textColor="?android:attr/textColorSecondary" diff --git a/OsmAnd/res/layout/trip_recording_active_fragment.xml b/OsmAnd/res/layout/trip_recording_active_fragment.xml new file mode 100644 index 0000000000..4f45d49fc9 --- /dev/null +++ b/OsmAnd/res/layout/trip_recording_active_fragment.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 1d23e9db07..20294eb4e9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + On pause Hillshade / Slope / Contour lines Select edits for upload Uploaded %1$d of %2$d diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 42bae2ab62..1ddb443891 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -318,7 +318,9 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public void controlDialog(final Activity activity, final boolean showTrackSelection) { - final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); + /*final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); final boolean nightMode; if (activity instanceof MapActivity) { nightMode = app.getDaynightHelper().isNightModeForMapControls(); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java new file mode 100644 index 0000000000..6234d58b18 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -0,0 +1,244 @@ +package net.osmand.plus.monitoring; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.SwitchCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; + +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.TrackAppearanceFragment; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.util.Algorithms; + +import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; + +public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = TripRecordingActiveBottomSheet.class.getSimpleName(); + + private OsmandApplication app; + private OsmandSettings settings; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + settings = app.getSettings(); + Context context = requireContext(); + + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); + items.add(new BottomSheetItemWithDescription.Builder() + .setCustomView(itemView) + .create()); + + TextView statusTitle = itemView.findViewById(R.id.status); + statusTitle.setText(ItemType.SEARCHING_GPS.titleId); + statusTitle.setTextColor(ContextCompat.getColor(app, getSecondaryTextColorId())); + ImageView statusIcon = itemView.findViewById(R.id.icon_status); + Drawable statusDrawable = UiUtilities.tintDrawable( + AppCompatResources.getDrawable(app, ItemType.SEARCHING_GPS.iconId), + ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light) + ); + statusIcon.setImageDrawable(statusDrawable); + + View buttonClear = itemView.findViewById(R.id.button_clear); + View buttonStart = itemView.findViewById(R.id.button_start); + View buttonSave = itemView.findViewById(R.id.button_save); + View buttonPause = itemView.findViewById(R.id.button_pause); + View buttonStop = itemView.findViewById(R.id.button_stop); + + createButton(buttonClear, ItemType.CLEAR_DATA, true, null); + createButton(buttonStart, ItemType.START_SEGMENT, true, null); + createButton(buttonSave, ItemType.SAVE, true, "17 min. ago"); + createButton(buttonPause, ItemType.PAUSE, true, null); + createButton(buttonStop, ItemType.STOP, true, null); + + LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); + TextView showTrackOnMapTitle = showTrackOnMapView.findViewById(R.id.title); + showTrackOnMapTitle.setText(R.string.show_track_on_map); + + ImageView trackAppearanceIcon = showTrackOnMapView.findViewById(R.id.icon_after_divider); + + int color = settings.CURRENT_TRACK_COLOR.get(); + String width = settings.CURRENT_TRACK_WIDTH.get(); + boolean showArrows = settings.CURRENT_TRACK_SHOW_ARROWS.get(); + Drawable drawable = TrackAppearanceFragment.getTrackIcon(app, width, showArrows, color); + + trackAppearanceIcon.setImageDrawable(drawable); + trackAppearanceIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + hide(); + GpxSelectionHelper.SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, TripRecordingActiveBottomSheet.this); + } + } + }); + + final SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); + showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); + View basicItem = itemView.findViewById(R.id.basic_item_body); + basicItem.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = !showTrackOnMapButton.isChecked(); + showTrackOnMapButton.setChecked(checked); + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); + } + }); + UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + + } + + private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { + + Context ctx = view.getContext(); + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { + view.setBackground(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); + } else { + view.setBackgroundDrawable(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); + } + + TextViewEx title = view.findViewById(R.id.title); + TextViewEx desc = view.findViewById(R.id.desc); + AppCompatImageView icon = view.findViewById(R.id.icon); + + title.setText(type.getTitleId()); + title.setTextColor(ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete + : enabled ? getActiveTextColorId() : getSecondaryTextColorId())); + + Drawable tintDrawable = UiUtilities.tintDrawable( + AppCompatResources.getDrawable(ctx, type.iconId), + ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete + : enabled ? getActiveIconColorId() : getSecondaryIconColorId()) + ); + icon.setBackgroundDrawable(tintDrawable); + + boolean isShowDesc = !Algorithms.isBlank(description); + int marginSingle = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + AndroidUiHelper.updateVisibility(desc, isShowDesc); + UiUtilities.setMargins(title, 0, isShowDesc ? 0 : marginSingle, 0, isShowDesc ? 0 : marginSingle); + desc.setText(description); + } + + enum ItemType { + SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), + RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), + ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), + CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), + START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), + SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), + PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); + + @StringRes + private int titleId; + @DrawableRes + private int iconId; + + ItemType(@StringRes int titleId, @DrawableRes int iconId) { + this.titleId = titleId; + this.iconId = iconId; + } + + public int getTitleId() { + return titleId; + } + + public int getIconId() { + return iconId; + } + } + + @ColorRes + protected int getActiveTextColorId() { + return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; + } + + @ColorRes + protected int getSecondaryTextColorId() { + return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; + } + + @ColorRes + protected int getActiveIconColorId() { + return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; + } + + @ColorRes + protected int getSecondaryIconColorId() { + return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light; + } + + @ColorRes + protected int getOsmandIconColorId() { + return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; + } + + @Override + protected int getDismissButtonHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_close; + } + + @Override + protected boolean useVerticalButtons() { + return true; + } + + @Nullable + public MapActivity getMapActivity() { + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } + return null; + } + + public void hide() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + + public static void showInstance(@NonNull FragmentManager fragmentManager) { + if (!fragmentManager.isStateSaved()) { + TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); + fragment.show(fragmentManager, TAG); + } + } +} From 06617378a0ad56d030ae3324d9b8ceca39f7d281 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 4 Feb 2021 15:03:41 +0200 Subject: [PATCH 057/398] Segment navigation --- .../layout/bottom_sheet_select_segment.xml | 88 ++++++++++--------- OsmAnd/res/layout/gpx_segment_list_item.xml | 4 +- .../FollowTrackFragment.java | 15 +++- .../track/TrackSelectSegmentBottomSheet.java | 49 +++++++++-- 4 files changed, 104 insertions(+), 52 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_select_segment.xml b/OsmAnd/res/layout/bottom_sheet_select_segment.xml index de758bc182..427d0d93a8 100644 --- a/OsmAnd/res/layout/bottom_sheet_select_segment.xml +++ b/OsmAnd/res/layout/bottom_sheet_select_segment.xml @@ -5,51 +5,58 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="@dimen/bottom_sheet_selected_item_title_height" - android:orientation="vertical" - android:paddingStart="@dimen/content_padding" - android:paddingLeft="@dimen/content_padding" - android:paddingTop="@dimen/measurement_tool_menu_title_padding_top" - android:paddingEnd="@dimen/content_padding" - android:paddingRight="@dimen/content_padding" - android:paddingBottom="@dimen/content_padding_small"> + android:orientation="vertical"> - + android:orientation="vertical" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/measurement_tool_menu_title_padding_top" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/content_padding_small"> - + - + + + + - \ No newline at end of file diff --git a/OsmAnd/res/layout/gpx_segment_list_item.xml b/OsmAnd/res/layout/gpx_segment_list_item.xml index f591d86e50..8266775053 100644 --- a/OsmAnd/res/layout/gpx_segment_list_item.xml +++ b/OsmAnd/res/layout/gpx_segment_list_item.xml @@ -6,6 +6,8 @@ android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" android:minHeight="@dimen/favorites_list_item_height" + android:paddingTop="@dimen/list_header_settings_top_margin" + android:paddingBottom="@dimen/list_header_settings_top_margin" android:orientation="horizontal"> + osmand:srcCompat="@drawable/ic_action_distance_16" /> 1; String fileName = null; File file = null; if (!Algorithms.isEmpty(gpxFile.path)) { file = new File(gpxFile.path); - fileName = file.getName(); + if (isTrackContainsMultiSegment) { + fileName = Algorithms.getFileNameWithoutExtension(file.getName()); + } else { + fileName = Algorithms.getFileNameWithoutExtension(file.getName()); + } } else if (!Algorithms.isEmpty(gpxFile.tracks)) { fileName = gpxFile.tracks.get(0).name; } @@ -489,9 +494,12 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca GPXInfo gpxInfo = card.getGpxInfoList().get(index); String fileName = gpxInfo.getFileName(); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); - if (selectedGpxFile != null) { + boolean isTrackContainsMultiSegment = selectedGpxFile.getGpxFile().getNonEmptySegmentsCount() > 1; + if (selectedGpxFile != null && !isTrackContainsMultiSegment) { selectTrackToFollow(selectedGpxFile.getGpxFile()); updateSelectionMode(false); + } else if (selectedGpxFile != null && isTrackContainsMultiSegment) { + TrackSelectSegmentBottomSheet.showInstance(getFragmentManager(), selectedGpxFile); } else { CallbackWithObject callback = new CallbackWithObject() { @Override @@ -702,6 +710,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca } } + @Override public void routeWasCancelled() { diff --git a/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java index 199e30c1cd..03065539e8 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java @@ -1,7 +1,11 @@ package net.osmand.plus.track; import android.content.Context; +import android.graphics.Typeface; import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; @@ -10,15 +14,19 @@ import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.TrackSelectSegmentAdapter; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -44,31 +52,58 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); View itemView = inflater.inflate(R.layout.bottom_sheet_select_segment, null, false); - String titleGpxTrack = Algorithms.getFileWithoutDirs(file.getGpxFile().path); - - items.add(new BottomSheetItemWithDescription.Builder() - .setDescription(getString(R.string.select_segments_description, titleGpxTrack)) - .setCustomView(itemView) - .create()); OsmandApplication app = getMyApplication(); if (app == null) { return; } + + String titleGpxTrack = Algorithms.getFileWithoutDirs(file.getGpxFile().path); + Typeface typeface = FontCache.getRobotoMedium(app); + SpannableString spannable = UiUtilities.createCustomFontSpannable(typeface, titleGpxTrack, titleGpxTrack, titleGpxTrack); + int descriptionColor = getResolvedColor(nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light); + ForegroundColorSpan colorSpan = new ForegroundColorSpan(descriptionColor); + spannable.setSpan(colorSpan, 0, titleGpxTrack.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(getString(R.string.select_segments_description, spannable)) + .setCustomView(itemView) + .create()); + TextViewEx titleGpxTrackView = itemView.findViewById(R.id.title_gpx_track); titleGpxTrackView.setText(titleGpxTrack); final RecyclerView recyclerView = itemView.findViewById(R.id.gpx_segment_list); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setNestedScrollingEnabled(false); - List segments = file.getPointsToDisplay(); + final List segments = file.getPointsToDisplay(); adapterSegments = new TrackSelectSegmentAdapter(requireContext(), segments); adapterSegments.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() { @Override public void onItemClick(int position) { + selectSegmentToFollow(segments.get(position), file); + dismiss(); } }); recyclerView.setAdapter(adapterSegments); } + + private void selectSegmentToFollow(TrkSegment segment, GpxSelectionHelper.SelectedGpxFile file) { + MapActivity mapActivity = (MapActivity) getActivity(); + if (mapActivity != null) { + List points = segment.points; + if (!points.isEmpty()) { + ApplicationMode mode = ApplicationMode.valueOfStringKey(points.get(0).getProfileType(), null); + if (mode != null) { + getMyApplication().getRoutingHelper().setAppMode(mode); + getMyApplication().initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); + } + } + mapActivity.getMapActions().setGPXRouteParams(file.getGpxFile()); + getMyApplication().getTargetPointsHelper().updateRouteAndRefresh(true); + getMyApplication().getRoutingHelper().onSettingsChanged(true); + } + } } + From b35e8ea6bedea6c3d9e1e7680fc410a01808bb27 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 4 Feb 2021 16:46:51 +0300 Subject: [PATCH 058/398] Process xml namespaces for java --- OsmAnd-java/src/main/java/net/osmand/PlatformUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/PlatformUtil.java b/OsmAnd-java/src/main/java/net/osmand/PlatformUtil.java index ffc9bf05b0..fd3fa2e2eb 100644 --- a/OsmAnd-java/src/main/java/net/osmand/PlatformUtil.java +++ b/OsmAnd-java/src/main/java/net/osmand/PlatformUtil.java @@ -23,7 +23,9 @@ public class PlatformUtil { } public static XmlPullParser newXMLPullParser() throws XmlPullParserException{ - return new org.kxml2.io.KXmlParser(); + org.kxml2.io.KXmlParser xmlParser = new org.kxml2.io.KXmlParser(); + xmlParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + return xmlParser; } public static XmlSerializer newSerializer() { From 8a5ff112642e25c1dbcc11804602ad454ea46c69 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 4 Feb 2021 19:24:44 +0100 Subject: [PATCH 059/398] Fix search --- .../osmand/binary/BinaryMapIndexReader.java | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java index d00bbcd09f..dc16b89f30 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java @@ -2163,7 +2163,7 @@ public class BinaryMapIndexReader { private static boolean testAddressJustifySearch = false; private static boolean testPoiSearch = true; private static boolean testPoiSearchOnPath = false; - private static boolean testTransportSearch = true; + private static boolean testTransportSearch = false; private static int sleft = MapUtils.get31TileNumberX(27.55079); private static int sright = MapUtils.get31TileNumberX(27.55317); @@ -2177,7 +2177,7 @@ public class BinaryMapIndexReader { public static void main(String[] args) throws IOException { File fl = new File(System.getProperty("maps") + "/Synthetic_test_rendering.obf"); - fl = new File("/Users/plotva/work/osmand/maps/Wikivoyage.obf"); + fl = new File(System.getProperty("maps") +"/Wikivoyage.obf__"); RandomAccessFile raf = new RandomAccessFile(fl, "r"); @@ -2385,8 +2385,10 @@ public class BinaryMapIndexReader { } - void readIndexedStringTable(Collator instance, List queries, String prefix, List listOffsets, TIntArrayList charMatchesList) throws IOException { + void readIndexedStringTable(Collator instance, List queries, String prefix, List listOffsets, TIntArrayList matchedCharacters) throws IOException { String key = null; + boolean[] matched = new boolean[matchedCharacters.size()]; + boolean shouldWeReadSubtable = false; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); @@ -2398,41 +2400,41 @@ public class BinaryMapIndexReader { if (prefix.length() > 0) { key = prefix + key; } + shouldWeReadSubtable = false; for (int i = 0; i < queries.size(); i++) { - int charMatches = charMatchesList.get(i); - if (charMatches < 0) { + int charMatches = matchedCharacters.get(i); + String query = queries.get(i); + matched[i] = false; + if (query == null) { continue; } - String query = queries.get(i); + // check query is part of key (the best matching) if (CollatorStringMatcher.cmatches(instance, key, query, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { if (query.length() >= charMatches) { if (query.length() > charMatches) { - charMatchesList.set(i, query.length()); + matchedCharacters.set(i, query.length()); listOffsets.get(i).clear(); } - } else { - charMatchesList.set(i, -1); + matched[i] = true; } // check key is part of query } else if (CollatorStringMatcher.cmatches(instance, query, key, StringMatcherMode.CHECK_ONLY_STARTS_WITH)) { if (key.length() >= charMatches) { if (key.length() > charMatches) { - charMatchesList.set(i, key.length()); + matchedCharacters.set(i, key.length()); listOffsets.get(i).clear(); } - } else { - charMatchesList.set(i, -1); + matched[i] = true; } - } else { - charMatchesList.set(i, -1); } + shouldWeReadSubtable |= matched[i]; } break; case OsmandOdb.IndexedStringTable.VAL_FIELD_NUMBER : int val = readInt(); for (int i = 0; i < queries.size(); i++) { - if (charMatchesList.get(i) >= 0) { + if (matched[i]) { listOffsets.get(i).add(val); } } @@ -2440,21 +2442,15 @@ public class BinaryMapIndexReader { case OsmandOdb.IndexedStringTable.SUBTABLES_FIELD_NUMBER : int len = codedIS.readRawVarint32(); int oldLim = codedIS.pushLimit(len); - boolean shouldWeReadSubtable = false; - for (int i = 0; i < queries.size(); i++) { - if (charMatchesList.get(i) >= 0) { - shouldWeReadSubtable = true; - } - } if (shouldWeReadSubtable && key != null) { - TIntArrayList subcharMatchesList = new TIntArrayList(charMatchesList); - readIndexedStringTable(instance, queries, key, listOffsets, subcharMatchesList); - // looks like true - for (int i = 0; i < queries.size(); i++) { - if (subcharMatchesList.get(i) >= charMatchesList.get(i)) { - charMatchesList.set(i, subcharMatchesList.get(i)); + List subqueries = new ArrayList<>(queries); + // reset query so we don't search what was not matched + for(int i = 0; i < queries.size(); i++) { + if(!matched[i]) { + subqueries.set(i, null); } - } + } + readIndexedStringTable(instance, subqueries, key, listOffsets, matchedCharacters); } else { codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); } From c2281b8fe19105e24f5797f13e74f60c2849413f Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 11:34:01 +0100 Subject: [PATCH 060/398] Create config.yml --- .github/ISSUE_TEMPLATE/config.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..7410b26a46 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Outdated FAQ + - url: https://groups.google.com/forum/#!forum/osmand + - about: Fix wrong or outdated FAQ on the forum instead From dfa8ab27fcb9a16168f8df5c439ba2fa6c6f1491 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 11:35:39 +0100 Subject: [PATCH 061/398] Delete 2-faq-report.md --- .github/ISSUE_TEMPLATE/2-faq-report.md | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/2-faq-report.md diff --git a/.github/ISSUE_TEMPLATE/2-faq-report.md b/.github/ISSUE_TEMPLATE/2-faq-report.md deleted file mode 100644 index 531d263d7f..0000000000 --- a/.github/ISSUE_TEMPLATE/2-faq-report.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: "📚 Outdated FAQ" -about: Report an issue in FAQ ---- - -🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑 - -Please do not file FAQ issues on the GitHub issues tracker. - -Instead use the [Google group](https://groups.google.com/forum/#!forum/osmand) to fix wrong or outdated FAQ. - -🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑 From 982c09b450fa10bdd8d3350e21a1af46772bcc50 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 11:36:52 +0100 Subject: [PATCH 062/398] Rename 3-bug-report.md to 2-bug-report.md --- .github/ISSUE_TEMPLATE/{3-bug-report.md => 2-bug-report.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{3-bug-report.md => 2-bug-report.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/2-bug-report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/3-bug-report.md rename to .github/ISSUE_TEMPLATE/2-bug-report.md From 414e11fb618e7af234fd20b7715e7fd2a75b42d6 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 11:36:59 +0100 Subject: [PATCH 063/398] Rename 4-routing-report.md to 3-routing-report.md --- .../ISSUE_TEMPLATE/{4-routing-report.md => 3-routing-report.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{4-routing-report.md => 3-routing-report.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/4-routing-report.md b/.github/ISSUE_TEMPLATE/3-routing-report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/4-routing-report.md rename to .github/ISSUE_TEMPLATE/3-routing-report.md From 5a99cd8255d7c8cbccbc71200a10e65925fa878e Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 11:37:14 +0100 Subject: [PATCH 064/398] Rename 5-feature-request.md to 4-feature-request.md --- .../ISSUE_TEMPLATE/{5-feature-request.md => 4-feature-request.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{5-feature-request.md => 4-feature-request.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/5-feature-request.md b/.github/ISSUE_TEMPLATE/4-feature-request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/5-feature-request.md rename to .github/ISSUE_TEMPLATE/4-feature-request.md From ba2cd944a63c21d78580f7c206421ea29ec40fa5 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Fri, 5 Feb 2021 16:08:15 +0300 Subject: [PATCH 065/398] Add phrases --- OsmAnd/res/values/phrases.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 3b5feac342..13efca2404 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4332,5 +4332,12 @@ Bat bridge Bat tunnel + Ski jump + Piste name + Gladed: yes + Patrolled: yes + Patrolled: no + Piste status: open + Piste status: closed From 5605e33c3238941e798da548fad99886d61648bd Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 5 Feb 2021 19:31:57 +0500 Subject: [PATCH 066/398] Add bottom sheet dialogs to clear recoderd data and stop trip recording --- .../bottom_sheet_item_button_with_icon.xml | 69 +++++++ OsmAnd/res/values/sizes.xml | 2 + OsmAnd/res/values/strings.xml | 4 + .../ClearRecordedDataBottomSheetFragment.java | 160 +++++++++++++++ .../StopTrackRecordingBottomFragment.java | 187 ++++++++++++++++++ 5 files changed, 422 insertions(+) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java diff --git a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml new file mode 100644 index 0000000000..9b2b395ccb --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml index a086849297..afdc8438af 100644 --- a/OsmAnd/res/values/sizes.xml +++ b/OsmAnd/res/values/sizes.xml @@ -413,4 +413,6 @@ 32dp 24dp + + 0dp \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a15fb40cbd..905a947661 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,10 @@ --> + Are you sure you want to stop recording?\nAll unsaved data will be lost. + Track recording stopped + Save and stop recording + Stop without saving Login to OpenPlaceReviews Use test.openplacereviews.org OpenPlaceReviews diff --git a/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java new file mode 100644 index 0000000000..971bfd01e0 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java @@ -0,0 +1,160 @@ +package net.osmand.plus.monitoring; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.widgets.TextViewEx; + +import androidx.annotation.DimenRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogFragment implements View.OnClickListener { + + public static final String TAG = ClearRecordedDataBottomSheetFragment.class.getSimpleName(); + + private OsmandApplication app; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(app.getString(R.string.clear_recorded_data_warning)) + .setDescriptionColorId(!nightMode ? R.color.text_color_primary_light : R.color.text_color_primary_dark) + .setDescriptionMaxLines(2) + .setTitle(app.getString(R.string.clear_recorded_data)) + .setLayoutId(R.layout.bottom_sheet_item_title_with_description) + .create()); + + LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupBtn(inflater, ButtonType.CLEAR)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupBtn(inflater, ButtonType.CANCEL)) + .setOnClickListener(this) + .create()); + + } + + private View setupBtn(LayoutInflater inflater, ButtonType type) { + View button = inflater.inflate(R.layout.bottom_sheet_item_button_with_icon, null); + button.setTag(type); + Context context = button.getContext(); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding); + int top = context.getResources().getDimensionPixelSize(type.topMarginRes); + int bottom = context.getResources().getDimensionPixelSize(R.dimen.content_padding_small); + params.setMargins(horizontal, top, horizontal, bottom); + button.setLayoutParams(params); + + UiUtilities.setupDialogButton(nightMode, button, type.effect, type.titleId); + + TextViewEx title = button.findViewById(R.id.button_text); + int margin = context.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + UiUtilities.setMargins(title, 0, margin, 0, margin); + + int colorRes; + if (type.effect == UiUtilities.DialogButtonType.SECONDARY_HARMFUL) { + colorRes = R.color.color_osm_edit_delete; + } else { + colorRes = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light; + } + AppCompatImageView icon = button.findViewById(R.id.icon); + icon.setImageDrawable(getIcon(type.iconRes, colorRes)); + + return button; + } + + @Override + public void onClick(View v) { + Object o = v.getTag(); + if (!(o instanceof ButtonType)) { + return; + } + + ButtonType tag = (ButtonType) o; + if (tag == ButtonType.CLEAR) { + app.getSavingTrackHelper().clearRecordedData(true); + } + dismiss(); + } + + @Override + public void onResume() { + super.onResume(); + // Replace later with tTripRecordingActiveBottomSheet.hide() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + } + + @Override + public void onPause() { + super.onPause(); + // Replace later with tTripRecordingActiveBottomSheet.show() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.show(); + } + } + } + + enum ButtonType { + CLEAR(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark, R.dimen.dialog_content_margin, UiUtilities.DialogButtonType.SECONDARY_HARMFUL), + CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close, R.dimen.content_padding_small, UiUtilities.DialogButtonType.SECONDARY); + + @StringRes + private final int titleId; + @DrawableRes + private final int iconRes; + @DimenRes + private final int topMarginRes; + private final UiUtilities.DialogButtonType effect; + + ButtonType(int titleId, int iconRes, int topMarginRes, UiUtilities.DialogButtonType effect) { + this.titleId = titleId; + this.iconRes = iconRes; + this.topMarginRes = topMarginRes; + this.effect = effect; + } + } + + @Override + protected boolean hideButtonsContainer() { + return true; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + if (!fragmentManager.isStateSaved()) { + ClearRecordedDataBottomSheetFragment fragment = new ClearRecordedDataBottomSheetFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java new file mode 100644 index 0000000000..b7bf829457 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java @@ -0,0 +1,187 @@ +package net.osmand.plus.monitoring; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.widgets.TextViewEx; + +import androidx.annotation.DimenRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragment implements View.OnClickListener { + + public static final String TAG = StopTrackRecordingBottomFragment.class.getSimpleName(); + + private OsmandApplication app; + private OsmandSettings settings; + private OsmandMonitoringPlugin plugin; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + settings = app.getSettings(); + plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(app.getString(R.string.track_recording_description)) + .setDescriptionColorId(!nightMode ? R.color.text_color_primary_light : R.color.text_color_primary_dark) + .setDescriptionMaxLines(4) + .setTitle(app.getString(R.string.track_recording_title)) + .setLayoutId(R.layout.bottom_sheet_item_title_with_description) + .create()); + + LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.STOP_AND_DISCARD)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.SAVE_AND_STOP)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.CANCEL)) + .setOnClickListener(this) + .create()); + } + + private View setupButton(LayoutInflater inflater, ButtonType type) { + View button = inflater.inflate(R.layout.bottom_sheet_item_button_with_icon, null); + button.setTag(type); + Context context = button.getContext(); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding); + int top = context.getResources().getDimensionPixelSize(type.topMarginRes); + int bottom = context.getResources().getDimensionPixelSize(R.dimen.content_padding_small); + params.setMargins(horizontal, top, horizontal, bottom); + button.setLayoutParams(params); + + UiUtilities.setupDialogButton(nightMode, button, type.effect, type.titleId); + + TextViewEx title = button.findViewById(R.id.button_text); + int margin = context.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + UiUtilities.setMargins(title, 0, margin, 0, margin); + + int colorRes; + if (type.effect == DialogButtonType.SECONDARY_HARMFUL) { + colorRes = R.color.color_osm_edit_delete; + } else { + colorRes = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light; + } + AppCompatImageView icon = button.findViewById(R.id.icon); + icon.setImageDrawable(getIcon(type.iconRes, colorRes)); + + if (type == ButtonType.STOP_AND_DISCARD) { + int size = context.getResources().getDimensionPixelSize(R.dimen.map_widget_height); + LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(size, size); + icon.setLayoutParams(iconParams); + } + + return button; + } + + @Override + public void onClick(View v) { + Object o = v.getTag(); + if (!(o instanceof ButtonType)) { + return; + } + + ButtonType tag = (ButtonType) o; + if (tag == ButtonType.STOP_AND_DISCARD) { + if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { + plugin.stopRecording(); + app.getNotificationHelper().refreshNotifications(); + } + app.getSavingTrackHelper().clearRecordedData(true); + } else if (tag == ButtonType.SAVE_AND_STOP) { + if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { + plugin.saveCurrentTrack(); + app.getNotificationHelper().refreshNotifications(); + } + } + dismiss(); + } + + @Override + public void onResume() { + super.onResume(); + // Replace later with tTripRecordingActiveBottomSheet.hide() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + } + + @Override + public void onPause() { + super.onPause(); + // Replace later with tTripRecordingActiveBottomSheet.show() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.show(); + } + } + } + + enum ButtonType { + STOP_AND_DISCARD(R.string.track_recording_stop_without_saving, R.drawable.ic_action_rec_stop, R.dimen.dialog_content_margin, DialogButtonType.SECONDARY_HARMFUL), + SAVE_AND_STOP(R.string.track_recording_save_and_stop, R.drawable.ic_action_save_to_file, R.dimen.content_padding_small, DialogButtonType.SECONDARY), + CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close, R.dimen.zero, DialogButtonType.SECONDARY); + + @StringRes + private final int titleId; + @DrawableRes + private final int iconRes; + @DimenRes + private final int topMarginRes; + private final DialogButtonType effect; + + ButtonType(int titleId, int iconRes, int topMarginRes, DialogButtonType type) { + this.titleId = titleId; + this.iconRes = iconRes; + this.topMarginRes = topMarginRes; + this.effect = type; + } + } + + @Override + protected boolean hideButtonsContainer() { + return true; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + if (!fragmentManager.isStateSaved()) { + StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + } + } +} From 08b5e9fdf993e25a4f4c1ed2dfe94fc08fb472e7 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Fri, 5 Feb 2021 18:32:54 +0200 Subject: [PATCH 067/398] Add Show more button --- OsmAnd/res/layout/wikivoyage_button_card.xml | 26 +++++++ .../plus/wikivoyage/data/TravelDbHelper.java | 10 +-- .../plus/wikivoyage/data/TravelHelper.java | 6 +- .../plus/wikivoyage/data/TravelObfHelper.java | 76 +++++++++++-------- .../wikivoyage/explore/ExploreRvAdapter.java | 8 ++ .../explore/ExploreTabFragment.java | 27 ++++++- .../explore/WikivoyageExploreActivity.java | 16 ++-- .../explore/travelcards/TravelButtonCard.java | 56 ++++++++++++++ 8 files changed, 178 insertions(+), 47 deletions(-) create mode 100644 OsmAnd/res/layout/wikivoyage_button_card.xml create mode 100644 OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelButtonCard.java diff --git a/OsmAnd/res/layout/wikivoyage_button_card.xml b/OsmAnd/res/layout/wikivoyage_button_card.xml new file mode 100644 index 0000000000..412fd36f5d --- /dev/null +++ b/OsmAnd/res/layout/wikivoyage_button_card.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index b53605a0bb..90e6444cff 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -174,9 +174,9 @@ public class TravelDbHelper implements TravelHelper { } @Override - public void initializeDataToDisplay() { + public void initializeDataToDisplay(boolean showMore) { localDataHelper.refreshCachedData(); - loadPopularArticles(); + loadPopularArticles(showMore); } @@ -283,7 +283,7 @@ public class TravelDbHelper implements TravelHelper { } @NonNull - public List loadPopularArticles() { + public List loadPopularArticles(boolean showMore) { String language = application.getLanguage(); SQLiteConnection conn = openConnection(); if (conn == null) { @@ -292,7 +292,7 @@ public class TravelDbHelper implements TravelHelper { } String LANG_WHERE = " WHERE " + ARTICLES_COL_LANG + " = '" + language + "'"; SQLiteCursor cursor = conn.rawQuery(POP_ARTICLES_TABLE_SELECT + LANG_WHERE, null); - if(cursor == null) { + if (cursor == null) { return popularArticles; } // read popular articles @@ -549,7 +549,7 @@ public class TravelDbHelper implements TravelHelper { @Override @Nullable - public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback) { + public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, String lang, boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle res = null; SQLiteConnection conn = openConnection(); String routeId = articleId.routeId; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java index 967138b0bd..4688dd7ff0 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -3,7 +3,6 @@ package net.osmand.plus.wikivoyage.data; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.data.LatLon; import net.osmand.data.QuadRect; @@ -25,7 +24,7 @@ public interface TravelHelper { void initializeDataOnAppStartup(); - void initializeDataToDisplay(); + void initializeDataToDisplay(boolean showMore); boolean isAnyTravelBookPresent(); @@ -35,6 +34,9 @@ public interface TravelHelper { @NonNull List getPopularArticles(); + @NonNull + List loadPopularArticles(boolean showMore); + @NonNull Map> getNavigationMap(@NonNull TravelArticle article); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index f230929f1d..162616e063 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -68,9 +68,7 @@ public class TravelObfHelper implements TravelHelper { public static final String ROUTE_ARTICLE = "route_article"; public static final String ROUTE_ARTICLE_POINT = "route_article_point"; public static final String ROUTE_TRACK = "route_track"; - public static final int POPULAR_ARTICLES_SEARCH_RADIUS = 100000; public static final int ARTICLE_SEARCH_RADIUS = 50000; - public static final int GPX_TRACKS_SEARCH_RADIUS = 10000; public static final int MAX_POPULAR_ARTICLES_COUNT = 30; public static final String REF_TAG = "ref"; public static final String NAME_TAG = "name"; @@ -81,6 +79,10 @@ public class TravelObfHelper implements TravelHelper { private List popularArticles = new ArrayList<>(); private final Map> cachedArticles = new ConcurrentHashMap<>(); private final TravelLocalDataHelper localDataHelper; + private int searchRadius = ARTICLE_SEARCH_RADIUS; + private int count = 0; + private int page = 0; + final List> amenities = new ArrayList<>(); public TravelObfHelper(OsmandApplication app) { this.app = app; @@ -98,48 +100,54 @@ public class TravelObfHelper implements TravelHelper { } @Override - public void initializeDataToDisplay() { + public void initializeDataToDisplay(boolean showMore) { localDataHelper.refreshCachedData(); - loadPopularArticles(); + loadPopularArticles(showMore); } @NonNull - public synchronized List loadPopularArticles() { + public synchronized List loadPopularArticles(boolean showMore) { String lang = app.getLanguage(); List popularArticles = new ArrayList<>(); - final List> amenities = new ArrayList<>(); - final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); - for (final BinaryMapIndexReader reader : getReaders()) { - try { - searchAmenity(amenities, location, reader, POPULAR_ARTICLES_SEARCH_RADIUS, -1, ROUTE_ARTICLE); - searchAmenity(amenities, location, reader, GPX_TRACKS_SEARCH_RADIUS, 15, ROUTE_TRACK); - } catch (Exception e) { - LOG.error(e.getMessage(), e); + if (amenities.size() - count < MAX_POPULAR_ARTICLES_COUNT) { + final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); + for (final BinaryMapIndexReader reader : getReaders()) { + try { + searchAmenity(amenities, location, reader, searchRadius, -1, ROUTE_ARTICLE); + searchAmenity(amenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } } + if (amenities.size() > 0) { + Collections.sort(amenities, new Comparator>() { + @Override + public int compare(Pair article1, Pair article2) { + int d1 = (int) (MapUtils.getDistance(((Amenity) article1.second).getLocation(), location)); + int d2 = (int) (MapUtils.getDistance(((Amenity) article2.second).getLocation(), location)); + return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); + } + }); + } + searchRadius *= 2; } - if (amenities.size() > 0) { - Collections.sort(amenities, new Comparator>() { - @Override - public int compare(Pair article1, Pair article2) { - int d1 = (int) (MapUtils.getDistance(((Amenity) article1.second).getLocation(), location)); - int d2 = (int) (MapUtils.getDistance(((Amenity) article2.second).getLocation(), location)); - return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); - } - }); - for (Pair amenity : amenities) { - if (!Algorithms.isEmpty(amenity.second.getName(lang))) { - TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null); - if (article != null) { - popularArticles.add(article); - if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) { - break; - } + int lastIndex; + for (lastIndex = count; lastIndex < amenities.size() - 1; lastIndex++) { + Pair amenity = amenities.get(lastIndex); + if (!Algorithms.isEmpty(amenity.second.getName(lang))) { + TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null); + if (article != null) { + popularArticles.add(article); + this.popularArticles.add(article); + if (this.popularArticles.size() >= (page + 1) * MAX_POPULAR_ARTICLES_COUNT) { + page++; + break; } } } } - this.popularArticles = popularArticles; + count = ++lastIndex; return popularArticles; } @@ -172,8 +180,10 @@ public class TravelObfHelper implements TravelHelper { } if (!Algorithms.isEmpty(articles)) { TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier(); - cachedArticles.put(newArticleId, articles); - article = getCachedArticle(newArticleId, lang, readPoints, callback); + if (!cachedArticles.containsKey(newArticleId)) { + cachedArticles.put(newArticleId, articles); + article = getCachedArticle(newArticleId, lang, readPoints, callback); + } } return article; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java index b18e04b7f4..923645b775 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java @@ -18,6 +18,8 @@ import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard.OpenBetaTravelVH; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard.TravelButtonVH; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH; @@ -55,6 +57,9 @@ public class ExploreRvAdapter extends RecyclerView.Adapter 0; i--) { BaseTravelCard o = items.get(i); + if (o instanceof TravelButtonCard) { + return 0; + } if (o instanceof ArticleTravelCard || o instanceof TravelGpxCard) { return i; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index f3af57bc6d..2e0cacca65 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -36,6 +36,7 @@ import net.osmand.plus.wikivoyage.explore.travelcards.BaseTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.HeaderTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; @@ -45,6 +46,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; +import static net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity.*; + public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEvents, TravelLocalDataHelper.Listener { private static boolean SHOW_TRAVEL_UPDATE_CARD = true; @@ -172,17 +175,37 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv if (!Version.isPaidVersion(app) && !OpenBetaTravelCard.isClosed()) { items.add(new OpenBetaTravelCard(activity, nightMode)); } - List popularArticles = app.getTravelHelper().getPopularArticles(); + final List popularArticles = app.getTravelHelper().getPopularArticles(); if (!popularArticles.isEmpty()) { items.add(new HeaderTravelCard(app, nightMode, getString(R.string.popular_destinations))); for (TravelArticle article : popularArticles) { if (article instanceof TravelGpx) { - items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, getActivity())); + items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, activity)); } else { items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); } } } + + TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode); + travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() { + @Override + public void onPrimaryButtonClick() { + new LoadWikivoyageData(ExploreTabFragment.this.getExploreActivity(), true).execute(); + } + + @Override + public void onSecondaryButtonClick() { + + } + + @Override + public void onIndexItemClick(IndexItem item) { + + } + }); + items.add(travelButtonCard); + items.add(new StartEditingTravelCard(activity, nightMode)); adapter.setItems(items); final DownloadIndexesThread downloadThread = app.getDownloadThread(); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index dae47525aa..fc28bc6213 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -314,6 +314,10 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv } public void populateData() { + populateData(false); + } + + public void populateData(final boolean showMore) { switchProgressBarVisibility(true); if (app.isApplicationInitializing()) { final WeakReference activityRef = new WeakReference<>(this); @@ -326,12 +330,12 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv public void onFinish(AppInitializer init) { WikivoyageExploreActivity activity = activityRef.get(); if (AndroidUtils.isActivityNotDestroyed(activity)) { - new LoadWikivoyageData(activity).execute(); + new LoadWikivoyageData(activity, showMore).execute(); } } }); } else { - new LoadWikivoyageData(this).execute(); + new LoadWikivoyageData(this, showMore).execute(); } } @@ -380,19 +384,21 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv updateFragments(); } - private static class LoadWikivoyageData extends AsyncTask { + public static class LoadWikivoyageData extends AsyncTask { private final WeakReference activityRef; private final TravelHelper travelHelper; + private final boolean showMore; - LoadWikivoyageData(WikivoyageExploreActivity activity) { + LoadWikivoyageData(WikivoyageExploreActivity activity, boolean showMore) { travelHelper = activity.getMyApplication().getTravelHelper(); activityRef = new WeakReference<>(activity); + this.showMore = showMore; } @Override protected Void doInBackground(Void... params) { - travelHelper.initializeDataToDisplay(); + travelHelper.initializeDataToDisplay(showMore); return null; } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelButtonCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelButtonCard.java new file mode 100644 index 0000000000..fd0a48718d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelButtonCard.java @@ -0,0 +1,56 @@ +package net.osmand.plus.wikivoyage.explore.travelcards; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard.CardListener; + +public class TravelButtonCard extends BaseTravelCard { + + public static final int TYPE = 5; + private CardListener listener; + + public TravelButtonCard(OsmandApplication app, boolean nightMode) { + super(app, nightMode); + } + + public void setListener(CardListener listener) { + this.listener = listener; + } + + @Override + public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof TravelButtonVH) { + final TravelButtonVH holder = (TravelButtonVH) viewHolder; + UiUtilities.setupDialogButton(nightMode, holder.button, UiUtilities.DialogButtonType.SECONDARY, R.string.show_more); + holder.button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (listener != null) { + listener.onPrimaryButtonClick(); + } + } + }); + } + } + + public static class TravelButtonVH extends RecyclerView.ViewHolder { + + final View button; + + public TravelButtonVH(View itemView) { + super(itemView); + button = itemView.findViewById(R.id.button); + } + } + + @Override + public int getCardType() { + return TYPE; + } +} \ No newline at end of file From 75624d44ba5c2aafce79a52628df5b04768e4b21 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 5 Feb 2021 18:13:34 +0100 Subject: [PATCH 068/398] Fix config.yml syntax --- .github/ISSUE_TEMPLATE/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7410b26a46..bca7b3f727 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ contact_links: - name: Outdated FAQ - - url: https://groups.google.com/forum/#!forum/osmand - - about: Fix wrong or outdated FAQ on the forum instead + url: https://groups.google.com/forum/#!forum/osmand + about: Fix wrong or outdated FAQ on the forum instead From 9efe8ffd0afc8cc39ad370eb74ef0e0831538fb1 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sat, 6 Feb 2021 13:08:43 +0300 Subject: [PATCH 069/398] Speedup location via gms --- OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java | 4 ++-- .../src/net/osmand/plus/views/layers/PointLocationLayer.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java index 41c74012a3..eaab9e3d06 100644 --- a/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java +++ b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java @@ -63,11 +63,11 @@ public class LocationServiceHelperImpl extends LocationServiceHelper { // Sets the fastest rate for active location updates. This interval is exact, and your // application will never receive updates more frequently than this value. - .setFastestInterval(50) + //.setFastestInterval(50) // Sets the maximum time when batched location updates are delivered. Updates may be // delivered sooner than this interval. - .setMaxWaitTime(200) + .setMaxWaitTime(0) .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/PointLocationLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/PointLocationLayer.java index 21dbbcc7bd..16952876a8 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/PointLocationLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/PointLocationLayer.java @@ -130,7 +130,9 @@ public class PointLocationLayer extends OsmandMapLayer implements ContextMenuLay canvas.restore(); } // Issue 5538: Some devices return positives for hasBearing() at rest, hence add 0.0 check: - boolean isBearing = lastKnownLocation.hasBearing() && (lastKnownLocation.getBearing() != 0.0); + boolean isBearing = lastKnownLocation.hasBearing() && (lastKnownLocation.getBearing() != 0.0) + && (!lastKnownLocation.hasSpeed() || lastKnownLocation.getSpeed() > 0.1); + if (!locationOutdated && isBearing) { float bearing = lastKnownLocation.getBearing(); canvas.rotate(bearing - 90, locationX, locationY); From f20a8882bde3bdc16dac8f828c7a39635255fdeb Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Sat, 6 Feb 2021 13:11:49 +0200 Subject: [PATCH 070/398] Fix get activity type name and icon --- .../net/osmand/osm/RouteActivityType.java | 34 ++++++++----------- OsmAnd/res/values/strings.xml | 26 +++++++------- OsmAnd/src/net/osmand/AndroidUtils.java | 6 ++++ .../explore/travelcards/TravelGpxCard.java | 19 ++++++----- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index e7a7a0600a..6f8a0b0e9a 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -1,31 +1,29 @@ package net.osmand.osm; public enum RouteActivityType { - WATER("Water", "yellow", "mx_special_kayak", "activity_type_water"), - WINTER("Winter", "yellow", "mx_special_skiing", "activity_type_winter"), - SNOWMOBILE("Snowmobile", "yellow", "mx_special_snowmobile", "activity_type_snowmobile"), - RIDING("Riding", "yellow", "mx_special_horse", "activity_type_riding"), - RACING("Racing", "yellow", "mx_raceway", "activity_type_racing"), - MOUNTAINBIKE("Mountainbike", "blue", "mx_sport_cycling", "activity_type_mountainbike"), - CYCLING("Cycling", "blue", "mx_special_bicycle", "activity_type_cycling"), - HIKING("Hiking", "orange", "mx_special_trekking", "activity_type_hiking"), - RUNNING("Running", "orange", "mx_running", "activity_type_running"), - WALKING("Walking", "orange", " mx_special_walking", "activity_type_walking"), - OFFROAD("Off-road", "yellow", "mx_special_offroad", "activity_type_offroad"), - MOTORBIKE("Motorbike", "green", "mx_special_motorcycle", "activity_type_motorbike"), - CAR("Car", "green", "mx_shop_car", "activity_type_car"); + WATER("water", "yellow", "special_kayak"), + WINTER("winter", "yellow", "special_skiing"), + SNOWMOBILE("snowmobile", "yellow", "special_snowmobile"), + RIDING("riding", "yellow", "special_horse"), + RACING("racing", "yellow", "raceway"), + MOUNTAINBIKE("mountainbike", "blue", "sport_cycling"), + CYCLING("cycling", "blue", "special_bicycle"), + HIKING("hiking", "orange", "special_trekking"), + RUNNING("running", "orange", "running"), + WALKING("walking", "orange", "special_walking"), + OFFROAD("offroad", "yellow", "special_offroad"), + MOTORBIKE("motorbike", "green", "special_motorcycle"), + CAR("car", "green", "shop_car"); // less specific bottom order String name; String color; String icon; - String title; - RouteActivityType(String nm, String clr, String icon, String title) { + RouteActivityType(String nm, String clr, String icon) { this.name = nm; this.color = clr; this.icon = icon; - this.title = title; } public String getName() { @@ -40,10 +38,6 @@ public enum RouteActivityType { return icon; } - public String getTitle() { - return title; - } - public static RouteActivityType getTypeFromName(String name) { for (RouteActivityType rat : values()) { if (rat.name().equalsIgnoreCase(name)) { diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 0c2feea060..8b1a73aa95 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,19 +12,19 @@ --> - Car - Motorbike - Off-road - Walking - Running - Hiking - Cycling - Mountainbike - Racing - Riding - Snowmobile - Winter - Water + Car + Motorbike + Off-road + Walking + Running + Hiking + Cycling + Mountainbike + Racing + Riding + Snowmobile + Winter + Water Login to OpenPlaceReviews Use test.openplacereviews.org OpenPlaceReviews diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 545e7b7391..ce7547a2c4 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -951,6 +951,12 @@ public class AndroidUtils { 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; + } + private static String getStringByProperty(@NonNull Context ctx, @NonNull String property) { try { Field field = R.string.class.getField(property); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 69772bac1c..119df5a54a 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -7,10 +7,10 @@ import android.widget.TextView; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; -import androidx.annotation.StringRes; import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; +import net.osmand.AndroidUtils; import net.osmand.osm.RouteActivityType; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; @@ -21,6 +21,8 @@ import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; import java.io.File; +import static net.osmand.util.Algorithms.capitalizeFirstLetterAndLowercase; + public class TravelGpxCard extends BaseTravelCard { public static final int TYPE = 3; @@ -48,12 +50,11 @@ public class TravelGpxCard extends BaseTravelCard { RouteActivityType activityType = RouteActivityType.getTypeFromName(article.activityType); if (activityType != null) { int iconId = getActivityTypeIcon(activityType); - int titleId = getActivityTypeTitle(activityType); - if (iconId > 0 && titleId > 0) { + if (iconId > 0) { holder.activityTypeIcon.setImageDrawable(getActiveIcon(iconId)); - holder.activityType.setText(titleId); - holder.activityTypeLabel.setVisibility(View.VISIBLE); } + holder.activityType.setText(getActivityTypeTitle(activityType)); + holder.activityTypeLabel.setVisibility(View.VISIBLE); } holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); @@ -79,12 +80,12 @@ public class TravelGpxCard extends BaseTravelCard { @DrawableRes private int getActivityTypeIcon(RouteActivityType activityType) { - return app.getResources().getIdentifier(activityType.getIcon(), "drawable", app.getPackageName()); + return app.getResources().getIdentifier("mx_" + activityType.getIcon(), "drawable", app.getPackageName()); } - @StringRes - private int getActivityTypeTitle(RouteActivityType activityType) { - return app.getResources().getIdentifier(activityType.getTitle(), "string", app.getPackageName()); + private String getActivityTypeTitle(RouteActivityType activityType) { + return AndroidUtils.getActivityTypeStringPropertyName(app, activityType.getName(), + capitalizeFirstLetterAndLowercase(activityType.getName())); } private void updateSaveButton(final TravelGpxVH holder) { From 1ca8718015b2c360d23303414ae9b9a1fc93f6b5 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Sat, 6 Feb 2021 16:31:59 +0300 Subject: [PATCH 071/398] Add phrases --- OsmAnd/res/values/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 13efca2404..33c4f8aae6 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4340,4 +4340,7 @@ Piste status: open Piste status: closed + Summit register: yes + Summit register: no + From 5c40df5867c1724b8a811a2ec25d5be93e7cefe6 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Sat, 6 Feb 2021 17:49:56 +0300 Subject: [PATCH 072/398] Add phrase --- OsmAnd/res/values/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 33c4f8aae6..5811de0322 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4343,4 +4343,6 @@ Summit register: yes Summit register: no + Mobile library stop position + From 3f2e78671ffce8fce61ca83ece70537ad4d7cebc Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 7 Feb 2021 11:38:59 +0200 Subject: [PATCH 073/398] Spannable string description, null check --- .../FollowTrackFragment.java | 15 ++++++----- .../track/TrackSelectSegmentBottomSheet.java | 26 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index e36cfcde15..b4bd04037e 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -494,12 +494,15 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca GPXInfo gpxInfo = card.getGpxInfoList().get(index); String fileName = gpxInfo.getFileName(); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByName(fileName); - boolean isTrackContainsMultiSegment = selectedGpxFile.getGpxFile().getNonEmptySegmentsCount() > 1; - if (selectedGpxFile != null && !isTrackContainsMultiSegment) { - selectTrackToFollow(selectedGpxFile.getGpxFile()); - updateSelectionMode(false); - } else if (selectedGpxFile != null && isTrackContainsMultiSegment) { - TrackSelectSegmentBottomSheet.showInstance(getFragmentManager(), selectedGpxFile); + FragmentManager fragmentManager = getFragmentManager(); + if (selectedGpxFile != null && fragmentManager != null) { + boolean isTrackContainsMultiSegment = selectedGpxFile.getGpxFile().getNonEmptySegmentsCount() > 1; + if (!isTrackContainsMultiSegment) { + selectTrackToFollow(selectedGpxFile.getGpxFile()); + updateSelectionMode(false); + } else { + TrackSelectSegmentBottomSheet.showInstance(fragmentManager, selectedGpxFile); + } } else { CallbackWithObject callback = new CallbackWithObject() { @Override diff --git a/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java index 03065539e8..da9c729d84 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackSelectSegmentBottomSheet.java @@ -3,8 +3,8 @@ package net.osmand.plus.track; import android.content.Context; import android.graphics.Typeface; import android.os.Bundle; +import android.text.Spannable; import android.text.SpannableString; -import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; @@ -19,6 +19,7 @@ import net.osmand.GPXUtilities.TrkSegment; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MenuBottomSheetDialogFragment; @@ -26,8 +27,10 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.TrackSelectSegmentAdapter; +import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.TextViewEx; +import net.osmand.plus.widgets.style.CustomTypefaceSpan; import net.osmand.util.Algorithms; import java.util.List; @@ -60,13 +63,16 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment String titleGpxTrack = Algorithms.getFileWithoutDirs(file.getGpxFile().path); Typeface typeface = FontCache.getRobotoMedium(app); - SpannableString spannable = UiUtilities.createCustomFontSpannable(typeface, titleGpxTrack, titleGpxTrack, titleGpxTrack); + String selectSegmentDescription = getString(R.string.select_segments_description, titleGpxTrack); + SpannableString gpxTrackName = new SpannableString(selectSegmentDescription); + int startIndex = selectSegmentDescription.indexOf(titleGpxTrack); int descriptionColor = getResolvedColor(nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light); - ForegroundColorSpan colorSpan = new ForegroundColorSpan(descriptionColor); - spannable.setSpan(colorSpan, 0, titleGpxTrack.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + int endIndex = startIndex + titleGpxTrack.length(); + gpxTrackName.setSpan(new CustomTypefaceSpan(typeface), startIndex, endIndex, 0); + gpxTrackName.setSpan(new ForegroundColorSpan(descriptionColor), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); items.add(new BottomSheetItemWithDescription.Builder() - .setDescription(getString(R.string.select_segments_description, spannable)) + .setDescription(gpxTrackName) .setCustomView(itemView) .create()); @@ -92,17 +98,19 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment private void selectSegmentToFollow(TrkSegment segment, GpxSelectionHelper.SelectedGpxFile file) { MapActivity mapActivity = (MapActivity) getActivity(); if (mapActivity != null) { + TargetPointsHelper targetPointsHelper = mapActivity.getMyApplication().getTargetPointsHelper(); + RoutingHelper routingHelper = mapActivity.getMyApplication().getRoutingHelper(); List points = segment.points; if (!points.isEmpty()) { ApplicationMode mode = ApplicationMode.valueOfStringKey(points.get(0).getProfileType(), null); if (mode != null) { - getMyApplication().getRoutingHelper().setAppMode(mode); - getMyApplication().initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); + routingHelper.setAppMode(mode); + mapActivity.getMyApplication().initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); } } mapActivity.getMapActions().setGPXRouteParams(file.getGpxFile()); - getMyApplication().getTargetPointsHelper().updateRouteAndRefresh(true); - getMyApplication().getRoutingHelper().onSettingsChanged(true); + targetPointsHelper.updateRouteAndRefresh(true); + routingHelper.onSettingsChanged(true); } } } From 3b0b49ae1b12b7b08613b173f4296f056110de02 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 8 Feb 2021 02:35:54 +0200 Subject: [PATCH 074/398] First part integration --- .../aidlapi/OsmAndCustomizationConstants.java | 1 + .../bottom_sheet_item_button_with_icon.xml | 3 +- OsmAnd/res/values/strings.xml | 2 +- .../plus/activities/MapActivityActions.java | 20 +++ .../monitoring/OsmandMonitoringPlugin.java | 13 +- .../TripRecordingActiveBottomSheet.java | 151 +++++++++++++----- 6 files changed, 144 insertions(+), 46 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java index af48552bc4..53e838a9a7 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java @@ -11,6 +11,7 @@ public interface OsmAndCustomizationConstants { String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places"; String DRAWER_SEARCH_ID = DRAWER_ITEM_ID_SCHEME + "search"; String DRAWER_DIRECTIONS_ID = DRAWER_ITEM_ID_SCHEME + "directions"; + String DRAWER_TRIP_RECORDING_ID = DRAWER_ITEM_ID_SCHEME + "trip_recording"; String DRAWER_CONFIGURE_MAP_ID = DRAWER_ITEM_ID_SCHEME + "configure_map"; String DRAWER_DOWNLOAD_MAPS_ID = DRAWER_ITEM_ID_SCHEME + "download_maps"; String DRAWER_OSMAND_LIVE_ID = DRAWER_ITEM_ID_SCHEME + "osmand_live"; diff --git a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml index 9b2b395ccb..3d2d1bbab1 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml @@ -34,7 +34,6 @@ android:layout_height="wrap_content" android:duplicateParentState="true" android:textSize="@dimen/default_desc_text_size" - osmand:letterSpacing="@dimen/description_letter_spacing" osmand:typeface="@string/font_roboto_medium" tools:text="Title" tools:textColor="@color/text_color_secondary_light" /> @@ -47,7 +46,7 @@ android:textColor="@color/text_color_secondary_light" android:textSize="@dimen/default_desc_text_size" android:visibility="gone" - osmand:letterSpacing="@dimen/description_letter_spacing" + android:letterSpacing="@dimen/description_letter_spacing" osmand:typeface="@string/font_roboto_medium" tools:text="Description" tools:visibility="visible" /> diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 905a947661..b2a92f75c2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,7 +11,7 @@ Thx - Hardy --> - + On pause Are you sure you want to stop recording?\nAll unsaved data will be lost. Track recording stopped Save and stop recording diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 258ed7be38..625396e5e3 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -22,6 +22,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; @@ -62,6 +63,8 @@ import net.osmand.plus.mapmarkers.MarkersPlanRouteContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.StartPlanRouteBottomSheet; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.monitoring.TripRecordingActiveBottomSheet; +import net.osmand.plus.monitoring.TripRecordingBottomSheet; import net.osmand.plus.osmedit.dialogs.DismissRouteBottomSheetFragment; import net.osmand.plus.profiles.ProfileDataObject; import net.osmand.plus.profiles.ProfileDataUtils; @@ -98,6 +101,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_P import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_SCREEN_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DASHBOARD_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DIRECTIONS_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_TRIP_RECORDING_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DIVIDER_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DOWNLOAD_MAPS_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_HELP_ID; @@ -839,6 +843,22 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); + boolean isTripRecordingPluginOn = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null; + if (isTripRecordingPluginOn) { + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.map_widget_monitoring, mapActivity) + .setId(DRAWER_TRIP_RECORDING_ID) + .setIcon(R.drawable.ic_action_track_recordable) + .setListener(new ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { + app.logEvent("trip_recording_open"); + MapActivity.clearPrevActivityIntent(); + TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); + return true; + } + }).createItem()); + } + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.get_directions, mapActivity) .setId(DRAWER_DIRECTIONS_ID) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 1ddb443891..65538733b0 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -43,6 +43,7 @@ import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType; +import net.osmand.plus.track.TrackDisplayHelper; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.MapInfoLayer; @@ -318,9 +319,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public void controlDialog(final Activity activity, final boolean showTrackSelection) { - FragmentActivity fragmentActivity = (FragmentActivity) activity; - TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); - /*final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); final boolean nightMode; if (activity instanceof MapActivity) { nightMode = app.getDaynightHelper().isNightModeForMapControls(); @@ -329,6 +328,8 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } AlertDialog.Builder bld = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, nightMode)); final TIntArrayList items = new TIntArrayList(); + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); if (wasTrackMonitored) { items.add(R.string.gpx_monitoring_stop); items.add(R.string.gpx_start_new_segment); @@ -417,7 +418,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { run.run(); } }); - bld.show(); +// bld.show(); } } @@ -538,7 +539,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public static LinearLayout createIntervalChooseLayout(final OsmandApplication app, - final Context uiCtx, + final Context uiCtx, final String patternMsg, final int[] seconds, final int[] minutes, final ValueHolder choice, final ValueHolder v, @@ -598,7 +599,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } } - + ll.setOrientation(LinearLayout.VERTICAL); ll.addView(tv); ll.addView(sliderContainer); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 6234d58b18..3e3fad8b75 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -4,8 +4,10 @@ import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.graphics.drawable.Drawable; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -21,34 +23,84 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; 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.snackbar.Snackbar; + +import net.osmand.GPXUtilities; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.TrackAppearanceFragment; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment { public static final String TAG = TripRecordingActiveBottomSheet.class.getSimpleName(); - private OsmandApplication app; - private OsmandSettings settings; + SaveGpxAsyncTask.SaveGpxListener saveGpxListener = new SaveGpxAsyncTask.SaveGpxListener() { + + @Override + public void gpxSavingStarted() { + + } + + @Override + public void gpxSavingFinished(Exception errorMessage) { + String gpxFileName = Algorithms.getFileWithoutDirs(app.getSavingTrackHelper().getCurrentTrack().getGpxFile().path); + final MapActivity mapActivity = getMapActivity(); + SavingTrackHelper helper = app.getSavingTrackHelper(); + final SavingTrackHelper.SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); + if (mapActivity != null) { + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), + getString(R.string.shared_string_file_is_saved, gpxFileName), + Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_undo, new View.OnClickListener() { + @Override + public void onClick(View view) { + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + final FragmentActivity fragmentActivity = mapActivityRef.get(); + SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); + } + }); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + dismiss(); + } + } + + }; + + public static void showInstance(@NonNull FragmentManager fragmentManager) { + if (!fragmentManager.isStateSaved()) { + TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); + fragment.show(fragmentManager, TAG); + } + } @Override public void createMenuItems(Bundle savedInstanceState) { app = requiredMyApplication(); - settings = app.getSettings(); + OsmandSettings settings = app.getSettings(); Context context = requireContext(); LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); @@ -67,6 +119,19 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen ); statusIcon.setImageDrawable(statusDrawable); + String timeTrackSaved = String.valueOf(app.getSavingTrackHelper().getLastTimeUpdated()); + SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + CharSequence formattedTimeTrackSaved = null; + try { + long time = sdf.parse(timeTrackSaved).getTime(); + long now = System.currentTimeMillis(); + formattedTimeTrackSaved = + DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); + } catch (ParseException e) { + e.printStackTrace(); + } + View buttonClear = itemView.findViewById(R.id.button_clear); View buttonStart = itemView.findViewById(R.id.button_start); View buttonSave = itemView.findViewById(R.id.button_save); @@ -75,7 +140,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen createButton(buttonClear, ItemType.CLEAR_DATA, true, null); createButton(buttonStart, ItemType.START_SEGMENT, true, null); - createButton(buttonSave, ItemType.SAVE, true, "17 min. ago"); + createButton(buttonSave, ItemType.SAVE, true, (String) formattedTimeTrackSaved); createButton(buttonPause, ItemType.PAUSE, true, null); createButton(buttonStop, ItemType.STOP, true, null); @@ -116,6 +181,25 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen }); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + buttonSave.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final GPXUtilities.GPXFile gpxFile = app.getSavingTrackHelper().getCurrentTrack().getGpxFile(); + new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + } + }); + + buttonStop.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentManager fragmentManager = getFragmentManager(); + Fragment targetFragment = getTargetFragment(); + if (fragmentManager != null && targetFragment != null) { + StopTrackRecordingBottomFragment.showInstance(fragmentManager, targetFragment); + } + } + }); } private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { @@ -150,35 +234,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen desc.setText(description); } - enum ItemType { - SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), - RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), - ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), - CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), - START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), - SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), - PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), - STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); - - @StringRes - private int titleId; - @DrawableRes - private int iconId; - - ItemType(@StringRes int titleId, @DrawableRes int iconId) { - this.titleId = titleId; - this.iconId = iconId; - } - - public int getTitleId() { - return titleId; - } - - public int getIconId() { - return iconId; - } - } - @ColorRes protected int getActiveTextColorId() { return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; @@ -235,10 +290,32 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } - public static void showInstance(@NonNull FragmentManager fragmentManager) { - if (!fragmentManager.isStateSaved()) { - TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); - fragment.show(fragmentManager, TAG); + enum ItemType { + SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), + RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), + ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), + CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), + START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), + SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), + PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); + + @StringRes + private int titleId; + @DrawableRes + private int iconId; + + ItemType(@StringRes int titleId, @DrawableRes int iconId) { + this.titleId = titleId; + this.iconId = iconId; + } + + public int getTitleId() { + return titleId; + } + + public int getIconId() { + return iconId; } } } From 30afafcd59741b7c944593d1f8e6ff49f618d3bb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 8 Feb 2021 11:01:56 +0200 Subject: [PATCH 075/398] Added icon for multi download button --- .../res/drawable/ic_action_multi_download.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 OsmAnd/res/drawable/ic_action_multi_download.xml diff --git a/OsmAnd/res/drawable/ic_action_multi_download.xml b/OsmAnd/res/drawable/ic_action_multi_download.xml new file mode 100644 index 0000000000..13c1b8bcba --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_multi_download.xml @@ -0,0 +1,20 @@ + + + + + From 38ab4a14fdb819a88e46609f51f7869cae206055 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:39:29 +0200 Subject: [PATCH 076/398] Update TripRecordingActiveBottomSheet.java --- .../TripRecordingActiveBottomSheet.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 3e3fad8b75..f085c581bd 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -49,6 +49,7 @@ import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Date; import java.util.TimeZone; import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; @@ -102,6 +103,8 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen app = requiredMyApplication(); OsmandSettings settings = app.getSettings(); Context context = requireContext(); + final FragmentManager fragmentManager = getFragmentManager(); + final Fragment targetFragment = getTargetFragment(); LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); @@ -119,12 +122,14 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen ); statusIcon.setImageDrawable(statusDrawable); - String timeTrackSaved = String.valueOf(app.getSavingTrackHelper().getLastTimeUpdated()); - SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm"); + long timeTrackSaved = app.getSavingTrackHelper().getLastTimeUpdated(); + SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + Date resultDate = new Date(timeTrackSaved); + String sdfFormatted = sdf.format(resultDate); CharSequence formattedTimeTrackSaved = null; try { - long time = sdf.parse(timeTrackSaved).getTime(); + long time = sdf.parse(sdfFormatted).getTime(); long now = System.currentTimeMillis(); formattedTimeTrackSaved = DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); @@ -186,20 +191,26 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void onClick(View v) { final GPXUtilities.GPXFile gpxFile = app.getSavingTrackHelper().getCurrentTrack().getGpxFile(); new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } }); buttonStop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - FragmentManager fragmentManager = getFragmentManager(); - Fragment targetFragment = getTargetFragment(); - if (fragmentManager != null && targetFragment != null) { + if (fragmentManager != null) { StopTrackRecordingBottomFragment.showInstance(fragmentManager, targetFragment); } } }); + + buttonClear.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fragmentManager != null) { + ClearRecordedDataBottomSheetFragment.showInstance(fragmentManager, targetFragment); + } + } + }); } private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { From 23ff6a54cf48395484cee741b223663f729fe296 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 8 Feb 2021 12:43:31 +0100 Subject: [PATCH 077/398] Fix #10796 --- .../osmand/plus/base/MenuBottomSheetDialogFragment.java | 9 +-------- .../plus/monitoring/SaveGPXBottomSheetFragment.java | 6 ++++++ .../plus/profiles/AppModesBottomSheetDialogFragment.java | 6 +++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index e4f0c6fa58..88800d8fa0 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -57,9 +57,6 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private LinearLayout itemsContainer; private LinearLayout buttonsContainer; - @StringRes - protected int dismissButtonStringRes = R.string.shared_string_cancel; - public void setUsedOnMap(boolean usedOnMap) { this.usedOnMap = usedOnMap; } @@ -261,11 +258,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra @StringRes protected int getDismissButtonTextId() { - return dismissButtonStringRes; - } - - protected void setDismissButtonTextId(@StringRes int stringRes) { - dismissButtonStringRes = stringRes; + return R.string.shared_string_cancel; } protected int getDismissButtonHeight(){ diff --git a/OsmAnd/src/net/osmand/plus/monitoring/SaveGPXBottomSheetFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/SaveGPXBottomSheetFragment.java index 4bd5e6bcda..d37d113e6c 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/SaveGPXBottomSheetFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/SaveGPXBottomSheetFragment.java @@ -143,6 +143,12 @@ public class SaveGPXBottomSheetFragment extends MenuBottomSheetDialogFragment { return UiUtilities.DialogButtonType.SECONDARY; } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_close; + } + @Override protected int getRightBottomButtonTextId() { return R.string.shared_string_open_track; diff --git a/OsmAnd/src/net/osmand/plus/profiles/AppModesBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/profiles/AppModesBottomSheetDialogFragment.java index 8b61d67462..70356e9945 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/AppModesBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/profiles/AppModesBottomSheetDialogFragment.java @@ -27,10 +27,14 @@ public abstract class AppModesBottomSheetDialogFragment Date: Mon, 8 Feb 2021 14:08:30 +0200 Subject: [PATCH 078/398] Snackbar top --- .../monitoring/TripRecordingActiveBottomSheet.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index f085c581bd..8c37b6903e 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -8,8 +8,10 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.text.format.DateUtils; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -29,6 +31,7 @@ import androidx.fragment.app.FragmentManager; import com.google.android.material.snackbar.Snackbar; +import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; @@ -69,9 +72,10 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void gpxSavingFinished(Exception errorMessage) { String gpxFileName = Algorithms.getFileWithoutDirs(app.getSavingTrackHelper().getCurrentTrack().getGpxFile().path); final MapActivity mapActivity = getMapActivity(); + final Context context = getContext(); SavingTrackHelper helper = app.getSavingTrackHelper(); final SavingTrackHelper.SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); - if (mapActivity != null) { + if (mapActivity != null && context != null) { Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), getString(R.string.shared_string_file_is_saved, gpxFileName), Snackbar.LENGTH_LONG) @@ -83,9 +87,13 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); } }); + View view = snackbar.getView(); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); + params.gravity = Gravity.TOP; + AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); + view.setLayoutParams(params); UiUtilities.setupSnackbar(snackbar, nightMode); snackbar.show(); - dismiss(); } } @@ -309,6 +317,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + RESUME(R.string.shared_string_pause, R.drawable.ic_play_dark), STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); @StringRes From e261150279158cfe3d1e4afbf42391756f9d3a20 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 8 Feb 2021 16:41:10 +0200 Subject: [PATCH 079/398] Convert RouteActivityType to class --- .../net/osmand/osm/RouteActivityType.java | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index 6f8a0b0e9a..01d5a5c98e 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -1,29 +1,32 @@ package net.osmand.osm; -public enum RouteActivityType { - WATER("water", "yellow", "special_kayak"), - WINTER("winter", "yellow", "special_skiing"), - SNOWMOBILE("snowmobile", "yellow", "special_snowmobile"), - RIDING("riding", "yellow", "special_horse"), - RACING("racing", "yellow", "raceway"), - MOUNTAINBIKE("mountainbike", "blue", "sport_cycling"), - CYCLING("cycling", "blue", "special_bicycle"), - HIKING("hiking", "orange", "special_trekking"), - RUNNING("running", "orange", "running"), - WALKING("walking", "orange", "special_walking"), - OFFROAD("offroad", "yellow", "special_offroad"), - MOTORBIKE("motorbike", "green", "special_motorcycle"), - CAR("car", "green", "shop_car"); - // less specific bottom order +import java.util.ArrayList; +import java.util.List; +public class RouteActivityType { + private static final List values = new ArrayList<>(); + + public static final RouteActivityType WATER = createType("water", "yellow").icon("special_kayak").reg(); + public static final RouteActivityType WINTER = createType("winter", "yellow").icon("special_skiing").reg(); + public static final RouteActivityType SNOWMOBILE = createType("snowmobile", "yellow").icon("special_snowmobile").reg(); + public static final RouteActivityType RIDING = createType("riding", "yellow").icon("special_horse").reg(); + public static final RouteActivityType RACING = createType("racing", "yellow").icon("raceway").reg(); + public static final RouteActivityType MOUNTAINBIKE = createType("mountainbike", "blue").icon("sport_cycling").reg(); + public static final RouteActivityType CYCLING = createType("cycling", "blue").icon("special_bicycle").reg(); + public static final RouteActivityType HIKING = createType("hiking", "orange").icon("special_trekking").reg(); + public static final RouteActivityType RUNNING = createType("running", "orange").icon("running").reg(); + public static final RouteActivityType WALKING = createType("walking", "orange").icon("special_walking").reg(); + public static final RouteActivityType OFFROAD = createType("offroad", "yellow").icon("special_offroad").reg(); + public static final RouteActivityType MOTORBIKE = createType("motorbike", "green").icon("special_motorcycle").reg(); + public static final RouteActivityType CAR = createType("car", "green").icon("shop_car").reg(); + // less specific bottom order String name; String color; String icon; - RouteActivityType(String nm, String clr, String icon) { + RouteActivityType(String nm, String clr) { this.name = nm; this.color = clr; - this.icon = icon; } public String getName() { @@ -39,20 +42,26 @@ public enum RouteActivityType { } public static RouteActivityType getTypeFromName(String name) { - for (RouteActivityType rat : values()) { - if (rat.name().equalsIgnoreCase(name)) { + for (RouteActivityType rat : values) { + if (rat.name.equalsIgnoreCase(name)) { return rat; } } return null; } + private static RouteActivityTypeBuilder createType(String name, String color) { + RouteActivityTypeBuilder builder = new RouteActivityTypeBuilder(); + builder.routeActivityType = new RouteActivityType(name, color); + return builder; + } + public static RouteActivityType getTypeFromTags(String[] tags) { RouteActivityType activityType = null; for (String tg : tags) { RouteActivityType rat = RouteActivityType.convertFromOsmGPXTag(tg); if (rat != null) { - if (activityType == null || activityType.ordinal() > rat.ordinal()) { + if (activityType == null || values.indexOf(activityType) > values.indexOf(rat)) { activityType = rat; } } @@ -237,4 +246,19 @@ public enum RouteActivityType { } return null; } + + public static class RouteActivityTypeBuilder { + + private RouteActivityType routeActivityType; + + public RouteActivityTypeBuilder icon(String icon) { + routeActivityType.icon = icon; + return this; + } + + private RouteActivityType reg() { + values.add(routeActivityType); + return routeActivityType; + } + } } \ No newline at end of file From 4ec42791365d754d7c72eb7617002cb7ea047eaa Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 8 Feb 2021 17:31:14 +0200 Subject: [PATCH 080/398] add block statistics; show current recording status; many fixes; the basis is prepared for the implementation of the functionality --- .../btn_background_active_dark.xml | 6 + .../btn_background_inactive_dark.xml | 6 + .../btn_background_inactive_light.xml | 6 + .../btn_background_stroked_active_dark.xml | 6 + .../btn_background_stroked_active_light.xml | 6 + .../btn_background_stroked_inactive_dark.xml | 6 + .../btn_background_stroked_inactive_light.xml | 6 + .../drawable/btn_background_active_light.xml | 6 + .../layout/bottom_sheet_button_with_icon.xml | 104 ++-- .../layout/trip_recording_active_fragment.xml | 10 +- .../monitoring/OsmandMonitoringPlugin.java | 35 +- .../TripRecordingActiveBottomSheet.java | 444 +++++++++++++----- .../plus/track/GpxBlockStatisticsBuilder.java | 297 ++++++++++++ 13 files changed, 750 insertions(+), 188 deletions(-) create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_active_dark.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_inactive_dark.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_inactive_light.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_stroked_active_dark.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_stroked_active_light.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_dark.xml create mode 100644 OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_light.xml create mode 100644 OsmAnd/res/drawable/btn_background_active_light.xml create mode 100644 OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java diff --git a/OsmAnd/res/drawable-mdpi/btn_background_active_dark.xml b/OsmAnd/res/drawable-mdpi/btn_background_active_dark.xml new file mode 100644 index 0000000000..88873ec3b4 --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_active_dark.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_inactive_dark.xml b/OsmAnd/res/drawable-mdpi/btn_background_inactive_dark.xml new file mode 100644 index 0000000000..07c3aed3e9 --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_inactive_dark.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_inactive_light.xml b/OsmAnd/res/drawable-mdpi/btn_background_inactive_light.xml new file mode 100644 index 0000000000..03ca0abfe5 --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_inactive_light.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_dark.xml b/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_dark.xml new file mode 100644 index 0000000000..1cdfa50a92 --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_dark.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_light.xml b/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_light.xml new file mode 100644 index 0000000000..543dd7ef1f --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_stroked_active_light.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_dark.xml b/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_dark.xml new file mode 100644 index 0000000000..f669c9d34f --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_dark.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_light.xml b/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_light.xml new file mode 100644 index 0000000000..feacf12888 --- /dev/null +++ b/OsmAnd/res/drawable-mdpi/btn_background_stroked_inactive_light.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable/btn_background_active_light.xml b/OsmAnd/res/drawable/btn_background_active_light.xml new file mode 100644 index 0000000000..4d8d8e82a5 --- /dev/null +++ b/OsmAnd/res/drawable/btn_background_active_light.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml index ba24cc289c..79b89d1213 100644 --- a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml +++ b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml @@ -1,59 +1,69 @@ - + android:layout_height="wrap_content"> + android:id="@+id/button_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clickable="true" + android:focusable="true" + android:gravity="center_vertical" + android:orientation="horizontal" + android:paddingStart="@dimen/content_padding_small" + android:paddingLeft="@dimen/content_padding_small" + android:paddingTop="@dimen/text_margin_small" + android:paddingEnd="@dimen/content_padding_small" + android:paddingRight="@dimen/content_padding_small" + android:paddingBottom="@dimen/text_margin_small" + tools:ignore="UselessParent"> - + android:layout_weight="1" + android:duplicateParentState="true" + android:orientation="vertical"> - + + + + + + + - - - \ No newline at end of file + \ No newline at end of file diff --git a/OsmAnd/res/layout/trip_recording_active_fragment.xml b/OsmAnd/res/layout/trip_recording_active_fragment.xml index 4f45d49fc9..df687a1bc5 100644 --- a/OsmAnd/res/layout/trip_recording_active_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_active_fragment.xml @@ -30,14 +30,17 @@ osmand:typeface="@string/font_roboto_medium" /> + android:layout_marginRight="@dimen/content_padding" + android:layout_marginBottom="@dimen/content_padding" /> choice, final ValueHolder v, @@ -569,11 +580,11 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) { String s; int progress = (int) value; - if(progress == 0) { + if (progress == 0) { s = uiCtx.getString(R.string.int_continuosly); v.value = 0; } else { - if(progress < secondsLength) { + if (progress < secondsLength) { s = seconds[progress] + " " + uiCtx.getString(R.string.int_seconds); v.value = seconds[progress] * 1000; } else { @@ -598,7 +609,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } } - + ll.setOrientation(LinearLayout.VERTICAL); ll.addView(tv); ll.addView(sliderContainer); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 6234d58b18..5f5c662882 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -1,14 +1,18 @@ package net.osmand.plus.monitoring; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.content.Context; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -22,8 +26,12 @@ import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; -import net.osmand.plus.GpxSelectionHelper; +import net.osmand.AndroidUtils; +import net.osmand.Location; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -31,7 +39,9 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.GpxBlockStatisticsBuilder; import net.osmand.plus.track.TrackAppearanceFragment; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -44,179 +54,205 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen private OsmandApplication app; private OsmandSettings settings; + private SelectedGpxFile selectedGpxFile; + private GpxBlockStatisticsBuilder blockStatisticsBuilder; + private boolean wasTrackMonitored = false; + private boolean hasDataToSave = false; + private boolean searchingGPS = false; + + private View statusContainer; + + private final Handler handler = new Handler(); + private Runnable updatingGPS; + + public void setSelectedGpxFile(SelectedGpxFile selectedGpxFile) { + this.selectedGpxFile = selectedGpxFile; + } + + public void setWasTrackMonitored(boolean wasTrackMonitored) { + this.wasTrackMonitored = wasTrackMonitored; + } + + public void setHasDataToSave(boolean hasDataToSave) { + this.hasDataToSave = hasDataToSave; + } + + public void setSearchingGPS(boolean searchingGPS) { + this.searchingGPS = searchingGPS; + } @Override public void createMenuItems(Bundle savedInstanceState) { app = requiredMyApplication(); settings = app.getSettings(); - Context context = requireContext(); + LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); - LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); items.add(new BottomSheetItemWithDescription.Builder() .setCustomView(itemView) .create()); - TextView statusTitle = itemView.findViewById(R.id.status); - statusTitle.setText(ItemType.SEARCHING_GPS.titleId); - statusTitle.setTextColor(ContextCompat.getColor(app, getSecondaryTextColorId())); - ImageView statusIcon = itemView.findViewById(R.id.icon_status); - Drawable statusDrawable = UiUtilities.tintDrawable( - AppCompatResources.getDrawable(app, ItemType.SEARCHING_GPS.iconId), - ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light) - ); - statusIcon.setImageDrawable(statusDrawable); - View buttonClear = itemView.findViewById(R.id.button_clear); View buttonStart = itemView.findViewById(R.id.button_start); View buttonSave = itemView.findViewById(R.id.button_save); - View buttonPause = itemView.findViewById(R.id.button_pause); + final View buttonPause = itemView.findViewById(R.id.button_pause); View buttonStop = itemView.findViewById(R.id.button_stop); - createButton(buttonClear, ItemType.CLEAR_DATA, true, null); - createButton(buttonStart, ItemType.START_SEGMENT, true, null); - createButton(buttonSave, ItemType.SAVE, true, "17 min. ago"); - createButton(buttonPause, ItemType.PAUSE, true, null); - createButton(buttonStop, ItemType.STOP, true, null); + createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave, null); + createItem(buttonStart, ItemType.START_SEGMENT, wasTrackMonitored, null); + createItem(buttonSave, ItemType.SAVE, hasDataToSave, "..."); + createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); + createItem(buttonStop, ItemType.STOP, true, null); - LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); - TextView showTrackOnMapTitle = showTrackOnMapView.findViewById(R.id.title); - showTrackOnMapTitle.setText(R.string.show_track_on_map); + statusContainer = itemView.findViewById(R.id.status_container); + updateStatus(); - ImageView trackAppearanceIcon = showTrackOnMapView.findViewById(R.id.icon_after_divider); - - int color = settings.CURRENT_TRACK_COLOR.get(); - String width = settings.CURRENT_TRACK_WIDTH.get(); - boolean showArrows = settings.CURRENT_TRACK_SHOW_ARROWS.get(); - Drawable drawable = TrackAppearanceFragment.getTrackIcon(app, width, showArrows, color); - - trackAppearanceIcon.setImageDrawable(drawable); - trackAppearanceIcon.setOnClickListener(new View.OnClickListener() { + // todo example, need to check + buttonPause.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - hide(); - GpxSelectionHelper.SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); - TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, TripRecordingActiveBottomSheet.this); - } + boolean wasTrackMonitored = !settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); + TripRecordingActiveBottomSheet.this.wasTrackMonitored = wasTrackMonitored; + settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); + updateStatus(); } }); - final SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); + RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics); + blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, null); + blockStatisticsBuilder.setBlocksView(statBlocks); + blockStatisticsBuilder.initStatBlocks(null, ContextCompat.getColor(app, getActiveTextColorId(nightMode)), nightMode); + + LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); + final LinearLayout basicItemBody = showTrackOnMapView.findViewById(R.id.basic_item_body); + + TextView showTrackTitle = basicItemBody.findViewById(R.id.title); + showTrackTitle.setText(ItemType.SHOW_TRACK.getTitleId()); + showTrackTitle.setTextColor(ContextCompat.getColor(app, getActiveIconColorId(nightMode))); + showTrackTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); + Typeface typeface = FontCache.getFont(app, app.getResources().getString(R.string.font_roboto_medium)); + showTrackTitle.setTypeface(typeface); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + float letterSpacing = AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing); + showTrackTitle.setLetterSpacing(letterSpacing); + } + final SwitchCompat showTrackOnMapButton = basicItemBody.findViewById(R.id.switch_button); showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); - View basicItem = itemView.findViewById(R.id.basic_item_body); - basicItem.setOnClickListener(new View.OnClickListener() { + UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + + final LinearLayout additionalButton = showTrackOnMapView.findViewById(R.id.additional_button); + View divider = additionalButton.getChildAt(0); + AndroidUiHelper.setVisibility(View.GONE, divider); + int marginS = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_small); + UiUtilities.setMargins(additionalButton, marginS, 0, 0, 0); + String width = settings.CURRENT_TRACK_WIDTH.get(); + boolean showArrows = settings.CURRENT_TRACK_SHOW_ARROWS.get(); + int color = settings.CURRENT_TRACK_COLOR.get(); + Drawable appearanceDrawable = TrackAppearanceFragment.getTrackIcon(app, width, showArrows, color); + AppCompatImageView appearanceIcon = additionalButton.findViewById(R.id.icon_after_divider); + int marginTrackIconH = app.getResources().getDimensionPixelSize(R.dimen.content_padding_small); + UiUtilities.setMargins(appearanceIcon, marginTrackIconH, 0, marginTrackIconH, 0); + appearanceIcon.setImageDrawable(appearanceDrawable); + additionalButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (showTrackOnMapButton.isChecked()) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + hide(); + SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile, TripRecordingActiveBottomSheet.this); + } + } + } + }); + createItem(additionalButton, ItemType.APPEARANCE, showTrackOnMapButton.isChecked(), null); + setShowOnMapBackgroundInactive(basicItemBody, app, showTrackOnMapButton.isChecked(), nightMode); + basicItemBody.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean checked = !showTrackOnMapButton.isChecked(); showTrackOnMapButton.setChecked(checked); app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); + setShowOnMapBackgroundInactive(basicItemBody, app, checked, nightMode); + createItem(additionalButton, ItemType.APPEARANCE, checked, null); } }); - UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); - } - private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { + private void updateStatus() { + TextView statusTitle = statusContainer.findViewById(R.id.text_status); + AppCompatImageView statusIcon = statusContainer.findViewById(R.id.icon_status); + ItemType status = searchingGPS ? ItemType.SEARCHING_GPS : !wasTrackMonitored ? ItemType.ON_PAUSE : ItemType.RECORDING; + statusTitle.setText(status.getTitleId()); + int colorText = status.equals(ItemType.SEARCHING_GPS) ? getSecondaryTextColorId(nightMode) : getOsmandIconColorId(nightMode); + statusTitle.setTextColor(ContextCompat.getColor(app, colorText)); + int colorDrawable = ContextCompat.getColor(app, + status.equals(ItemType.SEARCHING_GPS) ? getSecondaryIconColorId(nightMode) : getOsmandIconColorId(nightMode)); + Drawable statusDrawable = UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, status.getIconId()), colorDrawable); + statusIcon.setImageDrawable(statusDrawable); + } - Context ctx = view.getContext(); + private void createItem(View view, ItemType type, boolean enabled, @Nullable String description) { + view.setTag(type); + LinearLayout button = view.findViewById(R.id.button_container); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { - view.setBackground(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); - } else { - view.setBackgroundDrawable(AppCompatResources.getDrawable(ctx, nightMode ? R.drawable.dlg_btn_secondary_dark : R.drawable.dlg_btn_secondary_light)); - } - - TextViewEx title = view.findViewById(R.id.title); - TextViewEx desc = view.findViewById(R.id.desc); AppCompatImageView icon = view.findViewById(R.id.icon); - - title.setText(type.getTitleId()); - title.setTextColor(ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete - : enabled ? getActiveTextColorId() : getSecondaryTextColorId())); - - Drawable tintDrawable = UiUtilities.tintDrawable( - AppCompatResources.getDrawable(ctx, type.iconId), - ContextCompat.getColor(ctx, type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete - : enabled ? getActiveIconColorId() : getSecondaryIconColorId()) - ); - icon.setBackgroundDrawable(tintDrawable); - - boolean isShowDesc = !Algorithms.isBlank(description); - int marginSingle = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); - AndroidUiHelper.updateVisibility(desc, isShowDesc); - UiUtilities.setMargins(title, 0, isShowDesc ? 0 : marginSingle, 0, isShowDesc ? 0 : marginSingle); - desc.setText(description); - } - - enum ItemType { - SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), - RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), - ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), - CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), - START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), - SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), - PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), - STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); - - @StringRes - private int titleId; - @DrawableRes - private int iconId; - - ItemType(@StringRes int titleId, @DrawableRes int iconId) { - this.titleId = titleId; - this.iconId = iconId; + if (icon != null) { + type.setTintedIcon(icon, app, enabled, false, nightMode); } - public int getTitleId() { - return titleId; + TextView title = view.findViewById(R.id.title); + if (title != null) { + title.setText(type.getTitleId()); + type.setTextColor(title, app, enabled, false, nightMode); } - public int getIconId() { - return iconId; + setItemBackgroundInactive(button != null ? button : (LinearLayout) view, app, nightMode); + type.changeOnTouch(button != null ? button : (LinearLayout) view, icon, title, app, enabled, nightMode); + + TextViewEx desc = view.findViewById(R.id.desc); + if (desc != null) { + boolean isShowDesc = !Algorithms.isBlank(description); + int marginDesc = isShowDesc ? 0 : app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + AndroidUiHelper.updateVisibility(desc, isShowDesc); + UiUtilities.setMargins(title, 0, marginDesc, 0, marginDesc); + desc.setText(description); } } - @ColorRes - protected int getActiveTextColorId() { - return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; - } - - @ColorRes - protected int getSecondaryTextColorId() { - return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; - } - - @ColorRes - protected int getActiveIconColorId() { - return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; - } - - @ColorRes - protected int getSecondaryIconColorId() { - return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light; - } - - @ColorRes - protected int getOsmandIconColorId() { - return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; + @Override + public void onResume() { + super.onResume(); + blockStatisticsBuilder.runUpdatingStatBlocks(); + runUpdatingGPS(); } @Override - protected int getDismissButtonHeight() { - return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + public void onPause() { + super.onPause(); + blockStatisticsBuilder.stopUpdatingStatBlocks(); + stopUpdatingGPS(); } - @Override - protected int getDismissButtonTextId() { - return R.string.shared_string_close; + public void stopUpdatingGPS() { + handler.removeCallbacks(updatingGPS); } - @Override - protected boolean useVerticalButtons() { - return true; + public void runUpdatingGPS() { + updatingGPS = new Runnable() { + @Override + public void run() { + int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); + OsmAndLocationProvider locationProvider = app.getLocationProvider(); + Location lastKnownLocation = locationProvider.getLastKnownLocation(); + searchingGPS = lastKnownLocation == null; + updateStatus(); + handler.postDelayed(this, Math.max(1000, interval)); + } + }; + handler.post(updatingGPS); } @Nullable @@ -235,9 +271,165 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } - public static void showInstance(@NonNull FragmentManager fragmentManager) { + private static void setItemBackgroundActive(LinearLayout view, Context context, boolean nightMode) { + Drawable background = AppCompatResources.getDrawable(context, + nightMode ? R.drawable.btn_background_active_dark : R.drawable.btn_background_active_light); + view.setBackgroundDrawable(background); + } + + private static void setItemBackgroundInactive(LinearLayout view, Context context, boolean nightMode) { + Drawable background = AppCompatResources.getDrawable(context, + nightMode ? R.drawable.btn_background_inactive_dark : R.drawable.btn_background_inactive_light); + view.setBackgroundDrawable(background); + } + + private static void setShowOnMapBackgroundActive(LinearLayout view, Context context, boolean checked, boolean nightMode) { + Drawable background = AppCompatResources.getDrawable(context, + nightMode ? checked ? R.drawable.btn_background_active_dark : R.drawable.btn_background_stroked_active_dark + : checked ? R.drawable.btn_background_active_light : R.drawable.btn_background_stroked_active_light); + view.setBackgroundDrawable(background); + } + + private static void setShowOnMapBackgroundInactive(LinearLayout view, Context context, boolean checked, boolean nightMode) { + Drawable background = AppCompatResources.getDrawable(context, + nightMode ? checked ? R.drawable.btn_background_inactive_dark : R.drawable.btn_background_stroked_inactive_dark + : checked ? R.drawable.btn_background_inactive_light : R.drawable.btn_background_stroked_inactive_light); + view.setBackgroundDrawable(background); + } + + enum ItemType { + SHOW_TRACK(R.string.shared_string_show_on_map, null), + APPEARANCE(null, null), + SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), + RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), + ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), + CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), + START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), + SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), + PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + RESUME(R.string.shared_string_resume, R.drawable.ic_play_dark), + STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); + + @StringRes + private final Integer titleId; + @DrawableRes + private final Integer iconId; + + ItemType(@Nullable @StringRes Integer titleId, @Nullable @DrawableRes Integer iconId) { + this.titleId = titleId; + this.iconId = iconId; + } + + public Integer getTitleId() { + return titleId; + } + + public Integer getIconId() { + return iconId; + } + + public void setTextColor(TextView tv, Context context, boolean enabled, boolean pressed, boolean nightMode) { + if (tv != null) { + tv.setTextColor(ContextCompat.getColor(context, + enabled ? pressed ? getPressedColorId(nightMode) + : equals(ItemType.CLEAR_DATA) ? R.color.color_osm_edit_delete + : getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); + } + } + + public void setTintedIcon(AppCompatImageView iv, Context context, boolean enabled, boolean pressed, boolean nightMode) { + if (iv != null) { + int iconColor = ContextCompat.getColor(context, + enabled ? pressed ? getPressedColorId(nightMode) + : equals(ItemType.CLEAR_DATA) ? R.color.color_osm_edit_delete + : getActiveIconColorId(nightMode) : getSecondaryIconColorId(nightMode)); + Drawable icon = UiUtilities.createTintedDrawable(context, iconId, iconColor); + iv.setImageDrawable(icon); + } + } + + @SuppressLint("ClickableViewAccessibility") + private void changeOnTouch(final LinearLayout button, @Nullable final AppCompatImageView iv, @Nullable final TextView tv, + final Context context, final boolean enabled, final boolean nightMode) { + button.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (enabled) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: { + setItemBackgroundActive(button, context, nightMode); + setTintedIcon(iv, context, enabled, true, nightMode); + setTextColor(tv, context, enabled, true, nightMode); + break; + } + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: { + setItemBackgroundInactive(button, context, nightMode); + setTintedIcon(iv, context, enabled, false, nightMode); + setTextColor(tv, context, enabled, false, nightMode); + break; + } + } + } + return false; + } + }); + } + } + + @ColorRes + private static int getActiveTextColorId(boolean nightMode) { + return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; + } + + @ColorRes + private static int getSecondaryTextColorId(boolean nightMode) { + return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; + } + + @ColorRes + private static int getActiveIconColorId(boolean nightMode) { + return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; + } + + @ColorRes + private static int getSecondaryIconColorId(boolean nightMode) { + return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light; + } + + @ColorRes + private static int getOsmandIconColorId(boolean nightMode) { + return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; + } + + @ColorRes + private static int getPressedColorId(boolean nightMode) { + return nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; + } + + @Override + protected int getDismissButtonHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_close; + } + + @Override + protected boolean useVerticalButtons() { + return true; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, SelectedGpxFile selectedGpxFile, + boolean wasTrackMonitored, boolean hasDataToSave, boolean searchingGPS) { if (!fragmentManager.isStateSaved()) { TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); + fragment.setSelectedGpxFile(selectedGpxFile); + fragment.setWasTrackMonitored(wasTrackMonitored); + fragment.setHasDataToSave(hasDataToSave); + fragment.setSearchingGPS(searchingGPS); fragment.show(fragmentManager, TAG); } } diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java new file mode 100644 index 0000000000..d132de4ede --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -0,0 +1,297 @@ +package net.osmand.plus.track; + +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities.GPXTrackAnalysis; +import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; +import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; +import net.osmand.plus.myplaces.SegmentActionsListener; +import net.osmand.plus.widgets.TextViewEx; +import net.osmand.util.Algorithms; + +import java.util.ArrayList; +import java.util.List; + +import android.os.Handler; + +public class GpxBlockStatisticsBuilder { + + private final OsmandApplication app; + private RecyclerView blocksView; + private final SelectedGpxFile selectedGpxFile; + private final TrackDisplayHelper displayHelper; + private final GpxDisplayItemType[] filterTypes = {GpxDisplayItemType.TRACK_SEGMENT}; + + private BlockStatisticsAdapter bsAdapter; + private final List items = new ArrayList<>(); + + private final Handler handler = new Handler(); + private Runnable updatingStats; + + public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile, TrackDisplayHelper displayHelper) { + this.app = app; + this.selectedGpxFile = selectedGpxFile; + this.displayHelper = displayHelper; + } + + public void setBlocksView(RecyclerView blocksView) { + this.blocksView = blocksView; + } + + private GPXTrackAnalysis getAnalysis() { + return selectedGpxFile.getTrackAnalysis(app); + } + + public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { + initItems(); + if (Algorithms.isEmpty(items)) { + AndroidUiHelper.updateVisibility(blocksView, false); + } else { + bsAdapter = new BlockStatisticsAdapter(actionsListener, activeColor, nightMode); + bsAdapter.setItems(items); + blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); + blocksView.setAdapter(bsAdapter); + } + } + + public void stopUpdatingStatBlocks() { + handler.removeCallbacks(updatingStats); + } + + public void runUpdatingStatBlocks() { + updatingStats = new Runnable() { + @Override + public void run() { + Log.d("BlockStatisticsBuilder", "run: working"); + if (bsAdapter != null) { + initItems(); + bsAdapter.setItems(items); + } + int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); + handler.postDelayed(this, Math.max(1000, interval)); + } + }; + handler.post(updatingStats); + } + + public void initItems() { + GPXTrackAnalysis analysis = getAnalysis(); + float totalDistance = analysis.totalDistance; + float timeSpan = analysis.timeSpan; + String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); + String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); + String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); + + items.clear(); + prepareData(analysis, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), + R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE); + prepareData(analysis, app.getString(R.string.altitude_ascent), asc, + R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE); + prepareData(analysis, app.getString(R.string.altitude_descent), desc, + R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE); + prepareData(analysis, app.getString(R.string.average_speed), avg, + R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); + prepareData(analysis, app.getString(R.string.max_speed), max, + R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); + prepareData(analysis, app.getString(R.string.shared_string_time_span), + Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()), + R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME); + } + + public void prepareData(GPXTrackAnalysis analysis, String title, String value, + @DrawableRes int imageResId, @ColorRes int imageColorId, + GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) { + StatBlock statBlock = new StatBlock(title, value, imageResId, imageColorId, firstType, secondType, itemType); + switch (statBlock.itemType) { + case ITEM_DISTANCE: { + if (analysis.totalDistance != 0f) { + items.add(statBlock); + } + break; + } + case ITEM_ALTITUDE: { + if (analysis.hasElevationData) { + items.add(statBlock); + } + break; + } + case ITEM_SPEED: { + if (analysis.isSpeedSpecified()) { + items.add(statBlock); + } + break; + } + case ITEM_TIME: { + if (analysis.hasSpeedData) { + items.add(statBlock); + } + break; + } + } + } + + private void setImageDrawable(ImageView iv, @DrawableRes Integer resId, @ColorRes int color) { + Drawable icon = resId != null ? app.getUIUtilities().getIcon(resId, color) + : UiUtilities.tintDrawable(iv.getDrawable(), getResolvedColor(color)); + iv.setImageDrawable(icon); + } + + @ColorInt + protected int getResolvedColor(@ColorRes int colorId) { + return ContextCompat.getColor(app, colorId); + } + + public class StatBlock { + + private final String title; + private final String value; + private final int imageResId; + private final int imageColorId; + private final GPXDataSetType firstType; + private final GPXDataSetType secondType; + private final ItemType itemType; + + public StatBlock(String title, String value, @DrawableRes int imageResId, @ColorRes int imageColorId, + GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) { + this.title = title; + this.value = value; + this.imageResId = imageResId; + this.imageColorId = imageColorId; + this.firstType = firstType; + this.secondType = secondType; + this.itemType = itemType; + } + } + + public enum ItemType { + ITEM_DISTANCE, + ITEM_ALTITUDE, + ITEM_SPEED, + ITEM_TIME; + } + + private class BlockStatisticsAdapter extends RecyclerView.Adapter { + + @ColorInt + private final int activeColor; + private final List statBlocks = new ArrayList<>(); + private final boolean nightMode; + private final SegmentActionsListener actionsListener; + + public BlockStatisticsAdapter(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { + this.actionsListener = actionsListener; + this.activeColor = activeColor; + this.nightMode = nightMode; + } + + @Override + public int getItemCount() { + return statBlocks.size(); + } + + @NonNull + @Override + public BlockStatisticsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_gpx_stat_block, parent, false); + return new BlockStatisticsViewHolder(itemView); + } + + @Override + public void onBindViewHolder(final BlockStatisticsViewHolder holder, int position) { + final StatBlock item = statBlocks.get(position); + holder.valueText.setText(item.value); + holder.titleText.setText(item.title); + if (handler.hasCallbacks(updatingStats)) { + holder.titleText.setWidth(app.getResources().getDimensionPixelSize(R.dimen.map_route_buttons_width)); + } + holder.valueText.setTextColor(activeColor); + holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light)); + if (actionsListener != null && displayHelper != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + List groups = displayHelper.getDisplayGroups(filterTypes); + GpxDisplayGroup group = null; + for (GpxDisplayGroup g : groups) { + if (g.isGeneralTrack()) { + group = g; + } + } + if (group == null && !groups.isEmpty()) { + group = groups.get(0); + } + if (group != null) { + GpxDisplayItem displayItem = group.getModifiableList().get(0); + if (displayItem != null && displayItem.analysis != null) { + ArrayList list = new ArrayList<>(); + if (displayItem.analysis.hasElevationData || displayItem.analysis.isSpeedSpecified() || displayItem.analysis.hasSpeedData) { + if (item.firstType != null) { + list.add(item.firstType); + } + if (item.secondType != null) { + list.add(item.secondType); + } + } + displayItem.chartTypes = list.size() > 0 ? list.toArray(new GPXDataSetType[0]) : null; + displayItem.locationOnMap = displayItem.locationStart; + actionsListener.openAnalyzeOnMap(displayItem); + } + } + } + }); + } + setImageDrawable(holder.imageView, item.imageResId, item.imageColorId); + AndroidUtils.setBackgroundColor(app, holder.divider, nightMode, R.color.divider_color_light, R.color.divider_color_dark); + AndroidUiHelper.updateVisibility(holder.divider, position != statBlocks.size() - 1); + } + + public void setItems(List statBlocks) { + this.statBlocks.clear(); + this.statBlocks.addAll(statBlocks); + notifyItemRangeChanged(0, getItemCount()); + } + } + + private class BlockStatisticsViewHolder extends RecyclerView.ViewHolder { + + private final TextViewEx valueText; + private final TextView titleText; + private final AppCompatImageView imageView; + private final View divider; + + public BlockStatisticsViewHolder(View view) { + super(view); + valueText = view.findViewById(R.id.value); + titleText = view.findViewById(R.id.title); + imageView = view.findViewById(R.id.image); + divider = view.findViewById(R.id.divider); + } + } +} From 6c32861ebd653d680da0594c4832ac001ec32518 Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 8 Feb 2021 18:27:01 +0200 Subject: [PATCH 081/398] test commit --- .../src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 838944a988..a7b23e18ec 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -190,7 +190,7 @@ public class GpxBlockStatisticsBuilder { ITEM_DISTANCE, ITEM_ALTITUDE, ITEM_SPEED, - ITEM_TIME; + ITEM_TIME } private class BlockStatisticsAdapter extends RecyclerView.Adapter { @@ -292,3 +292,4 @@ public class GpxBlockStatisticsBuilder { } } } +// \ No newline at end of file From 2efd0cad00b55700fe06d7faa55b7ce0fb2a37b9 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 8 Feb 2021 18:27:18 +0200 Subject: [PATCH 082/398] Add custom activity type --- .../src/main/java/net/osmand/osm/RouteActivityType.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index 01d5a5c98e..65fa50bf68 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -5,6 +5,8 @@ import java.util.List; public class RouteActivityType { private static final List values = new ArrayList<>(); + public static final String DEFAULT_ICON = "special_marker"; + public static final String DEFAULT_COLOR = "orange"; public static final RouteActivityType WATER = createType("water", "yellow").icon("special_kayak").reg(); public static final RouteActivityType WINTER = createType("winter", "yellow").icon("special_skiing").reg(); @@ -47,7 +49,7 @@ public class RouteActivityType { return rat; } } - return null; + return createType(name.toLowerCase(), DEFAULT_COLOR).icon(DEFAULT_ICON).reg(); } private static RouteActivityTypeBuilder createType(String name, String color) { From 0b7816eb84af3ccd83bbfb34aa7e5b6db3ff36f7 Mon Sep 17 00:00:00 2001 From: nasr pen Date: Mon, 8 Feb 2021 16:36:16 +0000 Subject: [PATCH 083/398] Translated using Weblate (Arabic) Currently translated at 99.9% (3659 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 130 +++++++++++++++---------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index d12d0a4de4..be1ee7842e 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -329,7 +329,7 @@ نسخ الاحتياطي كتعديل OSM %1$d ملف بقى يظهر الإعدادات لتمكين التتبع والملاحة في وضعية السكون ( الشاشة مغلقة ) عبر إيقاظ دوري لجهاز GPS. - تمكين لحساب المسارات بدقة دون أخطاء. لا يزال محدود المسافة وبطيء. + حساب الطرق بدقة دون أخطاء. لا يزال محدود المسافة وبطيء. صورة %1$s %2$s مزامنة المسارات والملاحظات الصوتية / الفيديو مع حساب Dropbox الخاص بك. تنسيق الفيديو الناتج: @@ -471,7 +471,7 @@ إفريقيا آسيا أستراليا و أوقيانوسيا - التوجيه مع الطرق + التوجيه ضبط خاص لكل وضع من أوضاع الملاحة. إدارة بيانات الخرائط إعدادات عامة @@ -977,7 +977,7 @@ مصدر الخريطة عرض أسماء المفضلة لغة الخريطة - تفاصيل إضافية + التفاصيل الوقت الحالي اتجاه الخريطة اتجاه الحركة في الأعلى @@ -992,7 +992,7 @@ تسجيل المسار اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة صوت مسج - التوجيه مع الطرق + الاتجاهات استخدام الموقع… مفضلة نقاط مفضلة مجاورة @@ -1071,7 +1071,7 @@ تجنب الطرق… طرق السكك الحديدية خطوط الترام - المسارات الرياضية + الطرق وسائل المواصلات سمات أخرى للخريطة العناصر الأخرى @@ -1170,7 +1170,7 @@ طرق الحافلات الكهربائية طرق الحافلات سكك قطار الأنفاق - شارك طرق التاكسي + تاكسي مشاركة الطرق حدد حد السرعة المسموح به لتلقي تنبيه صوتي إذا ما تجاوزته. مراقبة الحدود كشك الرسوم @@ -1184,7 +1184,7 @@ قيود الدخول عرض قيود الدخول عرض سطح الطريق - إظهار مسارات الدراجات + إظهار طرق الدراجات بدء التوجيه المفصل تلقائياً مسارات فرعية: %1$s نقاط الطريق: %1$s @@ -1390,7 +1390,7 @@ قطار المسار الحالي مستوى البطارية - تغيير موقع التوجيه المباشر + تغيير موقع العلامة تابعنا اتجاه صدى الصوت الملاحة عبر أوسماند لايف @@ -1411,7 +1411,7 @@ مظهرالخريطة رقيقة متوسط - لم تضف توجيه مباشر على الخريطة + أضف علامات عبر الخريطة لم يتم العثور على نقاط الطريق التقرير سمح الآن للتطبيق بالكتابة على وحدة التخزين الخارجية. الرجاء إعادة تشغيله يدويا. @@ -1436,7 +1436,7 @@ رفع كمستخدم مجهول رفع ملاحظة OSM شريط الأدوات - حدد توجيه مباشرعلى الخريطة + حدد علامات الخريطة ترتيب عكسي تفعيل ميزة العلامات. الأسترية @@ -1472,7 +1472,7 @@ حرف غير قانوني في اسم الملف تقرير عن خرائط العالم - حرك الخريطة لتغيير مكان التوجيه المباشر + حرك الخريطة لتغيير مكان العلامة إشارة صوتية عند اتجاه نقطة الوصول. حدد اتجاه النقطة المستهدفة بالاهتزاز. @@ -1590,7 +1590,7 @@ حرك للاسفل اسم مستخدم و كلمة سر OSM نحن بحاجة اليه لكي نوفر لك معلومات حول المساهمات. - حدد توجيه مباشر + اختر علامة عرض شريط الشفافية لا توجد مساحة كافية! \n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم. @@ -1611,7 +1611,7 @@ \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية عدد خطوط التوجيه - التوجيه المباشر + علامات الخريطة تخطي الحدود حدد الطرق التي تريد تجنبها أثناء التنقل. الفئات @@ -1629,11 +1629,11 @@ الخرائط الموجودة انتقال للأعلى التعديلات %1$s ، الرتبة %2$s ، مجموع التعديلات %3$s - التوجيه المباشرالأول للخريطة - التوجيه المباشرالثاني للخريطة - إضافة إلى التوجيه المباشر - حذف كافة التوجيه المباشرالنشط على الخريطة؟ - توجيه مباشر على الخريطة + أول علامة + ثاني علامة + إضافة إلى علامات الخريطة + حذف كافة العلامات النشطة على الخريطة؟ + علامة خريطة عرض المضلعات الحالة حفظ التعديلات @@ -1655,7 +1655,7 @@ اختر التوجيه الصوتي اختر أو قم بتحميل التوجيه الصوتي الخاص بلغتك. منح الوصول إلى بيانات الموقع. - مسارات الخيول + طرق الخيول إخفاء جودة أقل أعلى جودة @@ -1749,7 +1749,7 @@ خطأ تحيين القائمة المحلية لPOI. تحيين الPOI قم بتحميل مذكرة OSM الخاصة بك دون الكشف عن هويتك أو باستخدام ملف تعريف OpenStreetMap.org . - إضافة جميع النقاط إلى التوجيه المباشر؟ + إضافة جميع النقاط إلى علامات الخريطة؟ مسح السجلات ؟ إظهار مسارات الدراجة الجبلية يمكنك إزالة التحديثات المحملة والرجوع إلى الإصدار الأصلي للخريطة @@ -1830,7 +1830,7 @@ ملاحظة OSM معلق عليها مسار زلق لإظهار خرائط التزلج، يجب تحميل خريطة خاصة محلية. - حافلة، ترامواي وغيرها + حافلة، عربة وغيرها إنشاء ملاحظة OSM حدث استثناء: لم يتم إنشاء الملاحظة. حدث استثناء: لم يتم غلق الملاحظة. @@ -1868,7 +1868,7 @@ تلوين وفق الانتماء للشبكة تلوين وفق رمز تنزه OSMC خروج - هل أنت متأكد من أنك تريد حذف الملاحظات %1$d؟ + حذف الملاحظات %1$d؟ لعرض الخرائط البحرية، يجب تحميل خريطة خاصة محلياً. تسجيل الموقع العام إلى ملف GPX يمكن تشغيله أو إيقافه باستخدام نافذة تسجيل GPX على الشاشة خريطة. ضبط اسم مضيف البروكسي (مثال 127.0.0.1). @@ -2089,7 +2089,7 @@ إجراءات سريعة إجراء %d شاشة %d - إضافة توجيه مباشر للخريطة + إضافة علامة خريطة إضافة POI نمط الخريطة نمط الخرائط تغير ل \"%s\". @@ -2468,7 +2468,7 @@ إضافة نقطة قبل إضافة نقطة بعد خيارات - سيتم توصيل النقاط بمسارات الوضع المحدد. + سيتم توصيل النقاط بطرق الوضع المحدد. يمكنك حفظ النقاط إما كنقاط طريق أو كخط. اختر وضع الملاحة إضافة نقاط مسار @@ -2481,12 +2481,12 @@ عتبة توجيه الخريطة حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'. تم نقل جميع العلامات إلى السجل - تم نقل التوجيه المباشر إلى السجل - التوجيه المباشر انتقل كنشط + تم نقل العلامة إلى السجل + العلامة أصبحت نشطة قائمة مجموعات آخر استخدام : %1$s - تنشيط التوجيه المباشر + تنشيط العلامة اليوم أمس آخر ٧ أيام @@ -2502,12 +2502,12 @@ سهم متجه للهدف عرض المتجاوز إخفاء المتجاوز - إزالة من \"التوجيه المباشر\" + إزالة من \"علامات الخريطة\" تنازلي تصاعدي تاريخ الإضافة ترتيب حسب: - حدد كيفية الإشارة إلى المسافة والاتجاه للتوجيه المباشر على شاشة الخريطة: + حدد كيفية الإشارة إلى مسافة واتجاه العلامة على شاشة الخريطة: استخدم الموقع أضف موقعك كنقطة أولى لتخطيط طريق مثالي. موقعي @@ -2518,7 +2518,7 @@ تصدير علاماتك إلى ملف يمكنك تحديده هنا: نقل إلى السجل سيتم إزالة المجموعة بعد إعادة تشغيل التطبيق. - التوجيه المباشر + العلامات نمط الإحداثيات لوحة مفاتيح النظام اختر نسق إدخال الأحداثيات. يمكنك دائماً تغييره بالنقر على خيارات. @@ -2535,12 +2535,12 @@ أظهر الخريطة تم حساب المسار رحلة ذهاب وإياب - يجب عليك إضافة توجيه مباشر واحد على الأقل لاستخدام هذه الوظيفة. + يجب عليك إضافة علامة واحدة على الأقل لاستخدام هذه الوظيفة. تنسيق خاطئ أدخل اسم جديد عودة عرض - تمت إضافة نقاط الطريق إلى التوجيه المباشر للخريطة + تمت إضافة نقاط الطريق إلى علامات الخريطة إدخال خاطئ يمكن استيرادها كنقاط مفضلة، أو كملف GPX. استيراد كملف GPX @@ -2548,15 +2548,15 @@ استيراد ملف نقرة على الخريطة ستفعل أزرار التحكم والويدجت. شاشة كاملة - توجيه مباشر مجتاز + علامة مُجتازة إنشاء أو تعديل عناصر OSM قم بإنشاء أو تعديل نقاط الاهتمام OSM ، وفتح ملاحظات OSM أو التعليق عليها ، والمساهمة في ملفات GPX المسجلة. حذف مُعدلة تمت الإضافة تعديل طلب البحث. - تم تنشيط التوجيه المباشر %s. - انقر على التوجيه المباشر في الخريطة لجعله الاعلى بدون فتح القائمة. + تم تنشيط العلامة %s. + انقر على العلامة في الخريطة لجعلها بالاعلى بدون فتح القائمة. تدوين ملاحظات! بدون حد زمني اقرأ المقال كاملا @@ -2564,27 +2564,27 @@ جميع نقاط هذه المجموعة افتح من مفتوح حتى - يغلق أبوابه على - سيفتح الأبواب على - يفتح أبوابه على + يغلق عند + يفتح عند + يفتح عند إجراءات إضافية إجراءات - توجيه مباشر + العلامات الملاحظات حسب التاريخ حسب التاريخ حسب النوع المزيد - التوجيه المباشر + المظهر على الخريطة نقاط المسار إضافة مجموعة - قم بإنشاء التوجيه المباشر على الخريطة ! + قم بإنشاء علامات على الخريطة ! استيراد مجموعات عدد الأرقام اليمين اليسار لصق الانتقال إلى الحقل التالي - إعادة تسمية التوجيه المباشر + إعادة تسمية العلامة مجموع التبرعات تسميات POI بدون اسم @@ -2616,7 +2616,7 @@ ج ش اسم النقطة - الطرق القريبة التي في الداخل + الطرق القريبة في الداخل أدخل اسم الملف. خطأ أثناء استرجاع الخريطة تمت عملية استيراد الخريطة @@ -2628,7 +2628,7 @@ قم باختيار نسق الملف جميع البيانات ملاحظات OSM - سيفتح أبوابه غداً على + سيفتح غداً عند ماذا هنا: اللاوسية عرض خريطة السياحة @@ -2692,7 +2692,7 @@ تنزيل الكل إعادة تشغيل التطبيق إشارة مرجعية - نقاط بالطريق تم إزالتها من التوجيه المباشر للخريطة + نقاط بالطريق تم إزالتها من علامات الخريطة بواسطة أوسماند الأسعار والاشتراك شهري @@ -2707,14 +2707,14 @@ يجدد سنويا حدد فترة الدفع المناسبة لك: تبرعات مساعدة صندوق رسم الخرائط OSM. - حذف التوجيه المباشر \'%s\'؟ - تعديل التوجيه المباشر + حذف العلامة \'%s\'؟ + تعديل العلامة بحث عن شارع اختر المدينة أولاً استعادة تطبيق من طرف ثالث - عند التفعيل سيبقى التوجيه المباشر المضاف من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز التوجيه المباشر\". إذا كانت المجموعة غير نشطة ستختفي الوجهات المباشرة من الخريطة. - إبقاء التوجيه المباشر المتجاوز + ستبقى العلامات المضافة من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز العلامة\". إذا كانت المجموعة غير نشطة ستختفي العلامات من الخريطة. + إبقاء العلامة المتجاوز هناك المزيد من وسائل النقل في هذا الموقف. يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل. شكرا على الرد @@ -2842,7 +2842,7 @@ إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة. ابحث عن المسارات مع نقاط الطريق حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق). - نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر التوجيه المباشر. + نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر علامة. يمكنك استيراد المجموعات المفضلة أو نقاط المسار كتوجيه. ستظهر العلامات التي تم تجاوزها على هذه الشاشة. خط مباشر من موقعك إلى الهدف. @@ -2992,7 +2992,7 @@ سنوات ثلاثة أشهر مجاناً - إظهار شبكة مسارات الدارجات الهوائية + إظهار شبكة طرق الدارجات الهوائية نافذة تحميل الخريطة النوافذ والإشعارات التحكم في النوافذ المنبثقة ، ومربعات الحوار والإشعارات. @@ -3017,7 +3017,7 @@ لصق مسار مجلد بيانات أوسماند تغيير مجلد التخزين ؟ نقل للموقع الجديد - تجنب بعض الطرق + تجنب بعض أنواع الطرق جنبًا إلى جنب طريق تلفريك اتصال @@ -3042,7 +3042,7 @@ تفضيل الطرق الغير معبدة تفضيل الطرق الغير معبدة. تحديث كل الخرائط - هل أنت متأكد من رغبتك بتحديث (%1$d) خريطة؟ + تحديث (%1$d) خريطة؟ • تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. \n \n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط @@ -3328,14 +3328,14 @@ طرق لجولات التزلج. تزلج منحدرات لاستخدام الزلاجات. - السماح بالمسارات المتوسطة - طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات التي ينبغي تجنبها. + السماح بالطرق المتوسطة + طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات ينبغي تجنبها. السماح للطرق المتقدمة طرق صعبة ، مع عقبات خطيرة وأقسام شديدة الانحدار. السماح بطرق المتخصصين طرق صعبة للغاية ، مع عقبات خطيرة والمناطق المحيطة بها. السماح بالتزلج على الطرق فقط - الطريق مصممة خصيصا بحرية أو التزلج على الجليد. + طرق مصممة للأسلوب الحر أو التزلج فقط بدون المسارات الكلاسيكية. السماح للطرق الكلاسيكية فقط تم إعداد الطرق للأسلوب الكلاسيكي فقط دون مسارات التزلج. يشمل ذلك الطرق التي يتم إعدادها بواسطة عربة ثلجية أصغر مع زحلقة مرنة ومسارات مصنوعة يدوياً بواسطة المتزلجين. الصعوبة المفضلة @@ -3355,8 +3355,8 @@ لوحة المفاتيح وندرلينك ببغاء - المسار: المسافة%2$s، وقت التوجيه %1$s. -\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب) + "المسار: المسافة%1$s، الوقت %2$s. +\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب" الأوكيتانية ثم %1$s تطبيق فقط على \"%1$s\" @@ -3378,7 +3378,7 @@ اختر اللون لا يمكنك حذف أوضاع أوسماند الافتراضية ، ولكن يمكنك تعطيلها في الشاشة السابقة ، أو نقلها إلى الأسفل. تحرير الأوضاع - يؤثر نوع التنقل على قواعد حسابات المسار. + يؤثر نوع التنقل على قواعد حساب الطرق. مظهر الوضع اختر الايقونة واللون والاسم تحرير قائمة الأوضاع @@ -3534,7 +3534,7 @@ استعادة جميع إعدادات الوضع؟ حفظ الوضع الجديد لا يمكن عمل نسخة احتياطية لهذا الوضع. - هل أنت متأكد من أنك تريد مسح البيانات المسجلة؟ + مسح البيانات المسجلة؟ استيراد البيانات من %1$s استيراد OsmAnd تحقق %1$s للتكرارات مع العناصر الموجودة في التطبيق. @@ -3730,7 +3730,7 @@ مهلة الشاشة الافتراضية يمكنك تصدير أو استيراد إجراءات سريعة باستخدام أوضاع التطبيق . حذف الكل؟ - هل أنت متأكد من رغبتك في حذف الاختصارات السريعة %d نهائيًا؟ + حذف الاختصارات السريعة %d نهائيًا؟ مهلة الشاشة نغمات أدل بعرض مركبتك، قد يتم تطبيق بعض القيود على المركبات العريضة. @@ -3787,7 +3787,7 @@ أغلق ملاحظة OSM تحتاج إلى تعيين أيام العمل للمتابعة المسار بين النقاط - قياس المسافة + تخطيط طريق إضافة إلى مسار لن تكون النقطة المضافة مرئية على الخريطة، نظرًا لأن المجموعة المحددة مخفية، يمكنك العثور عليها في \"%s\". إظهار رموز البدء والانتهاء @@ -3816,7 +3816,7 @@ بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد أوضاع التنقل الخاصة بك لاستخدام هذا الخيار. بداية المسافة صور للشارع - هل أنت متأكد أنك تريد إغلاق مسار الرحلة دون حفظ؟ سوف تفقد كل التغييرات؟ + إغلاق مسار الرحلة دون حفظ؟ ستفقد كل التغييرات؟ في حالة الاتجاه المعاكس تسجيل المسار أثناء الملاحة حفظ كملف مسار جديد @@ -3997,8 +3997,8 @@ \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n \n - وضع الاستعراض - ملف تعريف المستخدم + وضع أساسي + وضع المستخدم عكس جميع النقاط حدد الوضع الذي سيتم استخدامه في بدء التطبيق. آخر استخدام From 4308ab15dd65ad1ed8f952ee1cb9803681064a91 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Mon, 8 Feb 2021 10:03:59 +0000 Subject: [PATCH 084/398] Translated using Weblate (Arabic) Currently translated at 99.9% (3659 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index be1ee7842e..48e89e070c 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4074,4 +4074,13 @@ رفع %1$d من %2$d تم رفع %1$d من %2$d تحديد التعديلات للتحميل + التضاريس / الانحدار / الخطوط المحيطية + OpenPlaceReviews هو مشروع يحركه المجتمع حول الأماكن العامة مثل المطاعم والفنادق والمتاحف ونقاط الطريق. يقوم بجمع جميع المعلومات العامة المتعلقة بهم مثل الصور والتعليقات والروابط إلى ارتباط الأنظمة الأخرى OpenStreetMap و Wikipedia. +\n +\nجميع بيانات OpenPlaceReview مفتوحة ومتاحة للجميع: http://openplacereviews.org/data. +\n +\nيمكنك قراءة المزيد على: http://openplacereviews.org + مراجعات الأمكنة + استخدام test.openplacereviews.org + الدخول إلى OpenPlaceReviews \ No newline at end of file From cc2653d79addacc5174a81db9a24e541041e7f52 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Sun, 7 Feb 2021 13:47:50 +0000 Subject: [PATCH 085/398] Translated using Weblate (French) Currently translated at 99.9% (3660 of 3661 strings) --- OsmAnd/res/values-fr/strings.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index c963ab462e..1f8808c5dc 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -2382,7 +2382,7 @@ Enregistrer les traces dans des dossiers mensuels Enregistrer les traces dans des sous-dossiers organisés par mois (par exemple 2018-01). %1$d de %2$d - Durée de déplacement + Durée de mouvement Min / Max Rose translucide Suspendre / Reprendre la Navigation @@ -3981,7 +3981,7 @@ Ce nom existe déjà Poids lourd Durée - Analyser par intervalles (fractionner) + Analyser par intervalles de fractionnement Intervalles de temps et de distance Le délai d\'annonce des alertes vocales dépend du type d\'annonce, de la vitesse actuelle et du type de navigation. Délai de l\'annonce @@ -4001,4 +4001,8 @@ %1$d sur %2$d envoyé Envoi en cours Envoi terminé + Ombrage du relief / Pente / Courbes de niveaux + OpenPlaceReviews + Utilisez test.openplacereviews.org + Se connecter à OpenPlaceReviews \ No newline at end of file From bf8320023e4cbbe5258152cc11fa1ed28b1857bb Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 7 Feb 2021 15:56:39 +0000 Subject: [PATCH 086/398] Translated using Weblate (German) Currently translated at 99.9% (3658 of 3661 strings) --- OsmAnd/res/values-de/strings.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index f71ed65545..215d278648 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3694,7 +3694,7 @@ Mapillary ein-/ausblenden Mapillary ausblenden Mapillary anzeigen - Eine Umschaltfläche zum ein- oder ausblenden der Mapillary-Layer auf der Karte. + Eine Umschaltfläche zum Ein- oder Ausblenden des Mapillary-Layers auf der Karte. Blitzer deinstallieren Rechtliches Blitzer-POIs @@ -4013,4 +4013,13 @@ Lade %1$d von %2$d hoch %1$d von %2$d hochgeladen Bearbeitungen zum Hochladen auswählen + Relief / Hangneigung / Höhenlinien + OpenPlaceReviews ist ein von der Gemeinschaft betriebenes Projekt über öffentliche Orte wie Restaurants, Hotels, Museen, Wegpunkte. Es sammelt alle öffentlichen Informationen über sie wie Fotos, Bewertungen, Links zu anderen Systemen, Link OpenStreetMap, Wikipedia. +\n +\nAlle OpenPlaceReview-Daten sind offen und für jedermann zugänglich: http://openplacereviews.org/data. +\n +\nMehr Informationen finden Sie unter: http://openplacereviews.org + OpenPlaceReviews + test.openplacereviews.org verwenden + Anmelden bei OpenPlaceReviews \ No newline at end of file From 8d6cc1127d3bfaf2401ed6cd6821a383b206abcb Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 7 Feb 2021 17:56:11 +0000 Subject: [PATCH 087/398] Translated using Weblate (Russian) Currently translated at 99.7% (3647 of 3657 strings) --- OsmAnd/res/values-ru/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 5747a78d85..4836ea274c 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3992,4 +3992,13 @@ Отправка %1$d из %2$d Отправлено %1$d из %2$d Выберите правки для отправки + Рельеф / Уклон/ Контурные линии + Транспортное средство + Велосипед + Электрический велосипед + Горный велосипед + Шоссейный велосипед + Обычный велосипед + Гоночный велосипед + Горный велосипед \ No newline at end of file From 39347ce7e2a55ddf349ac6b35b0976b372cf2a28 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 8 Feb 2021 14:23:17 +0000 Subject: [PATCH 088/398] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3657 of 3657 strings) --- OsmAnd/res/values-uk/strings.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index f724876c74..470ebc3850 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -2971,7 +2971,7 @@ Лижі Лижі Показати компас-лінійку - Приховати компас-лінійку + Сховати компас-лінійку Оберіть значок Режим: %s Користувацький режим, похідний від: %s @@ -2988,7 +2988,7 @@ Зберегти зміни Спочатку збережіть зміни в профілі Видалити профіль - Ви дійсно хочете видалити профіль %s\? + Ви дійсно хочете видалити профіль «%s» Виберіть профіль для початку Служба завантаження OsmAnd Пурпуровий @@ -3302,7 +3302,7 @@ Профілі, додані втулком Вимкнути Нова втулка додана - Приєднати частки + Об’єднати сегменти Додати новий профіль \'%1$s\'\? Зберегти заголовок Зберегти заголовок для кожної точки треку під час запису. @@ -3736,7 +3736,7 @@ Суцільний В останнє змінено Імпортувати трек - Переглянути наявний трек + Відкрити наявний трек Створити новий маршрут Виберіть який файл з треком відкрити. Готово @@ -3966,7 +3966,7 @@ Вибрати теку Виберіть теку або додайте нову Порожньо - Аналіз за інтервалами (розділений інтервал) + Аналізувати розділені інтервали Відвантажити на OpenStreetMap Редагувати трек Перейменувати трек @@ -4010,4 +4010,5 @@ Вивантаження %1$d з %2$d Вивантажено %1$d з %2$d Виберіть зміни для вивантаження + Рельєф місцевості / Схили / Горизонталі \ No newline at end of file From 0ff11328058eeaa7a8c9453be8e6fbfdaa6284a0 Mon Sep 17 00:00:00 2001 From: Michalis Date: Mon, 8 Feb 2021 16:06:31 +0000 Subject: [PATCH 089/398] Translated using Weblate (Greek) Currently translated at 92.4% (3386 of 3661 strings) --- OsmAnd/res/values-el/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-el/strings.xml b/OsmAnd/res/values-el/strings.xml index b1ddebc715..af31956d26 100644 --- a/OsmAnd/res/values-el/strings.xml +++ b/OsmAnd/res/values-el/strings.xml @@ -778,7 +778,7 @@ Ενημέρωση χάρτη Δημιουργία ΣΕ Ναι - Ακύρωση + Άκυρο Εφαρμογή Όχι Εισαγωγή ονόματος αγαπημένου @@ -1270,7 +1270,7 @@ Λήψη Νέου Χάρτη Γλώσσα χάρτη Μορφή δρόμου - Προκαθορισμένο + Προεπιλογή Πορτοκαλί Διασταύρωση σιδηροτροχιάς Διασταυρώσεις σιδηροτροχιάς @@ -1467,7 +1467,7 @@ Τμήματα διαδρομής Σημεία της διαδρομής Τοποθεσία:\n Γ. Πλ %1$s\n Γ. Μηκ %2$s - Προκαθορισμένο + Προεπιλογή Εκτύπωση διαδρομής εκπρόθεσμο Προσομοίωση της θέση σας @@ -3013,7 +3013,7 @@ Εμφάνιση στον χάρτη ζωνών για χαμηλή εκπομπή καυσαερίων. Δεν επηρεάζει τη δρομολόγηση. Εμφάνιση ζωνών χαμηλής εκπομπής καυσαερίων Λάβετε υπόψη τους προσωρινούς περιορισμούς - Προεπιλεγμένο + Προεπιλογή Ημιφορτηγό Ημέρα Ημέρες From c0d397ccc24ea317e831ab5bd52db863b8f574fc Mon Sep 17 00:00:00 2001 From: ace shadow Date: Sun, 7 Feb 2021 22:32:43 +0000 Subject: [PATCH 090/398] Translated using Weblate (Slovak) Currently translated at 100.0% (3657 of 3657 strings) --- OsmAnd/res/values-sk/strings.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 84b80a03a8..ada5be40c9 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -2415,7 +2415,7 @@ Vzdialenosť opravená Povolenia Nepodarilo sa naimportovať súbor. Prosím zabezpečte, že OsmAnd má oprávnenie čítať súbor. - Polomerové pravítko + Kruhové pravítko Resetovať Znovu načítať Znovu načítať dlaždice pre získanie aktuálnych dát. @@ -3580,7 +3580,7 @@ Stopovanie OsmAnd OsmAnd + Mapillary Rýchla akcia - Polomerové pravítko + Kruhové pravítko Merať vzdialenosť Cestovanie (Wikivoyage a Wikipédia) Mapové značky @@ -3962,7 +3962,7 @@ Zvoľte priečinok Zvoľte priečinok alebo pridajte nový Prázdne - Analyzovať podľa intervalov (rozdeliť interval) + Analyzovať rozdelené intervaly Nahrať do OpenStreetMap Upraviť stopu Premenovať stopu @@ -4006,4 +4006,5 @@ Odosiela sa %1$d z %2$d Odoslané %1$d z %2$d Zvoľte úpravy na odoslanie + Tieňované svahy / Sklony svahov / Vrstevnice \ No newline at end of file From de0d774ae71945f4afee6d5bf82cdcf6d78546e2 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sun, 7 Feb 2021 15:52:43 +0000 Subject: [PATCH 091/398] Translated using Weblate (Hebrew) Currently translated at 99.8% (3656 of 3661 strings) --- OsmAnd/res/values-iw/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 737272e2e5..d91880e6d1 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4013,4 +4013,7 @@ נשלחות %1$d מתוך %2$d נשלחו %1$d מתוך %2$d נא לבחור עריכות לשליחה + OpenPlaceReviews + להשתמש ב־test.openplacereviews.org + כניסה ל־OpenPlaceReviews \ No newline at end of file From 5686fa9ab5588b98a26cdb83d7e080ff9d7067fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Mon, 8 Feb 2021 07:31:19 +0000 Subject: [PATCH 092/398] Translated using Weblate (Czech) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-cs/strings.xml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 738a4e98fe..ed36b49158 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -3425,7 +3425,7 @@ Směrové šipky Naposledy upraveno Importovat trasu - Otevřít existující trasu + Otevřít existující stopu Vytvořit novou trasu Vyberte stopu k otevření. Hotovo @@ -3442,10 +3442,10 @@ Přidat mezicíl Záznam trasy Uložit jako soubor trasy - Sledovat trasu + Sledovat stopu Zvolte soubor trasy, kterou chcete sledovat Zvolte soubor stopy, kterou chcete sledovat, nebo jej importujte ze svého zařízení. - Zvolit jinou trasu + Zvolit jinou stopu Navigovat z mé polohy k trase Bod trasy pro navigování Začátek trasy @@ -3490,7 +3490,7 @@ Ukládat trasu do GPX souboru Trasa ze stopy Přidat soubory stop - Zjednodušená trasa + Zjednodušená stopa Uloží se pouze linie trasy, mezicíle budou odstraněny. Název souboru %s vybraných souborů stop @@ -3505,7 +3505,7 @@ Pouze vybraný úsek bude přepočítán pomocí vybraného profilu. Všechny následující úseky budou přepočítány pomocí vybraného profilu. Všechny předcházející úseky budou přepočítány pomocí vybraného profilu. - Otevřít uloženou trasu + Otevřít uloženou stopu je uloženo Přidejte prosím alespoň dva body. Znovu @@ -3967,7 +3967,7 @@ Zvolte složku Zvolte složku nebo vytvořte novou Prázdné - Analyzovat podle intervalů (rozdělit interval) + Analyzovat rozdělené intervaly Nahrát do OpenStreetMap Editovat stopu Přejmenovat stopu @@ -4011,4 +4011,13 @@ Nahrávám %1$d z %2$d Nahráno %1$d z %2$d Vyberte úpravy pro nahrání + Stínované svahy / Sklon svahů / Vrstevnice + OpenPlaceReviews je komunitní projekt o veřejných místech, jako jsou restaurace, hotely, muzea a další. Shromažďuje o nich veškeré veřejné informace, např. fotografie, hodnocení, odkazy do dalších systémů jako OpenStreetMap či Wikipedie. +\n +\nVšechna data OpenPlaceReviews jsou otevřená a přístupná každému: http://openplacereviews.org/data. +\n +\nPřečtěte si více na http://openplacereviews.org + OpenPlaceReviews + Použít test.openplacereviews.org + Přihlásit se do OpenPlaceReviews \ No newline at end of file From c626e95421479744e859bba5930b73044657d748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1ns?= Date: Mon, 8 Feb 2021 14:27:06 +0000 Subject: [PATCH 093/398] Translated using Weblate (Galician) Currently translated at 99.8% (3657 of 3661 strings) --- OsmAnd/res/values-gl/strings.xml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml index c39329ec8e..6c078f0d5b 100644 --- a/OsmAnd/res/values-gl/strings.xml +++ b/OsmAnd/res/values-gl/strings.xml @@ -3998,4 +3998,35 @@ Lon %2$s Bicicleta de montaña Erro do servidor: %1$s O nome xa existe + Analizar intres divididos + Subir ao OpenStreetMap + Editar pista + Renomear pista + Mudar cartafol + seg + Pasando + Aproximación + Longa preparación + Preparar + Fóra da ruta + Eliminar este motor de navegación en liña\? + Ler completo + Editar descrición + Eliminar puntos de referencia + Copiar ás marcaxes do mapa + Copiar aos favoritos + Subindo + Subida completa + Subindo %1$d de %2$d + Subíronse %1$d de %2$d + Seleccionar edicións para subir + Sombras do relevo / Pendentes / Curvas de nivel + O OpenPlaceReviews é un proxecto impulsado pola comunidade sobre lugares públicos como restaurantes, hoteis, museos, puntos de referencia. Recolle toda a información pública sobre eles como imaxes, recesións, ligazóns a outros servizos como OpenStreetMap e Wikipedia. +\n +\nTodos os datos do OpenPlaceReviews son abertos e están dispoñíbeis para todos: http://openplacereviews.org/data. +\n +\nPodes ler máis en: https://openplacereviews.org + OpenPlaceReviews + Empregar test.openplacereviews.org + Iniciar sesión ao OpenPlaceReviews \ No newline at end of file From 049146c1343facfef0b1fbb314aeaf86225bed6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Mon, 8 Feb 2021 07:57:38 +0000 Subject: [PATCH 094/398] Translated using Weblate (Czech) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-cs/phrases.xml | 48 +++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-cs/phrases.xml b/OsmAnd/res/values-cs/phrases.xml index 8c6b4981ff..8fafe343d7 100644 --- a/OsmAnd/res/values-cs/phrases.xml +++ b/OsmAnd/res/values-cs/phrases.xml @@ -3601,7 +3601,7 @@ Přístup vozidel: vojenské Přístup vozidel: zásobování Přístup vozidel: lesnictví - Přístup aut: + Přístup aut: ano Přístup aut: soukromý Přístup aut: ne Přístup aut: cíl @@ -3835,4 +3835,50 @@ Neimigrační víza Konzulát Ambasáda + Mobilní směnárna + Prostředník + Prostředník + Netopýří tunel + Netopýří most + Ekodukt + Plovárna + Veřejná prádelna + Překladiště odpadů + Mostní váha + Stanice rangera + Jezero + Řeka + Studna + Poháněné čerpadlo + Vodní nádrž + Kohoutek + Zásobování vodou + Trubková studna + Očkování: COVID19 + Očkování + Záchranářská základna + Siréna + Zdravotní sestra + Ne + Ano + Ne + Ano + Ne + Ano + Podnárodní + Reprezentační kancelář + Kancelář + Honorární konzul + Generální konzulát + Kancelář konzula + Konzulární zastupitelstvo + Vedená konzulem + Rezidence + Nunciatura + Mise + Zájmová sekce + Vysoký komisař + Delegace + Pobočka + Vedená velvyslancem \ No newline at end of file From f7c9bd393f59a833b6f4d38d130e6953ac78b8d6 Mon Sep 17 00:00:00 2001 From: Franco Date: Sun, 7 Feb 2021 22:40:27 +0000 Subject: [PATCH 095/398] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (3660 of 3661 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 56 ++++++++++++++++------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 18a479e18b..b1bdd574c8 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -772,24 +772,24 @@ \n Los PDI de OsmAnd están siendo desarrollados activamente. Nuestro proyecto y su continuo progreso, se basa en contribuciones económicas para desarrollar y probar nuevas funcionalidades. Por favor, considera comprar OsmAnd+, financiar nuevas funciones o hacer una donación general en https://osmand.net. Navegación y Mapas OsmAnd+ Visor y navegador móvil global de mapas OSM con y sin conexión - OsmAnd+ (OSM Automated Navigation Directions, y en español, Guía de Navegación Automatizada de OSM) -\n -\nOsmAnd+ es un software de navegación de código abierto con acceso a una amplia variedad de datos globales de OSM. Todos los datos del mapa (vectores y teselas), pueden ser almacenados en la memoria del teléfono para su uso sin conexión. Ofrece funcionalidades de rutas con y sin conexión, incluyendo guía de giro-a-giro por voz. -\n -\n OsmAnd+ es la versión de pago de la aplicación, comprándola ayudas al proyecto, financias el desarrollo de nuevas funciones, y recibes las últimas actualizaciones. -\n -\n Algunas de las funciones fundamentales: -\n - Completa funcionalidad sin conexión (guarda los mapas vectoriales o teselas descargados en el almacenamiento del dispositivo) -\n - Mapas mundiales vectoriales compactos disponibles -\n - Descarga ilimitada de mapas de países o regiones directamente desde la aplicación -\n - Posibilidad de superponer varias capas de mapa, como GPX o rutas de navegación, Puntos de Interés, Favoritos, curvas de nivel, paradas de transporte público, mapas adicionales con transparencia personalizable -\n -\n - Búsqueda sin conexión de direcciones y sitios (PDI) -\n - Rutas sin conexión para distancias de rango medio -\n - Modos de automóvil, bicicleta y peatón con opcional: -\n - Cambio automático de modo diurno/nocturno -\n - Zoom del mapa según la velocidad -\n - Alineación del mapa, según brújula o dirección del movimiento + OsmAnd+ (OSM Automated Navigation Directions, y en español, Guía de Navegación Automatizada de OSM) +\n +\n OsmAnd+ es un software de navegación de código abierto con acceso a una amplia variedad de datos globales de OSM. Todos los datos del mapa (vectores y teselas), pueden ser almacenados en la memoria del teléfono para su uso sin conexión. Ofrece funcionalidades de rutas con y sin conexión, incluyendo guía de giro-a-giro por voz. +\n +\n OsmAnd+ es la versión de pago de la aplicación, comprándola ayudas al proyecto, financias el desarrollo de nuevas funciones, y recibes las últimas actualizaciones. +\n +\n Algunas de las funciones fundamentales: +\n - Completa funcionalidad sin conexión (guarda los mapas vectoriales o teselas descargados en el almacenamiento del dispositivo) +\n - Mapas mundiales vectoriales compactos disponibles +\n - Descarga ilimitada de mapas de países o regiones directamente desde la aplicación +\n - Posibilidad de superponer varias capas de mapa, como GPX o rutas de navegación, Puntos de Interés, Favoritos, curvas de nivel, paradas de transporte público, mapas adicionales con transparencia personalizable +\n +\n - Búsqueda sin conexión de direcciones y sitios (PDI) +\n - Rutas sin conexión para distancias de rango medio +\n - Modos de automóvil, bicicleta y peatón con opcional: +\n - Cambio automático de modo diurno/nocturno +\n - Zoom del mapa según la velocidad +\n - Alineación del mapa, según brújula o dirección del movimiento \n - Indicación de carriles, mostrar límites de velocidad, voces grabadas y sintetizadas \n Crear filtro PDI @@ -1222,8 +1222,7 @@ Todos los datos sin conexión en la versión vieja de OsmAnd son compatibles con la nueva versión, pero los puntos de Favoritos deben exportarse desde la versión vieja y luego, importarse en la nueva. Compilación {0} instalada ({1}). Descargando compilación… - ¿Instalar OsmAnd? -\nVersión: {0} + ¿Instalar OsmAnd {0}\? \nFecha: {1} \nTamaño: {2} MB Error al recuperar la lista de compilaciones de OsmAnd @@ -2063,7 +2062,7 @@ Notificaciones Sin archivos de trazas aún También puedes añadir archivos de trazas a la carpeta - Añadir GPX + Añadir más… Aspecto Muy fino Cálculo de la ruta @@ -3732,8 +3731,8 @@ El punto añadido no será visible en el mapa, ya que el grupo elegido está oculto, se puede encontrar en «%s». Mostrar los iconos de inicio y fin Elegir la anchura - Marca el intervalo en el que se mostrarán las marcas con distancia o tiempo en la traza. - Marca la opción de división deseada: por tiempo o por distancia. + Elige el intervalo de la traza en el que se mostrarán las marcas con la distancia o el tiempo. + Elige la opción de división deseada: por tiempo o por distancia. Personalizado Flechas de dirección Sólido @@ -3970,7 +3969,7 @@ Elegir carpeta Elegir carpeta o añadir una nueva Vacío - Analizar por intervalos (intervalo de división) + Analizar intervalos divididos Subir a OpenStreetMap Editar traza Renombrar traza @@ -4014,4 +4013,13 @@ Subiendo %1$d de %2$d Se subieron %1$d de %2$d Marcar ediciones a subir + Sombreado / Pendiente / Curvas de nivel + OpenPlaceReviews es un proyecto impulsado por la comunidad sobre lugares públicos como restaurantes, hoteles, museos, puntos de referencia. Recoge toda la información pública sobre ellos como fotos, reseñas, enlaces a otros servicios como OpenStreetMap y Wikipedia. +\n +\nTodos los datos de OpenPlaceReviews son abiertos y están disponibles para todos: http://openplacereviews.org/data. +\n +\nPuedes leer más en: https://openplacereviews.org + OpenPlaceReviews + Usar test.openplacereviews.org + Acceder a OpenPlaceReviews \ No newline at end of file From 919efeee4ee555b09d243478ae07b61afe7bc980 Mon Sep 17 00:00:00 2001 From: Franco Date: Sun, 7 Feb 2021 22:43:35 +0000 Subject: [PATCH 096/398] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3881 of 3881 strings) --- OsmAnd/res/values-es-rAR/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml index ac7e14f5ee..44abab2a5b 100644 --- a/OsmAnd/res/values-es-rAR/phrases.xml +++ b/OsmAnd/res/values-es-rAR/phrases.xml @@ -2723,7 +2723,7 @@ Acuicultura: mejillones Edad mínima - No + Productos orgánicos: no Únicamente Espejo de tráfico Consulado From e995142894663f5b962a80dfb80adcb6e2afa9ef Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Sun, 7 Feb 2021 13:29:48 +0000 Subject: [PATCH 097/398] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3657 of 3657 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 023809b5ae..afd52545aa 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3782,7 +3782,7 @@ Alterar o tipo de rota antes Alterar o tipo de rota após Trilha simplificada - Apenas a linha da rota será salva, os waypoints serão excluídos. + Apenas a linha da rota será salva, os pontos de passagem serão excluídos. Nome do arquivo %s arquivos de trilha selecionados O registro de trilhas fará uma pausa quando o aplicativo for encerrado (por meio de aplicativos recentes). (A indicação de segundo plano do OsmAnd desaparece da barra de notificação do Android.) @@ -3962,7 +3962,7 @@ Selecione a pasta Selecione a pasta ou adicione uma nova Vazio - Analisar por intervalos (intervalo de divisão) + Analisar intervalos de divisão Carregar para OpenStreetMap Editar trilha Renomear trilha @@ -4006,4 +4006,5 @@ Carregando %1$d de %2$d Carregado %1$d de %2$d Selecione as edições para carregamento + Sombras de relevo / Encostas / Curvas de nível \ No newline at end of file From 1e63481a4a8bbe843857e96d56c77dc446ac50e5 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sun, 7 Feb 2021 18:44:19 +0000 Subject: [PATCH 098/398] Translated using Weblate (Esperanto) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-eo/strings.xml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 219a59ae10..da7a929cf2 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -654,7 +654,7 @@ Trovis nenion. Se vi ne povas trovi vian regionon, vi povas fari ĝin mem (rigardu https://osmand.net). Unue elektu GPX‑dosieron per frapetadi. Elektu kurson - Intertempo de divido + Fragmento Ordigi laŭ distanco Ordigi laŭ nomo Turisma map-vido @@ -2405,7 +2405,7 @@ Kontribui viajn strat-nivelajn vidaĵojn pri tiu ĉi loko al Mapillary. Strat-nivelaj fotoj por ĉiuj. Esplori lokojn, kunlabori kaj foti la mondon. Enretaj fotoj - Neniuj fotoj tie ĉi. + Neniu foto tie ĉi. Instali Pliigi fotan atingon de Mapillary Instalu la aplikaĵon Mapillary por aldoni fotojn al tiu ĉi loko sur la mapo. @@ -3967,7 +3967,7 @@ Elekti dosierujon Elekti dosierujon aŭ krei novan Malplena - Analizi laŭ intertempoj (dividoj) + Analizi laŭ fragmentoj Alŝuti al OpenStreetMap Redakti spuron Renomi spuron @@ -4011,4 +4011,13 @@ Sendado de %1$d el %2$d Sendis %1$d el %2$d Elektu redaktojn por sendi + Nivelombrumo / dekliveco / nivelkurboj + OpenPlaceReviews estas komunuma projekto pri publikaj lokoj, kiel restoracioj, hoteloj, muzeoj, rekoniloj, ktp. Ĝi kolektas diversajn publikajn informojn pri tiuj punktoj: fotojn, opiniojn, ligilojn al OpenStreetMap kaj Vikipedio. +\n +\nĈiuj OpenPlaceReview‑datumoj estas malfermaj kaj disponeblaj por ĉiu: http://openplacereviews.org/data +\n +\nPliaj informoj ĉe http://openplacereviews.org + OpenPlaceReviews + Uzi test.openplacereviews.org + Ensaluti al OpenPlaceReviews \ No newline at end of file From 5425152065baa442cecd5dcb86cd9dffb3d7a971 Mon Sep 17 00:00:00 2001 From: Liu Tao Date: Sun, 7 Feb 2021 15:57:20 +0000 Subject: [PATCH 099/398] Translated using Weblate (Chinese (Simplified)) Currently translated at 67.7% (2478 of 3657 strings) --- OsmAnd/res/values-zh-rCN/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index c21fc6f733..9550f1fb9c 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -35,7 +35,7 @@ 避開高速路 自动缩放地图 運輸方式: - 選擇傳輸模式 + 运输模式: 地图风格 熒光路線 統治者 @@ -430,9 +430,9 @@ 等高线数据 录制视频 录制音频 - 选择缺省窗体动作。 + 默认小部件操作: 缺省窗体动作 - 选择视频输出格式。 + 视频输出格式: 视频输出格式 使用系统程序录制视频。 使用系统程序拍照 @@ -481,7 +481,7 @@ 路线小地图 设置唤醒间隔: 上次导航未完成。是否继续?(%1$s 秒) - 选择模拟导航速度 + 路线模拟速度: 已分配内存 %1$s MB (Android 限制 %2$s MB,Dalvik %3$s MB)。 分享位置 有时间限制 @@ -555,7 +555,7 @@ 开始模拟导航 文件无法重命名。 同名文件已存在。 - 找到多个满足查询的POI类别: + 找到了几个相关的 POI 类别。 用于搜索POI的本地数据不存在。 按名称搜索 兴趣点数据文件 \'%1$s\' 是多余的,可以删除。 @@ -2020,7 +2020,7 @@ 感谢您使用 OsmAnd。对于此应用程序的许多功能,您需要一些地区的离线数据,您可以透过\'设置\' -> \'管理地图文件\'来下载。之后您可浏览地图、位置的地址、查看兴趣点以及寻找大众运输工具。 底图为某些特别的应用功能必需使用的,并且缺省为下载。 启动插件的高级设置和更多的附加功能。 - 用所选择的语音播放指令 + 通过播放通知选择语音和测试: 回到目前位置 横向(8 个扇区) 顺时针(12 个扇区) @@ -3068,7 +3068,7 @@ 到期时间 选择如何储存下载的数据。 你可以在应用配置中导入导出快捷操作。 - 你确定要删除%d快捷操作吗? + 你确定要不可撤销地删除 %d 快捷操作吗? 在某些国家或地区,使用测速摄像头提示应用是非法的。 \n \n你需要根据你所在的国家的法律作出选择。 From d3e4cf8cfbd34974067e5c39789dde7ffca4e712 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 8 Feb 2021 01:40:21 +0000 Subject: [PATCH 100/398] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3657 of 3657 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 9b601f4c19..388b13d671 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3960,7 +3960,7 @@ 選取資料夾 選取資料夾或新增 - 按時間間隔分析(分割時間間隔) + 分析分割間隔 上傳到 OpenStreetMap 編輯軌跡 重新命名軌跡 @@ -4004,4 +4004,5 @@ 正在上傳 %1$d,共 %2$d 已上傳 %1$d,共 %2$d 選取要上傳的檔案 + 地形陰影/斜坡/等高線 \ No newline at end of file From 562f09ce76c52733869fc8251492ce3e9f74e1f3 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 7 Feb 2021 17:09:54 +0000 Subject: [PATCH 101/398] Translated using Weblate (Russian) Currently translated at 99.9% (3878 of 3881 strings) --- OsmAnd/res/values-ru/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml index 839721ba13..95e72999d5 100644 --- a/OsmAnd/res/values-ru/phrases.xml +++ b/OsmAnd/res/values-ru/phrases.xml @@ -3878,4 +3878,5 @@ Станция перекачки отходов Станция рейнджеров Место для купания + Экодук \ No newline at end of file From 455518decc5632ff10cd5938f9e7ad17342b4fdf Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 8 Feb 2021 18:44:21 +0200 Subject: [PATCH 102/398] Add custom activity type --- .../wikivoyage/explore/travelcards/TravelGpxCard.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java index 119df5a54a..795980df32 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelGpxCard.java @@ -48,14 +48,9 @@ public class TravelGpxCard extends BaseTravelCard { holder.userIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_user_account_16)); holder.user.setText(article.user); RouteActivityType activityType = RouteActivityType.getTypeFromName(article.activityType); - if (activityType != null) { - int iconId = getActivityTypeIcon(activityType); - if (iconId > 0) { - holder.activityTypeIcon.setImageDrawable(getActiveIcon(iconId)); - } - holder.activityType.setText(getActivityTypeTitle(activityType)); - holder.activityTypeLabel.setVisibility(View.VISIBLE); - } + holder.activityTypeIcon.setImageDrawable(getActiveIcon(getActivityTypeIcon(activityType))); + holder.activityType.setText(getActivityTypeTitle(activityType)); + holder.activityTypeLabel.setVisibility(View.VISIBLE); holder.distance.setText(OsmAndFormatter.getFormattedDistance(article.totalDistance, app)); holder.diffElevationUp.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationUp, app)); holder.diffElevationDown.setText(OsmAndFormatter.getFormattedAlt(article.diffElevationDown, app)); From 27ee57339ba9cb243bdd92a5976969890cf07158 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 8 Feb 2021 21:57:12 +0200 Subject: [PATCH 103/398] Fix compare by distance --- .../plus/wikivoyage/data/TravelDbHelper.java | 6 +++--- .../plus/wikivoyage/data/TravelHelper.java | 5 +++-- .../plus/wikivoyage/data/TravelObfHelper.java | 16 ++++++++++------ .../wikivoyage/explore/ExploreTabFragment.java | 4 +++- .../explore/WikivoyageExploreActivity.java | 14 ++++---------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index 90e6444cff..90ed62569f 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -174,9 +174,9 @@ public class TravelDbHelper implements TravelHelper { } @Override - public void initializeDataToDisplay(boolean showMore) { + public void initializeDataToDisplay() { localDataHelper.refreshCachedData(); - loadPopularArticles(showMore); + loadPopularArticles(); } @@ -283,7 +283,7 @@ public class TravelDbHelper implements TravelHelper { } @NonNull - public List loadPopularArticles(boolean showMore) { + public List loadPopularArticles() { String language = application.getLanguage(); SQLiteConnection conn = openConnection(); if (conn == null) { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java index 4688dd7ff0..b8bb9cdf98 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -17,6 +17,7 @@ public interface TravelHelper { interface GpxReadCallback { void onGpxFileReading(); + void onGpxFileRead(@Nullable GPXFile gpxFile); } @@ -24,7 +25,7 @@ public interface TravelHelper { void initializeDataOnAppStartup(); - void initializeDataToDisplay(boolean showMore); + void initializeDataToDisplay(); boolean isAnyTravelBookPresent(); @@ -35,7 +36,7 @@ public interface TravelHelper { List getPopularArticles(); @NonNull - List loadPopularArticles(boolean showMore); + List loadPopularArticles(); @NonNull Map> getNavigationMap(@NonNull TravelArticle article); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 162616e063..036ba50bbb 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -100,13 +100,13 @@ public class TravelObfHelper implements TravelHelper { } @Override - public void initializeDataToDisplay(boolean showMore) { + public void initializeDataToDisplay() { localDataHelper.refreshCachedData(); - loadPopularArticles(showMore); + loadPopularArticles(); } @NonNull - public synchronized List loadPopularArticles(boolean showMore) { + public synchronized List loadPopularArticles() { String lang = app.getLanguage(); List popularArticles = new ArrayList<>(); if (amenities.size() - count < MAX_POPULAR_ARTICLES_COUNT) { @@ -123,9 +123,13 @@ public class TravelObfHelper implements TravelHelper { Collections.sort(amenities, new Comparator>() { @Override public int compare(Pair article1, Pair article2) { - int d1 = (int) (MapUtils.getDistance(((Amenity) article1.second).getLocation(), location)); - int d2 = (int) (MapUtils.getDistance(((Amenity) article2.second).getLocation(), location)); - return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); + Amenity amenity1 = (Amenity) article1.second; + double d1 = MapUtils.getDistance(amenity1.getLocation(), location) + / (ROUTE_ARTICLE.equals(amenity1.getSubType()) ? 5 : 1); + Amenity amenity2 = (Amenity) article2.second; + double d2 = MapUtils.getDistance(amenity2.getLocation(), location) + / (ROUTE_ARTICLE.equals(amenity2.getSubType()) ? 5 : 1); + return Double.compare(d1, d2); } }); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 2e0cacca65..9afa7a33c3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -191,7 +191,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() { @Override public void onPrimaryButtonClick() { - new LoadWikivoyageData(ExploreTabFragment.this.getExploreActivity(), true).execute(); + if (activity instanceof WikivoyageExploreActivity) { + new LoadWikivoyageData((WikivoyageExploreActivity) activity).execute(); + } } @Override diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index fc28bc6213..3191926522 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -314,10 +314,6 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv } public void populateData() { - populateData(false); - } - - public void populateData(final boolean showMore) { switchProgressBarVisibility(true); if (app.isApplicationInitializing()) { final WeakReference activityRef = new WeakReference<>(this); @@ -330,12 +326,12 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv public void onFinish(AppInitializer init) { WikivoyageExploreActivity activity = activityRef.get(); if (AndroidUtils.isActivityNotDestroyed(activity)) { - new LoadWikivoyageData(activity, showMore).execute(); + new LoadWikivoyageData(activity).execute(); } } }); } else { - new LoadWikivoyageData(this, showMore).execute(); + new LoadWikivoyageData(this).execute(); } } @@ -388,17 +384,15 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv private final WeakReference activityRef; private final TravelHelper travelHelper; - private final boolean showMore; - LoadWikivoyageData(WikivoyageExploreActivity activity, boolean showMore) { + LoadWikivoyageData(WikivoyageExploreActivity activity) { travelHelper = activity.getMyApplication().getTravelHelper(); activityRef = new WeakReference<>(activity); - this.showMore = showMore; } @Override protected Void doInBackground(Void... params) { - travelHelper.initializeDataToDisplay(showMore); + travelHelper.initializeDataToDisplay(); return null; } From a055724d3616e589575481c765cec3da869e621d Mon Sep 17 00:00:00 2001 From: Manuel Tassi Date: Mon, 8 Feb 2021 19:32:21 +0000 Subject: [PATCH 104/398] Translated using Weblate (Italian) Currently translated at 87.9% (3220 of 3661 strings) --- OsmAnd/res/values-it/strings.xml | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 7a3d6ee245..e8a03879ba 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -3925,4 +3925,37 @@ \n" Unisci segmenti Spezza + Arrivo a destinazione + Svolta + Avvia registrazione + Mostra il percorso sulla mappa + Sedia a rotelle + Escursionismo + A piedi + Mezzi pesanti + Camion + Scooter + Bici da corsa + MTB + Errore del server: %1$s + Il nome esiste già + Eliminare questo motore di routing online\? + Modifica descrizione + Elimina i waypoint + Aggiungi ai marcatori + Copia nei preferiti + Caricamento + Caricamento completato + Carico %1$d di %2$d + Caricati %1$d di %2$d + Seleziona le modifiche per il caricamento + Hillshade / Pendenza / Linee di contorno + OpenPlaceReviews è un progetto community-driven su luoghi pubblici come ristoranti, hotel, musei, waypoint. Raccoglie tutte le informazioni pubbliche su di essi come foto, recensioni, link ad altri sistemi che collegano OpenStreetMap, Wikipedia. +\n +\nTutti i dati di OpenPlaceReview sono aperti e disponibili a tutti: http://openplacereviews.org/data. +\n +\nPer maggiori informazioni: http://openplacereviews.org + OpenPlaceReviews + Usa test.openplacereviews.org + Accedi a OpenPlaceReviews \ No newline at end of file From b09e5762f01c0e29b5d4b84e62a9ec974e7df005 Mon Sep 17 00:00:00 2001 From: Michalis Date: Mon, 8 Feb 2021 23:15:17 +0000 Subject: [PATCH 105/398] Translated using Weblate (Greek) Currently translated at 92.4% (3386 of 3661 strings) --- OsmAnd/res/values-el/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-el/strings.xml b/OsmAnd/res/values-el/strings.xml index af31956d26..a2601e7c97 100644 --- a/OsmAnd/res/values-el/strings.xml +++ b/OsmAnd/res/values-el/strings.xml @@ -267,7 +267,7 @@ Επεξεργασία χωρίς διαδίκτυο Χρήση πάντα της επεξεργασίας χωρίς διαδίκτυο. Οι αλλαγές στα ΣΕ μέσω της εφαρμογής δεν επηρεάζουν τα ληφθέντα αρχεία χάρτη, οι αλλαγές αποθηκεύονται ως αρχείο στη συσκευή σας. - Αποστολή … + Αποστολή… {0} ΣΕ/Οι σημειώσεις απεστάλησαν Αποστολή όλων Αποστολή επεξεργασίας στο OSM @@ -813,7 +813,7 @@ Διαγραφή αυτού του φίλτρου; Το φίλτρο \'%1$s\' διαγράφηκε Το φίλτρο \'%1$s\' δημιουργήθηκε - ηλ. διεύθυνση + ηλεκτρονικό ταχυδρομείο Ο ενδιάμεσος προορισμός %1$s είναι πολύ μακριά από τον πλησιέστερο δρόμο. Φτάσατε στον ενδιάμεσο προορισμό σας Προσθήκη ως ενδιάμεσου προορισμού @@ -1175,7 +1175,7 @@ Μόνο χειροκίνητα (πατήστε το βέλος) Επανάληψη οδηγιών πλοήγησης Αποθήκευση δεδομένων ως αρχείο GPX ή εισαγωγή σημείων διαδρομής στα \'Αγαπημένα\'; - Διαμοιρασμός + Κοινοποίηση Μη έγκυρη μορφή: %s Διακοπή Διακοπή λειτουργίας παρασκηνίου του GPS; @@ -3385,7 +3385,7 @@ Σύσταση: Είναι δύσκολο να προβλεφθεί τι θα εγγραφεί και τι όχι, ίσως είναι καλύτερο να απενεργοποιήσετε αυτό το φίλτρο. Παρατήρηση: Εάν το GPS είχε απενεργοποιηθεί αμέσως πριν μια εγγραφή, το πρώτο μετρούμενο σημείο μπορεί να έχει μειωμένη ακρίβεια, έτσι μπορεί να θέλουμε να περιμένουμε λιγάκι πριν την καταγραφή σημείου (ή να εγγράψουμε τα καλύτερα 3 διαδοχικά σημεία, κλπ.), αλλά αυτό δεν έχει ακόμα υλοποιηθεί. Αυτό το φίλτρο αποφεύγει διπλά σημεία να εγγραφούν όταν έχει συμβεί πολύ λίγη ενεργή κίνηση, καθιστώντας καλύτερη τη χωροταξική εμφάνιση των ιχνών που δεν επεξεργάζονται αργότερα. - Τιμή + Βαθμολόγηση Παράπλευρα αποτελέσματα: Περίοδοι σε ακινησία δεν καταγράφονται καθόλου ή μόνο με ένα σημείο καθεμιά. Μικρές (πραγματικός κόσμος) κινήσεις (π.χ. πλάγιες, για να σημειώσουν έξοδο στο ταξίδι σας) μπορεί να φιλτραριστούν. Το αρχείο σας περιέχει λιγότερες πληροφορίες για μετεπεξεργασία και έχει χειρότερα στατιστικά φιλτράροντας προφανώς περιττά σημεία κατά τον χρόνο εγγραφής, ενώ δυνητικά διατηρεί παράσιτα που προκαλούνται από κακή λήψη ή επιπτώσεις κυκλωμάτων GPS. Σύσταση: Ρύθμιση 5 μέτρων μπορεί να λειτουργήσει καλά για σας, εάν δεν χρειάζεστε να πιάσετε λεπτομέρειες πιο ακριβείς από αυτό και δεν θέλετε να πάρετε δεδομένα σε ακινησία. Ενδιάμεσος χρόνος From 1ca4acb986f7984d20f1cb29190d20f8ef3e94b3 Mon Sep 17 00:00:00 2001 From: Softmap Date: Mon, 8 Feb 2021 21:32:55 +0000 Subject: [PATCH 106/398] Translated using Weblate (Arabic) Currently translated at 99.9% (3660 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 48e89e070c..8a697b7f21 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3833,7 +3833,7 @@ أضف إحداثية مسار تسجيل الرحلة حفظ كمسار - تتبع المسار + اتبع المسار اختر مسار للمتابعة اختر ملف المسار للمتابعة أو قم باستيراده من الجهاز. حدد مسارا آخر @@ -3841,7 +3841,7 @@ نقطة المسار للتنقل بداية المسار أقرب نقطة - إرفاق الطرق + إرفاق بالطرق حذف عنوان إضافة عنوان أدخل العنوان @@ -3864,7 +3864,7 @@ فتح المسار المحفوظ محفوظ مسار مبسط - سيتم حفظ خط التوجيه فقط، وسيتم حذف نقاط الطريق. + سيتم حفظ خط الطريق فقط، وسيتم حذف نقاط المسار. اسم الملف الرجاء إضافة نقطتين على الأقل. إعادة @@ -3997,8 +3997,8 @@ \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n \n - وضع أساسي - وضع المستخدم + ملف تعريف التطبيق + حساب المستخدم عكس جميع النقاط حدد الوضع الذي سيتم استخدامه في بدء التطبيق. آخر استخدام From fd69f52d831e812a1e1f8eab4fdbd961bee61991 Mon Sep 17 00:00:00 2001 From: nasr pen Date: Mon, 8 Feb 2021 16:40:54 +0000 Subject: [PATCH 107/398] Translated using Weblate (Arabic) Currently translated at 99.9% (3660 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 8a697b7f21..d94cd5692f 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4030,7 +4030,7 @@ تحديد مجلد تحديد مجلد أو إضافة واحد جديد فارغ - التحليل حسب الفواصل الزمنية (الفاصل الزمني) + تحليل حسب الفاصل الزمني رفع إلى خريطة الشارع المفتوح تحرير المسار تسمية المسار From c5023e8a0288c10818324a3583c42e039cec7201 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 9 Feb 2021 00:29:53 +0000 Subject: [PATCH 108/398] Translated using Weblate (Ukrainian) Currently translated at 99.8% (3887 of 3891 strings) --- OsmAnd/res/values-uk/phrases.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 9464312798..78b128b95b 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -3881,4 +3881,10 @@ Тунель кажанів Міст кажанів Переправа диких тварин + Стан траси: зачинена + Стан траси: відчинена + Патрулюється: ні + Патрулюється: так + Назва траси + Cтрибки на лижах \ No newline at end of file From 94bda75c61c349611d1e0abecdf1304f5be4d805 Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Mon, 8 Feb 2021 23:16:50 +0000 Subject: [PATCH 109/398] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3891 of 3891 strings) --- OsmAnd/res/values-pt-rBR/phrases.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml index 458222fa16..6dd132682f 100644 --- a/OsmAnd/res/values-pt-rBR/phrases.xml +++ b/OsmAnd/res/values-pt-rBR/phrases.xml @@ -3881,4 +3881,14 @@ Túnel para morcego Ponte para morcego Travessia de vida selvagem + Posição de parada da biblioteca móvel + Registro de conferência: não + Registro de conferência: sim + Status da pista: fechada + Status da pista: aberta + Patrulhado: não + Patrulhado: sim + Satisfeito: sim + Nome da pista + Salto de esqui \ No newline at end of file From f35749d811269ddaea43f4bbd31ce013fdc3d467 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 9 Feb 2021 02:07:21 +0000 Subject: [PATCH 110/398] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3891 of 3891 strings) --- OsmAnd/res/values-zh-rTW/phrases.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml index 2677e6653a..a7fe870b96 100644 --- a/OsmAnd/res/values-zh-rTW/phrases.xml +++ b/OsmAnd/res/values-zh-rTW/phrases.xml @@ -3881,4 +3881,14 @@ 蝙蝠隧道 蝙蝠橋 野生動物穿越 + 行動圖書館停放位置 + 峰頂紀錄:否 + 峰頂紀錄:是 + 滑雪道狀態:關閉 + 滑雪道狀態:開放 + 巡邏:否 + 巡邏:是 + 林間空地:是 + 滑雪道名稱 + 跳台滑雪 \ No newline at end of file From 39e86bce2e9acf668eeb32ce0525bfe239158b0c Mon Sep 17 00:00:00 2001 From: Michalis Date: Mon, 8 Feb 2021 19:15:11 +0000 Subject: [PATCH 111/398] Translated using Weblate (Greek) Currently translated at 97.3% (3789 of 3891 strings) --- OsmAnd/res/values-el/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-el/phrases.xml b/OsmAnd/res/values-el/phrases.xml index 02aaee6bc2..cd34506f9b 100644 --- a/OsmAnd/res/values-el/phrases.xml +++ b/OsmAnd/res/values-el/phrases.xml @@ -1212,7 +1212,7 @@ Περιγραφή Τηλέφωνο Ιστότοπος - Ηλ. διεύθυνση + Ηλεκτρονικό ταχυδρομείο Τηλεομοιότυπο (φαξ) Facebook Twitter From eb3ecabf5319fb48aad24e4b207c1857421dda78 Mon Sep 17 00:00:00 2001 From: Michalis Date: Mon, 8 Feb 2021 23:15:17 +0000 Subject: [PATCH 112/398] Translated using Weblate (Greek) Currently translated at 19.5% (53 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/el/ --- OsmAnd-telegram/res/values-el/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/res/values-el/strings.xml b/OsmAnd-telegram/res/values-el/strings.xml index ce8aec1832..ff81d49e6c 100644 --- a/OsmAnd-telegram/res/values-el/strings.xml +++ b/OsmAnd-telegram/res/values-el/strings.xml @@ -36,7 +36,7 @@ Κλείσιμο Ανενεργό Εγκατάσταση - Διαμοιρασμός + Κοινοποίηση Προηγούμενο Συνέχεια Ακύρωση From 7315679c8fb9f25161a4f8c08732436a6fd27b77 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 9 Feb 2021 05:19:04 +0200 Subject: [PATCH 113/398] implementation of functionality; many fixes; --- .../layout/bottom_sheet_button_with_icon.xml | 9 +- .../bottom_sheet_item_button_with_icon.xml | 9 +- .../plus/activities/MapActivityActions.java | 27 +- .../ClearRecordedDataBottomSheetFragment.java | 12 +- .../monitoring/OsmandMonitoringPlugin.java | 34 ++- .../StopTrackRecordingBottomFragment.java | 12 +- .../TripRecordingActiveBottomSheet.java | 235 +++++++++++------- .../monitoring/TripRecordingBottomSheet.java | 8 +- .../plus/track/GpxBlockStatisticsBuilder.java | 3 +- .../plus/track/TrackAppearanceFragment.java | 3 + 10 files changed, 221 insertions(+), 131 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml index 79b89d1213..b184a3bea7 100644 --- a/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml +++ b/OsmAnd/res/layout/bottom_sheet_button_with_icon.xml @@ -19,6 +19,7 @@ android:paddingEnd="@dimen/content_padding_small" android:paddingRight="@dimen/content_padding_small" android:paddingBottom="@dimen/text_margin_small" + tools:background="@drawable/btn_background_inactive_dark" tools:ignore="UselessParent"> + tools:textColor="@color/active_color_primary_dark" /> @@ -62,7 +63,7 @@ android:layout_marginLeft="@dimen/context_menu_padding_margin_large" android:duplicateParentState="true" tools:srcCompat="@drawable/ic_action_appearance" - tools:tint="@color/icon_color_secondary_light" /> + tools:tint="@color/icon_color_active_dark" /> diff --git a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml index 3d2d1bbab1..2e1c2cd881 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml @@ -1,7 +1,7 @@ @@ -9,9 +9,9 @@ android:id="@+id/button_container" android:layout_width="match_parent" android:layout_height="wrap_content" + android:duplicateParentState="true" android:gravity="center_vertical" android:orientation="horizontal" - android:duplicateParentState="true" android:paddingStart="@dimen/content_padding_small" android:paddingLeft="@dimen/content_padding_small" android:paddingTop="@dimen/text_margin_small" @@ -33,6 +33,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:duplicateParentState="true" + android:letterSpacing="@dimen/description_letter_spacing" android:textSize="@dimen/default_desc_text_size" osmand:typeface="@string/font_roboto_medium" tools:text="Title" @@ -43,10 +44,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:duplicateParentState="true" + android:letterSpacing="@dimen/description_letter_spacing" android:textColor="@color/text_color_secondary_light" android:textSize="@dimen/default_desc_text_size" android:visibility="gone" - android:letterSpacing="@dimen/description_letter_spacing" osmand:typeface="@string/font_roboto_medium" tools:text="Description" tools:visibility="visible" /> @@ -57,9 +58,9 @@ android:id="@+id/icon" android:layout_width="@dimen/map_widget_icon" android:layout_height="@dimen/map_widget_icon" - android:duplicateParentState="true" android:layout_marginStart="@dimen/context_menu_padding_margin_large" android:layout_marginLeft="@dimen/context_menu_padding_margin_large" + android:duplicateParentState="true" tools:srcCompat="@drawable/ic_action_appearance" tools:tint="@color/icon_color_secondary_light" /> diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 625396e5e3..b216913466 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -360,10 +360,10 @@ public class MapActivityActions implements DialogProvider { } public void addActionsToAdapter(final double latitude, - final double longitude, - final ContextMenuAdapter adapter, - Object selectedObj, - boolean configureMenu) { + final double longitude, + final ContextMenuAdapter adapter, + Object selectedObj, + boolean configureMenu) { ItemBuilder itemBuilder = new ItemBuilder(); adapter.addItem(itemBuilder @@ -543,17 +543,17 @@ public class MapActivityActions implements DialogProvider { } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu) { + boolean useIntermediatePointsByDefault, boolean showMenu) { enterRoutePlanningModeGivenGpx(gpxFile, from, fromName, useIntermediatePointsByDefault, showMenu, MapRouteInfoMenu.DEFAULT_MENU_STATE); } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { + boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { enterRoutePlanningModeGivenGpx(gpxFile, null, from, fromName, useIntermediatePointsByDefault, showMenu, menuState); } public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, ApplicationMode appMode, LatLon from, PointDescription fromName, - boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { + boolean useIntermediatePointsByDefault, boolean showMenu, int menuState) { settings.USE_INTERMEDIATE_POINTS_NAVIGATION.set(useIntermediatePointsByDefault); OsmandApplication app = mapActivity.getMyApplication(); TargetPointsHelper targets = app.getTargetPointsHelper(); @@ -843,7 +843,8 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); - boolean isTripRecordingPluginOn = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null; + final OsmandMonitoringPlugin monitoringPlugin = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class); + boolean isTripRecordingPluginOn = monitoringPlugin != null; if (isTripRecordingPluginOn) { optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.map_widget_monitoring, mapActivity) .setId(DRAWER_TRIP_RECORDING_ID) @@ -853,7 +854,13 @@ public class MapActivityActions implements DialogProvider { public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { app.logEvent("trip_recording_open"); MapActivity.clearPrevActivityIntent(); - TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); + if (monitoringPlugin.isHasDataToSave() || monitoringPlugin.isWasTrackMonitored()) { + TripRecordingActiveBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), + monitoringPlugin.getCurrentTrack(), monitoringPlugin.isWasTrackMonitored(), + monitoringPlugin.isHasDataToSave(), monitoringPlugin.isSearchingGPS()); + } else { + TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); + } return true; } }).createItem()); @@ -1107,7 +1114,7 @@ public class MapActivityActions implements DialogProvider { } private String getProfileDescription(OsmandApplication app, ApplicationMode mode, - Map profilesObjects, String defaultDescription) { + Map profilesObjects, String defaultDescription) { String description = defaultDescription; String routingProfileKey = mode.getRoutingProfile(); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java index 971bfd01e0..0bdced7bc5 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java @@ -102,26 +102,18 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF @Override public void onResume() { super.onResume(); - // Replace later with tTripRecordingActiveBottomSheet.hide() Fragment target = getTargetFragment(); if (target instanceof TripRecordingActiveBottomSheet) { - Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); - if (dialog != null) { - dialog.hide(); - } + ((TripRecordingActiveBottomSheet) target).hide(); } } @Override public void onPause() { super.onPause(); - // Replace later with tTripRecordingActiveBottomSheet.show() Fragment target = getTargetFragment(); if (target instanceof TripRecordingActiveBottomSheet) { - Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); - if (dialog != null) { - dialog.show(); - } + ((TripRecordingActiveBottomSheet) target).show(); } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 65538733b0..eaa54a948a 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -28,6 +28,8 @@ import com.google.android.material.slider.Slider; import net.osmand.AndroidUtils; import net.osmand.Location; import net.osmand.ValueHolder; +import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndLocationProvider; @@ -318,8 +320,34 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } + public SelectedGpxFile getCurrentTrack() { + return app.getSavingTrackHelper().getCurrentTrack(); + } + + public boolean isWasTrackMonitored() { + return settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + } + + public boolean isHasDataToSave() { + return app.getSavingTrackHelper().hasDataToSave(); + } + + public boolean isSearchingGPS() { + OsmAndLocationProvider locationProvider = app.getLocationProvider(); + Location lastKnownLocation = locationProvider.getLastKnownLocation(); + return lastKnownLocation == null; + } + public void controlDialog(final Activity activity, final boolean showTrackSelection) { - final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + if (isHasDataToSave() || isWasTrackMonitored()) { + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager(), + getCurrentTrack(), isWasTrackMonitored(), isHasDataToSave(), isSearchingGPS()); + } else { + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); + } + /*final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); final boolean nightMode; if (activity instanceof MapActivity) { nightMode = app.getDaynightHelper().isNightModeForMapControls(); @@ -328,8 +356,6 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } AlertDialog.Builder bld = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, nightMode)); final TIntArrayList items = new TIntArrayList(); - FragmentActivity fragmentActivity = (FragmentActivity) activity; - TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); if (wasTrackMonitored) { items.add(R.string.gpx_monitoring_stop); items.add(R.string.gpx_start_new_segment); @@ -419,7 +445,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } }); // bld.show(); - } + }*/ } public void saveCurrentTrack() { diff --git a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java index b7bf829457..5172bfc1bf 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java @@ -128,26 +128,18 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm @Override public void onResume() { super.onResume(); - // Replace later with tTripRecordingActiveBottomSheet.hide() Fragment target = getTargetFragment(); if (target instanceof TripRecordingActiveBottomSheet) { - Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); - if (dialog != null) { - dialog.hide(); - } + ((TripRecordingActiveBottomSheet) target).hide(); } } @Override public void onPause() { super.onPause(); - // Replace later with tTripRecordingActiveBottomSheet.show() Fragment target = getTargetFragment(); if (target instanceof TripRecordingActiveBottomSheet) { - Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); - if (dialog != null) { - dialog.show(); - } + ((TripRecordingActiveBottomSheet) target).show(); } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 23bf24e287..775bbac87c 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -29,7 +29,6 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.RecyclerView; @@ -37,8 +36,9 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.snackbar.Snackbar; import net.osmand.AndroidUtils; -import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.Location; +import net.osmand.PlatformUtil; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; @@ -46,6 +46,7 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SavingTrackHelper; +import net.osmand.plus.activities.SavingTrackHelper.SaveGpxResult; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.AndroidUiHelper; @@ -53,15 +54,18 @@ import net.osmand.plus.helpers.FontCache; import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.track.GpxBlockStatisticsBuilder; -import net.osmand.plus.track.SaveGpxAsyncTask; +import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.track.TrackAppearanceFragment; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; +import org.apache.commons.logging.Log; + import java.lang.ref.WeakReference; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; import java.util.TimeZone; import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; @@ -69,57 +73,28 @@ import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment { public static final String TAG = TripRecordingActiveBottomSheet.class.getSimpleName(); + private static final Log log = PlatformUtil.getLog(TripRecordingActiveBottomSheet.class); private OsmandApplication app; private OsmandSettings settings; + private SavingTrackHelper helper; private SelectedGpxFile selectedGpxFile; - private GpxBlockStatisticsBuilder blockStatisticsBuilder; private boolean wasTrackMonitored = false; private boolean hasDataToSave = false; private boolean searchingGPS = false; private View statusContainer; + private View buttonSave; + private GpxBlockStatisticsBuilder blockStatisticsBuilder; private final Handler handler = new Handler(); private Runnable updatingGPS; + private Runnable updatingTimeTrackSaved; + private SaveGpxListener saveGpxListener; - SaveGpxAsyncTask.SaveGpxListener saveGpxListener = new SaveGpxAsyncTask.SaveGpxListener() { - - @Override - public void gpxSavingStarted() { - - } - - @Override - public void gpxSavingFinished(Exception errorMessage) { - String gpxFileName = Algorithms.getFileWithoutDirs(app.getSavingTrackHelper().getCurrentTrack().getGpxFile().path); - final MapActivity mapActivity = getMapActivity(); - final Context context = getContext(); - SavingTrackHelper helper = app.getSavingTrackHelper(); - final SavingTrackHelper.SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); - if (mapActivity != null && context != null) { - Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), - getString(R.string.shared_string_file_is_saved, gpxFileName), - Snackbar.LENGTH_LONG) - .setAction(R.string.shared_string_undo, new View.OnClickListener() { - @Override - public void onClick(View view) { - final WeakReference mapActivityRef = new WeakReference<>(mapActivity); - final FragmentActivity fragmentActivity = mapActivityRef.get(); - SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); - } - }); - View view = snackbar.getView(); - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); - params.gravity = Gravity.TOP; - AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); - view.setLayoutParams(params); - UiUtilities.setupSnackbar(snackbar, nightMode); - snackbar.show(); - } - } - - }; + private GPXFile getGPXFile() { + return selectedGpxFile.getGpxFile(); + } public void setSelectedGpxFile(SelectedGpxFile selectedGpxFile) { this.selectedGpxFile = selectedGpxFile; @@ -153,57 +128,30 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void createMenuItems(Bundle savedInstanceState) { app = requiredMyApplication(); settings = app.getSettings(); + helper = app.getSavingTrackHelper(); LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); final FragmentManager fragmentManager = getFragmentManager(); - final Fragment targetFragment = getTargetFragment(); View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); items.add(new BottomSheetItemWithDescription.Builder() .setCustomView(itemView) .create()); - long timeTrackSaved = app.getSavingTrackHelper().getLastTimeUpdated(); - SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z"); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - Date resultDate = new Date(timeTrackSaved); - String sdfFormatted = sdf.format(resultDate); - CharSequence formattedTimeTrackSaved = null; - try { - long time = sdf.parse(sdfFormatted).getTime(); - long now = System.currentTimeMillis(); - formattedTimeTrackSaved = - DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); - } catch (ParseException e) { - e.printStackTrace(); - } - View buttonClear = itemView.findViewById(R.id.button_clear); View buttonStart = itemView.findViewById(R.id.button_start); - View buttonSave = itemView.findViewById(R.id.button_save); + buttonSave = itemView.findViewById(R.id.button_save); final View buttonPause = itemView.findViewById(R.id.button_pause); View buttonStop = itemView.findViewById(R.id.button_stop); createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave, null); createItem(buttonStart, ItemType.START_SEGMENT, wasTrackMonitored, null); - createItem(buttonSave, ItemType.SAVE, hasDataToSave, (String) formattedTimeTrackSaved); +// createItem(buttonSave, ItemType.SAVE, hasDataToSave, getTimeTrackSaved()); createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); createItem(buttonStop, ItemType.STOP, true, null); statusContainer = itemView.findViewById(R.id.status_container); updateStatus(); - // todo example, need to check - buttonPause.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - boolean wasTrackMonitored = !settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); - createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); - TripRecordingActiveBottomSheet.this.wasTrackMonitored = wasTrackMonitored; - settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); - updateStatus(); - } - }); - RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics); blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, null); blockStatisticsBuilder.setBlocksView(statBlocks); @@ -265,11 +213,49 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } }); + buttonClear.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fragmentManager != null && hasDataToSave) { + ClearRecordedDataBottomSheetFragment.showInstance(fragmentManager, TripRecordingActiveBottomSheet.this); + } + } + }); + + buttonStart.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (wasTrackMonitored) { + + } + } + }); + + setSaveListener(); buttonSave.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final GPXUtilities.GPXFile gpxFile = app.getSavingTrackHelper().getCurrentTrack().getGpxFile(); - new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + if (hasDataToSave) { + final GPXFile gpxFile = getGPXFile(); + new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + }); + + // todo example, need to check + buttonPause.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean wasTrackMonitored = !settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); + if (!wasTrackMonitored) { + blockStatisticsBuilder.stopUpdatingStatBlocks(); + } else { + blockStatisticsBuilder.runUpdatingStatBlocks(); + } + TripRecordingActiveBottomSheet.this.wasTrackMonitored = wasTrackMonitored; + settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); + updateStatus(); } }); @@ -277,16 +263,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void onClick(View v) { if (fragmentManager != null) { - StopTrackRecordingBottomFragment.showInstance(fragmentManager, targetFragment); - } - } - }); - - buttonClear.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (fragmentManager != null) { - ClearRecordedDataBottomSheetFragment.showInstance(fragmentManager, targetFragment); + StopTrackRecordingBottomFragment.showInstance(fragmentManager, TripRecordingActiveBottomSheet.this); } } }); @@ -314,7 +291,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen type.setTintedIcon(icon, app, enabled, false, nightMode); } - TextView title = view.findViewById(R.id.title); + TextView title = view.findViewById(R.id.button_text); if (title != null) { title.setText(type.getTitleId()); type.setTextColor(title, app, enabled, false, nightMode); @@ -333,11 +310,29 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } + private String getTimeTrackSaved() { + long timeTrackSaved = helper.getLastTimeUpdated(); + SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z", Locale.getDefault()); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + Date resultDate = new Date(timeTrackSaved); + String sdfFormatted = sdf.format(resultDate); + CharSequence formattedTimeTrackSaved = null; + try { + long time = sdf.parse(sdfFormatted).getTime(); + long now = System.currentTimeMillis(); + formattedTimeTrackSaved = DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); + } catch (ParseException e) { + log.error(e); + } + return String.valueOf(formattedTimeTrackSaved); + } + @Override public void onResume() { super.onResume(); blockStatisticsBuilder.runUpdatingStatBlocks(); runUpdatingGPS(); + runUpdatingTimeTrackSaved(); } @Override @@ -345,6 +340,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen super.onPause(); blockStatisticsBuilder.stopUpdatingStatBlocks(); stopUpdatingGPS(); + stopUpdatingTimeTrackSaved(); } public void stopUpdatingGPS() { @@ -366,6 +362,61 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen handler.post(updatingGPS); } + public void stopUpdatingTimeTrackSaved() { + handler.removeCallbacks(updatingTimeTrackSaved); + } + + public void runUpdatingTimeTrackSaved() { + updatingTimeTrackSaved = new Runnable() { + @Override + public void run() { + String time = getTimeTrackSaved(); + createItem(buttonSave, ItemType.SAVE, hasDataToSave, !Algorithms.isEmpty(time) ? time : null); + handler.postDelayed(this, 60000); + } + }; + handler.post(updatingTimeTrackSaved); + } + + private void setSaveListener() { + if (saveGpxListener == null) { + saveGpxListener = new SaveGpxListener() { + + @Override + public void gpxSavingStarted() { + } + + @Override + public void gpxSavingFinished(Exception errorMessage) { + String gpxFileName = Algorithms.getFileWithoutDirs(getGPXFile().path); + final MapActivity mapActivity = getMapActivity(); + final Context context = getContext(); + final SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); + if (mapActivity != null && context != null) { + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), + getString(R.string.shared_string_file_is_saved, gpxFileName), + Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_undo, new View.OnClickListener() { + @Override + public void onClick(View view) { + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + final FragmentActivity fragmentActivity = mapActivityRef.get(); + SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); + } + }); + View view = snackbar.getView(); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); + params.gravity = Gravity.TOP; + AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); + view.setLayoutParams(params); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + } + } + }; + } + } + @Nullable public MapActivity getMapActivity() { Activity activity = getActivity(); @@ -375,6 +426,13 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen return null; } + public void show() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.show(); + } + } + public void hide() { Dialog dialog = getDialog(); if (dialog != null) { @@ -443,7 +501,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen if (tv != null) { tv.setTextColor(ContextCompat.getColor(context, enabled ? pressed ? getPressedColorId(nightMode) - : equals(ItemType.CLEAR_DATA) ? R.color.color_osm_edit_delete + : this == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete : getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); } } @@ -452,10 +510,15 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen if (iv != null) { int iconColor = ContextCompat.getColor(context, enabled ? pressed ? getPressedColorId(nightMode) - : equals(ItemType.CLEAR_DATA) ? R.color.color_osm_edit_delete + : this == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete : getActiveIconColorId(nightMode) : getSecondaryIconColorId(nightMode)); Drawable icon = UiUtilities.createTintedDrawable(context, iconId, iconColor); iv.setImageDrawable(icon); + if (this == ItemType.STOP) { + int stopSize = iv.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(stopSize, stopSize); + iv.setLayoutParams(params); + } } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 178e662176..6653b6f5c3 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -28,6 +28,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.DialogButtonType; @@ -246,12 +247,12 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { } @Override - protected int getRightButtonHeight(){ + protected int getRightButtonHeight() { return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); } @Override - protected int getDismissButtonHeight(){ + protected int getDismissButtonHeight() { return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); } @@ -280,6 +281,9 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { app.getSavingTrackHelper().startNewSegment(); settings.SAVE_GLOBAL_TRACK_TO_GPX.set(true); app.startNavigationService(NavigationService.USED_BY_GPX); + OsmandMonitoringPlugin plugin = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class); + TripRecordingActiveBottomSheet.showInstance(getMapActivity().getSupportFragmentManager(), + plugin.getCurrentTrack(), plugin.isWasTrackMonitored(), plugin.isHasDataToSave(), plugin.isSearchingGPS()); dismiss(); } diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index a7b23e18ec..3421a46a10 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -89,6 +89,7 @@ public class GpxBlockStatisticsBuilder { if (bsAdapter != null) { initItems(); bsAdapter.setItems(items); + AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items)); } int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); handler.postDelayed(this, Math.max(1000, interval)); @@ -272,7 +273,7 @@ public class GpxBlockStatisticsBuilder { public void setItems(List statBlocks) { this.statBlocks.clear(); this.statBlocks.addAll(statBlocks); - notifyItemRangeChanged(0, getItemCount()); + notifyDataSetChanged(); } } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 522103ac02..0ad5475337 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -44,6 +44,7 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.monitoring.TripRecordingActiveBottomSheet; import net.osmand.plus.monitoring.TripRecordingBottomSheet; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; @@ -383,6 +384,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement Fragment target = getTargetFragment(); if (target instanceof TripRecordingBottomSheet) { ((TripRecordingBottomSheet) target).show(); + } else if (target instanceof TripRecordingActiveBottomSheet) { + ((TripRecordingActiveBottomSheet) target).show(); } } From ddce9bf9555cb6377385f41fe18635b56f728fc6 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 9 Feb 2021 10:05:01 +0200 Subject: [PATCH 114/398] Rename snackbar button --- .../osmand/plus/monitoring/TripRecordingActiveBottomSheet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 775bbac87c..bcc7fa7cf0 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -396,7 +396,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), getString(R.string.shared_string_file_is_saved, gpxFileName), Snackbar.LENGTH_LONG) - .setAction(R.string.shared_string_undo, new View.OnClickListener() { + .setAction(R.string.shared_string_rename, new View.OnClickListener() { @Override public void onClick(View view) { final WeakReference mapActivityRef = new WeakReference<>(mapActivity); From 3de4d7048b59f8bcb369c4316afe8ac8d85f182a Mon Sep 17 00:00:00 2001 From: nasr pen Date: Tue, 9 Feb 2021 10:49:21 +0000 Subject: [PATCH 115/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index d94cd5692f..0b4fc0c435 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3800,7 +3800,7 @@ التعديل الأخير استيراد المسار فتح مسار موجود - إنشاء مسار جديد + إنشاء طريق جديد حدد المسار للفتح. تم الكتابة فوق المسار @@ -3836,7 +3836,7 @@ اتبع المسار اختر مسار للمتابعة اختر ملف المسار للمتابعة أو قم باستيراده من الجهاز. - حدد مسارا آخر + حدد مساراً آخر انتقل من موقعي إلى المسار نقطة المسار للتنقل بداية المسار @@ -3997,7 +3997,7 @@ \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n \n - ملف تعريف التطبيق + وضع التطبيق حساب المستخدم عكس جميع النقاط حدد الوضع الذي سيتم استخدامه في بدء التطبيق. From c806622c4fe18768a1cc89530ce2ea5dc6bda21c Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Tue, 9 Feb 2021 07:39:00 +0000 Subject: [PATCH 116/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 0b4fc0c435..06d4d70284 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3355,8 +3355,8 @@ لوحة المفاتيح وندرلينك ببغاء - "المسار: المسافة%1$s، الوقت %2$s. -\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب" + المسار: المسافة%1$s، الوقت %2$s. +\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب الأوكيتانية ثم %1$s تطبيق فقط على \"%1$s\" From e226eab08b56250506b7622f507430a15ebace92 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 9 Feb 2021 15:36:37 +0200 Subject: [PATCH 117/398] First segment recalculation --- .../plus/activities/MapActivityActions.java | 5 ++ .../FollowTrackFragment.java | 4 +- .../osmand/plus/routing/RouteProvider.java | 74 ++++++++++++++----- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 258ed7be38..19d9d93ba3 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -515,6 +515,10 @@ public class MapActivityActions implements DialogProvider { } public void setGPXRouteParams(GPXFile result) { + setGPXRouteParams(result, -1); + } + + public void setGPXRouteParams(GPXFile result, int selectedSegment) { if (result == null) { mapActivity.getRoutingHelper().setGpxParams(null); settings.FOLLOW_THE_GPX_ROUTE.set(null); @@ -522,6 +526,7 @@ public class MapActivityActions implements DialogProvider { GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, settings); params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()); params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get()); + params.setSelectedSegment(selectedSegment); List ps = params.getPoints(settings.getContext()); mapActivity.getRoutingHelper().setGpxParams(params); settings.FOLLOW_THE_GPX_ROUTE.set(result.path); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index b4bd04037e..f9cab5f518 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -502,6 +502,8 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca updateSelectionMode(false); } else { TrackSelectSegmentBottomSheet.showInstance(fragmentManager, selectedGpxFile); + selectTrackToFollow(selectedGpxFile.getGpxFile()); + updateSelectionMode(true); } } else { CallbackWithObject callback = new CallbackWithObject() { @@ -530,7 +532,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); } } - mapActivity.getMapActions().setGPXRouteParams(gpxFile); + mapActivity.getMapActions().setGPXRouteParams(gpxFile, 1); app.getTargetPointsHelper().updateRouteAndRefresh(true); app.getRoutingHelper().onSettingsChanged(true); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 96bb1b19dc..3b4515136b 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -20,15 +20,15 @@ import net.osmand.data.LatLon; import net.osmand.data.LocationPoint; import net.osmand.data.WptLocationPoint; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.onlinerouting.OnlineRoutingHelper; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; +import net.osmand.plus.onlinerouting.OnlineRoutingHelper; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameterType; @@ -161,6 +161,7 @@ public class RouteProvider { private boolean leftSide; private boolean passWholeRoute; private boolean calculateOsmAndRouteParts; + private int selectedSegment = -1; public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) { leftSide = settings.DRIVING_REGION.get().leftHandDriving; @@ -191,6 +192,14 @@ public class RouteProvider { this.calculateOsmAndRoute = calculateOsmAndRoute; } + public int getSelectedSegment() { + return selectedSegment; + } + + public void setSelectedSegment(int selectedSegment) { + this.selectedSegment = selectedSegment; + } + public void setPassWholeRoute(boolean passWholeRoute) { this.passWholeRoute = passWholeRoute; } @@ -235,6 +244,7 @@ public class RouteProvider { boolean calculateOsmAndRouteParts; boolean useIntermediatePointsRTE; private List wpt; + int selectedSegment = -1; boolean addMissingTurns = true; @@ -271,6 +281,7 @@ public class RouteProvider { passWholeRoute = builder.passWholeRoute; calculateOsmAndRouteParts = builder.calculateOsmAndRouteParts; useIntermediatePointsRTE = builder.isUseIntermediatePointsRTE(); + selectedSegment = builder.getSelectedSegment(); builder.calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute; if (!file.isPointsEmpty()) { wpt = new ArrayList(file.getPoints().size()); @@ -279,7 +290,7 @@ public class RouteProvider { } } if (OSMAND_ROUTER_V2.equals(file.author)) { - route = parseOsmAndGPXRoute(points, file); + route = parseOsmAndGPXRoute(points, file, selectedSegment); routePoints = file.getRoutePoints(); if (reverse) { Collections.reverse(points); @@ -287,7 +298,7 @@ public class RouteProvider { } addMissingTurns = route != null && route.isEmpty(); } else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) { - directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10); + directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment); if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) { // For files generated by OSMAND_ROUTER use directions contained unaltered addMissingTurns = false; @@ -303,7 +314,14 @@ public class RouteProvider { if (!useIntermediatePointsRTE) { for (Track tr : file.tracks) { if (!tr.generalTrack) { - for (TrkSegment tkSeg : tr.segments) { + if (selectedSegment == -1) { + for (TrkSegment tkSeg : tr.segments) { + for (WptPt pt : tkSeg.points) { + points.add(createLocation(pt)); + } + } + } else if (tr.segments.size() > selectedSegment) { + TrkSegment tkSeg = tr.segments.get(selectedSegment); for (WptPt pt : tkSeg.points) { points.add(createLocation(pt)); } @@ -998,20 +1016,33 @@ public class RouteProvider { return new RouteCalculationResult("Empty result"); } - private static List parseOsmAndGPXRoute(List points, GPXFile gpxFile) { + private static List parseOsmAndGPXRoute(List points, GPXFile gpxFile, int selectedSegment) { for (Track tr : gpxFile.tracks) { - for (TrkSegment ts : tr.segments) { - for (WptPt p : ts.points) { - points.add(createLocation(p)); + if (selectedSegment == -1) { + for (TrkSegment ts : tr.segments) { + for (WptPt p : ts.points) { + points.add(createLocation(p)); + } + } + } else if (tr.segments.size() > selectedSegment) { + TrkSegment ts = tr.segments.get(selectedSegment); + for (WptPt pt : ts.points) { + points.add(createLocation(pt)); } } } - RouteImporter routeImporter = new RouteImporter(gpxFile); - return routeImporter.importRoute(); + List segments = gpxFile.getNonEmptyTrkSegments(true); + if (selectedSegment>=0&&segments.size() > selectedSegment) { + RouteImporter routeImporter = new RouteImporter(segments.get(selectedSegment)); + return routeImporter.importRoute(); + } else { + RouteImporter routeImporter = new RouteImporter(gpxFile); + return routeImporter.importRoute(); + } } private static List parseOsmAndGPXRoute(List points, GPXFile gpxFile, boolean osmandRouter, - boolean leftSide, float defSpeed) { + boolean leftSide, float defSpeed, int selectedSegment) { List directions = null; if (!osmandRouter) { for (WptPt pt : gpxFile.getPoints()) { @@ -1019,9 +1050,16 @@ public class RouteProvider { } } else { for (Track tr : gpxFile.tracks) { - for (TrkSegment ts : tr.segments) { - for (WptPt p : ts.points) { - points.add(createLocation(p)); + if (selectedSegment == -1) { + for (TrkSegment ts : tr.segments) { + for (WptPt p : ts.points) { + points.add(createLocation(p)); + } + } + } else if (tr.segments.size() > selectedSegment) { + TrkSegment ts = tr.segments.get(selectedSegment); + for (WptPt pt : ts.points) { + points.add(createLocation(pt)); } } } @@ -1307,7 +1345,7 @@ public class RouteProvider { GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream); - dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed()); + dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed(), -1); if (dir != null) { addMissingTurns = false; From 3d2a2044b4e68c9e2c08c033a55194f010a3b261 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 9 Feb 2021 15:39:19 +0200 Subject: [PATCH 118/398] Add ALocation constructor --- .../src/net/osmand/aidlapi/map/ALocation.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java b/OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java index 03741138d5..0809944ba9 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/map/ALocation.java @@ -25,6 +25,24 @@ public class ALocation extends AidlParams { private ALocation() { } + public ALocation(double latitude, double longitude, long time, boolean hasAltitude, double altitude, + boolean hasSpeed, float speed, boolean hasBearing, float bearing, + boolean hasAccuracy, float accuracy, boolean hasVerticalAccuracy, float verticalAccuracy) { + this.latitude = latitude; + this.longitude = longitude; + this.time = time; + this.hasAltitude = hasAltitude; + this.altitude = altitude; + this.hasSpeed = hasSpeed; + this.speed = speed; + this.hasBearing = hasBearing; + this.bearing = bearing; + this.hasAccuracy = hasAccuracy; + this.accuracy = accuracy; + this.hasVerticalAccuracy = hasVerticalAccuracy; + this.verticalAccuracy = verticalAccuracy; + } + public ALocation(Parcel in) { readFromParcel(in); } From 61a1d69c58c3e2bdbfb217b4f23d43bdc18f0602 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 9 Feb 2021 16:18:20 +0200 Subject: [PATCH 119/398] Fix empty activity type --- .../net/osmand/osm/RouteActivityType.java | 2 +- .../explore/SavedArticlesRvAdapter.java | 25 +++++++++++++++---- .../explore/travelcards/TravelGpxCard.java | 16 ++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java index 65fa50bf68..7c54388f64 100644 --- a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -43,7 +43,7 @@ public class RouteActivityType { return icon; } - public static RouteActivityType getTypeFromName(String name) { + public static RouteActivityType getOrCreateTypeFromName(String name) { for (RouteActivityType rat : values) { if (rat.name.equalsIgnoreCase(name)) { return rat; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java index 002b5587d4..9bccece08d 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/SavedArticlesRvAdapter.java @@ -18,12 +18,13 @@ import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; import com.squareup.picasso.RequestCreator; +import net.osmand.AndroidUtils; import net.osmand.PicassoUtils; +import net.osmand.osm.RouteActivityType; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; -import net.osmand.plus.profiles.ProfileIcons; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.tools.CropCircleTransformation; import net.osmand.plus.wikipedia.WikiArticleHelper; @@ -37,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import static net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.*; +import static net.osmand.util.Algorithms.capitalizeFirstLetterAndLowercase; public class SavedArticlesRvAdapter extends RecyclerView.Adapter { @@ -140,10 +142,12 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter Date: Tue, 9 Feb 2021 18:14:31 +0200 Subject: [PATCH 120/398] fix changing track info after enabling the "Join segments" option; fix display track info with enabled/disabled "Join segments" option in chart; --- .../other/TrackDetailsMenu.java | 21 ++- .../plus/track/GpxBlockStatisticsBuilder.java | 121 +++++++++--------- .../net/osmand/plus/track/OverviewCard.java | 5 +- .../osmand/plus/track/TrackMenuFragment.java | 7 +- 4 files changed, 83 insertions(+), 71 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java index edec4eeb2f..e0efd25a7e 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java @@ -36,6 +36,7 @@ import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -66,6 +67,8 @@ public class TrackDetailsMenu { @Nullable private GpxDisplayItem gpxItem; @Nullable + private SelectedGpxFile selectedGpxFile; + @Nullable private TrackDetailsBarController toolbarController; @Nullable private TrkSegment segment; @@ -101,6 +104,15 @@ public class TrackDetailsMenu { this.gpxItem = gpxItem; } + @Nullable + public SelectedGpxFile getSelectedGpxFile() { + return selectedGpxFile; + } + + public void setSelectedGpxFile(@NonNull SelectedGpxFile selectedGpxFile) { + this.selectedGpxFile = selectedGpxFile; + } + public boolean isVisible() { return visible; } @@ -539,7 +551,7 @@ public class TrackDetailsMenu { } } - public boolean shouldShowXAxisPoints () { + public boolean shouldShowXAxisPoints() { return true; } @@ -707,18 +719,19 @@ public class TrackDetailsMenu { if (gpxItem.chartTypes != null && gpxItem.chartTypes.length > 0) { for (int i = 0; i < gpxItem.chartTypes.length; i++) { OrderedLineDataSet dataSet = null; + boolean withoutGaps = selectedGpxFile != null && (!selectedGpxFile.isJoinSegments() && gpxItem.isGeneralTrack()); switch (gpxItem.chartTypes[i]) { case ALTITUDE: dataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis, - gpxItem.chartAxisType, false, true, false); + gpxItem.chartAxisType, false, true, withoutGaps); break; case SPEED: dataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis, - gpxItem.chartAxisType, gpxItem.chartTypes.length > 1, true, false); + gpxItem.chartAxisType, gpxItem.chartTypes.length > 1, true, withoutGaps); break; case SLOPE: dataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart, analysis, - gpxItem.chartAxisType, null, gpxItem.chartTypes.length > 1, true, false); + gpxItem.chartAxisType, null, gpxItem.chartTypes.length > 1, true, withoutGaps); break; } if (dataSet != null) { diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 59cd460bcc..b6f07ecf50 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -17,16 +17,16 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; -import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; -import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.myplaces.SegmentActionsListener; import net.osmand.plus.widgets.TextViewEx; @@ -40,51 +40,60 @@ public class GpxBlockStatisticsBuilder { private final OsmandApplication app; private RecyclerView blocksView; private final SelectedGpxFile selectedGpxFile; - private final TrackDisplayHelper displayHelper; - private final GpxDisplayItemType[] filterTypes = {GpxDisplayItemType.TRACK_SEGMENT}; - public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile, TrackDisplayHelper displayHelper) { + public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile) { this.app = app; this.selectedGpxFile = selectedGpxFile; - this.displayHelper = displayHelper; } public void setBlocksView(RecyclerView blocksView) { this.blocksView = blocksView; } - private GPXTrackAnalysis getAnalysis() { - return selectedGpxFile.getTrackAnalysis(app); + private GpxDisplayItem getDisplayItem(GPXFile gpxFile) { + return GpxUiHelper.makeGpxDisplayItem(app, gpxFile); + } + + private GPXFile getGPXFile() { + return selectedGpxFile.getGpxFile(); } public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { - GPXTrackAnalysis analysis = getAnalysis(); - float totalDistance = analysis.totalDistance; - float timeSpan = analysis.timeSpan; - String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); - String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); - String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); - String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); List items = new ArrayList<>(); + GPXFile gpxFile = getGPXFile(); + GpxDisplayItem gpxDisplayItem = null; + GPXTrackAnalysis analysis = null; + if (gpxFile.tracks.size() > 0) { + gpxDisplayItem = getDisplayItem(gpxFile); + analysis = gpxDisplayItem.analysis; + } + if (gpxDisplayItem != null && analysis != null) { + boolean withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack(); + float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; + float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; + String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); + String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); + String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); - prepareData(analysis, items, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), - R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE); - prepareData(analysis, items, app.getString(R.string.altitude_ascent), asc, - R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE); - prepareData(analysis, items, app.getString(R.string.altitude_descent), desc, - R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE); - prepareData(analysis, items, app.getString(R.string.average_speed), avg, - R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); - prepareData(analysis, items, app.getString(R.string.max_speed), max, - R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); - prepareData(analysis, items, app.getString(R.string.shared_string_time_span), - Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()), - R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME); - - if (Algorithms.isEmpty(items)) { - AndroidUiHelper.updateVisibility(blocksView, false); - } else { - final BlockStatisticsAdapter sbAdapter = new BlockStatisticsAdapter(items, actionsListener, activeColor, nightMode); + prepareData(analysis, items, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), + R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE); + prepareData(analysis, items, app.getString(R.string.altitude_ascent), asc, + R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE); + prepareData(analysis, items, app.getString(R.string.altitude_descent), desc, + R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE); + prepareData(analysis, items, app.getString(R.string.average_speed), avg, + R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); + prepareData(analysis, items, app.getString(R.string.max_speed), max, + R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); + prepareData(analysis, items, app.getString(R.string.shared_string_time_span), + Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()), + R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME); + } + boolean isNotEmpty = !Algorithms.isEmpty(items); + AndroidUiHelper.updateVisibility(blocksView, isNotEmpty); + if (isNotEmpty && gpxDisplayItem != null) { + final BlockStatisticsAdapter sbAdapter = new BlockStatisticsAdapter(items, gpxDisplayItem, actionsListener, activeColor, nightMode); blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); blocksView.setAdapter(sbAdapter); } @@ -134,7 +143,6 @@ public class GpxBlockStatisticsBuilder { } public class StatBlock { - private final String title; private final String value; private final int imageResId; @@ -164,14 +172,17 @@ public class GpxBlockStatisticsBuilder { private class BlockStatisticsAdapter extends RecyclerView.Adapter { + private final List statBlocks; + private final GpxDisplayItem displayItem; + private final SegmentActionsListener actionsListener; @ColorInt private final int activeColor; - private final List statBlocks; private final boolean nightMode; - private final SegmentActionsListener actionsListener; - public BlockStatisticsAdapter(List statBlocks, SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { + public BlockStatisticsAdapter(List statBlocks, GpxDisplayItem displayItem, + SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { this.statBlocks = statBlocks; + this.displayItem = displayItem; this.actionsListener = actionsListener; this.activeColor = activeColor; this.nightMode = nightMode; @@ -200,32 +211,20 @@ public class GpxBlockStatisticsBuilder { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - List groups = displayHelper.getDisplayGroups(filterTypes); - GpxDisplayGroup group = null; - for (GpxDisplayGroup g : groups) { - if (g.isGeneralTrack()) { - group = g; - } - } - if (group == null && !groups.isEmpty()) { - group = groups.get(0); - } - if (group != null) { - GpxDisplayItem displayItem = group.getModifiableList().get(0); - if (displayItem != null && displayItem.analysis != null) { - ArrayList list = new ArrayList<>(); - if (displayItem.analysis.hasElevationData || displayItem.analysis.isSpeedSpecified() || displayItem.analysis.hasSpeedData) { - if (item.firstType != null) { - list.add(item.firstType); - } - if (item.secondType != null) { - list.add(item.secondType); - } + GPXTrackAnalysis analysis = displayItem.analysis; + if (displayItem != null && analysis != null) { + ArrayList list = new ArrayList<>(); + if (analysis.hasElevationData || analysis.isSpeedSpecified() || analysis.hasSpeedData) { + if (item.firstType != null) { + list.add(item.firstType); + } + if (item.secondType != null) { + list.add(item.secondType); } - displayItem.chartTypes = list.size() > 0 ? list.toArray(new GPXDataSetType[0]) : null; - displayItem.locationOnMap = displayItem.locationStart; - actionsListener.openAnalyzeOnMap(displayItem); } + displayItem.chartTypes = list.size() > 0 ? list.toArray(new GPXDataSetType[0]) : null; + displayItem.locationOnMap = displayItem.locationStart; + actionsListener.openAnalyzeOnMap(displayItem); } } }); diff --git a/OsmAnd/src/net/osmand/plus/track/OverviewCard.java b/OsmAnd/src/net/osmand/plus/track/OverviewCard.java index d0a396499d..bb56b43f89 100644 --- a/OsmAnd/src/net/osmand/plus/track/OverviewCard.java +++ b/OsmAnd/src/net/osmand/plus/track/OverviewCard.java @@ -43,12 +43,11 @@ public class OverviewCard extends BaseCard { private final SelectedGpxFile selectedGpxFile; private final GpxBlockStatisticsBuilder blockStatisticsBuilder; - public OverviewCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper, - @NonNull SegmentActionsListener actionsListener, SelectedGpxFile selectedGpxFile) { + public OverviewCard(@NonNull MapActivity mapActivity, @NonNull SegmentActionsListener actionsListener, SelectedGpxFile selectedGpxFile) { super(mapActivity); this.actionsListener = actionsListener; this.selectedGpxFile = selectedGpxFile; - blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, displayHelper); + blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile); } @Override diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index e0e196a712..ff2ec67140 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -326,7 +326,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } headerContainer.addView(overviewCard.getView()); } else { - overviewCard = new OverviewCard(getMapActivity(), displayHelper, this, selectedGpxFile); + overviewCard = new OverviewCard(getMapActivity(), this, selectedGpxFile); overviewCard.setListener(this); headerContainer.addView(overviewCard.build(getMapActivity())); } @@ -760,7 +760,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card segment = segments.get(0); } } - GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}; + GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT}; List items = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)); if (segment != null && !Algorithms.isEmpty(items)) { SplitSegmentDialogFragment.showInstance(fragmentManager, displayHelper, items.get(0), segment); @@ -1013,6 +1013,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card public void openAnalyzeOnMap(GpxDisplayItem gpxItem) { TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu(); trackDetailsMenu.setGpxItem(gpxItem); + trackDetailsMenu.setSelectedGpxFile(selectedGpxFile); trackDetailsMenu.show(); hide(); } @@ -1110,7 +1111,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card @Override public void gpxSavingFinished(Exception errorMessage) { if (selectedGpxFile != null) { - List groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}); + List groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT}); selectedGpxFile.setDisplayGroups(groups, app); selectedGpxFile.processPoints(app); } From 321ceb797fac20ff4a74d17819b8b75a125ad372 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 9 Feb 2021 18:01:39 +0100 Subject: [PATCH 121/398] Refactor translation names & remove no translate unclear file --- OsmAnd/.gitignore | 2 -- OsmAnd/AndroidManifest-nightlyFree.xml | 4 +--- OsmAnd/build-common.gradle | 14 -------------- OsmAnd/build.gradle | 24 +++++++++++------------- OsmAnd/{ => res/values}/no_translate.xml | 1 - 5 files changed, 12 insertions(+), 33 deletions(-) rename OsmAnd/{ => res/values}/no_translate.xml (97%) diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index b8c08a2225..3149fb4209 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -39,8 +39,6 @@ mx_* valgrind/ bin/ dist/ -res/values/no_translate.xml -res/values/skip_translate.xml assets/specialphrases/* assets/voice/* assets/fonts/* diff --git a/OsmAnd/AndroidManifest-nightlyFree.xml b/OsmAnd/AndroidManifest-nightlyFree.xml index 6ec6d5a12e..c58c4b35ac 100644 --- a/OsmAnd/AndroidManifest-nightlyFree.xml +++ b/OsmAnd/AndroidManifest-nightlyFree.xml @@ -4,10 +4,8 @@ - replaceNoTranslate(line); - } - } - into 'res/values/' -} task validateTranslate { println "Validating translations" @@ -147,10 +138,6 @@ task collectVoiceAssets(type: Sync) { include "**/*.js" } -task cleanNoTranslate(type: Delete) { - delete('res/values/no_translate.xml') -} - task collectFonts(type: Copy) { from "../../resources/fonts" from "../../resources/rendering_styles/fonts" @@ -262,7 +249,6 @@ task collectExternalResources { copyMapShaderIcons, copyMapPOIIcons, copyLargePOIIcons, - updateNoTranslate, validateTranslate, copyWidgetIcons, copyWidgetIconsHdpi, diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index bf435f606b..22a9d3a2b1 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -105,31 +105,42 @@ android { nightlyFree { dimension "version" applicationId "net.osmand.dev" + resValue "string", "app_name", "OsmAnd Nightly" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" // resConfig "en" } androidFull { dimension "version" applicationId "net.osmand.plus" + resValue "string", "app_name", "OsmAnd~" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" } gplayFree { dimension "version" applicationId "net.osmand" + resValue "string", "app_name", "OsmAnd" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" } gplayFull { dimension "version" applicationId "net.osmand.plus" + resValue "string", "app_name", "OsmAnd+" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" } amazonFree { dimension "version" applicationId "net.osmand" + resValue "string", "app_name", "OsmAnd" } amazonFull { dimension "version" applicationId "net.osmand.plus" + resValue "string", "app_name", "OsmAnd+" } huawei { dimension "version" applicationId "net.osmand.huawei" + resValue "string", "app_name", "OsmAnd" } // Build that includes 3D OpenGL release @@ -153,19 +164,6 @@ android { } -def replaceNoTranslate(line) { - if (line.contains("\"app_name\"") && System.getenv("TARGET_APP_PLUS_NAME")) { - return line.replaceAll(">[^<]*<", ">" + System.getenv("TARGET_APP_PLUS_NAME") + "<") - } - if (line.contains("\"app_name_free\"") && System.getenv("TARGET_APP_FREE_NAME")) { - return line.replaceAll(">[^<]*<", ">" + System.getenv("TARGET_APP_FREE_NAME") + "<") - } - if (line.contains("\"app_edition\"") && System.getenv("APP_EDITION")) { - return line.replaceAll(">[^<]*<", ">" + System.getenv("APP_EDITION") + "<") - } - return line; -} - afterEvaluate { android.applicationVariants.all { variant -> variant.javaCompiler.dependsOn(collectExternalResources, buildOsmAndCore, cleanupDuplicatesInCore) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/res/values/no_translate.xml similarity index 97% rename from OsmAnd/no_translate.xml rename to OsmAnd/res/values/no_translate.xml index d5ecc7c149..1bbd142295 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/res/values/no_translate.xml @@ -1,7 +1,6 @@ OsmAnd~ - OsmAnd Nightly From 96ebd6dbd07601a46104f6f85ba70dc835871db7 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 9 Feb 2021 18:07:43 +0100 Subject: [PATCH 122/398] Refactor translation names & remove no translate unclear file --- OsmAnd/AndroidManifest-library.xml | 3 --- OsmAnd/build-library.gradle | 4 ---- OsmAnd/build.gradle | 12 ++++++------ 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/OsmAnd/AndroidManifest-library.xml b/OsmAnd/AndroidManifest-library.xml index 379f1ce963..f5a1bb6dc8 100644 --- a/OsmAnd/AndroidManifest-library.xml +++ b/OsmAnd/AndroidManifest-library.xml @@ -40,9 +40,6 @@ - - diff --git a/OsmAnd/build-library.gradle b/OsmAnd/build-library.gradle index b8cf0a21a5..c282fa6fa2 100644 --- a/OsmAnd/build-library.gradle +++ b/OsmAnd/build-library.gradle @@ -28,10 +28,6 @@ android { } } -def replaceNoTranslate(line) { - return line; -} - afterEvaluate { android.libraryVariants.all { variant -> variant.javaCompiler.dependsOn(collectExternalResources, buildOsmAndCore, cleanupDuplicatesInCore) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index 22a9d3a2b1..e49cd28611 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -36,9 +36,9 @@ android { defaultConfig { minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15 - versionCode 390 + versionCode 400 versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode - versionName "3.9.0" + versionName "4.0.0" versionName System.getenv("APK_VERSION")? System.getenv("APK_VERSION").toString(): versionName versionName System.getenv("APK_VERSION_SUFFIX")? versionName + System.getenv("APK_VERSION_SUFFIX").toString(): versionName } @@ -106,26 +106,26 @@ android { dimension "version" applicationId "net.osmand.dev" resValue "string", "app_name", "OsmAnd Nightly" - resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION") : "" // resConfig "en" } androidFull { dimension "version" applicationId "net.osmand.plus" resValue "string", "app_name", "OsmAnd~" - resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION") : "" } gplayFree { dimension "version" applicationId "net.osmand" resValue "string", "app_name", "OsmAnd" - resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION") : "" } gplayFull { dimension "version" applicationId "net.osmand.plus" resValue "string", "app_name", "OsmAnd+" - resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION").toInteger() : "" + resValue "string", "app_edition", System.getenv("APP_EDITION") ? System.getenv("APP_EDITION") : "" } amazonFree { dimension "version" From ae7ad29dc087b0eaddd120edc8e00dc635c29a20 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 9 Feb 2021 18:10:21 +0100 Subject: [PATCH 123/398] Refactor translation names & remove no translate unclear file --- OsmAnd/build.gradle | 3 +++ OsmAnd/res/values/no_translate.xml | 8 +++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index e49cd28611..11c9388fa0 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -131,16 +131,19 @@ android { dimension "version" applicationId "net.osmand" resValue "string", "app_name", "OsmAnd" + resValue "string", "app_edition", "" } amazonFull { dimension "version" applicationId "net.osmand.plus" resValue "string", "app_name", "OsmAnd+" + resValue "string", "app_edition", "" } huawei { dimension "version" applicationId "net.osmand.huawei" resValue "string", "app_name", "OsmAnd" + resValue "string", "app_edition", "" } // Build that includes 3D OpenGL release diff --git a/OsmAnd/res/values/no_translate.xml b/OsmAnd/res/values/no_translate.xml index 1bbd142295..2ae0fc4ec5 100644 --- a/OsmAnd/res/values/no_translate.xml +++ b/OsmAnd/res/values/no_translate.xml @@ -1,6 +1,8 @@ - OsmAnd~ + + + @@ -8,11 +10,7 @@ €2,99 €1,39 OsmAnd Live - UA-28342846-2 - 10 - true © OpenStreetMap - support@osmand.net Display language Device language From 847aabfc736606013a9434f9a65367bf401cc25f Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 9 Feb 2021 18:14:21 +0100 Subject: [PATCH 124/398] Fix nightly free --- OsmAnd/AndroidManifest-nightlyFree.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/OsmAnd/AndroidManifest-nightlyFree.xml b/OsmAnd/AndroidManifest-nightlyFree.xml index c58c4b35ac..d4e57e4b87 100644 --- a/OsmAnd/AndroidManifest-nightlyFree.xml +++ b/OsmAnd/AndroidManifest-nightlyFree.xml @@ -4,7 +4,6 @@ Date: Wed, 10 Feb 2021 04:31:49 +0200 Subject: [PATCH 125/398] add ability to update data with track recording interval --- .../plus/track/GpxBlockStatisticsBuilder.java | 117 +++++++++++------- 1 file changed, 73 insertions(+), 44 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index b6f07ecf50..2f11a6136a 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -1,10 +1,10 @@ package net.osmand.plus.track; import android.graphics.drawable.Drawable; +import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.ColorInt; @@ -12,7 +12,6 @@ import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageView; -import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -24,7 +23,6 @@ import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; @@ -41,6 +39,13 @@ public class GpxBlockStatisticsBuilder { private RecyclerView blocksView; private final SelectedGpxFile selectedGpxFile; + private BlockStatisticsAdapter adapter; + private final List items = new ArrayList<>(); + + private final Handler handler = new Handler(); + private Runnable updatingItems; + private boolean updateRunning = false; + public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile) { this.app = app; this.selectedGpxFile = selectedGpxFile; @@ -59,7 +64,39 @@ public class GpxBlockStatisticsBuilder { } public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { - List items = new ArrayList<>(); + initItems(); + boolean isNotEmpty = !Algorithms.isEmpty(items); + AndroidUiHelper.updateVisibility(blocksView, isNotEmpty); + if (isNotEmpty) { + adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode); + adapter.setItems(items); + blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); + blocksView.setAdapter(adapter); + } + } + + public void stopUpdatingStatBlocks() { + handler.removeCallbacks(updatingItems); + updateRunning = false; + } + + public void runUpdatingStatBlocks() { + updatingItems = new Runnable() { + @Override + public void run() { + if (adapter != null) { + initItems(); + adapter.setItems(items); + AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items)); + } + int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); + handler.postDelayed(this, Math.max(1000, interval)); + } + }; + updateRunning = handler.post(updatingItems); + } + + public void initItems() { GPXFile gpxFile = getGPXFile(); GpxDisplayItem gpxDisplayItem = null; GPXTrackAnalysis analysis = null; @@ -76,72 +113,55 @@ public class GpxBlockStatisticsBuilder { String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); - prepareData(analysis, items, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), + items.clear(); + prepareData(analysis, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app), R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE); - prepareData(analysis, items, app.getString(R.string.altitude_ascent), asc, + prepareData(analysis, app.getString(R.string.altitude_ascent), asc, R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE); - prepareData(analysis, items, app.getString(R.string.altitude_descent), desc, + prepareData(analysis, app.getString(R.string.altitude_descent), desc, R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE); - prepareData(analysis, items, app.getString(R.string.average_speed), avg, + prepareData(analysis, app.getString(R.string.average_speed), avg, R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); - prepareData(analysis, items, app.getString(R.string.max_speed), max, + prepareData(analysis, app.getString(R.string.max_speed), max, R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED); - prepareData(analysis, items, app.getString(R.string.shared_string_time_span), + prepareData(analysis, app.getString(R.string.shared_string_time_span), Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()), R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME); } - boolean isNotEmpty = !Algorithms.isEmpty(items); - AndroidUiHelper.updateVisibility(blocksView, isNotEmpty); - if (isNotEmpty && gpxDisplayItem != null) { - final BlockStatisticsAdapter sbAdapter = new BlockStatisticsAdapter(items, gpxDisplayItem, actionsListener, activeColor, nightMode); - blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); - blocksView.setAdapter(sbAdapter); - } } - public void prepareData(GPXTrackAnalysis analysis, List listItems, String title, - String value, @DrawableRes int imageResId, @ColorRes int imageColorId, + public void prepareData(GPXTrackAnalysis analysis, String title, String value, + @DrawableRes int imageResId, @ColorRes int imageColorId, GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) { StatBlock statBlock = new StatBlock(title, value, imageResId, imageColorId, firstType, secondType, itemType); switch (statBlock.itemType) { case ITEM_DISTANCE: { if (analysis.totalDistance != 0f) { - listItems.add(statBlock); + items.add(statBlock); } break; } case ITEM_ALTITUDE: { if (analysis.hasElevationData) { - listItems.add(statBlock); + items.add(statBlock); } break; } case ITEM_SPEED: { if (analysis.isSpeedSpecified()) { - listItems.add(statBlock); + items.add(statBlock); } break; } case ITEM_TIME: { if (analysis.hasSpeedData) { - listItems.add(statBlock); + items.add(statBlock); } break; } } } - private void setImageDrawable(ImageView iv, @DrawableRes Integer resId, @ColorRes int color) { - Drawable icon = resId != null ? app.getUIUtilities().getIcon(resId, color) - : UiUtilities.tintDrawable(iv.getDrawable(), getResolvedColor(color)); - iv.setImageDrawable(icon); - } - - @ColorInt - protected int getResolvedColor(@ColorRes int colorId) { - return ContextCompat.getColor(app, colorId); - } - public class StatBlock { private final String title; private final String value; @@ -172,16 +192,15 @@ public class GpxBlockStatisticsBuilder { private class BlockStatisticsAdapter extends RecyclerView.Adapter { - private final List statBlocks; + private final List items = new ArrayList<>(); private final GpxDisplayItem displayItem; private final SegmentActionsListener actionsListener; @ColorInt private final int activeColor; private final boolean nightMode; - public BlockStatisticsAdapter(List statBlocks, GpxDisplayItem displayItem, - SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { - this.statBlocks = statBlocks; + public BlockStatisticsAdapter(GpxDisplayItem displayItem, SegmentActionsListener actionsListener, + @ColorInt int activeColor, boolean nightMode) { this.displayItem = displayItem; this.actionsListener = actionsListener; this.activeColor = activeColor; @@ -190,7 +209,7 @@ public class GpxBlockStatisticsBuilder { @Override public int getItemCount() { - return statBlocks.size(); + return items.size(); } @NonNull @@ -203,16 +222,19 @@ public class GpxBlockStatisticsBuilder { @Override public void onBindViewHolder(BlockStatisticsViewHolder holder, int position) { - final StatBlock item = statBlocks.get(position); + final StatBlock item = items.get(position); holder.valueText.setText(item.value); holder.titleText.setText(item.title); + if (updateRunning) { + holder.titleText.setWidth(app.getResources().getDimensionPixelSize(R.dimen.map_route_buttons_width)); + } holder.valueText.setTextColor(activeColor); holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - GPXTrackAnalysis analysis = displayItem.analysis; - if (displayItem != null && analysis != null) { + GPXTrackAnalysis analysis = displayItem != null ? displayItem.analysis : null; + if (analysis != null) { ArrayList list = new ArrayList<>(); if (analysis.hasElevationData || analysis.isSpeedSpecified() || analysis.hasSpeedData) { if (item.firstType != null) { @@ -228,9 +250,16 @@ public class GpxBlockStatisticsBuilder { } } }); - setImageDrawable(holder.imageView, item.imageResId, item.imageColorId); + Drawable icon = app.getUIUtilities().getIcon(item.imageResId, item.imageColorId); + holder.imageView.setImageDrawable(icon); AndroidUtils.setBackgroundColor(app, holder.divider, nightMode, R.color.divider_color_light, R.color.divider_color_dark); - AndroidUiHelper.updateVisibility(holder.divider, position != statBlocks.size() - 1); + AndroidUiHelper.updateVisibility(holder.divider, position != items.size() - 1); + } + + public void setItems(List items) { + this.items.clear(); + this.items.addAll(items); + notifyDataSetChanged(); } } From 9453a14fe458e0f6931f05b0cbf51f8140b40d45 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 10 Feb 2021 12:44:44 +0500 Subject: [PATCH 126/398] Add restart button after settings import if language was changed --- .../res/layout/fragment_import_complete.xml | 62 +++++++++++++++---- OsmAnd/res/values/strings.xml | 1 + .../src/net/osmand/plus/AppInitializer.java | 2 + .../net/osmand/plus/OsmandApplication.java | 7 ++- .../net/osmand/plus/helpers/LocaleHelper.java | 37 +++++++++++ .../backend/backup/SettingsHelper.java | 9 +++ .../fragments/ImportCompleteFragment.java | 25 ++++++++ 7 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/helpers/LocaleHelper.java diff --git a/OsmAnd/res/layout/fragment_import_complete.xml b/OsmAnd/res/layout/fragment_import_complete.xml index 6e9a5fa22b..e9d6180784 100644 --- a/OsmAnd/res/layout/fragment_import_complete.xml +++ b/OsmAnd/res/layout/fragment_import_complete.xml @@ -66,28 +66,64 @@ - + android:orientation="horizontal" > - + android:background="?attr/dlg_btn_secondary" + android:layout_weight="1"> - + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a15fb40cbd..3f5841204a 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + Restart Login to OpenPlaceReviews Use test.openplacereviews.org OpenPlaceReviews diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 065c7aba2e..13b3102c93 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -36,6 +36,7 @@ import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.DayNightHelper; +import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.inapp.InAppPurchaseHelperImpl; @@ -471,6 +472,7 @@ public class AppInitializer implements IProgress { app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class); app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class); app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class); + app.localeHelper = startupInit(new LocaleHelper(app), LocaleHelper.class); initOpeningHoursParser(); } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 9d2524d30c..285a0135eb 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -59,6 +59,7 @@ import net.osmand.plus.download.DownloadService; import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.DayNightHelper; +import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.helpers.LocationServiceHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.WaypointHelper; @@ -165,6 +166,7 @@ public class OsmandApplication extends MultiDexApplication { OprAuthHelper oprAuthHelper; MeasurementEditingContext measurementEditingContext; OnlineRoutingHelper onlineRoutingHelper; + LocaleHelper localeHelper; private Resources localizedResources; private Map customRoutingConfigs = new ConcurrentHashMap<>(); @@ -402,6 +404,10 @@ public class OsmandApplication extends MultiDexApplication { return oprAuthHelper; } + public LocaleHelper getLocaleHelper() { + return localeHelper; + } + public synchronized DownloadIndexesThread getDownloadThread() { if (downloadIndexesThread == null) { downloadIndexesThread = new DownloadIndexesThread(this); @@ -717,7 +723,6 @@ public class OsmandApplication extends MultiDexApplication { } } - public TargetPointsHelper getTargetPointsHelper() { return targetPointsHelper; } diff --git a/OsmAnd/src/net/osmand/plus/helpers/LocaleHelper.java b/OsmAnd/src/net/osmand/plus/helpers/LocaleHelper.java new file mode 100644 index 0000000000..02250098bc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/LocaleHelper.java @@ -0,0 +1,37 @@ +package net.osmand.plus.helpers; + +import net.osmand.StateChangedListener; +import net.osmand.plus.OsmandApplication; + +public class LocaleHelper implements StateChangedListener { + + private boolean needRestart = false; + + private OsmandApplication app; + + public LocaleHelper(OsmandApplication app) { + this.app = app; + } + + public void listenLocaleChanges() { + app.getSettings().PREFERRED_LOCALE.addListener(this); + } + + public void stopListeningLocaleChanges() { + app.getSettings().PREFERRED_LOCALE.removeListener(this); + } + + public boolean needRestart() { + return needRestart; + } + + public void setNeedRestart(boolean needRestart) { + this.needRestart = needRestart; + } + + @Override + public void stateChanged(String change) { + needRestart = true; + app.checkPreferredLocale(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java index 11fe377040..2e548f0c2b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java @@ -29,6 +29,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.mapmarkers.MapMarker; @@ -193,6 +194,7 @@ public class SettingsHelper { private File file; private SettingsImportListener listener; private List items; + private LocaleHelper localeHelper; ImportItemsAsyncTask(@NonNull File file, @Nullable SettingsImportListener listener, @@ -201,6 +203,12 @@ public class SettingsHelper { this.file = file; this.listener = listener; this.items = items; + localeHelper = app.getLocaleHelper(); + } + + @Override + protected void onPreExecute() { + localeHelper.listenLocaleChanges(); } @Override @@ -218,6 +226,7 @@ public class SettingsHelper { @Override protected void onPostExecute(Boolean success) { + localeHelper.stopListeningLocaleChanges(); finishImport(listener, success, items); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java index 0d40a3c2f1..ddee0e1393 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java @@ -15,6 +15,7 @@ import android.widget.TextView; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -28,6 +29,7 @@ import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment; +import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.quickaction.QuickActionListFragment; @@ -97,6 +99,10 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { dismissFragment(); } }); + if (app.getLocaleHelper().needRestart()) { + app.getLocaleHelper().setNeedRestart(false); + setupRestartButton(root); + } if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(app, root); } @@ -239,6 +245,25 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { } } + private void setupRestartButton(View root) { + View buttonsDivider = root.findViewById(R.id.buttons_divider); + View buttonContainer = root.findViewById(R.id.button_restart_container); + AndroidUiHelper.setVisibility(View.VISIBLE, buttonsDivider, buttonContainer); + + TextView btnRestart = root.findViewById(R.id.button_restart); + btnRestart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity activity = getActivity(); + if (activity instanceof MapActivity) { + MapActivity.doRestart(activity); + } else { + android.os.Process.killProcess(android.os.Process.myPid()); + } + } + }); + } + @Override public int getStatusBarColorId() { return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light; From ecd911a79c006d578fbcee8e89c0fe6b0179960f Mon Sep 17 00:00:00 2001 From: max-klaus Date: Wed, 10 Feb 2021 10:53:21 +0300 Subject: [PATCH 127/398] Fix free version manifest --- OsmAnd/AndroidManifest-gplayFree.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/AndroidManifest-gplayFree.xml b/OsmAnd/AndroidManifest-gplayFree.xml index 873848e1e9..eb06260f4e 100644 --- a/OsmAnd/AndroidManifest-gplayFree.xml +++ b/OsmAnd/AndroidManifest-gplayFree.xml @@ -4,7 +4,7 @@ Date: Wed, 10 Feb 2021 10:57:24 +0300 Subject: [PATCH 128/398] Fix lib gradle --- OsmAnd/build-library.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/build-library.gradle b/OsmAnd/build-library.gradle index c282fa6fa2..2c50079396 100644 --- a/OsmAnd/build-library.gradle +++ b/OsmAnd/build-library.gradle @@ -24,6 +24,7 @@ android { // Build that doesn't include 3D OpenGL legacy { dimension "coreversion" + resValue "string", "app_edition", "" } } } From b9c2f9029ea8f2e7fcef58b2008b5cada5c13bbe Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:07 +0000 Subject: [PATCH 129/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 06d4d70284..8d9da7a4fd 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -593,6 +593,7 @@ التغييرات POI داخل التطبيق لا تؤثرعلى ملفات الخرائط المحملة، يتم حفظ التغييرات إلى ملف محلي بدلا من ذلك. وضع تركيز الكاميرا: أوسماند+ (OSM اتجاهات التنقل التلقائية) +\n \n عبارة عن تطبيق ملاحة مفتوح المصدر مع إمكانية الوصول إلى العديد من بيانات عالمية للموقع. كل بيانات الخرائط (خرائط التوجيه أو الخرائط الجزئية) يمكن تخزينها في ذاكرة الجهاز للإستخدام دون إنترنت. يوفر التطبيق كذلك وظائف توجيه بما في ذلك التوجيه الصوتي. \n \nبعض الميزات الأساسية: @@ -602,6 +603,7 @@ \n - ميزة ويكيبيديا المحلية ( قم بتحميل نقاط الاهتمام لويكيبيديا)، الأمثل لمشاهدة المعالم الأثرية \n - يمكن تراكب عدة طبقات للخرائط، ك GPX أو مسارات الملاحة، مواقع ذات الاهتمام ، الأماكن المفضلة، الحدود الكنتورية، أماكن توقف النقل العمومي، خرائط إضافية بشفافية قابلة للتعديل \n - البحث عن العناوين وأماكن الاهتمام دون إنترنت +\n \n - تحديد الطريق لمسافات متوسطة المدى \n - وضع السيارة، الدراجة والمشاة متوفر مع: \n - تبديل اختياري آلي لوضع الرؤية في الليل/النهار @@ -3954,7 +3956,7 @@ تعليق ملاحظة OSM قم بتسجيل الدخول باستخدام طريقة المصادقة الآمنة أو استخدم اسم المستخدم وكلمة المرور. إضافة صورة - سجل في + سجل في \nOpenPlaceReviews.org قم بتسجيل الدخول إلى موقع مشروع البيانات المفتوحة OpenPlaceReviews.org لرفع المزيد من الصور. إنشاء حساب جديد @@ -3970,9 +3972,9 @@ لا يوجد مساحة كافية أضف إلى مابيلاي إضافة إلى OpenPlaceReviews - يعرض صورا من عدة مصادر: -\nOpenPlaceReviews - صور POI ؛ -\nMapillary - صور على مستوى الشارع ؛ + يعرض صورا من عدة مصادر: +\nOpenPlaceReviews - صور POI ؛ +\nMapillary - صور على مستوى الشارع ؛ \nالويب / ويكيميديا - صور POI المحددة في بيانات OpenStreetMap. حدد المجموعات التي سيتم استيرادها. حدد العناصر التي سيتم استيرادها. @@ -3988,17 +3990,17 @@ تقسيم قبل تقسيم بعد إضافة شريحة جديدة - • خيار مضاف لتصدير واستيراد جميع البيانات بما في ذلك الإعدادات والموارد والأماكن الخاصة بي -\n -\n • مخطط الطريق: الرسوم البيانية لأجزاء المسار مع الطريق ، إضافة القدرة على إنشاء وتحرير مقاطع مسارات متعددة -\n -\n • تمت إضافة طريقة مصادقة آلية OAuth ل OpenStreetMap ، وواجهة مستخدم محسنة لمربعات حوار OSM -\n + • خيار مضاف لتصدير واستيراد جميع البيانات بما في ذلك الإعدادات والموارد والأماكن الخاصة بي +\n +\n • مخطط الطريق: الرسوم البيانية لأجزاء المسار مع الطريق ، إضافة القدرة على إنشاء وتحرير مقاطع مسارات متعددة +\n +\n • تمت إضافة طريقة مصادقة آلية OAuth ل OpenStreetMap ، وواجهة مستخدم محسنة لمربعات حوار OSM +\n \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n \n - وضع التطبيق - حساب المستخدم + وضع الاستعراض + ملف تعريف المستخدم عكس جميع النقاط حدد الوضع الذي سيتم استخدامه في بدء التطبيق. آخر استخدام @@ -4030,7 +4032,7 @@ تحديد مجلد تحديد مجلد أو إضافة واحد جديد فارغ - تحليل حسب الفاصل الزمني + التحليل حسب الفواصل الزمنية (الفاصل الزمني) رفع إلى خريطة الشارع المفتوح تحرير المسار تسمية المسار @@ -4080,7 +4082,7 @@ \nجميع بيانات OpenPlaceReview مفتوحة ومتاحة للجميع: http://openplacereviews.org/data. \n \nيمكنك قراءة المزيد على: http://openplacereviews.org - مراجعات الأمكنة + OpenPlaceReviews استخدام test.openplacereviews.org الدخول إلى OpenPlaceReviews \ No newline at end of file From 5a7a0079c4b8dd08dbab546e9a65f15c95a7730a Mon Sep 17 00:00:00 2001 From: nasr pen Date: Tue, 9 Feb 2021 11:07:10 +0000 Subject: [PATCH 130/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 8d9da7a4fd..8858534772 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1964,8 +1964,7 @@ \nليست هناك حاجة لتحميل خريطة خاصة،الرؤية يتم إنشاؤها من خلال خرائطنا المحلية. \n \nهذه الرؤية يمكن التراجع عنها إما عن طريق تعطيلها هنا، أو تغيير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. - - Online OSM تصنيف الخريطة مع الصور. + Online OSM تصنيف الخريطة مع الصور. تعيين الحد الأقصى لوقت الانتظار لكل إصلاح موقع في الخلفية. الانتظار الأقصى للإصلاح إصدار غير معتمد من البيانات الصوتية @@ -2074,7 +2073,7 @@ اللون والسمك خذ المخرج %1$d ثم واصل المدينة أو المنطقة - مقالات ويكيبيديا قريبة + مقالات ويكيبيديا القريبة استخدام الطرق السريعة السماح للطرق السريعة. الصربية (اللاتينية) @@ -2618,7 +2617,7 @@ ج ش اسم النقطة - الطرق القريبة في الداخل + الطرق الداخلية المجاورة أدخل اسم الملف. خطأ أثناء استرجاع الخريطة تمت عملية استيراد الخريطة @@ -3945,7 +3944,7 @@ الحساب تسجيل الدخول \"إمكانية التتبع\" تعني أن التتبع لا يظهر في أي قوائم عامة ولكن نقاط التتبع المعالجة مع طوابع زمنية صادرة عنها(التي لا يمكن أن تكون مرتبطة بك مباشرة) ستظهر خلال التنزيلات من واجهة برمجة التطبيقات GPS API العامة. - سجل تاريخ العلامات + سِجل تاريخ العلامات أرسل ملف GPX إلى OpenStreetMap أدخل العلامات مفصولة بفاصلة. \"خاص\"يعني أن التتبع لن يظهر في أي قوائم عامة ، ولكن نقاط التتبع الصادرة عنه ستظل متاحة من خلال واجهة برمجة تطبيقات GPS API العامة بدون طوابع زمنية ولكن لن يتم ترتيبها ترتيبًا زمنيًا. From 012bdf69cfe89b969f400b0923d91a6cf5246728 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:11 +0000 Subject: [PATCH 131/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 188 +++++++++++++++---------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 8858534772..28ff589f66 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -2693,7 +2693,7 @@ تنزيل الكل إعادة تشغيل التطبيق إشارة مرجعية - نقاط بالطريق تم إزالتها من علامات الخريطة + نقاط بالطريق تم إزالتها من التوجيه المباشر للخريطة بواسطة أوسماند الأسعار والاشتراك شهري @@ -2708,19 +2708,19 @@ يجدد سنويا حدد فترة الدفع المناسبة لك: تبرعات مساعدة صندوق رسم الخرائط OSM. - حذف العلامة \'%s\'؟ - تعديل العلامة + حذف التوجيه المباشر \'%s\'؟ + تعديل التوجيه المباشر بحث عن شارع اختر المدينة أولاً استعادة تطبيق من طرف ثالث - ستبقى العلامات المضافة من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز العلامة\". إذا كانت المجموعة غير نشطة ستختفي العلامات من الخريطة. - إبقاء العلامة المتجاوز + عند التفعيل سيبقى التوجيه المباشر المضاف من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز التوجيه المباشر\". إذا كانت المجموعة غير نشطة ستختفي الوجهات المباشرة من الخريطة. + إبقاء التوجيه المباشر المتجاوز هناك المزيد من وسائل النقل في هذا الموقف. يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل. شكرا على الرد النقطة أو الطريق غير موجود. - لايوجد نتائج للبحث؟ + لايوجد نتائج للبحث؟ \nأخبرنا برأيك زيادة نصف قطر البحث إلى %1$s إرسال استفسار البحث؟ @@ -2753,7 +2753,7 @@ اختر العنصر المناسب لا تفعل افعل - صور المقالة يمكن تحملها للاستخدام بدون اتصال. + صور المقالة يمكن تحملها للاستخدام بدون اتصال. \nدائماً متوفرة في \'اكتشف\'←\'خيارات\'. الصفحة متاحة على الإنترنت فقط. فتح في متصفح الويب؟ الصور المؤقتة @@ -2993,7 +2993,7 @@ سنوات ثلاثة أشهر مجاناً - إظهار شبكة طرق الدارجات الهوائية + إظهار شبكة مسارات الدارجات الهوائية نافذة تحميل الخريطة النوافذ والإشعارات التحكم في النوافذ المنبثقة ، ومربعات الحوار والإشعارات. @@ -3018,7 +3018,7 @@ لصق مسار مجلد بيانات أوسماند تغيير مجلد التخزين ؟ نقل للموقع الجديد - تجنب بعض أنواع الطرق + تجنب بعض الطرق جنبًا إلى جنب طريق تلفريك اتصال @@ -3043,21 +3043,21 @@ تفضيل الطرق الغير معبدة تفضيل الطرق الغير معبدة. تحديث كل الخرائط - تحديث (%1$d) خريطة؟ - • تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. -\n -\n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط -\n -\n • إصلاحات للنمط الليلي -\n -\n • إصلاح العديد من مشاكل التوجيه في جميع أنحاء العالم -\n -\n • خريطة الأساس المحدثة مع شبكة طرق أكثر تفصيلا -\n -\n • تحديث المناطق التي غمرتها الفيضانات في جميع أنحاء العالم -\n -\n • توجيه التزلج: إضافة وضع الارتفاع وتعقيد المسار إلى تفاصيل المسار -\n + هل أنت متأكد من رغبتك بتحديث (%1$d) خريطة؟ + • تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. +\n +\n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط +\n +\n • إصلاحات للنمط الليلي +\n +\n • إصلاح العديد من مشاكل التوجيه في جميع أنحاء العالم +\n +\n • خريطة الأساس المحدثة مع شبكة طرق أكثر تفصيلا +\n +\n • تحديث المناطق التي غمرتها الفيضانات في جميع أنحاء العالم +\n +\n • توجيه التزلج: إضافة وضع الارتفاع وتعقيد المسار إلى تفاصيل المسار +\n \n • إصلاحات أخرى \n \n @@ -3234,7 +3234,7 @@ تحديثات الخريطة الشهرية تحديثات الخريطة كل ساعة سيتم إرسال استعلام البحث إلى: \"%1$s\" ، بالإضافة إلى موقعك. -\n +\n \nلا يتم جمع المعلومات الشخصية ، فقط بيانات البحث اللازمة لتحسين البحث. لامركبة ترام تجنب مركبة الترام @@ -3259,8 +3259,8 @@ عرض الإحداثيات سياسة الخصوصية ساعدنا في جعل أوسماند أفضل - السماح ل OsmAnd بجمع ومعالجة بيانات استخدام التطبيق المجهول. لا يتم جمع بيانات حول موقعك أو المواقع التي تعرضها على الخريطة. -\n + السماح ل OsmAnd بجمع ومعالجة بيانات استخدام التطبيق المجهول. لا يتم جمع بيانات حول موقعك أو المواقع التي تعرضها على الخريطة. +\n \nقم بإعدادها في أي وقت لاحق في \'الإعدادات\' ← \'الخصوصية والأمان\'. اختر نوع البيانات التي تريد مشاركتها: الخرائط التي تم تنزيلها @@ -3379,7 +3379,7 @@ اختر اللون لا يمكنك حذف أوضاع أوسماند الافتراضية ، ولكن يمكنك تعطيلها في الشاشة السابقة ، أو نقلها إلى الأسفل. تحرير الأوضاع - يؤثر نوع التنقل على قواعد حساب الطرق. + يؤثر نوع التنقل على قواعد حسابات المسار. مظهر الوضع اختر الايقونة واللون والاسم تحرير قائمة الأوضاع @@ -3496,8 +3496,8 @@ تضمين بيانات إضافية يمكنك تحديد بيانات إضافية للتصدير مع الوضع. القارة القطبية الجنوبية - هذا الملحق هو تطبيق منفصل ، بإمكانك إزالته بشكل منفصل إذا لم تعد تخطط لاستخدامه. -\n + هذا الملحق هو تطبيق منفصل ، بإمكانك إزالته بشكل منفصل إذا لم تعد تخطط لاستخدامه. +\n \nسيبقى الملحق الإضافي على الجهاز بعد إزالة أوسماند. %1$s — %2$s — %3$s يحتوي الوضع المستوردة على بيانات إضافية. انقر فوق \"استيراد\" لاستيراد بيانات الوضع فقط أو حدد بيانات إضافية لاستيرادها. @@ -3524,8 +3524,8 @@ المدرج %1$s, موجودة بالفعل في أوسماند. احتفظ بكليهما سيتم إضافة العناصر المستوردة مع زيادة قبل اسمها - OsmAnd يحتوي بالفعل على عناصر بنفس الأسماء مثل التي استوردتها. -\n + OsmAnd يحتوي بالفعل على عناصر بنفس الأسماء مثل التي استوردتها. +\n \nحدد إجراء. بعض العناصر موجودة بالفعل حدد البيانات التي سيتم استيرادها. @@ -3535,11 +3535,11 @@ استعادة جميع إعدادات الوضع؟ حفظ الوضع الجديد لا يمكن عمل نسخة احتياطية لهذا الوضع. - مسح البيانات المسجلة؟ + هل أنت متأكد من أنك تريد مسح البيانات المسجلة؟ استيراد البيانات من %1$s استيراد - OsmAnd تحقق %1$s للتكرارات مع العناصر الموجودة في التطبيق. -\n + OsmAnd تحقق %1$s للتكرارات مع العناصر الموجودة في التطبيق. +\n \nقد يستغرق الأمر بعض الوقت. العناصر المضافة تم الاستيراد @@ -3586,8 +3586,8 @@ اللغة جميع اللغات هناك حاجة إلى خرائط إضافية لعرض النقاط المهمة من ويكيبيديا على الخريطة. - تخصيص كمية العناصر في درج تكوين خريطة قائمة السياق. -\n + تخصيص كمية العناصر في درج تكوين خريطة قائمة السياق. +\n \nيمكنك تعطيل الإضافات غير المستخدمة لإخفاء جميع الضوابط من الطلب %1$s. عناصر الدرج، قائمة السياق تخصيص واجهة المستخدم @@ -3637,10 +3637,10 @@ خرائط إضافية %1$s إجراء غير معتمد %1$s / %2$s - سيتم احتساب الدفع لحساب Google Play الخاص بك في تأكيد الشراء. -\n -\nيتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل تاريخ التجديد. سيتم تحميل حسابك لفترة التجديد (شهر / ثلاثة أشهر / سنة) فقط في تاريخ التجديد. -\n + سيتم احتساب الدفع لحساب Google Play الخاص بك في تأكيد الشراء. +\n +\nيتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل تاريخ التجديد. سيتم تحميل حسابك لفترة التجديد (شهر / ثلاثة أشهر / سنة) فقط في تاريخ التجديد. +\n \nيمكنك إدارة وإلغاء الاشتراكات الخاصة بك عن طريق الذهاب إلى إعدادات Google Play الخاصة بك. البحث عن أنواع poi اجمع أنواع النقاط المهمة من فئات مختلفة. اضغط على مفتاح التبديل لتحديد الكل ، ثم انقر على الجانب الأيسر لاختيار الفئة. @@ -3656,22 +3656,22 @@ مشتريات أوسماند دليل رموز الخريطة. أوضاع الملاحة - • خرائط جديدة للتضاريس توضح المنحدرات من دون الحاجة للاتصال بالإنترنت -\n -\n • التخصيص الكامل للمفضلات ونقاط الطرق GPX - الألوان المخصصة والأيقونات والأشكال -\n -\n • تخصيص ترتيب العناصر في قائمة السياق ، تكوين الخريطة ، درج -\n -\n • عرض ويكيبيديا كطبقة منفصلة في تكوين الخريطة ، حدد اللغات المطلوبة فقط -\n -\n • إنشاء مرشح / خرائط للمعالم الخاصة بك مع مرونة تامة -\n -\n • تمت إضافة خيارات لاستعادة إعدادات الأوضاع المخصصة -\n -\n • مسارات GPX كاملة من الممرات دعم حركة المرور وتعليمات كاملة -\n -\n • إصلاح أحجام واجهة المستخدم على الأجهزة اللوحية -\n + • خرائط جديدة للتضاريس توضح المنحدرات من دون الحاجة للاتصال بالإنترنت +\n +\n • التخصيص الكامل للمفضلات ونقاط الطرق GPX - الألوان المخصصة والأيقونات والأشكال +\n +\n • تخصيص ترتيب العناصر في قائمة السياق ، تكوين الخريطة ، درج +\n +\n • عرض ويكيبيديا كطبقة منفصلة في تكوين الخريطة ، حدد اللغات المطلوبة فقط +\n +\n • إنشاء مرشح / خرائط للمعالم الخاصة بك مع مرونة تامة +\n +\n • تمت إضافة خيارات لاستعادة إعدادات الأوضاع المخصصة +\n +\n • مسارات GPX كاملة من الممرات دعم حركة المرور وتعليمات كاملة +\n +\n • إصلاح أحجام واجهة المستخدم على الأجهزة اللوحية +\n \n • إصلاح الخلل مع اللغات التي تكتب من اليمين \n \n @@ -3723,15 +3723,15 @@ \n \n%2$s هي مستويات التكبير التي ستكون فيها الإطارات المتجانبة الأصلية مرئية. سوف يحدث التحجيم للأكبر أو الأصغر خارج هذه القيم. وقت انتهاء الصلاحية بالدقائق. سيتم إعادة تحميل الإطارات المتجانبة المخزنة مؤقتًا بعد الوقت المحدد. اترك هذا الحقل فارغًا لعدم تحديث الإطارات المتجانبة لهذا المصدر. -\n -\nيوم واحد هو 1440 دقيقة. -\nأسبوع واحد هو 10080 دقيقة. +\n +\nيوم واحد هو 1440 دقيقة. +\nأسبوع واحد هو 10080 دقيقة. \nشهر واحد هو 43 829 دقيقة. اختر كيفية تخزين الطبقات المنزلة. مهلة الشاشة الافتراضية يمكنك تصدير أو استيراد إجراءات سريعة باستخدام أوضاع التطبيق . حذف الكل؟ - حذف الاختصارات السريعة %d نهائيًا؟ + هل أنت متأكد من رغبتك في حذف الاختصارات السريعة %d نهائيًا؟ مهلة الشاشة نغمات أدل بعرض مركبتك، قد يتم تطبيق بعض القيود على المركبات العريضة. @@ -3761,12 +3761,12 @@ %1$s محذوفة إعادة التشغيل مطلوبة لحذف بيانات كاميرا السرعة بالكامل. إلغاء التثبيت وإعادة التشغيل - في بعض البلدان أو المناطق، يحظر القانون استخدام تطبيقات التحذير من كاميرا السرعة. -\n -\nعليك أن تختار اعتمادا على قانون بلدك. -\n -\nحدد %1$s وستتلقى تنبيهات وتحذيرات حول كاميرات السرعة. -\n + في بعض البلدان أو المناطق، يحظر القانون استخدام تطبيقات التحذير من كاميرا السرعة. +\n +\nعليك أن تختار اعتمادا على قانون بلدك. +\n +\nحدد %1$s وستتلقى تنبيهات وتحذيرات حول كاميرات السرعة. +\n \nحدد %2$s. جميع البيانات المتعلقة كاميرات السرعة: التنبيهات، والإشعارات، سيتم حذف نقاط الاهتمام حتى يتم إعادة تثبيت أوسماند تماما. تحديد الارتفاع الأعلى المسموح به على الطرق. حد الطول @@ -3788,7 +3788,7 @@ أغلق ملاحظة OSM تحتاج إلى تعيين أيام العمل للمتابعة المسار بين النقاط - تخطيط طريق + قياس المسافة إضافة إلى مسار لن تكون النقطة المضافة مرئية على الخريطة، نظرًا لأن المجموعة المحددة مخفية، يمكنك العثور عليها في \"%s\". إظهار رموز البدء والانتهاء @@ -3801,7 +3801,7 @@ التعديل الأخير استيراد المسار فتح مسار موجود - إنشاء طريق جديد + إنشاء مسار جديد حدد المسار للفتح. تم الكتابة فوق المسار @@ -3817,7 +3817,7 @@ بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد أوضاع التنقل الخاصة بك لاستخدام هذا الخيار. بداية المسافة صور للشارع - إغلاق مسار الرحلة دون حفظ؟ ستفقد كل التغييرات؟ + هل أنت متأكد أنك تريد إغلاق مسار الرحلة دون حفظ؟ سوف تفقد كل التغييرات؟ في حالة الاتجاه المعاكس تسجيل المسار أثناء الملاحة حفظ كملف مسار جديد @@ -3834,15 +3834,15 @@ أضف إحداثية مسار تسجيل الرحلة حفظ كمسار - اتبع المسار + تتبع المسار اختر مسار للمتابعة اختر ملف المسار للمتابعة أو قم باستيراده من الجهاز. - حدد مساراً آخر + حدد مسارا آخر انتقل من موقعي إلى المسار نقطة المسار للتنقل بداية المسار أقرب نقطة - إرفاق بالطرق + إرفاق الطرق حذف عنوان إضافة عنوان أدخل العنوان @@ -3865,22 +3865,22 @@ فتح المسار المحفوظ محفوظ مسار مبسط - سيتم حفظ خط الطريق فقط، وسيتم حذف نقاط المسار. + سيتم حفظ خط التوجيه فقط، وسيتم حذف نقاط الطريق. اسم الملف الرجاء إضافة نقطتين على الأقل. إعادة - • ميزة تخطيط المسار المحدثة: تسمح باستخدام أنواع الملاحة المختلفة لكل جزء وكذا اظافة طرق -\n -\n• قائمة مظهر جديدة للمسارات: تحديد اللون، السماكة، اظهار أسهم التوجيه، أيقونات الانطلاق والنهاية -\n -\n• تحسين رؤية عقد الدراجات -\n -\n• المسارات قابلة للنقر عليها الان وقائمة سياق بمعلومات أساسية -\n -\n• خوارزميات بحث محسنة -\n -\n• تم تحسين خيارات متابعة المسار خلال الملاحة -\n + • ميزة تخطيط المسار المحدثة: تسمح باستخدام أنواع الملاحة المختلفة لكل جزء وكذا اظافة طرق +\n +\n• قائمة مظهر جديدة للمسارات: تحديد اللون، السماكة، اظهار أسهم التوجيه، أيقونات الانطلاق والنهاية +\n +\n• تحسين رؤية عقد الدراجات +\n +\n• المسارات قابلة للنقر عليها الان وقائمة سياق بمعلومات أساسية +\n +\n• خوارزميات بحث محسنة +\n +\n• تم تحسين خيارات متابعة المسار خلال الملاحة +\n \n• تم إصلاح المشكلات المتعلقة باستيراد/تصدير الأوضاع الشخصية \n \n @@ -3890,10 +3890,10 @@ أيقونات البدء والانتهاء شكرا لشرائك \"خطوط الكنتور\" يتم احتساب الاشتراك للفترة المحددة. قم بإلغائه في AppGallery في أي وقت تريد. - يتم الخصم من حساب AppGallery الخاص بك عند تأكيد الشراء. -\n -\nيتم تمديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل تاريخ التجديد. سيتم الخصم من الحساب على فترة التجديد (شهر/ ثلاثة أشهر/ سنة) فقط عند تاريخ التجديد. -\n + يتم الخصم من حساب AppGallery الخاص بك عند تأكيد الشراء. +\n +\nيتم تمديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل تاريخ التجديد. سيتم الخصم من الحساب على فترة التجديد (شهر/ ثلاثة أشهر/ سنة) فقط عند تاريخ التجديد. +\n \nيمكنك إدارة وإلغاء الاشتراكات الخاصة بك في إعدادات AppGallery. تجنب الممرات تجنب الممرات @@ -3911,7 +3911,7 @@ تم استيراد الملف بالفعل في أوسماند استخدام خوارزمية توجيه من مرحلتين A* %1$s البيانات المتوفرة فقط على الطرق ، تحتاج إلى حساب طريق باستخدام \"الطريق بين النقاط\" للحصول عليها. - في انتظار إعادة حساب الطريق + في انتظار إعادة حساب الطريق \nسيتوفر الرسم البياني بعد إعادة الحساب. للقيادة على الجليد مع طرق ومسارات مخصصة. رسم بياني @@ -3937,14 +3937,14 @@ اشتراك OsmAnd Live معلق تسجيل الدخول لخريطة الشارع المفتوح تسجيل الدخول إلى خريطة الشارع المفتوح - قم بتسجيل الدخول لرفع التغييرات الجديدة أو المعدلة. -\n + قم بتسجيل الدخول لرفع التغييرات الجديدة أو المعدلة. +\n \nإما باستخدام المصادقة أو باستخدام اسم المستخدم وكلمة المرور. سجل الدخول باسم المستخدم وكلمة المرور الحساب تسجيل الدخول \"إمكانية التتبع\" تعني أن التتبع لا يظهر في أي قوائم عامة ولكن نقاط التتبع المعالجة مع طوابع زمنية صادرة عنها(التي لا يمكن أن تكون مرتبطة بك مباشرة) ستظهر خلال التنزيلات من واجهة برمجة التطبيقات GPS API العامة. - سِجل تاريخ العلامات + سجل تاريخ العلامات أرسل ملف GPX إلى OpenStreetMap أدخل العلامات مفصولة بفاصلة. \"خاص\"يعني أن التتبع لن يظهر في أي قوائم عامة ، ولكن نقاط التتبع الصادرة عنه ستظل متاحة من خلال واجهة برمجة تطبيقات GPS API العامة بدون طوابع زمنية ولكن لن يتم ترتيبها ترتيبًا زمنيًا. From f906c5ac864fda8aede86b1d583fd8da5117c35c Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:14 +0000 Subject: [PATCH 132/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 28ff589f66..b429b3c15d 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -2469,7 +2469,7 @@ إضافة نقطة قبل إضافة نقطة بعد خيارات - سيتم توصيل النقاط بطرق الوضع المحدد. + سيتم توصيل النقاط بمسارات الوضع المحدد. يمكنك حفظ النقاط إما كنقاط طريق أو كخط. اختر وضع الملاحة إضافة نقاط مسار @@ -2482,12 +2482,12 @@ عتبة توجيه الخريطة حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'. تم نقل جميع العلامات إلى السجل - تم نقل العلامة إلى السجل - العلامة أصبحت نشطة + تم نقل التوجيه المباشر إلى السجل + التوجيه المباشر انتقل كنشط قائمة مجموعات آخر استخدام : %1$s - تنشيط العلامة + تنشيط التوجيه المباشر اليوم أمس آخر ٧ أيام @@ -2503,12 +2503,12 @@ سهم متجه للهدف عرض المتجاوز إخفاء المتجاوز - إزالة من \"علامات الخريطة\" + إزالة من \"التوجيه المباشر\" تنازلي تصاعدي تاريخ الإضافة ترتيب حسب: - حدد كيفية الإشارة إلى مسافة واتجاه العلامة على شاشة الخريطة: + حدد كيفية الإشارة إلى المسافة والاتجاه للتوجيه المباشر على شاشة الخريطة: استخدم الموقع أضف موقعك كنقطة أولى لتخطيط طريق مثالي. موقعي @@ -2519,7 +2519,7 @@ تصدير علاماتك إلى ملف يمكنك تحديده هنا: نقل إلى السجل سيتم إزالة المجموعة بعد إعادة تشغيل التطبيق. - العلامات + التوجيه المباشر نمط الإحداثيات لوحة مفاتيح النظام اختر نسق إدخال الأحداثيات. يمكنك دائماً تغييره بالنقر على خيارات. @@ -2536,12 +2536,12 @@ أظهر الخريطة تم حساب المسار رحلة ذهاب وإياب - يجب عليك إضافة علامة واحدة على الأقل لاستخدام هذه الوظيفة. + يجب عليك إضافة توجيه مباشر واحد على الأقل لاستخدام هذه الوظيفة. تنسيق خاطئ أدخل اسم جديد عودة عرض - تمت إضافة نقاط الطريق إلى علامات الخريطة + تمت إضافة نقاط الطريق إلى التوجيه المباشر للخريطة إدخال خاطئ يمكن استيرادها كنقاط مفضلة، أو كملف GPX. استيراد كملف GPX @@ -2549,15 +2549,15 @@ استيراد ملف نقرة على الخريطة ستفعل أزرار التحكم والويدجت. شاشة كاملة - علامة مُجتازة + توجيه مباشر مجتاز إنشاء أو تعديل عناصر OSM قم بإنشاء أو تعديل نقاط الاهتمام OSM ، وفتح ملاحظات OSM أو التعليق عليها ، والمساهمة في ملفات GPX المسجلة. حذف مُعدلة تمت الإضافة تعديل طلب البحث. - تم تنشيط العلامة %s. - انقر على العلامة في الخريطة لجعلها بالاعلى بدون فتح القائمة. + تم تنشيط التوجيه المباشر %s. + انقر على التوجيه المباشر في الخريطة لجعله الاعلى بدون فتح القائمة. تدوين ملاحظات! بدون حد زمني اقرأ المقال كاملا @@ -2565,27 +2565,27 @@ جميع نقاط هذه المجموعة افتح من مفتوح حتى - يغلق عند - يفتح عند - يفتح عند + يغلق أبوابه على + سيفتح الأبواب على + يفتح أبوابه على إجراءات إضافية إجراءات - العلامات + توجيه مباشر الملاحظات حسب التاريخ حسب التاريخ حسب النوع المزيد - المظهر على الخريطة + التوجيه المباشر نقاط المسار إضافة مجموعة - قم بإنشاء علامات على الخريطة ! + قم بإنشاء التوجيه المباشر على الخريطة ! استيراد مجموعات عدد الأرقام اليمين اليسار لصق الانتقال إلى الحقل التالي - إعادة تسمية العلامة + إعادة تسمية التوجيه المباشر مجموع التبرعات تسميات POI بدون اسم @@ -2617,7 +2617,7 @@ ج ش اسم النقطة - الطرق الداخلية المجاورة + الطرق القريبة التي في الداخل أدخل اسم الملف. خطأ أثناء استرجاع الخريطة تمت عملية استيراد الخريطة @@ -2629,7 +2629,7 @@ قم باختيار نسق الملف جميع البيانات ملاحظات OSM - سيفتح غداً عند + سيفتح أبوابه غداً على ماذا هنا: اللاوسية عرض خريطة السياحة @@ -2843,7 +2843,7 @@ إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة. ابحث عن المسارات مع نقاط الطريق حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق). - نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر علامة. + نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر التوجيه المباشر. يمكنك استيراد المجموعات المفضلة أو نقاط المسار كتوجيه. ستظهر العلامات التي تم تجاوزها على هذه الشاشة. خط مباشر من موقعك إلى الهدف. From 21e7d202052791b5d8cc8a076c2440ee61f5f51a Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:15 +0000 Subject: [PATCH 133/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index b429b3c15d..f47a05d2f6 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1378,7 +1378,7 @@ خامل الرجاء إدخال عنوان بريد إلكتروني صالح أدخل اسم عمومي - شكرا لدعمكم أوسماند! + شكرا لدعمكم أوسماند! \nلتنشيط جميع الميزات الجديدة ، تحتاج إلى إعادة تشغيل أوسماند. إعدادات الاشتراك شريط جانبي @@ -1392,7 +1392,7 @@ قطار المسار الحالي مستوى البطارية - تغيير موقع العلامة + تغيير موقع التوجيه المباشر تابعنا اتجاه صدى الصوت الملاحة عبر أوسماند لايف @@ -1413,7 +1413,7 @@ مظهرالخريطة رقيقة متوسط - أضف علامات عبر الخريطة + لم تضف توجيه مباشر على الخريطة لم يتم العثور على نقاط الطريق التقرير سمح الآن للتطبيق بالكتابة على وحدة التخزين الخارجية. الرجاء إعادة تشغيله يدويا. @@ -1432,7 +1432,7 @@ سيتم إرسال جزء من التبرع إلى مستخدمي OSM الذين يقومون بإرسال التغييرات إلى الخريطة في تلك المنطقة. يرجى شراء اشتراك أوسماند لايف أولا يُتيحُ لك هذا الاشتراك الحصول على التحديثات كُل ساعة لجميع الخرائط حول العالم. -\nجزء من الدخل سيعود إلى مجتمع OSM ويُدفَع لكل مساهمة. +\nجزء من الدخل سيعود إلى مجتمع OSM ويُدفَع لكل مساهمة. \nإن كنت تحب أوسماند وOSM وترغب في الدّعم، هذه هي الطريقة المُثلى للقيام بذلك. وجهات أخرى رفع كمستخدم مجهول @@ -1474,7 +1474,7 @@ حرف غير قانوني في اسم الملف تقرير عن خرائط العالم - حرك الخريطة لتغيير مكان العلامة + حرك الخريطة لتغيير مكان التوجيه المباشر إشارة صوتية عند اتجاه نقطة الوصول. حدد اتجاه النقطة المستهدفة بالاهتزاز. @@ -1490,7 +1490,7 @@ عريض المستخدم المجهول لا يمكنه : \n- إنشاء مجموعة; -\n- مزامنة المجموعات والأجهزة مع السيرفر; +\n- مزامنة المجموعات والأجهزة مع السيرفر; \n- إدارة المجموعات والأجهزة من خلال لوحة تحكم خاصة على الموقع. تطبيق الملاحة أوسماند خطأ أثناء تحميل البيانات من الخادم. @@ -2073,7 +2073,7 @@ اللون والسمك خذ المخرج %1$d ثم واصل المدينة أو المنطقة - مقالات ويكيبيديا القريبة + مقالات ويكيبيديا قريبة استخدام الطرق السريعة السماح للطرق السريعة. الصربية (اللاتينية) From 283f15837048a39f2271184a83f6c374bd700486 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:17 +0000 Subject: [PATCH 134/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index f47a05d2f6..3223e1b6ff 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -628,7 +628,7 @@ حالة وضع السكون استخدمها لتشغيل أوسماند عندما تكون الشاشة مُطفأة. لا يوجد مساحة كافية لتحميل %1$s م.ب المساحة الخالية: %2$s. - تحميل {0} ملف(ات) ؟ + تحميل {0} ملف(ات) ؟ \n مساحة التخزين المستخدمة هي {1} مب (المساحة المتوفرة هي {2} مب). السمة الشفافة المكتبات الأصيلة غير مدعومة على هذا الجهاز. @@ -1438,7 +1438,7 @@ رفع كمستخدم مجهول رفع ملاحظة OSM شريط الأدوات - حدد علامات الخريطة + حدد توجيه مباشرعلى الخريطة ترتيب عكسي تفعيل ميزة العلامات. الأسترية @@ -1592,10 +1592,10 @@ حرك للاسفل اسم مستخدم و كلمة سر OSM نحن بحاجة اليه لكي نوفر لك معلومات حول المساهمات. - اختر علامة + حدد توجيه مباشر عرض شريط الشفافية - لا توجد مساحة كافية! -\n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم. + لا توجد مساحة كافية! +\n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم. \n (فقط {2} ميغابايت المتاحة.) نقطة الانطلاق الصوت @@ -1631,10 +1631,10 @@ الخرائط الموجودة انتقال للأعلى التعديلات %1$s ، الرتبة %2$s ، مجموع التعديلات %3$s - أول علامة - ثاني علامة - إضافة إلى علامات الخريطة - حذف كافة العلامات النشطة على الخريطة؟ + التوجيه المباشرالأول للخريطة + التوجيه المباشرالثاني للخريطة + إضافة إلى التوجيه المباشر + حذف كافة التوجيه المباشرالنشط على الخريطة؟ علامة خريطة عرض المضلعات الحالة @@ -1745,13 +1745,13 @@ الدخول عبر الخريطة عرض عند البدء التأثير النسبي - تحميل {0} ملف؟ + تحميل {0} ملف؟ \nمساحة التخزين المستخدمة هي {3} مب مؤقتة، {1} مب دائمة. (المساحة المتوفرة هي {2} مب.) مسافة المسلك خطأ تحيين القائمة المحلية لPOI. تحيين الPOI قم بتحميل مذكرة OSM الخاصة بك دون الكشف عن هويتك أو باستخدام ملف تعريف OpenStreetMap.org . - إضافة جميع النقاط إلى علامات الخريطة؟ + إضافة جميع النقاط إلى التوجيه المباشر؟ مسح السجلات ؟ إظهار مسارات الدراجة الجبلية يمكنك إزالة التحديثات المحملة والرجوع إلى الإصدار الأصلي للخريطة From 29986743ed149da9d4d5611dcf893f297f55119f Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:17 +0000 Subject: [PATCH 135/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 3223e1b6ff..6f0102bf92 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1613,7 +1613,7 @@ \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية عدد خطوط التوجيه - علامات الخريطة + التوجيه المباشر تخطي الحدود حدد الطرق التي تريد تجنبها أثناء التنقل. الفئات @@ -1635,7 +1635,7 @@ التوجيه المباشرالثاني للخريطة إضافة إلى التوجيه المباشر حذف كافة التوجيه المباشرالنشط على الخريطة؟ - علامة خريطة + توجيه مباشر على الخريطة عرض المضلعات الحالة حفظ التعديلات From dab1fb8da091717ba056a1a6298fe9f226489538 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:20:20 +0000 Subject: [PATCH 136/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 48 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 6f0102bf92..3fcd16c645 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -417,7 +417,7 @@ مساء صباحاً مكان للوقوف - يساعد هذا الملحق بحفظ الأماكن التي ركنت بها سيارتك والوقت المتبقي للركن (في حالة وجود وقت محدد). + يساعد هذا الملحق بحفظ الأماكن التي ركنت بها سيارتك والوقت المتبقي للركن (في حالة وجود وقت محدد). \nكل من المكان والزمن متواجدان على لوحة التحكم وكذلك في المؤشرات على شاشة الخريطة. يمكن إضافة منبه إلى التقويم للتذكير. مكان الموقف موقف السيارة @@ -557,11 +557,11 @@ تقديم الخريطة هل تريد حذف %1$d من التعديلات؟ احذف الكل - يوفر هذا الملحق طبقة خط كنتوري وطبقة للتضاريس ظاهرة على الخريطة الأساسية للتطبيق. هذه الوظيفة ستكون محل تقدير من طرف الرياضيين، المتنزهين، الرحالة، وكل من هو مهتم بجمال ورخاء الطبيعة. -\n + يوفر هذا الملحق طبقة خط كنتوري وطبقة للتضاريس ظاهرة على الخريطة الأساسية للتطبيق. هذه الوظيفة ستكون محل تقدير من طرف الرياضيين، المتنزهين، الرحالة، وكل من هو مهتم بجمال ورخاء الطبيعة. +\n \nالبيانات العالمية (بين 70 درجة شمالا و70 جنوبا) مبنية حسب قياسات SRTM (مكوك رادار البعثة الطبوغرافية) وASTER (المكوك المتقدم الخاص بالانبعاث الحراري والانعكاس الإشعاعي)، أداة تصوير على متن Terra، القمر الصناعي الرئيسي لنظام رصد الأرض التابع لناسا. ASTER هو جهد تعاوني فيما بين وكالة ناسا، وزارة الاقتصاد اليابانية، التجارة والصناعة (METI)، و أنظمة الفضاء اليابانية (J-spacesystems). - يوفر هذا الملحق خطوط كنتورية وطبقة تضاريس (طبيعية) تظهر على خرائط أوسماند. هذه الوظيفة ستعجب كثيرا الرياضيين، المتجولين، الرحالة، و كل من تهمه بنية التضاريس الطبيعية (يرجى ملاحظة أن بيانات الخطوط الكنتورية/أو المساعدة منفصلة ، وتتوفر تنزيلات إضافية بعد تنشيط الملحق.) -\nالبيانات العالمية (ما بين 70 درجة شمالاً و70 جنوباً) مبنية على مقاييس SRTM (مكوك رادار البعثة الطبوغرافية) و ASTER (الانبعاث الحراري الفضائي المتقدم والإنعكاس الإشعاعي)، أداة التصوير على متن Terra، القمر الصناعي الرئيسي لنظام رصد الأرض التابع لناسا. + يوفر هذا الملحق خطوط كنتورية وطبقة تضاريس (طبيعية) تظهر على خرائط أوسماند. هذه الوظيفة ستعجب كثيرا الرياضيين، المتجولين، الرحالة، و كل من تهمه بنية التضاريس الطبيعية (يرجى ملاحظة أن بيانات الخطوط الكنتورية/أو المساعدة منفصلة ، وتتوفر تنزيلات إضافية بعد تنشيط الملحق.) +\nالبيانات العالمية (ما بين 70 درجة شمالاً و70 جنوباً) مبنية على مقاييس SRTM (مكوك رادار البعثة الطبوغرافية) و ASTER (الانبعاث الحراري الفضائي المتقدم والإنعكاس الإشعاعي)، أداة التصوير على متن Terra، القمر الصناعي الرئيسي لنظام رصد الأرض التابع لناسا. \n ASTER هو جهد تعاوني بين كل من وكالة ناسا، وزارة الاقتصاد اليابانية، التجارة والصناعة (METI)، ونظم الفضاء اليابانية (J-spacesystems). أوسماند (اتجاهات التنقل الآلية OSM) \n @@ -585,10 +585,10 @@ \n - لا توجد إمكانية الوصول دون اتصال إلى النقاط المهمة في ويكيبيديا \n \n يجري تطوير أوسماند بنشاط ويعتمد مشروعنا والتقدم المستمر على المساهمات المالية لتطوير واختبار وظائف جديدة. يرجى النظر في شراء أوسماند+ ، أو تمويل ميزات جديدة محددة أو تقديم تبرع عام على https://osmand.net. - هذا الملحق يمكنك من الوصول إلى أنواع عديدة من خرائط النت (تدعى بالقطع أو النقطية)، من قطع OSM مسبقة ( مثل Mapnik) إلى صور أقمار وطبقات مخصصة كخرائط الطقس، الخرائط الجيولوجية، طبقات التضاريس...إلخ. -\n -\nكل من هذه الخرائط يمكن أن تستخدم إما كخرائط رئيسية (قاعدية) تظهر على واجهة التطبيق، أو كطبقة فوقية أو تحتية لخريطة قاعدية آخرى( كخرائط التطبيق المحلية). لجعل أي طبقة تحتية خريطة أكثر وضوحا، بعض عناصر خرائط التطبيق التوجيهيه يمكن إخفاءها في قائمة \'ضبط الخريطة\' حسب الرغبة. -\n + هذا الملحق يمكنك من الوصول إلى أنواع عديدة من خرائط النت (تدعى بالقطع أو النقطية)، من قطع OSM مسبقة ( مثل Mapnik) إلى صور أقمار وطبقات مخصصة كخرائط الطقس، الخرائط الجيولوجية، طبقات التضاريس...إلخ. +\n +\nكل من هذه الخرائط يمكن أن تستخدم إما كخرائط رئيسية (قاعدية) تظهر على واجهة التطبيق، أو كطبقة فوقية أو تحتية لخريطة قاعدية آخرى( كخرائط التطبيق المحلية). لجعل أي طبقة تحتية خريطة أكثر وضوحا، بعض عناصر خرائط التطبيق التوجيهيه يمكن إخفاءها في قائمة \'ضبط الخريطة\' حسب الرغبة. +\n \nأجزاء الخرائط يمكن الحصول عليها من مصادر إنترنت، أو تحضيرها للإستخدام دون إنترنت ( ونسخها يدويا إلى مجلد بيانات التطبيق) كقاعدة بيانات SQLite والتي يمكن إنتاجها عن طريق مجموعة متنوعة من أدوات تحضير الخرائط المستقلة. التغييرات POI داخل التطبيق لا تؤثرعلى ملفات الخرائط المحملة، يتم حفظ التغييرات إلى ملف محلي بدلا من ذلك. وضع تركيز الكاميرا: @@ -933,7 +933,7 @@ زيارة بعد زيارة قبل محاكاة تخيلية - خط العرض %1$s + خط العرض %1$s \nخط الطول %2$s الأسئلة الشائعة، التغييرات الحديثة، وأخرى. إعدادات الملاحة @@ -1025,8 +1025,8 @@ فشل في إعادة التسمية. عودة إلى الخريطة شارك ملاحظة - الموقع: -\n Lat %1$s + الموقع: +\n Lat %1$s \n Lon %2$s ملاحظات خريطة إنترنت @@ -1606,10 +1606,10 @@ الزمن : انعطف يميناً انعطف يسارا واذهب - هذا الملحق يوفير خرائط بحرية للزوارق والمراكب الشراعية وأنواع أخرى من الرياضات المائية. -\n -\nخريطة خاصة إضافية للتطبيق ستقدم كل علامات الملاحة البحرية سواء داخلية أو شاطئية وكذلك جدول للرموز. وصف كل وجهة ملاحة يوفر التفاصيل اللازمة للتعرف عليها ومعانيها (الفئة، الشكل، اللون، التسلسل، المرجع...إلخ.). -\n + هذا الملحق يوفير خرائط بحرية للزوارق والمراكب الشراعية وأنواع أخرى من الرياضات المائية. +\n +\nخريطة خاصة إضافية للتطبيق ستقدم كل علامات الملاحة البحرية سواء داخلية أو شاطئية وكذلك جدول للرموز. وصف كل وجهة ملاحة يوفر التفاصيل اللازمة للتعرف عليها ومعانيها (الفئة، الشكل، اللون، التسلسل، المرجع...إلخ.). +\n \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة. البحث قرب مركز الخريطة الحالية عدد خطوط التوجيه @@ -1657,7 +1657,7 @@ اختر التوجيه الصوتي اختر أو قم بتحميل التوجيه الصوتي الخاص بلغتك. منح الوصول إلى بيانات الموقع. - طرق الخيول + مسارات الخيول إخفاء جودة أقل أعلى جودة @@ -1870,7 +1870,7 @@ تلوين وفق الانتماء للشبكة تلوين وفق رمز تنزه OSMC خروج - حذف الملاحظات %1$d؟ + هل أنت متأكد من أنك تريد حذف الملاحظات %1$d؟ لعرض الخرائط البحرية، يجب تحميل خريطة خاصة محلياً. تسجيل الموقع العام إلى ملف GPX يمكن تشغيله أو إيقافه باستخدام نافذة تسجيل GPX على الشاشة خريطة. ضبط اسم مضيف البروكسي (مثال 127.0.0.1). @@ -1891,8 +1891,8 @@ أخرى %1$s %2$s عنصر ؟ البيانات الجغرافية المؤقتة - هذا الملحق يفعل وظيفة تسجيل وحفظ المسارات الخاصة بك عبر الضغط على نافذة GPX على شاشة الخريطة، أو كذلك تسجيل كافة طرق الملاحة الخاص بك تلقائيا إلى ملف GPX. -\n + هذا الملحق يفعل وظيفة تسجيل وحفظ المسارات الخاصة بك عبر الضغط على نافذة GPX على شاشة الخريطة، أو كذلك تسجيل كافة طرق الملاحة الخاص بك تلقائيا إلى ملف GPX. +\n \nالمسارات المسجلة يمكن مشاركتها مع أصدقائك أو استخدامها كمساهمات ل OSM . الرياضيون يمكنهم استخدام المسارات المسجلة لمتابعة تدريباتهم. بعض تحليل المسار الابتدائية يمكن القيام بها مباشرة في التطبيق، مثل توقيت الدورات، ومتوسط السرعة...الخ، و يمكن أيضا تحليل المسارات باستعمال أدوات تحليل جانبية لاحقا. أوسماند ليس لديه إذن لاستخدام ذاكرة البطاقة هل تريد حقا حفظ POI بدون تحديد نوعه؟ @@ -1990,8 +1990,8 @@ يرجى تفعيل ملحق المعالم البحرية %1$.1f من %2$.1f مب %.1f مب - يضع هذا الملحق بين يديك تفاصيل منحدرات تزلج عالمية، مسارات تزلج عبر كامل البلاد، التلفريك ومصاعد التزلج. الطرقات والمعابر مبينة بألوان حسب الصعوبة، -\n + يضع هذا الملحق بين يديك تفاصيل منحدرات تزلج عالمية، مسارات تزلج عبر كامل البلاد، التلفريك ومصاعد التزلج. الطرقات والمعابر مبينة بألوان حسب الصعوبة، +\n \nومصورة بنمط خريطة مميز \'شتوي\' تمثل مناظر الطبيعة بلون مثلج شتوي. أشياء فوق سطح الأرض تغيير @@ -2163,7 +2163,7 @@ قم بالضغط على الزر لفترة أطوَل ثم اسحبه لتغيير مكانه على الشاشة. معالم العمق البحري تقسيم المسارات آلياً إلى أجزاء بعد كل فراغ - تقصير رمز التموضع المفتوح + تقصير رمز التموضع المفتوح \n يُرجى تقديم رمزٍ كامل اسم الاختصار السريع مكرر سوف تكون تتمة هذه الرسالة تلقائية في المجال المخصص للتعليق. @@ -2419,7 +2419,7 @@ اسم الاختصار السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار. الضغط على زر الإجراء سيطبق أحد الأنماط من القائمة أدناه. تنقلاتك على هذا الطريق - OLC الصالحة بالكامل\nتمثل المنطقة: %1$s x %2$s + OLC الصالحة بالكامل تمثل المنطقة: %1$s x %2$s اسم المستخدم خاطئ إلى مِن From c267e35b145256dc0ed1eede87f844d63a64a373 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:18 +0000 Subject: [PATCH 137/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 3fcd16c645..accf0baef2 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1832,7 +1832,7 @@ ملاحظة OSM معلق عليها مسار زلق لإظهار خرائط التزلج، يجب تحميل خريطة خاصة محلية. - حافلة، عربة وغيرها + حافلة، ترامواي وغيرها إنشاء ملاحظة OSM حدث استثناء: لم يتم إنشاء الملاحظة. حدث استثناء: لم يتم غلق الملاحظة. From c71b6bdae9695d29363a747c93039b0347b06680 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:19 +0000 Subject: [PATCH 138/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index accf0baef2..bbda174f77 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1172,7 +1172,7 @@ طرق الحافلات الكهربائية طرق الحافلات سكك قطار الأنفاق - تاكسي مشاركة الطرق + شارك طرق التاكسي حدد حد السرعة المسموح به لتلقي تنبيه صوتي إذا ما تجاوزته. مراقبة الحدود كشك الرسوم From 12a277a226d5ad17943799299cc2b5ab6077dc89 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:19 +0000 Subject: [PATCH 139/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index bbda174f77..b149bdab61 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1073,7 +1073,7 @@ تجنب الطرق… طرق السكك الحديدية خطوط الترام - الطرق + المسارات الرياضية وسائل المواصلات سمات أخرى للخريطة العناصر الأخرى From 768bf89dcb61931603b9a5d634cedda24e022f7b Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:20 +0000 Subject: [PATCH 140/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index b149bdab61..fd131b6a8c 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -979,7 +979,7 @@ مصدر الخريطة عرض أسماء المفضلة لغة الخريطة - التفاصيل + تفاصيل إضافية الوقت الحالي اتجاه الخريطة اتجاه الحركة في الأعلى From 8d8f526cf324ad3bec2b32192af80c32a5026f7e Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:23 +0000 Subject: [PATCH 141/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 118 +++++++++++++++---------------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index fd131b6a8c..e79e7ddea5 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -329,7 +329,7 @@ نسخ الاحتياطي كتعديل OSM %1$d ملف بقى يظهر الإعدادات لتمكين التتبع والملاحة في وضعية السكون ( الشاشة مغلقة ) عبر إيقاظ دوري لجهاز GPS. - حساب الطرق بدقة دون أخطاء. لا يزال محدود المسافة وبطيء. + تمكين لحساب المسارات بدقة دون أخطاء. لا يزال محدود المسافة وبطيء. صورة %1$s %2$s مزامنة المسارات والملاحظات الصوتية / الفيديو مع حساب Dropbox الخاص بك. تنسيق الفيديو الناتج: @@ -372,9 +372,9 @@ مسطرة عرض الاتجاه عدادات شفافة - تشغيل + تشغيل \n التطبيق في الخلفية - إيقاف + إيقاف \n التشغيل في الخلفية الاختصارات أين أنا @@ -497,9 +497,9 @@ تركيز تلقائي التركيز البؤري نوع الكاميرا - * انقر لتحديد نقطة. -\n  * اضغط لفترة طويلة على الخريطة لحذف النقطة السابقة. -\n  * اضغط لفترة طويلة على نقطة لعرض وإرفاق الوصف. + * انقر لتحديد نقطة. +\n  * اضغط لفترة طويلة على الخريطة لحذف النقطة السابقة. +\n  * اضغط لفترة طويلة على نقطة لعرض وإرفاق الوصف. \n  * اضغط على أداة القياس لمعرفة المزيد من الإجراءات. طبقة التضاريس طبقة التضاريس @@ -546,7 +546,7 @@ اختيار المسار النشط الحالي اختيار مسار محفوظ تذكر اختياري - إجمالي الذاكرة الأصلية المخصصة من قبل التطبيق %1$s م.ب (دلفيك %2$s م.ب, أخرى %3$s م.ب). + إجمالي الذاكرة الأصلية المخصصة من قبل التطبيق %1$s م.ب (دلفيك %2$s م.ب, أخرى %3$s م.ب). \nالذاكرة النسبية %4$s م.ب (حد الأندرويد %5$s م.ب, دلفيك %6$s م.ب). مشي دراجة نارية @@ -592,23 +592,21 @@ \nأجزاء الخرائط يمكن الحصول عليها من مصادر إنترنت، أو تحضيرها للإستخدام دون إنترنت ( ونسخها يدويا إلى مجلد بيانات التطبيق) كقاعدة بيانات SQLite والتي يمكن إنتاجها عن طريق مجموعة متنوعة من أدوات تحضير الخرائط المستقلة. التغييرات POI داخل التطبيق لا تؤثرعلى ملفات الخرائط المحملة، يتم حفظ التغييرات إلى ملف محلي بدلا من ذلك. وضع تركيز الكاميرا: - أوسماند+ (OSM اتجاهات التنقل التلقائية) -\n -\n عبارة عن تطبيق ملاحة مفتوح المصدر مع إمكانية الوصول إلى العديد من بيانات عالمية للموقع. كل بيانات الخرائط (خرائط التوجيه أو الخرائط الجزئية) يمكن تخزينها في ذاكرة الجهاز للإستخدام دون إنترنت. يوفر التطبيق كذلك وظائف توجيه بما في ذلك التوجيه الصوتي. -\n -\nبعض الميزات الأساسية: -\n - تشغيل كامل دون إنترنت( خزن خرائط التوجيه أو الخرائط الجزئية المنزلة في ذاكرة الجهاز) -\n - خرائط التوجيه المدمجة للعالم ككل متاحة لتعمل دون إنترنت -\n - تحميل غير محدود لخرائط البلدان أو المناطق مباشرة من التطبيق -\n - ميزة ويكيبيديا المحلية ( قم بتحميل نقاط الاهتمام لويكيبيديا)، الأمثل لمشاهدة المعالم الأثرية -\n - يمكن تراكب عدة طبقات للخرائط، ك GPX أو مسارات الملاحة، مواقع ذات الاهتمام ، الأماكن المفضلة، الحدود الكنتورية، أماكن توقف النقل العمومي، خرائط إضافية بشفافية قابلة للتعديل -\n - البحث عن العناوين وأماكن الاهتمام دون إنترنت -\n -\n - تحديد الطريق لمسافات متوسطة المدى -\n - وضع السيارة، الدراجة والمشاة متوفر مع: -\n - تبديل اختياري آلي لوضع الرؤية في الليل/النهار -\n - تكبير اختياري حسب السرعة -\n - محاذاة اختيارية للخريطة حسب البوصلة أو اتجاه الحركة + أوسماند+ (OSM اتجاهات التنقل التلقائية) +\n عبارة عن تطبيق ملاحة مفتوح المصدر مع إمكانية الوصول إلى العديد من بيانات عالمية للموقع. كل بيانات الخرائط (خرائط التوجيه أو الخرائط الجزئية) يمكن تخزينها في ذاكرة الجهاز للإستخدام دون إنترنت. يوفر التطبيق كذلك وظائف توجيه بما في ذلك التوجيه الصوتي. +\n +\nبعض الميزات الأساسية: +\n - تشغيل كامل دون إنترنت( خزن خرائط التوجيه أو الخرائط الجزئية المنزلة في ذاكرة الجهاز) +\n - خرائط التوجيه المدمجة للعالم ككل متاحة لتعمل دون إنترنت +\n - تحميل غير محدود لخرائط البلدان أو المناطق مباشرة من التطبيق +\n - ميزة ويكيبيديا المحلية ( قم بتحميل نقاط الاهتمام لويكيبيديا)، الأمثل لمشاهدة المعالم الأثرية +\n - يمكن تراكب عدة طبقات للخرائط، ك GPX أو مسارات الملاحة، مواقع ذات الاهتمام ، الأماكن المفضلة، الحدود الكنتورية، أماكن توقف النقل العمومي، خرائط إضافية بشفافية قابلة للتعديل +\n - البحث عن العناوين وأماكن الاهتمام دون إنترنت +\n - تحديد الطريق لمسافات متوسطة المدى +\n - وضع السيارة، الدراجة والمشاة متوفر مع: +\n - تبديل اختياري آلي لوضع الرؤية في الليل/النهار +\n - تكبير اختياري حسب السرعة +\n - محاذاة اختيارية للخريطة حسب البوصلة أو اتجاه الحركة \n - توجيه اختياري للممر، عرض الحد الأقصى للسرعة، أصوات TTS (نص إلى كلام) أو أخرى مسجلة \n {0} POI/الملاحظات تم رفعها @@ -880,7 +878,7 @@ تجنب العبارات وزن المركبة منذ نسخة أندرويد كتكات 4.4، لا يمكنك تحميل أو تحديث الخرائط في مكان التخزين السابق (%s). هل تريد التغيير إلى مكان مسموح ونسخ كل الملفات إليه ؟ ملاحظات: 1-الملفات القديمة ستبقى كما هي (يمكن حذفها يدويا). -\n +\n \n2-لايمكن مشاركة الملفات بين أوسماند و +أوسماند في مكان التخزين الجديد. ينسخ الملف (%s) إلى مساره الجديد… تنبيه الوصول @@ -1186,7 +1184,7 @@ قيود الدخول عرض قيود الدخول عرض سطح الطريق - إظهار طرق الدراجات + إظهار مسارات الدراجات بدء التوجيه المفصل تلقائياً مسارات فرعية: %1$s نقاط الطريق: %1$s @@ -2313,8 +2311,8 @@ بدء مقطع جديدة بعد فارق 6 دقائق، مسار جديد بعد فارق 2 ساعة، أو ملف جديد بعد فارق أطول إذا تغير التاريخ. متوقف مؤقتاً قد يكون المسار طويلا جدا للحساب. يرجى إضافة وجهات وسطى إذا لم يتم العثور على نتيجة خلال 10 دقائق. - أوسماند(توجيهات OSM للتنقل الآلية) تطبيق خريطة وتنقل مع إمكانية الوصول إلى بيانات (OSM) مجاناً وفي جميع أنحاء العالم، وبجودة عالية -\n + أوسماند(توجيهات OSM للتنقل الآلية) تطبيق خريطة وتنقل مع إمكانية الوصول إلى بيانات (OSM) مجاناً وفي جميع أنحاء العالم، وبجودة عالية +\n \n. استمتع بمستكشف بالصوت والصورة، وعرض (نقاط الاهتمام)، إنشاء وإدارة مسارات GPX، استخدام عرض ارتفاع بيانات الخطوط الكنتورية(عن طريق الملحق)، اختيار بين نمط القيادة، ركوب الدراجات والمشاة، التعديل على الموقع وغيرها. التنقل عبر GPS \n• يمكنك أن تختار بين وضع دون اتصال (لا رسوم تجوال عندما تكون في الخارج) أو بالإنترنت (أسرع) @@ -2330,20 +2328,20 @@ \n خريطة \n• \"عرض النقاط POI\" (نقطة اهتمام) من حولك -\n• ضبط الخريطة اتجاه الحركة أو (البوصلة) +\n• ضبط الخريطة اتجاه الحركة أو (البوصلة) \n• إظهار مكانك الحالي وما يقابلك \n• مشاركة موقعك حتى يتسنى لأصدقاء إيجادك \n• الاحتفاظ بأهم الأماكن في المفضلة \n• يسمح لك باختيار كيفية عرض الأسماء على الخريطة: باللغة الإنجليزية، اللغة المحلية أو حسب الإملاء الصوتي \n• إظهار نمط خريطة إنترنت متخصص ، صورة قمر صناعي (بينج)، إظهار طبقات خريطة متراكبة مختلفة كالسياحة/مسارات GPX للملاحة وطبقات إضافية مع شفافية قابلة للتعديل \n - التزلج + التزلج \nملحق خرائط أوسماند للتزلج يمكنك من مشاهدة مسارات التزلج مع مستوى من التعقيد وبعض المعلومات الإضافية، كمواقع المصاعد والمرافق الأخرى. - ركوب الدراجات الهوائية -\n• العثورعلى مسار دراجات على الخريطة -\n• التنقل في وضع ركوب الدراجات تقترح لك مسار دراجات -\n• يمكنك مشاهدة سرعتك وارتفاعك -\n• خيار تسجيل GPX يتيح لك تسجيل رحلتك ومشاركتها + ركوب الدراجات الهوائية +\n• العثورعلى مسار دراجات على الخريطة +\n• التنقل في وضع ركوب الدراجات تقترح لك مسار دراجات +\n• يمكنك مشاهدة سرعتك وارتفاعك +\n• خيار تسجيل GPX يتيح لك تسجيل رحلتك ومشاركتها \n• عبر ملحق إضافي يمكنك عرض الخطوط الكنتورية والتضاريس المشي، التنزه، جولة في المدينة \n• الخريطة تظهر لك ممرات المشي والتنزه @@ -2366,34 +2364,34 @@ \n• أنتاركتيكا: * \nمعظم البلدان في جميع أنحاء العالم متاحة للتحميل! \nاحصل على برنامج تنقل موثوق به في بلدك - سواءاً في فرنسا، ألمانيا، المكسيك، المملكة المتحدة، إسبانيا، هولندا، الولايات المتحدة الأمريكية، روسيا، البرازيل أو أي دولة أخرى. - أوسماند بلس (توجيهات OSM للملاحة الآلية) تطبيق خريطة وملاحة مع إمكانية الوصول إلى بيانات الموقع مجاناً وفي جميع أنحاء العالم، وبجودة عالية. -\nاستمتع بالملاحة بصوت والصورة، عرض النقاط المهمة حولك (POI)، وإنشاء وإدارة مسارات GPX باستخدام معلومات عن تصور وعلو الخطوط الكنتورية، خياراً بين القيادة، ركوب الدراجات، وضع المشاة، التعديل على OSM وأكثر من ذلك بكثير. -\n -\nأوسماند بلس هو إصدار للتطبيق مدفوع الأجر. قبل شرائه، ادعم المشروع، بتمويل لتطوير الميزات الجديدة والحصول على آخر التحديثات. -\n + أوسماند بلس (توجيهات OSM للملاحة الآلية) تطبيق خريطة وملاحة مع إمكانية الوصول إلى بيانات الموقع مجاناً وفي جميع أنحاء العالم، وبجودة عالية. +\nاستمتع بالملاحة بصوت والصورة، عرض النقاط المهمة حولك (POI)، وإنشاء وإدارة مسارات GPX باستخدام معلومات عن تصور وعلو الخطوط الكنتورية، خياراً بين القيادة، ركوب الدراجات، وضع المشاة، التعديل على OSM وأكثر من ذلك بكثير. +\n +\nأوسماند بلس هو إصدار للتطبيق مدفوع الأجر. قبل شرائه، ادعم المشروع، بتمويل لتطوير الميزات الجديدة والحصول على آخر التحديثات. +\n \n بعض الميزات الرئيسية: - الملاحة + الملاحة \n• يعمل على الإنترنت (سريع) أو في وضع غير متصل (لا رسوم تجوال خارج الوطن) \n• توجيه صوتي بالتفصيل (الأصوات المسجلة أو مدرجة) \n• موجه مسار اختياري، عرض اسم الشارع، والوقت المقدر للوصول \n• يدعم نقاط وسيطة خلال مسارك \n• إعادة تلقائية للتوجيه كلما انحرفت عن الطريق \n• البحث عن الأماكن حسب العنوان، النوع (مثل: مطعم، فندق، محطة وقود، متحف)،أو حسب الإحداثيات الجغرافية - عرض الخريطة -\n• عرض موقعك والتوجيه -\n• محاذاة اختيارية للصورة وفق البوصلة أو توجيه الحركة -\n• حفظ أهم أماكنك المفضلة -\n• عرض نقاط الاهتمام من حولك -\n• عرض متخصص لبيانات خرائط على الإنترنت، الرؤية من الأقمار الصناعية (من بينج) وتراكب طبقات خرائط مختلفة كالسياحة ومسارات GPX للملاحة وطبقات إضافية مع شفافية قابلة للتعديل + عرض الخريطة +\n• عرض موقعك والتوجيه +\n• محاذاة اختيارية للصورة وفق البوصلة أو توجيه الحركة +\n• حفظ أهم أماكنك المفضلة +\n• عرض نقاط الاهتمام من حولك +\n• عرض متخصص لبيانات خرائط على الإنترنت، الرؤية من الأقمار الصناعية (من بينج) وتراكب طبقات خرائط مختلفة كالسياحة ومسارات GPX للملاحة وطبقات إضافية مع شفافية قابلة للتعديل \n• عرض اختياري لأسماء الأماكن باللغة الإنكليزية، اللغة المحلية، أو عبر الإملاء الصوتي \n - استخدام OSM وبيانات ويكيبيديا -\n• جودة معلومات من أفضل المشاريع التعاونية العالمية -\n• بيانات OSM متاحة لكل بلد أو منطقة -\n• POI ويكيبيديا، الأفضل لمشاهدة المعالم السياحية -\n• التنزيلات مجانية غير محدودة، مباشرة من التطبيق -\n• خرائط فيكتور مدمجة تحدث مرة واحدة في شهر على الأقل -\n + استخدام OSM وبيانات ويكيبيديا +\n• جودة معلومات من أفضل المشاريع التعاونية العالمية +\n• بيانات OSM متاحة لكل بلد أو منطقة +\n• POI ويكيبيديا، الأفضل لمشاهدة المعالم السياحية +\n• التنزيلات مجانية غير محدودة، مباشرة من التطبيق +\n• خرائط فيكتور مدمجة تحدث مرة واحدة في شهر على الأقل +\n \n• اختر بين بيانات منطقة كاملة أو شبكة الطرق فقط (مثال: سعة اليابان 700 MB في حين 200 MB لشبكة الطرق فقط) ميزات الأمان \n• عرض اختياري لوضع النهار/اليل @@ -2401,12 +2399,12 @@ \n• تكبير/تصغيير اختياري حسب السرعة \n• مشاركة موقعك حتى يتمكن لأصدقاءك ايجادك \n - ميزات الدراجة والمشاة -\n • عرض ممرات المشاة، التنزه، وأنشطة الهواء الطلق -\n • توجيه متخصص وعرض طرق خاصة باللدراجات الهوائية والمشاة -\n • محطات نقل عام اختيارية (حافلات، الترامواي، القطار) بما في ذلك أسماء خطوط النقل -\n • تسجيل رحلة اختياري إلى ملف GPX محلي أو لخدمة على الإنترنت -\n • عرض اختياري للسرعة والارتفاع + ميزات الدراجة والمشاة +\n • عرض ممرات المشاة، التنزه، وأنشطة الهواء الطلق +\n • توجيه متخصص وعرض طرق خاصة باللدراجات الهوائية والمشاة +\n • محطات نقل عام اختيارية (حافلات، الترامواي، القطار) بما في ذلك أسماء خطوط النقل +\n • تسجيل رحلة اختياري إلى ملف GPX محلي أو لخدمة على الإنترنت +\n • عرض اختياري للسرعة والارتفاع \n • عرض الخطوط الكنتورية والتضاريس (عن طريق برامج ملحق إضافي) المساهمة مباشرة في OSM \n• الابلاغ عن الأخطاء في البرنامج From ac284c49d901dc2a795d995c6f2d64bf6144b0ca Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:23 +0000 Subject: [PATCH 142/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index e79e7ddea5..6cfa74a29d 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -471,7 +471,7 @@ إفريقيا آسيا أستراليا و أوقيانوسيا - التوجيه + التوجيه مع الطرق ضبط خاص لكل وضع من أوضاع الملاحة. إدارة بيانات الخرائط إعدادات عامة @@ -721,8 +721,8 @@ عكس اتجاه المسار استخدم الوجهة الحالية يمر على طول المسار باكمله - خريطة التنقل متوفرة لهذا الموقع فعلها عبر -\n + خريطة التنقل متوفرة لهذا الموقع فعلها عبر +\n \n\'القائمة\' ← \'ضبط الخريطة\' ← \'مصدر الخريطة\' ← \'الخريطة المحملة\'. مصدر التوجيه الصوتي اختيار قناة لتشغيل التوجيه الصوتي. From 8c3bc0d36843f193b129a6b122f6f238411b59dd Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:24 +0000 Subject: [PATCH 143/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 6cfa74a29d..befbe065ae 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -770,7 +770,7 @@ ميل ساعة ميل شارك المكان باستخدام - الموقع: %1$s + الموقع: %1$s \n%2$s إتبع رابط متصفح الويب لمشاهدة المكان %1$s أو استعمل رابط أندرويد الخاص %2$s إرسال الموقع @@ -992,7 +992,7 @@ تسجيل المسار اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة صوت مسج - الاتجاهات + التوجيه مع الطرق استخدام الموقع… مفضلة نقاط مفضلة مجاورة @@ -1895,8 +1895,8 @@ أوسماند ليس لديه إذن لاستخدام ذاكرة البطاقة هل تريد حقا حفظ POI بدون تحديد نوعه؟ هناك خيار جديد لتحكم بشكل مرن بالتطبيق عبر لوحة القياس أو القائمة الثابتة. اختيارك يمكن تغييره دائما في إعدادات لوحة القياس. - ملاحة أوسماند دون نت ميزة تجريبية وهي لا تعمل لمسافات تزيد عن 20 كم. -\n + ملاحة أوسماند دون نت ميزة تجريبية وهي لا تعمل لمسافات تزيد عن 20 كم. +\n \n خدمة الملاحة حولت مؤقتا إلى CloudMade على الإنترنت. إصدار {0} تثبيت بنجاح ({1}). جار تحميل الإصدار… @@ -1969,7 +1969,7 @@ البيانات الصوتية المحددة تالفة بطاقة الذاكرة غير متاحة. \nلن تكون قادرا على رؤية الخرائط أو العثور على أماكن. - بطاقة الذاكرة في وضع القراءة فقط. + بطاقة الذاكرة في وضع القراءة فقط. \n يمكنك فقط مشاهدة الخريطة المحملة مسبقاً ولا يمكنك التحميل من الإنترنت. انعطف يميناً بشكل حاد انعطف يساراً بشكل حاد @@ -1979,7 +1979,7 @@ المسار اللاحق للرحلة حساب الجزء الأول فقط من الطريق للرحلات الطويلة. إلغاء - خرائط محلية + خرائط محلية \nوملاحة إنشاء إحداثية POI عدد الصفوف في الدفعة %1$s @@ -2088,7 +2088,7 @@ إجراءات سريعة إجراء %d شاشة %d - إضافة علامة خريطة + إضافة توجيه مباشر للخريطة إضافة POI نمط الخريطة نمط الخرائط تغير ل \"%s\". @@ -3354,8 +3354,8 @@ لوحة المفاتيح وندرلينك ببغاء - المسار: المسافة%1$s، الوقت %2$s. -\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب + المسار: المسافة%2$s، وقت التوجيه %1$s. +\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب) الأوكيتانية ثم %1$s تطبيق فقط على \"%1$s\" From 8e8928a3af53c50009c28148fab6e9c318574f54 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:25 +0000 Subject: [PATCH 144/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index befbe065ae..e9a9b1e536 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3327,7 +3327,7 @@ طرق لجولات التزلج. تزلج منحدرات لاستخدام الزلاجات. - السماح بالطرق المتوسطة + السماح بالمسارات المتوسطة طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات ينبغي تجنبها. السماح للطرق المتقدمة طرق صعبة ، مع عقبات خطيرة وأقسام شديدة الانحدار. From c78b03515f601c3971e3fc4dc8865e56b46e89dd Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:25 +0000 Subject: [PATCH 145/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index e9a9b1e536..ab52475a31 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3328,7 +3328,7 @@ تزلج منحدرات لاستخدام الزلاجات. السماح بالمسارات المتوسطة - طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات ينبغي تجنبها. + طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات التي ينبغي تجنبها. السماح للطرق المتقدمة طرق صعبة ، مع عقبات خطيرة وأقسام شديدة الانحدار. السماح بطرق المتخصصين From 16c8f713c1ba3087d1400c4e07c3155aebdddef7 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 9 Feb 2021 23:22:39 +0000 Subject: [PATCH 146/398] Translated using Weblate (Hebrew) Currently translated at 99.9% (3660 of 3661 strings) --- OsmAnd/res/values-iw/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index d91880e6d1..02eb125d47 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3970,7 +3970,7 @@ בחירת תקינה נא לבחור תיקייה או להוסיף אחת חדשה ריק - ניתוח לפי מרווחים (פיצול מרווחים) + ניתוח מרווחי פיצול העלאה ל־OpenStreetMap עריכת מסלול שינוי שם מסלול @@ -4016,4 +4016,11 @@ OpenPlaceReviews להשתמש ב־test.openplacereviews.org כניסה ל־OpenPlaceReviews + זמן ההכרזה של ההנחיות הקוליות השונות תלוי בסוג ההכרזה, במהירות הניווט הנוכחית ובמהירות הניווט כבררת מחדל. + הצללה / מדרון / קווי מתאר + OpenPlaceReviews הוא מיזם בהובלת הקהילה בנוגע למקומות ציבוריים כגון מסעדות, מלונות, מוזיאונים ונקודות דרך. הוא אוסף מידע ציבורי עליהם כגון תמונות, סקירות, קישורים למערכות אחרות שמקושרות ל־OpenStreetMap, ויקיפדיה. +\n +\nכל הנתונים של OpenPlaceReview הם פתוחים וזמינים לציבור הרחב: http://openplacereviews.org/data. +\n +\nניתן לקרוא עוד באתר: http://openplacereviews.org \ No newline at end of file From fc808871882b3ce7823cc8f9a5f56de80010af97 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 09:21:26 +0000 Subject: [PATCH 147/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3661 of 3661 strings) --- OsmAnd/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index ab52475a31..6952e1c6c8 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3334,7 +3334,7 @@ السماح بطرق المتخصصين طرق صعبة للغاية ، مع عقبات خطيرة والمناطق المحيطة بها. السماح بالتزلج على الطرق فقط - طرق مصممة للأسلوب الحر أو التزلج فقط بدون المسارات الكلاسيكية. + الطريق مصممة خصيصا بحرية أو التزلج على الجليد. السماح للطرق الكلاسيكية فقط تم إعداد الطرق للأسلوب الكلاسيكي فقط دون مسارات التزلج. يشمل ذلك الطرق التي يتم إعدادها بواسطة عربة ثلجية أصغر مع زحلقة مرنة ومسارات مصنوعة يدوياً بواسطة المتزلجين. الصعوبة المفضلة From a9cc73f3fa74b8b039240e8c90f910a064bd4a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Tue, 9 Feb 2021 17:58:50 +0000 Subject: [PATCH 148/398] Translated using Weblate (Hungarian) Currently translated at 99.9% (3889 of 3891 strings) --- OsmAnd/res/values-hu/phrases.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml index b4ca7f9b08..b8a0cd6817 100644 --- a/OsmAnd/res/values-hu/phrases.xml +++ b/OsmAnd/res/values-hu/phrases.xml @@ -54,7 +54,7 @@ Autógumi-szerelő Autómosó Benzinkút;Töltőállomás;Gázolajtöltő-állomás - Elektromos töltőállomás + Elektromos töltőállomás;Elektromos autó töltése;Villanyautó töltése;Elektromos töltőpont Sűrített levegő Parkoló Motorkerékpár-parkoló @@ -3879,4 +3879,14 @@ Denevéralagút Denevérhíd Vadátjáró + Csúcsnapló nincs + Csúcsnapló van + Hegyi mentő nincs + Hegyi mentő van + Erdei pálya + Mozgó könyvtár tartózkodási helye + Pálya állapota: zárva + Pálya állapota: nyitva + Pálya neve + Síugrósánc \ No newline at end of file From 162182a8ee2b91af8efad9d04ed4b7e7985fdf01 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 12:30:09 +0200 Subject: [PATCH 149/398] fix for future use when new track recording starts --- .../net/osmand/plus/track/GpxBlockStatisticsBuilder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 2f11a6136a..7d7b911078 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -100,12 +100,15 @@ public class GpxBlockStatisticsBuilder { GPXFile gpxFile = getGPXFile(); GpxDisplayItem gpxDisplayItem = null; GPXTrackAnalysis analysis = null; + boolean withoutGaps = false; if (gpxFile.tracks.size() > 0) { gpxDisplayItem = getDisplayItem(gpxFile); - analysis = gpxDisplayItem.analysis; } - if (gpxDisplayItem != null && analysis != null) { - boolean withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack(); + if (gpxDisplayItem != null) { + analysis = gpxDisplayItem.analysis; + withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack(); + } + if (analysis != null) { float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); From 32509e40ced42d824bfe59b9d91601191aea43a1 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 10 Feb 2021 12:33:57 +0200 Subject: [PATCH 150/398] scrollbars="none" --- OsmAnd/res/layout/wpt_list_item.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/layout/wpt_list_item.xml b/OsmAnd/res/layout/wpt_list_item.xml index db24c056ac..1c018bd5d7 100644 --- a/OsmAnd/res/layout/wpt_list_item.xml +++ b/OsmAnd/res/layout/wpt_list_item.xml @@ -103,6 +103,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="2" + android:scrollbars="none" android:textColor="@color/wikivoyage_secondary_text" android:textSize="@dimen/default_sub_text_size" osmand:typeface="@string/font_roboto_regular" From aa81622bb90318020c084174199ccad9fbfd73ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 10 Feb 2021 10:25:03 +0000 Subject: [PATCH 151/398] Translated using Weblate (Turkish) Currently translated at 100.0% (3674 of 3674 strings) --- OsmAnd/res/values-tr/strings.xml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 1f9d208ac4..cdb2e6571f 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -2227,7 +2227,7 @@ İşaretleyicilerinizi şu GPX dosyasına aktarın: Haritada yön gösterici okları göster OsmAnd seçilmiş profil için rotalı noktalara bağlanacak. - Lütfen en az bir nokta ekleyiniz. + Lütfen en az bir nokta ekleyin. Haritayı görüntüle ve nokta ekle Kaydedilmiş izlenen yolları aylık klasörlerde depola Resimleri göndericiye, tarihe ya da türüne göre filtreleyin. Sadece yakın mesafe yakınlaştırmasında etkin. @@ -3738,7 +3738,7 @@ Koyu Son düzenleme Yolu içe aktar - Mevcut yolu aç + Var olan yolu aç Yeni güzergah oluştur Açmak için bir yol dosyası seçin. Bitti @@ -3968,7 +3968,7 @@ Klasör seç Klasör seçin veya yeni bir tane ekleyin Boş - Aralıklara göre analiz et (bölme aralığı) + Bölünmüş aralıkları analiz et OpenStreetMap\'e yükle Yolu düzenle Yolu yeniden adlandır @@ -4012,4 +4012,26 @@ %1$d / %2$d karşıya yükleniyor %1$d / %2$d karşıya yüklendi Karşıya yüklenecek düzenlemeleri seçin + tepe gölgesi / yamaç / eş yükselti eğrileri + OpenPlaceReviews, restoranlar, oteller, müzeler, ara noktalar gibi halka açık yerler hakkında topluluk tarafından yürütülen bir projedir. Fotoğraflar, yorumlar, OpenStreetMap, Wikipedia gibi diğer sistemlere bağlantılar gibi onlar hakkındaki tüm halka açık bilgileri toplar. +\n +\nTüm OpenPlaceReview verileri açık ve herkes tarafından kullanılabilir: http://openplacereviews.org/data +\n +\nDaha fazlasını şu adresten okuyabilirsiniz: http://openplacereviews.org + OpenPlaceReviews + test.openplacereviews.org adresini kullan + OpenPlaceReviews\'te oturum aç + Su + Kış + Kar arabası + Binme + Yarış + Dağ bisikleti + Bisiklet sürme + Yürüyüş + Koşma + Yürüme + Arazi + Motosiklet + Araba \ No newline at end of file From 75379bc9d451b17dd4e8bbcd9ef53bb6a30940ed Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 10 Feb 2021 10:33:12 +0000 Subject: [PATCH 152/398] Translated using Weblate (Arabic) Currently translated at 100.0% (3674 of 3674 strings) --- OsmAnd/res/values-ar/strings.xml | 70 ++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 6952e1c6c8..b0ea31530a 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -359,7 +359,7 @@ برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه أوسماند+ للخرائط و الملاحة برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه - أنشئ مُرشِّح نقاط مهمة + إنشاء فلتر نقاط الاهتمام نمط المواصلات: وسائل النقل: الشروق: %1$s @@ -1830,7 +1830,7 @@ ملاحظة OSM معلق عليها مسار زلق لإظهار خرائط التزلج، يجب تحميل خريطة خاصة محلية. - حافلة، ترامواي وغيرها + حافلة، عربة وغيرها إنشاء ملاحظة OSM حدث استثناء: لم يتم إنشاء الملاحظة. حدث استثناء: لم يتم غلق الملاحظة. @@ -2071,7 +2071,7 @@ اللون والسمك خذ المخرج %1$d ثم واصل المدينة أو المنطقة - مقالات ويكيبيديا قريبة + مقالات ويكيبيديا القريبة استخدام الطرق السريعة السماح للطرق السريعة. الصربية (اللاتينية) @@ -2218,18 +2218,19 @@ حدد مجلد المسار المسارات الوقت - التغطية التقريبية للخريطة و جودتها : -\n• أوروبا الغربية : **** -\n• أوروبا الشرقية : *** -\n• روسيا : *** -\n• أمريكا الشمالية : *** -\n• امريكا الجنوبية : ** -\n• آسيا : ** -\n• اليابان وكوريا : *** -\n• الشرق الأوسط : ** -\n• إفريقيا : ** -\n• أنتاركتيكا : * -\n معظم البلدان في جميع أنحاء العالم متاحة للتنزيل ! من أفغانستان إلى زيمبابوي، من أستراليا إلى الولايات المتحدة الأمريكية. الأرجنتين، البرازيل، كندا، فرنسا، ألمانيا، المكسيك، المملكة المتحدة، إسبانيا + التغطية التقريبية للخريطة و جودتها: +\n • أوروبا الغربية: **** +\n • أوروبا الشرقية: *** +\n • روسيا: *** +\n • أمريكا الشمالية: *** +\n • امريكا الجنوبية: ** +\n • آسيا: ** +\n • اليابان وكوريا: *** +\n • الشرق الأوسط : ** +\n • إفريقيا: ** +\n • أنتاركتيكا: * +\n معظم البلدان في جميع أنحاء العالم متاحة للتنزيل +\n من أفغانستان إلى زيمبابوي، من أستراليا إلى الولايات المتحدة الأمريكية. الأرجنتين، البرازيل، كندا، فرنسا، ألمانيا، المكسيك، المملكة المتحدة، أسبانيا , … \n إعادة البحث المساهمة في OSM @@ -2370,13 +2371,14 @@ \nأوسماند بلس هو إصدار للتطبيق مدفوع الأجر. قبل شرائه، ادعم المشروع، بتمويل لتطوير الميزات الجديدة والحصول على آخر التحديثات. \n \n بعض الميزات الرئيسية: - الملاحة -\n• يعمل على الإنترنت (سريع) أو في وضع غير متصل (لا رسوم تجوال خارج الوطن) -\n• توجيه صوتي بالتفصيل (الأصوات المسجلة أو مدرجة) -\n• موجه مسار اختياري، عرض اسم الشارع، والوقت المقدر للوصول -\n• يدعم نقاط وسيطة خلال مسارك -\n• إعادة تلقائية للتوجيه كلما انحرفت عن الطريق -\n• البحث عن الأماكن حسب العنوان، النوع (مثل: مطعم، فندق، محطة وقود، متحف)،أو حسب الإحداثيات الجغرافية + الملاحة +\n • يعمل على الإنترنت (سريع) أو في وضع غير متصل (لا رسوم تجوال خارج الوطن) +\n • توجيه صوتي بالتفصيل (الأصوات المسجلة أو مدرجة) +\n • موجه مسار اختياري، عرض اسم الشارع، والوقت المقدر للوصول +\n • يدعم نقاط وسيطة خلال مسارك +\n • إعادة تلقائية للتوجيه كلما انحرفت عن الطريق +\n • البحث عن الأماكن حسب العنوان، النوع (مثل: مطعم، فندق، محطة وقود، متحف)،أو حسب الإحداثيات الجغرافية +\n عرض الخريطة \n• عرض موقعك والتوجيه \n• محاذاة اختيارية للصورة وفق البوصلة أو توجيه الحركة @@ -2417,7 +2419,8 @@ اسم الاختصار السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار. الضغط على زر الإجراء سيطبق أحد الأنماط من القائمة أدناه. تنقلاتك على هذا الطريق - OLC الصالحة بالكامل تمثل المنطقة: %1$s x %2$s + الصالحة بالكامل OLC +\nيمثل المنطقة: %1$s x %2$s اسم المستخدم خاطئ إلى مِن @@ -2615,7 +2618,7 @@ ج ش اسم النقطة - الطرق القريبة التي في الداخل + الطرق الداخلية المجاورة أدخل اسم الملف. خطأ أثناء استرجاع الخريطة تمت عملية استيراد الخريطة @@ -3334,7 +3337,7 @@ السماح بطرق المتخصصين طرق صعبة للغاية ، مع عقبات خطيرة والمناطق المحيطة بها. السماح بالتزلج على الطرق فقط - الطريق مصممة خصيصا بحرية أو التزلج على الجليد. + طرق مصممة للأسلوب الحر أو التزلج فقط بدون المسارات الكلاسيكية. السماح للطرق الكلاسيكية فقط تم إعداد الطرق للأسلوب الكلاسيكي فقط دون مسارات التزلج. يشمل ذلك الطرق التي يتم إعدادها بواسطة عربة ثلجية أصغر مع زحلقة مرنة ومسارات مصنوعة يدوياً بواسطة المتزلجين. الصعوبة المفضلة @@ -3840,7 +3843,7 @@ نقطة المسار للتنقل بداية المسار أقرب نقطة - إرفاق الطرق + إرفاق بالطرق حذف عنوان إضافة عنوان أدخل العنوان @@ -3863,7 +3866,7 @@ فتح المسار المحفوظ محفوظ مسار مبسط - سيتم حفظ خط التوجيه فقط، وسيتم حذف نقاط الطريق. + سيتم حفظ خط الطريق فقط، وسيتم حذف نقاط المسار. اسم الملف الرجاء إضافة نقطتين على الأقل. إعادة @@ -4082,4 +4085,17 @@ OpenPlaceReviews استخدام test.openplacereviews.org الدخول إلى OpenPlaceReviews + ماء + شتاء + الثلج + ركوب + سباق + دراجة جبلية + دراجة + مشي + الجري + مشي + الطرق الوعرة + دراجة نارية + سيارة \ No newline at end of file From fdf881c070f98d6e0ba1337edf5525279dfb4a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 10 Feb 2021 10:20:20 +0000 Subject: [PATCH 153/398] Translated using Weblate (Turkish) Currently translated at 83.1% (3234 of 3891 strings) --- OsmAnd/res/values-tr/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index b76cd1cada..5c3b4f7a6c 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -502,7 +502,7 @@ Tırmanma Kriket Kroket - Bisiklete binme + Bisiklet sürme Dalış Tüplü dalış Köpek yarışı From ff1b4fa9122b011bc8fc8e897f3d66bbb24d1c1a Mon Sep 17 00:00:00 2001 From: Verdulo Date: Wed, 10 Feb 2021 10:41:23 +0000 Subject: [PATCH 154/398] Translated using Weblate (Esperanto) Currently translated at 99.9% (3888 of 3891 strings) --- OsmAnd/res/values-eo/phrases.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index fd389f4538..2af7eb4454 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -3881,4 +3881,11 @@ Ponto por vespertoj Trairejo por sovaĝaj bestoj Naĝejo natura + Stato de skivojo: fermita + Stato de skivojo: malfermita + Kontrolata: ne + Kontrolata: jes + Senarbigita: jes + Nomo de skivojo + Skisaltejo \ No newline at end of file From c50a671021ed91c0d2719631451484c4c4024ecb Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 13:07:36 +0200 Subject: [PATCH 155/398] fix for future use when new track recording starts p2 --- OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 7d7b911078..0e005b0d8c 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -100,7 +100,7 @@ public class GpxBlockStatisticsBuilder { GPXFile gpxFile = getGPXFile(); GpxDisplayItem gpxDisplayItem = null; GPXTrackAnalysis analysis = null; - boolean withoutGaps = false; + boolean withoutGaps = true; if (gpxFile.tracks.size() > 0) { gpxDisplayItem = getDisplayItem(gpxFile); } From 3979b6ab16f3a0fab3cc54257443e280ccef88b4 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 10 Feb 2021 13:29:17 +0200 Subject: [PATCH 156/398] Update gpx_track_item.xml --- OsmAnd/res/layout/gpx_track_item.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/layout/gpx_track_item.xml b/OsmAnd/res/layout/gpx_track_item.xml index 54dd3e9161..69bfbb6119 100644 --- a/OsmAnd/res/layout/gpx_track_item.xml +++ b/OsmAnd/res/layout/gpx_track_item.xml @@ -37,6 +37,7 @@ android:layout_marginRight="@dimen/dialog_content_margin" android:layout_marginEnd="@dimen/dialog_content_margin" android:clickable="false" + android:scrollbars="none" android:focusableInTouchMode="false" /> Date: Wed, 10 Feb 2021 12:52:51 +0000 Subject: [PATCH 157/398] Translated using Weblate (Chinese (Simplified)) Currently translated at 69.4% (2550 of 3674 strings) --- OsmAnd/res/values-zh-rCN/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 9550f1fb9c..04e0d0a0f0 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -2663,7 +2663,7 @@ 旅游书 下载图片 黑色 - + 木头 地铁 骑马 品红色 @@ -2839,7 +2839,7 @@ 显示关闭的注记 关闭的OSM注记 添加在线资源 - + 驮道 砾石 比利时石砌路 允许专家路线 From 6a532846e5e5e090ae023e5c078726dbceedd478 Mon Sep 17 00:00:00 2001 From: Liu Tao Date: Wed, 10 Feb 2021 12:50:32 +0000 Subject: [PATCH 158/398] Translated using Weblate (Chinese (Simplified)) Currently translated at 69.4% (2550 of 3674 strings) --- OsmAnd/res/values-zh-rCN/strings.xml | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 04e0d0a0f0..137c034f83 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -3124,4 +3124,79 @@ 添加轨迹航点 将轨迹记录到GPX文件 当应用程序被杀死时,跟踪日志将被暂停(通过最近的应用程序)。(OsmAnd背景指示会从Android通知栏中消失)。 + 添加在线路线引擎 + 编辑在线路线引擎 + 子类型 + 车辆 + API 密钥 + 服务器 URL + 输入参数 + 否则请保持空白 + 测试路线计算 + 驾驶 + 汽车 + 复制地址 + 在线路线引擎 + 在线路线引擎 + 文件夹 + 选择文件夹 + 选择文件夹或添加新文件夹 + 上传到 OpenStreetMap + 编辑轨迹 + 重命名轨迹 + 更改文件夹 + + 通过 + 长时间准备 + 准备 + 偏离路线 + 到达目的地 + 转弯 + 时间和距离间隔 + 不同语音提示的公告时间取决于提示类型、当前导航速度和默认导航速度。 + 公告时间 + 开始录制 + 在地图上显示轨迹 + 轮椅 + 徒步 + 步行 + 电动自行车 + 山地自行车 + 公路自行车 + 重型货车 + 小型卡车 + 卡车 + 踏板车 + 竞速自行车 + 山地车 + 服务器错误:%1$s + 删除这个在线路线引擎? + 名字已经存在 + 阅读全文 + 编辑描述 + 删除航点 + 复制到地图标记 + 复制到收藏 + 上传中 + 上传完成 + 正在上传 %1$d,共 %2$d + 选择要上传的编辑 + 已上传 %1$d,共 %2$d + 山体阴影/斜坡/等高线 + OpenPlaceReviews 是一个社区驱动的项目,关于公共场所,如餐馆,酒店,博物馆,航点。它收集了所有关于它们的公共信息,如照片、评论、链接到其他系统的 OpenStreetMap、维基百科。 +\n +\n所有 OpenPlaceReview 的数据都是开放的,所有人都可以使用:http://openplacereviews.org/data。 +\n +\n你可以在以下网站阅读更多信息:http://openplacereviews.org + OpenPlaceReviews + 使用 test.openplacereviews.org + 登录 OpenPlaceReviews + 冬季 + 雪地摩托 + 骑行 + 骑车 + 健行 + 跑步 + 步行 + 摩托车 \ No newline at end of file From 2f6f362217f5390e692d95c6f9c84d4b641d7126 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Wed, 10 Feb 2021 11:05:32 +0000 Subject: [PATCH 159/398] Translated using Weblate (French) Currently translated at 99.8% (3669 of 3674 strings) --- OsmAnd/res/values-fr/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 1f8808c5dc..33f448572b 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4005,4 +4005,13 @@ OpenPlaceReviews Utilisez test.openplacereviews.org Se connecter à OpenPlaceReviews + Eau + Hiver + Motoneige + Vélo + VTT + Randonnée + Course à pied + Marche + Voiture \ No newline at end of file From 3004acacef1db17b934ce416e30000754064787c Mon Sep 17 00:00:00 2001 From: Verdulo Date: Wed, 10 Feb 2021 11:06:41 +0000 Subject: [PATCH 160/398] Translated using Weblate (Esperanto) Currently translated at 100.0% (3674 of 3674 strings) --- OsmAnd/res/values-eo/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index da7a929cf2..def12120ad 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4020,4 +4020,17 @@ OpenPlaceReviews Uzi test.openplacereviews.org Ensaluti al OpenPlaceReviews + Akvo + Vintro + Motorsledo + Rajdado + Kurkonkurso + Montbiciklo + Biciklado + Marŝado + Kurado + Piedirado + Ekstervoje + Motorciklo + Aŭto \ No newline at end of file From a5c0abd1c44e3fc8c890bf758b9189e89500d833 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Wed, 10 Feb 2021 10:46:14 +0000 Subject: [PATCH 161/398] Translated using Weblate (Esperanto) Currently translated at 100.0% (3891 of 3891 strings) --- OsmAnd/res/values-eo/phrases.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index 2af7eb4454..a6ca5bed0f 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -3888,4 +3888,7 @@ Senarbigita: jes Nomo de skivojo Skisaltejo + Movebla biblioteko (haltloko) + Pint‑taglibro: ne + Pint‑taglibro: jes \ No newline at end of file From 22241d2956ec9742b528771e272fba466c40789a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Wed, 10 Feb 2021 11:15:45 +0000 Subject: [PATCH 162/398] Translated using Weblate (Icelandic) Currently translated at 99.9% (3673 of 3674 strings) --- OsmAnd/res/values-is/strings.xml | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index ebb0385e37..4b92baf978 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -3972,7 +3972,7 @@ Veldu möppu Veldu möppu eða bættu við nýrri Tómt - Greina eftir millibilum (uppskipting millibila) + Greina eftir uppskiptingu millibila Senda inn í OpenStreetMap Breyta ferli Endurnefna feril @@ -4005,4 +4005,32 @@ Fjallahjól Villa í netþjóni: %1$s Nafnið er þegar til staðar + Eyða þessari leiðagerð á netinu\? + Lesa óstytt + Breyta lýsingu + Eyða ferilpunktum + Afrita í kortamerki + Afrita í eftirlæti + Sendi inn + Innsendingu er lokið + Sendi inn %1$d af %2$d + Sent inn %1$d af %2$d + Veldu breytingar til að senda inn + Hæðaskygging / Halli / Hæðarlínur + OpenPlaceReviews + Nota test.openplacereviews.org + Skrá inn á OpenPlaceReviews + Vatn + Vetur + Vélsleðar + Útreiðar + Kappakstur + Fjallahjól + Hjólreiðar + Gönguferðir + Hlaup + Gangandi + Utanvegaakstur + Vélhjól + Akandi \ No newline at end of file From 5117056ec79cdcb5637e3e35f4f60413f6755873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Wed, 10 Feb 2021 11:13:37 +0000 Subject: [PATCH 163/398] Translated using Weblate (Icelandic) Currently translated at 100.0% (3891 of 3891 strings) --- OsmAnd/res/values-is/phrases.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OsmAnd/res/values-is/phrases.xml b/OsmAnd/res/values-is/phrases.xml index e2ee6f1cb3..459a777d6c 100644 --- a/OsmAnd/res/values-is/phrases.xml +++ b/OsmAnd/res/values-is/phrases.xml @@ -3881,4 +3881,14 @@ Brú fyrir leðurblökur Þverun villtra dýra Sundsvæði + Stæði fyrir bókabíl + Skráning á tind: nei + Skráning á tind: já + Staða brautar: lokuð + Staða brautar: opin + Eftirlit: nei + Eftirlit: já + Skafið: já + Heiti brautar + Skíðastökk \ No newline at end of file From 5ab2b0319cf6f12e47b8d08b52c57370292847a8 Mon Sep 17 00:00:00 2001 From: One Two Date: Wed, 10 Feb 2021 12:53:48 +0000 Subject: [PATCH 164/398] Translated using Weblate (Chinese (Simplified)) Currently translated at 69.4% (2550 of 3674 strings) --- OsmAnd/res/values-zh-rCN/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 137c034f83..97e514b125 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -2674,7 +2674,7 @@ 兴趣点(POI) 容量 金属 - 路径 + 走道 直升机 滑雪 滑雪 From c36d007b5c169051a9e7e3329c7ab8bc6c31a596 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 16:04:25 +0200 Subject: [PATCH 165/398] fix ability to click on statistics blocks; add functionality of the button "start new segment"; add snackbar with file rename to "save and stop recording" button; some fixes; --- .../StopTrackRecordingBottomFragment.java | 22 ++++- .../TripRecordingActiveBottomSheet.java | 92 +++++++++---------- .../plus/track/GpxBlockStatisticsBuilder.java | 10 +- 3 files changed, 72 insertions(+), 52 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java index 5172bfc1bf..fd28bd7431 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java @@ -1,12 +1,13 @@ package net.osmand.plus.monitoring; -import android.app.Dialog; import android.content.Context; +import android.os.AsyncTask; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; @@ -15,7 +16,9 @@ import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.widgets.TextViewEx; import androidx.annotation.DimenRes; @@ -33,6 +36,16 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm private OsmandApplication app; private OsmandSettings settings; private OsmandMonitoringPlugin plugin; + private GPXFile gpxFile; + private SaveGpxListener saveGpxListener; + + public void setGpxFile(GPXFile gpxFile) { + this.gpxFile = gpxFile; + } + + public void setSaveGpxListener(SaveGpxListener saveGpxListener) { + this.saveGpxListener = saveGpxListener; + } @Override public void createMenuItems(Bundle savedInstanceState) { @@ -118,7 +131,8 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm app.getSavingTrackHelper().clearRecordedData(true); } else if (tag == ButtonType.SAVE_AND_STOP) { if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { - plugin.saveCurrentTrack(); + new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + plugin.stopRecording(); app.getNotificationHelper().refreshNotifications(); } } @@ -169,9 +183,11 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm return true; } - public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + public static void showInstance(GPXFile gpxFile, SaveGpxListener saveGpxListener, @NonNull FragmentManager fragmentManager, @NonNull Fragment target) { if (!fragmentManager.isStateSaved()) { StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment(); + fragment.setGpxFile(gpxFile); + fragment.setSaveGpxListener(saveGpxListener); fragment.setTargetFragment(target, 0); fragment.show(fragmentManager, TAG); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index bcc7fa7cf0..7c0f10a10f 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -90,7 +90,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen private final Handler handler = new Handler(); private Runnable updatingGPS; private Runnable updatingTimeTrackSaved; - private SaveGpxListener saveGpxListener; private GPXFile getGPXFile() { return selectedGpxFile.getGpxFile(); @@ -145,7 +144,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave, null); createItem(buttonStart, ItemType.START_SEGMENT, wasTrackMonitored, null); -// createItem(buttonSave, ItemType.SAVE, hasDataToSave, getTimeTrackSaved()); createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); createItem(buttonStop, ItemType.STOP, true, null); @@ -153,8 +151,9 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen updateStatus(); RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics); - blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, null); + blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile); blockStatisticsBuilder.setBlocksView(statBlocks); + blockStatisticsBuilder.setBlocksClickable(false); blockStatisticsBuilder.initStatBlocks(null, ContextCompat.getColor(app, getActiveTextColorId(nightMode)), nightMode); LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); @@ -226,18 +225,17 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void onClick(View v) { if (wasTrackMonitored) { - + helper.startNewSegment(); } } }); - setSaveListener(); buttonSave.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (hasDataToSave) { final GPXFile gpxFile = getGPXFile(); - new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new SaveCurrentTrackTask(app, gpxFile, createSaveListener()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } } }); @@ -263,7 +261,8 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void onClick(View v) { if (fragmentManager != null) { - StopTrackRecordingBottomFragment.showInstance(fragmentManager, TripRecordingActiveBottomSheet.this); + final GPXFile gpxFile = getGPXFile(); + StopTrackRecordingBottomFragment.showInstance(gpxFile, createSaveListener(), fragmentManager, TripRecordingActiveBottomSheet.this); } } }); @@ -307,6 +306,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen AndroidUiHelper.updateVisibility(desc, isShowDesc); UiUtilities.setMargins(title, 0, marginDesc, 0, marginDesc); desc.setText(description); + type.setTextColor(desc, app, false, false, nightMode); } } @@ -378,43 +378,41 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen handler.post(updatingTimeTrackSaved); } - private void setSaveListener() { - if (saveGpxListener == null) { - saveGpxListener = new SaveGpxListener() { + private SaveGpxListener createSaveListener() { + return new SaveGpxListener() { - @Override - public void gpxSavingStarted() { - } + @Override + public void gpxSavingStarted() { + } - @Override - public void gpxSavingFinished(Exception errorMessage) { - String gpxFileName = Algorithms.getFileWithoutDirs(getGPXFile().path); - final MapActivity mapActivity = getMapActivity(); - final Context context = getContext(); - final SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); - if (mapActivity != null && context != null) { - Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), - getString(R.string.shared_string_file_is_saved, gpxFileName), - Snackbar.LENGTH_LONG) - .setAction(R.string.shared_string_rename, new View.OnClickListener() { - @Override - public void onClick(View view) { - final WeakReference mapActivityRef = new WeakReference<>(mapActivity); - final FragmentActivity fragmentActivity = mapActivityRef.get(); - SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); - } - }); - View view = snackbar.getView(); - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); - params.gravity = Gravity.TOP; - AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); - view.setLayoutParams(params); - UiUtilities.setupSnackbar(snackbar, nightMode); - snackbar.show(); - } + @Override + public void gpxSavingFinished(Exception errorMessage) { + String gpxFileName = Algorithms.getFileWithoutDirs(getGPXFile().path); + final MapActivity mapActivity = getMapActivity(); + final Context context = getContext(); + final SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); + if (mapActivity != null && context != null) { + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), + getString(R.string.shared_string_file_is_saved, gpxFileName), + Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_rename, new View.OnClickListener() { + @Override + public void onClick(View view) { + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + final FragmentActivity fragmentActivity = mapActivityRef.get(); + SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); + } + }); + View view = snackbar.getView(); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); + params.gravity = Gravity.TOP; + AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); + view.setLayoutParams(params); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); } - }; - } + } + }; } @Nullable @@ -508,12 +506,12 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void setTintedIcon(AppCompatImageView iv, Context context, boolean enabled, boolean pressed, boolean nightMode) { if (iv != null) { - int iconColor = ContextCompat.getColor(context, - enabled ? pressed ? getPressedColorId(nightMode) - : this == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete - : getActiveIconColorId(nightMode) : getSecondaryIconColorId(nightMode)); - Drawable icon = UiUtilities.createTintedDrawable(context, iconId, iconColor); - iv.setImageDrawable(icon); + Drawable icon = AppCompatResources.getDrawable(context, iconId); + int iconColor = enabled ? pressed ? getPressedColorId(nightMode) + : this == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete + : getActiveIconColorId(nightMode) : getSecondaryIconColorId(nightMode); + Drawable tintedIcon = UiUtilities.tintDrawable(icon, ContextCompat.getColor(context, iconColor)); + iv.setImageDrawable(tintedIcon); if (this == ItemType.STOP) { int stopSize = iv.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(stopSize, stopSize); diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 0e005b0d8c..3c06eb8882 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -11,6 +11,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -41,6 +42,7 @@ public class GpxBlockStatisticsBuilder { private BlockStatisticsAdapter adapter; private final List items = new ArrayList<>(); + private boolean blocksClickable = true; private final Handler handler = new Handler(); private Runnable updatingItems; @@ -51,6 +53,10 @@ public class GpxBlockStatisticsBuilder { this.selectedGpxFile = selectedGpxFile; } + public void setBlocksClickable(boolean blocksClickable) { + this.blocksClickable = blocksClickable; + } + public void setBlocksView(RecyclerView blocksView) { this.blocksView = blocksView; } @@ -63,7 +69,7 @@ public class GpxBlockStatisticsBuilder { return selectedGpxFile.getGpxFile(); } - public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { + public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { initItems(); boolean isNotEmpty = !Algorithms.isEmpty(items); AndroidUiHelper.updateVisibility(blocksView, isNotEmpty); @@ -237,7 +243,7 @@ public class GpxBlockStatisticsBuilder { @Override public void onClick(View v) { GPXTrackAnalysis analysis = displayItem != null ? displayItem.analysis : null; - if (analysis != null) { + if (blocksClickable && analysis != null && actionsListener != null) { ArrayList list = new ArrayList<>(); if (analysis.hasElevationData || analysis.isSpeedSpecified() || analysis.hasSpeedData) { if (item.firstType != null) { From 6adbcd5ff6e21f3c5ca1b5a3057e144221f6c6ad Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 17:21:01 +0200 Subject: [PATCH 166/398] fix another way to show the bottom sheet with renaming and opening current track after clicking "Save and stop recording"; fix showing correct track save time; fix now after clicking the "Stop.." buttons, the track recording fragment does not open --- .../plus/activities/SavingTrackHelper.java | 2 + .../StopTrackRecordingBottomFragment.java | 35 +++++++--------- .../TripRecordingActiveBottomSheet.java | 41 ++++++++----------- .../plus/myplaces/SaveCurrentTrackTask.java | 1 + 4 files changed, 34 insertions(+), 45 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java index e173a49ad1..a5c5c74100 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java @@ -78,6 +78,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { private SelectedGpxFile currentTrack; private int points; private int trkPoints = 0; + public long time; public SavingTrackHelper(OsmandApplication ctx) { super(ctx, DATABASE_NAME, null, DATABASE_VERSION); @@ -255,6 +256,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { GPXTrackAnalysis analysis = gpx.getAnalysis(fout.lastModified()); GpxDataItem item = new GpxDataItem(fout, analysis); ctx.getGpxDbHelper().add(item); + time = fout.lastModified(); } } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java index fd28bd7431..3d648f432b 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java @@ -1,24 +1,21 @@ package net.osmand.plus.monitoring; import android.content.Context; -import android.os.AsyncTask; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; -import net.osmand.GPXUtilities.GPXFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; -import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.widgets.TextViewEx; import androidx.annotation.DimenRes; @@ -34,17 +31,13 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm public static final String TAG = StopTrackRecordingBottomFragment.class.getSimpleName(); private OsmandApplication app; + private MapActivity mapActivity; private OsmandSettings settings; private OsmandMonitoringPlugin plugin; - private GPXFile gpxFile; - private SaveGpxListener saveGpxListener; + private ButtonType tag = ButtonType.CANCEL; - public void setGpxFile(GPXFile gpxFile) { - this.gpxFile = gpxFile; - } - - public void setSaveGpxListener(SaveGpxListener saveGpxListener) { - this.saveGpxListener = saveGpxListener; + public void setMapActivity(MapActivity mapActivity) { + this.mapActivity = mapActivity; } @Override @@ -122,7 +115,7 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm return; } - ButtonType tag = (ButtonType) o; + tag = (ButtonType) o; if (tag == ButtonType.STOP_AND_DISCARD) { if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { plugin.stopRecording(); @@ -131,8 +124,7 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm app.getSavingTrackHelper().clearRecordedData(true); } else if (tag == ButtonType.SAVE_AND_STOP) { if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { - new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - plugin.stopRecording(); + plugin.saveCurrentTrack(null, mapActivity); app.getNotificationHelper().refreshNotifications(); } } @@ -151,9 +143,11 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm @Override public void onPause() { super.onPause(); - Fragment target = getTargetFragment(); - if (target instanceof TripRecordingActiveBottomSheet) { - ((TripRecordingActiveBottomSheet) target).show(); + if (tag == ButtonType.CANCEL) { + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + ((TripRecordingActiveBottomSheet) target).show(); + } } } @@ -183,11 +177,10 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm return true; } - public static void showInstance(GPXFile gpxFile, SaveGpxListener saveGpxListener, @NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + public static void showInstance(MapActivity mapActivity, @NonNull FragmentManager fragmentManager, @NonNull Fragment target) { if (!fragmentManager.isStateSaved()) { StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment(); - fragment.setGpxFile(gpxFile); - fragment.setSaveGpxListener(saveGpxListener); + fragment.setMapActivity(mapActivity); fragment.setTargetFragment(target, 0); fragment.show(fragmentManager, TAG); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 7c0f10a10f..f72f736997 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -62,11 +62,6 @@ import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import java.lang.ref.WeakReference; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; @@ -261,8 +256,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void onClick(View v) { if (fragmentManager != null) { - final GPXFile gpxFile = getGPXFile(); - StopTrackRecordingBottomFragment.showInstance(gpxFile, createSaveListener(), fragmentManager, TripRecordingActiveBottomSheet.this); + StopTrackRecordingBottomFragment.showInstance(getMapActivity(), fragmentManager, TripRecordingActiveBottomSheet.this); } } }); @@ -311,20 +305,14 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } private String getTimeTrackSaved() { - long timeTrackSaved = helper.getLastTimeUpdated(); - SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z", Locale.getDefault()); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - Date resultDate = new Date(timeTrackSaved); - String sdfFormatted = sdf.format(resultDate); - CharSequence formattedTimeTrackSaved = null; - try { - long time = sdf.parse(sdfFormatted).getTime(); + if (helper.time != 0) { + long timeTrackSaved = helper.time; long now = System.currentTimeMillis(); - formattedTimeTrackSaved = DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); - } catch (ParseException e) { - log.error(e); + CharSequence time = DateUtils.getRelativeTimeSpanString(timeTrackSaved, now, DateUtils.MINUTE_IN_MILLIS); + return String.valueOf(time); + } else { + return null; } - return String.valueOf(formattedTimeTrackSaved); } @Override @@ -406,7 +394,8 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen View view = snackbar.getView(); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); params.gravity = Gravity.TOP; - AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); + final int dp16 = AndroidUtils.dpToPx(mapActivity, 16f); + AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context) + dp16, 0, 0); view.setLayoutParams(params); UiUtilities.setupSnackbar(snackbar, nightMode); snackbar.show(); @@ -438,26 +427,30 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } - private static void setItemBackgroundActive(LinearLayout view, Context context, boolean nightMode) { + private static void setItemBackgroundActive(LinearLayout view, Context context, + boolean nightMode) { Drawable background = AppCompatResources.getDrawable(context, nightMode ? R.drawable.btn_background_active_dark : R.drawable.btn_background_active_light); view.setBackgroundDrawable(background); } - private static void setItemBackgroundInactive(LinearLayout view, Context context, boolean nightMode) { + private static void setItemBackgroundInactive(LinearLayout view, Context context, + boolean nightMode) { Drawable background = AppCompatResources.getDrawable(context, nightMode ? R.drawable.btn_background_inactive_dark : R.drawable.btn_background_inactive_light); view.setBackgroundDrawable(background); } - private static void setShowOnMapBackgroundActive(LinearLayout view, Context context, boolean checked, boolean nightMode) { + private static void setShowOnMapBackgroundActive(LinearLayout view, Context context, + boolean checked, boolean nightMode) { Drawable background = AppCompatResources.getDrawable(context, nightMode ? checked ? R.drawable.btn_background_active_dark : R.drawable.btn_background_stroked_active_dark : checked ? R.drawable.btn_background_active_light : R.drawable.btn_background_stroked_active_light); view.setBackgroundDrawable(background); } - private static void setShowOnMapBackgroundInactive(LinearLayout view, Context context, boolean checked, boolean nightMode) { + private static void setShowOnMapBackgroundInactive(LinearLayout view, Context context, + boolean checked, boolean nightMode) { Drawable background = AppCompatResources.getDrawable(context, nightMode ? checked ? R.drawable.btn_background_inactive_dark : R.drawable.btn_background_stroked_inactive_dark : checked ? R.drawable.btn_background_inactive_light : R.drawable.btn_background_stroked_inactive_light); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SaveCurrentTrackTask.java b/OsmAnd/src/net/osmand/plus/myplaces/SaveCurrentTrackTask.java index 84959d17f7..843d7b7ea1 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/SaveCurrentTrackTask.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/SaveCurrentTrackTask.java @@ -52,6 +52,7 @@ public class SaveCurrentTrackTask extends AsyncTask { for (final String f : files.keySet()) { File fout = new File(dir, f + IndexConstants.GPX_FILE_EXT); GPXUtilities.writeGpxFile(fout, gpx); + app.getSavingTrackHelper().time = fout.lastModified(); } return shouldClearPath; } From b7497338b3702ef37163f224577f90ab262aec70 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 18:05:58 +0200 Subject: [PATCH 167/398] fix updating block statistics and time track saved after clicking "Save" button --- .../TripRecordingActiveBottomSheet.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index f72f736997..24e2bb4843 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -230,7 +230,15 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void onClick(View v) { if (hasDataToSave) { final GPXFile gpxFile = getGPXFile(); - new SaveCurrentTrackTask(app, gpxFile, createSaveListener()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new SaveCurrentTrackTask(app, gpxFile, createSaveListener(new Runnable() { + @Override + public void run() { + blockStatisticsBuilder.stopUpdatingStatBlocks(); + blockStatisticsBuilder.runUpdatingStatBlocks(); + stopUpdatingTimeTrackSaved(); + runUpdatingTimeTrackSaved(); + } + })).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } } }); @@ -366,7 +374,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen handler.post(updatingTimeTrackSaved); } - private SaveGpxListener createSaveListener() { + private SaveGpxListener createSaveListener(@Nullable final Runnable callback) { return new SaveGpxListener() { @Override @@ -399,6 +407,9 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen view.setLayoutParams(params); UiUtilities.setupSnackbar(snackbar, nightMode); snackbar.show(); + if (callback != null) { + callback.run(); + } } } }; From 8c92c3f87c6a36b70ea1e8ab3ff1a85d04f5fb4a Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 10 Feb 2021 18:18:37 +0200 Subject: [PATCH 168/398] Fix review --- .../plus/wikivoyage/data/TravelArticle.java | 22 +++++++- .../plus/wikivoyage/data/TravelDbHelper.java | 8 +-- .../plus/wikivoyage/data/TravelHelper.java | 7 +-- .../plus/wikivoyage/data/TravelObfHelper.java | 54 ++++++++++--------- .../explore/ExploreTabFragment.java | 2 +- .../explore/WikivoyageExploreActivity.java | 10 ++-- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java index 952b85be4d..a346f496eb 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelArticle.java @@ -169,6 +169,26 @@ public class TravelArticle { return new String[]{md5.substring(0, 1), md5.substring(0, 2)}; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TravelArticle that = (TravelArticle) o; + return TravelArticleIdentifier.areLatLonEqual(that.lat, that.lon, lat, lon) && + Algorithms.objectEquals(file, that.file) && + Algorithms.stringsEqual(routeId, that.routeId) && + Algorithms.stringsEqual(routeSource, that.routeSource); + } + + @Override + public int hashCode() { + return Algorithms.hash(file, lat, lon, routeId, routeSource); + } + public static class TravelArticleIdentifier implements Parcelable { @Nullable File file; double lat; @@ -249,7 +269,7 @@ public class TravelArticle { return Algorithms.hash(file, lat, lon, routeId, routeSource); } - private static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) { + public static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) { boolean latEqual = (Double.isNaN(lat1) && Double.isNaN(lat2)) || Math.abs(lat1 - lat2) < 0.00001; boolean lonEqual = (Double.isNaN(lon1) && Double.isNaN(lon2)) || Math.abs(lon1 - lon2) < 0.00001; return latEqual && lonEqual; diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index 90ed62569f..0fc6c232f9 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -174,7 +174,7 @@ public class TravelDbHelper implements TravelHelper { } @Override - public void initializeDataToDisplay() { + public void initializeDataToDisplay(boolean resetData) { localDataHelper.refreshCachedData(); loadPopularArticles(); } @@ -549,13 +549,13 @@ public class TravelDbHelper implements TravelHelper { @Override @Nullable - public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, String lang, boolean readGpx, @Nullable GpxReadCallback callback) { + public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle res = null; SQLiteConnection conn = openConnection(); String routeId = articleId.routeId; - if (conn != null && !Algorithms.isEmpty(routeId)) { + if (conn != null && !Algorithms.isEmpty(routeId) && lang != null) { SQLiteCursor cursor = conn.rawQuery(ARTICLES_TABLE_SELECT + " WHERE " + ARTICLES_COL_TRIP_ID + " = ? AND " - + ARTICLES_COL_LANG + " = ?", new String[] { routeId, lang }); + + ARTICLES_COL_LANG + " = ?", new String[]{routeId, lang}); if (cursor != null) { if (cursor.moveToFirst()) { res = readArticle(cursor); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java index b8bb9cdf98..7e89431690 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelHelper.java @@ -25,7 +25,7 @@ public interface TravelHelper { void initializeDataOnAppStartup(); - void initializeDataToDisplay(); + void initializeDataToDisplay(boolean resetData); boolean isAnyTravelBookPresent(); @@ -35,14 +35,11 @@ public interface TravelHelper { @NonNull List getPopularArticles(); - @NonNull - List loadPopularArticles(); - @NonNull Map> getNavigationMap(@NonNull TravelArticle article); @Nullable - TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback); + TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, boolean readGpx, @Nullable GpxReadCallback callback); @Nullable TravelArticle getArticleByTitle(@NonNull String title, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java index 036ba50bbb..b15b157089 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelObfHelper.java @@ -80,9 +80,8 @@ public class TravelObfHelper implements TravelHelper { private final Map> cachedArticles = new ConcurrentHashMap<>(); private final TravelLocalDataHelper localDataHelper; private int searchRadius = ARTICLE_SEARCH_RADIUS; - private int count = 0; - private int page = 0; - final List> amenities = new ArrayList<>(); + private int foundAmenitiesIndex = 0; + private final List> foundAmenities = new ArrayList<>(); public TravelObfHelper(OsmandApplication app) { this.app = app; @@ -100,7 +99,13 @@ public class TravelObfHelper implements TravelHelper { } @Override - public void initializeDataToDisplay() { + public void initializeDataToDisplay(boolean resetData) { + if (resetData) { + foundAmenities.clear(); + foundAmenitiesIndex = 0; + popularArticles.clear(); + searchRadius = ARTICLE_SEARCH_RADIUS; + } localDataHelper.refreshCachedData(); loadPopularArticles(); } @@ -108,19 +113,19 @@ public class TravelObfHelper implements TravelHelper { @NonNull public synchronized List loadPopularArticles() { String lang = app.getLanguage(); - List popularArticles = new ArrayList<>(); - if (amenities.size() - count < MAX_POPULAR_ARTICLES_COUNT) { + List popularArticles = new ArrayList<>(this.popularArticles); + if (foundAmenities.size() - foundAmenitiesIndex < MAX_POPULAR_ARTICLES_COUNT) { final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); for (final BinaryMapIndexReader reader : getReaders()) { try { - searchAmenity(amenities, location, reader, searchRadius, -1, ROUTE_ARTICLE); - searchAmenity(amenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK); + searchAmenity(foundAmenities, location, reader, searchRadius, -1, ROUTE_ARTICLE); + searchAmenity(foundAmenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK); } catch (Exception e) { LOG.error(e.getMessage(), e); } } - if (amenities.size() > 0) { - Collections.sort(amenities, new Comparator>() { + if (foundAmenities.size() > 0) { + Collections.sort(foundAmenities, new Comparator>() { @Override public int compare(Pair article1, Pair article2) { Amenity amenity1 = (Amenity) article1.second; @@ -136,22 +141,21 @@ public class TravelObfHelper implements TravelHelper { searchRadius *= 2; } - int lastIndex; - for (lastIndex = count; lastIndex < amenities.size() - 1; lastIndex++) { - Pair amenity = amenities.get(lastIndex); + int pagesCount = popularArticles.size() / MAX_POPULAR_ARTICLES_COUNT; + while (foundAmenitiesIndex < foundAmenities.size() - 1) { + Pair amenity = foundAmenities.get(foundAmenitiesIndex); if (!Algorithms.isEmpty(amenity.second.getName(lang))) { TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null); - if (article != null) { + if (article != null && !popularArticles.contains(article)) { popularArticles.add(article); - this.popularArticles.add(article); - if (this.popularArticles.size() >= (page + 1) * MAX_POPULAR_ARTICLES_COUNT) { - page++; + if (popularArticles.size() >= (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT) { break; } } } + foundAmenitiesIndex++; } - count = ++lastIndex; + this.popularArticles = popularArticles; return popularArticles; } @@ -184,10 +188,8 @@ public class TravelObfHelper implements TravelHelper { } if (!Algorithms.isEmpty(articles)) { TravelArticleIdentifier newArticleId = articles.values().iterator().next().generateIdentifier(); - if (!cachedArticles.containsKey(newArticleId)) { - cachedArticles.put(newArticleId, articles); - article = getCachedArticle(newArticleId, lang, readPoints, callback); - } + cachedArticles.put(newArticleId, articles); + article = getCachedArticle(newArticleId, lang, readPoints, callback); } return article; } @@ -628,8 +630,8 @@ public class TravelObfHelper implements TravelHelper { } @Override - public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, - boolean readGpx, @Nullable GpxReadCallback callback) { + public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, + boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle article = getCachedArticle(articleId, lang, readGpx, callback); if (article == null) { article = localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang); @@ -641,8 +643,8 @@ public class TravelObfHelper implements TravelHelper { } @Nullable - private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, - boolean readGpx, @Nullable GpxReadCallback callback) { + private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, + boolean readGpx, @Nullable GpxReadCallback callback) { TravelArticle article = null; Map articles = cachedArticles.get(articleId); if (articles != null) { diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 9afa7a33c3..ff692f8f1c 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -192,7 +192,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv @Override public void onPrimaryButtonClick() { if (activity instanceof WikivoyageExploreActivity) { - new LoadWikivoyageData((WikivoyageExploreActivity) activity).execute(); + new LoadWikivoyageData((WikivoyageExploreActivity) activity,false).execute(); } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java index 3191926522..bc4de7d575 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/WikivoyageExploreActivity.java @@ -326,12 +326,12 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv public void onFinish(AppInitializer init) { WikivoyageExploreActivity activity = activityRef.get(); if (AndroidUtils.isActivityNotDestroyed(activity)) { - new LoadWikivoyageData(activity).execute(); + new LoadWikivoyageData(activity,true).execute(); } } }); } else { - new LoadWikivoyageData(this).execute(); + new LoadWikivoyageData(this,true).execute(); } } @@ -384,15 +384,17 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv private final WeakReference activityRef; private final TravelHelper travelHelper; + private final boolean resetData; - LoadWikivoyageData(WikivoyageExploreActivity activity) { + LoadWikivoyageData(WikivoyageExploreActivity activity, boolean resetData) { travelHelper = activity.getMyApplication().getTravelHelper(); activityRef = new WeakReference<>(activity); + this.resetData = resetData; } @Override protected Void doInBackground(Void... params) { - travelHelper.initializeDataToDisplay(); + travelHelper.initializeDataToDisplay(resetData); return null; } From 26083c53a35903b5fa43b2847bf4705607f64562 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 10 Feb 2021 19:22:29 +0200 Subject: [PATCH 169/398] small code cleanup; --- .../plus/activities/MapActivityActions.java | 7 +-- .../monitoring/OsmandMonitoringPlugin.java | 40 ++++++----------- .../TripRecordingActiveBottomSheet.java | 45 +++++++------------ .../monitoring/TripRecordingBottomSheet.java | 9 ++-- 4 files changed, 35 insertions(+), 66 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index b216913466..7bfcdd754b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -22,7 +22,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; -import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; @@ -854,10 +853,8 @@ public class MapActivityActions implements DialogProvider { public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { app.logEvent("trip_recording_open"); MapActivity.clearPrevActivityIntent(); - if (monitoringPlugin.isHasDataToSave() || monitoringPlugin.isWasTrackMonitored()) { - TripRecordingActiveBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), - monitoringPlugin.getCurrentTrack(), monitoringPlugin.isWasTrackMonitored(), - monitoringPlugin.isHasDataToSave(), monitoringPlugin.isSearchingGPS()); + if (monitoringPlugin.hasDataToSave() || monitoringPlugin.wasTrackMonitored()) { + TripRecordingActiveBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), monitoringPlugin.getCurrentTrack()); } else { TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index eaa54a948a..df7390af7b 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -1,9 +1,7 @@ package net.osmand.plus.monitoring; -import android.Manifest; import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; @@ -19,7 +17,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatCheckBox; -import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; @@ -28,11 +25,9 @@ import com.google.android.material.slider.Slider; import net.osmand.AndroidUtils; import net.osmand.Location; import net.osmand.ValueHolder; -import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmAndFormatter; -import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndTaskManager.OsmAndTaskRunnable; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -45,7 +40,6 @@ import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType; -import net.osmand.plus.track.TrackDisplayHelper; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.MapInfoLayer; @@ -55,8 +49,6 @@ import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; import java.util.List; -import gnu.trove.list.array.TIntArrayList; - import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; public class OsmandMonitoringPlugin extends OsmandPlugin { @@ -165,9 +157,9 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } - public static final int[] SECONDS = new int[] {0, 1, 2, 3, 5, 10, 15, 20, 30, 60, 90}; - public static final int[] MINUTES = new int[] {2, 3, 5}; - public static final int[] MAX_INTERVAL_TO_SEND_MINUTES = new int[] {1, 2, 5, 10, 15, 20, 30, 60, 90, 2 * 60, 3 * 60, 4 * 60, 6 * 60, 12 * 60, 24 * 60}; + public static final int[] SECONDS = new int[]{0, 1, 2, 3, 5, 10, 15, 20, 30, 60, 90}; + public static final int[] MINUTES = new int[]{2, 3, 5}; + public static final int[] MAX_INTERVAL_TO_SEND_MINUTES = new int[]{1, 2, 5, 10, 15, 20, 30, 60, 90, 2 * 60, 3 * 60, 4 * 60, 6 * 60, 12 * 60, 24 * 60}; @Override public SettingsScreenType getSettingsScreenType() { @@ -185,9 +177,10 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { private TextInfoWidget createMonitoringControl(final MapActivity map) { monitoringControl = new TextInfoWidget(map) { long lastUpdateTime; + @Override public boolean updateInfo(DrawSettings drawSettings) { - if(isSaving){ + if (isSaving) { setText(map.getString(R.string.shared_string_save), ""); setIcons(R.drawable.widget_monitoring_rec_big_day, R.drawable.widget_monitoring_rec_big_night); return true; @@ -215,7 +208,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } final boolean liveMonitoringEnabled = liveMonitoringHelper.isLiveMonitoringEnabled(); - if(globalRecord) { + if (globalRecord) { //indicates global recording (+background recording) if (liveMonitoringEnabled) { dn = R.drawable.widget_live_monitoring_rec_big_night; @@ -324,25 +317,18 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { return app.getSavingTrackHelper().getCurrentTrack(); } - public boolean isWasTrackMonitored() { + public boolean wasTrackMonitored() { return settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); } - public boolean isHasDataToSave() { + public boolean hasDataToSave() { return app.getSavingTrackHelper().hasDataToSave(); } - public boolean isSearchingGPS() { - OsmAndLocationProvider locationProvider = app.getLocationProvider(); - Location lastKnownLocation = locationProvider.getLastKnownLocation(); - return lastKnownLocation == null; - } - public void controlDialog(final Activity activity, final boolean showTrackSelection) { - if (isHasDataToSave() || isWasTrackMonitored()) { + if (hasDataToSave() || wasTrackMonitored()) { FragmentActivity fragmentActivity = (FragmentActivity) activity; - TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager(), - getCurrentTrack(), isWasTrackMonitored(), isHasDataToSave(), isSearchingGPS()); + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager(), getCurrentTrack()); } else { FragmentActivity fragmentActivity = (FragmentActivity) activity; TripRecordingBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); @@ -507,7 +493,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } - public void stopRecording(){ + public void stopRecording() { settings.SAVE_GLOBAL_TRACK_TO_GPX.set(false); if (app.getNavigationService() != null) { app.getNavigationService().stopIfNeeded(app, NavigationService.USED_BY_GPX); @@ -596,11 +582,11 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) { String s; int progress = (int) value; - if(progress == 0) { + if (progress == 0) { s = uiCtx.getString(R.string.int_continuosly); v.value = 0; } else { - if(progress < secondsLength) { + if (progress < secondsLength) { s = seconds[progress] + " " + uiCtx.getString(R.string.int_seconds); v.value = seconds[progress] * 1000; } else { diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 24e2bb4843..7b05345608 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -37,10 +37,8 @@ import com.google.android.material.snackbar.Snackbar; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities.GPXFile; -import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; -import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -74,9 +72,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen private OsmandSettings settings; private SavingTrackHelper helper; private SelectedGpxFile selectedGpxFile; - private boolean wasTrackMonitored = false; - private boolean hasDataToSave = false; - private boolean searchingGPS = false; private View statusContainer; private View buttonSave; @@ -94,26 +89,22 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen this.selectedGpxFile = selectedGpxFile; } - public void setWasTrackMonitored(boolean wasTrackMonitored) { - this.wasTrackMonitored = wasTrackMonitored; + public boolean hasDataToSave() { + return app.getSavingTrackHelper().hasDataToSave(); } - public void setHasDataToSave(boolean hasDataToSave) { - this.hasDataToSave = hasDataToSave; + public boolean searchingGPS() { + return app.getLocationProvider().getLastKnownLocation() == null; } - public void setSearchingGPS(boolean searchingGPS) { - this.searchingGPS = searchingGPS; + public boolean wasTrackMonitored() { + return settings != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); } - public static void showInstance(@NonNull FragmentManager fragmentManager, SelectedGpxFile selectedGpxFile, - boolean wasTrackMonitored, boolean hasDataToSave, boolean searchingGPS) { + public static void showInstance(@NonNull FragmentManager fragmentManager, SelectedGpxFile selectedGpxFile) { if (!fragmentManager.isStateSaved()) { TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); fragment.setSelectedGpxFile(selectedGpxFile); - fragment.setWasTrackMonitored(wasTrackMonitored); - fragment.setHasDataToSave(hasDataToSave); - fragment.setSearchingGPS(searchingGPS); fragment.show(fragmentManager, TAG); } } @@ -137,9 +128,9 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen final View buttonPause = itemView.findViewById(R.id.button_pause); View buttonStop = itemView.findViewById(R.id.button_stop); - createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave, null); - createItem(buttonStart, ItemType.START_SEGMENT, wasTrackMonitored, null); - createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); + createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave(), null); + createItem(buttonStart, ItemType.START_SEGMENT, wasTrackMonitored(), null); + createItem(buttonPause, wasTrackMonitored() ? ItemType.PAUSE : ItemType.RESUME, true, null); createItem(buttonStop, ItemType.STOP, true, null); statusContainer = itemView.findViewById(R.id.status_container); @@ -210,7 +201,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen buttonClear.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (fragmentManager != null && hasDataToSave) { + if (fragmentManager != null && hasDataToSave()) { ClearRecordedDataBottomSheetFragment.showInstance(fragmentManager, TripRecordingActiveBottomSheet.this); } } @@ -219,7 +210,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen buttonStart.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (wasTrackMonitored) { + if (wasTrackMonitored()) { helper.startNewSegment(); } } @@ -228,7 +219,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen buttonSave.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (hasDataToSave) { + if (hasDataToSave()) { final GPXFile gpxFile = getGPXFile(); new SaveCurrentTrackTask(app, gpxFile, createSaveListener(new Runnable() { @Override @@ -247,14 +238,13 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen buttonPause.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - boolean wasTrackMonitored = !settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + boolean wasTrackMonitored = !wasTrackMonitored(); createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); if (!wasTrackMonitored) { blockStatisticsBuilder.stopUpdatingStatBlocks(); } else { blockStatisticsBuilder.runUpdatingStatBlocks(); } - TripRecordingActiveBottomSheet.this.wasTrackMonitored = wasTrackMonitored; settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); updateStatus(); } @@ -273,7 +263,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen private void updateStatus() { TextView statusTitle = statusContainer.findViewById(R.id.text_status); AppCompatImageView statusIcon = statusContainer.findViewById(R.id.icon_status); - ItemType status = searchingGPS ? ItemType.SEARCHING_GPS : !wasTrackMonitored ? ItemType.ON_PAUSE : ItemType.RECORDING; + ItemType status = searchingGPS() ? ItemType.SEARCHING_GPS : !wasTrackMonitored() ? ItemType.ON_PAUSE : ItemType.RECORDING; statusTitle.setText(status.getTitleId()); int colorText = status.equals(ItemType.SEARCHING_GPS) ? getSecondaryTextColorId(nightMode) : getOsmandIconColorId(nightMode); statusTitle.setTextColor(ContextCompat.getColor(app, colorText)); @@ -348,9 +338,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void run() { int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); - OsmAndLocationProvider locationProvider = app.getLocationProvider(); - Location lastKnownLocation = locationProvider.getLastKnownLocation(); - searchingGPS = lastKnownLocation == null; updateStatus(); handler.postDelayed(this, Math.max(1000, interval)); } @@ -367,7 +354,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen @Override public void run() { String time = getTimeTrackSaved(); - createItem(buttonSave, ItemType.SAVE, hasDataToSave, !Algorithms.isEmpty(time) ? time : null); + createItem(buttonSave, ItemType.SAVE, hasDataToSave(), !Algorithms.isEmpty(time) ? time : null); handler.postDelayed(this, 60000); } }; diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 6653b6f5c3..bd7f98d45f 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -28,11 +28,11 @@ import net.osmand.AndroidUtils; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.AndroidUiHelper; @@ -278,12 +278,11 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { @Override protected void onRightBottomButtonClick() { - app.getSavingTrackHelper().startNewSegment(); + SavingTrackHelper helper = app.getSavingTrackHelper(); + helper.startNewSegment(); settings.SAVE_GLOBAL_TRACK_TO_GPX.set(true); app.startNavigationService(NavigationService.USED_BY_GPX); - OsmandMonitoringPlugin plugin = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class); - TripRecordingActiveBottomSheet.showInstance(getMapActivity().getSupportFragmentManager(), - plugin.getCurrentTrack(), plugin.isWasTrackMonitored(), plugin.isHasDataToSave(), plugin.isSearchingGPS()); + TripRecordingActiveBottomSheet.showInstance(getMapActivity().getSupportFragmentManager(), helper.getCurrentTrack()); dismiss(); } From 567c8f2a5bacf9a7b3ee184a81a29fc8b42811d4 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 11 Feb 2021 01:09:30 +0200 Subject: [PATCH 170/398] fix statistics blocks are immediately displayed after the start of recording; fix height of the "show on map" block when increasing the font size --- .../layout/trip_recording_active_fragment.xml | 2 +- .../TripRecordingActiveBottomSheet.java | 30 +++++++++---------- .../plus/track/GpxBlockStatisticsBuilder.java | 17 +++++------ 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/OsmAnd/res/layout/trip_recording_active_fragment.xml b/OsmAnd/res/layout/trip_recording_active_fragment.xml index df687a1bc5..630b68a5fd 100644 --- a/OsmAnd/res/layout/trip_recording_active_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_active_fragment.xml @@ -77,7 +77,7 @@ android:id="@+id/show_track_on_map" layout="@layout/bottom_sheet_with_switch_divider_and_additional_button" android:layout_width="match_parent" - android:layout_height="@dimen/context_menu_buttons_bottom_height" + android:layout_height="wrap_content" android:layout_marginStart="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding" android:layout_marginTop="@dimen/content_padding_half" diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 7b05345608..3dd1b69b7e 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -142,10 +142,11 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen blockStatisticsBuilder.setBlocksClickable(false); blockStatisticsBuilder.initStatBlocks(null, ContextCompat.getColor(app, getActiveTextColorId(nightMode)), nightMode); - LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); - final LinearLayout basicItemBody = showTrackOnMapView.findViewById(R.id.basic_item_body); + LinearLayout showTrackContainer = itemView.findViewById(R.id.show_track_on_map); + showTrackContainer.setMinimumHeight(app.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_list_item_height)); - TextView showTrackTitle = basicItemBody.findViewById(R.id.title); + final LinearLayout buttonShow = showTrackContainer.findViewById(R.id.basic_item_body); + TextView showTrackTitle = buttonShow.findViewById(R.id.title); showTrackTitle.setText(ItemType.SHOW_TRACK.getTitleId()); showTrackTitle.setTextColor(ContextCompat.getColor(app, getActiveIconColorId(nightMode))); showTrackTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); @@ -155,24 +156,24 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen float letterSpacing = AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing); showTrackTitle.setLetterSpacing(letterSpacing); } - final SwitchCompat showTrackOnMapButton = basicItemBody.findViewById(R.id.switch_button); + final SwitchCompat showTrackOnMapButton = buttonShow.findViewById(R.id.switch_button); showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); - final LinearLayout additionalButton = showTrackOnMapView.findViewById(R.id.additional_button); - View divider = additionalButton.getChildAt(0); + final LinearLayout buttonAppearance = showTrackContainer.findViewById(R.id.additional_button); + View divider = buttonAppearance.getChildAt(0); AndroidUiHelper.setVisibility(View.GONE, divider); int marginS = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_small); - UiUtilities.setMargins(additionalButton, marginS, 0, 0, 0); + UiUtilities.setMargins(buttonAppearance, marginS, 0, 0, 0); String width = settings.CURRENT_TRACK_WIDTH.get(); boolean showArrows = settings.CURRENT_TRACK_SHOW_ARROWS.get(); int color = settings.CURRENT_TRACK_COLOR.get(); Drawable appearanceDrawable = TrackAppearanceFragment.getTrackIcon(app, width, showArrows, color); - AppCompatImageView appearanceIcon = additionalButton.findViewById(R.id.icon_after_divider); + AppCompatImageView appearanceIcon = buttonAppearance.findViewById(R.id.icon_after_divider); int marginTrackIconH = app.getResources().getDimensionPixelSize(R.dimen.content_padding_small); UiUtilities.setMargins(appearanceIcon, marginTrackIconH, 0, marginTrackIconH, 0); appearanceIcon.setImageDrawable(appearanceDrawable); - additionalButton.setOnClickListener(new View.OnClickListener() { + buttonAppearance.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (showTrackOnMapButton.isChecked()) { @@ -185,16 +186,16 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } }); - createItem(additionalButton, ItemType.APPEARANCE, showTrackOnMapButton.isChecked(), null); - setShowOnMapBackgroundInactive(basicItemBody, app, showTrackOnMapButton.isChecked(), nightMode); - basicItemBody.setOnClickListener(new View.OnClickListener() { + createItem(buttonAppearance, ItemType.APPEARANCE, showTrackOnMapButton.isChecked(), null); + setShowOnMapBackgroundInactive(buttonShow, app, showTrackOnMapButton.isChecked(), nightMode); + buttonShow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean checked = !showTrackOnMapButton.isChecked(); showTrackOnMapButton.setChecked(checked); app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); - setShowOnMapBackgroundInactive(basicItemBody, app, checked, nightMode); - createItem(additionalButton, ItemType.APPEARANCE, checked, null); + setShowOnMapBackgroundInactive(buttonShow, app, checked, nightMode); + createItem(buttonAppearance, ItemType.APPEARANCE, checked, null); } }); @@ -234,7 +235,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } }); - // todo example, need to check buttonPause.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 3c06eb8882..51ee200d26 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -71,14 +71,11 @@ public class GpxBlockStatisticsBuilder { public void initStatBlocks(@Nullable SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { initItems(); - boolean isNotEmpty = !Algorithms.isEmpty(items); - AndroidUiHelper.updateVisibility(blocksView, isNotEmpty); - if (isNotEmpty) { - adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode); - adapter.setItems(items); - blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); - blocksView.setAdapter(adapter); - } + adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode); + adapter.setItems(items); + blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); + blocksView.setAdapter(adapter); + AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items)); } public void stopUpdatingStatBlocks() { @@ -90,11 +87,11 @@ public class GpxBlockStatisticsBuilder { updatingItems = new Runnable() { @Override public void run() { + initItems(); if (adapter != null) { - initItems(); adapter.setItems(items); - AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items)); } + AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items)); int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); handler.postDelayed(this, Math.max(1000, interval)); } From 77c4b12259efb5b00779376b6346ecca8afb45ec Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 11 Feb 2021 04:08:11 +0200 Subject: [PATCH 171/398] some fixes; --- .../layout/trip_recording_active_fragment.xml | 2 +- .../TripRecordingActiveBottomSheet.java | 22 ++++++++++--------- .../plus/track/GpxBlockStatisticsBuilder.java | 10 ++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/OsmAnd/res/layout/trip_recording_active_fragment.xml b/OsmAnd/res/layout/trip_recording_active_fragment.xml index 630b68a5fd..9bb2e62b29 100644 --- a/OsmAnd/res/layout/trip_recording_active_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_active_fragment.xml @@ -103,7 +103,7 @@ android:layout_marginBottom="@dimen/content_padding" /> 0 ? GpxUiHelper.makeGpxDisplayItem(app, gpxFile) : null; } private GPXFile getGPXFile() { @@ -101,12 +102,9 @@ public class GpxBlockStatisticsBuilder { public void initItems() { GPXFile gpxFile = getGPXFile(); - GpxDisplayItem gpxDisplayItem = null; + GpxDisplayItem gpxDisplayItem = getDisplayItem(gpxFile); GPXTrackAnalysis analysis = null; boolean withoutGaps = true; - if (gpxFile.tracks.size() > 0) { - gpxDisplayItem = getDisplayItem(gpxFile); - } if (gpxDisplayItem != null) { analysis = gpxDisplayItem.analysis; withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack(); From aca0ed1b5de3e5610f2f31bc3a98ba1b69071712 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 11 Feb 2021 15:18:02 +0500 Subject: [PATCH 172/398] Fix NPE --- .../osmand/plus/track/GpxReadDescriptionDialogFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxReadDescriptionDialogFragment.java b/OsmAnd/src/net/osmand/plus/track/GpxReadDescriptionDialogFragment.java index b652c7a3bd..2a45e23d58 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxReadDescriptionDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxReadDescriptionDialogFragment.java @@ -200,7 +200,9 @@ public class GpxReadDescriptionDialogFragment extends BaseOsmAndDialogFragment { @Override public void onPageCommitVisible(WebView webView, String url) { super.onPageCommitVisible(webView, url); - setupDependentViews(view); + if (getActivity() != null) { + setupDependentViews(view); + } } }); loadWebviewData(); From 4a37c8ee88544295bf5a1dbbd5593b8e55417104 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 11 Feb 2021 12:57:59 +0200 Subject: [PATCH 173/398] fix letter spacing in favorite groups selection --- .../layout/favorite_category_dialog_item.xml | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/layout/favorite_category_dialog_item.xml b/OsmAnd/res/layout/favorite_category_dialog_item.xml index 92aa731363..c5e3e52d7a 100644 --- a/OsmAnd/res/layout/favorite_category_dialog_item.xml +++ b/OsmAnd/res/layout/favorite_category_dialog_item.xml @@ -1,25 +1,27 @@ -