Merge pull request #10952 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2021-02-20 00:04:14 +01:00 committed by GitHub
commit 1a4a5509a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 620 additions and 338 deletions

View file

@ -620,9 +620,7 @@ public class GeneralRouter implements VehicleRouter {
public double calculateTurnTime(RouteSegment segment, int segmentEnd, RouteSegment prev, int prevSegmentEnd) { public double calculateTurnTime(RouteSegment segment, int segmentEnd, RouteSegment prev, int prevSegmentEnd) {
float ts = getPenaltyTransition(segment.getRoad()); float ts = getPenaltyTransition(segment.getRoad());
float prevTs = getPenaltyTransition(prev.getRoad()); float prevTs = getPenaltyTransition(prev.getRoad());
float totalPenalty = 0; float totalPenalty = 0;
if (prevTs != ts) { if (prevTs != ts) {
totalPenalty += Math.abs(ts - prevTs) / 2; totalPenalty += Math.abs(ts - prevTs) / 2;
} }
@ -638,7 +636,9 @@ public class GeneralRouter implements VehicleRouter {
// } // }
// } // }
// } // }
if (shortestRoute) {
return totalPenalty;
}
if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) { if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
double rt = getRoundaboutTurn(); double rt = getRoundaboutTurn();
if(rt > 0) { if(rt > 0) {

View file

@ -4,7 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.hardware.* import android.hardware.*
import android.location.Location import android.location.Location
import android.os.Looper import android.os.HandlerThread
import android.util.Log import android.util.Log
import com.google.android.gms.location.* import com.google.android.gms.location.*
import net.osmand.PlatformUtil import net.osmand.PlatformUtil
@ -43,11 +43,12 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
var lastKnownLocation: net.osmand.Location? = null var lastKnownLocation: net.osmand.Location? = null
private set private set
private val locationUpdateHandlerThread = HandlerThread("LocationProviderUpdateHandlerThread")
private var fusedLocationProviderClient: FusedLocationProviderClient? = null private var fusedLocationProviderClient: FusedLocationProviderClient? = null
private val locationRequest = LocationRequest().apply { private val locationRequest = LocationRequest().apply {
interval = 1000 interval = 1000
fastestInterval = 500 //fastestInterval = 500
maxWaitTime = 2000 maxWaitTime = 0
priority = LocationRequest.PRIORITY_HIGH_ACCURACY priority = LocationRequest.PRIORITY_HIGH_ACCURACY
} }
private val locationCallback = object : LocationCallback() { private val locationCallback = object : LocationCallback() {
@ -81,6 +82,10 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
fun updateCompassValue(value: Float) fun updateCompassValue(value: Float)
} }
init {
locationUpdateHandlerThread.start()
}
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
fun resumeAllUpdates() { fun resumeAllUpdates() {
if (AndroidUtils.isLocationPermissionAvailable(app) && fusedLocationProviderClient == null) { if (AndroidUtils.isLocationPermissionAvailable(app) && fusedLocationProviderClient == null) {
@ -89,7 +94,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
try { try {
fusedLocationProviderClient?.requestLocationUpdates( fusedLocationProviderClient?.requestLocationUpdates(
locationRequest, locationCallback, Looper.myLooper()) locationRequest, locationCallback, locationUpdateHandlerThread.looper)
} catch (unlikely: SecurityException) { } catch (unlikely: SecurityException) {
Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely") Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely")
} }

View file

@ -38,6 +38,7 @@ class TelegramService : Service(), TelegramIncomingMessagesListener,
private var updateWidgetHandler: Handler? = null private var updateWidgetHandler: Handler? = null
private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread") private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread")
private var locationUpdateHandlerThread = HandlerThread("LocationUpdateServiceThread")
// FusedLocationProviderClient - Main class for receiving location updates. // FusedLocationProviderClient - Main class for receiving location updates.
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
@ -62,6 +63,7 @@ class TelegramService : Service(), TelegramIncomingMessagesListener,
mHandlerThread.start() mHandlerThread.start()
tracksHandlerThread.start() tracksHandlerThread.start()
updateWidgetThread.start() updateWidgetThread.start()
locationUpdateHandlerThread.start()
updateShareInfoHandler = Handler(mHandlerThread.looper) updateShareInfoHandler = Handler(mHandlerThread.looper)
updateTracksHandler = Handler(tracksHandlerThread.looper) updateTracksHandler = Handler(tracksHandlerThread.looper)
updateWidgetHandler = Handler(updateWidgetThread.looper) updateWidgetHandler = Handler(updateWidgetThread.looper)
@ -82,11 +84,11 @@ class TelegramService : Service(), TelegramIncomingMessagesListener,
// Sets the fastest rate for active location updates. This interval is exact, and your // Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates more frequently than this value. // application will never receive updates more frequently than this value.
fastestInterval = 500 //fastestInterval = 500
// Sets the maximum time when batched location updates are delivered. Updates may be // Sets the maximum time when batched location updates are delivered. Updates may be
// delivered sooner than this interval. // delivered sooner than this interval.
maxWaitTime = 2000 maxWaitTime = 0
priority = LocationRequest.PRIORITY_HIGH_ACCURACY priority = LocationRequest.PRIORITY_HIGH_ACCURACY
} }
@ -166,6 +168,7 @@ class TelegramService : Service(), TelegramIncomingMessagesListener,
tracksHandlerThread.quit() tracksHandlerThread.quit()
mHandlerThread.quit() mHandlerThread.quit()
updateWidgetThread.quit() updateWidgetThread.quit()
locationUpdateHandlerThread.quit()
app().showLocationHelper.addOrUpdateStatusWidget(-1, false) app().showLocationHelper.addOrUpdateStatusWidget(-1, false)
usedBy = 0 usedBy = 0
@ -198,7 +201,7 @@ class TelegramService : Service(), TelegramIncomingMessagesListener,
// request location updates // request location updates
try { try {
fusedLocationProviderClient.requestLocationUpdates( fusedLocationProviderClient.requestLocationUpdates(
locationRequest, locationCallback, Looper.myLooper()) locationRequest, locationCallback, locationUpdateHandlerThread.looper)
} catch (unlikely: SecurityException) { } catch (unlikely: SecurityException) {
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show() Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely") Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely")

Binary file not shown.

View file

@ -109,4 +109,5 @@
<asset source="sounds/camera_click.ogg" destination="sounds/camera_click.ogg" mode="copyOnlyIfDoesNotExist" /> <asset source="sounds/camera_click.ogg" destination="sounds/camera_click.ogg" mode="copyOnlyIfDoesNotExist" />
<asset source="World_basemap_mini.obf" destination="World_basemap_mini.obf" mode="alwaysOverwriteOrCopy" /> <asset source="World_basemap_mini.obf" destination="World_basemap_mini.obf" mode="alwaysOverwriteOrCopy" />
<asset source="Default_wikivoyage.travel.obf" destination="travel/Default_wikivoyage.travel.obf" mode="copyOnlyIfDoesNotExist" />
</assets> </assets>

View file

@ -36,9 +36,9 @@ android {
defaultConfig { defaultConfig {
minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15 minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15
versionCode 400 versionCode 390
versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode
versionName "4.0.0" versionName "3.9.0"
versionName System.getenv("APK_VERSION")? System.getenv("APK_VERSION").toString(): versionName 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 versionName System.getenv("APK_VERSION_SUFFIX")? versionName + System.getenv("APK_VERSION_SUFFIX").toString(): versionName
} }

View file

@ -12,6 +12,7 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="@dimen/content_padding_small" android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small" android:paddingLeft="@dimen/content_padding_small"
@ -34,7 +35,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:duplicateParentState="true" android:duplicateParentState="true"
android:letterSpacing="@dimen/description_letter_spacing" android:letterSpacing="@dimen/text_button_letter_spacing"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
tools:text="Title" tools:text="Title"
@ -45,7 +46,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:duplicateParentState="true" android:duplicateParentState="true"
android:letterSpacing="@dimen/description_letter_spacing" android:letterSpacing="@dimen/text_button_letter_spacing"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
android:visibility="gone" android:visibility="gone"
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"

View file

@ -78,20 +78,20 @@
<Button <Button
android:id="@+id/button_action" android:id="@+id/button_action"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="33dp" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding"
android:background="@drawable/buy_btn_background_light" android:minWidth="@dimen/list_header_height"
android:minWidth="40dp" android:minHeight="@dimen/list_content_padding_large"
android:paddingLeft="18dp" android:paddingLeft="@dimen/bottom_sheet_exit_button_margin"
android:paddingRight="18dp" android:paddingRight="@dimen/bottom_sheet_exit_button_margin"
android:text="@string/get_plugin" android:text="@string/get_plugin"
android:textColor="@color/buy_button_color" android:textColor="@color/text_color_tab_active_light"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" tools:visibility="visible"
android:paddingEnd="18dp" android:paddingEnd="@dimen/bottom_sheet_exit_button_margin"
android:paddingStart="18dp" /> android:paddingStart="@dimen/bottom_sheet_exit_button_margin" />
</LinearLayout> </LinearLayout>

View file

@ -102,6 +102,19 @@
android:layout_marginRight="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding" /> android:layout_marginBottom="@dimen/content_padding" />
<include
android:id="@+id/button_online"
layout="@layout/bottom_sheet_button_with_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_half"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding"
android:visibility="gone" />
<include <include
android:id="@+id/button_segment" android:id="@+id/button_segment"
layout="@layout/bottom_sheet_button_with_icon" layout="@layout/bottom_sheet_button_with_icon"

View file

@ -94,13 +94,13 @@
android:layout_marginRight="@dimen/list_header_padding" android:layout_marginRight="@dimen/list_header_padding"
android:minWidth="@dimen/list_header_height" android:minWidth="@dimen/list_header_height"
android:minHeight="@dimen/list_content_padding_large" android:minHeight="@dimen/list_content_padding_large"
android:paddingStart="@dimen/context_menu_progress_padding_left" android:paddingStart="@dimen/bottom_sheet_exit_button_margin"
android:paddingLeft="@dimen/context_menu_progress_padding_left" android:paddingLeft="@dimen/bottom_sheet_exit_button_margin"
android:paddingEnd="@dimen/context_menu_progress_padding_left" android:paddingEnd="@dimen/bottom_sheet_exit_button_margin"
android:paddingRight="@dimen/context_menu_progress_padding_left" android:paddingRight="@dimen/bottom_sheet_exit_button_margin"
android:text="@string/buy" android:text="@string/buy"
android:textColor="@color/text_color_tab_active_light" android:textColor="@color/text_color_tab_active_light"
android:visibility="gone" /> android:visibility="visible" />
</LinearLayout> </LinearLayout>

View file

@ -13,6 +13,12 @@
android:icon="@drawable/ic_map" android:icon="@drawable/ic_map"
android:title="@string/shared_string_maps"/> android:title="@string/shared_string_maps"/>
<Preference
android:key="travel_memory_used"
android:layout="@layout/data_storage_memory_used_item"
android:icon="@drawable/ic_action_wikipedia"
android:title="@string/wikivoyage_travel_guide"/>
<Preference <Preference
android:key="terrain_memory_used" android:key="terrain_memory_used"
android:layout="@layout/data_storage_memory_used_item" android:layout="@layout/data_storage_memory_used_item"

View file

@ -1,6 +1,7 @@
package net.osmand.plus; package net.osmand.plus;
import android.location.Location; import android.location.Location;
import android.os.HandlerThread;
import android.os.Looper; import android.os.Looper;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -32,6 +33,8 @@ public class LocationServiceHelperImpl extends LocationServiceHelper {
private final OsmandApplication app; private final OsmandApplication app;
private final HandlerThread mHandlerThread = new HandlerThread("LocationServiceHelperThread");
// FusedLocationProviderClient - Main class for receiving location updates. // FusedLocationProviderClient - Main class for receiving location updates.
private final FusedLocationProviderClient fusedLocationProviderClient; private final FusedLocationProviderClient fusedLocationProviderClient;
@ -46,6 +49,7 @@ public class LocationServiceHelperImpl extends LocationServiceHelper {
public LocationServiceHelperImpl(@NonNull OsmandApplication app) { public LocationServiceHelperImpl(@NonNull OsmandApplication app) {
this.app = app; this.app = app;
mHandlerThread.start();
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(app); fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(app);
@ -100,7 +104,7 @@ public class LocationServiceHelperImpl extends LocationServiceHelper {
// request location updates // request location updates
try { try {
fusedLocationProviderClient.requestLocationUpdates( fusedLocationProviderClient.requestLocationUpdates(
fusedLocationRequest, fusedLocationCallback, Looper.myLooper()); fusedLocationRequest, fusedLocationCallback, mHandlerThread.getLooper());
} catch (SecurityException e) { } catch (SecurityException e) {
LOG.debug("Location service permission not granted"); LOG.debug("Location service permission not granted");
throw e; throw e;

View file

@ -66,6 +66,8 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -84,6 +86,7 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.util.TypedValue.COMPLEX_UNIT_SP; import static android.util.TypedValue.COMPLEX_UNIT_SP;
public class AndroidUtils { public class AndroidUtils {
private static final Log LOG = PlatformUtil.getLog(AndroidUtils.class);
public static final String STRING_PLACEHOLDER = "%s"; public static final String STRING_PLACEHOLDER = "%s";
public static final MessageFormat formatKb = new MessageFormat("{0, number,##.#}", Locale.US); public static final MessageFormat formatKb = new MessageFormat("{0, number,##.#}", Locale.US);
@ -804,16 +807,24 @@ public class AndroidUtils {
public static long getAvailableSpace(@Nullable File dir) { public static long getAvailableSpace(@Nullable File dir) {
if (dir != null && dir.canRead()) { if (dir != null && dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
return fs.getAvailableBlocksLong() * fs.getBlockSize(); return fs.getAvailableBlocksLong() * fs.getBlockSize();
} catch (IllegalArgumentException e) {
LOG.error(e);
}
} }
return -1; return -1;
} }
public static float getFreeSpaceGb(File dir) { public static float getFreeSpaceGb(File dir) {
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
return (float) (fs.getBlockSize()) * fs.getAvailableBlocks() / (1 << 30); return (float) (fs.getBlockSize()) * fs.getAvailableBlocks() / (1 << 30);
} catch (IllegalArgumentException e) {
LOG.error(e);
}
} }
return -1; return -1;
} }

View file

@ -11,6 +11,8 @@ import com.squareup.picasso.Picasso;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -23,6 +25,7 @@ import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
public class PicassoUtils { public class PicassoUtils {
private static final Log LOG = PlatformUtil.getLog(PicassoUtils.class);
private static final String PICASSO_CACHE = "picasso-cache"; private static final String PICASSO_CACHE = "picasso-cache";
private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MB private static final int MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024; // 5MB
@ -109,7 +112,8 @@ public class PicassoUtils {
long available = blockCount * blockSize; long available = blockCount * blockSize;
// Target 2% of the total space. // Target 2% of the total space.
size = available / 50; size = available / 50;
} catch (IllegalArgumentException ignored) { } catch (IllegalArgumentException e) {
LOG.error(e);
} }
// Bound inside min/max size for disk cache. // Bound inside min/max size for disk cache.

View file

@ -89,7 +89,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
public static final int IMPORT_FAVOURITES_ID = 7; public static final int IMPORT_FAVOURITES_ID = 7;
public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded"; public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded";
private static final int MAX_POINTS_IN_DESCRIPTION = 100; private static final int MAX_CHARS_IN_DESCRIPTION = 100000;
private FavouritesAdapter favouritesAdapter; private FavouritesAdapter favouritesAdapter;
private FavouritesDbHelper helper; private FavouritesDbHelper helper;
@ -611,35 +611,51 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
private String generateHtmlPrint(List<FavoriteGroup> groups) { private String generateHtmlPrint(List<FavoriteGroup> groups) {
StringBuilder html = new StringBuilder(); StringBuilder html = new StringBuilder();
StringBuilder buffer = new StringBuilder();
html.append("<h1>My Favorites</h1>"); html.append("<h1>My Favorites</h1>");
int addedPoints = 0;
for (FavoriteGroup group : groups) { for (FavoriteGroup group : groups) {
html.append("<h3>").append(group.getDisplayName(app)).append("</h3>"); buffer.setLength(0);
for (FavouritePoint fp : group.getPoints()) { buffer.append("<h3>").append(group.getDisplayName(app)).append("</h3>");
if (addedPoints >= MAX_POINTS_IN_DESCRIPTION) { if (buffer.length() + html.length() > MAX_CHARS_IN_DESCRIPTION) {
break; return html.append("<p>...</p>").toString();
} }
html.append(buffer);
boolean reachedLimit = generateHtmlForGroup(group.getPoints(), html);
if (reachedLimit) {
return html.append("<p>...</p>").toString();
}
}
return html.toString();
}
private boolean generateHtmlForGroup(List<FavouritePoint> points, StringBuilder html) {
StringBuilder buffer = new StringBuilder();
for (FavouritePoint fp : points) {
buffer.setLength(0);
float lat = (float) fp.getLatitude(); float lat = (float) fp.getLatitude();
float lon = (float) fp.getLongitude(); float lon = (float) fp.getLongitude();
String url = "geo:" + lat + "," + lon + "?m=" + fp.getName(); String url = "geo:" + lat + "," + lon + "?m=" + fp.getName();
html.append("<p>") buffer.append("<p>")
.append(fp.getDisplayName(app)) .append(fp.getDisplayName(app))
.append(" - <a href=\"") .append(" - <a href=\"")
.append(url) .append(url)
.append("\">geo:") .append("\">geo:")
.append(lat).append(",").append(lon) .append(lat).append(",").append(lon)
.append("</a><br></p>"); .append("</a><br></p>");
addedPoints++;
if (buffer.length() + html.length() > MAX_CHARS_IN_DESCRIPTION) {
return true;
} }
if (addedPoints >= MAX_POINTS_IN_DESCRIPTION) { html.append(buffer);
html.append("<p>...</p>");
break;
} }
}
return html.toString(); return false;
} }
private void shareFavourites() { private void shareFavourites() {

View file

@ -384,8 +384,12 @@ public class MultimediaNotesFragment extends BaseSettingsFragment implements Cop
File dir = app.getAppPath("").getParentFile(); File dir = app.getAppPath("").getParentFile();
long size = 0; long size = 0;
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
size = ((long) fs.getBlockSize() * (long) fs.getBlockCount()) / (1 << 30); size = ((long) fs.getBlockSize() * (long) fs.getBlockCount()) / (1 << 30);
} catch (IllegalArgumentException e) {
log.error(e);
}
} }
if (size > 0) { if (size > 0) {
int value = 1; int value = 1;

View file

@ -31,6 +31,7 @@ import androidx.fragment.app.FragmentActivity;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.FileUtils; import net.osmand.FileUtils;
import net.osmand.PlatformUtil;
import net.osmand.ValueHolder; import net.osmand.ValueHolder;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -39,6 +40,8 @@ import net.osmand.plus.R;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -52,7 +55,7 @@ import java.util.Locale;
import gnu.trove.list.array.TIntArrayList; import gnu.trove.list.array.TIntArrayList;
public class DashChooseAppDirFragment { public class DashChooseAppDirFragment {
private static final Log LOG = PlatformUtil.getLog(DashChooseAppDirFragment.class);
public static class ChooseAppDirFragment { public static class ChooseAppDirFragment {
public static final int VERSION_DEFAULTLOCATION_CHANGED = 19; public static final int VERSION_DEFAULTLOCATION_CHANGED = 19;
@ -92,8 +95,12 @@ public class DashChooseAppDirFragment {
private String getFreeSpace(File dir) { private String getFreeSpace(File dir) {
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
return AndroidUtils.formatSize(activity, (long) fs.getAvailableBlocks() * fs.getBlockSize()); return AndroidUtils.formatSize(activity, (long) fs.getAvailableBlocks() * fs.getBlockSize());
} catch (IllegalArgumentException e) {
LOG.error(e);
}
} }
return ""; return "";
} }

View file

@ -22,6 +22,8 @@ import android.widget.ProgressBar;
import android.widget.Space; import android.widget.Space;
import android.widget.TextView; import android.widget.TextView;
import com.ibm.icu.impl.IllegalIcuArgumentException;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
@ -653,9 +655,13 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
String size = ""; String size = "";
int percent = 0; int percent = 0;
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
size = AndroidUtils.formatSize(activity, ((long) fs.getAvailableBlocks()) * fs.getBlockSize()); size = AndroidUtils.formatSize(activity, ((long) fs.getAvailableBlocks()) * fs.getBlockSize());
percent = 100 - (int) ((long) fs.getAvailableBlocks() * 100 / fs.getBlockCount()); percent = 100 - (int) ((long) fs.getAvailableBlocks() * 100 / fs.getBlockCount());
} catch (IllegalIcuArgumentException e) {
LOG.error(e);
}
} }
sizeProgress.setIndeterminate(false); sizeProgress.setIndeterminate(false);
sizeProgress.setProgress(percent); sizeProgress.setProgress(percent);

View file

@ -304,8 +304,12 @@ public class DownloadIndexesThread {
File dir = app.getAppPath("").getParentFile(); File dir = app.getAppPath("").getParentFile();
double asz = -1; double asz = -1;
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
asz = (((long) fs.getAvailableBlocks()) * fs.getBlockSize()) / (1 << 20); asz = (((long) fs.getAvailableBlocks()) * fs.getBlockSize()) / (1 << 20);
} catch (IllegalArgumentException e) {
LOG.error(e);
}
} }
return asz; return asz;
} }

View file

@ -50,10 +50,10 @@ public class DownloadResources extends DownloadResourceGroup {
public static final String WORLD_SEAMARKS_NAME = "World_seamarks"; public static final String WORLD_SEAMARKS_NAME = "World_seamarks";
public static final String WORLD_SEAMARKS_OLD_KEY = "world_seamarks_basemap"; public static final String WORLD_SEAMARKS_OLD_KEY = "world_seamarks_basemap";
public static final String WORLD_SEAMARKS_OLD_NAME = "World_seamarks_basemap"; public static final String WORLD_SEAMARKS_OLD_NAME = "World_seamarks_basemap";
public static final String WIKIVOYAGE_FILE_FILTER = "wikivoyage";
private static final Log LOG = PlatformUtil.getLog(DownloadResources.class); private static final Log LOG = PlatformUtil.getLog(DownloadResources.class);
public DownloadResources(OsmandApplication app) { public DownloadResources(OsmandApplication app) {
super(null, DownloadResourceGroupType.WORLD, ""); super(null, DownloadResourceGroupType.WORLD, "");
this.region = app.getRegions().getWorldRegion(); this.region = app.getRegions().getWorldRegion();
@ -369,7 +369,9 @@ public class DownloadResources extends DownloadResourceGroup {
continue; continue;
} }
if (ii.getType() == DownloadActivityType.TRAVEL_FILE) { if (ii.getType() == DownloadActivityType.TRAVEL_FILE) {
if (ii.getFileName().contains(WIKIVOYAGE_FILE_FILTER)) {
wikivoyageMaps.addItem(ii); wikivoyageMaps.addItem(ii);
}
continue; continue;
} }
String basename = ii.getBasename().toLowerCase(); String basename = ii.getBasename().toLowerCase();

View file

@ -17,12 +17,15 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.ibm.icu.impl.IllegalIcuArgumentException;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.FileUtils; import net.osmand.FileUtils;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.PlatformUtil;
import net.osmand.plus.OnDismissDialogFragmentListener; import net.osmand.plus.OnDismissDialogFragmentListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -32,9 +35,12 @@ import net.osmand.plus.dashboard.DashChooseAppDirFragment;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment { public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
private static final Log LOG = PlatformUtil.getLog(DataStoragePlaceDialogFragment.class);
public static final String TAG = "DataStoragePlaceDialogFragment"; public static final String TAG = "DataStoragePlaceDialogFragment";
private static final String STORAGE_READOLNY_KEY = "storage_readolny_key"; private static final String STORAGE_READOLNY_KEY = "storage_readolny_key";
@ -189,12 +195,16 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
private String getFreeSpace(File dir) { private String getFreeSpace(File dir) {
String sz = ""; String sz = "";
if (dir != null && dir.canRead()) { if (dir != null && dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
long size = (long) fs.getAvailableBlocks() * fs.getBlockSize(); long size = (long) fs.getAvailableBlocks() * fs.getBlockSize();
if (size > 0) { if (size > 0) {
sz = AndroidUtils.formatSize(getActivity(), size); sz = AndroidUtils.formatSize(getActivity(), size);
} }
} catch (IllegalIcuArgumentException e) {
LOG.error(e);
}
} }
return sz; return sz;
} }

View file

@ -335,7 +335,8 @@ public class ItemViewHolder {
clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_ENABLE; clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_ENABLE;
} }
} else if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE } else if ((item.getType() == DownloadActivityType.WIKIPEDIA_FILE
|| item.getType() == DownloadActivityType.TRAVEL_FILE)
&& !Version.isPaidVersion(context.getMyApplication())) { && !Version.isPaidVersion(context.getMyApplication())) {
clickAction = RightButtonAction.ASK_FOR_FULL_VERSION_PURCHASE; clickAction = RightButtonAction.ASK_FOR_FULL_VERSION_PURCHASE;
} else if (item.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) { } else if (item.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) {

View file

@ -26,6 +26,7 @@ import androidx.fragment.app.FragmentActivity;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.ValueHolder; import net.osmand.ValueHolder;
import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapDataObject;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
@ -67,6 +68,8 @@ import java.util.TimerTask;
public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmAndLocationListener, public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmAndLocationListener,
AppInitializeListener, DownloadEvents { AppInitializeListener, DownloadEvents {
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(FirstUsageWizardFragment.class);
public static final String TAG = "FirstUsageWizardFrag"; public static final String TAG = "FirstUsageWizardFrag";
public static final int FIRST_USAGE_LOCATION_PERMISSION = 300; public static final int FIRST_USAGE_LOCATION_PERMISSION = 300;
public static final int FIRST_USAGE_REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 400; public static final int FIRST_USAGE_REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 400;
@ -736,8 +739,12 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
private String getFreeSpace(File dir) { private String getFreeSpace(File dir) {
if (dir.canRead()) { if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath()); StatFs fs = new StatFs(dir.getAbsolutePath());
return AndroidUtils.formatSize(getActivity(), (long) fs.getAvailableBlocks() * fs.getBlockSize()); return AndroidUtils.formatSize(getActivity(), (long) fs.getAvailableBlocks() * fs.getBlockSize());
} catch (IllegalArgumentException e) {
LOG.error(e);
}
} }
return ""; return "";
} }

View file

@ -23,12 +23,23 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF
private OsmandApplication app; private OsmandApplication app;
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);
}
}
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
app = requiredMyApplication(); app = requiredMyApplication();
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
int verticalBig = getResources().getDimensionPixelSize(R.dimen.dialog_content_margin); int verticalBig = getResources().getDimensionPixelSize(R.dimen.dialog_content_margin);
int verticalSmall = getResources().getDimensionPixelSize(R.dimen.content_padding_small); int verticalNormal = getResources().getDimensionPixelSize(R.dimen.content_padding);
final View buttonClear = createItem(inflater, ItemType.CLEAR_DATA);
final View buttonCancel = createItem(inflater, ItemType.CANCEL);
items.add(new BottomSheetItemWithDescription.Builder() items.add(new BottomSheetItemWithDescription.Builder()
.setDescription(app.getString(R.string.clear_recorded_data_warning)) .setDescription(app.getString(R.string.clear_recorded_data_warning))
@ -41,7 +52,7 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF
items.add(new DividerSpaceItem(app, verticalBig)); items.add(new DividerSpaceItem(app, verticalBig));
items.add(new BaseBottomSheetItem.Builder() items.add(new BaseBottomSheetItem.Builder()
.setCustomView(TripRecordingActiveBottomSheet.createButton(inflater, ItemType.CLEAR_DATA, nightMode)) .setCustomView(buttonClear)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -54,7 +65,7 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF
items.add(new DividerSpaceItem(app, verticalBig)); items.add(new DividerSpaceItem(app, verticalBig));
items.add(new BaseBottomSheetItem.Builder() items.add(new BaseBottomSheetItem.Builder()
.setCustomView(TripRecordingActiveBottomSheet.createButton(inflater, ItemType.CANCEL, nightMode)) .setCustomView(buttonCancel)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -63,7 +74,11 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF
}) })
.create()); .create());
items.add(new DividerSpaceItem(app, verticalSmall)); items.add(new DividerSpaceItem(app, verticalNormal));
}
private View createItem(LayoutInflater inflater, ItemType type) {
return TripRecordingActiveBottomSheet.createItem(app, nightMode, inflater, type);
} }
@Override @Override
@ -88,12 +103,4 @@ public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogF
protected boolean hideButtonsContainer() { protected boolean hideButtonsContainer() {
return true; 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);
}
}
} }

View file

@ -34,6 +34,15 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
this.mapActivity = mapActivity; this.mapActivity = mapActivity;
} }
public static void showInstance(MapActivity mapActivity, @NonNull FragmentManager fragmentManager, @NonNull Fragment target) {
if (!fragmentManager.isStateSaved()) {
StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment();
fragment.setMapActivity(mapActivity);
fragment.setTargetFragment(target, 0);
fragment.show(fragmentManager, TAG);
}
}
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
app = requiredMyApplication(); app = requiredMyApplication();
@ -41,7 +50,11 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class); plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class);
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
int verticalBig = getResources().getDimensionPixelSize(R.dimen.dialog_content_margin); int verticalBig = getResources().getDimensionPixelSize(R.dimen.dialog_content_margin);
int verticalSmall = getResources().getDimensionPixelSize(R.dimen.content_padding_small); int verticalNormal = getResources().getDimensionPixelSize(R.dimen.content_padding);
// final View buttonDiscard = createItem(inflater, ItemType.STOP_AND_DISCARD);
final View buttonSave = createItem(inflater, ItemType.STOP_AND_SAVE);
final View buttonCancel = createItem(inflater, ItemType.CANCEL);
items.add(new BottomSheetItemWithDescription.Builder() items.add(new BottomSheetItemWithDescription.Builder()
.setDescription(app.getString(R.string.track_recording_description)) .setDescription(app.getString(R.string.track_recording_description))
@ -53,12 +66,12 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
items.add(new DividerSpaceItem(app, verticalBig)); items.add(new DividerSpaceItem(app, verticalBig));
items.add(new BaseBottomSheetItem.Builder() /*items.add(new BaseBottomSheetItem.Builder()
.setCustomView(TripRecordingActiveBottomSheet.createButton(inflater, ItemType.STOP_AND_DISCARD, nightMode)) .setCustomView(buttonDiscard)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
tag = ItemType.STOP_AND_DISCARD; tag = (ItemType) buttonDiscard.getTag();
if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) {
plugin.stopRecording(); plugin.stopRecording();
app.getNotificationHelper().refreshNotifications(); app.getNotificationHelper().refreshNotifications();
@ -69,14 +82,14 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
}) })
.create()); .create());
items.add(new DividerSpaceItem(app, verticalBig)); items.add(new DividerSpaceItem(app, verticalBig));*/
items.add(new BaseBottomSheetItem.Builder() items.add(new BaseBottomSheetItem.Builder()
.setCustomView(TripRecordingActiveBottomSheet.createButton(inflater, ItemType.SAVE_AND_STOP, nightMode)) .setCustomView(buttonSave)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
tag = ItemType.SAVE_AND_STOP; tag = (ItemType) buttonSave.getTag();
if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) {
plugin.saveCurrentTrack(null, mapActivity); plugin.saveCurrentTrack(null, mapActivity);
app.getNotificationHelper().refreshNotifications(); app.getNotificationHelper().refreshNotifications();
@ -86,20 +99,24 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
}) })
.create()); .create());
items.add(new DividerSpaceItem(app, verticalSmall)); items.add(new DividerSpaceItem(app, verticalNormal));
items.add(new BaseBottomSheetItem.Builder() items.add(new BaseBottomSheetItem.Builder()
.setCustomView(TripRecordingActiveBottomSheet.createButton(inflater, ItemType.CANCEL, nightMode)) .setCustomView(buttonCancel)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
tag = ItemType.CANCEL; tag = (ItemType) buttonCancel.getTag();
dismiss(); dismiss();
} }
}) })
.create()); .create());
items.add(new DividerSpaceItem(app, verticalSmall)); items.add(new DividerSpaceItem(app, verticalNormal));
}
private View createItem(LayoutInflater inflater, ItemType type) {
return TripRecordingActiveBottomSheet.createItem(app, nightMode, inflater, type);
} }
@Override @Override
@ -114,10 +131,13 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
if (tag == ItemType.CANCEL) {
Fragment target = getTargetFragment(); Fragment target = getTargetFragment();
if (target instanceof TripRecordingActiveBottomSheet) { if (target instanceof TripRecordingActiveBottomSheet) {
((TripRecordingActiveBottomSheet) target).show(); TripRecordingActiveBottomSheet tripRec = (TripRecordingActiveBottomSheet) target;
if (tag == ItemType.CANCEL) {
tripRec.show();
} else {
tripRec.dismiss();
} }
} }
} }
@ -126,13 +146,4 @@ public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragm
protected boolean hideButtonsContainer() { protected boolean hideButtonsContainer() {
return true; return true;
} }
public static void showInstance(MapActivity mapActivity, @NonNull FragmentManager fragmentManager, @NonNull Fragment target) {
if (!fragmentManager.isStateSaved()) {
StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment();
fragment.setMapActivity(mapActivity);
fragment.setTargetFragment(target, 0);
fragment.show(fragmentManager, TAG);
}
}
} }

View file

@ -43,7 +43,6 @@ import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.DialogButtonType;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.activities.SavingTrackHelper.SaveGpxResult; import net.osmand.plus.activities.SavingTrackHelper.SaveGpxResult;
@ -62,6 +61,8 @@ import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.List;
import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT;
@ -79,6 +80,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
private SelectedGpxFile selectedGpxFile; private SelectedGpxFile selectedGpxFile;
private View statusContainer; private View statusContainer;
private LinearLayout buttonAppearance;
private View buttonSave; private View buttonSave;
private GpxBlockStatisticsBuilder blockStatisticsBuilder; private GpxBlockStatisticsBuilder blockStatisticsBuilder;
@ -128,15 +130,19 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
.create()); .create());
View buttonClear = itemView.findViewById(R.id.button_clear); View buttonClear = itemView.findViewById(R.id.button_clear);
final View buttonOnline = itemView.findViewById(R.id.button_online);
View buttonSegment = itemView.findViewById(R.id.button_segment); View buttonSegment = itemView.findViewById(R.id.button_segment);
buttonSave = itemView.findViewById(R.id.button_save); buttonSave = itemView.findViewById(R.id.button_save);
final 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); View buttonStop = itemView.findViewById(R.id.button_stop);
createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave(), null); createItem(buttonClear, ItemType.CLEAR_DATA, hasDataToSave());
createItem(buttonSegment, ItemType.START_SEGMENT, wasTrackMonitored(), null); createItem(buttonOnline, ItemType.STOP_ONLINE, hasDataToSave());
createItem(buttonPause, wasTrackMonitored() ? ItemType.PAUSE : ItemType.RESUME, true, null); createItem(buttonSegment, ItemType.START_SEGMENT, wasTrackMonitored());
createItem(buttonStop, ItemType.STOP, true, null); createItem(buttonPause, wasTrackMonitored() ? ItemType.PAUSE : ItemType.RESUME, true);
createItem(buttonStop, ItemType.STOP, true);
AndroidUiHelper.updateVisibility(buttonOnline, app.getLiveMonitoringHelper().isLiveMonitoringEnabled());
statusContainer = itemView.findViewById(R.id.status_container); statusContainer = itemView.findViewById(R.id.status_container);
updateStatus(); updateStatus();
@ -162,31 +168,25 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
if (showTitle != null) { if (showTitle != null) {
showTrackTitle.setText(showTitle); showTrackTitle.setText(showTitle);
} }
AndroidUtils.setPadding(buttonShow, AndroidUtils.dpToPx(app, 12f), 0, buttonShow.getPaddingRight(), 0);
showTrackTitle.setTextColor(ContextCompat.getColor(app, getActiveIconColorId(nightMode))); showTrackTitle.setTextColor(ContextCompat.getColor(app, getActiveIconColorId(nightMode)));
showTrackTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); 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)); Typeface typeface = FontCache.getFont(app, app.getResources().getString(R.string.font_roboto_medium));
showTrackTitle.setTypeface(typeface); showTrackTitle.setTypeface(typeface);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
float letterSpacing = AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing); float letterSpacing = AndroidUtils.getFloatValueFromRes(app, R.dimen.text_button_letter_spacing);
showTrackTitle.setLetterSpacing(letterSpacing); showTrackTitle.setLetterSpacing(letterSpacing);
} }
final SwitchCompat showTrackOnMapButton = buttonShow.findViewById(R.id.switch_button); final SwitchCompat showTrackOnMapButton = buttonShow.findViewById(R.id.switch_button);
showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null);
UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT);
final LinearLayout buttonAppearance = showTrackContainer.findViewById(R.id.additional_button); buttonAppearance = showTrackContainer.findViewById(R.id.additional_button);
View divider = buttonAppearance.getChildAt(0); View divider = buttonAppearance.getChildAt(0);
AndroidUiHelper.setVisibility(View.GONE, divider); AndroidUiHelper.setVisibility(View.GONE, divider);
int marginS = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_small); int marginS = app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_small);
UiUtilities.setMargins(buttonAppearance, marginS, 0, 0, 0); UiUtilities.setMargins(buttonAppearance, marginS, 0, 0, 0);
String width = settings.CURRENT_TRACK_WIDTH.get(); updateTrackIcon(buttonAppearance);
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 = 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);
buttonAppearance.setOnClickListener(new View.OnClickListener() { buttonAppearance.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -200,7 +200,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
} }
}); });
createItem(buttonAppearance, ItemType.APPEARANCE, showTrackOnMapButton.isChecked(), null); createItem(buttonAppearance, ItemType.APPEARANCE, showTrackOnMapButton.isChecked());
setShowOnMapBackground(buttonShow, app, showTrackOnMapButton.isChecked(), nightMode); setShowOnMapBackground(buttonShow, app, showTrackOnMapButton.isChecked(), nightMode);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
buttonShow.setBackgroundTintList(null); buttonShow.setBackgroundTintList(null);
@ -211,7 +211,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
boolean checked = !showTrackOnMapButton.isChecked(); boolean checked = !showTrackOnMapButton.isChecked();
showTrackOnMapButton.setChecked(checked); showTrackOnMapButton.setChecked(checked);
app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false);
createItem(buttonAppearance, ItemType.APPEARANCE, checked, null); createItem(buttonAppearance, ItemType.APPEARANCE, checked);
setShowOnMapBackground(buttonShow, app, checked, nightMode); setShowOnMapBackground(buttonShow, app, checked, nightMode);
} }
}); });
@ -225,6 +225,14 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
}); });
buttonOnline.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
settings.LIVE_MONITORING.set(false);
AndroidUiHelper.updateVisibility(buttonOnline, false);
}
});
buttonSegment.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() { buttonSegment.findViewById(R.id.button_container).setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -265,7 +273,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored);
updateStatus(); updateStatus();
createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true, null); createItem(buttonPause, wasTrackMonitored ? ItemType.PAUSE : ItemType.RESUME, true);
} }
}); });
@ -279,12 +287,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
}); });
} }
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(UPDATE_CURRENT_GPX_FILE, true);
}
private void updateStatus() { private void updateStatus() {
TextView statusTitle = statusContainer.findViewById(R.id.text_status); TextView statusTitle = statusContainer.findViewById(R.id.text_status);
AppCompatImageView statusIcon = statusContainer.findViewById(R.id.icon_status); AppCompatImageView statusIcon = statusContainer.findViewById(R.id.icon_status);
@ -304,72 +306,67 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
} }
private void updateTrackIcon(View buttonAppearance) {
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 = 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);
}
private void createItem(View view, ItemType type, boolean enabled) {
createItem(app, nightMode, view, type, enabled, null);
}
private void createItem(View view, ItemType type, boolean enabled, @Nullable String description) { private void createItem(View view, ItemType type, boolean enabled, @Nullable String description) {
createItem(app, nightMode, view, type, enabled, description);
}
public static View createItem(Context context, boolean nightMode, LayoutInflater inflater, ItemType type) {
View button = inflater.inflate(R.layout.bottom_sheet_button_with_icon, null);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding);
params.setMargins(horizontal, 0, horizontal, 0);
button.setLayoutParams(params);
LinearLayout container = button.findViewById(R.id.button_container);
container.setClickable(false);
container.setFocusable(false);
createItem(context, nightMode, button, type, true, null);
return button;
}
public static void createItem(Context context, boolean nightMode, View view, ItemType type, boolean enabled, @Nullable String description) {
view.setTag(type); view.setTag(type);
LinearLayout button = view.findViewById(R.id.button_container); LinearLayout button = view.findViewById(R.id.button_container);
AppCompatImageView icon = view.findViewById(R.id.icon); AppCompatImageView icon = view.findViewById(R.id.icon);
if (icon != null) { if (icon != null) {
setTintedIcon(icon, enabled, nightMode, type); setTintedIcon(context, icon, enabled, nightMode, type);
} }
TextView title = view.findViewById(R.id.button_text); TextView title = view.findViewById(R.id.button_text);
Integer titleId = type.getTitleId(); Integer titleId = type.getTitleId();
if (title != null && titleId != null) { if (title != null && titleId != null) {
title.setText(titleId); title.setText(titleId);
setTextColor(title, enabled, nightMode, type); setTextColor(context, title, enabled, nightMode, type);
} }
TextViewEx desc = view.findViewById(R.id.desc); TextViewEx desc = view.findViewById(R.id.desc);
if (desc != null) { if (desc != null) {
boolean isShowDesc = !Algorithms.isBlank(description); boolean isShowDesc = !Algorithms.isBlank(description);
int marginDesc = isShowDesc ? 0 : app.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); int marginDesc = isShowDesc ? 0 : context.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium);
AndroidUiHelper.updateVisibility(desc, isShowDesc); AndroidUiHelper.updateVisibility(desc, isShowDesc);
if (title != null) { if (title != null) {
UiUtilities.setMargins(title, 0, marginDesc, 0, marginDesc); UiUtilities.setMargins(title, 0, marginDesc, 0, marginDesc);
} }
desc.setText(description); desc.setText(description);
setTextColor(desc, false, nightMode, type); setTextColor(context, desc, false, nightMode, type);
} }
setItemBackground(button != null ? button : (LinearLayout) view, enabled); setItemBackground(context, nightMode, button != null ? button : (LinearLayout) view, enabled);
}
protected static View createButton(LayoutInflater inflater, ItemType type, boolean nightMode) {
View button = inflater.inflate(R.layout.bottom_sheet_button_with_icon, null);
button.setTag(type);
Context context = button.getContext();
LinearLayout container = button.findViewById(R.id.button_container);
container.setClickable(false);
container.setFocusable(false);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding);
params.setMargins(horizontal, 0, horizontal, 0);
button.setLayoutParams(params);
if (type.getTitleId() != null) {
UiUtilities.setupDialogButton(nightMode, button, type.getEffect(), type.getTitleId());
}
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.getEffect() == 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);
if (type.getIconId() != null) {
Drawable drawable = AppCompatResources.getDrawable(context, type.getIconId());
UiUtilities.tintDrawable(drawable, ContextCompat.getColor(context, colorRes));
icon.setImageDrawable(drawable);
}
return button;
} }
private String getTimeTrackSaved() { private String getTimeTrackSaved() {
@ -383,6 +380,12 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
} }
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(UPDATE_CURRENT_GPX_FILE, true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
@ -489,6 +492,13 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
} }
public void show(boolean updateTrackIcon) {
show();
if (updateTrackIcon && buttonAppearance != null) {
updateTrackIcon(buttonAppearance);
}
}
public void hide() { public void hide() {
Dialog dialog = getDialog(); Dialog dialog = getDialog();
if (dialog != null) { if (dialog != null) {
@ -497,31 +507,31 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
public enum ItemType { public enum ItemType {
SHOW_TRACK(R.string.shared_string_show_on_map, null, null), SHOW_TRACK(R.string.shared_string_show_on_map, null),
APPEARANCE(null, null, null), APPEARANCE(null, null),
SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info, 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, null), RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable),
ON_PAUSE(R.string.on_pause, R.drawable.ic_pause, null), ON_PAUSE(R.string.on_pause, R.drawable.ic_pause),
CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark, UiUtilities.DialogButtonType.SECONDARY_HARMFUL), 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, null), 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, null), SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file),
PAUSE(R.string.shared_string_pause, R.drawable.ic_pause, null), PAUSE(R.string.shared_string_pause, R.drawable.ic_pause),
RESUME(R.string.shared_string_resume, R.drawable.ic_play_dark, null), RESUME(R.string.shared_string_resume, R.drawable.ic_play_dark),
STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop, null), STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop),
STOP_AND_DISCARD(R.string.track_recording_stop_without_saving, R.drawable.ic_action_rec_stop, DialogButtonType.SECONDARY_HARMFUL), STOP_AND_DISCARD(R.string.track_recording_stop_without_saving, R.drawable.ic_action_rec_stop),
SAVE_AND_STOP(R.string.track_recording_save_and_stop, R.drawable.ic_action_save_to_file, DialogButtonType.SECONDARY), STOP_AND_SAVE(R.string.track_recording_save_and_stop, R.drawable.ic_action_save_to_file),
CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close, DialogButtonType.SECONDARY); STOP_ONLINE(R.string.live_monitoring_stop, R.drawable.ic_world_globe_dark),
CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close);
@StringRes @StringRes
private final Integer titleId; private final Integer titleId;
@DrawableRes @DrawableRes
private final Integer iconId; private final Integer iconId;
private final DialogButtonType effect; private static final List<ItemType> negative = Arrays.asList(CLEAR_DATA, STOP_AND_DISCARD);
ItemType(@Nullable @StringRes Integer titleId, @Nullable @DrawableRes Integer iconId, @Nullable DialogButtonType effect) { ItemType(@Nullable @StringRes Integer titleId, @Nullable @DrawableRes Integer iconId) {
this.titleId = titleId; this.titleId = titleId;
this.iconId = iconId; this.iconId = iconId;
this.effect = effect;
} }
@Nullable @Nullable
@ -534,53 +544,52 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
return iconId; return iconId;
} }
@Nullable public boolean isNegative() {
public DialogButtonType getEffect() { return negative.contains(this);
return effect;
} }
} }
private void setItemBackground(LinearLayout view, boolean enabled) { public static void setItemBackground(Context context, boolean nightMode, LinearLayout view, boolean enabled) {
Drawable background = AppCompatResources.getDrawable(app, R.drawable.btn_background_inactive_light); Drawable background = AppCompatResources.getDrawable(context, R.drawable.btn_background_inactive_light);
if (background != null && enabled) { if (background != null && enabled) {
ColorStateList iconColorStateList = AndroidUtils.createPressedColorStateList( ColorStateList iconColorStateList = AndroidUtils.createPressedColorStateList(
app, getInactiveButtonColorId(nightMode), getActiveButtonColorId(nightMode) context, getInactiveButtonColorId(nightMode), getActiveButtonColorId(nightMode)
); );
DrawableCompat.setTintList(background, iconColorStateList); DrawableCompat.setTintList(background, iconColorStateList);
} else { } else {
UiUtilities.tintDrawable(background, ContextCompat.getColor(app, getInactiveButtonColorId(nightMode))); UiUtilities.tintDrawable(background, ContextCompat.getColor(context, getInactiveButtonColorId(nightMode)));
} }
view.setBackgroundDrawable(background); view.setBackgroundDrawable(background);
} }
private static void setShowOnMapBackground(LinearLayout view, Context context, boolean checked, boolean nightMode) { public static void setShowOnMapBackground(LinearLayout view, Context context, boolean checked, boolean nightMode) {
Drawable background = AppCompatResources.getDrawable(context, Drawable background = AppCompatResources.getDrawable(context,
nightMode ? checked ? R.drawable.btn_background_inactive_dark : R.drawable.btn_background_stroked_inactive_dark 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); : checked ? R.drawable.btn_background_inactive_light : R.drawable.btn_background_stroked_inactive_light);
view.setBackgroundDrawable(background); view.setBackgroundDrawable(background);
} }
public void setTextColor(TextView tv, boolean enabled, boolean nightMode, ItemType type) { public static void setTextColor(Context context, TextView tv, boolean enabled, boolean nightMode, ItemType type) {
if (tv != null) { if (tv != null) {
int activeColorId = type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete : getActiveTextColorId(nightMode); int activeColorId = type.isNegative() ? R.color.color_osm_edit_delete : getActiveTextColorId(nightMode);
int normalColorId = enabled ? activeColorId : getSecondaryTextColorId(nightMode); int normalColorId = enabled ? activeColorId : getSecondaryTextColorId(nightMode);
ColorStateList textColorStateList = AndroidUtils.createPressedColorStateList(app, normalColorId, getPressedColorId(nightMode)); ColorStateList textColorStateList = AndroidUtils.createPressedColorStateList(context, normalColorId, getPressedColorId(nightMode));
tv.setTextColor(textColorStateList); tv.setTextColor(textColorStateList);
} }
} }
public void setTintedIcon(AppCompatImageView iv, boolean enabled, boolean nightMode, ItemType type) { public static void setTintedIcon(Context context, AppCompatImageView iv, boolean enabled, boolean nightMode, ItemType type) {
Integer iconId = type.getIconId(); Integer iconId = type.getIconId();
if (iv != null && iconId != null) { if (iv != null && iconId != null) {
Drawable icon = AppCompatResources.getDrawable(app, iconId); Drawable icon = AppCompatResources.getDrawable(context, iconId);
int activeColorId = type == ItemType.CLEAR_DATA ? R.color.color_osm_edit_delete : getActiveIconColorId(nightMode); int activeColorId = type.isNegative() ? R.color.color_osm_edit_delete : getActiveIconColorId(nightMode);
int normalColorId = enabled ? activeColorId : getSecondaryIconColorId(nightMode); int normalColorId = enabled ? activeColorId : getSecondaryIconColorId(nightMode);
ColorStateList iconColorStateList = AndroidUtils.createPressedColorStateList(app, normalColorId, getPressedColorId(nightMode)); ColorStateList iconColorStateList = AndroidUtils.createPressedColorStateList(context, normalColorId, getPressedColorId(nightMode));
if (icon != null) { if (icon != null) {
DrawableCompat.setTintList(icon, iconColorStateList); DrawableCompat.setTintList(icon, iconColorStateList);
} }
iv.setImageDrawable(icon); iv.setImageDrawable(icon);
if (type == ItemType.STOP) { if (type.iconId == R.drawable.ic_action_rec_stop) {
int stopSize = iv.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); int stopSize = iv.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(stopSize, stopSize); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(stopSize, stopSize);
iv.setLayoutParams(params); iv.setLayoutParams(params);
@ -589,42 +598,42 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
} }
@ColorRes @ColorRes
private static int getActiveTextColorId(boolean nightMode) { public static int getActiveTextColorId(boolean nightMode) {
return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
} }
@ColorRes @ColorRes
private static int getSecondaryTextColorId(boolean nightMode) { public static int getSecondaryTextColorId(boolean nightMode) {
return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light; return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light;
} }
@ColorRes @ColorRes
private static int getActiveIconColorId(boolean nightMode) { public static int getActiveIconColorId(boolean nightMode) {
return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light; return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
} }
@ColorRes @ColorRes
private static int getSecondaryIconColorId(boolean nightMode) { public static int getSecondaryIconColorId(boolean nightMode) {
return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light; return nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light;
} }
@ColorRes @ColorRes
private static int getActiveButtonColorId(boolean nightMode) { public static int getActiveButtonColorId(boolean nightMode) {
return nightMode ? R.color.active_buttons_and_links_bg_pressed_dark : R.color.active_buttons_and_links_bg_pressed_light; return nightMode ? R.color.active_buttons_and_links_bg_pressed_dark : R.color.active_buttons_and_links_bg_pressed_light;
} }
@ColorRes @ColorRes
private static int getInactiveButtonColorId(boolean nightMode) { public static int getInactiveButtonColorId(boolean nightMode) {
return nightMode ? R.color.inactive_buttons_and_links_bg_dark : R.color.inactive_buttons_and_links_bg_light; return nightMode ? R.color.inactive_buttons_and_links_bg_dark : R.color.inactive_buttons_and_links_bg_light;
} }
@ColorRes @ColorRes
private static int getOsmandIconColorId(boolean nightMode) { public static int getOsmandIconColorId(boolean nightMode) {
return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; return nightMode ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light;
} }
@ColorRes @ColorRes
private static int getPressedColorId(boolean nightMode) { public static int getPressedColorId(boolean nightMode) {
return nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; return nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light;
} }

View file

@ -88,6 +88,7 @@ public class ResourceManager {
public static final String VECTOR_MAP = "#vector_map"; //$NON-NLS-1$ public static final String VECTOR_MAP = "#vector_map"; //$NON-NLS-1$
private static final String INDEXES_CACHE = "ind.cache"; private static final String INDEXES_CACHE = "ind.cache";
public static final String DEFAULT_WIKIVOYAGE_TRAVEL_OBF = "Default_wikivoyage.travel.obf";
private static final Log log = PlatformUtil.getLog(ResourceManager.class); private static final Log log = PlatformUtil.getLog(ResourceManager.class);
@ -638,6 +639,8 @@ public class ResourceManager {
if (Version.isPaidVersion(context)) { if (Version.isPaidVersion(context)) {
collectFiles(context.getAppPath(IndexConstants.WIKI_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files); collectFiles(context.getAppPath(IndexConstants.WIKI_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
collectFiles(context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR), IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT, files); collectFiles(context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR), IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT, files);
} else {
collectFiles(context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR), DEFAULT_WIKIVOYAGE_TRAVEL_OBF, files);
} }
if (OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null || InAppPurchaseHelper.isContourLinesPurchased(context)) { if (OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null || InAppPurchaseHelper.isContourLinesPurchased(context)) {
collectFiles(context.getAppPath(IndexConstants.SRTM_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files); collectFiles(context.getAppPath(IndexConstants.SRTM_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
@ -701,7 +704,7 @@ public class ResourceManager {
} }
boolean wikiMap = (f.getName().contains("_wiki") || f.getName().contains(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)); boolean wikiMap = (f.getName().contains("_wiki") || f.getName().contains(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT));
boolean srtmMap = f.getName().contains(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT); boolean srtmMap = f.getName().contains(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT);
if (mapReader == null || (!Version.isPaidVersion(context) && wikiMap)) { if (mapReader == null || (!Version.isPaidVersion(context) && wikiMap && !f.getName().equals(DEFAULT_WIKIVOYAGE_TRAVEL_OBF))) {
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
} else { } else {
if (mapReader.isBasemap()) { if (mapReader.isBasemap()) {

View file

@ -424,16 +424,13 @@ public class RouteProvider {
if (gpxParams.reverse && gpxParams.routePoints.size() > 1) { if (gpxParams.reverse && gpxParams.routePoints.size() > 1) {
List<Location> gpxRouteLocations = new ArrayList<>(); List<Location> gpxRouteLocations = new ArrayList<>();
List<RouteSegmentResult> gpxRoute = new ArrayList<>(); List<RouteSegmentResult> gpxRoute = new ArrayList<>();
Location start = null; WptPt firstGpxPoint = gpxParams.routePoints.get(0);
for (int i = 0; i < gpxParams.routePoints.size(); i++) { Location start = new Location("", firstGpxPoint.getLatitude(), firstGpxPoint.getLongitude());
WptPt pt = gpxParams.routePoints.get(i);
ApplicationMode appMode = ApplicationMode.valueOfStringKey(pt.getProfileType(), ApplicationMode.DEFAULT); for (int i = 1; i < gpxParams.routePoints.size(); i++) {
LatLon end = new LatLon(pt.getLatitude(), pt.getLongitude()); WptPt gpxPoint = gpxParams.routePoints.get(i);
if (start == null) { ApplicationMode appMode = ApplicationMode.valueOfStringKey(gpxPoint.getProfileType(), ApplicationMode.DEFAULT);
start = new Location(""); LatLon end = new LatLon(gpxPoint.getLatitude(), gpxPoint.getLongitude());
start.setLatitude(routeParams.start.getLatitude());
start.setLongitude(routeParams.start.getLongitude());
}
RouteCalculationParams params = new RouteCalculationParams(); RouteCalculationParams params = new RouteCalculationParams();
params.inSnapToRoadMode = true; params.inSnapToRoadMode = true;
@ -457,7 +454,7 @@ public class RouteProvider {
routeParams.mode.getDefaultSpeed(), new LocationsHolder(locations).getLatLonList())); routeParams.mode.getDefaultSpeed(), new LocationsHolder(locations).getLatLonList()));
} }
gpxRouteLocations.addAll(locations); gpxRouteLocations.addAll(locations);
if (i > 0 && !gpxRouteLocations.isEmpty()) { if (!gpxRouteLocations.isEmpty()) {
gpxRouteLocations.remove(gpxRouteLocations.size() - 1); gpxRouteLocations.remove(gpxRouteLocations.size() - 1);
} }
gpxRoute.addAll(route); gpxRoute.addAll(route);
@ -478,29 +475,29 @@ public class RouteProvider {
RouteCalculationResult result = new RouteCalculationResult(gpxRouteResult, routeParams.start, routeParams.end, RouteCalculationResult result = new RouteCalculationResult(gpxRouteResult, routeParams.start, routeParams.end,
routeParams.intermediates, routeParams.ctx, routeParams.leftSide, null, null, routeParams.mode, false); routeParams.intermediates, routeParams.ctx, routeParams.leftSide, null, null, routeParams.mode, false);
List<Location> gpxRouteLocations = result.getImmutableAllLocations(); List<Location> gpxRouteLocations = result.getImmutableAllLocations();
int gpxNextIndex = calcWholeRoute ? 0 : findStartIndexFromRoute(gpxRouteLocations, routeParams.start, calculateOsmAndRouteParts); int nearestGpxPointInd = calcWholeRoute ? 0 : findNearestGpxPointIndexFromRoute(gpxRouteLocations, routeParams.start, calculateOsmAndRouteParts);
Location gpxNextLocation = null; Location nearestGpxLocation = null;
Location gpxLastLocation = !gpxRouteLocations.isEmpty() ? gpxRouteLocations.get(gpxRouteLocations.size() - 1) : null; Location gpxLastLocation = !gpxRouteLocations.isEmpty() ? gpxRouteLocations.get(gpxRouteLocations.size() - 1) : null;
List<RouteSegmentResult> firstSegmentRoute = null; List<RouteSegmentResult> firstSegmentRoute = null;
List<RouteSegmentResult> lastSegmentRoute = null; List<RouteSegmentResult> lastSegmentRoute = null;
List<RouteSegmentResult> gpxRoute; List<RouteSegmentResult> gpxRoute;
if (gpxNextIndex > 0) { if (nearestGpxPointInd > 0) {
gpxNextLocation = gpxRouteLocations.get(gpxNextIndex); nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
gpxRoute = result.getOriginalRoute(gpxNextIndex); gpxRoute = result.getOriginalRoute(nearestGpxPointInd);
if (gpxRoute.size() > 0) { if (gpxRoute.size() > 0) {
gpxRoute.remove(0); gpxRoute.remove(0);
} }
} else { } else {
if (!gpxRouteLocations.isEmpty()) { if (!gpxRouteLocations.isEmpty()) {
gpxNextLocation = gpxRouteLocations.get(0); nearestGpxLocation = gpxRouteLocations.get(0);
} }
gpxRoute = result.getOriginalRoute(); gpxRoute = result.getOriginalRoute();
} }
if (calculateOsmAndRouteParts if (calculateOsmAndRouteParts
&& routeParams.start != null && gpxNextLocation != null && routeParams.start != null && nearestGpxLocation != null
&& gpxNextLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) { && nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
RouteCalculationResult firstSegmentResult = findOfflineRouteSegment( RouteCalculationResult firstSegmentResult = findOfflineRouteSegment(
routeParams, routeParams.start, new LatLon(gpxNextLocation.getLatitude(), gpxNextLocation.getLongitude())); routeParams, routeParams.start, new LatLon(nearestGpxLocation.getLatitude(), nearestGpxLocation.getLongitude()));
firstSegmentRoute = firstSegmentResult.getOriginalRoute(); firstSegmentRoute = firstSegmentResult.getOriginalRoute();
} }
if (calculateOsmAndRouteParts if (calculateOsmAndRouteParts
@ -750,28 +747,28 @@ public class RouteProvider {
return sublist; return sublist;
} }
private int findStartIndexFromRoute(List<Location> route, Location startLoc, boolean calculateOsmAndRouteParts) { private int findNearestGpxPointIndexFromRoute(List<Location> route, Location startLoc, boolean calculateOsmAndRouteParts) {
float minDist = Integer.MAX_VALUE; float minDist = Integer.MAX_VALUE;
int start = 0; int nearestPointIndex = 0;
if (startLoc != null) { if (startLoc != null) {
for (int i = 0; i < route.size(); i++) { for (int i = 0; i < route.size(); i++) {
float d = route.get(i).distanceTo(startLoc); float d = route.get(i).distanceTo(startLoc);
if (d < minDist) { if (d < minDist) {
start = i; nearestPointIndex = i;
minDist = d; minDist = d;
} }
} }
} }
if (start > 0 && calculateOsmAndRouteParts) { if (nearestPointIndex > 0 && calculateOsmAndRouteParts) {
Location newStartLoc = route.get(start); Location nearestLocation = route.get(nearestPointIndex);
for (int i = start + 1; i < route.size(); i++) { for (int i = nearestPointIndex + 1; i < route.size(); i++) {
Location loc = route.get(i); Location nextLocation = route.get(i);
if (loc.distanceTo(newStartLoc) >= ADDITIONAL_DISTANCE_FOR_START_POINT) { if (nextLocation.distanceTo(nearestLocation) >= ADDITIONAL_DISTANCE_FOR_START_POINT) {
return i; return i;
} }
} }
} }
return start; return nearestPointIndex;
} }
protected String getString(Context ctx, int resId){ protected String getString(Context ctx, int resId){

View file

@ -39,6 +39,7 @@ public class DataStorageHelper {
public final static String MANUALLY_SPECIFIED = "manually_specified"; public final static String MANUALLY_SPECIFIED = "manually_specified";
public final static String MAPS_MEMORY = "maps_memory_used"; public final static String MAPS_MEMORY = "maps_memory_used";
public final static String TRAVEL_MEMORY = "travel_memory_used";
public final static String TERRAIN_MEMORY = "terrain_memory_used"; public final static String TERRAIN_MEMORY = "terrain_memory_used";
public final static String TRACKS_MEMORY = "tracks_memory_used"; public final static String TRACKS_MEMORY = "tracks_memory_used";
public final static String NOTES_MEMORY = "notes_memory_used"; public final static String NOTES_MEMORY = "notes_memory_used";
@ -52,6 +53,7 @@ public class DataStorageHelper {
private ArrayList<MemoryItem> memoryItems = new ArrayList<>(); private ArrayList<MemoryItem> memoryItems = new ArrayList<>();
private MemoryItem mapsMemory; private MemoryItem mapsMemory;
private MemoryItem travelMemory;
private MemoryItem terrainMemory; private MemoryItem terrainMemory;
private MemoryItem tracksMemory; private MemoryItem tracksMemory;
private MemoryItem notesMemory; private MemoryItem notesMemory;
@ -184,11 +186,18 @@ public class DataStorageHelper {
createDirectory(MAPS_PATH, false, EXTENSIONS, true), createDirectory(MAPS_PATH, false, EXTENSIONS, true),
createDirectory(ROADS_INDEX_DIR, true, EXTENSIONS, true), createDirectory(ROADS_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(WIKI_INDEX_DIR, true, EXTENSIONS, true), createDirectory(WIKI_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(WIKIVOYAGE_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(BACKUP_INDEX_DIR, true, EXTENSIONS, true)) createDirectory(BACKUP_INDEX_DIR, true, EXTENSIONS, true))
.createItem(); .createItem();
memoryItems.add(mapsMemory); memoryItems.add(mapsMemory);
travelMemory = MemoryItem.builder()
.setKey(TRAVEL_MEMORY)
.setExtensions(IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT)
.setDirectories(
createDirectory(WIKIVOYAGE_INDEX_DIR, true, EXTENSIONS, true))
.createItem();
memoryItems.add(travelMemory);
terrainMemory = MemoryItem.builder() terrainMemory = MemoryItem.builder()
.setKey(TERRAIN_MEMORY) .setKey(TERRAIN_MEMORY)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT) .setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
@ -270,7 +279,7 @@ public class DataStorageHelper {
public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter uiAdapter) { public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter uiAdapter) {
File rootDir = new File(currentStoragePath); File rootDir = new File(currentStoragePath);
RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(uiAdapter, otherMemory, rootDir, null, null, OTHER_MEMORY); RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(uiAdapter, otherMemory, rootDir, null, null, OTHER_MEMORY);
task.execute(mapsMemory, terrainMemory, tracksMemory, notesMemory); task.execute(mapsMemory, travelMemory, terrainMemory, tracksMemory, notesMemory);
return task; return task;
} }

View file

@ -1,6 +1,7 @@
package net.osmand.plus.track; package net.osmand.plus.track;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -250,7 +251,11 @@ public class GpxBlockStatisticsBuilder {
holder.valueText.setTextColor(activeColor); holder.valueText.setTextColor(activeColor);
holder.titleText.setText(item.title); holder.titleText.setText(item.title);
holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light)); holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
holder.titleText.setWidth(calculateWidthWithin(item.title, item.value)); float letterSpacing = 0.00f;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
letterSpacing = Math.max(holder.valueText.getLetterSpacing(), holder.titleText.getLetterSpacing());
}
holder.titleText.setMinWidth(calculateWidthWithin(letterSpacing, item.title, item.value));
holder.itemView.setOnClickListener(new View.OnClickListener() { holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -283,8 +288,11 @@ public class GpxBlockStatisticsBuilder {
notifyDataSetChanged(); notifyDataSetChanged();
} }
public int calculateWidthWithin(String... texts) { public int calculateWidthWithin(float letterSpacing, String... texts) {
int textWidth = AndroidUtils.getTextMaxWidth(textSize, Arrays.asList(texts)); int textWidth = AndroidUtils.getTextMaxWidth(textSize, Arrays.asList(texts));
if (letterSpacing != 0.00f) {
textWidth += Math.ceil(textWidth * letterSpacing);
}
return Math.min(maxWidthPx, Math.max(minWidthPx, textWidth)); return Math.min(maxWidthPx, Math.max(minWidthPx, textWidth));
} }
} }

View file

@ -385,7 +385,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
if (target instanceof TripRecordingBottomSheet) { if (target instanceof TripRecordingBottomSheet) {
((TripRecordingBottomSheet) target).show(); ((TripRecordingBottomSheet) target).show();
} else if (target instanceof TripRecordingActiveBottomSheet) { } else if (target instanceof TripRecordingActiveBottomSheet) {
((TripRecordingActiveBottomSheet) target).show(); ((TripRecordingActiveBottomSheet) target).show(true);
} }
} }

View file

@ -83,6 +83,7 @@ import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
import net.osmand.plus.widgets.IconPopupMenu; import net.osmand.plus.widgets.IconPopupMenu;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -94,6 +95,8 @@ import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import static net.osmand.plus.activities.MapActivityActions.KEY_LATITUDE;
import static net.osmand.plus.activities.MapActivityActions.KEY_LONGITUDE;
import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING; import static net.osmand.plus.activities.TrackActivity.CURRENT_RECORDING;
import static net.osmand.plus.activities.TrackActivity.TRACK_FILE_NAME; import static net.osmand.plus.activities.TrackActivity.TRACK_FILE_NAME;
import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.isGpxFileSelected; import static net.osmand.plus.myplaces.TrackActivityFragmentAdapter.isGpxFileSelected;
@ -115,7 +118,7 @@ import static net.osmand.plus.track.TrackPointsCard.OPEN_WAYPOINT_INDEX;
public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener, public class TrackMenuFragment extends ContextMenuScrollFragment implements CardListener,
SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OnPointsDeleteListener, SegmentActionsListener, RenameCallback, OnTrackFileMoveListener, OnPointsDeleteListener,
OsmAndLocationListener, OsmAndCompassListener, TrackSelectSegmentBottomSheet.OnSegmentSelectedListener { OsmAndLocationListener, OsmAndCompassListener, OnSegmentSelectedListener {
public static final String OPEN_TRACK_MENU = "open_track_menu"; public static final String OPEN_TRACK_MENU = "open_track_menu";
public static final String RETURN_SCREEN_NAME = "return_screen_name"; public static final String RETURN_SCREEN_NAME = "return_screen_name";
@ -226,18 +229,32 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
app = requireMyApplication(); app = requireMyApplication();
displayHelper = new TrackDisplayHelper(app); displayHelper = new TrackDisplayHelper(app);
updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache(); updateLocationViewCache = app.getUIUtilities().getUpdateLocationViewCache();
if (!selectedGpxFile.isShowCurrentTrack()) {
File file = new File(selectedGpxFile.getGpxFile().path);
displayHelper.setFile(file);
displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file));
}
displayHelper.setGpx(selectedGpxFile.getGpxFile());
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
gpxTitle = !isCurrentRecordingTrack() ? GpxUiHelper.getGpxTitle(fileName)
: app.getResources().getString(R.string.shared_string_currently_recording_track);
toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar); toolbarHeightPx = getResources().getDimensionPixelSize(R.dimen.dashboard_map_toolbar);
if (selectedGpxFile == null && savedInstanceState != null) {
String path = savedInstanceState.getString(TRACK_FILE_NAME);
boolean showCurrentTrack = savedInstanceState.getBoolean(CURRENT_RECORDING);
MapActivity mapActivity = requireMapActivity();
loadSelectedGpxFile(mapActivity, path, showCurrentTrack, new CallbackWithObject<SelectedGpxFile>() {
@Override
public boolean processResult(SelectedGpxFile result) {
selectedGpxFile = result;
setupDisplayHelper();
if (getView() != null) {
initContent(getView());
}
return true;
}
});
if (savedInstanceState.containsKey(KEY_LATITUDE) && savedInstanceState.containsKey(KEY_LONGITUDE)) {
double latitude = savedInstanceState.getDouble(KEY_LATITUDE);
double longitude = savedInstanceState.getDouble(KEY_LONGITUDE);
latLon = new LatLon(latitude, longitude);
}
} else if (selectedGpxFile != null) {
setupDisplayHelper();
}
FragmentActivity activity = requireMyActivity(); FragmentActivity activity = requireMyActivity();
activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
public void handleOnBackPressed() { public void handleOnBackPressed() {
@ -261,6 +278,18 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
}); });
} }
private void setupDisplayHelper() {
if (!selectedGpxFile.isShowCurrentTrack()) {
File file = new File(selectedGpxFile.getGpxFile().path);
displayHelper.setFile(file);
displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file));
}
displayHelper.setGpx(selectedGpxFile.getGpxFile());
String fileName = Algorithms.getFileWithoutDirs(getGpx().path);
gpxTitle = !isCurrentRecordingTrack() ? GpxUiHelper.getGpxTitle(fileName)
: app.getResources().getString(R.string.shared_string_currently_recording_track);
}
public GPXFile getGpx() { public GPXFile getGpx() {
return displayHelper.getGpx(); return displayHelper.getGpx();
} }
@ -300,7 +329,14 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
params.gravity = Gravity.BOTTOM | Gravity.START; params.gravity = Gravity.BOTTOM | Gravity.START;
bottomNav.setLayoutParams(params); bottomNav.setLayoutParams(params);
} }
if (selectedGpxFile != null) {
initContent(view);
}
}
return view;
}
private void initContent(@NonNull View view) {
setupCards(); setupCards();
setupToolbar(); setupToolbar();
updateHeader(); updateHeader();
@ -312,8 +348,6 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
calculateLayoutAndUpdateMenuState(); calculateLayoutAndUpdateMenuState();
} }
} }
return view;
}
private void setHeaderTitle(String text, boolean iconVisibility) { private void setHeaderTitle(String text, boolean iconVisibility) {
headerTitle.setText(text); headerTitle.setText(text);
@ -553,9 +587,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
updateControlsVisibility(true); updateControlsVisibility(true);
startLocationUpdate(); startLocationUpdate();
GpxBlockStatisticsBuilder blockStats = overviewCard.getBlockStatisticsBuilder(); if (overviewCard != null && menuType == TrackMenuType.OVERVIEW && isCurrentRecordingTrack()) {
if (menuType == TrackMenuType.OVERVIEW && isCurrentRecordingTrack()) { overviewCard.getBlockStatisticsBuilder().runUpdatingStatBlocksIfNeeded();
blockStats.runUpdatingStatBlocksIfNeeded();
} }
} }
@ -568,8 +601,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
updateControlsVisibility(false); updateControlsVisibility(false);
stopLocationUpdate(); stopLocationUpdate();
if (overviewCard != null) {
overviewCard.getBlockStatisticsBuilder().stopUpdatingStatBlocks(); overviewCard.getBlockStatisticsBuilder().stopUpdatingStatBlocks();
} }
}
@Override @Override
public void updateLocation(Location location) { public void updateLocation(Location location) {
@ -603,8 +638,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
private void updateDistanceDirection() { private void updateDistanceDirection() {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null && overviewCard != null && overviewCard.getView() != null) {
View view = overviewCard.getView(); View view = overviewCard.getView();
if (mapActivity != null && view != null) {
TextView distanceText = view.findViewById(R.id.distance); TextView distanceText = view.findViewById(R.id.distance);
ImageView direction = view.findViewById(R.id.direction); ImageView direction = view.findViewById(R.id.direction);
app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, latLon); app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, latLon);
@ -677,6 +712,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
public void onSaveInstanceState(@NonNull Bundle outState) { public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putString(TRACK_FILE_NAME, getGpx().path); outState.putString(TRACK_FILE_NAME, getGpx().path);
outState.putBoolean(CURRENT_RECORDING, selectedGpxFile.isShowCurrentTrack()); outState.putBoolean(CURRENT_RECORDING, selectedGpxFile.isShowCurrentTrack());
if (latLon != null) {
outState.putDouble(KEY_LATITUDE, latLon.getLatitude());
outState.putDouble(KEY_LONGITUDE, latLon.getLongitude());
}
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
} }
@ -888,9 +927,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
private void adjustMapPosition(int y) { private void adjustMapPosition(int y) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null && mapActivity.getMapView() != null) {
GPXFile gpxFile = getGpx(); GPXFile gpxFile = getGpx();
MapActivity mapActivity = getMapActivity();
if (mapActivity != null && mapActivity.getMapView() != null && gpxFile != null) {
QuadRect r = gpxFile.getRect(); QuadRect r = gpxFile.getRect();
RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
@ -1204,8 +1243,8 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
} }
public static void showInstance(@NonNull MapActivity mapActivity, @Nullable String path, private static void loadSelectedGpxFile(@NonNull MapActivity mapActivity, @Nullable String path,
boolean showCurrentTrack, @Nullable final LatLon latLon, @Nullable final String returnScreenName) { boolean showCurrentTrack, final CallbackWithObject<SelectedGpxFile> callback) {
OsmandApplication app = mapActivity.getMyApplication(); OsmandApplication app = mapActivity.getMyApplication();
SelectedGpxFile selectedGpxFile; SelectedGpxFile selectedGpxFile;
if (showCurrentTrack) { if (showCurrentTrack) {
@ -1214,7 +1253,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(path); selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(path);
} }
if (selectedGpxFile != null) { if (selectedGpxFile != null) {
showInstance(mapActivity, selectedGpxFile, latLon, returnScreenName); callback.processResult(selectedGpxFile);
} else if (!Algorithms.isEmpty(path)) { } else if (!Algorithms.isEmpty(path)) {
String title = app.getString(R.string.loading_smth, ""); String title = app.getString(R.string.loading_smth, "");
final ProgressDialog progress = ProgressDialog.show(mapActivity, title, app.getString(R.string.loading_data)); final ProgressDialog progress = ProgressDialog.show(mapActivity, title, app.getString(R.string.loading_data));
@ -1228,7 +1267,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
OsmandApplication app = mapActivity.getMyApplication(); OsmandApplication app = mapActivity.getMyApplication();
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().selectGpxFile(result, true, false); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().selectGpxFile(result, true, false);
if (selectedGpxFile != null) { if (selectedGpxFile != null) {
showInstance(mapActivity, selectedGpxFile, latLon, returnScreenName); callback.processResult(selectedGpxFile);
} }
} }
if (progress != null && AndroidUtils.isActivityNotDestroyed(mapActivity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(mapActivity)) {
@ -1241,6 +1280,21 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
} }
public static void showInstance(@NonNull MapActivity mapActivity, @Nullable String path,
boolean showCurrentTrack, @Nullable final LatLon latLon, @Nullable final String returnScreenName) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
loadSelectedGpxFile(mapActivity, path, showCurrentTrack, new CallbackWithObject<SelectedGpxFile>() {
@Override
public boolean processResult(SelectedGpxFile selectedGpxFile) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && selectedGpxFile != null) {
showInstance(mapActivity, selectedGpxFile, latLon, returnScreenName);
}
return true;
}
});
}
public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile, public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile,
@Nullable LatLon latLon, @Nullable String returnScreenName) { @Nullable LatLon latLon, @Nullable String returnScreenName) {
try { try {

View file

@ -0,0 +1,48 @@
package net.osmand.plus.wikivoyage.data;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
public class PopularArticles {
public static final int ARTICLES_PER_PAGE = 30;
private List<TravelArticle> articles;
public PopularArticles() {
this.articles = new ArrayList<>();
}
public PopularArticles(@NonNull PopularArticles articles) {
this.articles = articles.articles;
}
public void clear() {
articles = new ArrayList<>();
}
@NonNull
public List<TravelArticle> getArticles() {
return new ArrayList<>(articles);
}
public boolean add(@NonNull TravelArticle article) {
articles.add(article);
return articles.size() % ARTICLES_PER_PAGE != 0;
}
public boolean contains(@NonNull TravelArticle article) {
return articles.contains(article);
}
public boolean containsByRouteId(@NonNull String routeId) {
for (TravelArticle article : articles) {
if (article.getRouteId().equals(routeId)) {
return true;
}
}
return false;
}
}

View file

@ -55,6 +55,7 @@ import static net.osmand.GPXUtilities.TrkSegment;
import static net.osmand.GPXUtilities.WptPt; import static net.osmand.GPXUtilities.WptPt;
import static net.osmand.GPXUtilities.writeGpxFile; import static net.osmand.GPXUtilities.writeGpxFile;
import static net.osmand.plus.helpers.GpxUiHelper.getGpxTitle; import static net.osmand.plus.helpers.GpxUiHelper.getGpxTitle;
import static net.osmand.plus.wikivoyage.data.PopularArticles.ARTICLES_PER_PAGE;
import static net.osmand.plus.wikivoyage.data.TravelGpx.DIFF_ELE_DOWN; 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.DIFF_ELE_UP;
import static net.osmand.plus.wikivoyage.data.TravelGpx.DISTANCE; import static net.osmand.plus.wikivoyage.data.TravelGpx.DISTANCE;
@ -69,16 +70,16 @@ public class TravelObfHelper implements TravelHelper {
public static final String ROUTE_ARTICLE = "route_article"; public static final String ROUTE_ARTICLE = "route_article";
public static final String ROUTE_ARTICLE_POINT = "route_article_point"; public static final String ROUTE_ARTICLE_POINT = "route_article_point";
public static final String ROUTE_TRACK = "route_track"; public static final String ROUTE_TRACK = "route_track";
public static final int ARTICLE_SEARCH_RADIUS = 50000; public static final int ARTICLE_SEARCH_RADIUS = 50 * 1000;
public static final int SAVED_ARTICLE_SEARCH_RADIUS = 30000; public static final int SAVED_ARTICLE_SEARCH_RADIUS = 30 * 1000;
public static final int MAX_POPULAR_ARTICLES_COUNT = 30; public static final int MAX_SEARCH_RADIUS = 10000 * 1000;
public static final String REF_TAG = "ref"; public static final String REF_TAG = "ref";
public static final String NAME_TAG = "name"; public static final String NAME_TAG = "name";
private final OsmandApplication app; private final OsmandApplication app;
private final Collator collator; private final Collator collator;
private List<TravelArticle> popularArticles = new ArrayList<>(); private PopularArticles popularArticles = new PopularArticles();
private final Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>(); private final Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>();
private final TravelLocalDataHelper localDataHelper; private final TravelLocalDataHelper localDataHelper;
private int searchRadius = ARTICLE_SEARCH_RADIUS; private int searchRadius = ARTICLE_SEARCH_RADIUS;
@ -113,13 +114,13 @@ public class TravelObfHelper implements TravelHelper {
} }
@NonNull @NonNull
public synchronized List<TravelArticle> loadPopularArticles() { public synchronized PopularArticles loadPopularArticles() {
String lang = app.getLanguage(); String lang = app.getLanguage();
List<TravelArticle> popularArticles = new ArrayList<>(this.popularArticles); PopularArticles popularArticles = new PopularArticles(this.popularArticles);
int pagesCount;
if (isAnyTravelBookPresent()) { if (isAnyTravelBookPresent()) {
boolean articlesLimitReached = false;
do { do {
if (foundAmenities.size() - foundAmenitiesIndex < MAX_POPULAR_ARTICLES_COUNT) { if (foundAmenities.size() - foundAmenitiesIndex < ARTICLES_PER_PAGE) {
final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); final LatLon location = app.getMapViewTrackingUtilities().getMapLocation();
for (final BinaryMapIndexReader reader : getReaders()) { for (final BinaryMapIndexReader reader : getReaders()) {
try { try {
@ -145,21 +146,25 @@ public class TravelObfHelper implements TravelHelper {
} }
searchRadius *= 2; searchRadius *= 2;
} }
pagesCount = popularArticles.size() / MAX_POPULAR_ARTICLES_COUNT;
while (foundAmenitiesIndex < foundAmenities.size() - 1) { while (foundAmenitiesIndex < foundAmenities.size() - 1) {
Pair<File, Amenity> amenity = foundAmenities.get(foundAmenitiesIndex); Pair<File, Amenity> fileAmenity = foundAmenities.get(foundAmenitiesIndex);
if (!Algorithms.isEmpty(amenity.second.getName(lang))) { File file = fileAmenity.first;
TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null); Amenity amenity = fileAmenity.second;
if (!Algorithms.isEmpty(amenity.getName(lang))) {
String routeId = amenity.getAdditionalInfo(Amenity.ROUTE_ID);
if (!popularArticles.containsByRouteId(routeId)) {
TravelArticle article = cacheTravelArticles(file, amenity, lang, false, null);
if (article != null && !popularArticles.contains(article)) { if (article != null && !popularArticles.contains(article)) {
popularArticles.add(article); if (!popularArticles.add(article)) {
if (popularArticles.size() >= (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT) { articlesLimitReached = true;
break; break;
} }
} }
} }
}
foundAmenitiesIndex++; foundAmenitiesIndex++;
} }
} while (popularArticles.size() < (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT); } while (!articlesLimitReached && searchRadius < MAX_SEARCH_RADIUS);
} }
this.popularArticles = popularArticles; this.popularArticles = popularArticles;
return popularArticles; return popularArticles;
@ -526,7 +531,7 @@ public class TravelObfHelper implements TravelHelper {
@NonNull @NonNull
@Override @Override
public List<TravelArticle> getPopularArticles() { public List<TravelArticle> getPopularArticles() {
return popularArticles; return popularArticles.getArticles();
} }
@NonNull @NonNull

View file

@ -156,7 +156,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public void addNeededMapsCard(TravelNeededMapsCard card) { public void addNeededMapsCard(TravelNeededMapsCard card) {
this.neededMapsCard = card; this.neededMapsCard = card;
if (neededMapsCardExists(getNeededMapsCardPosition())) { if (isCardExists(getNeededMapsCardPosition(), TravelNeededMapsCard.TYPE)) {
updateNeededMapsCard(false); updateNeededMapsCard(false);
} else if (addItem(getNeededMapsCardPosition(), card)) { } else if (addItem(getNeededMapsCardPosition(), card)) {
notifyDataSetChanged(); notifyDataSetChanged();
@ -172,7 +172,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
return; return;
} }
int pos = getNeededMapsCardPosition(); int pos = getNeededMapsCardPosition();
if (neededMapsCardExists(pos)) { if (isCardExists(pos, TravelNeededMapsCard.TYPE)) {
notifyItemChanged(pos); notifyItemChanged(pos);
} }
} }
@ -180,28 +180,25 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public void removeNeededMapsCard() { public void removeNeededMapsCard() {
this.neededMapsCard = null; this.neededMapsCard = null;
int pos = getNeededMapsCardPosition(); int pos = getNeededMapsCardPosition();
if (neededMapsCardExists(pos)) { if (isCardExists(pos, TravelNeededMapsCard.TYPE)) {
removeItem(pos); removeItem(pos);
notifyItemRemoved(pos); notifyItemRemoved(pos);
} }
} }
private int getNeededMapsCardPosition() { private int getNeededMapsCardPosition() {
if (downloadUpdateCardExists(FIRST_POSITION)) { if (isCardExists(FIRST_POSITION, TravelDownloadUpdateCard.TYPE)) {
return SECOND_POSITION; return SECOND_POSITION;
} }
return FIRST_POSITION; return FIRST_POSITION;
} }
private boolean neededMapsCardExists(int position) {
return items.size() > position && items.get(position).getCardType() == TravelNeededMapsCard.TYPE;
}
public void addDownloadUpdateCard(TravelDownloadUpdateCard card) { public void addDownloadUpdateCard(TravelDownloadUpdateCard card) {
this.downloadCard = card; this.downloadCard = card;
if (downloadUpdateCardExists(getDownloadUpdateCardPosition())) { int pos = getDownloadUpdateCardPosition();
if (isCardExists(pos, TravelDownloadUpdateCard.TYPE)) {
updateDownloadUpdateCard(false); updateDownloadUpdateCard(false);
} else if (addItem(getDownloadUpdateCardPosition(), card)) { } else if (addItem(pos, card)) {
notifyDataSetChanged(); notifyDataSetChanged();
} }
} }
@ -215,7 +212,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
return; return;
} }
int pos = getDownloadUpdateCardPosition(); int pos = getDownloadUpdateCardPosition();
if (downloadUpdateCardExists(pos)) { if (isCardExists(pos, TravelDownloadUpdateCard.TYPE)) {
notifyItemChanged(pos); notifyItemChanged(pos);
} }
} }
@ -223,7 +220,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
public void removeDownloadUpdateCard() { public void removeDownloadUpdateCard() {
this.downloadCard = null; this.downloadCard = null;
int pos = getDownloadUpdateCardPosition(); int pos = getDownloadUpdateCardPosition();
if (downloadUpdateCardExists(pos)) { if (isCardExists(pos, TravelDownloadUpdateCard.TYPE)) {
removeItem(pos); removeItem(pos);
notifyItemRemoved(pos); notifyItemRemoved(pos);
} }
@ -233,7 +230,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
return FIRST_POSITION; return FIRST_POSITION;
} }
private boolean downloadUpdateCardExists(int position) { private boolean isCardExists(int position, int cardType) {
return items.size() > position && items.get(position).getCardType() == TravelDownloadUpdateCard.TYPE; return items.size() > position && items.get(position).getCardType() == cardType;
} }
} }

View file

@ -15,6 +15,7 @@ import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -46,6 +47,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.osmand.plus.download.DownloadResources.WIKIVOYAGE_FILE_FILTER;
import static net.osmand.plus.resources.ResourceManager.DEFAULT_WIKIVOYAGE_TRAVEL_OBF;
import static net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity.*; import static net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity.*;
public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEvents, TravelLocalDataHelper.Listener { public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEvents, TravelLocalDataHelper.Listener {
@ -186,7 +189,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
} }
} }
if (app.getTravelHelper().isAnyTravelBookPresent()) { if (!isOnlyDefaultTravelBookPresent()) {
TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode); TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode);
travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() { travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() {
@Override @Override
@ -248,8 +251,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) { private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) {
final OsmandApplication app = getMyApplication(); if (isOnlyDefaultTravelBookPresent()) {
if (app != null && !app.getTravelHelper().isAnyTravelBookPresent()) {
this.mainIndexItems.clear(); this.mainIndexItems.clear();
this.mainIndexItems.addAll(mainIndexItem); this.mainIndexItems.addAll(mainIndexItem);
addDownloadUpdateCard(); addDownloadUpdateCard();
@ -259,6 +261,18 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
addNeededMapsCard(); addNeededMapsCard();
} }
private boolean isOnlyDefaultTravelBookPresent() {
OsmandApplication app = getMyApplication();
if (app != null && !app.isApplicationInitializing()) {
for (BinaryMapIndexReader reader : app.getResourceManager().getTravelRepositories()) {
if (!reader.getFile().getName().equals(DEFAULT_WIKIVOYAGE_TRAVEL_OBF)) {
return false;
}
}
}
return true;
}
private void addDownloadUpdateCard() { private void addDownloadUpdateCard() {
final OsmandApplication app = getMyApplication(); final OsmandApplication app = getMyApplication();
if (app != null && !mainIndexItems.isEmpty() && SHOW_TRAVEL_UPDATE_CARD) { if (app != null && !mainIndexItems.isEmpty() && SHOW_TRAVEL_UPDATE_CARD) {
@ -286,7 +300,8 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
@Override @Override
public void onIndexItemClick(IndexItem item) { public void onIndexItemClick(IndexItem item) {
if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE && !Version.isPaidVersion(app)) { if ((item.getType() == DownloadActivityType.WIKIPEDIA_FILE
|| item.getType() == DownloadActivityType.TRAVEL_FILE) && !Version.isPaidVersion(app)) {
FragmentManager fm = getFragmentManager(); FragmentManager fm = getFragmentManager();
if (fm != null) { if (fm != null) {
ChoosePlanDialogFragment.showWikipediaInstance(fm); ChoosePlanDialogFragment.showWikipediaInstance(fm);
@ -341,7 +356,8 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
@Override @Override
public void onIndexItemClick(IndexItem item) { public void onIndexItemClick(IndexItem item) {
if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE && !Version.isPaidVersion(app)) { if ((item.getType() == DownloadActivityType.WIKIPEDIA_FILE
|| item.getType() == DownloadActivityType.TRAVEL_FILE) && !Version.isPaidVersion(app)) {
FragmentManager fm = getFragmentManager(); FragmentManager fm = getFragmentManager();
if (fm != null) { if (fm != null) {
ChoosePlanDialogFragment.showWikipediaInstance(fm); ChoosePlanDialogFragment.showWikipediaInstance(fm);
@ -403,7 +419,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
List<IndexItem> allWikivoyageItems = app.getDownloadThread().getIndexes().getWikivoyageItems(); List<IndexItem> allWikivoyageItems = app.getDownloadThread().getIndexes().getWikivoyageItems();
if (allWikivoyageItems != null) { if (allWikivoyageItems != null) {
for (IndexItem item : allWikivoyageItems) { for (IndexItem item : allWikivoyageItems) {
if (!item.isDownloaded() && !mainItems.contains(item)) { if (!item.isDownloaded()
&& !mainItems.contains(item)
&& item.getFileName().contains(WIKIVOYAGE_FILE_FILTER)) {
mainItems.add(item); mainItems.add(item);
} }
} }

View file

@ -111,7 +111,7 @@ public class TravelNeededMapsCard extends BaseTravelCard {
boolean downloading = downloadThread.isDownloading(item); boolean downloading = downloadThread.isDownloading(item);
boolean currentDownloading = downloading && downloadThread.getCurrentDownloadingItem() == item; boolean currentDownloading = downloading && downloadThread.getCurrentDownloadingItem() == item;
boolean lastItem = i == items.size() - 1; boolean lastItem = i == items.size() - 1;
View view = holder.itemsContainer.getChildAt(i); final View view = holder.itemsContainer.getChildAt(i);
if (item.isDownloaded()) { if (item.isDownloaded()) {
view.setOnClickListener(null); view.setOnClickListener(null);
@ -131,12 +131,23 @@ public class TravelNeededMapsCard extends BaseTravelCard {
if (item.isDownloaded()) { if (item.isDownloaded()) {
iconAction.setVisibility(View.GONE); iconAction.setVisibility(View.GONE);
buttonAction.setVisibility(View.GONE); buttonAction.setVisibility(View.GONE);
} else { } else {
boolean showBtn = !paidVersion && item.getType() == DownloadActivityType.WIKIPEDIA_FILE; boolean showBtn = !paidVersion
&& (item.getType() == DownloadActivityType.WIKIPEDIA_FILE
|| item.getType() == DownloadActivityType.TRAVEL_FILE);
iconAction.setVisibility(showBtn ? View.GONE : View.VISIBLE); iconAction.setVisibility(showBtn ? View.GONE : View.VISIBLE);
buttonAction.setVisibility(showBtn ? View.VISIBLE : View.GONE); buttonAction.setVisibility(showBtn ? View.VISIBLE : View.GONE);
if (!showBtn) { if (showBtn) {
buttonAction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.callOnClick();
}
});
} else {
iconAction.setImageDrawable(downloading ? cancelIcon : downloadIcon); iconAction.setImageDrawable(downloading ? cancelIcon : downloadIcon);
buttonAction.setOnClickListener(null);
} }
} }
@ -195,7 +206,7 @@ public class TravelNeededMapsCard extends BaseTravelCard {
* @return true if button is visible, false otherwise. * @return true if button is visible, false otherwise.
*/ */
private boolean updatePrimaryButton(NeededMapsVH vh) { private boolean updatePrimaryButton(NeededMapsVH vh) {
if (showPrimaryButton()) { if (showPrimaryButton() && Version.isPaidVersion(app)) {
boolean enabled = isInternetAvailable(); boolean enabled = isInternetAvailable();
vh.primaryBtnContainer.setVisibility(View.VISIBLE); vh.primaryBtnContainer.setVisibility(View.VISIBLE);
vh.primaryBtnContainer.setBackgroundResource(getPrimaryBtnBgRes(enabled)); vh.primaryBtnContainer.setBackgroundResource(getPrimaryBtnBgRes(enabled));