From 5e68d14273ff365a4840e556051fd6d3ab573615 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 24 Jan 2021 19:30:44 +0200 Subject: [PATCH 01/81] Change UI for graph toggle Change UI for graph toggle (Overview | Altitude | Speed). The same toggle is used in Configure Map -> Terrain. --- OsmAnd/res/layout/center_button_container.xml | 19 ++++ OsmAnd/res/layout/custom_radio_buttons.xml | 56 +----------- .../res/layout/gpx_list_item_tab_content.xml | 2 +- OsmAnd/res/layout/left_button_container.xml | 20 +++++ OsmAnd/res/layout/right_button_container.xml | 19 ++++ OsmAnd/src/net/osmand/plus/UiUtilities.java | 87 +++++++++++++++++++ .../plus/myplaces/GPXItemPagerAdapter.java | 74 +++++++++++----- .../views/controls/PagerSlidingTabStrip.java | 14 +-- 8 files changed, 210 insertions(+), 81 deletions(-) create mode 100644 OsmAnd/res/layout/center_button_container.xml create mode 100644 OsmAnd/res/layout/left_button_container.xml create mode 100644 OsmAnd/res/layout/right_button_container.xml diff --git a/OsmAnd/res/layout/center_button_container.xml b/OsmAnd/res/layout/center_button_container.xml new file mode 100644 index 0000000000..8c8fdf1617 --- /dev/null +++ b/OsmAnd/res/layout/center_button_container.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/custom_radio_buttons.xml b/OsmAnd/res/layout/custom_radio_buttons.xml index d768e58004..d4bd1c8082 100644 --- a/OsmAnd/res/layout/custom_radio_buttons.xml +++ b/OsmAnd/res/layout/custom_radio_buttons.xml @@ -1,6 +1,5 @@ - + - + - - - - - - - - - - - - - + \ No newline at end of file diff --git a/OsmAnd/res/layout/gpx_list_item_tab_content.xml b/OsmAnd/res/layout/gpx_list_item_tab_content.xml index d2ce779b8b..fbe7bf5e1c 100644 --- a/OsmAnd/res/layout/gpx_list_item_tab_content.xml +++ b/OsmAnd/res/layout/gpx_list_item_tab_content.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + + + + + + diff --git a/OsmAnd/res/layout/right_button_container.xml b/OsmAnd/res/layout/right_button_container.xml new file mode 100644 index 0000000000..bb618949af --- /dev/null +++ b/OsmAnd/res/layout/right_button_container.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 94bd3c4bcb..7c9546d93d 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -90,6 +90,12 @@ public class UiUtilities { END, } + public enum CustomRadioButtonTypeGroup { + START, + CENTER, + END, + } + public UiUtilities(OsmandApplication app) { this.app = app; } @@ -484,6 +490,87 @@ public class UiUtilities { } } + public static void updateCustomRadioButtonsGroup(Context app, View buttonsView, boolean nightMode, + CustomRadioButtonTypeGroup buttonType) { + int activeColor = ContextCompat.getColor(app, nightMode + ? R.color.active_color_primary_dark + : R.color.active_color_primary_light); + int inActiveColor = ContextCompat.getColor(app, nightMode + ? R.color.text_color_secondary_dark + : R.color.text_color_secondary_light); + int textColor = ContextCompat.getColor(app, nightMode + ? R.color.text_color_primary_dark + : R.color.text_color_primary_light); + int roundedCorner = AndroidUtils.dpToPx(app, 4); + boolean isLayoutRtl = AndroidUtils.isLayoutRtl(app); + + TextView startButtonText = buttonsView.findViewById(R.id.left_button); + View startButtonContainer = buttonsView.findViewById(R.id.left_button_container); + TextView centerButtonText = buttonsView.findViewById(R.id.center_button); + View centerButtonContainer = buttonsView.findViewById(R.id.center_button_container); + TextView endButtonText = buttonsView.findViewById(R.id.right_button); + View endButtonContainer = buttonsView.findViewById(R.id.right_button_container); + GradientDrawable background = new GradientDrawable(); + background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); + background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f)); + GradientDrawable startButtonSharpCorner = new GradientDrawable(); + startButtonSharpCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); + GradientDrawable endButtonRoundedCorner = new GradientDrawable(); + endButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); + GradientDrawable centerButtonSharpCorner = new GradientDrawable(); + centerButtonSharpCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); + setStartEndCenterRoundedCorner(roundedCorner, isLayoutRtl, startButtonSharpCorner, endButtonRoundedCorner, centerButtonSharpCorner); + + if (buttonType == CustomRadioButtonTypeGroup.START) { + if (isLayoutRtl) { + background.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); + } else { + background.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); + } + endButtonContainer.setBackground(endButtonRoundedCorner); + endButtonText.setTextColor(activeColor); + centerButtonContainer.setBackground(centerButtonSharpCorner); + centerButtonText.setTextColor(activeColor); + endButtonText.setTextColor(activeColor); + startButtonContainer.setBackgroundDrawable(background); + startButtonText.setTextColor(textColor); + } else if (buttonType == CustomRadioButtonTypeGroup.CENTER){ + endButtonContainer.setBackground(endButtonRoundedCorner); + endButtonText.setTextColor(activeColor); + startButtonContainer.setBackground(startButtonSharpCorner); + startButtonText.setTextColor(activeColor); + endButtonText.setTextColor(activeColor); + centerButtonContainer.setBackgroundDrawable(background); + centerButtonText.setTextColor(textColor); + } else { + if (isLayoutRtl) { + background.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); + } else { + background.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); + } + endButtonContainer.setBackgroundDrawable(background); + endButtonText.setTextColor(textColor); + startButtonContainer.setBackground(startButtonSharpCorner); + startButtonText.setTextColor(activeColor); + centerButtonContainer.setBackground(centerButtonSharpCorner); + centerButtonText.setTextColor(activeColor); + } + } + + private static void setStartEndCenterRoundedCorner(int roundedCorner, boolean isLayoutRtl, GradientDrawable startButtonRoundedCorner, GradientDrawable endButtonRoundedCorner, GradientDrawable centerButtonSharpCorner) { + if (isLayoutRtl) { + startButtonRoundedCorner.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); + } else { + startButtonRoundedCorner.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); + } + if (isLayoutRtl) { + endButtonRoundedCorner.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); + } else { + endButtonRoundedCorner.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); + } + centerButtonSharpCorner.setCornerRadii(new float[]{0, 0, 0, 0, 0, 0, 0, 0}); + } + public static void setupCompoundButtonDrawable(Context ctx, boolean nightMode, @ColorInt int activeColor, Drawable drawable) { int inactiveColor = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); int[][] states = new int[][]{ diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index 81d9ee9d72..8cd70de903 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -13,6 +13,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.SwitchCompat; import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager.OnPageChangeListener; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.data.Entry; @@ -23,6 +24,7 @@ import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture; import com.github.mikephil.charting.listener.OnChartGestureListener; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; +import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; @@ -78,7 +80,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private boolean chartClicked; - public GPXItemPagerAdapter(@NonNull PagerSlidingTabStrip tabs, + public GPXItemPagerAdapter(@NonNull final PagerSlidingTabStrip tabs, @NonNull GpxDisplayItem gpxItem, @NonNull TrackDisplayHelper displayHelper, @NonNull SegmentActionsListener actionsListener) { @@ -89,6 +91,34 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid this.actionsListener = actionsListener; app = (OsmandApplication) tabs.getContext().getApplicationContext(); iconsCache = app.getUIUtilities(); + + tabs.setOnPageChangeListener(new OnPageChangeListener() { + + @Override + public void onPageSelected(int arg0) { + UiUtilities.CustomRadioButtonTypeGroup type; + if (arg0 == 0) { + type = UiUtilities.CustomRadioButtonTypeGroup.START; + } else if (arg0 == 1) { + type = UiUtilities.CustomRadioButtonTypeGroup.CENTER; + } else { + type = UiUtilities.CustomRadioButtonTypeGroup.END; + } + + View parent = (View) tabs.getChildAt(0); + UiUtilities.updateCustomRadioButtonsGroup(app, parent, false, type); + } + + @Override + public void onPageScrolled(int arg0, float arg1, int arg2) { + } + + @Override + public void onPageScrollStateChanged(int arg0) { + + } + }); + fetchTabTypes(); } @@ -588,7 +618,15 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid @Override public View getCustomTabView(@NonNull ViewGroup parent, int position) { - View tab = LayoutInflater.from(parent.getContext()).inflate(R.layout.gpx_tab, parent, false); + int layoutId; + if (position == 0) { + layoutId = R.layout.left_button_container; + } else if (position == 1) { + layoutId = R.layout.center_button_container; + } else { + layoutId = R.layout.right_button_container; + } + View tab = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); tab.setTag(tabTypes[position].name()); deselect(tab); return tab; @@ -597,29 +635,25 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid @Override public void select(View tab) { GPXTabItemType tabType = GPXTabItemType.valueOf((String) tab.getTag()); - ImageView img = tab.findViewById(R.id.tab_image); - switch (tabs.getTabSelectionType()) { - case ALPHA: - img.setAlpha(tabs.getTabTextSelectedAlpha()); - break; - case SOLID_COLOR: - img.setImageDrawable(iconsCache.getPaintedIcon(tabType.getIconId(), tabs.getTextColor())); - break; + UiUtilities.CustomRadioButtonTypeGroup type; + if (tabType == GPXTabItemType.GPX_TAB_ITEM_GENERAL) { + type = UiUtilities.CustomRadioButtonTypeGroup.START; + } else if (tabType == GPXTabItemType.GPX_TAB_ITEM_ALTITUDE) { + type = UiUtilities.CustomRadioButtonTypeGroup.CENTER; + } else { + type = UiUtilities.CustomRadioButtonTypeGroup.END; } + View parent = (View) tab.getParent(); + UiUtilities.updateCustomRadioButtonsGroup(app,parent , false, type); + + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) parent.getLayoutParams(); + int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); + int containerMargin = app.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_content_margin_small); + AndroidUtils.setMargins(params, contentPadding, containerMargin, contentPadding, containerMargin); } @Override public void deselect(View tab) { - GPXTabItemType tabType = GPXTabItemType.valueOf((String) tab.getTag()); - ImageView img = tab.findViewById(R.id.tab_image); - switch (tabs.getTabSelectionType()) { - case ALPHA: - img.setAlpha(tabs.getTabTextAlpha()); - break; - case SOLID_COLOR: - img.setImageDrawable(iconsCache.getPaintedIcon(tabType.getIconId(), tabs.getTabInactiveTextColor())); - break; - } } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java index a92d2c5e0a..e38a8619b0 100644 --- a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java +++ b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java @@ -352,13 +352,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { tab_title.setTextColor(pager.getCurrentItem() == i ? tabTextColor : tabInactiveTextColor); break; } - if (pager.getAdapter() instanceof CustomTabProvider) { - if (pager.getCurrentItem() == i) { - ((CustomTabProvider) pager.getAdapter()).select(v); - } else { - ((CustomTabProvider) pager.getAdapter()).deselect(v); - } - } // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a // pre-ICS-build @@ -370,6 +363,13 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { } } } + if (pager.getAdapter() instanceof CustomTabProvider) { + if (pager.getCurrentItem() == i) { + ((CustomTabProvider) pager.getAdapter()).select(v); + } else { + ((CustomTabProvider) pager.getAdapter()).deselect(v); + } + } } } From 3c6b065f50e62d4d1f62a3f123db93b70472afc6 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 24 Jan 2021 23:36:55 +0200 Subject: [PATCH 02/81] null exeption fix --- .../res/layout/gpx_list_item_tab_content.xml | 2 +- OsmAnd/src/net/osmand/plus/UiUtilities.java | 64 +++++++++++++------ .../plus/myplaces/GPXItemPagerAdapter.java | 2 +- .../plus/myplaces/SegmentGPXAdapter.java | 8 +-- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/OsmAnd/res/layout/gpx_list_item_tab_content.xml b/OsmAnd/res/layout/gpx_list_item_tab_content.xml index fbe7bf5e1c..d2ce779b8b 100644 --- a/OsmAnd/res/layout/gpx_list_item_tab_content.xml +++ b/OsmAnd/res/layout/gpx_list_item_tab_content.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + { PagerSlidingTabStrip tabLayout = row.findViewById(R.id.sliding_tabs); tabLayout.setTabBackground(R.color.color_transparent); - tabLayout.setIndicatorColorResource(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light); - tabLayout.setIndicatorBgColorResource(nightMode ? R.color.divider_color_dark : R.color.divider_color_light); - tabLayout.setIndicatorHeight(AndroidUtils.dpToPx(context, 1f)); - if (!nightMode) { - tabLayout.setTextColor(tabLayout.getIndicatorColor()); - tabLayout.setTabInactiveTextColor(ContextCompat.getColor(row.getContext(), R.color.text_color_secondary_light)); - } + tabLayout.setIndicatorHeight(AndroidUtils.dpToPx(context, 0)); tabLayout.setTextSize(AndroidUtils.spToPx(context, 12f)); tabLayout.setShouldExpand(true); WrapContentHeightViewPager pager = row.findViewById(R.id.pager); From 2cdb8953f6af0c3c679cb2f186a03255b3bf830c Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 24 Jan 2021 23:54:44 +0200 Subject: [PATCH 03/81] Update UiUtilities.java --- OsmAnd/src/net/osmand/plus/UiUtilities.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 3890725d8a..43c6ca94c5 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -560,7 +560,7 @@ public class UiUtilities { endButtonContainer.setBackground(endButtonRoundedCorner); endButtonText.setTextColor(activeColor); } else { - endButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); + endButtonRoundedCorner.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); centerButtonContainer.setBackgroundDrawable(endButtonRoundedCorner); centerButtonText.setTextColor(textColor); } From 0bc61f85c1d3d387df504e62fdb0f5f1c4f6341d Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 28 Jan 2021 01:48:44 +0200 Subject: [PATCH 04/81] fix saving correct icon and background type of waypoints after saving current recording track --- .../plus/activities/SavingTrackHelper.java | 137 ++++++++++-------- 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java index ff7039702e..b06d3bb1a5 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java @@ -38,10 +38,10 @@ import java.util.Locale; import java.util.Map; public class SavingTrackHelper extends SQLiteOpenHelper { - + public final static String DATABASE_NAME = "tracks"; //$NON-NLS-1$ - public final static int DATABASE_VERSION = 6; - + public final static int DATABASE_VERSION = 7; + public final static String TRACK_NAME = "track"; //$NON-NLS-1$ public final static String TRACK_COL_DATE = "date"; //$NON-NLS-1$ public final static String TRACK_COL_LAT = "lat"; //$NON-NLS-1$ @@ -50,7 +50,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { public final static String TRACK_COL_SPEED = "speed"; //$NON-NLS-1$ public final static String TRACK_COL_HDOP = "hdop"; //$NON-NLS-1$ public final static String TRACK_COL_HEADING = "heading"; //$NON-NLS-1$ - + public final static String POINT_NAME = "point"; //$NON-NLS-1$ public final static String POINT_COL_DATE = "date"; //$NON-NLS-1$ public final static String POINT_COL_LAT = "lat"; //$NON-NLS-1$ @@ -59,7 +59,9 @@ public class SavingTrackHelper extends SQLiteOpenHelper { public final static String POINT_COL_CATEGORY = "category"; //$NON-NLS-1$ public final static String POINT_COL_DESCRIPTION = "description"; //$NON-NLS-1$ public final static String POINT_COL_COLOR = "color"; //$NON-NLS-1$ - + public final static String POINT_COL_ICON = "icon"; //$NON-NLS-1$ + public final static String POINT_COL_BACKGROUND = "background"; //$NON-NLS-1$ + public final static float NO_HEADING = -1.0f; public final static Log log = PlatformUtil.getLog(SavingTrackHelper.class); @@ -76,8 +78,8 @@ public class SavingTrackHelper extends SQLiteOpenHelper { private SelectedGpxFile currentTrack; private int points; private int trkPoints = 0; - - public SavingTrackHelper(OsmandApplication ctx){ + + public SavingTrackHelper(OsmandApplication ctx) { super(ctx, DATABASE_NAME, null, DATABASE_VERSION); this.ctx = ctx; this.currentTrack = new SelectedGpxFile(); @@ -88,11 +90,11 @@ public class SavingTrackHelper extends SQLiteOpenHelper { prepareCurrentTrackForRecording(); updateScript = "INSERT INTO " + TRACK_NAME + " (" + TRACK_COL_LAT + ", " + TRACK_COL_LON + ", " - + TRACK_COL_ALTITUDE + ", " + TRACK_COL_SPEED + ", " + TRACK_COL_HDOP + ", " - + TRACK_COL_DATE + ", " + TRACK_COL_HEADING + ")" + + TRACK_COL_ALTITUDE + ", " + TRACK_COL_SPEED + ", " + TRACK_COL_HDOP + ", " + + TRACK_COL_DATE + ", " + TRACK_COL_HEADING + ")" + " VALUES (?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ - insertPointsScript = "INSERT INTO " + POINT_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ + insertPointsScript = "INSERT INTO " + POINT_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ } @Override @@ -100,19 +102,19 @@ public class SavingTrackHelper extends SQLiteOpenHelper { createTableForTrack(db); createTableForPoints(db); } - - private void createTableForTrack(SQLiteDatabase db){ + + private void createTableForTrack(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TRACK_NAME + " (" + TRACK_COL_LAT + " double, " + TRACK_COL_LON + " double, " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + TRACK_COL_ALTITUDE + " double, " + TRACK_COL_SPEED + " double, " //$NON-NLS-1$ //$NON-NLS-2$ + TRACK_COL_HDOP + " double, " + TRACK_COL_DATE + " long, " + TRACK_COL_HEADING + " float )"); //$NON-NLS-1$ //$NON-NLS-2$ } - - private void createTableForPoints(SQLiteDatabase db){ + + private void createTableForPoints(SQLiteDatabase db) { try { db.execSQL("CREATE TABLE " + POINT_NAME + " (" + POINT_COL_LAT + " double, " + POINT_COL_LON + " double, " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + POINT_COL_DATE + " long, " + POINT_COL_DESCRIPTION + " text, " + POINT_COL_NAME + " text, " - + POINT_COL_CATEGORY + " text, " + POINT_COL_COLOR + " long" + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + + POINT_COL_CATEGORY + " text, " + POINT_COL_COLOR + " long, " + POINT_COL_ICON + " text, " + POINT_COL_BACKGROUND + " text )"); //$NON-NLS-1$ //$NON-NLS-2$ } catch (RuntimeException e) { // ignore if already exists } @@ -120,25 +122,29 @@ public class SavingTrackHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if(oldVersion < 2){ + if (oldVersion < 2) { createTableForPoints(db); } - if(oldVersion < 3){ + if (oldVersion < 3) { db.execSQL("ALTER TABLE " + TRACK_NAME + " ADD " + TRACK_COL_HDOP + " double"); } - if(oldVersion < 4){ - db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_NAME + " text"); - db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_CATEGORY + " text"); + if (oldVersion < 4) { + db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_NAME + " text"); + db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_CATEGORY + " text"); } - if(oldVersion < 5){ - db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_COLOR + " long"); + if (oldVersion < 5) { + db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_COLOR + " long"); } - if(oldVersion < 6){ - db.execSQL("ALTER TABLE " + TRACK_NAME + " ADD " + TRACK_COL_HEADING + " float"); + if (oldVersion < 6) { + db.execSQL("ALTER TABLE " + TRACK_NAME + " ADD " + TRACK_COL_HEADING + " float"); + } + if (oldVersion < 7) { + db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_ICON + " text"); + db.execSQL("ALTER TABLE " + POINT_NAME + " ADD " + POINT_COL_BACKGROUND + " text"); } } - - + + public long getLastTrackPointTime() { long res = 0; try { @@ -146,7 +152,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { if (db != null) { try { Cursor query = db.rawQuery("SELECT " + TRACK_COL_DATE + " FROM " + TRACK_NAME + " ORDER BY " + TRACK_COL_DATE + " DESC", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if(query.moveToFirst()) { + if (query.moveToFirst()) { res = query.getLong(0); } query.close(); @@ -154,11 +160,11 @@ public class SavingTrackHelper extends SQLiteOpenHelper { db.close(); } } - } catch(RuntimeException e) { + } catch (RuntimeException e) { } return res; } - + public synchronized boolean hasDataToSave() { try { SQLiteDatabase db = getWritableDatabase(); @@ -172,11 +178,11 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } q = db.query(false, POINT_NAME, new String[]{POINT_COL_LAT, POINT_COL_LON}, null, null, null, null, null, null); has = q.moveToFirst(); - while(has) { - if(q.getDouble(0) != 0 || q.getDouble(1) != 0) { + while (has) { + if (q.getDouble(0) != 0 || q.getDouble(1) != 0) { break; } - if(!q.moveToNext()) { + if (!q.moveToNext()) { has = false; break; } @@ -189,7 +195,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { db.close(); } } - } catch(RuntimeException e) { + } catch (RuntimeException e) { return false; } @@ -294,7 +300,8 @@ public class SavingTrackHelper extends SQLiteOpenHelper { private void collectDBPoints(SQLiteDatabase db, Map dataTracks) { Cursor query = db.rawQuery("SELECT " + POINT_COL_LAT + "," + POINT_COL_LON + "," + POINT_COL_DATE + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - + POINT_COL_DESCRIPTION + "," + POINT_COL_NAME + "," + POINT_COL_CATEGORY + "," + POINT_COL_COLOR + " FROM " + POINT_NAME+" ORDER BY " + POINT_COL_DATE +" ASC", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + POINT_COL_DESCRIPTION + "," + POINT_COL_NAME + "," + POINT_COL_CATEGORY + "," + POINT_COL_COLOR + "," + + POINT_COL_ICON + "," + POINT_COL_BACKGROUND + " FROM " + POINT_NAME + " ORDER BY " + POINT_COL_DATE + " ASC", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (query.moveToFirst()) { do { WptPt pt = new WptPt(); @@ -309,18 +316,20 @@ public class SavingTrackHelper extends SQLiteOpenHelper { if (color != 0) { pt.setColor(color); } + pt.setIconName(query.getString(7)); + pt.setBackgroundType(query.getString(8)); // check if name is extension (needed for audio/video plugin & josm integration) - if(pt.name != null && pt.name.length() > 4 && pt.name.charAt(pt.name.length() - 4) == '.') { + if (pt.name != null && pt.name.length() > 4 && pt.name.charAt(pt.name.length() - 4) == '.') { pt.link = pt.name; } - + String date = DateFormat.format("yyyy-MM-dd", time).toString(); //$NON-NLS-1$ GPXFile gpx; if (dataTracks.containsKey(date)) { gpx = dataTracks.get(date); } else { - gpx = new GPXFile(Version.getFullVersion(ctx)); + gpx = new GPXFile(Version.getFullVersion(ctx)); dataTracks.put(date, gpx); } ctx.getSelectedGpxHelper().addPoint(pt, gpx); @@ -329,10 +338,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } query.close(); } - + private void collectDBTracks(SQLiteDatabase db, Map dataTracks) { Cursor query = db.rawQuery("SELECT " + TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - + TRACK_COL_SPEED + "," + TRACK_COL_HDOP + "," + TRACK_COL_DATE + "," + TRACK_COL_HEADING + " FROM " + TRACK_NAME +" ORDER BY " + TRACK_COL_DATE +" ASC", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + TRACK_COL_SPEED + "," + TRACK_COL_HDOP + "," + TRACK_COL_DATE + "," + TRACK_COL_HEADING + " FROM " + TRACK_NAME + " ORDER BY " + TRACK_COL_DATE + " ASC", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ long previousTime = 0; long previousInterval = 0; TrkSegment segment = null; @@ -351,14 +360,14 @@ public class SavingTrackHelper extends SQLiteOpenHelper { pt.heading = heading == NO_HEADING ? Float.NaN : heading; long currentInterval = Math.abs(time - previousTime); boolean newInterval = pt.lat == 0 && pt.lon == 0; - + if (track != null && !newInterval && (!ctx.getSettings().AUTO_SPLIT_RECORDING.get() || currentInterval < 6 * 60 * 1000 || currentInterval < 10 * previousInterval)) { // 6 minute - same segment segment.points.add(pt); } else if (track != null && (ctx.getSettings().AUTO_SPLIT_RECORDING.get() && currentInterval < 2 * 60 * 60 * 1000)) { // 2 hour - same track segment = new TrkSegment(); - if(!newInterval) { + if (!newInterval) { segment.points.add(pt); } track.segments.add(segment); @@ -367,10 +376,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper { track = new Track(); segment = new TrkSegment(); track.segments.add(segment); - if(!newInterval) { + if (!newInterval) { segment.points.add(pt); } - String date = new SimpleDateFormat("yyyy-MM-dd", Locale.US).format(new Date(time));; //$NON-NLS-1$ + String date = new SimpleDateFormat("yyyy-MM-dd", Locale.US).format(new Date(time)); //$NON-NLS-1$ if (dataTracks.containsKey(date)) { GPXFile gpx = dataTracks.get(date); gpx.tracks.add(track); @@ -411,14 +420,14 @@ public class SavingTrackHelper extends SQLiteOpenHelper { dataTracks.remove(date); } } - + public void startNewSegment() { lastTimeUpdated = 0; lastPoint = null; - execWithClose(updateScript, new Object[] { 0, 0, 0, 0, 0, System.currentTimeMillis(), NO_HEADING}); + execWithClose(updateScript, new Object[]{0, 0, 0, 0, 0, System.currentTimeMillis(), NO_HEADING}); addTrackPoint(null, true, System.currentTimeMillis()); } - + public void updateLocation(net.osmand.Location location, Float heading) { // use because there is a bug on some devices with location.getTime() long locationTime = System.currentTimeMillis(); @@ -459,12 +468,12 @@ public class SavingTrackHelper extends SQLiteOpenHelper { ctx.getNotificationHelper().refreshNotification(NotificationType.GPX); } } - + public void insertData(double lat, double lon, double alt, double speed, double hdop, long time, float heading, - OsmandSettings settings) { + OsmandSettings settings) { // * 1000 in next line seems to be wrong with new IntervalChooseDialog // if (time - lastTimeUpdated > settings.SAVE_TRACK_INTERVAL.get() * 1000) { - execWithClose(updateScript, new Object[] { lat, lon, alt, speed, hdop, time, heading }); + execWithClose(updateScript, new Object[]{lat, lon, alt, speed, hdop, time, heading}); boolean newSegment = false; if (lastPoint == null || (time - lastTimeUpdated) > 180 * 1000) { lastPoint = new LatLon(lat, lon); @@ -485,7 +494,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { addTrackPoint(pt, newSegment, time); trkPoints++; } - + private void addTrackPoint(WptPt pt, boolean newSegment, long time) { List points = currentTrack.getModifiablePointsToDisplay(); Track track = currentTrack.getModifiableGpxFile().tracks.get(0); @@ -511,12 +520,12 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } public WptPt insertPointData(double lat, double lon, long time, String description, String name, String category, - int color) { + int color) { return insertPointData(lat, lon, time, description, name, category, color, null, null); } public WptPt insertPointData(double lat, double lon, long time, String description, String name, String category, - int color, String iconName, String backgroundName) { + int color, String iconName, String backgroundName) { final WptPt pt = new WptPt(lat, lon, time, Double.NaN, 0, Double.NaN); pt.name = name; pt.category = category; @@ -529,7 +538,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { ctx.getSelectedGpxHelper().addPoint(pt, currentTrack.getModifiableGpxFile()); currentTrack.getModifiableGpxFile().modifiedTime = time; points++; - execWithClose(insertPointsScript, new Object[] { lat, lon, time, description, name, category, color }); + execWithClose(insertPointsScript, new Object[]{lat, lon, time, description, name, category, color, iconName, backgroundName}); return pt; } @@ -538,7 +547,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } public void updatePointData(WptPt pt, double lat, double lon, long time, String description, String name, - String category, int color, String iconName, String iconBackground) { + String category, int color, String iconName, String iconBackground) { currentTrack.getModifiableGpxFile().modifiedTime = time; List params = new ArrayList<>(); @@ -549,6 +558,8 @@ public class SavingTrackHelper extends SQLiteOpenHelper { params.add(name); params.add(category); params.add(color); + params.add(iconName); + params.add(iconBackground); params.add(pt.getLatitude()); params.add(pt.getLongitude()); @@ -563,7 +574,9 @@ public class SavingTrackHelper extends SQLiteOpenHelper { + POINT_COL_DESCRIPTION + "=?, " + POINT_COL_NAME + "=?, " + POINT_COL_CATEGORY + "=?, " - + POINT_COL_COLOR + "=? " + + POINT_COL_COLOR + "=?, " + + POINT_COL_ICON + "=?, " + + POINT_COL_BACKGROUND + "=? " + "WHERE " + POINT_COL_LAT + "=? AND " + POINT_COL_LON + "=? AND " @@ -662,10 +675,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } } - public void loadGpxFromDatabase(){ + public void loadGpxFromDatabase() { Map files = collectRecordedData(); currentTrack.getModifiableGpxFile().tracks.clear(); - for (Map.Entry entry : files.entrySet()){ + for (Map.Entry entry : files.entrySet()) { ctx.getSelectedGpxHelper().addPoints(entry.getValue().getPoints(), currentTrack.getModifiableGpxFile()); currentTrack.getModifiableGpxFile().tracks.addAll(entry.getValue().tracks); } @@ -679,10 +692,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper { } private void prepareCurrentTrackForRecording() { - if(currentTrack.getModifiableGpxFile().tracks.size() == 0) { + if (currentTrack.getModifiableGpxFile().tracks.size() == 0) { currentTrack.getModifiableGpxFile().tracks.add(new Track()); } - while(currentTrack.getPointsToDisplay().size() < currentTrack.getModifiableGpxFile().tracks.size()) { + while (currentTrack.getPointsToDisplay().size() < currentTrack.getModifiableGpxFile().tracks.size()) { TrkSegment trkSegment = new TrkSegment(); currentTrack.getModifiablePointsToDisplay().add(trkSegment); } @@ -705,7 +718,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper { public int getPoints() { return points; } - + public int getTrkPoints() { return trkPoints; } @@ -717,11 +730,11 @@ public class SavingTrackHelper extends SQLiteOpenHelper { public GPXFile getCurrentGpx() { return currentTrack.getGpxFile(); } - + public SelectedGpxFile getCurrentTrack() { return currentTrack; } - + public class SaveGpxResult { public SaveGpxResult(List warnings, List filenames) { From fb9afd7119fd74c78a3f03ed9d4d9c6c1d16876c Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 28 Jan 2021 17:18:18 +0500 Subject: [PATCH 05/81] Test solution --- .../osmand/plus/activities/MapActivity.java | 4 +- .../plus/importfiles/SettingsImportTask.java | 2 +- .../backend/backup/SettingsHelper.java | 123 ++++++++++++++---- .../fragments/ExportSettingsFragment.java | 2 +- 4 files changed, 103 insertions(+), 28 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index eb6dcbfbb7..7b81a13e0a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -652,7 +652,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); setIntent(intent); - intentHelper.parseLaunchIntents(); + if (!intentHelper.parseLaunchIntents()) { + intentHelper.parseContentIntent(); + } } @Override diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java index 0a5e0370af..1f886a23bb 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java @@ -102,7 +102,7 @@ class SettingsImportTask extends BaseLoadAsyncTask { } } else { Map> allSettingsMap = getSettingsToOperate(pluginIndependentItems, false); - List settingsList = settingsHelper.getFilteredSettingsItems(allSettingsMap, settingsTypes, false); + List settingsList = settingsHelper.getFilteredSettingsItems(allSettingsMap, settingsTypes, pluginIndependentItems, false); settingsHelper.checkDuplicates(file, settingsList, settingsList, getDuplicatesListener(file, replace)); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java index 7008425f14..1fdfef081b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java @@ -480,19 +480,21 @@ public class SettingsHelper { typesMap.putAll(getMyPlacesItems()); typesMap.putAll(getResourcesItems()); - return getFilteredSettingsItems(typesMap, settingsTypes, export); + return getFilteredSettingsItems(typesMap, settingsTypes, null, export); } - public List getFilteredSettingsItems(Map> allSettingsMap, - List settingsTypes, boolean export) { - List settingsItems = new ArrayList<>(); + public List getFilteredSettingsItems( + Map> allSettingsMap, List settingsTypes, + List settingsItems, boolean export + ) { + List filteredSettingsItems = new ArrayList<>(); for (ExportSettingsType settingsType : settingsTypes) { List settingsDataObjects = allSettingsMap.get(settingsType); if (settingsDataObjects != null) { - settingsItems.addAll(prepareSettingsItems(settingsDataObjects, export)); + filteredSettingsItems.addAll(prepareSettingsItems(settingsDataObjects, settingsItems, export)); } } - return settingsItems; + return filteredSettingsItems; } public Map getSettingsByCategory(boolean addProfiles) { @@ -693,8 +695,8 @@ public class SettingsHelper { return files; } - public List prepareSettingsItems(List data, boolean export) { - List settingsItems = new ArrayList<>(); + public List prepareSettingsItems(List data, List settingsItems, boolean export) { + List result = new ArrayList<>(); List quickActions = new ArrayList<>(); List poiUIFilters = new ArrayList<>(); List tileSourceTemplates = new ArrayList<>(); @@ -719,9 +721,9 @@ public class SettingsHelper { try { File file = (File) object; if (file.getName().endsWith(IndexConstants.GPX_FILE_EXT)) { - settingsItems.add(new GpxSettingsItem(app, file)); + result.add(new GpxSettingsItem(app, file)); } else { - settingsItems.add(new FileSettingsItem(app, file)); + result.add(new FileSettingsItem(app, file)); } } catch (IllegalArgumentException e) { LOG.warn("Trying to export unsuported file type", e); @@ -746,65 +748,136 @@ public class SettingsHelper { } else if (object instanceof HistoryEntry) { historyEntries.add((HistoryEntry) object); } else if (object instanceof GlobalSettingsItem) { - settingsItems.add((GlobalSettingsItem) object); + result.add((GlobalSettingsItem) object); } else if (object instanceof OnlineRoutingEngine) { onlineRoutingEngines.add((OnlineRoutingEngine) object); } } if (!quickActions.isEmpty()) { - settingsItems.add(new QuickActionsSettingsItem(app, quickActions)); + result.add(new QuickActionsSettingsItem(app, getBaseQuickActionsSettingsItem(settingsItems), quickActions)); } if (!poiUIFilters.isEmpty()) { - settingsItems.add(new PoiUiFiltersSettingsItem(app, poiUIFilters)); + result.add(new PoiUiFiltersSettingsItem(app, getBasePoiUiFiltersSettingsItem(settingsItems), poiUIFilters)); } if (!tileSourceTemplates.isEmpty()) { - settingsItems.add(new MapSourcesSettingsItem(app, tileSourceTemplates)); + result.add(new MapSourcesSettingsItem(app, getBaseMapSourcesSettingsItem(settingsItems), tileSourceTemplates)); } if (!avoidRoads.isEmpty()) { - settingsItems.add(new AvoidRoadsSettingsItem(app, avoidRoads)); + result.add(new AvoidRoadsSettingsItem(app, getBaseAvoidRoadsSettingsItem(settingsItems), avoidRoads)); } if (!appModeBeans.isEmpty()) { for (ApplicationModeBean modeBean : appModeBeans) { if (export) { ApplicationMode mode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); if (mode != null) { - settingsItems.add(new ProfileSettingsItem(app, mode)); + result.add(new ProfileSettingsItem(app, mode)); } } else { - settingsItems.add(new ProfileSettingsItem(app, null, modeBean)); + result.add(new ProfileSettingsItem(app, getBaseProfileSettingsItem(modeBean, settingsItems), modeBean)); } } } if (!osmNotesPointList.isEmpty()) { - settingsItems.add(new OsmNotesSettingsItem(app, osmNotesPointList)); + OsmNotesSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_NOTES, OsmNotesSettingsItem.class, settingsItems); + result.add(new OsmNotesSettingsItem(app, baseItem, osmNotesPointList)); } if (!osmEditsPointList.isEmpty()) { - settingsItems.add(new OsmEditsSettingsItem(app, osmEditsPointList)); + OsmEditsSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_EDITS, OsmEditsSettingsItem.class, settingsItems); + result.add(new OsmEditsSettingsItem(app, baseItem, osmEditsPointList)); } if (!favoriteGroups.isEmpty()) { - settingsItems.add(new FavoritesSettingsItem(app, favoriteGroups)); + FavoritesSettingsItem baseItem = getBaseItem(SettingsItemType.FAVOURITES, FavoritesSettingsItem.class, settingsItems); + result.add(new FavoritesSettingsItem(app, baseItem, favoriteGroups)); } if (!markersGroups.isEmpty()) { List mapMarkers = new ArrayList<>(); for (MapMarkersGroup group : markersGroups) { mapMarkers.addAll(group.getMarkers()); } - settingsItems.add(new MarkersSettingsItem(app, mapMarkers)); + MarkersSettingsItem baseItem = getBaseItem(SettingsItemType.ACTIVE_MARKERS, MarkersSettingsItem.class, settingsItems); + result.add(new MarkersSettingsItem(app, baseItem, mapMarkers)); } if (!markersHistoryGroups.isEmpty()) { List mapMarkers = new ArrayList<>(); for (MapMarkersGroup group : markersHistoryGroups) { mapMarkers.addAll(group.getMarkers()); } - settingsItems.add(new HistoryMarkersSettingsItem(app, mapMarkers)); + HistoryMarkersSettingsItem baseItem = getBaseItem(SettingsItemType.HISTORY_MARKERS, HistoryMarkersSettingsItem.class, settingsItems); + result.add(new HistoryMarkersSettingsItem(app, baseItem, mapMarkers)); } if (!historyEntries.isEmpty()) { - settingsItems.add(new SearchHistorySettingsItem(app, historyEntries)); + SearchHistorySettingsItem baseItem = getBaseItem(SettingsItemType.SEARCH_HISTORY, SearchHistorySettingsItem.class, settingsItems); + result.add(new SearchHistorySettingsItem(app, baseItem, historyEntries)); } if (!onlineRoutingEngines.isEmpty()) { - settingsItems.add(new OnlineRoutingSettingsItem(app, onlineRoutingEngines)); + OnlineRoutingSettingsItem baseItem = getBaseItem(SettingsItemType.ONLINE_ROUTING_ENGINES, OnlineRoutingSettingsItem.class, settingsItems); + result.add(new OnlineRoutingSettingsItem(app, baseItem, onlineRoutingEngines)); } - return settingsItems; + return result; + } + + @Nullable + private ProfileSettingsItem getBaseProfileSettingsItem(ApplicationModeBean modeBean, List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == SettingsItemType.PROFILE) { + ProfileSettingsItem profileItem = (ProfileSettingsItem) settingsItem; + ApplicationModeBean bean = profileItem.getModeBean(); + if (Algorithms.objectEquals(bean.stringKey, modeBean.stringKey) && Algorithms.objectEquals(bean.userProfileName, modeBean.userProfileName)) { + return profileItem; + } + } + } + return null; + } + + @Nullable + private QuickActionsSettingsItem getBaseQuickActionsSettingsItem(List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == SettingsItemType.QUICK_ACTIONS) { + return (QuickActionsSettingsItem) settingsItem; + } + } + return null; + } + + @Nullable + private PoiUiFiltersSettingsItem getBasePoiUiFiltersSettingsItem(List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == SettingsItemType.POI_UI_FILTERS) { + return (PoiUiFiltersSettingsItem) settingsItem; + } + } + return null; + } + + @Nullable + private MapSourcesSettingsItem getBaseMapSourcesSettingsItem(List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == SettingsItemType.MAP_SOURCES) { + return (MapSourcesSettingsItem) settingsItem; + } + } + return null; + } + + @Nullable + private AvoidRoadsSettingsItem getBaseAvoidRoadsSettingsItem(List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == SettingsItemType.AVOID_ROADS) { + return (AvoidRoadsSettingsItem) settingsItem; + } + } + return null; + } + + @Nullable + private T getBaseItem(SettingsItemType settingsItemType, Class clazz, List settingsItems) { + for (SettingsItem settingsItem : settingsItems) { + if (settingsItem.getType() == settingsItemType && clazz.isInstance(settingsItem)) { + return clazz.cast(settingsItem); + } + } + return null; } public static Map getSettingsToOperateByCategory(List items, boolean importComplete) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java index 586b6f0db3..f38a0ba77a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java @@ -150,7 +150,7 @@ public class ExportSettingsFragment extends BaseSettingsListFragment { showExportProgressDialog(); File tempDir = FileUtils.getTempDir(app); String fileName = getFileName(); - List items = app.getSettingsHelper().prepareSettingsItems(adapter.getData(), true); + List items = app.getSettingsHelper().prepareSettingsItems(adapter.getData(), null, true); progress.setMax(getMaxProgress(items)); app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), items, true); } From 65facb4af39b7e41a9e37ed720cc2896ed6e1878 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 28 Jan 2021 18:11:24 +0500 Subject: [PATCH 06/81] Add silent setting --- .../customization/ProfileSettingsParams.java | 13 +++++++++++-- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 4 ++-- OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java index 00c68851e7..afca79aa0e 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java @@ -15,16 +15,18 @@ public class ProfileSettingsParams extends AidlParams { public static final String VERSION_KEY = "version"; public static final String REPLACE_KEY = "replace"; + public static final String SILENT_IMPORT_KEY = "silent_import"; public static final String LATEST_CHANGES_KEY = "latestChanges"; public static final String PROFILE_SETTINGS_URI_KEY = "profileSettingsUri"; private Uri profileSettingsUri; private String latestChanges; private int version; private ArrayList settingsTypeKeyList = new ArrayList<>(); - boolean replace; + private boolean silent; + private boolean replace; public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace, - String latestChanges, int version) { + boolean silent, String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; for (AExportSettingsType settingsType : settingsTypeList) { settingsTypeKeyList.add(settingsType.name()); @@ -32,6 +34,7 @@ public class ProfileSettingsParams extends AidlParams { this.replace = replace; this.latestChanges = latestChanges; this.version = version; + this.silent = silent; } public ProfileSettingsParams(Parcel in) { @@ -70,6 +73,10 @@ public class ProfileSettingsParams extends AidlParams { return replace; } + public boolean isSilent() { + return silent; + } + @Override public void writeToBundle(Bundle bundle) { bundle.putInt(VERSION_KEY, version); @@ -77,6 +84,7 @@ public class ProfileSettingsParams extends AidlParams { bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri); bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList); bundle.putBoolean(REPLACE_KEY, replace); + bundle.putBoolean(SILENT_IMPORT_KEY, silent); } @Override @@ -86,5 +94,6 @@ public class ProfileSettingsParams extends AidlParams { profileSettingsUri = bundle.getParcelable(PROFILE_SETTINGS_URI_KEY); settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY); replace = bundle.getBoolean(REPLACE_KEY); + silent = bundle.getBoolean(SILENT_IMPORT_KEY); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 1dc3e00d98..033fceff1a 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -2297,12 +2297,12 @@ public class OsmandAidlApi { } public boolean importProfileV2(final Uri profileUri, ArrayList settingsTypeKeys, boolean replace, - String latestChanges, int version) { + boolean silent, String latestChanges, int version) { if (profileUri != null) { Bundle bundle = new Bundle(); bundle.putStringArrayList(SettingsHelper.SETTINGS_TYPE_LIST_KEY, settingsTypeKeys); bundle.putBoolean(REPLACE_KEY, replace); - bundle.putBoolean(SILENT_IMPORT_KEY, true); + bundle.putBoolean(SILENT_IMPORT_KEY, silent); bundle.putString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY, latestChanges); bundle.putInt(SettingsHelper.SETTINGS_VERSION_KEY, version); diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index ed7ab614f3..fcd5d5159e 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -1270,7 +1270,7 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener try { OsmandAidlApi api = getApi("importProfile"); return api != null && api.importProfileV2(params.getProfileSettingsUri(), params.getSettingsTypeKeys(), - params.isReplace(), params.getLatestChanges(), params.getVersion()); + params.isReplace(), params.isSilent(), params.getLatestChanges(), params.getVersion()); } catch (Exception e) { handleException(e); return false; From 1f345d0dfd0a714b65fbaa8b9b53e833a3a33560 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 28 Jan 2021 18:19:30 +0500 Subject: [PATCH 07/81] Small edit --- .../osmand/plus/settings/backend/backup/SettingsHelper.java | 4 ++-- .../plus/settings/fragments/ExportSettingsFragment.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java index 1fdfef081b..9a50851a56 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java @@ -480,12 +480,12 @@ public class SettingsHelper { typesMap.putAll(getMyPlacesItems()); typesMap.putAll(getResourcesItems()); - return getFilteredSettingsItems(typesMap, settingsTypes, null, export); + return getFilteredSettingsItems(typesMap, settingsTypes, Collections.emptyList(), export); } public List getFilteredSettingsItems( Map> allSettingsMap, List settingsTypes, - List settingsItems, boolean export + @NonNull List settingsItems, boolean export ) { List filteredSettingsItems = new ArrayList<>(); for (ExportSettingsType settingsType : settingsTypes) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java index f38a0ba77a..6fef4d4e03 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsFragment.java @@ -36,6 +36,7 @@ import org.apache.commons.logging.Log; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; @@ -150,7 +151,7 @@ public class ExportSettingsFragment extends BaseSettingsListFragment { showExportProgressDialog(); File tempDir = FileUtils.getTempDir(app); String fileName = getFileName(); - List items = app.getSettingsHelper().prepareSettingsItems(adapter.getData(), null, true); + List items = app.getSettingsHelper().prepareSettingsItems(adapter.getData(), Collections.emptyList(), true); progress.setMax(getMaxProgress(items)); app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), items, true); } From 111e2791090ada3346ad0af9c6a208a606e341da Mon Sep 17 00:00:00 2001 From: Damjan Gerl Date: Wed, 27 Jan 2021 16:58:34 +0000 Subject: [PATCH 08/81] Translated using Weblate (Slovenian) Currently translated at 72.9% (2663 of 3651 strings) --- OsmAnd/res/values-sl/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-sl/strings.xml b/OsmAnd/res/values-sl/strings.xml index 89091ce1d4..0cb17c35f4 100644 --- a/OsmAnd/res/values-sl/strings.xml +++ b/OsmAnd/res/values-sl/strings.xml @@ -3305,4 +3305,8 @@ MTB Napaka strežnika: %1$s To ime že obstaja + Preberi v celoti + Uredi opis + Brisanje točk + Kopiraj na oznake na zemljevidu \ No newline at end of file From fe2e610b0577de8f624be798402dc8eb1978b504 Mon Sep 17 00:00:00 2001 From: solokot Date: Wed, 27 Jan 2021 15:45:19 +0000 Subject: [PATCH 09/81] Translated using Weblate (Russian) Currently translated at 99.5% (3633 of 3651 strings) --- OsmAnd/res/values-ru/strings.xml | 57 +++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 33236ca153..a0a8f5fdea 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1185,7 +1185,7 @@ Нет маршрута Включите GPS в настройках Показывать направление к пункту назначения - Включите плагин «Запись поездки» для использования сервисов мониторинга (запись GPX, сопровождение в реальном времени) + Включите плагин «Запись поездки» для использования служб мониторинга (запись GPX, сопровождение в реальном времени) Выберите цветовую схему дорог: Цветовая схема дорог Ш %1$.3f Д %2$.3f @@ -1731,7 +1731,7 @@ выбранные Нет Отменить выбор - Отменить выбор всех + Отменить выбор Поделиться Мои места Избранные @@ -3225,7 +3225,7 @@ \n Контурные линии и затенение рельефа Предпочитать грунтовые дороги - Предпочитать грунтовые дороги. + Предпочитать грунтовые дороги Вы уверены, что хотите обновить все карты (%1$d)\? Вы можете применить это ко всем или только к выбранному профилю. Общий @@ -3713,7 +3713,7 @@ Удалить ближайший пункт Задайте название точки Следующая точка маршрута будет удалена. Если это конечный пункт, навигация завершится. - Информация о достопримечательностях из Википедии. Ваш карманный офлайн-путеводитель — просто включите плагин Википедии и читайте об объектах вокруг вас. + Информация о достопримечательностях из Википедии, карманного автономного путеводителя со статьями о местах и направлениях. Скачать карты Википедии Эндуро мотоцикл Мотороллер @@ -3937,4 +3937,53 @@ Папки Выбор папки Выберите папку или добавьте новую + Время голосовых подсказок + Можно использовать данные о высотах для учёта подъёма/спуска поездки + Предпочитать пешеходные маршруты + Подтип + Введите параметр + Пешеход + Самокат + Анализ по интервалам (по отдельности) + Заблаговременно + Заранее + При прохождении + При приближении + Инвалидная коляска + Пеший туризм + Малый грузовик + Грузовик + Копировать в маркеры + Копировать в избранное + Удалить онлайн-маршрутизатор\? + Предпочитать пешеходные маршруты + Добавить онлайн-маршрутизатор + Редактировать онлайн-маршрутизатор + Ключ API + URL-адрес сервера + Оставить пустым, если не + URL со всеми параметрами будет выглядеть так: + Тест расчёта маршрута + Автомобиль + Онлайн-маршрутизатор + Онлайн-маршрутизаторы + Пусто + Отправить в OpenStreetMap + Редактировать трек + Переименовать трек + Изменить папку + сек. + Вне маршрута + Прибытие в пункт назначения + Поворот + Интервалы времени и расстояния + Время объявления + Время объявления различных голосовых подсказок зависит от типа подсказки, текущей скорости навигации и скорости навигации по умолчанию. + Начать запись + Показать трек на карте + Ошибка сервера: %1$s + Имя уже существует + Читать полностью + Редактировать описание + Удалить путевые точки \ No newline at end of file From 624c2419f4af2e97362a5ffb5a4ee6c3212672ab Mon Sep 17 00:00:00 2001 From: ace shadow Date: Wed, 27 Jan 2021 23:39:53 +0000 Subject: [PATCH 10/81] Translated using Weblate (Slovak) Currently translated at 100.0% (3651 of 3651 strings) --- OsmAnd/res/values-sk/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 95f34a3db1..2da9b2324b 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -3995,4 +3995,10 @@ Chyba servera: %1$s Názov už existuje Odbočiť + Odstrániť túto online navigačnú službu\? + Prečítať celé + Upraviť popis + Odstrániť body trasy + Skopírovať do mapových značiek + Skopírovať do obľúbených \ No newline at end of file From 45357c21397989fa550424d3cf20d0a38c363049 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Wed, 27 Jan 2021 12:59:17 +0000 Subject: [PATCH 11/81] Translated using Weblate (Arabic) Currently translated at 100.0% (3651 of 3651 strings) --- OsmAnd/res/values-ar/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 8929bd6f4d..699c82cd8e 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4063,4 +4063,10 @@ MTB خطأ في الخادم: %1$s الاسم موجود بالفعل + هل تريد حذف محرك التوجيه عبر الإنترنت؟ + قراءة كاملة + تحرير الوصف + حذف نقاط الطريق + نسخ لعلامات الخريطة + نسخ للمفضلة \ No newline at end of file From 092f990229c4e19cd7fd84a0c8a4ec63661fa53f Mon Sep 17 00:00:00 2001 From: nasr pen Date: Wed, 27 Jan 2021 09:10:59 +0000 Subject: [PATCH 12/81] Translated using Weblate (Arabic) Currently translated at 100.0% (3651 of 3651 strings) --- OsmAnd/res/values-ar/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 699c82cd8e..4b91263f2d 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -3513,7 +3513,7 @@ أنواع نقاط الاهتمام لا شيء محدد زر الإجراء السريع - ملفات التعريف + الأوضاع سيتم استبدال العناصر الحالية بالعناصر التي في الملف استبدل الكل احصل على %1$d %2$s عند %3$s مقابل. @@ -3965,7 +3965,7 @@ مساحة جهازك %1$s الخالية فقط. يرجى تحرير بعض المساحة أو إلغاء تحديد بعض العناصر للتصدير. المصادر حجم الملف التقريبي - حدد البيانات التي سيتم تصديرها إلى الملف. + حدد البيانات التي سيتم تصديرها إلى ملف. مطلوب للاستيراد لا يوجد مساحة كافية أضف إلى مابيلاي @@ -3997,10 +3997,10 @@ \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n \n - ملف تعريف أوسماند + وضع الاستعراض ملف تعريف المستخدم عكس جميع النقاط - حدد ملف التعريف، الذي سيتم استخدامه في بدء التطبيق. + حدد الوضع الذي سيتم استخدامه في بدء التطبيق. آخر استخدام تفضيل طرق التنزه تفضيل طرق التنزه From c53b863bd21a5bfe5b8d5354d4880581584aa53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Wed, 27 Jan 2021 04:05:25 +0000 Subject: [PATCH 13/81] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 59.2% (2163 of 3651 strings) --- OsmAnd/res/values-nb/strings.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index bff5af5293..7c3e0695ce 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -1526,7 +1526,7 @@ Taledataversjon som ikke støttes Sporer posisjonen din mens skjermen er slått av. Favoritter delt via OsmAnd - Lagre data som GPX-fil eller importere rutepunkter til Favoritter\? + Lagre data som GPX-fil eller importere rutepunkter til favoritter\? Format for geografiske koordinater. Koordinatformat Søk @@ -3919,4 +3919,18 @@ Vanlig sykling Tjenerfeil: %1$s Navnet finnes allerede + Analyser ved intervaller (delt intervall) + Ruteavvik + Stor lastebil + Slett denne nettbaserte rutingsmotoren\? + Les hele + Slett rutepunkt + Luke + Logg inn på OpenStreetMap + Logg inn + Tidsforbruk + Ankomst + Rediger beskrivelse + Kopier til kartmarkører + Kopier til favoritter \ No newline at end of file From 8694faaba66c3e4d06a9b0611007d8cd78314ab4 Mon Sep 17 00:00:00 2001 From: Franco Date: Wed, 27 Jan 2021 22:34:54 +0000 Subject: [PATCH 14/81] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.8% (3646 of 3651 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 1a037e42ff..56f6940aae 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -3982,7 +3982,7 @@ Preparar Fuera de la ruta Has llegado al destino - Giro + Girar Intervalos de tiempo y distancia El tiempo de anuncio de las diferentes indicaciones por voz depende del tipo de mensaje, la velocidad de navegación actual y la velocidad de navegación predefinida. Tiempo de anuncio @@ -4003,4 +4003,10 @@ Bicicleta de montaña Error de servidor: %1$s El nombre ya existe + ¿Borrar este motor de navegación en línea\? + Leer completo + Editar descripción + Borrar puntos de referencia + Copiar a «Marcadores del mapa» + Copiar a favoritos \ No newline at end of file From c96276556325757ebb18b5d1468b8efa863d6b7a Mon Sep 17 00:00:00 2001 From: Oymate Date: Thu, 28 Jan 2021 08:21:59 +0000 Subject: [PATCH 15/81] Translated using Weblate (Bengali) Currently translated at 0.4% (17 of 3651 strings) --- OsmAnd/res/values-bn/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-bn/strings.xml b/OsmAnd/res/values-bn/strings.xml index 1dd3435fca..09ae3e8f32 100644 --- a/OsmAnd/res/values-bn/strings.xml +++ b/OsmAnd/res/values-bn/strings.xml @@ -24,4 +24,8 @@ ওএসএমও কেনাকাটা একটি মানচিত্রের প্রতীকের জন্য গাইড ন্যাভিগেশন প্রোফাইল + অবস্থানগুলো + দিক নির্ণয় + মি/সে + নটিকাল মাইল \ No newline at end of file From a591cb14c6cf65a42b57d9e619f56471d26672c9 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 27 Jan 2021 01:46:38 +0000 Subject: [PATCH 16/81] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3651 of 3651 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 2c86df4178..c092cb961b 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3993,4 +3993,10 @@ 登山車 伺服器錯誤:%1$s 名稱已存在 + 刪除此線上路線引擎? + 讀取全部 + 編輯描述 + 刪除航點 + 複製到地圖標記 + 複製到收藏 \ No newline at end of file From eabd5037fd802d31fa6db7bc59e2ebf005d9741e Mon Sep 17 00:00:00 2001 From: CJTmmr Date: Wed, 27 Jan 2021 16:29:50 +0000 Subject: [PATCH 17/81] Translated using Weblate (Dutch) Currently translated at 96.1% (3510 of 3651 strings) --- OsmAnd/res/values-nl/strings.xml | 87 +++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 24 deletions(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 012850fd00..c9d8e87306 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -2178,8 +2178,8 @@ Tijdsduur Tijd in beweging Rijstijl - Gebruik hoogtegegevens - Factor in hoogtegegevens (van SRTM, ASTER en EU-DEM data). + Hoogtegegevens gebruiken + Gebruik hoogtegegevens (van SRTM, ASTER en EU-DEM data) bij bepalen route. Track Rechts rijdend Automatisch @@ -3320,9 +3320,9 @@ Route herberekening Meld Gebruikersnaam en wachtwoord - Deze instellingen hebben betrekking op alle profielen + Deze plugin-instellingen hebben betrekking op alle profielen OSM Bewerking - U kan al uw niet geüploade bewerkingen of OSM fouten zien in %1$s. Geüploade punten ziet u niet meer. + U kunt alle niet-geüploade bewerkingen of OSM-opmerkingen zien in %1$s. Geüploade wijzigingen ziet u niet meer. OSM Tijdens navigatie of beweging getoond icoon. Bij rust getoond icoon. @@ -3667,8 +3667,8 @@ Volgende segment Alle volgende segmenten Alle volgende segmenten worden opnieuw berekend met het geselecteerde profiel. - De ganse track - De ganse track wordt herberekend volgens het geselecteerde profiel. + De gehele route + De gehele route wordt herberekend volgens het geselecteerde profiel. Punt van de track om te navigeren Bewaar als nieuw trackbestand Bewaar als nieuwe track @@ -3730,8 +3730,8 @@ \nDe grafiek is beschikbaar na herberekening. %1$s — %2$s Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat. - Kloof - Op maat + Onderbreking + Aangepast Voer een OAuth-login uit om osm edit functies te gebruiken "• Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. \n @@ -3843,41 +3843,41 @@ Onderhoud Symbolen Sport - Noodtoestand + Noodgevallen Reizen Trackbestanden importeren of opnemen Track waypoint toevoegen Opslaan als trackbestand Rec U moet minimaal twee punten toevoegen - Login op OpenStreetMap - Login op OpenStreetMap.org - Login met OpenStreetMap - U moet inloggen om nieuwe of gewijzigde wijzigingen te uploaden. + Inloggen bij OpenStreetMap + Inloggen bij OpenStreetMap.org + Aanmelden via OpenStreetMap (OAuth) + U moet inloggen om wijzigingen te uploaden. \n -\nU kunt inloggen met de veilige OAuth-methode of uw login en wachtwoord gebruiken. - Gebruik uw login gegevens +\nU kunt inloggen met de veilige OAuth-methode of uw loginnaam en wachtwoord gebruiken. + Inloggen met gebruikersnaam en wachtwoord. Account - Inloggen + Gebruikersnaam Abonnement beheren Er is een probleem met uw abonnement. Klik op de knop om naar de Google Play-abonnementsinstellingen te gaan om uw betalingsmethode te corrigeren. OsmAnd Live-abonnement is verlopen OsmAnd Live-abonnement is gepauzeerd - Het OsmAnd Live-abonnement is op wacht gezet - Markeervlaggen geschiedenis + Het OsmAnd Live-abonnement is opgeschort + Markeervlaggetjes-geschiedenis Stuur het GPX-bestand naar OpenStreetMap Voer tags in, gescheiden door komma\'s. - Openbaar betekent dat de trace openbaar zal worden getoond in Uw GPS-sporen en in openbare GPS-traceerlijsten. Gegevens die via de API worden geleverd, verwijzen niet naar uw traceerpagina. Tijdaanduidingen van de traceerpunten zijn niet beschikbaar via de openbare GPS-API en de punten zijn niet chronologisch gerangschikt. Andere gebruikers kunnen de onbewerkte tracering echter nog steeds downloaden van de openbare traceringslijst en eventuele tijdaanduiding erin. - Privé betekent dat de trace niet in openbare vermeldingen zal verschijnen, maar trackpoints ervan zullen nog steeds beschikbaar zijn via de openbare GPS API zonder tijdaanduiding, maar zullen niet chronologisch worden gerangschikt. - Identificeerbaar betekent dat de trace openbaar wordt getoond in uw GPS-sporen en in openbare GPS-trace-lijsten, dat wil zeggen dat andere gebruikers de onbewerkte trace kunnen downloaden en deze aan uw gebruikersnaam kunnen koppelen. Gegevens die via de trackpoints-API worden aangeboden, verwijzen naar uw oorspronkelijke tracepagina. Tijdaanduidingen van de traceerpunten zijn beschikbaar via de openbare GPS-API. - Trackbaar betekent dat de trace niet in openbare vermeldingen zal verschijnen, maar trackpoints ervan zullen nog steeds beschikbaar zijn via de openbare GPS API met tijdaanduiding. Andere gebruikers kunnen alleen verwerkte trackpoints downloaden van uw trace die niet rechtstreeks aan u kunnen worden gekoppeld. + \"Publiek\" betekent dat de track openbaar wordt getoond in \"Jouw GPS-tracks\" en in openbare GPS-track-lijsten. Trackpoints die d.m.v. de API worden gedownload zullen niet aan je oorspronkelijke trackpagina refereren. Tijden in de tracks zijn niet beschikbaar in de publieke GPS API, maar de punten zullen wel chronologisch geordend zijn. Echter, andere gebruikers kunnen de track van de openbare GPS-track-lijsten downloaden met alle tijdinformatie. + \"Persoonlijk\" betekent dat de track niet wordt getoond in openbare GPS-track-lijsten, maar de trackpunten zijn wel beschikbaar in volgorde van tijd door de publieke GPS API, maar zonder tijdinformatie. + \"Identificeerbaar\" betekent dat de trace openbaar wordt getoond in uw GPS-sporen en in openbare GPS-trace-lijsten. Dat wil zeggen dat andere gebruikers de onbewerkte trace kunnen downloaden en deze aan uw gebruikersnaam kunnen koppelen. Gegevens die via de trackpoints-API worden aangeboden, verwijzen naar uw oorspronkelijke tracepagina. Tijdaanduidingen van de traceerpunten zijn beschikbaar via de openbare GPS-API. + \"Traceerbaar\" betekent dat de track niet wordt getoond in openbare GPS-track-lijsten maar de trackpunten zijn wel beschikbaar door de publieke GPS API met tijdinformatie. Andere gebruikers kunnen alleen bewerkte trackpunten downloaden die niet aan jou herleid kunnen worden. Sluit OSM Note Opmerking maken bij OSM-nota - U kunt inloggen met de veilige OAuth-methode of uw login en wachtwoord gebruiken. + U kunt inloggen met de veilige OAuth-methode, of uw loginnaam en wachtwoord gebruiken. Een foto toevoegen Registreer u op \nOpenPlaceReviews.org - Foto\'s zijn afkomstig van het open data-project OpenPlaceReviews.org. Om uw foto\'s te uploaden, moet u zich aanmelden op deze website. + Foto\'s zijn afkomstig van het open data-project OpenPlaceReviews.org. Om uw foto\'s te uploaden, moet u zich aanmelden op hun website. Maak een nieuw account aan Ik heb al een account %1$s * %2$s @@ -3954,4 +3954,43 @@ Laat regelmatig droogvallende waterwegen toe Geef een parameter Laat leeg indien niet + Analyseren met intervallen + Uploaden naar OpenStreetMap + GPX-track bewerken + GPX-track hernoemen + Map wijzigen + sec + Bij nadering + Bij passeren + Ruime vooraankondiging + Vooraankondiging + Afwijking van de route + Aankomst op bestemming + Bocht + Tijd- en afstandsintervallen + De aankondigingstijd van verschillende aankondigen hangt af van type en huidige snelheid. + Aankondigingstijd + Start opname + Toon GPX-track op de kaart + Rolstoel + Hiken + Wandelen + Elektische Fiets + Mountainbiken + Fietsen + Normaal Fietsen + Vrachtwagen + Kleine Vrachtwagen + Vrachtwagen + Scooter + Racefiets + Mountainbike + Server fout: %1$s + Deze naam bestaat al + Deze Online-routeservice verwijderen\? + Helemaal inlezen + Beschrijving bewerken + Waypoints verwijderen + Kopiëren naar Markeervlaggetjes + Kopiëren naar Favorieten \ No newline at end of file From c50e1d0679f49e2ef4ae1828ec65a80c1df4ad64 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 28 Jan 2021 18:29:10 +0200 Subject: [PATCH 18/81] Night mode fix, separate layout --- OsmAnd/res/layout/custom_radio_buttons.xml | 55 ++++++++++++++- .../res/layout/custom_radio_buttons_group.xml | 68 +++++++++++++++++++ OsmAnd/src/net/osmand/plus/UiUtilities.java | 7 +- .../plus/myplaces/GPXItemPagerAdapter.java | 9 ++- .../plus/myplaces/SegmentGPXAdapter.java | 6 +- .../net/osmand/plus/track/SegmentsCard.java | 2 +- 6 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 OsmAnd/res/layout/custom_radio_buttons_group.xml diff --git a/OsmAnd/res/layout/custom_radio_buttons.xml b/OsmAnd/res/layout/custom_radio_buttons.xml index d4bd1c8082..d5ef10977d 100644 --- a/OsmAnd/res/layout/custom_radio_buttons.xml +++ b/OsmAnd/res/layout/custom_radio_buttons.xml @@ -1,6 +1,7 @@ - + + - + - + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/custom_radio_buttons_group.xml b/OsmAnd/res/layout/custom_radio_buttons_group.xml new file mode 100644 index 0000000000..f0caa4a375 --- /dev/null +++ b/OsmAnd/res/layout/custom_radio_buttons_group.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 43c6ca94c5..8847f953eb 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -490,6 +490,7 @@ public class UiUtilities { } } + public static void updateCustomRadioButtonsGroup(Context app, View buttonsView, boolean nightMode, CustomRadioButtonTypeGroup buttonType) { int activeColor = ContextCompat.getColor(app, nightMode @@ -513,12 +514,14 @@ public class UiUtilities { GradientDrawable background = new GradientDrawable(); background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f)); + GradientDrawable startButtonRoundedCorner = new GradientDrawable(); startButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); GradientDrawable endButtonRoundedCorner = new GradientDrawable(); endButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); GradientDrawable centerButtonSharpCorner = new GradientDrawable(); centerButtonSharpCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); + setStartEndCenterRoundedCorner(roundedCorner, isLayoutRtl, startButtonRoundedCorner, endButtonRoundedCorner, centerButtonSharpCorner); if (buttonType == CustomRadioButtonTypeGroup.START) { @@ -564,6 +567,7 @@ public class UiUtilities { centerButtonContainer.setBackgroundDrawable(endButtonRoundedCorner); centerButtonText.setTextColor(textColor); } + } else { if (isLayoutRtl) { background.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); @@ -595,6 +599,7 @@ public class UiUtilities { centerButtonSharpCorner.setCornerRadii(new float[]{0, 0, 0, 0, 0, 0, 0, 0}); } + public static void setupCompoundButtonDrawable(Context ctx, boolean nightMode, @ColorInt int activeColor, Drawable drawable) { int inactiveColor = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); int[][] states = new int[][]{ @@ -747,7 +752,7 @@ public class UiUtilities { int activeDisableColor = getColorWithAlpha(activeColor, 0.25f); ColorStateList activeCsl = new ColorStateList(states, new int[] {activeColor, activeDisableColor}); int inactiveColor = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_secondary_light); - ColorStateList inactiveCsl = new ColorStateList(states, new int[] {inactiveColor, inactiveColor}); + ColorStateList inactiveCsl = new ColorStateList(states, new int[] {activeDisableColor, inactiveColor}); slider.setTrackActiveTintList(activeCsl); slider.setTrackInactiveTintList(inactiveCsl); slider.setHaloTintList(activeCsl); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index a9e36ff421..f3238c90b5 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -78,16 +78,19 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private SegmentActionsListener actionsListener; private boolean chartClicked; + private boolean nightMode; public GPXItemPagerAdapter(@NonNull final PagerSlidingTabStrip tabs, @NonNull GpxDisplayItem gpxItem, @NonNull TrackDisplayHelper displayHelper, - @NonNull SegmentActionsListener actionsListener) { + @NonNull SegmentActionsListener actionsListener, + final boolean nightMode) { super(); this.tabs = tabs; this.gpxItem = gpxItem; this.displayHelper = displayHelper; + this.nightMode = nightMode; this.actionsListener = actionsListener; app = (OsmandApplication) tabs.getContext().getApplicationContext(); iconsCache = app.getUIUtilities(); @@ -106,7 +109,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid } View parent = (View) tabs.getChildAt(0); - UiUtilities.updateCustomRadioButtonsGroup(app, parent, false, type); + UiUtilities.updateCustomRadioButtonsGroup(app, parent, nightMode, type); } @Override @@ -644,7 +647,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid type = UiUtilities.CustomRadioButtonTypeGroup.END; } View parent = (View) tab.getParent(); - UiUtilities.updateCustomRadioButtonsGroup(app, parent, false, type); + UiUtilities.updateCustomRadioButtonsGroup(app, parent, nightMode, type); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) parent.getLayoutParams(); int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java index f2d5c88617..9f2e234dcd 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java @@ -1,6 +1,7 @@ package net.osmand.plus.myplaces; import android.content.Context; +import android.graphics.drawable.GradientDrawable; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; @@ -21,7 +22,6 @@ import java.util.List; public class SegmentGPXAdapter extends ArrayAdapter { - private OsmandApplication app; private TrackDisplayHelper displayHelper; private SegmentActionsListener listener; private boolean nightMode; @@ -31,7 +31,7 @@ public class SegmentGPXAdapter extends ArrayAdapter { @NonNull SegmentActionsListener listener, boolean nightMode) { super(context, R.layout.gpx_list_item_tab_content, items); - this.app = (OsmandApplication) context.getApplicationContext(); + OsmandApplication app = (OsmandApplication) context.getApplicationContext(); this.displayHelper = displayHelper; this.listener = listener; this.nightMode = nightMode; @@ -56,7 +56,7 @@ public class SegmentGPXAdapter extends ArrayAdapter { WrapContentHeightViewPager pager = row.findViewById(R.id.pager); PagerSlidingTabStrip tabLayout = row.findViewById(R.id.sliding_tabs); - pager.setAdapter(new GPXItemPagerAdapter(tabLayout, item, displayHelper, listener)); + pager.setAdapter(new GPXItemPagerAdapter(tabLayout, item, displayHelper, listener, nightMode)); if (create) { tabLayout.setViewPager(pager); } else { diff --git a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java index b3921a6889..421b8a9a8e 100644 --- a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java +++ b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java @@ -48,7 +48,7 @@ public class SegmentsCard extends BaseCard { WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager); PagerSlidingTabStrip tabLayout = segmentView.findViewById(R.id.sliding_tabs); - pager.setAdapter(new GPXItemPagerAdapter(tabLayout, displayItem, displayHelper, listener)); + pager.setAdapter(new GPXItemPagerAdapter(tabLayout, displayItem, displayHelper, listener, nightMode)); tabLayout.setViewPager(pager); container.addView(segmentView); From 44bcf483759a72aa40a36761b46e1b166acf53ba Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 18:54:45 +0200 Subject: [PATCH 19/81] Add opr blockchain name --- .../plus/mapcontextmenu/MenuBuilder.java | 2 +- .../mapcontextmenu/UploadPhotosAsyncTask.java | 6 ++-- .../osmand/plus/osmedit/opr/OpenDBAPI.java | 32 ++++++++++++++++--- .../plus/settings/backend/OsmandSettings.java | 3 ++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 183e41a84f..93f2bdf6b5 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -421,7 +421,7 @@ public class MenuBuilder { new Thread(new Runnable() { @Override public void run() { - if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { + if (openDBAPI.checkPrivateKeyValid(app, baseUrl, name, privateKey)) { app.runInUIThread(new Runnable() { @Override public void run() { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index 30932e8b42..1bb48ff1f0 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -131,12 +131,12 @@ public class UploadPhotosAsyncTask extends AsyncTask { try { StringBuilder error = new StringBuilder(); String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - String username = app.getSettings().OPR_USERNAME.get(); + String name = app.getSettings().OPR_BLOCKCHAIN_NAME.get(); res = openDBAPI.uploadImage( placeId, baseUrl, privateKey, - username, + name, response, error); if (res != 200) { app.showToastMessage(error.toString()); @@ -170,7 +170,7 @@ public class UploadPhotosAsyncTask extends AsyncTask { String baseUrl = OPRConstants.getBaseUrl(app); String name = app.getSettings().OPR_USERNAME.get(); String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { + if (openDBAPI.checkPrivateKeyValid(app, baseUrl, name, privateKey)) { app.showToastMessage(R.string.cannot_upload_image); } else { app.runInUIThread(new Runnable() { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index a16361c8bd..14c0e97672 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -3,10 +3,15 @@ package net.osmand.plus.osmedit.opr; import android.net.TrafficStats; import android.os.Build; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; import net.osmand.PlatformUtil; import net.osmand.osm.io.NetworkUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -27,6 +32,7 @@ import java.security.KeyPair; import java.security.Security; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -40,7 +46,7 @@ public class OpenDBAPI { public static final String PURPOSE = "osmand-android"; private static final Log log = PlatformUtil.getLog(SecUtils.class); private static final String checkLoginEndpoint = "api/auth/user-check-loginkey?"; - private static final String LOGIN_SUCCESS_MESSAGE = "{\"result\":\"OK\"}"; + private static final String LOGIN_SUCCESS_MESSAGE = "\"result\":\"OK\""; private static final int THREAD_ID = 11200; /* @@ -51,7 +57,7 @@ public class OpenDBAPI { * Need to encode key * Do not call on mainThread */ - public boolean checkPrivateKeyValid(String baseUrl, String username, String privateKey) { + public boolean checkPrivateKeyValid(OsmandApplication app, String baseUrl, String username, String privateKey) { String url = null; try { String purposeParam = "purpose=" + PURPOSE; @@ -65,9 +71,27 @@ public class OpenDBAPI { } catch (UnsupportedEncodingException e) { return false; } + StringBuilder response = new StringBuilder(); - return (NetworkUtils.sendGetRequest(url,null,response) == null) && - response.toString().contains(LOGIN_SUCCESS_MESSAGE); + String error = NetworkUtils.sendGetRequest(url, null, response); + if (error == null) { + String responseStr = response.toString(); + try { + Map tagMap = new Gson().fromJson( + responseStr, new TypeToken>() { + }.getType() + ); + if (Algorithms.isEmpty(tagMap) && tagMap.containsKey("blockchain-name")) { + String blockchainName = tagMap.get("blockchain-name"); + app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); + } + } catch (JsonSyntaxException e) { + return false; + } + return responseStr.contains(LOGIN_SUCCESS_MESSAGE); + } else { + return false; + } } public int uploadImage(String[] placeId, String baseUrl, String privateKey, String username, String image, StringBuilder sb) throws FailedVerificationException { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index dfaaea9468..0d3cddb136 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1171,6 +1171,9 @@ public class OsmandSettings { public final OsmandPreference OPR_USERNAME = new StringPreference(this, "opr_username_secret", "").makeGlobal(); + public final OsmandPreference OPR_BLOCKCHAIN_NAME = + new StringPreference(this, "opr_blockchain_name", "").makeGlobal(); + // this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition public final OsmandPreference OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal().makeShared(); public final OsmandPreference USE_DEV_URL = new BooleanPreference(this, "use_dev_url", false).makeGlobal().makeShared(); From ef899fad821229ecefb27c317d6ac907d90520ec Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 18:58:49 +0200 Subject: [PATCH 20/81] Small fix --- OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index 14c0e97672..62612f2ffe 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -77,13 +77,15 @@ public class OpenDBAPI { if (error == null) { String responseStr = response.toString(); try { - Map tagMap = new Gson().fromJson( + Map map = new Gson().fromJson( responseStr, new TypeToken>() { }.getType() ); - if (Algorithms.isEmpty(tagMap) && tagMap.containsKey("blockchain-name")) { - String blockchainName = tagMap.get("blockchain-name"); + if (Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { + String blockchainName = map.get("blockchain-name"); app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); + } else { + return false; } } catch (JsonSyntaxException e) { return false; From 1c904641e00118114c8b17359c2640c741a4bd4e Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 28 Jan 2021 18:59:37 +0200 Subject: [PATCH 21/81] Check upload success --- .../UploadPhotoProgressBottomSheet.java | 1 - .../mapcontextmenu/UploadPhotosAsyncTask.java | 23 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java index f1c37a55ee..46483ffc9b 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java @@ -87,7 +87,6 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen @Override public void uploadPhotosFinished() { - updateProgress(maxProgress); if (progress == maxProgress) { uploadedPhotosCounter.setText((getString(R.string.uploaded_count, progress, maxProgress))); setDismissButtonTextId(R.string.shared_string_close); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index 30932e8b42..b47cc51f68 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -34,6 +34,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -45,14 +46,13 @@ public class UploadPhotosAsyncTask extends AsyncTask { private final OsmandApplication app; private final WeakReference activityRef; - private UploadPhotosListener listener; - private final OpenDBAPI openDBAPI = new OpenDBAPI(); private final LatLon latLon; private final List data; private final String[] placeId; private final Map params; private final GetImageCardsListener imageCardListener; + private UploadPhotosListener listener; public UploadPhotosAsyncTask(MapActivity activity, List data, LatLon latLon, String[] placeId, Map params, GetImageCardsListener imageCardListener) { @@ -87,13 +87,16 @@ public class UploadPhotosAsyncTask extends AsyncTask { } protected Void doInBackground(Void... uris) { + List uploadedPhotoUris = new ArrayList<>(); for (int i = 0; i < data.size(); i++) { if (isCancelled()) { break; } Uri uri = data.get(i); - handleSelectedImage(uri); - publishProgress(i + 1); + if (handleSelectedImage(uri)) { + uploadedPhotoUris.add(uri); + publishProgress(uploadedPhotoUris.size()); + } } return null; } @@ -105,12 +108,13 @@ public class UploadPhotosAsyncTask extends AsyncTask { } } - private void handleSelectedImage(final Uri uri) { + private boolean handleSelectedImage(final Uri uri) { + boolean success = false; InputStream inputStream = null; try { inputStream = app.getContentResolver().openInputStream(uri); if (inputStream != null) { - uploadImageToPlace(inputStream); + success = uploadImageToPlace(inputStream); } } catch (Exception e) { LOG.error(e); @@ -118,9 +122,11 @@ public class UploadPhotosAsyncTask extends AsyncTask { } finally { Algorithms.closeStream(inputStream); } + return success; } - private void uploadImageToPlace(InputStream image) { + private boolean uploadImageToPlace(InputStream image) { + boolean success = false; InputStream serverData = new ByteArrayInputStream(compressImageToJpeg(image)); final String baseUrl = OPRConstants.getBaseUrl(app); // all these should be constant @@ -146,6 +152,7 @@ public class UploadPhotosAsyncTask extends AsyncTask { } catch (FailedVerificationException e) { LOG.error(e); checkTokenAndShowScreen(); + } if (res != 200) { //image was uploaded but not added to blockchain @@ -159,10 +166,12 @@ public class UploadPhotosAsyncTask extends AsyncTask { if (activity != null) { MenuBuilder.execute(new GetImageCardsTask(activity, latLon, params, imageCardListener)); } + success = true; } } else { checkTokenAndShowScreen(); } + return success; } //This method runs on non main thread From b43a4e46f370b1ba4549f538352a5435303c5b93 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 18:00:25 +0100 Subject: [PATCH 22/81] Update no_translate.xml --- OsmAnd/no_translate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml index d5ecc7c149..92d3a4034f 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/no_translate.xml @@ -40,7 +40,7 @@ items modified OsmAnd Unlimited Markers - https://openplacereviews.org/ + https://test.openplacereviews.org/ https://test.openplacereviews.org/ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J From 31dc53203d727fb00be67b5b0654833bdd8d5c7d Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Jan 2021 19:04:23 +0200 Subject: [PATCH 23/81] Fix typo --- OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index 62612f2ffe..1fdeba64f0 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -81,7 +81,7 @@ public class OpenDBAPI { responseStr, new TypeToken>() { }.getType() ); - if (Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { + if (!Algorithms.isEmpty(map) && map.containsKey("blockchain-name")) { String blockchainName = map.get("blockchain-name"); app.getSettings().OPR_BLOCKCHAIN_NAME.set(blockchainName); } else { From 70c7e8a3676111ed088a0ab2d830d4139bbb11b8 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 28 Jan 2021 20:44:22 +0100 Subject: [PATCH 24/81] Update no_translate.xml --- OsmAnd/no_translate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml index 92d3a4034f..d5ecc7c149 100644 --- a/OsmAnd/no_translate.xml +++ b/OsmAnd/no_translate.xml @@ -40,7 +40,7 @@ items modified OsmAnd Unlimited Markers - https://test.openplacereviews.org/ + https://openplacereviews.org/ https://test.openplacereviews.org/ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J From e188034530bc0ec591fe944fed8febbd4c1153c7 Mon Sep 17 00:00:00 2001 From: Jurijus Date: Thu, 28 Jan 2021 16:19:56 +0000 Subject: [PATCH 25/81] Translated using Weblate (Lithuanian) Currently translated at 59.1% (2163 of 3656 strings) --- OsmAnd/res/values-lt/strings.xml | 44 +++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-lt/strings.xml b/OsmAnd/res/values-lt/strings.xml index 09ee2a83fd..3c683d41cf 100644 --- a/OsmAnd/res/values-lt/strings.xml +++ b/OsmAnd/res/values-lt/strings.xml @@ -18,9 +18,8 @@ po piet ryto Statymo vieta - Šis įskiepis leidžia įsiminti vietą, kurioje palikote savo automobilį ir kiek laiko liko iki parkavimo pabaigos (jei ribojamas laikas). - -Tiek vieta, tiek laikas yra matomi OsmAnd valdymo skydelyje bei skydelyje žemėlapyje rodinyje. Šis įskiepis taip pat gali įrašyti priminimą į kalendorių. + Šis įskiepis leidžia įsiminti vietą, kurioje palikote savo automobilį ir kiek laiko liko iki parkavimo pabaigos . +\nTiek vieta, tiek laikas yra matomi OsmAnd valdymo skydelyje bei skydelyje žemėlapyje rodinyje. Šis įskiepis taip pat gali įrašyti priminimą į Android kalendorių. Statymo vieta Žymėti statymo vietą Naikinti statymo žymę @@ -200,9 +199,8 @@ Tiek vieta, tiek laikas yra matomi OsmAnd valdymo skydelyje bei skydelyje žemė Foninis režimas Reikalinga, jei norite naudoti OsmAnd kai ekranas yra išjungtas. Neužtenka vietos parsiųsti %1$s MB (laisva: %2$s). - Atsiųsti {0} failą(-us)? -Tam prireiks {1} MB pastoviam saugojimui. -(Dabar laisvos vietos yra {2} MB.) + Atsiųsti {0} failą(-us)\? +\nTam prireiks {1} MB pastoviam saugojimui. (Dabar laisvos vietos yra {2} MB.) Permatoma tema Aparatinė biblioteka šiame įrenginyje nepalaikoma. Inicializuojama aparatinė biblioteka… @@ -778,8 +776,28 @@ Tam prireiks {1} MB pastoviam saugojimui. Vengti greitkelių Poziciją rodyti ant kelių kai naviguojama. Rodyti ant kelio - OsmAnd (OSM Automated Navigation Directions) -\nOsmAnd yra atviro kodo programa naudojanti įvairius OpenStreetMap (OSM) duomenis. Visi žemėlapių duomenys (vektoriniai ar lakštiniai) gali būti išsaugoti telefone ir naudojami be interneto prieigos. OsmAnd taip pat gali pasiūlyti maršruto skaičiavimo paslaugas internete ar įrenginyje, bei balso nurodymus kelionei apskaičiuotu maršrutu. Dalis pagrindinių savybių: - Veikia be interneto (išsaugokite parsiųstus žemėlapius ar jų lakštus įrenginyje) - Kompaktiški vektoriniai viso pasaulio žemėlapiai - Parsisųskite šalies ar regiono žemėlapius tiesiai iš pačios propgramos - Galima sulieti kelis žemėlapop sluoksnius, tokius kaip GPX ar judėjimo istoriją, Lankytinas Vietas, mėgiamas vietas, kontūrų linijas, viešojo transporto stoteles, papildomus žemėlapius su pasirinktinai nustatomu permatomumo lygiu - Adresų ir LV paieška nenaudojant interneto - Vidutinio ilgio maršruto apskaičiavimas be interneto paslaugų - Automobilio, dviračio ir pėsčiojo režimai su: - pasirinktiniu dineos/nakties rodinio perjungimu - pasirinktiniu pagal judėjimo greitį automatiškai nustatomu mąsteliu - pasirinktine žemėlapio orientacija pagal kompaso arba judėjimo kryptį - pasirinktinis eismo juostų nurodymas, greičio ribojimų rodymas, įrašyti ar generuojami balsai Šios nemokamos OsmAnd versijos apribojimai: - Ribojamas žemėlapių parsiuntimų skaičius - Nėra prieigos prie iš Wikipedia parsiunčiamų LV OsmAnd yra aktyviai tobulinama ir mūsų projektas bei jo tolesnis progresas priklauso nuo finansinės paramos, kuri įgalina tolesnį vystymą ir naujų funkcijų kūrimą. Norime paskatinti jus nusipirkti OsmAnd+ programą arba finansiškai prisidėti prie specifinių funkcijų kūrimo arba šiaip paremti programą osmand.net svetainėje. + OsmAnd (OSM Automated Navigation Directions) +\n +\nOsmAnd yra atviro kodo programa naudojanti įvairius OpenStreetMap (OSM) duomenis. Visi žemėlapių duomenys (vektoriniai ar lakštiniai) gali būti išsaugoti telefone ir naudojami be interneto prieigos. OsmAnd taip pat gali pasiūlyti maršruto skaičiavimo paslaugas internete ar įrenginyje, bei balso nurodymus kelionei apskaičiuotu maršrutu. +\n +\nDalis pagrindinių savybių: +\n- Veikia be interneto (išsaugokite parsiųstus žemėlapius ar jų lakštus įrenginyje) +\n- Kompaktiški vektoriniai viso pasaulio žemėlapiai +\n- Parsisųskite šalies ar regiono žemėlapius tiesiai iš pačios propgramos +\n- Galima sulieti kelis žemėlapop sluoksnius, tokius kaip GPX ar judėjimo istoriją, Lankytinas Vietas, mėgiamas vietas, kontūrų linijas, viešojo transporto stoteles, papildomus žemėlapius su pasirinktinai nustatomu permatomumo lygiu +\n - Adresų ir LV paieška nenaudojant interneto +\n- Vidutinio ilgio maršruto apskaičiavimas be interneto prieigos +\n- Automobilio, dviračio ir pėsčiojo režimai su: +\n- pasirinktiniu dineos/nakties rodinio perjungimu +\n- pasirinktiniu pagal judėjimo greitį automatiškai nustatomu mąsteliu +\n- pasirinktine žemėlapio orientacija pagal kompaso arba judėjimo kryptį +\n- pasirinktinis eismo juostų nurodymas, greičio ribojimų rodymas, įrašyti ar generuojami balsai +\n +\nNemokamos OsmAnd versijos apribojimai: +\n- Ribojamas žemėlapių parsiuntimų skaičius +\n- Nėra prieigos prie iš Wikipedia parsiunčiamų LV +\n +\n OsmAnd yra aktyviai tobulinama ir mūsų projektas bei jo tolesnis progresas priklauso nuo finansinės paramos, kuri įgalina tolesnį vystymą ir naujų funkcijų kūrimą. Norime paskatinti jus nusipirkti OsmAnd+ programą arba finansiškai prisidėti prie specifinių funkcijų kūrimo arba šiaip paremti programą https://osmand.net svetainėje. OsmAnd - atviro kodo navigacijos programa su žemėlapiais OsmAnd+ (OSM Automated Navigation Directions) \n @@ -1872,9 +1890,9 @@ Failams reikalinga {3} MB laikinam ir {1} MB pastoviam saugojimui. Prenumerata leidžia kas valandą gauti visų pasaulio žemėlapių atnaujinimus. Dalis pajamų grįžta OSM bendruomenei ir apmokamas kiekvienas indėlis į OSM kūrimą. Tai yra puikus būdas paremti OsmAnd ir OSM, jei jie jums patinka. - Ar siųsti {0} failų? - Failams reikalinga {3} MB laikinam ir {1} MB pastoviam saugojimui. - (Šiuo metu prieinama tik {2} MB vietos.) + Ar siųsti {0} failų\? +\nFailams reikalinga {3} MB laikinam ir {1} MB pastoviam saugojimui. +\n(Šiuo metu prieinama tik {2} MB vietos.) Ispanų (Amerikos) Anglų (Junginė Karalystė) Belarusų (Lotynų) @@ -2419,7 +2437,9 @@ Tai yra puikus būdas paremti OsmAnd ir OSM, jei jie jums patinka. Paskutinį kartą naudota: %1$s Taisymų %1$s, suma %2$s mBTC Laosiečių - OsmAnd (OSM Automated Navigation Directions) yra žemėlapio ir navigacijos programa su prieiga prie nemokamų, pasaulinių ir aukštos kokybės OpenStreetMap (OSM) duomenų. Naudokitės balso ir vaizdo navigatoriumi, peržiūrėkite LV (lankytinas vietas), kurkite ir valdytkite GPX kelius, naudojkite kontūro linijos vizualizaciją ir aukščio info (įskiepių pagalba), pasirinkite vairavimo, dviračių, pėsčiųjų režimus, redaguokite OSM duomenis ir daug daugiau. + OsmAnd (OSM Automated Navigation Directions) yra žemėlapio ir navigacijos programa su prieiga prie nemokamų, pasaulinių ir aukštos kokybės OpenStreetMap (OSM) duomenų. +\n +\nNaudokitės balso ir vaizdo navigatoriumi, peržiūrėkite LV (lankytinas vietas), kurkite ir valdytkite GPX kelius, naudojkite kontūro linijos vizualizaciją ir aukščio info (įskiepių pagalba), pasirinkite vairavimo, dviračių, pėsčiųjų režimus, redaguokite OSM duomenis ir daug daugiau. Nuostatos pavadinimas Bakstelėję veiksmo mygtuką pridėsite žemėlapio žymeklį ekrano centre. Bakstelėję veiksmo mygtuką pridėsite garso įrašą ekrano centre. From b5f01a1c7f117a5756b2f6f65c7678ac601c048b Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 29 Jan 2021 04:04:33 +0200 Subject: [PATCH 26/81] add the ability to save the global settings of Wikipedia Languages --- .../SelectWikiLanguagesBottomSheet.java | 52 +++++++++++++++++-- .../plus/wikipedia/WikipediaPlugin.java | 31 +++++++++-- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java b/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java index 873feba53c..da3b6f106d 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java @@ -1,8 +1,12 @@ package net.osmand.plus.wikipedia; +import android.app.Activity; import android.content.res.Resources; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.text.SpannableString; +import android.text.style.StyleSpan; import android.view.View; import android.widget.CompoundButton; @@ -12,6 +16,8 @@ import androidx.core.content.ContextCompat; import androidx.core.os.ConfigurationCompat; import androidx.core.os.LocaleListCompat; +import com.google.android.material.snackbar.Snackbar; + import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -124,6 +130,12 @@ public class SelectWikiLanguagesBottomSheet extends MenuBottomSheetDialogFragmen } } + @Nullable + public MapActivity getMapActivity() { + Activity activity = getActivity(); + return (MapActivity) activity; + } + private void initLanguagesData() { languages = new ArrayList<>(); @@ -188,12 +200,44 @@ public class SelectWikiLanguagesBottomSheet extends MenuBottomSheetDialogFragmen localesForSaving.add(language.getLocale()); } } - wikiPlugin.setLanguagesToShow(localesForSaving); - wikiPlugin.setShowAllLanguages(isGlobalWikiPoiEnabled); - wikiPlugin.updateWikipediaState(); + applyPreferenceWithSnackBar(localesForSaving, isGlobalWikiPoiEnabled); dismiss(); } + protected final void applyPreference(boolean applyToAllProfiles, List localesForSaving, boolean global) { + if (applyToAllProfiles) { + for (ApplicationMode mode : ApplicationMode.allPossibleValues()) { + wikiPlugin.setLanguagesToShow(mode, localesForSaving); + wikiPlugin.setShowAllLanguages(mode, global); + } + } else { + wikiPlugin.setLanguagesToShow(localesForSaving); + wikiPlugin.setShowAllLanguages(isGlobalWikiPoiEnabled); + } + + wikiPlugin.updateWikipediaState(); + } + + protected void applyPreferenceWithSnackBar(final List localesForSaving, final boolean global) { + applyPreference(false, localesForSaving, global); + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + String modeName = appMode.toHumanString(); + String text = app.getString(R.string.changes_applied_to_profile, modeName); + SpannableString message = UiUtilities.createSpannableString(text, new StyleSpan(Typeface.BOLD), modeName); + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), message, Snackbar.LENGTH_LONG) + .setAction(R.string.apply_to_all_profiles, new View.OnClickListener() { + @Override + public void onClick(View view) { + applyPreference(true, localesForSaving, global); + } + }); + UiUtilities.setupSnackbarVerticalLayout(snackbar); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + } + } + private View getCustomButtonView() { OsmandApplication app = getMyApplication(); if (app == null) { @@ -265,7 +309,7 @@ public class SelectWikiLanguagesBottomSheet extends MenuBottomSheetDialogFragmen } public static void showInstance(@NonNull MapActivity mapActivity, - boolean usedOnMap) { + boolean usedOnMap) { SelectWikiLanguagesBottomSheet fragment = new SelectWikiLanguagesBottomSheet(); fragment.setUsedOnMap(usedOnMap); fragment.show(mapActivity.getSupportFragmentManager(), SelectWikiLanguagesBottomSheet.TAG); diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java index 16684fbe25..88b7618185 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java @@ -30,6 +30,7 @@ import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.search.QuickSearchListAdapter; import net.osmand.plus.search.listitems.QuickSearchBannerListItem; import net.osmand.plus.search.listitems.QuickSearchFreeBannerListItem; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.layers.DownloadedRegionsLayer; import net.osmand.plus.views.OsmandMapTileView; @@ -97,8 +98,8 @@ public class WikipediaPlugin extends OsmandPlugin { @Override protected void registerLayerContextMenuActions(OsmandMapTileView mapView, - ContextMenuAdapter adapter, - final MapActivity mapActivity) { + ContextMenuAdapter adapter, + final MapActivity mapActivity) { ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.OnRowItemClick() { @Override @@ -113,7 +114,7 @@ public class WikipediaPlugin extends OsmandPlugin { @Override public boolean onContextMenuClick(final ArrayAdapter adapter, int itemId, - final int pos, boolean isChecked, int[] viewCoordinates) { + final int pos, boolean isChecked, int[] viewCoordinates) { if (itemId == R.string.shared_string_wikipedia) { toggleWikipediaPoi(isChecked, new CallbackWithObject() { @Override @@ -189,26 +190,50 @@ public class WikipediaPlugin extends OsmandPlugin { return !isShowAllLanguages() && getLanguagesToShow() != null; } + public boolean hasCustomSettings(ApplicationMode profile) { + return !isShowAllLanguages(profile) && getLanguagesToShow(profile) != null; + } + public boolean hasLanguagesFilter() { return settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.get() != null; } + public boolean hasLanguagesFilter(ApplicationMode profile) { + return settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.getModeValue(profile) != null; + } + public boolean isShowAllLanguages() { return settings.GLOBAL_WIKIPEDIA_POI_ENABLED.get(); } + public boolean isShowAllLanguages(ApplicationMode mode) { + return settings.GLOBAL_WIKIPEDIA_POI_ENABLED.getModeValue(mode); + } + public void setShowAllLanguages(boolean showAllLanguages) { settings.GLOBAL_WIKIPEDIA_POI_ENABLED.set(showAllLanguages); } + public void setShowAllLanguages(ApplicationMode mode, boolean showAllLanguages) { + settings.GLOBAL_WIKIPEDIA_POI_ENABLED.setModeValue(mode, showAllLanguages); + } + public List getLanguagesToShow() { return settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.getStringsList(); } + public List getLanguagesToShow(ApplicationMode mode) { + return settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.getStringsListForProfile(mode); + } + public void setLanguagesToShow(List languagesToShow) { settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.setStringsList(languagesToShow); } + public void setLanguagesToShow(ApplicationMode mode, List languagesToShow) { + settings.WIKIPEDIA_POI_ENABLED_LANGUAGES.setStringsListForProfile(mode, languagesToShow); + } + public void toggleWikipediaPoi(boolean enable, CallbackWithObject callback) { if (enable) { showWikiOnMap(); From 54763fc22d1b73dd3e6f360d53d6ceb5e586e190 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 29 Jan 2021 18:51:28 +0500 Subject: [PATCH 27/81] Small edit --- .../aidlapi/customization/ProfileSettingsParams.java | 9 +++++---- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java index afca79aa0e..eee80329f7 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java @@ -8,6 +8,7 @@ import net.osmand.aidlapi.AidlParams; import net.osmand.aidlapi.profile.AExportSettingsType; import java.util.ArrayList; +import java.util.List; import static net.osmand.aidlapi.profile.ExportProfileParams.SETTINGS_TYPE_KEY; @@ -21,11 +22,11 @@ public class ProfileSettingsParams extends AidlParams { private Uri profileSettingsUri; private String latestChanges; private int version; - private ArrayList settingsTypeKeyList = new ArrayList<>(); + private List settingsTypeKeyList = new ArrayList<>(); private boolean silent; private boolean replace; - public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace, + public ProfileSettingsParams(Uri profileSettingsUri, List settingsTypeList, boolean replace, boolean silent, String latestChanges, int version) { this.profileSettingsUri = profileSettingsUri; for (AExportSettingsType settingsType : settingsTypeList) { @@ -65,7 +66,7 @@ public class ProfileSettingsParams extends AidlParams { return profileSettingsUri; } - public ArrayList getSettingsTypeKeys() { + public List getSettingsTypeKeys() { return settingsTypeKeyList; } @@ -82,7 +83,7 @@ public class ProfileSettingsParams extends AidlParams { bundle.putInt(VERSION_KEY, version); bundle.putString(LATEST_CHANGES_KEY, latestChanges); bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri); - bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList); + bundle.putStringArrayList(SETTINGS_TYPE_KEY, new ArrayList<>(settingsTypeKeyList)); bundle.putBoolean(REPLACE_KEY, replace); bundle.putBoolean(SILENT_IMPORT_KEY, silent); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 033fceff1a..3687602716 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -2296,11 +2296,11 @@ public class OsmandAidlApi { return false; } - public boolean importProfileV2(final Uri profileUri, ArrayList settingsTypeKeys, boolean replace, + public boolean importProfileV2(final Uri profileUri, List settingsTypeKeys, boolean replace, boolean silent, String latestChanges, int version) { if (profileUri != null) { Bundle bundle = new Bundle(); - bundle.putStringArrayList(SettingsHelper.SETTINGS_TYPE_LIST_KEY, settingsTypeKeys); + bundle.putStringArrayList(SettingsHelper.SETTINGS_TYPE_LIST_KEY, new ArrayList<>(settingsTypeKeys)); bundle.putBoolean(REPLACE_KEY, replace); bundle.putBoolean(SILENT_IMPORT_KEY, silent); bundle.putString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY, latestChanges); From 09f94a8848272c9546c482e4d663dacfcc34a2ea Mon Sep 17 00:00:00 2001 From: max-klaus Date: Fri, 29 Jan 2021 18:46:27 +0300 Subject: [PATCH 28/81] Fix travel in free version --- OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java index aaac5e6f9e..298e3fc287 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java @@ -292,10 +292,6 @@ public class DownloadActivityType { public IndexItem parseIndexItem(OsmandApplication ctx, XmlPullParser parser) { - if (TRAVEL_FILE == this && !Version.isDeveloperVersion(ctx)) { - //todo remove "if" when .travel.obf will be used in production - return null; - } String name = parser.getAttributeValue(null, "name"); //$NON-NLS-1$ if (!isAccepted(name)) { return null; From f04a181524d781955366d3b3aa8418f33d67a96f Mon Sep 17 00:00:00 2001 From: max-klaus Date: Fri, 29 Jan 2021 18:46:27 +0300 Subject: [PATCH 29/81] Fix travel in free version --- OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java index aaac5e6f9e..298e3fc287 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java @@ -292,10 +292,6 @@ public class DownloadActivityType { public IndexItem parseIndexItem(OsmandApplication ctx, XmlPullParser parser) { - if (TRAVEL_FILE == this && !Version.isDeveloperVersion(ctx)) { - //todo remove "if" when .travel.obf will be used in production - return null; - } String name = parser.getAttributeValue(null, "name"); //$NON-NLS-1$ if (!isAccepted(name)) { return null; From 55a1669afbfcd6d4d68aaf11f75702626c390da3 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 29 Jan 2021 18:12:20 +0200 Subject: [PATCH 30/81] fix max-width in stats block; fix align icon to the right in stats block --- OsmAnd/res/layout/item_gpx_stat_block.xml | 44 +++++++++++++++-------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/OsmAnd/res/layout/item_gpx_stat_block.xml b/OsmAnd/res/layout/item_gpx_stat_block.xml index 18dfa5cdde..dd0ed2a571 100644 --- a/OsmAnd/res/layout/item_gpx_stat_block.xml +++ b/OsmAnd/res/layout/item_gpx_stat_block.xml @@ -10,43 +10,59 @@ android:orientation="horizontal"> + android:gravity="center_vertical" + android:orientation="horizontal" + android:weightSum="2"> - + + + + + From 24c69f0a878c48b972bed241ea4e446d077ce7ec Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 29 Jan 2021 18:29:54 +0200 Subject: [PATCH 31/81] Added image for OpenPlaceReviews plugins screen --- .../img_plugin_openplacereviews.webp | Bin 0 -> 23698 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp diff --git a/OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp b/OsmAnd/res/drawable-xxhdpi/img_plugin_openplacereviews.webp new file mode 100644 index 0000000000000000000000000000000000000000..97e0b2e58ddc623cb109bbf0ca08ef656e52a8d7 GIT binary patch literal 23698 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 Date: Fri, 29 Jan 2021 09:16:26 +0000 Subject: [PATCH 32/81] Translated using Weblate (French) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-fr/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index e9c1c87b65..381fbfddb3 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3996,4 +3996,9 @@ Lire la suite Modifier la description Supprimer les points de passage + Envoi %1$d sur %2$d + Sélectionnez les modifications à envoyer + %1$d sur %2$d envoyé + Envoi en cours + Envoi terminé \ No newline at end of file From f6043222c4d8a91de1956500faf2bfce8d30f486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 29 Jan 2021 04:40:44 +0000 Subject: [PATCH 33/81] Translated using Weblate (Turkish) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-tr/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index 02664a0a1e..1f9d208ac4 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -2332,7 +2332,7 @@ Otomatik-sesli-bildirim periyodu Uğranacak-ara-noktalar bulunamadı İspanyolca (Amerikan) - Hareket Zamanı + Hareket halindeki zaman Plan seçin Çevrim dışı seyahat rehberi işlevselliğini almak için aşağıdakilerden birini satın alın: Uygun ögeyi seçin @@ -4007,4 +4007,9 @@ Bu çevrim içi yönlendirme motoru silinsin mi\? Tamamını oku Açıklamayı düzenle + Karşıya yükleniyor + Karşıya yükleme tamamlandı + %1$d / %2$d karşıya yükleniyor + %1$d / %2$d karşıya yüklendi + Karşıya yüklenecek düzenlemeleri seçin \ No newline at end of file From 97c06d99c080fabb353638bc475104617a95aad6 Mon Sep 17 00:00:00 2001 From: Tymofij Lytvynenko Date: Fri, 29 Jan 2021 07:50:28 +0000 Subject: [PATCH 34/81] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-uk/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index f180654a56..f724876c74 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -2436,7 +2436,7 @@ Середнє %1$d зі %2$d Підйом/спуск - Час руху + Час у русі Макс/мін Мін/макс Напівпрозорий рожевий @@ -4005,4 +4005,9 @@ Видалити маршрутні точки Копіювати до позначок мапи Копіювати до закладок + Вивантаження + Вивантаження завершено + Вивантаження %1$d з %2$d + Вивантажено %1$d з %2$d + Виберіть зміни для вивантаження \ No newline at end of file From dbdfe6151ccf18c05b2564dca74bf30abe5835fc Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Fri, 29 Jan 2021 17:50:53 +0000 Subject: [PATCH 35/81] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 44ac4e79b6..023809b5ae 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4001,4 +4001,9 @@ Copiar para favoritos Excluir este mecanismo de roteamento online\? Ler na íntegra + Carregando + Carreamento concluído + Carregando %1$d de %2$d + Carregado %1$d de %2$d + Selecione as edições para carregamento \ No newline at end of file From dadc703d486f3962e7f5ffbdaa89698d70c29f0b Mon Sep 17 00:00:00 2001 From: Verdulo Date: Fri, 29 Jan 2021 15:03:25 +0000 Subject: [PATCH 36/81] Translated using Weblate (Esperanto) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-eo/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 349175b810..219a59ae10 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -2433,7 +2433,7 @@ Mezumo %1$d el %2$d Supreniroj/malsupreniroj - Movada tempo + Tempo dum movo Maks./min. Min./maks. Rozkolora diafana @@ -4006,4 +4006,9 @@ Redakti priskribon Forigi navigadpunktojn Kopii al map‑markoj + Sendado + Sendado finita + Sendado de %1$d el %2$d + Sendis %1$d el %2$d + Elektu redaktojn por sendi \ No newline at end of file From c81f05ea7f905c71ba001c644c12aa9fffa51ab5 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Fri, 29 Jan 2021 09:42:33 +0000 Subject: [PATCH 37/81] Translated using Weblate (Arabic) Currently translated at 92.9% (3606 of 3881 strings) --- OsmAnd/res/values-ar/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ar/phrases.xml b/OsmAnd/res/values-ar/phrases.xml index 2b880e83d6..9338e3e669 100644 --- a/OsmAnd/res/values-ar/phrases.xml +++ b/OsmAnd/res/values-ar/phrases.xml @@ -3678,4 +3678,5 @@ نفق خفافيش جسر خفافيش معبر الحيوانات البرية + شريط التمرير \ No newline at end of file From c11be07b0b39067d036bc47edcb3639037bedd14 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 29 Jan 2021 01:32:23 +0000 Subject: [PATCH 38/81] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index c092cb961b..9b601f4c19 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -2430,7 +2430,7 @@ 平均 %1$d 的 %2$d 上升/下降 - 移動時間 + 運動時間 最大/最小 最小/最大 半透明粉紅色 @@ -3999,4 +3999,9 @@ 刪除航點 複製到地圖標記 複製到收藏 + 正在上傳 + 已完成上傳 + 正在上傳 %1$d,共 %2$d + 已上傳 %1$d,共 %2$d + 選取要上傳的檔案 \ No newline at end of file From 446860082b8d846cc4068cb3ae0d620e60c04215 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Fri, 29 Jan 2021 20:59:02 +0000 Subject: [PATCH 39/81] Translated using Weblate (French) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 381fbfddb3..c963ab462e 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3996,7 +3996,7 @@ Lire la suite Modifier la description Supprimer les points de passage - Envoi %1$d sur %2$d + Envoi de %1$d sur %2$d Sélectionnez les modifications à envoyer %1$d sur %2$d envoyé Envoi en cours From cfac0c352dbb5f0d5eb88d6c45eb204a28fc44e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Fri, 29 Jan 2021 21:51:09 +0000 Subject: [PATCH 40/81] Translated using Weblate (Hungarian) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-hu/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index d883e7189b..5355241d87 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -4000,4 +4000,9 @@ Útpontok törlése Másolás a térképjelölők közé Másolás a kedvencek közé + Felöltés folyamatban + Feltöltés befejezve + %1$d / %2$d feltöltés alatt + %1$d / %2$d feltöltve + Szerkesztések kijelölése feltöltéshez \ No newline at end of file From 82a02ca5596ac5f1931c80b7125a42f31b02664b Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Fri, 29 Jan 2021 23:04:00 +0000 Subject: [PATCH 41/81] Translated using Weblate (Hebrew) Currently translated at 99.9% (3654 of 3656 strings) --- OsmAnd/res/values-iw/strings.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 4915811995..737272e2e5 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -1528,7 +1528,7 @@ מרחק ממוצע %1$d מתוך %2$d - זמן תנועה + זמן בתנועה מרבי/מזערי מזערי/מרבי סיורים @@ -4001,4 +4001,16 @@ מחיקת נקודות דרך העתקה לסמני המפה העתקה למועדפים + שנ׳ + מעבר + הגעה + הכנה ממושכת + הכנה + פנייה + הפרשי זמן ומרחק + מתבצעת שליחה + השליחה הושלמה + נשלחות %1$d מתוך %2$d + נשלחו %1$d מתוך %2$d + נא לבחור עריכות לשליחה \ No newline at end of file From 24a455cd7b597865e6056dc3ab0e4f3ddf652648 Mon Sep 17 00:00:00 2001 From: ace shadow Date: Sat, 30 Jan 2021 15:18:55 +0000 Subject: [PATCH 42/81] Translated using Weblate (Slovak) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-sk/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 2da9b2324b..84b80a03a8 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -2434,7 +2434,7 @@ Priemer %1$d z %2$d Stúpanie/Klesanie - Trvanie presunu + Čas v pohybe Max/Min Pozastaviť/pokračovať navigáciu Tlačidlo pre pozastavenie alebo pokračovanie navigácie. @@ -4001,4 +4001,9 @@ Odstrániť body trasy Skopírovať do mapových značiek Skopírovať do obľúbených + Odosielanie + Odoslanie dokončené + Odosiela sa %1$d z %2$d + Odoslané %1$d z %2$d + Zvoľte úpravy na odoslanie \ No newline at end of file From 9d94820aa3064f5331c102ed8a9415eb9f71c0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Kotr=C4=8D?= Date: Sat, 30 Jan 2021 07:12:16 +0000 Subject: [PATCH 43/81] Translated using Weblate (Czech) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-cs/strings.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 404ec25431..738a4e98fe 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -2314,7 +2314,7 @@ Průměr %1$d z %2$d Stoupání/Klesání - Čas pohybu + Doba pohybu Max/Min Min/Max Pozastavit/pokračovat v navigaci @@ -4000,4 +4000,15 @@ Horské kolo Chyba serveru: %1$s Název již existuje + Odstranit tuto online navigační službu\? + Přečíst celé + Upravit popis + Odstranit body trasy + Kopírovat do mapových značek + Kopírovat do oblíbených + Nahrávání + Nahrávání dokončeno + Nahrávám %1$d z %2$d + Nahráno %1$d z %2$d + Vyberte úpravy pro nahrání \ No newline at end of file From 5d82bbcd27282a1e43cdfc978bdca20536ffe771 Mon Sep 17 00:00:00 2001 From: Franco Date: Sat, 30 Jan 2021 17:17:26 +0000 Subject: [PATCH 44/81] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (3655 of 3656 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 56f6940aae..18a479e18b 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -2438,7 +2438,7 @@ Promedio %1$d de %2$d Ascenso/Descenso - Tiempo moviéndose + Tiempo en movimiento Máx/Min Min/Máx Rosa translúcido @@ -4009,4 +4009,9 @@ Borrar puntos de referencia Copiar a «Marcadores del mapa» Copiar a favoritos + Subiendo + Subida completa + Subiendo %1$d de %2$d + Se subieron %1$d de %2$d + Marcar ediciones a subir \ No newline at end of file From fc7466ab94781864a83c39f034aebd2cf455054f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20=C3=87akmak?= Date: Sat, 30 Jan 2021 17:09:06 +0000 Subject: [PATCH 45/81] Translated using Weblate (Turkish) Currently translated at 83.3% (3234 of 3881 strings) --- OsmAnd/res/values-tr/phrases.xml | 152 +++++++++++++++++++++++++------ 1 file changed, 124 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/values-tr/phrases.xml b/OsmAnd/res/values-tr/phrases.xml index 2fe8bccf32..b76cd1cada 100644 --- a/OsmAnd/res/values-tr/phrases.xml +++ b/OsmAnd/res/values-tr/phrases.xml @@ -299,14 +299,14 @@ Kağıt Giyim Kutular - Cam şişeler + Cam şişeleri Plastik Hurda metal Piller Plastik şişeler Yeşil atık Atık (siyah çanta) - Plastik Ambalaj + Plastik ambalaj Gazete Kartonlar Mukavva @@ -316,11 +316,11 @@ Ahşap Kitaplar Ayakkabı - alüminyum + Alüminyum Organik İçecek kartonları Bahçe atıkları - Düşük enerji Ampüller + Düşük enerjili ampüller Floresan tüpler Metal Elektrik ögeleri @@ -329,16 +329,16 @@ Motor yağı Plastik torbalar Tehlikeli atık - Cep telefonları + Cep telefonu Cıva Bilgisayarlar - Lastikler + Araba lastiği TV, monitör Karton kutu Moloz CD Atık yağ - Şişe + Şişeler Tıpa Yazıcı kartuşları Sac metal @@ -349,7 +349,7 @@ Gübre Zor Noel ağaçları - Işık Ampülleri + Ampüller Sunta Polyester Alçıpan @@ -584,7 +584,7 @@ İbadethane Hristiyanlık Yahudilik - İslami + İslam Sih dini Budizm Hinduizm @@ -823,9 +823,9 @@ Muhasebeci Bitcoin ödeme Mağara girişi - Dağın tepesi + Zirve Eyer - Volkan + Yanardağ Krater Sırt Buzul @@ -896,13 +896,13 @@ İbranice wiki Hintçe wiki Hırvatça wiki - Haiti dilinde wiki + Haitice wiki Macarca wiki Endonezyaca wiki İtalyanca wiki Letonca wiki Malayca wiki - Newar dilinde wiki + Nevarca wiki Flemenkçe wiki Norveççe Nynorsk wiki Norveççe wiki @@ -1385,7 +1385,7 @@ Enerji kaynağı: dizel Uluslararası isim Ulusal isim - Bölgesel isim + Yerel ad Yerel isim Eski isim Alternatif isim @@ -1679,12 +1679,12 @@ Sadece glutensiz Glutensiz Glutensiz diyet: hayır - Sadece kosher + Sadece koşer Kosher - Kosher diyet: hayır + Koşer gıda: hayır Sadece helal Helal - Helal diyet: hayır + Helal gıda: hayır Sadece laktozsuz Laktozsuz Laktozsuz diyet: hayır @@ -1718,7 +1718,7 @@ Vejetaryen Vegan Glutensiz - Kosher + Koşer Helal Laktozsuz Evet @@ -1902,7 +1902,7 @@ FAA kodu Sanat eseri türü: heykel İnternet erişimi var - Nakit para çekme + Nakit çekme Salıncak kapı Kent at arabası boşluğu Rüzgar tarafından düşürülen @@ -2283,7 +2283,7 @@ Uygarlık: nuragic (MÖ 18. yy – MS 2. yy) Uygarlık: etrüsk (MÖ 12. – 6. yy) Uygarlık: tarih öncesi - Uygarlık: antik yunan + Uygarlık: eski yunan Uygarlık: roma Uygarlık: bizans (MS 285 – MS 1453) Uygarlık: çin imparatorluğu (MÖ 221 – MS 1911) @@ -2291,7 +2291,7 @@ Uygarlık: kelt Uygarlık: batı roma (MS 285 – MS 476) Uygarlık: miken - Uygarlık: dacian + Uygarlık: daçya Uygarlık: hernici Uygarlık: yunan mısırı (MÖ 332 – MÖ 30) Uygarlık: roma ve bizans mısırı @@ -2309,10 +2309,10 @@ SMS Durum Tür - Tarihi çağ: kalkolitik (MÖ 4.–3. milenyum) - Tarihi çağ: neolitik - Tarihi çağ: mezolitik - Tarihi çağ: paleolitik (günümüzden 2,6 milyon yıl önce – 10000 yıl önce) + Tarihi çağ: bakır taş (MÖ 4.–3. milenyum) + Tarihi çağ: cilalı taş + Tarihi çağ: orta taş + Tarihi çağ: yontma taş (günümüzden 2,6 milyon yıl önce – 10000 yıl önce) Tarihi dönem: imparatorluk (dönem V, MS 900 – MS 1200 Tarihi dönem: klasik (dönem IV, MS 374 – MS 900) Tarihi dönem: kentsel (dönem III, MS 133 – MS 374) @@ -2892,18 +2892,18 @@ Waffle Krep Falafel - Taco + Tako Kantin Tuzlu krep Kızarmış tavuk Kuskus Fırın Bistro - Kızarmış yiyecekler + Kızartma Dondurulmuş yoğurt Şarküteri Turta - Çay dükkanı + Çaycı Sağlık çalışanının rolü: büyücü Sağlık çalışanının rolü: teknisyen Sağlık çalışanının rolü: doktor asistanı @@ -3138,4 +3138,100 @@ Ağır yük aracı erişimi: tarım Ağır yük aracı erişimi: hayır Ağır yük aracı erişimi: özel + Göl + Irmak + Kuyu + Aşılama: Kovid-19 + Hemşire + Hayır + Evet + Hayır + Evet + Hayır + Evet + Çerezci + Arı kovanı + Sadece yürümeye izin verildiğinde + İnternet erişimi: müşteriler + Püskürme sayısı + Son püskürme + Mezar + Girocard + Nakit çekme ücreti: hayır + Nakit çekme ücreti: evet + Nakit çekme para birimi + Nakit çekme + Nakit çekme: evet + Evet + Evet + Evet + Evet + Evet + Serbest + Evet + Evet + Evet + Evet + Evet + Serbest + Evet + Taksi erişimi: hayır + Taksi erişimi: evet + Tarım aracı erişimi: hayır + Tarım aracı erişimi: evet + Kar arabası erişimi: hayır + Kar arabası erişimi: özel + Otobüs erişimi: hayır + Karavan erişimi: hayır + Yaya erişimi: müşteriler + Yaya erişimi: serbest + Yaya erişimi: hayır + Yaya erişimi: özel + Yaya erişimi: evet + At erişimi: serbest + At erişimi: özel + Bisiklet erişimi: müşteriler + Bisiklet erişimi: serbest + Bisiklet erişimi: özel + Moped erişimi: hayır + Motorsiklet erişimi: özel + Araç erişimi: askerî + Araç erişimi: müşteriler + Araç erişimi: serbset + Araç erişimi: hayır + Araç erişimi: özel + Araç erişimi: evet + Metro + Tıp laboratuvarı + Kalıntılar + Temassız kabul edilmiyor + Temassız + Lastikler + Araba parçaları + Tarım mağazası + Tür: otlak + Tırmanma güzergahları + Buz: hayır + Buz: evet + Spor: hayır + Spor: evet + Para gönderme + Konum: köprü + Kano: hayır + Kano: evet + Kayaklar: hayır + Kayaklar: evet + Kuşçuluk + Safari parkı + Lokomotif + Gıdon + Trafik aynası + Yazıt: KD + Yazıt: D + Yazıt: GD + Yazıt: G + Yazıt: GB + Yazıt: B + Yazıt: KB + Yazıt: K \ No newline at end of file From b00df8b5ea073a2375f58374af858cdc362f45bd Mon Sep 17 00:00:00 2001 From: WaldiS Date: Sat, 30 Jan 2021 19:21:23 +0000 Subject: [PATCH 46/81] Translated using Weblate (Polish) Currently translated at 99.2% (3630 of 3656 strings) --- OsmAnd/res/values-pl/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 04170526ec..dc7dcf24c9 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -2345,7 +2345,7 @@ Średnia %1$d z %2$d Podjazd/zjazd - Czas w ruchu + Czas poruszania Maks./min. Zatrzymaj/wznów nawigację Przycisk do wstrzymania lub wznowienia nawigacji. @@ -3998,4 +3998,14 @@ Taka nazwa już istnieje Silnik wyznaczania tras online Silniki wyznaczania tras online + Przeczytaj całość + Edytuj opis + Usuń punkty trasy + Skopiuj do znaczników mapy + Skopiuj do ulubionych + Wysyłanie + Przesyłanie zakończone + Przesyłanie %1$d z %2$d + Przesłano %1$d z %2$d + Wybierz zmiany do przesłania \ No newline at end of file From 8bc2679e917463aa572a122a12a28c9836e95de7 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Sat, 30 Jan 2021 21:07:33 +0000 Subject: [PATCH 47/81] Translated using Weblate (Sardinian) Currently translated at 99.4% (3636 of 3656 strings) --- OsmAnd/res/values-sc/strings.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index c0caa235d6..020b6b3915 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3982,4 +3982,21 @@ MTB (motosilurante) Errore de su serbidore: %1$s Su nùmene esistit giai + Analiza pro intervallos (intervallu fratzionadu) + Càrriga in OpenStreetMap + Modìfica sa rasta + Modìfica su nùmene de sa rasta + Càmbia sa cartella + seg + Iscantzellare custu motore de càrculu in lìnia\? + Leghe totu + Modìfica sa descritzione + Iscantzella sos puntos de coladòrgiu + Còpia in sos marcadores de sa mapa + Còpia in sos preferidos + Carrighende + Carrigamentu acabadu + Carrighende %1$d de %2$d + %1$d de %2$d carrigados + Ischerta modìficas de carrigare \ No newline at end of file From 9d5bd47f4a62f80bdeb17d165cf6bad7a9fde36e Mon Sep 17 00:00:00 2001 From: Skalii Date: Sun, 31 Jan 2021 02:59:28 +0200 Subject: [PATCH 48/81] fix display of distance and direction --- .../SelectedGpxMenuController.java | 4 +++- .../osmand/plus/track/TrackMenuFragment.java | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java index 5ea0766469..6e062829a6 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java @@ -43,7 +43,9 @@ public class SelectedGpxMenuController extends MenuController { @Override public void buttonPressed() { mapContextMenu.hide(false); - TrackMenuFragment.showInstance(mapActivity, selectedGpxPoint.getSelectedGpxFile()); + WptPt wptPt = selectedGpxPoint.selectedPoint; + LatLon latLon = new LatLon(wptPt.lat, wptPt.lon); + TrackMenuFragment.showInstance(mapActivity, selectedGpxPoint.getSelectedGpxFile(), latLon); } }; leftTitleButtonController.caption = mapActivity.getString(R.string.shared_string_open_track); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index 9147de6de9..4b58c0b9dc 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -149,6 +149,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card private Location lastLocation; private UpdateLocationViewCache updateLocationViewCache; private boolean locationUpdateStarted; + private LatLon latLon; private int menuTitleHeight; private int toolbarHeightPx; @@ -259,6 +260,10 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card this.selectedGpxFile = selectedGpxFile; } + public void setLatLon(LatLon latLon) { + this.latLon = latLon; + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); @@ -556,10 +561,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card MapActivity mapActivity = getMapActivity(); View view = overviewCard.getView(); if (mapActivity != null && view != null) { - MapContextMenu menu = mapActivity.getContextMenu(); TextView distanceText = (TextView) view.findViewById(R.id.distance); ImageView direction = (ImageView) view.findViewById(R.id.direction); - app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, menu.getLatLon()); + app.getUIUtilities().updateLocationView(updateLocationViewCache, direction, distanceText, latLon); } } @@ -1113,7 +1117,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(path); } if (selectedGpxFile != null) { - showInstance(mapActivity, selectedGpxFile); + showInstance(mapActivity, selectedGpxFile, null); } else if (!Algorithms.isEmpty(path)) { String title = app.getString(R.string.loading_smth, ""); final ProgressDialog progress = ProgressDialog.show(mapActivity, title, app.getString(R.string.loading_data)); @@ -1126,7 +1130,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card if (mapActivity != null) { OsmandApplication app = mapActivity.getMyApplication(); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().selectGpxFile(result, true, false); - showInstance(mapActivity, selectedGpxFile); + showInstance(mapActivity, selectedGpxFile, null); } if (progress != null && AndroidUtils.isActivityNotDestroyed(mapActivity)) { progress.dismiss(); @@ -1138,7 +1142,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } } - public static boolean showInstance(@NonNull MapActivity mapActivity, SelectedGpxFile selectedGpxFile) { + public static boolean showInstance(@NonNull MapActivity mapActivity, SelectedGpxFile selectedGpxFile, @Nullable LatLon latLon) { try { Bundle args = new Bundle(); args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuState.HEADER_ONLY); @@ -1148,6 +1152,14 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card fragment.setRetainInstance(true); fragment.setSelectedGpxFile(selectedGpxFile); + if (latLon != null) { + fragment.setLatLon(latLon); + } else { + QuadRect rect = selectedGpxFile.getGpxFile().getRect(); + LatLon latLonRect = new LatLon(rect.centerY(), rect.centerX()); + fragment.setLatLon(latLonRect); + } + mapActivity.getSupportFragmentManager() .beginTransaction() .replace(R.id.fragmentContainer, fragment, TAG) From a335ce8c10bcc4731534ac96c1c8f4f80866341e Mon Sep 17 00:00:00 2001 From: Hardy Date: Sun, 31 Jan 2021 09:01:39 +0100 Subject: [PATCH 49/81] shorten string --- OsmAnd/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 2c3358dda4..bbf5028d03 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -55,7 +55,7 @@ Rename track Edit track Upload to OpenStreetMap - Analyze by intervals (split interval) + Analyze split intervals Empty Select folder or add new one Select folder From 77c69183e02192ed94cf08a2fc139c035f07506e Mon Sep 17 00:00:00 2001 From: Hardy Date: Sun, 31 Jan 2021 09:09:24 +0100 Subject: [PATCH 50/81] shorten string --- OsmAnd/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 620e4a10ea..063f7f7df3 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3972,7 +3972,7 @@ Ordner auswählen Ordner auswählen oder neuen hinzufügen Leer - Nach Intervallen auswerten (geteiltes Intervall) + Nach Intervallen auswerten Hochladen zu OpenStreetMap Track editieren Track umbenennen @@ -4008,4 +4008,4 @@ Wegpunkte löschen In Favoriten kopieren In Kartenmarkierungen kopieren - \ No newline at end of file + From bbf341cde2dc6bdc375eb81870bd9cf1e167bf07 Mon Sep 17 00:00:00 2001 From: Skalii Date: Sun, 31 Jan 2021 12:43:14 +0200 Subject: [PATCH 51/81] add column names to the insert script for clarity in which order to insert data --- OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java index b06d3bb1a5..e173a49ad1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java @@ -94,7 +94,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper { + TRACK_COL_DATE + ", " + TRACK_COL_HEADING + ")" + " VALUES (?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ - insertPointsScript = "INSERT INTO " + POINT_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ + insertPointsScript = "INSERT INTO " + POINT_NAME + " (" + POINT_COL_LAT + ", " + POINT_COL_LON + ", " + + POINT_COL_DATE + ", " + POINT_COL_DESCRIPTION + ", " + POINT_COL_NAME + ", " + + POINT_COL_CATEGORY + ", " + POINT_COL_COLOR + ", " + POINT_COL_ICON + ", " + + POINT_COL_BACKGROUND + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; //$NON-NLS-1$ //$NON-NLS-2$ } @Override From 29b9d038758e9e537f8b404b7570e1a4904594be Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Sun, 31 Jan 2021 15:34:00 +0200 Subject: [PATCH 52/81] Small fix --- .../osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java b/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java index da3b6f106d..2fdf57b9be 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/SelectWikiLanguagesBottomSheet.java @@ -212,7 +212,7 @@ public class SelectWikiLanguagesBottomSheet extends MenuBottomSheetDialogFragmen } } else { wikiPlugin.setLanguagesToShow(localesForSaving); - wikiPlugin.setShowAllLanguages(isGlobalWikiPoiEnabled); + wikiPlugin.setShowAllLanguages(global); } wikiPlugin.updateWikipediaState(); From 46559fc3280a4bbb4dd25a4c0e1a4841afdbf5db Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Feb 2021 01:19:40 +0200 Subject: [PATCH 53/81] Small fix --- .../net/osmand/aidlapi/customization/ProfileSettingsParams.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java index eee80329f7..a22d4e3c91 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java @@ -16,7 +16,7 @@ public class ProfileSettingsParams extends AidlParams { public static final String VERSION_KEY = "version"; public static final String REPLACE_KEY = "replace"; - public static final String SILENT_IMPORT_KEY = "silent_import"; + public static final String SILENT_IMPORT_KEY = "silentImport"; public static final String LATEST_CHANGES_KEY = "latestChanges"; public static final String PROFILE_SETTINGS_URI_KEY = "profileSettingsUri"; private Uri profileSettingsUri; From 8f8ddbf9b457362e28d8b873ed208c00b871c116 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Feb 2021 01:59:58 +0200 Subject: [PATCH 54/81] Try to remove duplicate code --- .../backend/backup/SettingsHelper.java | 54 +---- .../fragments/ImportSettingsFragment.java | 210 +----------------- 2 files changed, 11 insertions(+), 253 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java index 9a50851a56..11fe377040 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java @@ -728,6 +728,8 @@ public class SettingsHelper { } catch (IllegalArgumentException e) { LOG.warn("Trying to export unsuported file type", e); } + } else if (object instanceof FileSettingsItem) { + result.add((FileSettingsItem) object); } else if (object instanceof AvoidRoadInfo) { avoidRoads.add((AvoidRoadInfo) object); } else if (object instanceof ApplicationModeBean) { @@ -754,16 +756,20 @@ public class SettingsHelper { } } if (!quickActions.isEmpty()) { - result.add(new QuickActionsSettingsItem(app, getBaseQuickActionsSettingsItem(settingsItems), quickActions)); + QuickActionsSettingsItem baseItem = getBaseItem(SettingsItemType.QUICK_ACTIONS, QuickActionsSettingsItem.class, settingsItems); + result.add(new QuickActionsSettingsItem(app, baseItem, quickActions)); } if (!poiUIFilters.isEmpty()) { - result.add(new PoiUiFiltersSettingsItem(app, getBasePoiUiFiltersSettingsItem(settingsItems), poiUIFilters)); + PoiUiFiltersSettingsItem baseItem = getBaseItem(SettingsItemType.POI_UI_FILTERS, PoiUiFiltersSettingsItem.class, settingsItems); + result.add(new PoiUiFiltersSettingsItem(app, baseItem, poiUIFilters)); } if (!tileSourceTemplates.isEmpty()) { - result.add(new MapSourcesSettingsItem(app, getBaseMapSourcesSettingsItem(settingsItems), tileSourceTemplates)); + MapSourcesSettingsItem baseItem = getBaseItem(SettingsItemType.MAP_SOURCES, MapSourcesSettingsItem.class, settingsItems); + result.add(new MapSourcesSettingsItem(app, baseItem, tileSourceTemplates)); } if (!avoidRoads.isEmpty()) { - result.add(new AvoidRoadsSettingsItem(app, getBaseAvoidRoadsSettingsItem(settingsItems), avoidRoads)); + AvoidRoadsSettingsItem baseItem = getBaseItem(SettingsItemType.AVOID_ROADS, AvoidRoadsSettingsItem.class, settingsItems); + result.add(new AvoidRoadsSettingsItem(app, baseItem, avoidRoads)); } if (!appModeBeans.isEmpty()) { for (ApplicationModeBean modeBean : appModeBeans) { @@ -830,46 +836,6 @@ public class SettingsHelper { return null; } - @Nullable - private QuickActionsSettingsItem getBaseQuickActionsSettingsItem(List settingsItems) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.QUICK_ACTIONS) { - return (QuickActionsSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private PoiUiFiltersSettingsItem getBasePoiUiFiltersSettingsItem(List settingsItems) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.POI_UI_FILTERS) { - return (PoiUiFiltersSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private MapSourcesSettingsItem getBaseMapSourcesSettingsItem(List settingsItems) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.MAP_SOURCES) { - return (MapSourcesSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private AvoidRoadsSettingsItem getBaseAvoidRoadsSettingsItem(List settingsItems) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.AVOID_ROADS) { - return (AvoidRoadsSettingsItem) settingsItem; - } - } - return null; - } - @Nullable private T getBaseItem(SettingsItemType settingsItemType, Class clazz, List settingsItems) { for (SettingsItem settingsItem : settingsItems) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java index 83a271b059..b614bc57dd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java @@ -18,57 +18,24 @@ import androidx.fragment.app.FragmentManager; import com.google.android.material.appbar.CollapsingToolbarLayout; -import net.osmand.IndexConstants; import net.osmand.PlatformUtil; -import net.osmand.map.ITileSource; -import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.AppInitializer; -import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; -import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.download.ReloadIndexesTask; import net.osmand.plus.download.ReloadIndexesTask.ReloadIndexesListener; -import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; -import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; -import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.mapmarkers.MapMarkersGroup; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; -import net.osmand.plus.osmedit.OpenstreetmapPoint; -import net.osmand.plus.osmedit.OsmNotesPoint; -import net.osmand.plus.poi.PoiUIFilter; -import net.osmand.plus.quickaction.QuickAction; -import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; -import net.osmand.plus.settings.backend.ExportSettingsType; -import net.osmand.plus.settings.backend.backup.AvoidRoadsSettingsItem; -import net.osmand.plus.settings.backend.backup.FavoritesSettingsItem; import net.osmand.plus.settings.backend.backup.FileSettingsItem; -import net.osmand.plus.settings.backend.backup.GlobalSettingsItem; -import net.osmand.plus.settings.backend.backup.GpxSettingsItem; -import net.osmand.plus.settings.backend.backup.HistoryMarkersSettingsItem; -import net.osmand.plus.settings.backend.backup.MapSourcesSettingsItem; -import net.osmand.plus.settings.backend.backup.MarkersSettingsItem; -import net.osmand.plus.settings.backend.backup.OnlineRoutingSettingsItem; -import net.osmand.plus.settings.backend.backup.OsmEditsSettingsItem; -import net.osmand.plus.settings.backend.backup.OsmNotesSettingsItem; -import net.osmand.plus.settings.backend.backup.PoiUiFiltersSettingsItem; -import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; -import net.osmand.plus.settings.backend.backup.QuickActionsSettingsItem; -import net.osmand.plus.settings.backend.backup.SearchHistorySettingsItem; import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.settings.backend.backup.SettingsHelper.ImportAsyncTask; import net.osmand.plus.settings.backend.backup.SettingsItem; -import net.osmand.plus.settings.backend.backup.SettingsItemType; -import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import java.io.File; import java.lang.ref.WeakReference; -import java.util.ArrayList; import java.util.List; public class ImportSettingsFragment extends BaseSettingsListFragment { @@ -177,7 +144,7 @@ public class ImportSettingsFragment extends BaseSettingsListFragment { } private void importItems() { - List selectedItems = getSettingsItemsFromData(adapter.getData()); + List selectedItems = settingsHelper.prepareSettingsItems(adapter.getData(), settingsItems, false); if (file != null && settingsItems != null) { duplicateStartTime = System.currentTimeMillis(); settingsHelper.checkDuplicates(file, settingsItems, selectedItems, getDuplicatesListener()); @@ -272,181 +239,6 @@ public class ImportSettingsFragment extends BaseSettingsListFragment { this.settingsItems = settingsItems; } - @Nullable - private ProfileSettingsItem getBaseProfileSettingsItem(ApplicationModeBean modeBean) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.PROFILE) { - ProfileSettingsItem profileItem = (ProfileSettingsItem) settingsItem; - ApplicationModeBean bean = profileItem.getModeBean(); - if (Algorithms.objectEquals(bean.stringKey, modeBean.stringKey) && Algorithms.objectEquals(bean.userProfileName, modeBean.userProfileName)) { - return profileItem; - } - } - } - return null; - } - - @Nullable - private QuickActionsSettingsItem getBaseQuickActionsSettingsItem() { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.QUICK_ACTIONS) { - return (QuickActionsSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private PoiUiFiltersSettingsItem getBasePoiUiFiltersSettingsItem() { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.POI_UI_FILTERS) { - return (PoiUiFiltersSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private MapSourcesSettingsItem getBaseMapSourcesSettingsItem() { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.MAP_SOURCES) { - return (MapSourcesSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private AvoidRoadsSettingsItem getBaseAvoidRoadsSettingsItem() { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == SettingsItemType.AVOID_ROADS) { - return (AvoidRoadsSettingsItem) settingsItem; - } - } - return null; - } - - @Nullable - private T getBaseItem(SettingsItemType settingsItemType, Class clazz) { - for (SettingsItem settingsItem : settingsItems) { - if (settingsItem.getType() == settingsItemType && clazz.isInstance(settingsItem)) { - return clazz.cast(settingsItem); - } - } - return null; - } - - private List getSettingsItemsFromData(List data) { - List settingsItems = new ArrayList<>(); - List appModeBeans = new ArrayList<>(); - List quickActions = new ArrayList<>(); - List poiUIFilters = new ArrayList<>(); - List tileSourceTemplates = new ArrayList<>(); - List avoidRoads = new ArrayList<>(); - List osmNotesPointList = new ArrayList<>(); - List osmEditsPointList = new ArrayList<>(); - List favoriteGroups = new ArrayList<>(); - List markersGroups = new ArrayList<>(); - List markersHistoryGroups = new ArrayList<>(); - List historyEntries = new ArrayList<>(); - List onlineRoutingEngines = new ArrayList<>(); - for (Object object : data) { - if (object instanceof ApplicationModeBean) { - appModeBeans.add((ApplicationModeBean) object); - } else if (object instanceof QuickAction) { - quickActions.add((QuickAction) object); - } else if (object instanceof PoiUIFilter) { - poiUIFilters.add((PoiUIFilter) object); - } else if (object instanceof TileSourceTemplate || object instanceof SQLiteTileSource) { - tileSourceTemplates.add((ITileSource) object); - } else if (object instanceof File) { - File file = (File) object; - if (file.getName().endsWith(IndexConstants.GPX_FILE_EXT)) { - settingsItems.add(new GpxSettingsItem(app, file)); - } else { - settingsItems.add(new FileSettingsItem(app, file)); - } - } else if (object instanceof FileSettingsItem) { - settingsItems.add((FileSettingsItem) object); - } else if (object instanceof AvoidRoadInfo) { - avoidRoads.add((AvoidRoadInfo) object); - } else if (object instanceof OsmNotesPoint) { - osmNotesPointList.add((OsmNotesPoint) object); - } else if (object instanceof OpenstreetmapPoint) { - osmEditsPointList.add((OpenstreetmapPoint) object); - } else if (object instanceof FavoriteGroup) { - favoriteGroups.add((FavoriteGroup) object); - } else if (object instanceof GlobalSettingsItem) { - settingsItems.add((GlobalSettingsItem) object); - } else if (object instanceof MapMarkersGroup) { - MapMarkersGroup markersGroup = (MapMarkersGroup) object; - if (ExportSettingsType.ACTIVE_MARKERS.name().equals(markersGroup.getId())) { - markersGroups.add((MapMarkersGroup) object); - } else if (ExportSettingsType.HISTORY_MARKERS.name().equals(markersGroup.getId())) { - markersHistoryGroups.add((MapMarkersGroup) object); - } - } else if (object instanceof HistoryEntry) { - historyEntries.add((HistoryEntry) object); - } else if (object instanceof OnlineRoutingEngine) { - onlineRoutingEngines.add((OnlineRoutingEngine) object); - } - } - if (!appModeBeans.isEmpty()) { - for (ApplicationModeBean modeBean : appModeBeans) { - settingsItems.add(new ProfileSettingsItem(app, getBaseProfileSettingsItem(modeBean), modeBean)); - } - } - if (!quickActions.isEmpty()) { - settingsItems.add(new QuickActionsSettingsItem(app, getBaseQuickActionsSettingsItem(), quickActions)); - } - if (!poiUIFilters.isEmpty()) { - settingsItems.add(new PoiUiFiltersSettingsItem(app, getBasePoiUiFiltersSettingsItem(), poiUIFilters)); - } - if (!tileSourceTemplates.isEmpty()) { - settingsItems.add(new MapSourcesSettingsItem(app, getBaseMapSourcesSettingsItem(), tileSourceTemplates)); - } - if (!avoidRoads.isEmpty()) { - settingsItems.add(new AvoidRoadsSettingsItem(app, getBaseAvoidRoadsSettingsItem(), avoidRoads)); - } - if (!osmNotesPointList.isEmpty()) { - OsmNotesSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_NOTES, OsmNotesSettingsItem.class); - settingsItems.add(new OsmNotesSettingsItem(app, baseItem, osmNotesPointList)); - } - if (!osmEditsPointList.isEmpty()) { - OsmEditsSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_EDITS, OsmEditsSettingsItem.class); - settingsItems.add(new OsmEditsSettingsItem(app, baseItem, osmEditsPointList)); - } - if (!favoriteGroups.isEmpty()) { - FavoritesSettingsItem baseItem = getBaseItem(SettingsItemType.FAVOURITES, FavoritesSettingsItem.class); - settingsItems.add(new FavoritesSettingsItem(app, baseItem, favoriteGroups)); - } - if (!markersGroups.isEmpty()) { - List mapMarkers = new ArrayList<>(); - for (MapMarkersGroup group : markersGroups) { - mapMarkers.addAll(group.getMarkers()); - } - MarkersSettingsItem baseItem = getBaseItem(SettingsItemType.ACTIVE_MARKERS, MarkersSettingsItem.class); - settingsItems.add(new MarkersSettingsItem(app, baseItem, mapMarkers)); - } - if (!markersHistoryGroups.isEmpty()) { - List mapMarkers = new ArrayList<>(); - for (MapMarkersGroup group : markersHistoryGroups) { - mapMarkers.addAll(group.getMarkers()); - } - HistoryMarkersSettingsItem baseItem = getBaseItem(SettingsItemType.HISTORY_MARKERS, HistoryMarkersSettingsItem.class); - settingsItems.add(new HistoryMarkersSettingsItem(app, baseItem, mapMarkers)); - } - if (!historyEntries.isEmpty()) { - SearchHistorySettingsItem baseItem = getBaseItem(SettingsItemType.SEARCH_HISTORY, SearchHistorySettingsItem.class); - settingsItems.add(new SearchHistorySettingsItem(app, baseItem, historyEntries)); - } - if (!onlineRoutingEngines.isEmpty()) { - OnlineRoutingSettingsItem baseItem = getBaseItem(SettingsItemType.ONLINE_ROUTING_ENGINES, OnlineRoutingSettingsItem.class); - settingsItems.add(new OnlineRoutingSettingsItem(app, baseItem, onlineRoutingEngines)); - } - return settingsItems; - } - public void setFile(File file) { this.file = file; } From a70ad01304e2440fd1c8bfca426927afbd528e0e Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Feb 2021 04:05:51 +0200 Subject: [PATCH 55/81] Minor fixes --- .../UploadPhotoProgressBottomSheet.java | 32 +++++++++---------- .../mapcontextmenu/UploadPhotosAsyncTask.java | 7 ++-- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java index 46483ffc9b..05e4bcc468 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java @@ -33,6 +33,7 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen private int progress; private int maxProgress; + private boolean uploadingFinished; @Override public void createMenuItems(Bundle savedInstanceState) { @@ -44,17 +45,12 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen uploadedPhotosCounter = view.findViewById(R.id.description); progressBar = view.findViewById(R.id.progress_bar); progressBar.setMax(maxProgress); - String titleProgress = getString(progress == maxProgress? R.string.upload_photo_completed: R.string.upload_photo); - String descriptionProgress; - if (progress == maxProgress) { - descriptionProgress = getString(R.string.uploaded_count, progress, maxProgress); - } else { - descriptionProgress = getString(R.string.uploading_count, progress, maxProgress); - } + + int descriptionId = uploadingFinished ? R.string.uploaded_count : R.string.uploading_count; BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder() - .setDescription(descriptionProgress) - .setTitle(titleProgress) + .setDescription(getString(descriptionId, progress, maxProgress)) + .setTitle(getString(uploadingFinished ? R.string.upload_photo_completed : R.string.upload_photo)) .setCustomView(view) .create(); items.add(descriptionItem); @@ -74,9 +70,10 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen } private void updateProgress(int progress) { + int descriptionId = uploadingFinished ? R.string.uploaded_count : R.string.uploading_count; progressBar.setProgress(progress); - uploadedPhotosCounter.setText((getString(R.string.uploading_count, progress, maxProgress))); - uploadedPhotosTitle.setText(progress == maxProgress ? R.string.upload_photo_completed : R.string.upload_photo); + uploadedPhotosCounter.setText(getString(descriptionId, progress, maxProgress)); + uploadedPhotosTitle.setText(uploadingFinished ? R.string.upload_photo_completed : R.string.upload_photo); } @Override @@ -87,11 +84,9 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen @Override public void uploadPhotosFinished() { - if (progress == maxProgress) { - uploadedPhotosCounter.setText((getString(R.string.uploaded_count, progress, maxProgress))); - setDismissButtonTextId(R.string.shared_string_close); - UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), getDismissButtonTextId()); - } + uploadingFinished = true; + updateProgress(progress); + UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), getDismissButtonTextId()); } @Override @@ -103,6 +98,11 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen } } + @Override + protected int getDismissButtonTextId() { + return uploadingFinished ? R.string.shared_string_close : R.string.shared_string_cancel; + } + public static UploadPhotosListener showInstance(@NonNull FragmentManager fragmentManager, int maxProgress, OnDismissListener listener) { UploadPhotoProgressBottomSheet fragment = new UploadPhotoProgressBottomSheet(); fragment.setRetainInstance(true); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index 24d70a83dc..afe492af6f 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -128,7 +128,7 @@ public class UploadPhotosAsyncTask extends AsyncTask { private boolean uploadImageToPlace(InputStream image) { boolean success = false; InputStream serverData = new ByteArrayInputStream(compressImageToJpeg(image)); - final String baseUrl = OPRConstants.getBaseUrl(app); + String baseUrl = OPRConstants.getBaseUrl(app); // all these should be constant String url = baseUrl + "api/ipfs/image"; String response = NetworkUtils.sendPostDataRequest(url, "file", "compressed.jpeg", serverData); @@ -146,18 +146,16 @@ public class UploadPhotosAsyncTask extends AsyncTask { response, error); if (res != 200) { app.showToastMessage(error.toString()); - } else { - //ok, continue } } catch (FailedVerificationException e) { LOG.error(e); checkTokenAndShowScreen(); - } if (res != 200) { //image was uploaded but not added to blockchain checkTokenAndShowScreen(); } else { + success = true; String str = app.getString(R.string.successfully_uploaded_pattern, 1, 1); app.showToastMessage(str); //refresh the image @@ -166,7 +164,6 @@ public class UploadPhotosAsyncTask extends AsyncTask { if (activity != null) { MenuBuilder.execute(new GetImageCardsTask(activity, latLon, params, imageCardListener)); } - success = true; } } else { checkTokenAndShowScreen(); From fbb1c770a1c2be8ab47af5c9cc92199505cfacbb Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Feb 2021 10:10:50 +0200 Subject: [PATCH 56/81] implement OSRM turn types parsing --- .../main/java/net/osmand/util/MapUtils.java | 9 +- .../onlinerouting/OnlineRoutingHelper.java | 8 +- .../engine/GraphhopperEngine.java | 19 ++- .../engine/OnlineRoutingEngine.java | 3 +- .../plus/onlinerouting/engine/OrsEngine.java | 2 + .../plus/onlinerouting/engine/OsrmEngine.java | 155 +++++++++++++++++- .../plus/routing/RouteCalculationResult.java | 2 +- .../osmand/plus/routing/RouteProvider.java | 2 +- 8 files changed, 178 insertions(+), 22 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java b/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java index 15c3364007..7a37eee3aa 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java @@ -668,8 +668,13 @@ public class MapUtils { public static boolean areLatLonEqual(Location l1, Location l2) { return l1 == null && l2 == null - || (l1 != null && l2 != null && Math.abs(l1.getLatitude() - l2.getLatitude()) < 0.00001 - && Math.abs(l1.getLongitude() - l2.getLongitude()) < 0.00001); + || (l2 != null && areLatLonEqual(l1, l2.getLatitude(), l2.getLongitude())); + } + + public static boolean areLatLonEqual(Location l, double lat, double lon) { + return l != null + && Math.abs(l.getLatitude() - lat) < 0.00001 + && Math.abs(l.getLongitude() - lon) < 0.00001; } public static LatLon rhumbDestinationPoint(LatLon latLon, double distance, double bearing){ diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index c62d952eb3..ab56cade13 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -82,12 +82,12 @@ public class OnlineRoutingHelper { } @Nullable - public OnlineRoutingResponse calculateRouteOnline(@NonNull OnlineRoutingEngine engine, - @NonNull List path, - boolean leftSideNavigation) throws IOException, JSONException { + private OnlineRoutingResponse calculateRouteOnline(@NonNull OnlineRoutingEngine engine, + @NonNull List path, + boolean leftSideNavigation) throws IOException, JSONException { String url = engine.getFullUrl(path); String content = makeRequest(url); - return engine.parseServerResponse(content, leftSideNavigation); + return engine.parseServerResponse(content, app, leftSideNavigation); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index f2c7e19829..bcb3654ac3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -5,6 +5,7 @@ import androidx.annotation.Nullable; import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingResponse; @@ -84,6 +85,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, + @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); JSONObject root = obj.getJSONArray("paths").getJSONObject(0); @@ -97,24 +99,24 @@ public class GraphhopperEngine extends OnlineRoutingEngine { List directions = new ArrayList<>(); for (int i = 0; i < instructions.length(); i++) { JSONObject item = instructions.getJSONObject(i); - int sign = Integer.parseInt(item.getString("sign")); - int distance = (int) Math.round(Double.parseDouble(item.getString("distance"))); + int sign = item.getInt("sign"); + int distance = (int) Math.round(item.getDouble("distance")); String description = item.getString("text"); String streetName = item.getString("street_name"); - int timeInSeconds = (int) Math.round(Integer.parseInt(item.getString("time")) / 1000f); + int timeInSeconds = Math.round(item.getInt("time") / 1000f); JSONArray interval = item.getJSONArray("interval"); int startPointOffset = interval.getInt(0); int endPointOffset = interval.getInt(1); float averageSpeed = (float) distance / timeInSeconds; TurnType turnType = identifyTurnType(sign, leftSideNavigation); + if (turnType == null) { + turnType = TurnType.straight(); + } // TODO turnType.setTurnAngle() RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); direction.routePointOffset = startPointOffset; - if (turnType != null && turnType.isRoundAbout()) { - direction.routeEndPointOffset = endPointOffset; - } direction.setDescriptionRoute(description); direction.setStreetName(streetName); direction.setDistance(distance); @@ -143,7 +145,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { */ @Nullable public static TurnType identifyTurnType(int sign, boolean leftSide) { - int id = INVALID_ID; + Integer id = null; if (sign == -98) { // an U-turn without the knowledge @@ -192,6 +194,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { } else if (sign == 4) { // the finish instruction before the last point + id = TurnType.C; } else if (sign == 5) { // the instruction before a via point @@ -209,6 +212,6 @@ public class GraphhopperEngine extends OnlineRoutingEngine { id = TurnType.TRU; } - return id != INVALID_ID ? TurnType.valueOf(id, leftSide) : null; + return id != null ? TurnType.valueOf(id, leftSide) : null; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index af94be4282..24e5db7d5d 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import net.osmand.GPXUtilities.WptPt; import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; @@ -33,7 +34,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); - public final static int INVALID_ID = -1; private final Map params = new HashMap<>(); private final List allowedVehicles = new ArrayList<>(); @@ -100,6 +100,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { @Nullable public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content, + @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException; @NonNull diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 4502f5e957..5f8c2a5108 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -5,6 +5,7 @@ import androidx.annotation.Nullable; import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingResponse; @@ -81,6 +82,7 @@ public class OrsEngine extends OnlineRoutingEngine { @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, + @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); JSONArray array = obj.getJSONArray("features").getJSONObject(0) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 478c24886e..2e892d2aa6 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -5,19 +5,27 @@ import androidx.annotation.Nullable; import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.routing.RouteCalculationResult; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; import net.osmand.util.GeoPolylineParserUtil; +import net.osmand.util.MapUtils; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; import java.util.List; import java.util.Map; import static net.osmand.util.Algorithms.isEmpty; +import static net.osmand.util.Algorithms.objectEquals; public class OsrmEngine extends OnlineRoutingEngine { @@ -70,17 +78,154 @@ public class OsrmEngine extends OnlineRoutingEngine { @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, + @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); - String encoded = obj.getJSONArray("routes").getJSONObject(0).getString("geometry"); - List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); - if (!isEmpty(points)) { - List route = convertRouteToLocationsList(points); - return new OnlineRoutingResponse(route, null); + JSONObject routeInfo = obj.getJSONArray("routes").getJSONObject(0); + String encodedPoints = routeInfo.getString("geometry"); + List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + + List route = convertRouteToLocationsList(points); + List directions = new ArrayList<>(); + int startSearchingId = 0; + JSONArray legs = routeInfo.getJSONArray("legs"); + for (int i = 0; i < legs.length(); i++) { + JSONObject leg = legs.getJSONObject(i); + if (!leg.has("steps")) continue; + + JSONArray steps = leg.getJSONArray("steps"); + for (int j = 0; j < steps.length(); j++) { + JSONObject instruction = steps.getJSONObject(j); + JSONObject maneuver = instruction.getJSONObject("maneuver"); + String maneuverType = maneuver.getString("type"); + + JSONArray location = maneuver.getJSONArray("location"); + double lon = location.getDouble(0); + double lat = location.getDouble(1); + Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); + if (routePointOffset == null) continue; + startSearchingId = routePointOffset; + + // in meters + int distance = (int) Math.round(instruction.getDouble("distance")); + // in seconds + int duration = (int) Math.round(instruction.getDouble("duration")); + + float averageSpeed = (float) distance / duration; + TurnType turnType = parseTurnType(maneuver, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.setDistance(distance); + + String streetName = instruction.getString("name"); + String description = ""; + if (!objectEquals(maneuverType, "arrive")) { + description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; + } + description = description.trim(); + + direction.setStreetName(streetName); + direction.setDescriptionRoute(description); + direction.routePointOffset = routePointOffset; + directions.add(direction); + } + } + + return new OnlineRoutingResponse(route, directions); + } + + @Nullable + private Integer getLocationIndexInList(@NonNull List locations, + int startIndex, double lat, double lon) { + for (int i = startIndex; i < locations.size(); i++) { + Location l = locations.get(i); + if (MapUtils.areLatLonEqual(l, lat, lon)) { + return i; + } } return null; } + @NonNull + private TurnType parseTurnType(@NonNull JSONObject maneuver, + boolean leftSide) throws JSONException { + TurnType turnType = null; + + String type = maneuver.getString("type"); + String modifier = null; + if (maneuver.has("modifier")) { + modifier = maneuver.getString("modifier"); + } + + if (objectEquals(type, "roundabout") + || objectEquals(type, "rotary") + || objectEquals(type, "roundabout turn")) { + if (maneuver.has("exit")) { + int exit = maneuver.getInt("exit"); + turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); + } else if (modifier != null) { + // for simple roundabout turn without "exit" parameter + turnType = identifyTurnType(modifier, leftSide); + } + } else { + // for other maneuver types find TurnType + // like a basic turn into direction of the modifier + if (modifier != null) { + turnType = identifyTurnType(modifier, leftSide); + } + } + if (turnType == null) { + turnType = TurnType.straight(); + } + + int bearingBefore = maneuver.getInt("bearing_before"); + int bearingAfter = maneuver.getInt("bearing_after"); + float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); + turnType.setTurnAngle(angle); + + return turnType; + } + + @Nullable + private TurnType identifyTurnType(@NonNull String modifier, + boolean leftSide) { + Integer id = null; + switch (modifier) { + case "uturn": + id = TurnType.TU; + break; + + case "sharp right": + id = TurnType.TSHR; + break; + + case "right": + id = TurnType.TR; + break; + + case "slight right": + id = TurnType.TSLR; + break; + + case "straight": + id = TurnType.C; + break; + + case "slight left": + id = TurnType.TSLL; + break; + + case "left": + id = TurnType.TL; + break; + + case "sharp left": + id = TurnType.TSHL; + break; + } + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + @Override public boolean parseServerMessage(@NonNull StringBuilder sb, @NonNull String content) throws JSONException { diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index 4ef286826d..e6efcc321f 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -711,7 +711,7 @@ public class RouteCalculationResult { if (directions != null && directions.size() > 1) { for (int i = 1; i < directions.size();) { RouteDirectionInfo r = directions.get(i); - if (r.getTurnType() != null && r.getTurnType().getValue() == TurnType.C) { + if (r.getTurnType().getValue() == TurnType.C) { RouteDirectionInfo prev = directions.get(i - 1); prev.setAverageSpeed((prev.distance + r.distance) / (prev.distance / prev.getAverageSpeed() + r.distance / r.getAverageSpeed())); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 96bb1b19dc..0d2564eb3e 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -1206,7 +1206,7 @@ public class RouteProvider { helper.calculateRouteOnline(stringKey, getPathFromParams(params), params.leftSide); if (response != null) { params.intermediates = null; - return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, true); + return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, false); } else { return new RouteCalculationResult("Route is empty"); } From 17bfdad2c6685030872103b509162a9eecfd15ea Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Feb 2021 10:56:17 +0200 Subject: [PATCH 57/81] add roundabout info about exit number and turn angle --- .../main/java/net/osmand/router/TurnType.java | 6 +- .../engine/GraphhopperEngine.java | 68 +++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/TurnType.java b/OsmAnd-java/src/main/java/net/osmand/router/TurnType.java index 7b67669cf3..6f0db3fa86 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/TurnType.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/TurnType.java @@ -140,7 +140,7 @@ public class TurnType { r.setTurnAngle(angle); return r; } - + private TurnType(int vl) { this.value = vl; @@ -156,6 +156,10 @@ public class TurnType { return value == RNLB || value == TRU; } + public void setExitOut(int exitOut) { + this.exitOut = exitOut; + } + public void setTurnAngle(float turnAngle) { this.turnAngle = turnAngle; } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index bcb3654ac3..20bbfaa70e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -98,24 +98,19 @@ public class GraphhopperEngine extends OnlineRoutingEngine { JSONArray instructions = root.getJSONArray("instructions"); List directions = new ArrayList<>(); for (int i = 0; i < instructions.length(); i++) { - JSONObject item = instructions.getJSONObject(i); - int sign = item.getInt("sign"); - int distance = (int) Math.round(item.getDouble("distance")); - String description = item.getString("text"); - String streetName = item.getString("street_name"); - int timeInSeconds = Math.round(item.getInt("time") / 1000f); - JSONArray interval = item.getJSONArray("interval"); + JSONObject instruction = instructions.getJSONObject(i); + int distance = (int) Math.round(instruction.getDouble("distance")); + String description = instruction.getString("text"); + String streetName = instruction.getString("street_name"); + int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); + JSONArray interval = instruction.getJSONArray("interval"); int startPointOffset = interval.getInt(0); int endPointOffset = interval.getInt(1); float averageSpeed = (float) distance / timeInSeconds; - TurnType turnType = identifyTurnType(sign, leftSideNavigation); - if (turnType == null) { - turnType = TurnType.straight(); - } - // TODO turnType.setTurnAngle() - + TurnType turnType = parseTurnType(instruction, leftSideNavigation); RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.routePointOffset = startPointOffset; direction.setDescriptionRoute(description); direction.setStreetName(streetName); @@ -125,24 +120,30 @@ public class GraphhopperEngine extends OnlineRoutingEngine { return new OnlineRoutingResponse(route, directions); } - @Override - public boolean parseServerMessage(@NonNull StringBuilder sb, - @NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - if (obj.has("message")) { - String message = obj.getString("message"); - sb.append(message); + @NonNull + private TurnType parseTurnType(@NonNull JSONObject instruction, + boolean leftSide) throws JSONException { + int sign = instruction.getInt("sign"); + TurnType turnType = identifyTurnType(sign, leftSide); + + if (turnType == null) { + turnType = TurnType.straight(); + } else if (turnType.isRoundAbout()) { + if (instruction.has("exit_number")) { + int exit = instruction.getInt("exit_number"); + turnType.setExitOut(exit); + } + if (instruction.has("turn_angle")) { + float angle = (float) instruction.getDouble("turn_angle"); + turnType.setTurnAngle(angle); + } + } else { + // TODO turnType.setTurnAngle() } - return obj.has("paths"); + + return turnType; } - /** - * @param sign - a number which specifies the turn type to show (Graphhopper API value) - * @return a TurnType object defined in OsmAnd which is equivalent to a value from the Graphhopper API - * - * For future compatibility it is important that all clients - * are able to handle also unknown instruction sign numbers - */ @Nullable public static TurnType identifyTurnType(int sign, boolean leftSide) { Integer id = null; @@ -214,4 +215,15 @@ public class GraphhopperEngine extends OnlineRoutingEngine { return id != null ? TurnType.valueOf(id, leftSide) : null; } + + @Override + public boolean parseServerMessage(@NonNull StringBuilder sb, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + if (obj.has("message")) { + String message = obj.getString("message"); + sb.append(message); + } + return obj.has("paths"); + } } From de773909a0ce3fceb6610eae9821189877d1f1bc Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Feb 2021 11:34:28 +0200 Subject: [PATCH 58/81] Small fixes --- OsmAnd/res/layout/center_button_container.xml | 28 ++-- OsmAnd/res/layout/custom_radio_buttons.xml | 55 ++----- .../res/layout/custom_radio_buttons_group.xml | 68 --------- .../res/layout/gpx_list_item_tab_content.xml | 40 +++--- OsmAnd/res/layout/left_button_container.xml | 7 +- OsmAnd/res/layout/right_button_container.xml | 6 +- OsmAnd/src/net/osmand/plus/UiUtilities.java | 134 +++--------------- .../plus/myplaces/GPXItemPagerAdapter.java | 101 ++++++------- .../plus/myplaces/SegmentGPXAdapter.java | 12 +- .../net/osmand/plus/track/SegmentsCard.java | 2 +- .../views/controls/PagerSlidingTabStrip.java | 115 ++++++++------- 11 files changed, 180 insertions(+), 388 deletions(-) delete mode 100644 OsmAnd/res/layout/custom_radio_buttons_group.xml diff --git a/OsmAnd/res/layout/center_button_container.xml b/OsmAnd/res/layout/center_button_container.xml index 8c8fdf1617..531b6b97e8 100644 --- a/OsmAnd/res/layout/center_button_container.xml +++ b/OsmAnd/res/layout/center_button_container.xml @@ -1,19 +1,19 @@ + xmlns:osmand="http://schemas.android.com/apk/res-auto" + android:id="@+id/center_button_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1"> - + \ No newline at end of file diff --git a/OsmAnd/res/layout/custom_radio_buttons.xml b/OsmAnd/res/layout/custom_radio_buttons.xml index d5ef10977d..2ea2775d62 100644 --- a/OsmAnd/res/layout/custom_radio_buttons.xml +++ b/OsmAnd/res/layout/custom_radio_buttons.xml @@ -1,7 +1,6 @@ - - + android:layout_weight="1" /> - - - + android:layout_weight="1" /> - - - - - - - - - + android:layout_weight="1" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/custom_radio_buttons_group.xml b/OsmAnd/res/layout/custom_radio_buttons_group.xml deleted file mode 100644 index f0caa4a375..0000000000 --- a/OsmAnd/res/layout/custom_radio_buttons_group.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/layout/gpx_list_item_tab_content.xml b/OsmAnd/res/layout/gpx_list_item_tab_content.xml index d2ce779b8b..ac7918d06a 100644 --- a/OsmAnd/res/layout/gpx_list_item_tab_content.xml +++ b/OsmAnd/res/layout/gpx_list_item_tab_content.xml @@ -1,24 +1,32 @@ + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> - + - + + - + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/left_button_container.xml b/OsmAnd/res/layout/left_button_container.xml index c6a32ec74a..e56ec7b06a 100644 --- a/OsmAnd/res/layout/left_button_container.xml +++ b/OsmAnd/res/layout/left_button_container.xml @@ -1,7 +1,6 @@ + osmand:typeface="@string/font_roboto_medium" /> - + \ No newline at end of file diff --git a/OsmAnd/res/layout/right_button_container.xml b/OsmAnd/res/layout/right_button_container.xml index bb618949af..02b237d6c0 100644 --- a/OsmAnd/res/layout/right_button_container.xml +++ b/OsmAnd/res/layout/right_button_container.xml @@ -12,8 +12,8 @@ android:layout_height="match_parent" android:background="?attr/selectableItemBackground" android:gravity="center" + android:text="@string/map_widget_speed" android:textSize="@dimen/default_desc_text_size" - osmand:typeface="@string/font_roboto_medium" - android:text="@string/map_widget_speed"/> + osmand:typeface="@string/font_roboto_medium" /> - + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 8847f953eb..47f3842711 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -86,11 +86,6 @@ public class UiUtilities { } public enum CustomRadioButtonType { - START, - END, - } - - public enum CustomRadioButtonTypeGroup { START, CENTER, END, @@ -462,6 +457,8 @@ public class UiUtilities { TextView startButtonText = buttonsView.findViewById(R.id.left_button); View startButtonContainer = buttonsView.findViewById(R.id.left_button_container); + TextView centerButtonText = buttonsView.findViewById(R.id.center_button); + View centerButtonContainer = buttonsView.findViewById(R.id.center_button_container); TextView endButtonText = buttonsView.findViewById(R.id.right_button); View endButtonContainer = buttonsView.findViewById(R.id.right_button_container); GradientDrawable background = new GradientDrawable(); @@ -477,9 +474,27 @@ public class UiUtilities { endButtonText.setTextColor(activeColor); startButtonContainer.setBackgroundDrawable(background); startButtonText.setTextColor(textColor); + + if (centerButtonContainer != null) { + centerButtonText.setTextColor(activeColor); + centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); + } + } else if (buttonType == CustomRadioButtonType.CENTER) { + background.setCornerRadii(new float[] {0, 0, 0, 0, 0, 0, 0, 0}); + centerButtonContainer.setBackgroundDrawable(background); + centerButtonText.setTextColor(textColor); + + if (endButtonContainer != null) { + endButtonText.setTextColor(activeColor); + endButtonContainer.setBackgroundColor(Color.TRANSPARENT); + } + if (startButtonContainer != null) { + startButtonText.setTextColor(activeColor); + startButtonContainer.setBackgroundColor(Color.TRANSPARENT); + } } else { if (isLayoutRtl) { - background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius}); + background.setCornerRadii(new float[] {radius, radius, 0, 0, 0, 0, radius, radius}); } else { background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0}); } @@ -487,119 +502,14 @@ public class UiUtilities { endButtonText.setTextColor(textColor); startButtonContainer.setBackgroundColor(Color.TRANSPARENT); startButtonText.setTextColor(activeColor); - } - } - - public static void updateCustomRadioButtonsGroup(Context app, View buttonsView, boolean nightMode, - CustomRadioButtonTypeGroup buttonType) { - int activeColor = ContextCompat.getColor(app, nightMode - ? R.color.active_color_primary_dark - : R.color.active_color_primary_light); - int inActiveColor = ContextCompat.getColor(app, nightMode - ? R.color.text_color_secondary_dark - : R.color.text_color_secondary_light); - int textColor = ContextCompat.getColor(app, nightMode - ? R.color.text_color_primary_dark - : R.color.text_color_primary_light); - int roundedCorner = AndroidUtils.dpToPx(app, 4); - boolean isLayoutRtl = AndroidUtils.isLayoutRtl(app); - - TextView startButtonText = buttonsView.findViewById(R.id.left_button); - View startButtonContainer = buttonsView.findViewById(R.id.left_button_container); - TextView centerButtonText = buttonsView.findViewById(R.id.center_button); - View centerButtonContainer = buttonsView.findViewById(R.id.center_button_container); - TextView endButtonText = buttonsView.findViewById(R.id.right_button); - View endButtonContainer = buttonsView.findViewById(R.id.right_button_container); - GradientDrawable background = new GradientDrawable(); - background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); - background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f)); - - GradientDrawable startButtonRoundedCorner = new GradientDrawable(); - startButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); - GradientDrawable endButtonRoundedCorner = new GradientDrawable(); - endButtonRoundedCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); - GradientDrawable centerButtonSharpCorner = new GradientDrawable(); - centerButtonSharpCorner.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(inActiveColor, 0.5f)); - - setStartEndCenterRoundedCorner(roundedCorner, isLayoutRtl, startButtonRoundedCorner, endButtonRoundedCorner, centerButtonSharpCorner); - - if (buttonType == CustomRadioButtonTypeGroup.START) { - if (isLayoutRtl) { - background.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); - } else { - background.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); - } - - if (endButtonContainer != null && centerButtonContainer != null) { - endButtonContainer.setBackground(endButtonRoundedCorner); - endButtonText.setTextColor(activeColor); - centerButtonContainer.setBackground(centerButtonSharpCorner); - centerButtonText.setTextColor(activeColor); - startButtonContainer.setBackgroundDrawable(background); - startButtonText.setTextColor(textColor); - } else if (centerButtonContainer != null) { - centerButtonContainer.setBackground(endButtonRoundedCorner); - centerButtonText.setTextColor(activeColor); - startButtonContainer.setBackgroundDrawable(background); - startButtonText.setTextColor(textColor); - } else if (endButtonContainer != null) { - endButtonContainer.setBackground(endButtonRoundedCorner); - endButtonText.setTextColor(activeColor); - startButtonContainer.setBackgroundDrawable(background); - startButtonText.setTextColor(textColor); - } else if (endButtonContainer == null && centerButtonContainer == null) { - background.setCornerRadii(new float[]{roundedCorner, roundedCorner, roundedCorner, roundedCorner, roundedCorner, roundedCorner, roundedCorner, roundedCorner}); - startButtonContainer.setBackgroundDrawable(background); - startButtonText.setTextColor(textColor); - } - - } else if (buttonType == CustomRadioButtonTypeGroup.CENTER) { - centerButtonContainer.setBackgroundDrawable(background); - centerButtonText.setTextColor(textColor); - startButtonContainer.setBackground(startButtonRoundedCorner); - startButtonText.setTextColor(activeColor); - if (endButtonContainer != null) { - endButtonContainer.setBackground(endButtonRoundedCorner); - endButtonText.setTextColor(activeColor); - } else { - endButtonRoundedCorner.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); - centerButtonContainer.setBackgroundDrawable(endButtonRoundedCorner); - centerButtonText.setTextColor(textColor); - } - - } else { - if (isLayoutRtl) { - background.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); - } else { - background.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); - } - startButtonContainer.setBackground(startButtonRoundedCorner); - startButtonText.setTextColor(activeColor); - endButtonContainer.setBackgroundDrawable(background); - endButtonText.setTextColor(textColor); if (centerButtonContainer != null) { - centerButtonContainer.setBackground(centerButtonSharpCorner); centerButtonText.setTextColor(activeColor); + centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); } } } - private static void setStartEndCenterRoundedCorner(int roundedCorner, boolean isLayoutRtl, GradientDrawable startButtonRoundedCorner, GradientDrawable endButtonRoundedCorner, GradientDrawable centerButtonSharpCorner) { - if (isLayoutRtl) { - startButtonRoundedCorner.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); - } else { - startButtonRoundedCorner.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); - } - if (isLayoutRtl) { - endButtonRoundedCorner.setCornerRadii(new float[]{roundedCorner, roundedCorner, 0, 0, 0, 0, roundedCorner, roundedCorner}); - } else { - endButtonRoundedCorner.setCornerRadii(new float[]{0, 0, roundedCorner, roundedCorner, roundedCorner, roundedCorner, 0, 0}); - } - centerButtonSharpCorner.setCornerRadii(new float[]{0, 0, 0, 0, 0, 0, 0, 0}); - } - - public static void setupCompoundButtonDrawable(Context ctx, boolean nightMode, @ColorInt int activeColor, Drawable drawable) { int inactiveColor = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); int[][] states = new int[][]{ diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index e712d3ca01..0b167e4c97 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -7,13 +7,13 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.SwitchCompat; import androidx.viewpager.widget.PagerAdapter; -import androidx.viewpager.widget.ViewPager.OnPageChangeListener; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.data.Entry; @@ -24,7 +24,6 @@ import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture; import com.github.mikephil.charting.listener.OnChartGestureListener; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; -import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; @@ -37,6 +36,7 @@ import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.CustomRadioButtonType; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; @@ -44,7 +44,6 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.helpers.GpxUiHelper.LineGraphType; import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet; import net.osmand.plus.track.TrackDisplayHelper; -import net.osmand.plus.views.controls.PagerSlidingTabStrip; import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider; import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionInterface; import net.osmand.util.Algorithms; @@ -53,6 +52,7 @@ import net.osmand.util.MapUtils; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -74,7 +74,6 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private GpxDisplayItem gpxItem; private GPXTabItemType[] tabTypes; - private PagerSlidingTabStrip tabs; private SparseArray views = new SparseArray<>(); private SegmentActionsListener actionsListener; @@ -82,47 +81,17 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private boolean nightMode; - public GPXItemPagerAdapter(@NonNull final PagerSlidingTabStrip tabs, + public GPXItemPagerAdapter(@NonNull OsmandApplication app, @NonNull GpxDisplayItem gpxItem, @NonNull TrackDisplayHelper displayHelper, - @NonNull SegmentActionsListener actionsListener, - final boolean nightMode) { + boolean nightMode, @NonNull SegmentActionsListener actionsListener) { super(); - this.tabs = tabs; + this.app = app; this.gpxItem = gpxItem; - this.displayHelper = displayHelper; this.nightMode = nightMode; + this.displayHelper = displayHelper; this.actionsListener = actionsListener; - app = (OsmandApplication) tabs.getContext().getApplicationContext(); iconsCache = app.getUIUtilities(); - - tabs.setOnPageChangeListener(new OnPageChangeListener() { - - @Override - public void onPageSelected(int arg0) { - UiUtilities.CustomRadioButtonTypeGroup type; - if (arg0 == 0) { - type = UiUtilities.CustomRadioButtonTypeGroup.START; - } else if (arg0 == 1) { - type = UiUtilities.CustomRadioButtonTypeGroup.CENTER; - } else { - type = UiUtilities.CustomRadioButtonTypeGroup.END; - } - - View parent = (View) tabs.getChildAt(0); - UiUtilities.updateCustomRadioButtonsGroup(app, parent, nightMode, type); - } - - @Override - public void onPageScrolled(int arg0, float arg1, int arg2) { - } - - @Override - public void onPageScrollStateChanged(int arg0) { - - } - }); - fetchTabTypes(); } @@ -589,44 +558,60 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid return view == object; } + int singleTabLayoutId[] = {R.layout.center_button_container}; + int doubleTabsLayoutIds[] = {R.layout.left_button_container, R.layout.right_button_container}; + int tripleTabsLayoutIds[] = {R.layout.left_button_container, R.layout.center_button_container, R.layout.right_button_container}; + @Override public View getCustomTabView(@NonNull ViewGroup parent, int position) { int layoutId; - if (position == 0) { - layoutId = R.layout.left_button_container; - } else if (position == 1) { - layoutId = R.layout.center_button_container; + int count = getCount(); + if (count == 1) { + layoutId = singleTabLayoutId[position]; + } else if (count == 2) { + layoutId = doubleTabsLayoutIds[position]; } else { - layoutId = R.layout.right_button_container; + layoutId = tripleTabsLayoutIds[position]; } View tab = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); tab.setTag(tabTypes[position].name()); - deselect(tab); return tab; } @Override public void select(View tab) { GPXTabItemType tabType = GPXTabItemType.valueOf((String) tab.getTag()); - UiUtilities.CustomRadioButtonTypeGroup type; - if (tabType == GPXTabItemType.GPX_TAB_ITEM_GENERAL) { - type = UiUtilities.CustomRadioButtonTypeGroup.START; - } else if (tabType == GPXTabItemType.GPX_TAB_ITEM_ALTITUDE) { - type = UiUtilities.CustomRadioButtonTypeGroup.CENTER; - } else { - type = UiUtilities.CustomRadioButtonTypeGroup.END; - } + int index = Arrays.asList(tabTypes).indexOf(tabType); View parent = (View) tab.getParent(); - UiUtilities.updateCustomRadioButtonsGroup(app, parent, nightMode, type); - - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) parent.getLayoutParams(); - int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); - int containerMargin = app.getResources().getDimensionPixelSize(R.dimen.bottom_sheet_content_margin_small); - AndroidUtils.setMargins(params, contentPadding, containerMargin, contentPadding, containerMargin); + UiUtilities.updateCustomRadioButtons(app, parent, nightMode, getCustomRadioButtonType(index)); } @Override public void deselect(View tab) { + + } + + @Override + public void tabStylesUpdated(View tabsContainer, int currentPosition) { + ViewGroup.MarginLayoutParams params = (MarginLayoutParams) tabsContainer.getLayoutParams(); + params.height = app.getResources().getDimensionPixelSize(R.dimen.dialog_button_height); + tabsContainer.setLayoutParams(params); + UiUtilities.updateCustomRadioButtons(app, tabsContainer, nightMode, getCustomRadioButtonType(currentPosition)); + } + + private CustomRadioButtonType getCustomRadioButtonType(int index) { + int count = getCount(); + CustomRadioButtonType type = CustomRadioButtonType.CENTER; + if (count == 2) { + type = index > 0 ? CustomRadioButtonType.END : CustomRadioButtonType.START; + } else if (count == 3) { + if (index == 0) { + type = CustomRadioButtonType.START; + } else if (index == 2) { + type = CustomRadioButtonType.END; + } + } + return type; } @Override diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java index 9f2e234dcd..60141d5ccf 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/SegmentGPXAdapter.java @@ -1,13 +1,11 @@ package net.osmand.plus.myplaces; import android.content.Context; -import android.graphics.drawable.GradientDrawable; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; @@ -22,6 +20,7 @@ import java.util.List; public class SegmentGPXAdapter extends ArrayAdapter { + private OsmandApplication app; private TrackDisplayHelper displayHelper; private SegmentActionsListener listener; private boolean nightMode; @@ -31,7 +30,7 @@ public class SegmentGPXAdapter extends ArrayAdapter { @NonNull SegmentActionsListener listener, boolean nightMode) { super(context, R.layout.gpx_list_item_tab_content, items); - OsmandApplication app = (OsmandApplication) context.getApplicationContext(); + this.app = (OsmandApplication) context.getApplicationContext(); this.displayHelper = displayHelper; this.listener = listener; this.nightMode = nightMode; @@ -56,7 +55,7 @@ public class SegmentGPXAdapter extends ArrayAdapter { WrapContentHeightViewPager pager = row.findViewById(R.id.pager); PagerSlidingTabStrip tabLayout = row.findViewById(R.id.sliding_tabs); - pager.setAdapter(new GPXItemPagerAdapter(tabLayout, item, displayHelper, listener, nightMode)); + pager.setAdapter(new GPXItemPagerAdapter(app, item, displayHelper, nightMode, listener)); if (create) { tabLayout.setViewPager(pager); } else { @@ -72,9 +71,8 @@ public class SegmentGPXAdapter extends ArrayAdapter { View row = UiUtilities.getInflater(context, nightMode).inflate(R.layout.gpx_list_item_tab_content, root, false); PagerSlidingTabStrip tabLayout = row.findViewById(R.id.sliding_tabs); - tabLayout.setTabBackground(R.color.color_transparent); - tabLayout.setIndicatorHeight(AndroidUtils.dpToPx(context, 0)); - tabLayout.setTextSize(AndroidUtils.spToPx(context, 12f)); + tabLayout.setTabBackground(AndroidUtils.resolveAttribute(context, R.attr.btn_bg_border_inactive)); + tabLayout.setIndicatorHeight(0); tabLayout.setShouldExpand(true); WrapContentHeightViewPager pager = row.findViewById(R.id.pager); pager.setSwipeable(false); diff --git a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java index 9aa7c91391..ad266fc2ab 100644 --- a/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java +++ b/OsmAnd/src/net/osmand/plus/track/SegmentsCard.java @@ -47,7 +47,7 @@ public class SegmentsCard extends BaseCard { WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager); PagerSlidingTabStrip tabLayout = segmentView.findViewById(R.id.sliding_tabs); - pager.setAdapter(new GPXItemPagerAdapter(tabLayout, displayItem, displayHelper, listener, nightMode)); + pager.setAdapter(new GPXItemPagerAdapter(app, displayItem, displayHelper, nightMode, listener)); tabLayout.setViewPager(pager); container.addView(segmentView); diff --git a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java index e38a8619b0..f6d5bdd4fd 100644 --- a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java +++ b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java @@ -68,6 +68,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { public View getCustomTabView(@NonNull ViewGroup parent, int position); public void select(View tab); public void deselect(View tab); + public void tabStylesUpdated(View tabsContainer, int currentPosition); } public interface OnTabReselectedListener { @@ -307,6 +308,10 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { } } + public int getCurrentPosition() { + return currentPosition; + } + private void addTab(final int position, CharSequence title, View tabView) { TextView textView = (TextView) tabView.findViewById(R.id.tab_title); if (textView != null) { @@ -332,42 +337,32 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { private void updateTabStyles() { tabsContainer.setBackgroundResource(tabBackgroundResId); - for (int i = 0; i < tabCount; i++) { - View v = tabsContainer.getChildAt(i); - v.setBackgroundResource(tabBackgroundResId); - v.setPadding(tabPadding, v.getPaddingTop(), tabPadding, v.getPaddingBottom()); - TextView tab_title = (TextView) v.findViewById(R.id.tab_title); + if (pager.getAdapter() instanceof CustomTabProvider) { + ((CustomTabProvider) pager.getAdapter()).tabStylesUpdated(tabsContainer, currentPosition); + } else { + for (int i = 0; i < tabCount; i++) { + View v = tabsContainer.getChildAt(i); + v.setBackgroundResource(tabBackgroundResId); + v.setPadding(tabPadding, v.getPaddingTop(), tabPadding, v.getPaddingBottom()); - if (tab_title != null) { - tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); - tab_title.setTypeface(tabTypeface, pager.getCurrentItem() == i ? tabTypefaceSelectedStyle : tabTypefaceStyle); - switch (tabSelectionType) { - case ALPHA: - float alpha = pager.getCurrentItem() == i ? tabTextSelectedAlpha : tabTextAlpha; - tab_title.setAlpha(alpha); - tab_title.setTextColor(tabTextColor); - break; - case SOLID_COLOR: - tab_title.setAlpha(OPAQUE); - tab_title.setTextColor(pager.getCurrentItem() == i ? tabTextColor : tabInactiveTextColor); - break; - } - - // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a - // pre-ICS-build - if (textAllCaps) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - tab_title.setAllCaps(true); - } else { - tab_title.setText(tab_title.getText().toString().toUpperCase(locale)); + TextView tabTitle = v.findViewById(R.id.tab_title); + if (tabTitle != null) { + tabTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); + tabTitle.setTypeface(tabTypeface, pager.getCurrentItem() == i ? tabTypefaceSelectedStyle : tabTypefaceStyle); + switch (tabSelectionType) { + case ALPHA: + float alpha = pager.getCurrentItem() == i ? tabTextSelectedAlpha : tabTextAlpha; + tabTitle.setAlpha(alpha); + tabTitle.setTextColor(tabTextColor); + break; + case SOLID_COLOR: + tabTitle.setAlpha(OPAQUE); + tabTitle.setTextColor(pager.getCurrentItem() == i ? tabTextColor : tabInactiveTextColor); + break; + } + if (textAllCaps) { + tabTitle.setAllCaps(true); } - } - } - if (pager.getAdapter() instanceof CustomTabProvider) { - if (pager.getCurrentItem() == i) { - ((CustomTabProvider) pager.getAdapter()).select(v); - } else { - ((CustomTabProvider) pager.getAdapter()).deselect(v); } } } @@ -558,39 +553,41 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { private void notSelected(View tab) { if (tab != null) { - TextView title = (TextView) tab.findViewById(R.id.tab_title); - if (title != null) { - title.setTypeface(tabTypeface, tabTypefaceStyle); - switch (tabSelectionType) { - case ALPHA: - title.setAlpha(tabTextAlpha); - break; - case SOLID_COLOR: - title.setTextColor(tabInactiveTextColor); - break; - } - } if (pager.getAdapter() instanceof CustomTabProvider) { ((CustomTabProvider) pager.getAdapter()).deselect(tab); + } else { + TextView title = tab.findViewById(R.id.tab_title); + if (title != null) { + title.setTypeface(tabTypeface, tabTypefaceStyle); + switch (tabSelectionType) { + case ALPHA: + title.setAlpha(tabTextAlpha); + break; + case SOLID_COLOR: + title.setTextColor(tabInactiveTextColor); + break; + } + } } } } private void selected(View tab) { if (tab != null) { - TextView title = (TextView) tab.findViewById(R.id.tab_title); - if (title != null) { - title.setTypeface(tabTypeface, tabTypefaceSelectedStyle); - switch (tabSelectionType) { - case ALPHA: - title.setAlpha(tabTextSelectedAlpha); - break; - case SOLID_COLOR: - title.setTextColor(tabTextColor); - break; - } - if (pager.getAdapter() instanceof CustomTabProvider) { - ((CustomTabProvider) pager.getAdapter()).select(tab); + if (pager.getAdapter() instanceof CustomTabProvider) { + ((CustomTabProvider) pager.getAdapter()).select(tab); + } else { + TextView title = tab.findViewById(R.id.tab_title); + if (title != null) { + title.setTypeface(tabTypeface, tabTypefaceSelectedStyle); + switch (tabSelectionType) { + case ALPHA: + title.setAlpha(tabTextSelectedAlpha); + break; + case SOLID_COLOR: + title.setTextColor(tabTextColor); + break; + } } } } From 99ae414d1d36cad58759bdc98bb28f205509da09 Mon Sep 17 00:00:00 2001 From: Nekromanser <78290702+Nekromanser@users.noreply.github.com> Date: Mon, 1 Feb 2021 10:17:32 +0000 Subject: [PATCH 59/81] Update phrases.xml Improved finnish translation and fixed typos. --- OsmAnd/res/values-fi/phrases.xml | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/values-fi/phrases.xml b/OsmAnd/res/values-fi/phrases.xml index 7751c5bb95..6453253dd4 100644 --- a/OsmAnd/res/values-fi/phrases.xml +++ b/OsmAnd/res/values-fi/phrases.xml @@ -17,7 +17,7 @@ Bussipysäkki Trollibussin pysäkki Raitiovaunupysäkki - Piknic paikka + Piknik-paikka Merkittävä kivi Ankkurointipaikka Majakka/linjavalo @@ -311,8 +311,8 @@ Ei Visa Electron -kortteja Shekit Shekkejä ei hyväksytä - Visa Debit -kortit - Ei Visa Debit -kortteja + Visa Debit-kortit + Ei Visa Debit-kortteja Muut Muita maksutapoja ei hyväksytä Bancomat @@ -1139,28 +1139,28 @@ Ei MasterCard-kortteja Maestro-kortit Ei Maestro-kortteja - Ei American Express (AMEX) -kortteja - Ei Diners Club -kortteja + Ei American Express (AMEX)-kortteja + Ei Diners Club-kortteja Ei DKV-kortteja Ei UTA-kortteja Ei Efectivo-maksua Ei Girocard-kortteja Discover Card - Ei Discover Card -kortteja + Ei Discover Card-kortteja Ei Litecoinia Ei PIKEPASS-maksua Ei kryptovaluuttaa - Ei Routex -tankkauskortteja - Ei IC Stored Fare -kortteja + Ei Routex-tankkauskortteja + Ei IC Stored Fare-kortteja Ei JCB-kortteja Ei Laser-kortteja Ei Quick-kortteja Ei Eurowag-kortteja - Ei E-ZPass -maksua + Ei E-ZPass-maksua Ei Euroshell-tankkauskortteja Ei KITCard-maksua Ei Westfalen-kortteja - Ei V PAY -kortteja + Ei V PAY-kortteja Ei Dogecoinia Ei Cibus-kortteja Ei maksua tilisiirrolla @@ -1172,7 +1172,7 @@ Ei Minipay-maksua Ei MiniCash-maksua Ei Moneo-maksua - Ei Monedero 4B -maksua + Ei Monedero 4B-maksua Ei Monedero-maksua Ei BankAxess-maksua Ei Coinkite-maksua @@ -1182,20 +1182,20 @@ Ei tekstiviestimaksua Ei Oyster-kortteja Ei SUBE-kortteja - Ei Via Verde -maksua + Ei Via Verde-maksua Lounassetelit Ei lounasseteleitä Ei PayPal-maksua - Ei U-Key -maksua + Ei U-Key-maksua Poletit Ei poletteja Ei lahjakorttimaksua - Ei Golden Crown -kortteja + Ei Golden Crown-kortteja Ei PRO100-kortteja - Ei Union Card -kortteja + Ei Union Card-kortteja Ei MTS-Money -maksua - Ei Yandex.Money -maksua - Ei OV-Chipkaart -kortteja + Ei Yandex.Money-maksua + Ei OV-Chipkaart-kortteja Tapahtumapaikka Vain kasvisruokaa Kasvisruokaa @@ -1245,9 +1245,9 @@ Sisätilat Ulkona Ei wc-tiloja - Inva-wc: kyllä - Inva-wc: ei - Asiakas-wc + Inva-WC: kyllä + Inva-WC: ei + Asiakas-WC WC:n käyttö: yhteisö WC:n käyttö: julkinen Vauvan vaihtopöytä @@ -1522,4 +1522,4 @@ Vieras talo Majapaikka Vuoristorata - \ No newline at end of file + From 0ff4b8701197603ea3c63952b8eb738a5f4a6c49 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 1 Feb 2021 12:37:56 +0200 Subject: [PATCH 60/81] Fix altitude --- OsmAnd/res/layout/center_button_container.xml | 7 ++++--- OsmAnd/res/layout/left_button_container.xml | 7 ++++--- OsmAnd/res/layout/right_button_container.xml | 7 ++++--- OsmAnd/src/net/osmand/plus/UiUtilities.java | 15 ++++++++++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/layout/center_button_container.xml b/OsmAnd/res/layout/center_button_container.xml index 531b6b97e8..99858650dc 100644 --- a/OsmAnd/res/layout/center_button_container.xml +++ b/OsmAnd/res/layout/center_button_container.xml @@ -1,19 +1,20 @@ + osmand:typeface="@string/font_roboto_medium" + tools:text="@string/altitude" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/left_button_container.xml b/OsmAnd/res/layout/left_button_container.xml index e56ec7b06a..3370e554aa 100644 --- a/OsmAnd/res/layout/left_button_container.xml +++ b/OsmAnd/res/layout/left_button_container.xml @@ -1,19 +1,20 @@ + osmand:typeface="@string/font_roboto_medium" + tools:text="@string/shared_string_overview" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/right_button_container.xml b/OsmAnd/res/layout/right_button_container.xml index 02b237d6c0..ab24bdfcc9 100644 --- a/OsmAnd/res/layout/right_button_container.xml +++ b/OsmAnd/res/layout/right_button_container.xml @@ -1,19 +1,20 @@ + osmand:typeface="@string/font_roboto_medium" + tools:text="@string/map_widget_speed" /> \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 47f3842711..5e5dc0db1e 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -455,12 +455,10 @@ public class UiUtilities { int radius = AndroidUtils.dpToPx(app, 4); boolean isLayoutRtl = AndroidUtils.isLayoutRtl(app); - TextView startButtonText = buttonsView.findViewById(R.id.left_button); View startButtonContainer = buttonsView.findViewById(R.id.left_button_container); - TextView centerButtonText = buttonsView.findViewById(R.id.center_button); View centerButtonContainer = buttonsView.findViewById(R.id.center_button_container); - TextView endButtonText = buttonsView.findViewById(R.id.right_button); View endButtonContainer = buttonsView.findViewById(R.id.right_button_container); + GradientDrawable background = new GradientDrawable(); background.setColor(UiUtilities.getColorWithAlpha(activeColor, 0.1f)); background.setStroke(AndroidUtils.dpToPx(app, 1), UiUtilities.getColorWithAlpha(activeColor, 0.5f)); @@ -470,25 +468,32 @@ public class UiUtilities { } else { background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius}); } + TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); + TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); + endButtonContainer.setBackgroundColor(Color.TRANSPARENT); endButtonText.setTextColor(activeColor); startButtonContainer.setBackgroundDrawable(background); startButtonText.setTextColor(textColor); if (centerButtonContainer != null) { + TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); centerButtonText.setTextColor(activeColor); centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); } } else if (buttonType == CustomRadioButtonType.CENTER) { background.setCornerRadii(new float[] {0, 0, 0, 0, 0, 0, 0, 0}); centerButtonContainer.setBackgroundDrawable(background); + TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); centerButtonText.setTextColor(textColor); if (endButtonContainer != null) { + TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); endButtonText.setTextColor(activeColor); endButtonContainer.setBackgroundColor(Color.TRANSPARENT); } if (startButtonContainer != null) { + TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); startButtonText.setTextColor(activeColor); startButtonContainer.setBackgroundColor(Color.TRANSPARENT); } @@ -498,12 +503,16 @@ public class UiUtilities { } else { background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0}); } + TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); + TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); + endButtonContainer.setBackgroundDrawable(background); endButtonText.setTextColor(textColor); startButtonContainer.setBackgroundColor(Color.TRANSPARENT); startButtonText.setTextColor(activeColor); if (centerButtonContainer != null) { + TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); centerButtonText.setTextColor(activeColor); centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); } From cfa202c3d4d459e0cf67b6f4310f1ea76e64935a Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Feb 2021 12:44:49 +0200 Subject: [PATCH 61/81] refactor server wrong response checking move OnlineRoutingResponse class to OnlineRoutingEngine --- .../onlinerouting/OnlineRoutingHelper.java | 1 + .../onlinerouting/OnlineRoutingResponse.java | 24 ------ .../engine/GraphhopperEngine.java | 23 +++--- .../engine/OnlineRoutingEngine.java | 76 ++++++++++++++++--- .../plus/onlinerouting/engine/OrsEngine.java | 24 +++--- .../plus/onlinerouting/engine/OsrmEngine.java | 26 +++---- .../ui/OnlineRoutingEngineFragment.java | 8 +- .../osmand/plus/routing/RouteProvider.java | 2 +- 8 files changed, 103 insertions(+), 81 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index ab56cade13..de36b87449 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -9,6 +9,7 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java deleted file mode 100644 index 02a6a8f53c..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.osmand.plus.onlinerouting; - -import net.osmand.Location; -import net.osmand.plus.routing.RouteDirectionInfo; - -import java.util.List; - -public class OnlineRoutingResponse { - private List route; - private List directions; - - public OnlineRoutingResponse(List route, List directions) { - this.route = route; - this.directions = directions; - } - - public List getRoute() { - return route; - } - - public List getDirections() { - return directions; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 20bbfaa70e..930ebcab8d 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -8,7 +8,6 @@ import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.router.TurnType; @@ -84,12 +83,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine { @Nullable @Override - public OnlineRoutingResponse parseServerResponse(@NonNull String content, + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { - JSONObject obj = new JSONObject(content); - JSONObject root = obj.getJSONArray("paths").getJSONObject(0); - String encoded = root.getString("points"); List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); if (isEmpty(points)) return null; @@ -216,14 +212,15 @@ public class GraphhopperEngine extends OnlineRoutingEngine { return id != null ? TurnType.valueOf(id, leftSide) : null; } + @NonNull @Override - public boolean parseServerMessage(@NonNull StringBuilder sb, - @NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - if (obj.has("message")) { - String message = obj.getString("message"); - sb.append(message); - } - return obj.has("paths"); + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "paths"; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 24e5db7d5d..0752282c70 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -12,12 +12,14 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteProvider; import net.osmand.util.Algorithms; +import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import java.util.ArrayList; import java.util.Arrays; @@ -98,10 +100,31 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull public abstract String getStandardUrl(); + public OnlineRoutingResponse parseServerResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONObject root = parseRootResponseObject(content); + return root != null ? parseServerResponse(root, app, leftSideNavigation) : null; + } + @Nullable - public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException; + protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; + + @Nullable + protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException { + JSONObject fullJSON = new JSONObject(content); + String responseArrayKey = getRootArrayKey(); + JSONArray array = null; + if (fullJSON.has(responseArrayKey)) { + array = fullJSON.getJSONArray(responseArrayKey); + } + return array != null && array.length() > 0 ? array.getJSONObject(0) : null; + } + + @NonNull + protected abstract String getRootArrayKey(); @NonNull protected List convertRouteToLocationsList(@NonNull List route) { @@ -161,7 +184,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { return allowedParameters.contains(key); } - protected void allowParameters(@NonNull EngineParameter ... allowedParams) { + protected void allowParameters(@NonNull EngineParameter... allowedParams) { allowedParameters.addAll(Arrays.asList(allowedParams)); } @@ -193,8 +216,19 @@ public abstract class OnlineRoutingEngine implements Cloneable { return CUSTOM_VEHICLE; } - public abstract boolean parseServerMessage(@NonNull StringBuilder sb, - @NonNull String content) throws JSONException; + public boolean checkServerResponse(@NonNull StringBuilder errorMessage, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + String messageKey = getErrorMessageKey(); + if (obj.has(messageKey)) { + String message = obj.getString(messageKey); + errorMessage.append(message); + } + return obj.has(getRootArrayKey()); + } + + @NonNull + protected abstract String getErrorMessageKey(); @NonNull @Override @@ -202,11 +236,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { return OnlineRoutingFactory.createEngine(getType(), getParams()); } - @NonNull - public static String generateKey() { - return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -216,4 +245,27 @@ public abstract class OnlineRoutingEngine implements Cloneable { if (getType() != engine.getType()) return false; return Algorithms.objectEquals(getParams(), engine.getParams()); } + + @NonNull + public static String generateKey() { + return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); + } + + public static class OnlineRoutingResponse { + private List route; + private List directions; + + public OnlineRoutingResponse(List route, List directions) { + this.route = route; + this.directions = directions; + } + + public List getRoute() { + return route; + } + + public List getDirections() { + return directions; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 5f8c2a5108..ed9168ccf9 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -8,7 +8,6 @@ import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import org.json.JSONArray; @@ -81,12 +80,10 @@ public class OrsEngine extends OnlineRoutingEngine { @Nullable @Override - public OnlineRoutingResponse parseServerResponse(@NonNull String content, + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { - JSONObject obj = new JSONObject(content); - JSONArray array = obj.getJSONArray("features").getJSONObject(0) - .getJSONObject("geometry").getJSONArray("coordinates"); + JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); List points = new ArrayList<>(); for (int i = 0; i < array.length(); i++) { JSONArray point = array.getJSONArray(i); @@ -101,14 +98,15 @@ public class OrsEngine extends OnlineRoutingEngine { return null; } + @NonNull @Override - public boolean parseServerMessage(@NonNull StringBuilder sb, - @NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - if (obj.has("error")) { - String message = obj.getString("error"); - sb.append(message); - } - return obj.has("features"); + protected String getErrorMessageKey() { + return "error"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "features"; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 2e892d2aa6..4d75b2b440 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -8,7 +8,6 @@ import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; @@ -77,19 +76,17 @@ public class OsrmEngine extends OnlineRoutingEngine { @Nullable @Override - public OnlineRoutingResponse parseServerResponse(@NonNull String content, + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, @NonNull OsmandApplication app, boolean leftSideNavigation) throws JSONException { - JSONObject obj = new JSONObject(content); - JSONObject routeInfo = obj.getJSONArray("routes").getJSONObject(0); - String encodedPoints = routeInfo.getString("geometry"); + String encodedPoints = root.getString("geometry"); List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); if (isEmpty(points)) return null; List route = convertRouteToLocationsList(points); List directions = new ArrayList<>(); int startSearchingId = 0; - JSONArray legs = routeInfo.getJSONArray("legs"); + JSONArray legs = root.getJSONArray("legs"); for (int i = 0; i < legs.length(); i++) { JSONObject leg = legs.getJSONObject(i); if (!leg.has("steps")) continue; @@ -226,14 +223,15 @@ public class OsrmEngine extends OnlineRoutingEngine { return id != null ? TurnType.valueOf(id, leftSide) : null; } + @NonNull @Override - public boolean parseServerMessage(@NonNull StringBuilder sb, - @NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - if (obj.has("message")) { - String message = obj.getString("message"); - sb.append(message); - } - return obj.has("routes"); + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "routes"; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 84856139b2..008bb75852 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -458,15 +458,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { new Thread(new Runnable() { @Override public void run() { - StringBuilder message = new StringBuilder(); + StringBuilder errorMessage = new StringBuilder(); boolean resultOk = false; try { String response = helper.makeRequest(exampleCard.getEditedText()); - resultOk = requestedEngine.parseServerMessage(message, response); + resultOk = requestedEngine.checkServerResponse(errorMessage, response); } catch (IOException | JSONException e) { - message.append(e.toString()); + errorMessage.append(e.toString()); } - showTestResults(resultOk, message.toString(), location); + showTestResults(resultOk, errorMessage.toString(), location); } }).start(); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 0d2564eb3e..b3b2a11ab6 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -21,7 +21,7 @@ import net.osmand.data.LocationPoint; import net.osmand.data.WptLocationPoint; import net.osmand.plus.OsmandApplication; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; -import net.osmand.plus.onlinerouting.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; From 353c2d167619b6f968493d2d82047b62e571d79a Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Feb 2021 17:43:20 +0200 Subject: [PATCH 62/81] Data storage refactoring, step 1 --- OsmAnd/res/xml/global_settings.xml | 2 +- .../osmand/plus/activities/MapActivity.java | 2 +- .../ChangeDataStorageBottomSheet.java | 16 +- .../DataStorageFragment.java | 253 ++------- .../datastorage/DataStorageHelper.java | 318 ++++++++++++ .../datastorage/item/DirectoryItem.java | 40 ++ .../item/MemoryItem.java} | 60 +-- .../item/StorageItem.java} | 30 +- .../datastorage/task/MoveFilesTask.java | 173 +++++++ .../task/RefreshUsedMemoryTask.java | 184 +++++++ .../datastorage/task/ReloadDataTask.java | 50 ++ .../fragments/BaseSettingsFragment.java | 1 + .../settings/fragments/DataStorageHelper.java | 485 ------------------ .../fragments/GlobalSettingsFragment.java | 4 +- 14 files changed, 841 insertions(+), 777 deletions(-) rename OsmAnd/src/net/osmand/plus/settings/{fragments => datastorage}/DataStorageFragment.java (70%) create mode 100644 OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java rename OsmAnd/src/net/osmand/plus/settings/{fragments/DataStorageMemoryItem.java => datastorage/item/MemoryItem.java} (52%) rename OsmAnd/src/net/osmand/plus/settings/{fragments/DataStorageMenuItem.java => datastorage/item/StorageItem.java} (78%) create mode 100644 OsmAnd/src/net/osmand/plus/settings/datastorage/task/MoveFilesTask.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/datastorage/task/ReloadDataTask.java delete mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageHelper.java diff --git a/OsmAnd/res/xml/global_settings.xml b/OsmAnd/res/xml/global_settings.xml index 7ba1dce420..1cb0e2e93d 100644 --- a/OsmAnd/res/xml/global_settings.xml +++ b/OsmAnd/res/xml/global_settings.xml @@ -22,7 +22,7 @@ android:layout="@layout/preference_with_descr" android:persistent="false" android:title="@string/application_dir" - app:fragment="net.osmand.plus.settings.fragments.DataStorageFragment" + app:fragment="net.osmand.plus.settings.datastorage.DataStorageFragment" tools:icon="@drawable/ic_action_folder" /> menuItems; - private ArrayList memoryItems; + private ArrayList storageItems; + private ArrayList memoryItems; private ArrayList dataStorageRadioButtonsGroup; private Preference changeButton; - private DataStorageMenuItem currentDataStorage; + private StorageItem currentDataStorage; private String tmpManuallySpecifiedPath; private DataStorageHelper dataStorageHelper; private boolean calculateTilesBtnPressed; - private DataStorageHelper.RefreshMemoryUsedInfo calculateMemoryTask; - private DataStorageHelper.RefreshMemoryUsedInfo calculateTilesMemoryTask; + private RefreshUsedMemoryTask calculateMemoryTask; + private RefreshUsedMemoryTask calculateTilesMemoryTask; private OsmandApplication app; private OsmandActionBarActivity activity; @@ -95,11 +94,11 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto return; } - menuItems = dataStorageHelper.getStorageItems(); + storageItems = dataStorageHelper.getStorageItems(); memoryItems = dataStorageHelper.getMemoryInfoItems(); dataStorageRadioButtonsGroup = new ArrayList<>(); - for (DataStorageMenuItem item : menuItems) { + for (StorageItem item : storageItems) { CheckBoxPreference preference = new CheckBoxPreference(activity); preference.setKey(item.getKey()); preference.setTitle(item.getTitle()); @@ -136,7 +135,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto Bundle resultData = (Bundle) newValue; if (resultData.containsKey(ChangeDataStorageBottomSheet.TAG)) { boolean moveMaps = resultData.getBoolean(MOVE_DATA); - DataStorageMenuItem newDataStorage = resultData.getParcelable(CHOSEN_DIRECTORY); + StorageItem newDataStorage = resultData.getParcelable(CHOSEN_DIRECTORY); if (newDataStorage != null) { if (tmpManuallySpecifiedPath != null) { String directory = tmpManuallySpecifiedPath; @@ -154,9 +153,9 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto if (pathChanged) { tmpManuallySpecifiedPath = resultData.getString(NEW_PATH); if (tmpManuallySpecifiedPath != null) { - DataStorageMenuItem manuallySpecified = null; + StorageItem manuallySpecified = null; try { - manuallySpecified = (DataStorageMenuItem) dataStorageHelper.getManuallySpecified().clone(); + manuallySpecified = (StorageItem) dataStorageHelper.getManuallySpecified().clone(); manuallySpecified.setDirectory(tmpManuallySpecifiedPath); } catch (CloneNotSupportedException e) { return false; @@ -170,7 +169,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto //show necessary dialog String key = preference.getKey(); if (key != null) { - DataStorageMenuItem newDataStorage = dataStorageHelper.getStorage(key); + StorageItem newDataStorage = dataStorageHelper.getStorage(key); if (newDataStorage != null) { if (!currentDataStorage.getKey().equals(newDataStorage.getKey())) { if (newDataStorage.getType() == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT @@ -212,7 +211,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto final View itemView = holder.itemView; if (preference instanceof CheckBoxPreference) { - DataStorageMenuItem item = dataStorageHelper.getStorage(key); + StorageItem item = dataStorageHelper.getStorage(key); if (item != null) { TextView tvTitle = itemView.findViewById(android.R.id.title); TextView tvSummary = itemView.findViewById(R.id.summary); @@ -267,7 +266,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto TextView tvSummary = itemView.findViewById(R.id.summary); tvSummary.setText(DataStorageHelper.getFormattedMemoryInfo(totalUsageBytes, memoryUnitsFormats)); } else { - for (DataStorageMemoryItem mi : memoryItems) { + for (MemoryItem mi : memoryItems) { if (key.equals(mi.getKey())) { TextView tvMemory = itemView.findViewById(R.id.memory); String summary = ""; @@ -326,7 +325,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } private void showFolderSelectionDialog() { - DataStorageMenuItem manuallySpecified = dataStorageHelper.getManuallySpecified(); + StorageItem manuallySpecified = dataStorageHelper.getManuallySpecified(); if (manuallySpecified != null) { SelectFolderBottomSheet.showInstance(getFragmentManager(), manuallySpecified.getKey(), manuallySpecified.getDirectory(), DataStorageFragment.this, @@ -335,11 +334,11 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } } - private void moveData(final DataStorageMenuItem currentStorage, final DataStorageMenuItem newStorage) { + private void moveData(final StorageItem currentStorage, final StorageItem newStorage) { File fromDirectory = new File(currentStorage.getDirectory()); File toDirectory = new File(newStorage.getDirectory()); @SuppressLint("StaticFieldLeak") - MoveFilesToDifferentDirectory task = new MoveFilesToDifferentDirectory(activity, fromDirectory, toDirectory) { + MoveFilesTask task = new MoveFilesTask(activity, fromDirectory, toDirectory) { @NonNull @@ -405,7 +404,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - private void confirm(OsmandApplication app, OsmandActionBarActivity activity, DataStorageMenuItem newStorageDirectory, boolean silentRestart) { + private void confirm(OsmandApplication app, OsmandActionBarActivity activity, StorageItem newStorageDirectory, boolean silentRestart) { String newDirectory = newStorageDirectory.getDirectory(); int type = newStorageDirectory.getType(); File newDirectoryFile = new File(newDirectory); @@ -454,7 +453,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } protected void reloadData() { - new ReloadData(activity, app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + new ReloadDataTask(activity, app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); } @Override @@ -469,198 +468,4 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto app.getSettings().OSMAND_USAGE_SPACE.set(dataStorageHelper.getTotalUsedBytes()); } } - - public static class MoveFilesToDifferentDirectory extends AsyncTask { - - protected WeakReference activity; - private WeakReference context; - private File from; - private File to; - protected ProgressImplementation progress; - private Runnable runOnSuccess; - private int movedCount; - private long movedSize; - private int copiedCount; - private long copiedSize; - private int failedCount; - private long failedSize; - private String exceptionMessage; - - public MoveFilesToDifferentDirectory(OsmandActionBarActivity activity, File from, File to) { - this.activity = new WeakReference<>(activity); - this.context = new WeakReference<>((Context) activity); - this.from = from; - this.to = to; - } - - public void setRunOnSuccess(Runnable runOnSuccess) { - this.runOnSuccess = runOnSuccess; - } - - public int getMovedCount() { - return movedCount; - } - - public int getCopiedCount() { - return copiedCount; - } - - public int getFailedCount() { - return failedCount; - } - - public long getMovedSize() { - return movedSize; - } - - public long getCopiedSize() { - return copiedSize; - } - - public long getFailedSize() { - return failedSize; - } - - @Override - protected void onPreExecute() { - Context ctx = context.get(); - if (context == null) { - return; - } - movedCount = 0; - copiedCount = 0; - failedCount = 0; - progress = ProgressImplementation.createProgressDialog( - ctx, ctx.getString(R.string.copying_osmand_files), - ctx.getString(R.string.copying_osmand_files_descr, to.getPath()), - ProgressDialog.STYLE_HORIZONTAL); - } - - @Override - protected void onPostExecute(Boolean result) { - Context ctx = context.get(); - if (ctx == null) { - return; - } - if (result != null) { - if (result.booleanValue() && runOnSuccess != null) { - runOnSuccess.run(); - } else if (!result.booleanValue()) { - Toast.makeText(ctx, ctx.getString(R.string.shared_string_io_error) + ": " + exceptionMessage, Toast.LENGTH_LONG).show(); - } - } - try { - if (progress.getDialog().isShowing()) { - progress.getDialog().dismiss(); - } - } catch (Exception e) { - //ignored - } - } - - private void movingFiles(File f, File t, int depth) throws IOException { - Context ctx = context.get(); - if (ctx == null) { - return; - } - if (depth <= 2) { - progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), -1); - } - if (f.isDirectory()) { - t.mkdirs(); - File[] lf = f.listFiles(); - if (lf != null) { - for (int i = 0; i < lf.length; i++) { - if (lf[i] != null) { - movingFiles(lf[i], new File(t, lf[i].getName()), depth + 1); - } - } - } - f.delete(); - } else if (f.isFile()) { - if (t.exists()) { - Algorithms.removeAllFiles(t); - } - boolean rnm = false; - long fileSize = f.length(); - try { - rnm = f.renameTo(t); - movedCount++; - movedSize += fileSize; - } catch (RuntimeException e) { - } - if (!rnm) { - FileInputStream fin = new FileInputStream(f); - FileOutputStream fout = new FileOutputStream(t); - try { - progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), (int) (f.length() / 1024)); - Algorithms.streamCopy(fin, fout, progress, 1024); - copiedCount++; - copiedSize += fileSize; - } catch (IOException e) { - failedCount++; - failedSize += fileSize; - } finally { - fin.close(); - fout.close(); - } - f.delete(); - } - } - if (depth <= 2) { - progress.finishTask(); - } - } - - @Override - protected Boolean doInBackground(Void... params) { - to.mkdirs(); - try { - movingFiles(from, to, 0); - } catch (IOException e) { - exceptionMessage = e.getMessage(); - return false; - } - return true; - } - - } - - public static class ReloadData extends AsyncTask { - private WeakReference ctx; - protected ProgressImplementation progress; - private OsmandApplication app; - - public ReloadData(Context ctx, OsmandApplication app) { - this.ctx = new WeakReference<>(ctx); - this.app = app; - } - - @Override - protected void onPreExecute() { - Context c = ctx.get(); - if (c == null) { - return; - } - progress = ProgressImplementation.createProgressDialog(c, c.getString(R.string.loading_data), - c.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL); - } - - @Override - protected void onPostExecute(Boolean result) { - try { - if (progress.getDialog().isShowing()) { - progress.getDialog().dismiss(); - } - } catch (Exception e) { - //ignored - } - } - - @Override - protected Boolean doInBackground(Void... params) { - app.getResourceManager().reloadIndexes(progress, new ArrayList()); - return true; - } - } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java new file mode 100644 index 0000000000..96a939eae3 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java @@ -0,0 +1,318 @@ +package net.osmand.plus.settings.datastorage; + +import android.os.Build; + +import androidx.annotation.NonNull; + +import net.osmand.IndexConstants; +import net.osmand.ValueHolder; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.settings.datastorage.item.DirectoryItem; +import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType; +import net.osmand.plus.settings.datastorage.item.MemoryItem; +import net.osmand.plus.settings.datastorage.item.StorageItem; +import net.osmand.plus.settings.datastorage.task.RefreshUsedMemoryTask; + +import java.io.File; +import java.text.DecimalFormat; +import java.util.ArrayList; + +import static net.osmand.IndexConstants.AV_INDEX_DIR; +import static net.osmand.IndexConstants.BACKUP_INDEX_DIR; +import static net.osmand.IndexConstants.GPX_INDEX_DIR; +import static net.osmand.IndexConstants.MAPS_PATH; +import static net.osmand.IndexConstants.ROADS_INDEX_DIR; +import static net.osmand.IndexConstants.SRTM_INDEX_DIR; +import static net.osmand.IndexConstants.TILES_INDEX_DIR; +import static net.osmand.IndexConstants.WIKIVOYAGE_INDEX_DIR; +import static net.osmand.IndexConstants.WIKI_INDEX_DIR; +import static net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType.EXTENSIONS; +import static net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType.PREFIX; + +public class DataStorageHelper { + public final static String INTERNAL_STORAGE = "internal_storage"; + public final static String EXTERNAL_STORAGE = "external_storage"; + public final static String SHARED_STORAGE = "shared_storage"; + public final static String MULTIUSER_STORAGE = "multiuser_storage"; + public final static String MANUALLY_SPECIFIED = "manually_specified"; + + public final static String MAPS_MEMORY = "maps_memory_used"; + public final static String SRTM_AND_HILLSHADE_MEMORY = "contour_lines_and_hillshade_memory"; + public final static String TRACKS_MEMORY = "tracks_memory_used"; + public final static String NOTES_MEMORY = "notes_memory_used"; + public final static String TILES_MEMORY = "tiles_memory_used"; + public final static String OTHER_MEMORY = "other_memory_used"; + + private OsmandApplication app; + private ArrayList storageItems = new ArrayList<>(); + private StorageItem currentDataStorage; + private StorageItem manuallySpecified; + + private ArrayList memoryItems = new ArrayList<>(); + private MemoryItem mapsMemory; + private MemoryItem srtmAndHillshadeMemory; + private MemoryItem tracksMemory; + private MemoryItem notesMemory; + private MemoryItem tilesMemory; + private MemoryItem otherMemory; + + private int currentStorageType; + private String currentStoragePath; + + public DataStorageHelper(@NonNull OsmandApplication app) { + this.app = app; + prepareData(); + } + + private void prepareData() { + OsmandSettings settings = app.getSettings(); + if (settings.getExternalStorageDirectoryTypeV19() >= 0) { + currentStorageType = settings.getExternalStorageDirectoryTypeV19(); + } else { + ValueHolder vh = new ValueHolder(); + if (vh.value != null && vh.value >= 0) { + currentStorageType = vh.value; + } else { + currentStorageType = 0; + } + } + currentStoragePath = settings.getExternalStorageDirectory().getAbsolutePath(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + + //internal storage + String path = settings.getInternalAppPath().getAbsolutePath(); + File dir = new File(path); + int iconId = R.drawable.ic_action_phone; + + StorageItem internalStorageItem = StorageItem.builder() + .setKey(INTERNAL_STORAGE) + .setTitle(app.getString(R.string.storage_directory_internal_app)) + .setDirectory(path) + .setDescription(app.getString(R.string.internal_app_storage_description)) + .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE) + .setIconResId(iconId) + .createItem(); + addItem(internalStorageItem); + + //shared storage + dir = settings.getDefaultInternalStorage(); + path = dir.getAbsolutePath(); + iconId = R.drawable.ic_action_phone; + + StorageItem sharedStorageItem = StorageItem.builder() + .setKey(SHARED_STORAGE) + .setTitle(app.getString(R.string.storage_directory_shared)) + .setDirectory(path) + .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT) + .setIconResId(iconId) + .createItem(); + addItem(sharedStorageItem); + + //external storage + File[] externals = app.getExternalFilesDirs(null); + if (externals != null) { + int i = 0; + for (File external : externals) { + if (external != null) { + ++i; + dir = external; + path = dir.getAbsolutePath(); + iconId = getIconForStorageType(dir); + StorageItem externalStorageItem = StorageItem.builder() + .setKey(EXTERNAL_STORAGE + i) + .setTitle(app.getString(R.string.storage_directory_external) + " " + i) + .setDirectory(path) + .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE) + .setIconResId(iconId) + .createItem(); + addItem(externalStorageItem); + } + } + } + + //multi user storage + File[] obbDirs = app.getObbDirs(); + if (obbDirs != null) { + int i = 0; + for (File obb : obbDirs) { + if (obb != null) { + ++i; + dir = obb; + path = dir.getAbsolutePath(); + iconId = getIconForStorageType(dir); + StorageItem multiuserStorageItem = StorageItem.builder() + .setKey(MULTIUSER_STORAGE + i) + .setTitle(app.getString(R.string.storage_directory_multiuser) + " " + i) + .setDirectory(path) + .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB) + .setIconResId(iconId) + .createItem(); + addItem(multiuserStorageItem); + } + } + } + } + + //manually specified storage + manuallySpecified = StorageItem.builder() + .setKey(MANUALLY_SPECIFIED) + .setTitle(app.getString(R.string.storage_directory_manual)) + .setDirectory(currentStoragePath) + .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) + .setIconResId(R.drawable.ic_action_folder) + .createItem(); + storageItems.add(manuallySpecified); + + if (currentDataStorage == null) { + currentDataStorage = manuallySpecified; + } + + initMemoryUsed(); + } + + private void initMemoryUsed() { + mapsMemory = MemoryItem.builder() + .setKey(MAPS_MEMORY) + .setExtensions(IndexConstants.BINARY_MAP_INDEX_EXT) + .setDirectories( + createDirectory((MAPS_PATH), false, EXTENSIONS, false), + createDirectory((ROADS_INDEX_DIR), true, EXTENSIONS, false), + createDirectory((WIKI_INDEX_DIR), true, EXTENSIONS, false), + createDirectory((WIKIVOYAGE_INDEX_DIR), true, EXTENSIONS, false), + createDirectory((BACKUP_INDEX_DIR), true, EXTENSIONS, false)) + .createItem(); + memoryItems.add(mapsMemory); + + srtmAndHillshadeMemory = MemoryItem.builder() + .setKey(SRTM_AND_HILLSHADE_MEMORY) + .setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT) + .setDirectories( + createDirectory((SRTM_INDEX_DIR), true, EXTENSIONS, false), + createDirectory((TILES_INDEX_DIR), false, PREFIX, true)) + .setPrefixes("Hillshade") + .createItem(); + memoryItems.add(srtmAndHillshadeMemory); + + tracksMemory = MemoryItem.builder() + .setKey(TRACKS_MEMORY) +// .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2") + .setDirectories( + createDirectory((GPX_INDEX_DIR), true, EXTENSIONS, false)) + .createItem(); + memoryItems.add(tracksMemory); + + notesMemory = MemoryItem.builder() + .setKey(NOTES_MEMORY) +// .setExtensions("") + .setDirectories( + createDirectory((AV_INDEX_DIR), true, EXTENSIONS, false)) + .createItem(); + memoryItems.add(notesMemory); + + tilesMemory = MemoryItem.builder() + .setKey(TILES_MEMORY) +// .setExtensions("") + .setDirectories( + createDirectory((TILES_INDEX_DIR), true, EXTENSIONS, false)) + .createItem(); + memoryItems.add(tilesMemory); + + otherMemory = MemoryItem.builder() + .setKey(OTHER_MEMORY) + .createItem(); + memoryItems.add(otherMemory); + } + + public ArrayList getStorageItems() { + return storageItems; + } + + private int getIconForStorageType(File dir) { + return R.drawable.ic_action_folder; + } + + public StorageItem getCurrentStorage() { + return currentDataStorage; + } + + private void addItem(StorageItem item) { + if (currentStorageType == item.getType() && currentStoragePath.equals(item.getDirectory())) { + currentDataStorage = item; + } + storageItems.add(item); + } + + public StorageItem getManuallySpecified() { + return manuallySpecified; + } + + public StorageItem getStorage(String key) { + if (storageItems != null && key != null) { + for (StorageItem storageItem : storageItems) { + if (key.equals(storageItem.getKey())) { + return storageItem; + } + } + } + return null; + } + + public ArrayList getMemoryInfoItems() { + return memoryItems; + } + + public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) { + File rootDir = new File(currentStoragePath); + RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, null, OTHER_MEMORY); + task.execute(mapsMemory, srtmAndHillshadeMemory, tracksMemory, notesMemory); + return task; + } + + public RefreshUsedMemoryTask calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) { + File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath()); + RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, srtmAndHillshadeMemory.getPrefixes(), TILES_MEMORY); + task.execute(tilesMemory); + return task; + } + + public long getTotalUsedBytes() { + long total = 0; + if (memoryItems != null && memoryItems.size() > 0) { + for (MemoryItem mi : memoryItems) { + total += mi.getUsedMemoryBytes(); + } + return total; + } + return -1; + } + + public DirectoryItem createDirectory(@NonNull String relativePath, + boolean goDeeper, + CheckingType checkingType, + boolean skipOther) { + String path = app.getAppPath(relativePath).getAbsolutePath(); + return new DirectoryItem(path, goDeeper, checkingType, skipOther); + } + + public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) { + int type = 0; + double memory = (double) bytes / 1024; + while (memory > 1024 && type < formatStrings.length) { + ++type; + memory = memory / 1024; + } + String formattedUsed = new DecimalFormat("#.##").format(memory); + return String.format(formatStrings[type], formattedUsed); + } + + public interface UpdateMemoryInfoUIAdapter { + + void onMemoryInfoUpdate(); + + void onFinishUpdating(String taskKey); + + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java new file mode 100644 index 0000000000..e1d7e1cad4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java @@ -0,0 +1,40 @@ +package net.osmand.plus.settings.datastorage.item; + +public class DirectoryItem { + + private final String absolutePath; + private final boolean goDeeper; + private final CheckingType checkingType; + private final boolean skipOther; + + public enum CheckingType { + EXTENSIONS, + PREFIX + } + + public DirectoryItem(String absolutePath, + boolean goDeeper, + CheckingType checkingType, + boolean skipOther) { + this.absolutePath = absolutePath; + this.goDeeper = goDeeper; + this.checkingType = checkingType; + this.skipOther = skipOther; + } + + public String getAbsolutePath() { + return absolutePath; + } + + public boolean isGoDeeper() { + return goDeeper; + } + + public CheckingType getCheckingType() { + return checkingType; + } + + public boolean isSkipOther() { + return skipOther; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMemoryItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/MemoryItem.java similarity index 52% rename from OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMemoryItem.java rename to OsmAnd/src/net/osmand/plus/settings/datastorage/item/MemoryItem.java index f7f955f89a..8fb65f99c3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMemoryItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/MemoryItem.java @@ -1,16 +1,18 @@ -package net.osmand.plus.settings.fragments; +package net.osmand.plus.settings.datastorage.item; + +public class MemoryItem { -public class DataStorageMemoryItem { - public final static int EXTENSIONS = 0; - public final static int PREFIX = 1; - private String key; - private String[] extensions; - private String[] prefixes; - private Directory[] directories; + private final String[] extensions; + private final String[] prefixes; + private final DirectoryItem[] directories; private long usedMemoryBytes; - private DataStorageMemoryItem(String key, String[] extensions, String[] prefixes, long usedMemoryBytes, Directory[] directories) { + private MemoryItem(String key, + String[] extensions, + String[] prefixes, + long usedMemoryBytes, + DirectoryItem[] directories) { this.key = key; this.extensions = extensions; this.prefixes = prefixes; @@ -42,7 +44,7 @@ public class DataStorageMemoryItem { return prefixes; } - public Directory[] getDirectories() { + public DirectoryItem[] getDirectories() { return directories; } @@ -54,7 +56,7 @@ public class DataStorageMemoryItem { private String key; private String[] extensions; private String[] prefixes; - private Directory[] directories; + private DirectoryItem[] directories; private long usedMemoryBytes; public DataStorageMemoryItemBuilder setKey(String key) { @@ -72,7 +74,7 @@ public class DataStorageMemoryItem { return this; } - public DataStorageMemoryItemBuilder setDirectories(Directory ... directories) { + public DataStorageMemoryItemBuilder setDirectories(DirectoryItem... directories) { this.directories = directories; return this; } @@ -82,38 +84,8 @@ public class DataStorageMemoryItem { return this; } - public DataStorageMemoryItem createItem() { - return new DataStorageMemoryItem(key, extensions, prefixes, usedMemoryBytes, directories); - } - } - - public static class Directory { - private String absolutePath; - private boolean goDeeper; - private int checkingType; - private boolean skipOther; - - public Directory(String absolutePath, boolean goDeeper, int checkingType, boolean skipOther) { - this.absolutePath = absolutePath; - this.goDeeper = goDeeper; - this.checkingType = checkingType; - this.skipOther = skipOther; - } - - public String getAbsolutePath() { - return absolutePath; - } - - public boolean isGoDeeper() { - return goDeeper; - } - - public int getCheckingType() { - return checkingType; - } - - public boolean isSkipOther() { - return skipOther; + public MemoryItem createItem() { + return new MemoryItem(key, extensions, prefixes, usedMemoryBytes, directories); } } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMenuItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/StorageItem.java similarity index 78% rename from OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMenuItem.java rename to OsmAnd/src/net/osmand/plus/settings/datastorage/item/StorageItem.java index f965b95fb1..717bcbd5e7 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageMenuItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/StorageItem.java @@ -1,11 +1,11 @@ -package net.osmand.plus.settings.fragments; +package net.osmand.plus.settings.datastorage.item; import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.IdRes; -public class DataStorageMenuItem implements Parcelable, Cloneable { +public class StorageItem implements Parcelable, Cloneable { private String key; private int type; @@ -15,8 +15,12 @@ public class DataStorageMenuItem implements Parcelable, Cloneable { @IdRes private int iconResId; - private DataStorageMenuItem(String key, int type, String title, String description, - String directory, int iconResId) { + private StorageItem(String key, + int type, + String title, + String description, + String directory, + int iconResId) { this.key = key; this.type = type; this.title = title; @@ -25,7 +29,7 @@ public class DataStorageMenuItem implements Parcelable, Cloneable { this.iconResId = iconResId; } - private DataStorageMenuItem(Parcel in) { + private StorageItem(Parcel in) { key = in.readString(); type = in.readInt(); title = in.readString(); @@ -99,16 +103,16 @@ public class DataStorageMenuItem implements Parcelable, Cloneable { dest.writeString(directory); } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override - public DataStorageMenuItem createFromParcel(Parcel source) { - return new DataStorageMenuItem(source); + public StorageItem createFromParcel(Parcel source) { + return new StorageItem(source); } @Override - public DataStorageMenuItem[] newArray(int size) { - return new DataStorageMenuItem[size]; + public StorageItem[] newArray(int size) { + return new StorageItem[size]; } }; @@ -151,14 +155,14 @@ public class DataStorageMenuItem implements Parcelable, Cloneable { return this; } - public DataStorageMenuItem createItem() { - return new DataStorageMenuItem(key, type, title, description, directory, iconResId); + public StorageItem createItem() { + return new StorageItem(key, type, title, description, directory, iconResId); } } @Override public Object clone() throws CloneNotSupportedException { - return DataStorageMenuItem.builder() + return StorageItem.builder() .setKey(this.key) .setTitle(this.title) .setDescription(this.description) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/MoveFilesTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/MoveFilesTask.java new file mode 100644 index 0000000000..b6fc45d93c --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/MoveFilesTask.java @@ -0,0 +1,173 @@ +package net.osmand.plus.settings.datastorage.task; + +import android.app.ProgressDialog; +import android.content.Context; +import android.os.AsyncTask; +import android.widget.Toast; + +import net.osmand.plus.ProgressImplementation; +import net.osmand.plus.R; +import net.osmand.plus.activities.OsmandActionBarActivity; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.ref.WeakReference; + +public class MoveFilesTask extends AsyncTask { + + protected WeakReference activity; + private WeakReference context; + private File from; + private File to; + protected ProgressImplementation progress; + private Runnable runOnSuccess; + private int movedCount; + private long movedSize; + private int copiedCount; + private long copiedSize; + private int failedCount; + private long failedSize; + private String exceptionMessage; + + public MoveFilesTask(OsmandActionBarActivity activity, File from, File to) { + this.activity = new WeakReference<>(activity); + this.context = new WeakReference<>((Context) activity); + this.from = from; + this.to = to; + } + + public void setRunOnSuccess(Runnable runOnSuccess) { + this.runOnSuccess = runOnSuccess; + } + + public int getMovedCount() { + return movedCount; + } + + public int getCopiedCount() { + return copiedCount; + } + + public int getFailedCount() { + return failedCount; + } + + public long getMovedSize() { + return movedSize; + } + + public long getCopiedSize() { + return copiedSize; + } + + public long getFailedSize() { + return failedSize; + } + + @Override + protected void onPreExecute() { + Context ctx = context.get(); + if (context == null) { + return; + } + movedCount = 0; + copiedCount = 0; + failedCount = 0; + progress = ProgressImplementation.createProgressDialog( + ctx, ctx.getString(R.string.copying_osmand_files), + ctx.getString(R.string.copying_osmand_files_descr, to.getPath()), + ProgressDialog.STYLE_HORIZONTAL); + } + + @Override + protected void onPostExecute(Boolean result) { + Context ctx = context.get(); + if (ctx == null) { + return; + } + if (result != null) { + if (result.booleanValue() && runOnSuccess != null) { + runOnSuccess.run(); + } else if (!result.booleanValue()) { + Toast.makeText(ctx, ctx.getString(R.string.shared_string_io_error) + ": " + exceptionMessage, Toast.LENGTH_LONG).show(); + } + } + try { + if (progress.getDialog().isShowing()) { + progress.getDialog().dismiss(); + } + } catch (Exception e) { + //ignored + } + } + + private void movingFiles(File f, File t, int depth) throws IOException { + Context ctx = context.get(); + if (ctx == null) { + return; + } + if (depth <= 2) { + progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), -1); + } + if (f.isDirectory()) { + t.mkdirs(); + File[] lf = f.listFiles(); + if (lf != null) { + for (int i = 0; i < lf.length; i++) { + if (lf[i] != null) { + movingFiles(lf[i], new File(t, lf[i].getName()), depth + 1); + } + } + } + f.delete(); + } else if (f.isFile()) { + if (t.exists()) { + Algorithms.removeAllFiles(t); + } + boolean rnm = false; + long fileSize = f.length(); + try { + rnm = f.renameTo(t); + movedCount++; + movedSize += fileSize; + } catch (RuntimeException e) { + } + if (!rnm) { + FileInputStream fin = new FileInputStream(f); + FileOutputStream fout = new FileOutputStream(t); + try { + progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), (int) (f.length() / 1024)); + Algorithms.streamCopy(fin, fout, progress, 1024); + copiedCount++; + copiedSize += fileSize; + } catch (IOException e) { + failedCount++; + failedSize += fileSize; + } finally { + fin.close(); + fout.close(); + } + f.delete(); + } + } + if (depth <= 2) { + progress.finishTask(); + } + } + + @Override + protected Boolean doInBackground(Void... params) { + to.mkdirs(); + try { + movingFiles(from, to, 0); + } catch (IOException e) { + exceptionMessage = e.getMessage(); + return false; + } + return true; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java new file mode 100644 index 0000000000..ad1dbb4bf5 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java @@ -0,0 +1,184 @@ +package net.osmand.plus.settings.datastorage.task; + +import android.os.AsyncTask; + +import net.osmand.plus.settings.datastorage.DataStorageHelper.UpdateMemoryInfoUIAdapter; +import net.osmand.plus.settings.datastorage.item.DirectoryItem; +import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType; +import net.osmand.plus.settings.datastorage.item.MemoryItem; + +import java.io.File; + +import static net.osmand.plus.settings.datastorage.DataStorageFragment.UI_REFRESH_TIME_MS; + +public class RefreshUsedMemoryTask extends AsyncTask { + private UpdateMemoryInfoUIAdapter listener; + private File rootDir; + private MemoryItem otherMemory; + private String[] directoriesToAvoid; + private String[] prefixesToAvoid; + private String taskKey; + private long lastRefreshTime; + + public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter listener, MemoryItem otherMemory, File rootDir, String[] directoriesToAvoid, String[] prefixesToAvoid, String taskKey) { + this.listener = listener; + this.otherMemory = otherMemory; + this.rootDir = rootDir; + this.directoriesToAvoid = directoriesToAvoid; + this.prefixesToAvoid = prefixesToAvoid; + this.taskKey = taskKey; + } + + @Override + protected Void doInBackground(MemoryItem... items) { + lastRefreshTime = System.currentTimeMillis(); + if (rootDir.canRead()) { + calculateMultiTypes(rootDir, items); + } + return null; + } + + private void calculateMultiTypes(File rootDir, MemoryItem... items) { + File[] subFiles = rootDir.listFiles(); + + for (File file : subFiles) { + if (isCancelled()) { + break; + } + nextFile : { + if (file.isDirectory()) { + //check current directory should be avoid + if (directoriesToAvoid != null) { + for (String directoryToAvoid : directoriesToAvoid) { + if (file.getAbsolutePath().equals(directoryToAvoid)) { + break nextFile; + } + } + } + //check current directory matched items type + for (MemoryItem item : items) { + DirectoryItem[] directories = item.getDirectories(); + if (directories == null) { + continue; + } + for (DirectoryItem dir : directories) { + if (file.getAbsolutePath().equals(dir.getAbsolutePath()) + || (file.getAbsolutePath().startsWith(dir.getAbsolutePath()))) { + if (dir.isGoDeeper()) { + calculateMultiTypes(file, items); + break nextFile; + } else if (dir.isSkipOther()) { + break nextFile; + } + } + } + } + //current directory did not match to any type + otherMemory.addBytes(getDirectorySize(file)); + } else if (file.isFile()) { + //check current file should be avoid + if (prefixesToAvoid != null) { + for (String prefixToAvoid : prefixesToAvoid) { + if (file.getName().toLowerCase().startsWith(prefixToAvoid.toLowerCase())) { + break nextFile; + } + } + } + //check current file matched items type + for (MemoryItem item : items) { + DirectoryItem[] directories = item.getDirectories(); + if (directories == null) { + continue; + } + for (DirectoryItem dir : directories) { + if (rootDir.getAbsolutePath().equals(dir.getAbsolutePath()) + || (rootDir.getAbsolutePath().startsWith(dir.getAbsolutePath()) && dir.isGoDeeper())) { + CheckingType checkingType = dir.getCheckingType(); + switch (checkingType) { + case EXTENSIONS : { + String[] extensions = item.getExtensions(); + if (extensions != null) { + for (String extension : extensions) { + if (file.getAbsolutePath().endsWith(extension)) { + item.addBytes(file.length()); + break nextFile; + } + } + } else { + item.addBytes(file.length()); + break nextFile; + } + break ; + } + case PREFIX : { + String[] prefixes = item.getPrefixes(); + if (prefixes != null) { + for (String prefix : prefixes) { + if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + item.addBytes(file.length()); + break nextFile; + } + } + } else { + item.addBytes(file.length()); + break nextFile; + } + break ; + } + } + if (dir.isSkipOther()) { + break nextFile; + } + } + } + } + //current file did not match any type + otherMemory.addBytes(file.length()); + } + } + refreshUI(); + } + } + + private long getDirectorySize(File dir) { + long bytes = 0; + if (dir.isDirectory()) { + File[] files = dir.listFiles(); + for (File file : files) { + if (isCancelled()) { + break; + } + if (file.isDirectory()) { + bytes += getDirectorySize(file); + } else if (file.isFile()) { + bytes += file.length(); + } + } + } + return bytes; + } + + @Override + protected void onProgressUpdate(Void... values) { + super.onProgressUpdate(values); + if (listener != null) { + listener.onMemoryInfoUpdate(); + } + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (listener != null) { + listener.onFinishUpdating(taskKey); + } + } + + private void refreshUI() { + long currentTime = System.currentTimeMillis(); + if ((currentTime - lastRefreshTime) > UI_REFRESH_TIME_MS) { + lastRefreshTime = currentTime; + publishProgress(); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/ReloadDataTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/ReloadDataTask.java new file mode 100644 index 0000000000..4e097b9df2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/ReloadDataTask.java @@ -0,0 +1,50 @@ +package net.osmand.plus.settings.datastorage.task; + +import android.app.ProgressDialog; +import android.content.Context; +import android.os.AsyncTask; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.ProgressImplementation; +import net.osmand.plus.R; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +public class ReloadDataTask extends AsyncTask { + private WeakReference ctx; + protected ProgressImplementation progress; + private OsmandApplication app; + + public ReloadDataTask(Context ctx, OsmandApplication app) { + this.ctx = new WeakReference<>(ctx); + this.app = app; + } + + @Override + protected void onPreExecute() { + Context c = ctx.get(); + if (c == null) { + return; + } + progress = ProgressImplementation.createProgressDialog(c, c.getString(R.string.loading_data), + c.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL); + } + + @Override + protected void onPostExecute(Boolean result) { + try { + if (progress.getDialog().isShowing()) { + progress.getDialog().dismiss(); + } + } catch (Exception e) { + //ignored + } + } + + @Override + protected Boolean doInBackground(Void... params) { + app.getResourceManager().reloadIndexes(progress, new ArrayList()); + return true; + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java index e2d3244f26..947a331290 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java @@ -73,6 +73,7 @@ import net.osmand.plus.settings.bottomsheets.ChangeGeneralProfilesPrefBottomShee import net.osmand.plus.settings.bottomsheets.EditTextPreferenceBottomSheet; import net.osmand.plus.settings.bottomsheets.MultiSelectPreferencesBottomSheet; import net.osmand.plus.settings.bottomsheets.SingleSelectPreferenceBottomSheet; +import net.osmand.plus.settings.datastorage.DataStorageFragment; import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference; import net.osmand.plus.settings.preferences.SwitchPreferenceEx; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageHelper.java deleted file mode 100644 index b270175d86..0000000000 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DataStorageHelper.java +++ /dev/null @@ -1,485 +0,0 @@ -package net.osmand.plus.settings.fragments; - -import android.os.AsyncTask; -import android.os.Build; - -import net.osmand.IndexConstants; -import net.osmand.ValueHolder; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.R; - -import java.io.File; -import java.text.DecimalFormat; -import java.util.ArrayList; - -import static net.osmand.plus.settings.fragments.DataStorageFragment.UI_REFRESH_TIME_MS; -import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.Directory; -import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.EXTENSIONS; -import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.PREFIX; - -public class DataStorageHelper { - public final static String INTERNAL_STORAGE = "internal_storage"; - public final static String EXTERNAL_STORAGE = "external_storage"; - public final static String SHARED_STORAGE = "shared_storage"; - public final static String MULTIUSER_STORAGE = "multiuser_storage"; - public final static String MANUALLY_SPECIFIED = "manually_specified"; - - public final static String MAPS_MEMORY = "maps_memory_used"; - public final static String SRTM_AND_HILLSHADE_MEMORY = "contour_lines_and_hillshade_memory"; - public final static String TRACKS_MEMORY = "tracks_memory_used"; - public final static String NOTES_MEMORY = "notes_memory_used"; - public final static String TILES_MEMORY = "tiles_memory_used"; - public final static String OTHER_MEMORY = "other_memory_used"; - - private ArrayList menuItems = new ArrayList<>(); - private DataStorageMenuItem currentDataStorage; - private DataStorageMenuItem manuallySpecified; - - private ArrayList memoryItems = new ArrayList<>(); - private DataStorageMemoryItem mapsMemory; - private DataStorageMemoryItem srtmAndHillshadeMemory; - private DataStorageMemoryItem tracksMemory; - private DataStorageMemoryItem notesMemory; - private DataStorageMemoryItem tilesMemory; - private DataStorageMemoryItem otherMemory; - - private int currentStorageType; - private String currentStoragePath; - - public DataStorageHelper(OsmandApplication app) { - prepareData(app); - } - - private void prepareData(OsmandApplication app) { - - if (app == null) { - return; - } - - OsmandSettings settings = app.getSettings(); - - if (settings.getExternalStorageDirectoryTypeV19() >= 0) { - currentStorageType = settings.getExternalStorageDirectoryTypeV19(); - } else { - ValueHolder vh = new ValueHolder(); - if (vh.value != null && vh.value >= 0) { - currentStorageType = vh.value; - } else { - currentStorageType = 0; - } - } - currentStoragePath = settings.getExternalStorageDirectory().getAbsolutePath(); - - String path; - File dir; - int iconId; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - - //internal storage - path = settings.getInternalAppPath().getAbsolutePath(); - dir = new File(path); - iconId = R.drawable.ic_action_phone; - - DataStorageMenuItem internalStorageItem = DataStorageMenuItem.builder() - .setKey(INTERNAL_STORAGE) - .setTitle(app.getString(R.string.storage_directory_internal_app)) - .setDirectory(path) - .setDescription(app.getString(R.string.internal_app_storage_description)) - .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE) - .setIconResId(iconId) - .createItem(); - addItem(internalStorageItem); - - //shared_storage - dir = settings.getDefaultInternalStorage(); - path = dir.getAbsolutePath(); - iconId = R.drawable.ic_action_phone; - - DataStorageMenuItem sharedStorageItem = DataStorageMenuItem.builder() - .setKey(SHARED_STORAGE) - .setTitle(app.getString(R.string.storage_directory_shared)) - .setDirectory(path) - .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT) - .setIconResId(iconId) - .createItem(); - addItem(sharedStorageItem); - - //external storage - File[] externals = app.getExternalFilesDirs(null); - if (externals != null) { - int i = 0; - for (File external : externals) { - if (external != null) { - ++i; - dir = external; - path = dir.getAbsolutePath(); - iconId = getIconForStorageType(dir); - DataStorageMenuItem externalStorageItem = DataStorageMenuItem.builder() - .setKey(EXTERNAL_STORAGE + i) - .setTitle(app.getString(R.string.storage_directory_external) + " " + i) - .setDirectory(path) - .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE) - .setIconResId(iconId) - .createItem(); - addItem(externalStorageItem); - } - } - } - - //multi user storage - File[] obbDirs = app.getObbDirs(); - if (obbDirs != null) { - int i = 0; - for (File obb : obbDirs) { - if (obb != null) { - ++i; - dir = obb; - path = dir.getAbsolutePath(); - iconId = getIconForStorageType(dir); - DataStorageMenuItem multiuserStorageItem = DataStorageMenuItem.builder() - .setKey(MULTIUSER_STORAGE + i) - .setTitle(app.getString(R.string.storage_directory_multiuser) + " " + i) - .setDirectory(path) - .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB) - .setIconResId(iconId) - .createItem(); - addItem(multiuserStorageItem); - } - } - } - } - - //manually specified storage - manuallySpecified = DataStorageMenuItem.builder() - .setKey(MANUALLY_SPECIFIED) - .setTitle(app.getString(R.string.storage_directory_manual)) - .setDirectory(currentStoragePath) - .setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) - .setIconResId(R.drawable.ic_action_folder) - .createItem(); - menuItems.add(manuallySpecified); - - if (currentDataStorage == null) { - currentDataStorage = manuallySpecified; - } - - initMemoryUsed(app); - } - - private void initMemoryUsed(OsmandApplication app) { - mapsMemory = DataStorageMemoryItem.builder() - .setKey(MAPS_MEMORY) - .setExtensions(IndexConstants.BINARY_MAP_INDEX_EXT) - .setDirectories( - new Directory(app.getAppPath(IndexConstants.MAPS_PATH).getAbsolutePath(), false, EXTENSIONS, false), - new Directory(app.getAppPath(IndexConstants.ROADS_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false), - new Directory(app.getAppPath(IndexConstants.WIKI_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false), - new Directory(app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false), - new Directory(app.getAppPath(IndexConstants.BACKUP_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false)) - .createItem(); - memoryItems.add(mapsMemory); - - srtmAndHillshadeMemory = DataStorageMemoryItem.builder() - .setKey(SRTM_AND_HILLSHADE_MEMORY) - .setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT) - .setDirectories( - new Directory(app.getAppPath(IndexConstants.SRTM_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false), - new Directory(app.getAppPath(IndexConstants.TILES_INDEX_DIR).getAbsolutePath(), false, PREFIX, true)) - .setPrefixes("Hillshade") - .createItem(); - memoryItems.add(srtmAndHillshadeMemory); - - tracksMemory = DataStorageMemoryItem.builder() - .setKey(TRACKS_MEMORY) -// .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2") - .setDirectories( - new Directory(app.getAppPath(IndexConstants.GPX_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false)) - .createItem(); - memoryItems.add(tracksMemory); - - notesMemory = DataStorageMemoryItem.builder() - .setKey(NOTES_MEMORY) -// .setExtensions("") - .setDirectories( - new Directory(app.getAppPath(IndexConstants.AV_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false)) - .createItem(); - memoryItems.add(notesMemory); - - tilesMemory = DataStorageMemoryItem.builder() - .setKey(TILES_MEMORY) -// .setExtensions("") - .setDirectories( - new Directory(app.getAppPath(IndexConstants.TILES_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false)) - .createItem(); - memoryItems.add(tilesMemory); - - otherMemory = DataStorageMemoryItem.builder() - .setKey(OTHER_MEMORY) - .createItem(); - memoryItems.add(otherMemory); - } - - public ArrayList getStorageItems() { - return menuItems; - } - - private int getIconForStorageType(File dir) { - return R.drawable.ic_action_folder; - } - - public DataStorageMenuItem getCurrentStorage() { - return currentDataStorage; - } - - private void addItem(DataStorageMenuItem item) { - if (currentStorageType == item.getType() && currentStoragePath.equals(item.getDirectory())) { - currentDataStorage = item; - } - menuItems.add(item); - } - - public DataStorageMenuItem getManuallySpecified() { - return manuallySpecified; - } - - public DataStorageMenuItem getStorage(String key) { - if (menuItems != null && key != null) { - for (DataStorageMenuItem menuItem : menuItems) { - if (key.equals(menuItem.getKey())) { - return menuItem; - } - } - } - return null; - } - - public int getCurrentType() { - return currentStorageType; - } - - public String getCurrentPath() { - return currentStoragePath; - } - - public ArrayList getMemoryInfoItems() { - return memoryItems; - } - - public RefreshMemoryUsedInfo calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) { - File rootDir = new File(currentStoragePath); - RefreshMemoryUsedInfo task = new RefreshMemoryUsedInfo(listener, otherMemory, rootDir, null, null, OTHER_MEMORY); - task.execute(mapsMemory, srtmAndHillshadeMemory, tracksMemory, notesMemory); - return task; - } - - public RefreshMemoryUsedInfo calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) { - File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath()); - RefreshMemoryUsedInfo task = new RefreshMemoryUsedInfo(listener, otherMemory, rootDir, null, srtmAndHillshadeMemory.getPrefixes(), TILES_MEMORY); - task.execute(tilesMemory); - return task; - } - - public static class RefreshMemoryUsedInfo extends AsyncTask { - private UpdateMemoryInfoUIAdapter listener; - private File rootDir; - private DataStorageMemoryItem otherMemory; - private String[] directoriesToAvoid; - private String[] prefixesToAvoid; - private String taskKey; - private long lastRefreshTime; - - public RefreshMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener, DataStorageMemoryItem otherMemory, File rootDir, String[] directoriesToAvoid, String[] prefixesToAvoid, String taskKey) { - this.listener = listener; - this.otherMemory = otherMemory; - this.rootDir = rootDir; - this.directoriesToAvoid = directoriesToAvoid; - this.prefixesToAvoid = prefixesToAvoid; - this.taskKey = taskKey; - } - - @Override - protected Void doInBackground(DataStorageMemoryItem... items) { - lastRefreshTime = System.currentTimeMillis(); - if (rootDir.canRead()) { - calculateMultiTypes(rootDir, items); - } - return null; - } - - private void calculateMultiTypes(File rootDir, DataStorageMemoryItem... items) { - File[] subFiles = rootDir.listFiles(); - - for (File file : subFiles) { - if (isCancelled()) { - break; - } - nextFile : { - if (file.isDirectory()) { - //check current directory should be avoid - if (directoriesToAvoid != null) { - for (String directoryToAvoid : directoriesToAvoid) { - if (file.getAbsolutePath().equals(directoryToAvoid)) { - break nextFile; - } - } - } - //check current directory matched items type - for (DataStorageMemoryItem item : items) { - Directory[] directories = item.getDirectories(); - if (directories == null) { - continue; - } - for (Directory dir : directories) { - if (file.getAbsolutePath().equals(dir.getAbsolutePath()) - || (file.getAbsolutePath().startsWith(dir.getAbsolutePath()))) { - if (dir.isGoDeeper()) { - calculateMultiTypes(file, items); - break nextFile; - } else if (dir.isSkipOther()) { - break nextFile; - } - } - } - } - //current directory did not match to any type - otherMemory.addBytes(getDirectorySize(file)); - } else if (file.isFile()) { - //check current file should be avoid - if (prefixesToAvoid != null) { - for (String prefixToAvoid : prefixesToAvoid) { - if (file.getName().toLowerCase().startsWith(prefixToAvoid.toLowerCase())) { - break nextFile; - } - } - } - //check current file matched items type - for (DataStorageMemoryItem item : items) { - Directory[] directories = item.getDirectories(); - if (directories == null) { - continue; - } - for (Directory dir : directories) { - if (rootDir.getAbsolutePath().equals(dir.getAbsolutePath()) - || (rootDir.getAbsolutePath().startsWith(dir.getAbsolutePath()) && dir.isGoDeeper())) { - int checkingType = dir.getCheckingType(); - switch (checkingType) { - case EXTENSIONS : { - String[] extensions = item.getExtensions(); - if (extensions != null) { - for (String extension : extensions) { - if (file.getAbsolutePath().endsWith(extension)) { - item.addBytes(file.length()); - break nextFile; - } - } - } else { - item.addBytes(file.length()); - break nextFile; - } - break ; - } - case PREFIX : { - String[] prefixes = item.getPrefixes(); - if (prefixes != null) { - for (String prefix : prefixes) { - if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) { - item.addBytes(file.length()); - break nextFile; - } - } - } else { - item.addBytes(file.length()); - break nextFile; - } - break ; - } - } - if (dir.isSkipOther()) { - break nextFile; - } - } - } - } - //current file did not match any type - otherMemory.addBytes(file.length()); - } - } - refreshUI(); - } - } - - private long getDirectorySize(File dir) { - long bytes = 0; - if (dir.isDirectory()) { - File[] files = dir.listFiles(); - for (File file : files) { - if (isCancelled()) { - break; - } - if (file.isDirectory()) { - bytes += getDirectorySize(file); - } else if (file.isFile()) { - bytes += file.length(); - } - } - } - return bytes; - } - - @Override - protected void onProgressUpdate(Void... values) { - super.onProgressUpdate(values); - if (listener != null) { - listener.onMemoryInfoUpdate(); - } - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (listener != null) { - listener.onFinishUpdating(taskKey); - } - } - - private void refreshUI() { - long currentTime = System.currentTimeMillis(); - if ((currentTime - lastRefreshTime) > UI_REFRESH_TIME_MS) { - lastRefreshTime = currentTime; - publishProgress(); - } - } - } - - public long getTotalUsedBytes() { - long total = 0; - if (memoryItems != null && memoryItems.size() > 0) { - for (DataStorageMemoryItem mi : memoryItems) { - total += mi.getUsedMemoryBytes(); - } - return total; - } - return -1; - } - - public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) { - int type = 0; - double memory = (double) bytes / 1024; - while (memory > 1024 && type < formatStrings.length) { - ++type; - memory = memory / 1024; - } - String formattedUsed = new DecimalFormat("#.##").format(memory); - return String.format(formatStrings[type], formattedUsed); - } - - public interface UpdateMemoryInfoUIAdapter { - - void onMemoryInfoUpdate(); - - void onFinishUpdating(String taskKey); - - } -} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java index fa7383228c..071d7be709 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/GlobalSettingsFragment.java @@ -22,6 +22,8 @@ import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.datastorage.DataStorageHelper; +import net.osmand.plus.settings.datastorage.item.StorageItem; import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.SwitchPreferenceEx; @@ -181,7 +183,7 @@ public class GlobalSettingsFragment extends BaseSettingsFragment externalStorageDir.setIcon(getActiveIcon(R.drawable.ic_action_folder)); DataStorageHelper holder = new DataStorageHelper(app); - DataStorageMenuItem currentStorage = holder.getCurrentStorage(); + StorageItem currentStorage = holder.getCurrentStorage(); long totalUsed = app.getSettings().OSMAND_USAGE_SPACE.get(); if (totalUsed > 0) { String[] usedMemoryFormats = new String[] { From 7041c4ecc98886ca8457d28629b855266e0d1e33 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Feb 2021 20:30:59 +0200 Subject: [PATCH 63/81] Data storage refactoring, step 2 --- OsmAnd/res/xml/data_storage.xml | 2 +- .../datastorage/DataStorageHelper.java | 20 +- .../datastorage/item/DirectoryItem.java | 20 +- .../task/RefreshUsedMemoryTask.java | 269 ++++++++++-------- 4 files changed, 178 insertions(+), 133 deletions(-) diff --git a/OsmAnd/res/xml/data_storage.xml b/OsmAnd/res/xml/data_storage.xml index a153ec4cd1..95168ac3ce 100644 --- a/OsmAnd/res/xml/data_storage.xml +++ b/OsmAnd/res/xml/data_storage.xml @@ -14,7 +14,7 @@ android:title="@string/shared_string_maps"/> diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java index 96a939eae3..fd66cd3e58 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java @@ -39,7 +39,7 @@ public class DataStorageHelper { public final static String MANUALLY_SPECIFIED = "manually_specified"; public final static String MAPS_MEMORY = "maps_memory_used"; - public final static String SRTM_AND_HILLSHADE_MEMORY = "contour_lines_and_hillshade_memory"; + public final static String TERRAIN_MEMORY = "terrain_memory_used"; public final static String TRACKS_MEMORY = "tracks_memory_used"; public final static String NOTES_MEMORY = "notes_memory_used"; public final static String TILES_MEMORY = "tiles_memory_used"; @@ -52,7 +52,7 @@ public class DataStorageHelper { private ArrayList memoryItems = new ArrayList<>(); private MemoryItem mapsMemory; - private MemoryItem srtmAndHillshadeMemory; + private MemoryItem terrainMemory; private MemoryItem tracksMemory; private MemoryItem notesMemory; private MemoryItem tilesMemory; @@ -186,15 +186,15 @@ public class DataStorageHelper { .createItem(); memoryItems.add(mapsMemory); - srtmAndHillshadeMemory = MemoryItem.builder() - .setKey(SRTM_AND_HILLSHADE_MEMORY) + terrainMemory = MemoryItem.builder() + .setKey(TERRAIN_MEMORY) .setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT) .setDirectories( createDirectory((SRTM_INDEX_DIR), true, EXTENSIONS, false), createDirectory((TILES_INDEX_DIR), false, PREFIX, true)) .setPrefixes("Hillshade") .createItem(); - memoryItems.add(srtmAndHillshadeMemory); + memoryItems.add(terrainMemory); tracksMemory = MemoryItem.builder() .setKey(TRACKS_MEMORY) @@ -267,13 +267,13 @@ public class DataStorageHelper { public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) { File rootDir = new File(currentStoragePath); RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, null, OTHER_MEMORY); - task.execute(mapsMemory, srtmAndHillshadeMemory, tracksMemory, notesMemory); + task.execute(mapsMemory, terrainMemory, tracksMemory, notesMemory); return task; } public RefreshUsedMemoryTask calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) { File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath()); - RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, srtmAndHillshadeMemory.getPrefixes(), TILES_MEMORY); + RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, terrainMemory.getPrefixes(), TILES_MEMORY); task.execute(tilesMemory); return task; } @@ -290,11 +290,11 @@ public class DataStorageHelper { } public DirectoryItem createDirectory(@NonNull String relativePath, - boolean goDeeper, + boolean processInternalDirectories, CheckingType checkingType, - boolean skipOther) { + boolean skipUnmatchedInDirectory) { String path = app.getAppPath(relativePath).getAbsolutePath(); - return new DirectoryItem(path, goDeeper, checkingType, skipOther); + return new DirectoryItem(path, processInternalDirectories, checkingType, skipUnmatchedInDirectory); } public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) { diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java index e1d7e1cad4..0f15e39f58 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java @@ -3,9 +3,9 @@ package net.osmand.plus.settings.datastorage.item; public class DirectoryItem { private final String absolutePath; - private final boolean goDeeper; + private final boolean processInternalDirectories; private final CheckingType checkingType; - private final boolean skipOther; + private final boolean skipUnmatchedInDirectory; public enum CheckingType { EXTENSIONS, @@ -13,28 +13,28 @@ public class DirectoryItem { } public DirectoryItem(String absolutePath, - boolean goDeeper, + boolean processInternalDirectories, CheckingType checkingType, - boolean skipOther) { + boolean skipUnmatchedInDirectory) { this.absolutePath = absolutePath; - this.goDeeper = goDeeper; + this.processInternalDirectories = processInternalDirectories; this.checkingType = checkingType; - this.skipOther = skipOther; + this.skipUnmatchedInDirectory = skipUnmatchedInDirectory; } public String getAbsolutePath() { return absolutePath; } - public boolean isGoDeeper() { - return goDeeper; + public boolean shouldProcessInternalDirectories() { + return processInternalDirectories; } public CheckingType getCheckingType() { return checkingType; } - public boolean isSkipOther() { - return skipOther; + public boolean shouldSkipUnmatchedInDirectory() { + return skipUnmatchedInDirectory; } } diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java index ad1dbb4bf5..dc84c97dbc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java @@ -2,6 +2,8 @@ package net.osmand.plus.settings.datastorage.task; import android.os.AsyncTask; +import androidx.annotation.NonNull; + import net.osmand.plus.settings.datastorage.DataStorageHelper.UpdateMemoryInfoUIAdapter; import net.osmand.plus.settings.datastorage.item.DirectoryItem; import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType; @@ -10,146 +12,189 @@ import net.osmand.plus.settings.datastorage.item.MemoryItem; import java.io.File; import static net.osmand.plus.settings.datastorage.DataStorageFragment.UI_REFRESH_TIME_MS; +import static net.osmand.util.Algorithms.objectEquals; public class RefreshUsedMemoryTask extends AsyncTask { - private UpdateMemoryInfoUIAdapter listener; - private File rootDir; - private MemoryItem otherMemory; - private String[] directoriesToAvoid; - private String[] prefixesToAvoid; - private String taskKey; + private final UpdateMemoryInfoUIAdapter uiAdapter; + private final File root; + private final MemoryItem otherMemoryItem; + private final String[] directoriesToSkip; + private final String[] filePrefixesToSkip; + private final String tag; private long lastRefreshTime; - public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter listener, MemoryItem otherMemory, File rootDir, String[] directoriesToAvoid, String[] prefixesToAvoid, String taskKey) { - this.listener = listener; - this.otherMemory = otherMemory; - this.rootDir = rootDir; - this.directoriesToAvoid = directoriesToAvoid; - this.prefixesToAvoid = prefixesToAvoid; - this.taskKey = taskKey; + public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter uiAdapter, + MemoryItem otherMemoryItem, + File root, + String[] directoriesToSkip, + String[] filePrefixesToSkip, + String tag) { + this.uiAdapter = uiAdapter; + this.otherMemoryItem = otherMemoryItem; + this.root = root; + this.directoriesToSkip = directoriesToSkip; + this.filePrefixesToSkip = filePrefixesToSkip; + this.tag = tag; } @Override protected Void doInBackground(MemoryItem... items) { lastRefreshTime = System.currentTimeMillis(); - if (rootDir.canRead()) { - calculateMultiTypes(rootDir, items); + if (root.canRead()) { + calculateMultiTypes(root, items); } return null; } - private void calculateMultiTypes(File rootDir, MemoryItem... items) { + private void calculateMultiTypes(File rootDir, + MemoryItem... items) { File[] subFiles = rootDir.listFiles(); + if (subFiles != null) { + for (File file : subFiles) { + if (isCancelled()) break; - for (File file : subFiles) { - if (isCancelled()) { - break; - } - nextFile : { if (file.isDirectory()) { - //check current directory should be avoid - if (directoriesToAvoid != null) { - for (String directoryToAvoid : directoriesToAvoid) { - if (file.getAbsolutePath().equals(directoryToAvoid)) { - break nextFile; - } - } + if (!shouldSkipDirectory(file)) { + processDirectory(file, items); } - //check current directory matched items type - for (MemoryItem item : items) { - DirectoryItem[] directories = item.getDirectories(); - if (directories == null) { - continue; - } - for (DirectoryItem dir : directories) { - if (file.getAbsolutePath().equals(dir.getAbsolutePath()) - || (file.getAbsolutePath().startsWith(dir.getAbsolutePath()))) { - if (dir.isGoDeeper()) { - calculateMultiTypes(file, items); - break nextFile; - } else if (dir.isSkipOther()) { - break nextFile; - } - } - } - } - //current directory did not match to any type - otherMemory.addBytes(getDirectorySize(file)); + } else if (file.isFile()) { - //check current file should be avoid - if (prefixesToAvoid != null) { - for (String prefixToAvoid : prefixesToAvoid) { - if (file.getName().toLowerCase().startsWith(prefixToAvoid.toLowerCase())) { - break nextFile; - } - } + if (!shouldSkipFile(file)) { + processFile(rootDir, file, items); } - //check current file matched items type - for (MemoryItem item : items) { - DirectoryItem[] directories = item.getDirectories(); - if (directories == null) { - continue; - } - for (DirectoryItem dir : directories) { - if (rootDir.getAbsolutePath().equals(dir.getAbsolutePath()) - || (rootDir.getAbsolutePath().startsWith(dir.getAbsolutePath()) && dir.isGoDeeper())) { - CheckingType checkingType = dir.getCheckingType(); - switch (checkingType) { - case EXTENSIONS : { - String[] extensions = item.getExtensions(); - if (extensions != null) { - for (String extension : extensions) { - if (file.getAbsolutePath().endsWith(extension)) { - item.addBytes(file.length()); - break nextFile; - } - } - } else { - item.addBytes(file.length()); - break nextFile; - } - break ; - } - case PREFIX : { - String[] prefixes = item.getPrefixes(); - if (prefixes != null) { - for (String prefix : prefixes) { - if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) { - item.addBytes(file.length()); - break nextFile; - } - } - } else { - item.addBytes(file.length()); - break nextFile; - } - break ; - } - } - if (dir.isSkipOther()) { - break nextFile; - } - } - } - } - //current file did not match any type - otherMemory.addBytes(file.length()); } + refreshUI(); } - refreshUI(); } } - private long getDirectorySize(File dir) { + private boolean shouldSkipDirectory(@NonNull File dir) { + if (directoriesToSkip != null) { + for (String dirToSkipPath : directoriesToSkip) { + String dirPath = dir.getAbsolutePath(); + if (objectEquals(dirPath, dirToSkipPath)) { + return true; + } + } + } + return false; + } + + private boolean shouldSkipFile(@NonNull File file) { + if (filePrefixesToSkip != null) { + String fileName = file.getName().toLowerCase(); + for (String prefixToAvoid : filePrefixesToSkip) { + String prefix = prefixToAvoid.toLowerCase(); + if (fileName.startsWith(prefix)) { + return true; + } + } + } + return false; + } + + private void processDirectory(@NonNull File directory, + @NonNull MemoryItem... items) { + String directoryPath = directory.getAbsolutePath(); + for (MemoryItem memoryItem : items) { + DirectoryItem[] allowedDirectories = memoryItem.getDirectories(); + if (allowedDirectories != null) { + for (DirectoryItem allowedDir : allowedDirectories) { + String allowedDirPath = allowedDir.getAbsolutePath(); + if (objectEquals(directoryPath, allowedDirPath) + || (directoryPath.startsWith(allowedDirPath))) { + if (allowedDir.shouldProcessInternalDirectories()) { + calculateMultiTypes(directory, items); + return; + } else if (allowedDir.shouldSkipUnmatchedInDirectory()) { + return; + } + } + } + } + } + // Current directory did not match to any type + otherMemoryItem.addBytes(calculateFolderSize(directory)); + } + + private void processFile(@NonNull File rootDir, + @NonNull File file, + @NonNull MemoryItem... items) { + for (MemoryItem item : items) { + DirectoryItem[] allowedDirectories = item.getDirectories(); + if (allowedDirectories == null) continue; + String rootDirPath = rootDir.getAbsolutePath(); + + for (DirectoryItem allowedDir : allowedDirectories) { + String allowedDirPath = allowedDir.getAbsolutePath(); + boolean processInternal = allowedDir.shouldProcessInternalDirectories(); + if (objectEquals(rootDirPath, allowedDirPath) + || (rootDirPath.startsWith(allowedDirPath) && processInternal)) { + CheckingType checkingType = allowedDir.getCheckingType(); + switch (checkingType) { + case EXTENSIONS: { + if (isSuitableExtension(file, item)) { + item.addBytes(file.length()); + return; + } + break; + } + case PREFIX: { + if (isSuitablePrefix(file, item)) { + item.addBytes(file.length()); + return; + } + break; + } + } + if (allowedDir.shouldSkipUnmatchedInDirectory()) { + return; + } + } + } + } + // Current file did not match any type + otherMemoryItem.addBytes(file.length()); + } + + private boolean isSuitableExtension(@NonNull File file, + @NonNull MemoryItem item) { + String[] extensions = item.getExtensions(); + if (extensions != null) { + for (String extension : extensions) { + if (file.getAbsolutePath().endsWith(extension)) { + return true; + } + } + } + return extensions == null; + } + + private boolean isSuitablePrefix(@NonNull File file, + @NonNull MemoryItem item) { + String[] prefixes = item.getPrefixes(); + if (prefixes != null) { + for (String prefix : prefixes) { + if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + return true; + } + } + } + return prefixes == null; + } + + private long calculateFolderSize(@NonNull File dir) { long bytes = 0; if (dir.isDirectory()) { File[] files = dir.listFiles(); + if (files == null) return 0; + for (File file : files) { if (isCancelled()) { break; } if (file.isDirectory()) { - bytes += getDirectorySize(file); + bytes += calculateFolderSize(file); } else if (file.isFile()) { bytes += file.length(); } @@ -161,16 +206,16 @@ public class RefreshUsedMemoryTask extends AsyncTask { @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); - if (listener != null) { - listener.onMemoryInfoUpdate(); + if (uiAdapter != null) { + uiAdapter.onMemoryInfoUpdate(); } } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); - if (listener != null) { - listener.onFinishUpdating(taskKey); + if (uiAdapter != null) { + uiAdapter.onFinishUpdating(tag); } } From 5d3d9500bf5393039fd68ef25dc42186550cd965 Mon Sep 17 00:00:00 2001 From: solokot Date: Mon, 1 Feb 2021 18:47:04 +0000 Subject: [PATCH 64/81] Translated using Weblate (Russian) Currently translated at 99.5% (3639 of 3656 strings) --- OsmAnd/res/values-ru/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index a0a8f5fdea..5747a78d85 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -3986,4 +3986,10 @@ Читать полностью Редактировать описание Удалить путевые точки + HGV + Отправка + Отправка завершена + Отправка %1$d из %2$d + Отправлено %1$d из %2$d + Выберите правки для отправки \ No newline at end of file From 601e8c36702d86178891b604436c7ae0022615b6 Mon Sep 17 00:00:00 2001 From: Matej U Date: Sun, 31 Jan 2021 17:24:39 +0000 Subject: [PATCH 65/81] Translated using Weblate (Slovenian) Currently translated at 74.1% (2710 of 3656 strings) --- OsmAnd/res/values-sl/strings.xml | 53 ++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-sl/strings.xml b/OsmAnd/res/values-sl/strings.xml index 0cb17c35f4..b453cd4b40 100644 --- a/OsmAnd/res/values-sl/strings.xml +++ b/OsmAnd/res/values-sl/strings.xml @@ -3275,14 +3275,14 @@ Izberi mapo Izberi mapo ali dodaj novo Prazno - Analiziraj po intervalih (razdelitveni interval) + Preuči po intervalih (razdelitveni interval) Naloži v OpenStreetMap Uredi sled Preimenuj sled Spremeni mapo sek Pristop - Pripravi se + Pripravljanje Izven poti Prihod na cilj Zavoj @@ -3296,7 +3296,7 @@ Električno kolesarjenje Gorsko kolesarjenje Cestno kolesarjenje - Redno kolesarjenje + Mestno kolesarjenje Težko tovorno vozilo Majhno tovorno vozilo Tovorno vozilo @@ -3309,4 +3309,51 @@ Uredi opis Brisanje točk Kopiraj na oznake na zemljevidu + Na napravi ni dovolj prostora. + Izbor skupin za uvoz. + Izbor predmetov za uvoz. + Dodaj na Mapillary + Dodaj na OpenPlaceReviews + Za preizkušanje pošiljanja sporočil, točk in sledi GPX preklopi iz openstreetmap.org na preizkusni dev.openstreetmap.org. + Uporabi dev.openstreetmap.org + Program podpira prikaz fotografij različnih virov: +\nOpenPlaceReviews – fotografije točk POI; +\nMapillary – ulična fotografija; +\nSplet / Wikimedia – fotografije točk POI in OpenStreetMap. + %1$s * %2$s + Dodaj nov del poti + Lahko letalo + Združi dele poti + Razdeli pred + Razdeli po + Profil OsmAnd + Uporabniški profil + Obrni vse točke + Izbor profila, ki bo prikazan ob zagonu programa. + Nazadnje uporabljeno + Podvrsta + Vozilo + Ključ API + Naslov URL strežnika + Vpis parametrov + Naslov URL z vsemi parametri bo zapisan kot: + Preizkusi izračun poti + Vožnja + Hoja + Kolo + Avto + Kopiraj naslov + Dolgo pripravljanje + Pokaži sled na zemljevidu + Raven približanja + Prosojnost + Legenda + Prikaz višinskega senčenja na zemljevidu. Več o tem je mogoče prebrati na spletni strani programa. + Senčenje + Kopiraj med priljubljene + Poteka pošiljanje + Pošiljanje je končano + Poteka pošiljanje %1$d od %2$d + Poslano %1$d od %2$d + Izbor sprememb za pošiljanje \ No newline at end of file From 4baed45334b62d3b3fde3314c23cfff6ea6a38da Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 31 Jan 2021 09:45:16 +0000 Subject: [PATCH 66/81] Translated using Weblate (German) Currently translated at 99.9% (3653 of 3656 strings) --- OsmAnd/res/values-de/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 620e4a10ea..6fec463772 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4008,4 +4008,9 @@ Wegpunkte löschen In Favoriten kopieren In Kartenmarkierungen kopieren + Lade hoch + Hochladen abgeschlossen + Lade %1$d von %2$d hoch + %1$d von %2$d hochgeladen + Bearbeitungen zum Hochladen auswählen \ No newline at end of file From cb59ac4589a3cde374e2de13bfea162f22ddbff8 Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Sun, 31 Jan 2021 18:52:23 +0000 Subject: [PATCH 67/81] Translated using Weblate (Arabic) Currently translated at 100.0% (3656 of 3656 strings) --- OsmAnd/res/values-ar/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 4b91263f2d..d12d0a4de4 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4069,4 +4069,9 @@ حذف نقاط الطريق نسخ لعلامات الخريطة نسخ للمفضلة + يتم الرفع + اكتمال الرفع + رفع %1$d من %2$d + تم رفع %1$d من %2$d + تحديد التعديلات للتحميل \ No newline at end of file From 9dc5d32c06f336e36911e17b44541c846d0c48f0 Mon Sep 17 00:00:00 2001 From: Jukefox Date: Sun, 31 Jan 2021 19:12:35 +0000 Subject: [PATCH 68/81] Translated using Weblate (Finnish) Currently translated at 63.8% (2334 of 3656 strings) --- OsmAnd/res/values-fi/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OsmAnd/res/values-fi/strings.xml b/OsmAnd/res/values-fi/strings.xml index 95df84bf3e..c188b64182 100644 --- a/OsmAnd/res/values-fi/strings.xml +++ b/OsmAnd/res/values-fi/strings.xml @@ -2739,4 +2739,15 @@ Jos pidät OsmAndista ja OSMsta ja haluat tukea niitä, on tämä täydellinen t Kävely Polkupyörä Auto + Palvelimen virhe: %1$s + Nimi on jo käytössä + Lue kaikki + Muokkaa kuvausta + Kopioi karttamerkkeihin + Kopioi suosikkeihin + Lähetetään + Lähetys valmis + Lähetetty %1$d muutosta %2$d muutoksesta + Lähetettiin %1$d muutosta %2$d muutoksesta + Valitse lähetettävät muutokset \ No newline at end of file From 870efe218392c4826b29f9c2633d2de2214d954c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Sun, 31 Jan 2021 22:27:22 +0000 Subject: [PATCH 69/81] Translated using Weblate (Hungarian) Currently translated at 99.9% (3878 of 3881 strings) --- OsmAnd/res/values-hu/phrases.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml index 488f760a80..b4ca7f9b08 100644 --- a/OsmAnd/res/values-hu/phrases.xml +++ b/OsmAnd/res/values-hu/phrases.xml @@ -708,7 +708,7 @@ Autó Kerékpár Radioaktívhulladék-lerakó - Vízgyűjtő + Vízgyűjtő medence Megfigyelőállomás Daru Építkezés @@ -2633,7 +2633,7 @@ Lottózó Szerencsejáték-helyszín Típus - Lottózó + Lottó Játékgépek Fogadás E-cigaretta-bolt @@ -3446,7 +3446,7 @@ Motorszerelés Biztosítás Gumiszerelés - Kötélpálya + Csúszópálya Kalandpark Via ferrata (vasalt út) Sodronyok száma @@ -3524,7 +3524,7 @@ akadémiai gyermekkönyv Atoll - Útdíjellenőrző kapu + Automatikus útdíjbeszedő kapu Gyermekgondozás (bölcsőde) Természeti emlék Tájékozódási pont From 7454c740653c15f71369b9084cd4979759c4dd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 1 Feb 2021 17:56:18 +0000 Subject: [PATCH 70/81] Translated using Weblate (Estonian) Currently translated at 98.1% (3590 of 3656 strings) --- OsmAnd/res/values-et/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OsmAnd/res/values-et/strings.xml b/OsmAnd/res/values-et/strings.xml index 3bd15abafa..1375440bb8 100644 --- a/OsmAnd/res/values-et/strings.xml +++ b/OsmAnd/res/values-et/strings.xml @@ -3948,4 +3948,9 @@ Viimati kasutatud Serveri viga: %1$s Selline nimi on juba olemas + Vali tehtud muudatused üleslaadimiseks + Üleslaaditud %1$d/%2$d + Laadin üles muudatusi %1$d/%2$d + Sai üleslaaditud + Laadin üles \ No newline at end of file From e4f99aeacee3bd3cf78a6dc19912e1c91a8d23d2 Mon Sep 17 00:00:00 2001 From: eol Date: Mon, 1 Feb 2021 17:35:59 +0000 Subject: [PATCH 71/81] Translated using Weblate (Dutch) Currently translated at 96.1% (3517 of 3656 strings) --- OsmAnd/res/values-nl/strings.xml | 51 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index c9d8e87306..6d4c127831 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -931,7 +931,7 @@ %1$d resterende bestanden %1$d resterende bestanden nog te downloaden Volledige versie - Annuleer route + Annuleer route \? Stop navigatie Bestemming wissen Gebruik magnetische sensor in plaats van oriëntatiesensor voor het kompas. @@ -3726,31 +3726,31 @@ Plan een route Gebruik de twee-fase A* route berekening methode Grafiek - Wacht op de herberekening van de route. -\nDe grafiek is beschikbaar na herberekening. + Wacht totdat route herberekend is. +\nNa herberekening is de grafiek zichtbaar. %1$s — %2$s Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat. Onderbreking Aangepast Voer een OAuth-login uit om osm edit functies te gebruiken - "• Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. + • Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. \n -\n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen +\n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen \n -\n • Donkere thema-fixes +\n • Donkere thema-fixes \n -\n • Verschillende routeringsproblemen over de hele wereld opgelost +\n • Verschillende routeringsproblemen over de hele wereld opgelost \n -\n • Bijgewerkte basiskaart met meer gedetailleerd wegennet +\n • Bijgewerkte basiskaart met meer gedetailleerd wegennet \n -\n • Vaste overstroomde gebieden over de hele wereld +\n • Vaste overstroomde gebieden over de hele wereld \n -\n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails +\n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails \n -\n • Andere bugs opgelost +\n • Andere bugs opgelost \n -\n" - "• Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen +\n + • Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen \n \n • Exitnummer toegevoegd in de navigatie \n @@ -3758,23 +3758,23 @@ \n \n • Herwerkt instellingenscherm voor snelle toegang tot alle profielen \n -\n • Optie toegevoegd om instellingen van een ander profiel te kopiëren +\n • Optie toegevoegd om instellingen van een ander profiel te kopiëren \n -\n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen +\n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen \n -\n • Correct uitgelijnde POI-pictogrammen op de kaart +\n • Correct uitgelijnde POI-pictogrammen op de kaart \n -\n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren +\n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren \n -\n • Thuis/werk-pictogrammen toegevoegd op de kaart +\n • Thuis/werk-pictogrammen toegevoegd op de kaart \n -\n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen +\n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen \n \n • Correcte transliteratie toegevoegd aan de kaart van Japan \n -\n • Antarctica-kaart toegevoegd +\n • Antarctica-kaart toegevoegd \n -\n" +\n Wat is er nieuw Voor sneeuwscooter, rijden met speciale wegen en tracks. Stel aantal werkdagen in om door te gaan @@ -3837,7 +3837,7 @@ Uitloggen gelukt Bestand is reeds geïmporteerd in OsmAnd Lokale kaarten - Aangenaam + Voorziening Speciaal Transport Onderhoud @@ -3856,7 +3856,7 @@ U moet inloggen om wijzigingen te uploaden. \n \nU kunt inloggen met de veilige OAuth-methode of uw loginnaam en wachtwoord gebruiken. - Inloggen met gebruikersnaam en wachtwoord. + Inloggen met gebruikersnaam en wachtwoord Account Gebruikersnaam Abonnement beheren @@ -3993,4 +3993,9 @@ Waypoints verwijderen Kopiëren naar Markeervlaggetjes Kopiëren naar Favorieten + Opladen + Opladen voltooid + Aan het opladen %1$d van %2$d + Opgeladen %1$d van %2$d + Selecteer de op te laden wijzigingen \ No newline at end of file From 56e8f85c04510ea75fb8ab242860b18a9533d639 Mon Sep 17 00:00:00 2001 From: nnngrach Date: Tue, 2 Feb 2021 04:02:43 +0300 Subject: [PATCH 72/81] add default profile name for unnamed or missing improted profiles --- .../settings/backend/backup/ProfileSettingsItem.java | 3 ++- .../settings/fragments/DuplicatesSettingsAdapter.java | 7 ++++++- .../plus/settings/fragments/ExportItemsBottomSheet.java | 9 ++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java index b0bfd5be61..5590d306c6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java @@ -26,6 +26,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; public class ProfileSettingsItem extends OsmandSettingsItem { @@ -124,7 +125,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem { if (Algorithms.isEmpty(modeBean.userProfileName)) { ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); if (appMode != null) { - modeBean.userProfileName = app.getString(appMode.getNameKeyResource()); + modeBean.userProfileName = appMode.toHumanString(); } } int number = 0; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 5d9e3af28a..7e7e52f340 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -33,6 +33,7 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.util.Algorithms; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import java.io.File; @@ -91,7 +92,11 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter Date: Tue, 2 Feb 2021 04:03:51 +0300 Subject: [PATCH 73/81] Revert "add default profile name for unnamed or missing improted profiles" This reverts commit 56e8f85c04510ea75fb8ab242860b18a9533d639. --- .../settings/backend/backup/ProfileSettingsItem.java | 3 +-- .../settings/fragments/DuplicatesSettingsAdapter.java | 7 +------ .../plus/settings/fragments/ExportItemsBottomSheet.java | 9 +-------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java index 5590d306c6..b0bfd5be61 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java @@ -26,7 +26,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; public class ProfileSettingsItem extends OsmandSettingsItem { @@ -125,7 +124,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem { if (Algorithms.isEmpty(modeBean.userProfileName)) { ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); if (appMode != null) { - modeBean.userProfileName = appMode.toHumanString(); + modeBean.userProfileName = app.getString(appMode.getNameKeyResource()); } } int number = 0; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 7e7e52f340..5d9e3af28a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -33,7 +33,6 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.util.Algorithms; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import java.io.File; @@ -92,11 +91,7 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter Date: Tue, 2 Feb 2021 04:04:07 +0300 Subject: [PATCH 74/81] Revert "Merge branch 'master' of https://github.com/osmandapp/Osmand" This reverts commit c2a88ef523a02b5708f68c350f0c407bf038a5fc, reversing changes made to 56e8f85c04510ea75fb8ab242860b18a9533d639. --- OsmAnd/res/values-fi/phrases.xml | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/values-fi/phrases.xml b/OsmAnd/res/values-fi/phrases.xml index 6453253dd4..7751c5bb95 100644 --- a/OsmAnd/res/values-fi/phrases.xml +++ b/OsmAnd/res/values-fi/phrases.xml @@ -17,7 +17,7 @@ Bussipysäkki Trollibussin pysäkki Raitiovaunupysäkki - Piknik-paikka + Piknic paikka Merkittävä kivi Ankkurointipaikka Majakka/linjavalo @@ -311,8 +311,8 @@ Ei Visa Electron -kortteja Shekit Shekkejä ei hyväksytä - Visa Debit-kortit - Ei Visa Debit-kortteja + Visa Debit -kortit + Ei Visa Debit -kortteja Muut Muita maksutapoja ei hyväksytä Bancomat @@ -1139,28 +1139,28 @@ Ei MasterCard-kortteja Maestro-kortit Ei Maestro-kortteja - Ei American Express (AMEX)-kortteja - Ei Diners Club-kortteja + Ei American Express (AMEX) -kortteja + Ei Diners Club -kortteja Ei DKV-kortteja Ei UTA-kortteja Ei Efectivo-maksua Ei Girocard-kortteja Discover Card - Ei Discover Card-kortteja + Ei Discover Card -kortteja Ei Litecoinia Ei PIKEPASS-maksua Ei kryptovaluuttaa - Ei Routex-tankkauskortteja - Ei IC Stored Fare-kortteja + Ei Routex -tankkauskortteja + Ei IC Stored Fare -kortteja Ei JCB-kortteja Ei Laser-kortteja Ei Quick-kortteja Ei Eurowag-kortteja - Ei E-ZPass-maksua + Ei E-ZPass -maksua Ei Euroshell-tankkauskortteja Ei KITCard-maksua Ei Westfalen-kortteja - Ei V PAY-kortteja + Ei V PAY -kortteja Ei Dogecoinia Ei Cibus-kortteja Ei maksua tilisiirrolla @@ -1172,7 +1172,7 @@ Ei Minipay-maksua Ei MiniCash-maksua Ei Moneo-maksua - Ei Monedero 4B-maksua + Ei Monedero 4B -maksua Ei Monedero-maksua Ei BankAxess-maksua Ei Coinkite-maksua @@ -1182,20 +1182,20 @@ Ei tekstiviestimaksua Ei Oyster-kortteja Ei SUBE-kortteja - Ei Via Verde-maksua + Ei Via Verde -maksua Lounassetelit Ei lounasseteleitä Ei PayPal-maksua - Ei U-Key-maksua + Ei U-Key -maksua Poletit Ei poletteja Ei lahjakorttimaksua - Ei Golden Crown-kortteja + Ei Golden Crown -kortteja Ei PRO100-kortteja - Ei Union Card-kortteja + Ei Union Card -kortteja Ei MTS-Money -maksua - Ei Yandex.Money-maksua - Ei OV-Chipkaart-kortteja + Ei Yandex.Money -maksua + Ei OV-Chipkaart -kortteja Tapahtumapaikka Vain kasvisruokaa Kasvisruokaa @@ -1245,9 +1245,9 @@ Sisätilat Ulkona Ei wc-tiloja - Inva-WC: kyllä - Inva-WC: ei - Asiakas-WC + Inva-wc: kyllä + Inva-wc: ei + Asiakas-wc WC:n käyttö: yhteisö WC:n käyttö: julkinen Vauvan vaihtopöytä @@ -1522,4 +1522,4 @@ Vieras talo Majapaikka Vuoristorata - + \ No newline at end of file From 8f302f8558dc94086d316bd5edeaad08dc790190 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 2 Feb 2021 09:41:34 +0200 Subject: [PATCH 75/81] Data storage refactoring, step 3 --- .../datastorage/DataStorageFragment.java | 4 +- .../datastorage/DataStorageHelper.java | 39 ++++++++++--------- .../datastorage/item/DirectoryItem.java | 10 ++--- .../task/RefreshUsedMemoryTask.java | 26 ++++++------- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java index bba6898aaf..7fd96b8185 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java @@ -462,9 +462,9 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } @Override - public void onFinishUpdating(String taskKey) { + public void onFinishUpdating(String tag) { updateAllSettings(); - if (taskKey != null && taskKey.equals(TILES_MEMORY)) { + if (tag != null && tag.equals(TILES_MEMORY)) { app.getSettings().OSMAND_USAGE_SPACE.set(dataStorageHelper.getTotalUsedBytes()); } } diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java index fd66cd3e58..b97da17a4c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java @@ -67,6 +67,11 @@ public class DataStorageHelper { } private void prepareData() { + initStorageItems(); + initUsedMemoryItems(); + } + + private void initStorageItems() { OsmandSettings settings = app.getSettings(); if (settings.getExternalStorageDirectoryTypeV19() >= 0) { currentStorageType = settings.getExternalStorageDirectoryTypeV19(); @@ -169,20 +174,18 @@ public class DataStorageHelper { if (currentDataStorage == null) { currentDataStorage = manuallySpecified; } - - initMemoryUsed(); } - private void initMemoryUsed() { + private void initUsedMemoryItems() { mapsMemory = MemoryItem.builder() .setKey(MAPS_MEMORY) .setExtensions(IndexConstants.BINARY_MAP_INDEX_EXT) .setDirectories( - createDirectory((MAPS_PATH), false, EXTENSIONS, false), - createDirectory((ROADS_INDEX_DIR), true, EXTENSIONS, false), - createDirectory((WIKI_INDEX_DIR), true, EXTENSIONS, false), - createDirectory((WIKIVOYAGE_INDEX_DIR), true, EXTENSIONS, false), - createDirectory((BACKUP_INDEX_DIR), true, EXTENSIONS, false)) + createDirectory(MAPS_PATH, false, EXTENSIONS, true), + createDirectory(ROADS_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)) .createItem(); memoryItems.add(mapsMemory); @@ -190,8 +193,8 @@ public class DataStorageHelper { .setKey(TERRAIN_MEMORY) .setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT) .setDirectories( - createDirectory((SRTM_INDEX_DIR), true, EXTENSIONS, false), - createDirectory((TILES_INDEX_DIR), false, PREFIX, true)) + createDirectory(SRTM_INDEX_DIR, true, EXTENSIONS, true), + createDirectory(TILES_INDEX_DIR, false, PREFIX, false)) .setPrefixes("Hillshade") .createItem(); memoryItems.add(terrainMemory); @@ -200,7 +203,7 @@ public class DataStorageHelper { .setKey(TRACKS_MEMORY) // .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2") .setDirectories( - createDirectory((GPX_INDEX_DIR), true, EXTENSIONS, false)) + createDirectory(GPX_INDEX_DIR, true, EXTENSIONS, true)) .createItem(); memoryItems.add(tracksMemory); @@ -208,7 +211,7 @@ public class DataStorageHelper { .setKey(NOTES_MEMORY) // .setExtensions("") .setDirectories( - createDirectory((AV_INDEX_DIR), true, EXTENSIONS, false)) + createDirectory(AV_INDEX_DIR, true, EXTENSIONS, true)) .createItem(); memoryItems.add(notesMemory); @@ -216,7 +219,7 @@ public class DataStorageHelper { .setKey(TILES_MEMORY) // .setExtensions("") .setDirectories( - createDirectory((TILES_INDEX_DIR), true, EXTENSIONS, false)) + createDirectory(TILES_INDEX_DIR, true, EXTENSIONS, true)) .createItem(); memoryItems.add(tilesMemory); @@ -264,9 +267,9 @@ public class DataStorageHelper { return memoryItems; } - public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) { + public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter uiAdapter) { File rootDir = new File(currentStoragePath); - RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, null, OTHER_MEMORY); + RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(uiAdapter, otherMemory, rootDir, null, null, OTHER_MEMORY); task.execute(mapsMemory, terrainMemory, tracksMemory, notesMemory); return task; } @@ -292,9 +295,9 @@ public class DataStorageHelper { public DirectoryItem createDirectory(@NonNull String relativePath, boolean processInternalDirectories, CheckingType checkingType, - boolean skipUnmatchedInDirectory) { + boolean addUnmatchedToOtherMemory) { String path = app.getAppPath(relativePath).getAbsolutePath(); - return new DirectoryItem(path, processInternalDirectories, checkingType, skipUnmatchedInDirectory); + return new DirectoryItem(path, processInternalDirectories, checkingType, addUnmatchedToOtherMemory); } public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) { @@ -312,7 +315,7 @@ public class DataStorageHelper { void onMemoryInfoUpdate(); - void onFinishUpdating(String taskKey); + void onFinishUpdating(String tag); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java index 0f15e39f58..f316a47920 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java @@ -5,7 +5,7 @@ public class DirectoryItem { private final String absolutePath; private final boolean processInternalDirectories; private final CheckingType checkingType; - private final boolean skipUnmatchedInDirectory; + private final boolean addUnmatchedToOtherMemory; public enum CheckingType { EXTENSIONS, @@ -15,11 +15,11 @@ public class DirectoryItem { public DirectoryItem(String absolutePath, boolean processInternalDirectories, CheckingType checkingType, - boolean skipUnmatchedInDirectory) { + boolean addUnmatchedToOtherMemory) { this.absolutePath = absolutePath; this.processInternalDirectories = processInternalDirectories; this.checkingType = checkingType; - this.skipUnmatchedInDirectory = skipUnmatchedInDirectory; + this.addUnmatchedToOtherMemory = addUnmatchedToOtherMemory; } public String getAbsolutePath() { @@ -34,7 +34,7 @@ public class DirectoryItem { return checkingType; } - public boolean shouldSkipUnmatchedInDirectory() { - return skipUnmatchedInDirectory; + public boolean shouldAddUnmatchedToOtherMemory() { + return addUnmatchedToOtherMemory; } } diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java index dc84c97dbc..6f45676888 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java @@ -97,16 +97,16 @@ public class RefreshUsedMemoryTask extends AsyncTask { @NonNull MemoryItem... items) { String directoryPath = directory.getAbsolutePath(); for (MemoryItem memoryItem : items) { - DirectoryItem[] allowedDirectories = memoryItem.getDirectories(); - if (allowedDirectories != null) { - for (DirectoryItem allowedDir : allowedDirectories) { - String allowedDirPath = allowedDir.getAbsolutePath(); + DirectoryItem[] targetDirectories = memoryItem.getDirectories(); + if (targetDirectories != null) { + for (DirectoryItem targetDirectory : targetDirectories) { + String allowedDirPath = targetDirectory.getAbsolutePath(); if (objectEquals(directoryPath, allowedDirPath) || (directoryPath.startsWith(allowedDirPath))) { - if (allowedDir.shouldProcessInternalDirectories()) { + if (targetDirectory.shouldProcessInternalDirectories()) { calculateMultiTypes(directory, items); return; - } else if (allowedDir.shouldSkipUnmatchedInDirectory()) { + } else if (!targetDirectory.shouldAddUnmatchedToOtherMemory()) { return; } } @@ -121,16 +121,16 @@ public class RefreshUsedMemoryTask extends AsyncTask { @NonNull File file, @NonNull MemoryItem... items) { for (MemoryItem item : items) { - DirectoryItem[] allowedDirectories = item.getDirectories(); - if (allowedDirectories == null) continue; + DirectoryItem[] targetDirectories = item.getDirectories(); + if (targetDirectories == null) continue; String rootDirPath = rootDir.getAbsolutePath(); - for (DirectoryItem allowedDir : allowedDirectories) { - String allowedDirPath = allowedDir.getAbsolutePath(); - boolean processInternal = allowedDir.shouldProcessInternalDirectories(); + for (DirectoryItem targetDirectory : targetDirectories) { + String allowedDirPath = targetDirectory.getAbsolutePath(); + boolean processInternal = targetDirectory.shouldProcessInternalDirectories(); if (objectEquals(rootDirPath, allowedDirPath) || (rootDirPath.startsWith(allowedDirPath) && processInternal)) { - CheckingType checkingType = allowedDir.getCheckingType(); + CheckingType checkingType = targetDirectory.getCheckingType(); switch (checkingType) { case EXTENSIONS: { if (isSuitableExtension(file, item)) { @@ -147,7 +147,7 @@ public class RefreshUsedMemoryTask extends AsyncTask { break; } } - if (allowedDir.shouldSkipUnmatchedInDirectory()) { + if (!targetDirectory.shouldAddUnmatchedToOtherMemory()) { return; } } From bba9ed1f26a883c4d7094696781e06fc34ff3a18 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 2 Feb 2021 10:13:01 +0200 Subject: [PATCH 76/81] Improve calculation algorithm of memory usage / fix "used memory of Hillshade doesn't calculated" --- .../task/RefreshUsedMemoryTask.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java index 6f45676888..0af4cf34cb 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java @@ -99,16 +99,19 @@ public class RefreshUsedMemoryTask extends AsyncTask { for (MemoryItem memoryItem : items) { DirectoryItem[] targetDirectories = memoryItem.getDirectories(); if (targetDirectories != null) { - for (DirectoryItem targetDirectory : targetDirectories) { - String allowedDirPath = targetDirectory.getAbsolutePath(); - if (objectEquals(directoryPath, allowedDirPath) - || (directoryPath.startsWith(allowedDirPath))) { - if (targetDirectory.shouldProcessInternalDirectories()) { - calculateMultiTypes(directory, items); - return; - } else if (!targetDirectory.shouldAddUnmatchedToOtherMemory()) { - return; - } + for (DirectoryItem dir : targetDirectories) { + String allowedDirPath = dir.getAbsolutePath(); + boolean isPerfectlyMatch = objectEquals(directoryPath, allowedDirPath); + boolean isParentDirectory = !isPerfectlyMatch && (directoryPath.startsWith(allowedDirPath)); + boolean isMatchDirectory = isPerfectlyMatch || isParentDirectory; + if (isPerfectlyMatch) { + calculateMultiTypes(directory, items); + return; + } else if (isParentDirectory && dir.shouldProcessInternalDirectories()) { + calculateMultiTypes(directory, items); + return; + } else if (isMatchDirectory && !dir.shouldAddUnmatchedToOtherMemory()) { + return; } } } @@ -122,7 +125,7 @@ public class RefreshUsedMemoryTask extends AsyncTask { @NonNull MemoryItem... items) { for (MemoryItem item : items) { DirectoryItem[] targetDirectories = item.getDirectories(); - if (targetDirectories == null) continue; + if (targetDirectories == null) return; String rootDirPath = rootDir.getAbsolutePath(); for (DirectoryItem targetDirectory : targetDirectories) { From 1030bc67cb58cb178509e0ec87e2a21b0a9938ea Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 2 Feb 2021 10:29:14 +0200 Subject: [PATCH 77/81] Fix #10665 Slope and Hillshade maps separated in the OsmAnd storage overview --- OsmAnd/res/layout/data_storage_memory_used_item.xml | 11 ++++++++--- OsmAnd/res/values/strings.xml | 1 + OsmAnd/res/xml/data_storage.xml | 2 +- .../plus/settings/datastorage/DataStorageHelper.java | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/layout/data_storage_memory_used_item.xml b/OsmAnd/res/layout/data_storage_memory_used_item.xml index 0edf24f056..72f49226e8 100644 --- a/OsmAnd/res/layout/data_storage_memory_used_item.xml +++ b/OsmAnd/res/layout/data_storage_memory_used_item.xml @@ -9,7 +9,8 @@ + android:layout_height="wrap_content" + android:minHeight="@dimen/card_row_min_height"> + tools:text="Internal application memory" /> + Hillshade / Slope / Contour lines Select edits for upload Uploaded %1$d of %2$d Uploading %1$d of %2$d diff --git a/OsmAnd/res/xml/data_storage.xml b/OsmAnd/res/xml/data_storage.xml index 95168ac3ce..173907c8b0 100644 --- a/OsmAnd/res/xml/data_storage.xml +++ b/OsmAnd/res/xml/data_storage.xml @@ -17,7 +17,7 @@ android:key="terrain_memory_used" android:layout="@layout/data_storage_memory_used_item" android:icon="@drawable/ic_map" - android:title="@string/contour_lines_and_hillshade"/> + android:title="@string/hillshade_slope_contour_lines"/> Date: Tue, 2 Feb 2021 12:42:40 +0200 Subject: [PATCH 78/81] small fix --- .../plus/settings/datastorage/task/RefreshUsedMemoryTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java index 0af4cf34cb..123aac1b2b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java @@ -125,7 +125,7 @@ public class RefreshUsedMemoryTask extends AsyncTask { @NonNull MemoryItem... items) { for (MemoryItem item : items) { DirectoryItem[] targetDirectories = item.getDirectories(); - if (targetDirectories == null) return; + if (targetDirectories == null) continue; String rootDirPath = rootDir.getAbsolutePath(); for (DirectoryItem targetDirectory : targetDirectories) { From a0d57b39cf8dbc4bb7ca4020043c8e887b930669 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 2 Feb 2021 13:28:19 +0200 Subject: [PATCH 79/81] hillshade/terrain toggle fix --- OsmAnd/res/layout/center_button_container.xml | 2 +- OsmAnd/res/layout/custom_radio_buttons.xml | 5 +++-- OsmAnd/res/layout/left_button_container.xml | 2 +- OsmAnd/res/layout/right_button_container.xml | 2 +- OsmAnd/src/net/osmand/plus/UiUtilities.java | 21 +++++++++++-------- .../plus/myplaces/GPXItemPagerAdapter.java | 6 +++++- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/layout/center_button_container.xml b/OsmAnd/res/layout/center_button_container.xml index 99858650dc..05fa83eae0 100644 --- a/OsmAnd/res/layout/center_button_container.xml +++ b/OsmAnd/res/layout/center_button_container.xml @@ -8,7 +8,7 @@ android:layout_weight="1"> @@ -22,7 +22,8 @@ layout="@layout/center_button_container" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_weight="1" /> + android:layout_weight="1" + android:visibility="gone" /> Date: Tue, 2 Feb 2021 13:43:45 +0100 Subject: [PATCH 80/81] clean up setup files --- .gitignore | 3 ++- plugins/Osmand-Nautical/.classpath | 9 ------- plugins/Osmand-Nautical/.project | 33 ------------------------- plugins/Osmand-ParkingPlugin/.classpath | 9 ------- plugins/Osmand-ParkingPlugin/.project | 33 ------------------------- plugins/Osmand-SRTMPlugin/.classpath | 9 ------- plugins/Osmand-SRTMPlugin/.project | 33 ------------------------- plugins/Osmand-Skimaps/.classpath | 9 ------- plugins/Osmand-Skimaps/.project | 33 ------------------------- 9 files changed, 2 insertions(+), 169 deletions(-) delete mode 100644 plugins/Osmand-Nautical/.classpath delete mode 100644 plugins/Osmand-Nautical/.project delete mode 100644 plugins/Osmand-ParkingPlugin/.classpath delete mode 100644 plugins/Osmand-ParkingPlugin/.project delete mode 100644 plugins/Osmand-SRTMPlugin/.classpath delete mode 100644 plugins/Osmand-SRTMPlugin/.project delete mode 100644 plugins/Osmand-Skimaps/.classpath delete mode 100644 plugins/Osmand-Skimaps/.project diff --git a/.gitignore b/.gitignore index 33e746a3d6..7386d5e61e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,8 @@ OsmAndCore_*.aar *.iml .settings .idea -.project +**/.project +**/.classpath out/ # Huawei diff --git a/plugins/Osmand-Nautical/.classpath b/plugins/Osmand-Nautical/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-Nautical/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-Nautical/.project b/plugins/Osmand-Nautical/.project deleted file mode 100644 index 69d5b60769..0000000000 --- a/plugins/Osmand-Nautical/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-Nautical - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-ParkingPlugin/.classpath b/plugins/Osmand-ParkingPlugin/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-ParkingPlugin/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-ParkingPlugin/.project b/plugins/Osmand-ParkingPlugin/.project deleted file mode 100644 index 1c708327e5..0000000000 --- a/plugins/Osmand-ParkingPlugin/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-ParkingPlugin - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-SRTMPlugin/.classpath b/plugins/Osmand-SRTMPlugin/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-SRTMPlugin/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-SRTMPlugin/.project b/plugins/Osmand-SRTMPlugin/.project deleted file mode 100644 index 6c3b83059d..0000000000 --- a/plugins/Osmand-SRTMPlugin/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-SRTMPlugin - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/plugins/Osmand-Skimaps/.classpath b/plugins/Osmand-Skimaps/.classpath deleted file mode 100644 index 7bc01d9a9c..0000000000 --- a/plugins/Osmand-Skimaps/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/plugins/Osmand-Skimaps/.project b/plugins/Osmand-Skimaps/.project deleted file mode 100644 index 852dfb35a5..0000000000 --- a/plugins/Osmand-Skimaps/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - Osmand-SkiMaps - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - From bb9a05766593a4f05f702801944be496ed7ba484 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 2 Feb 2021 15:40:48 +0100 Subject: [PATCH 81/81] Add route activity type class --- .../net/osmand/osm/RouteActivityType.java | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java new file mode 100644 index 0000000000..28c9b11551 --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/osm/RouteActivityType.java @@ -0,0 +1,218 @@ +package net.osmand.osm; + +public enum RouteActivityType { + WATER("Water", "yellow"), WINTER("Winter", "yellow"), SNOWMOBILE("Snowmobile", "yellow"), RIDING("Riding", "yellow"), RACING("Racing", "yellow"), + MOUNTAINBIKE("Mountainbike", "blue"), CYCLING("Cycling", "blue"), + HIKING("Hiking", "orange"), RUNNING("Running", "orange"), WALKING("Walking", "orange"), + OFFROAD("Off-road", "yellow"), + MOTORBIKE("Motorbike", "green"), CAR("Car", "green"); + // less specific bottom order + + String name; + String color; + + private RouteActivityType(String nm, String clr) { + this.name = nm; + this.color = clr; + } + + public String getName() { + return name; + } + + public String getColor() { + return color; + } + + public static RouteActivityType getTypeFromTags(String[] tags) { + RouteActivityType activityType = null; + for (String tg : tags) { + RouteActivityType rat = RouteActivityType.convertFromOsmGPXTag(tg); + if (rat != null) { + if (activityType == null || activityType.ordinal() > rat.ordinal()) { + activityType = rat; + } + } + } + return activityType; + } + + public static RouteActivityType convertFromOsmGPXTag(String tg) { + String t = tg.toLowerCase(); + if ("mountain hiking".equalsIgnoreCase(t)) { + return HIKING; + } + if ("motorcar".equalsIgnoreCase(t)) { + return CAR; + } + if ("laufen".equalsIgnoreCase(t)) { + return RUNNING; + } + if ("pedestrian".equalsIgnoreCase(t)) { + return WALKING; + } + switch (t) { + case "mountainbiking": + case "mtb": + case "mountainbike": + case "mountain bike": + case "mountain biking": + case "mountbarker": + case "mtb-tour": + case "ciclismo-mtb-gravel": + case "vtt": + case "btt": + case "vth": + case "mtb ride": + return MOUNTAINBIKE; + case "hiking": + case "route=hiking": + case "mountain hiking": + case "hiking trail": + case "wandern": + case "hike": + case "randonnée": + case "trekking": + case "climbing": + return HIKING; + case "bike": + case "biking": + case "bicycling": + case "bicycle": + case "cycling": + case "cycle": + case "cycleway": + case "cykel": + case "handcycle": + case "cyclotourisme": + case "route=bicycle": + case "cyclotourism": + case "fietsen": + case "вело": + case "велосипед": + case "rower": + case "trasa rowerem": + case "vélo": + case "velo": + case "radtour": + case "bici": + case "fiets": + case "fahrrad": + case "ncn": + case "icn": + case "lcn": + case "network=ncn": + case "network=icn": + case "network=lcn": + return CYCLING; + case "car": + case "motorcar": + case "by car": + case "auto": + case "автомобиль": + case "automobile": + case "autós": + case "driving": + case "drive": + case "van": + case "авто": + case "на автомобиле": + case "bus": + case "truck": + case "taxi": + return CAR; + case "running": + case "run": + case "rungis": + case "trail running": + case "trailrunning": + case "бег": + case "laufen": + case "langlauf": + case "lauf": + case "course": + case "jogging": + case "fitotrack": + return RUNNING; + case "wanderung": + case "walking": + case "walk": + case "nightwalk": + case "walkway": + case "пешком": + case "пеший": + case "pěšky": + case "marche": + case "pedestrian": + case "foot": + case "footing": + case "on_foot": + case "byfoot": + case "onfoot": + case "sightseeing": + case "geocaching": + case "etnanatura": + case "etna": + case "iwn": + case "lwn": + case "rwn": + case "network=iwn": + case "network=lwn": + case "network=rwn": + return WALKING; + case "ling-moto": + case "motorbiking": + case "motorcycle": + case "motorrad": + case "motorbike": + case "motor bike": + case "FVbike": + case "Motorrad": + return MOTORBIKE; + case "offroad": + case "off-road": + case "off road": + case "4x4": + case "terrain": + case "quad": + case "enduro": + case "feldwege": + case "feldweg": + return OFFROAD; + case "boat": + case "water": + case "boating": + case "kayak": + case "river": + case "lake": + case "lakes": + case "canal": + return WATER; + case "ski": + case "skiing": + case "skating": + case "skitour": + case "winter": + case "wintersports": + case "snowboard": + case "лыжи": + case "лыжня": + case "nordic": + case "piste": + return WINTER; + case "snowmobile=designated": + case "snowmobile=permissive": + case "snowmobile=yes": + case "snowmobile": + return SNOWMOBILE; + case "ride": + case "horse": + case "horse trail": + return RIDING; + case "racing": + return RACING; + } + return null; + } + +} \ No newline at end of file