diff --git a/OsmAnd/res/layout/gpx_item_list_header.xml b/OsmAnd/res/layout/gpx_item_list_header.xml index 2b694a8e7b..aa112865c3 100644 --- a/OsmAnd/res/layout/gpx_item_list_header.xml +++ b/OsmAnd/res/layout/gpx_item_list_header.xml @@ -6,27 +6,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + + - - - - - - - - - - + android:layout_height="152dp" + android:scaleType="center" + android:visibility="gone"/> + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java index db54d1550a..c32bbe9eae 100644 --- a/OsmAnd/src/net/osmand/plus/GPXDatabase.java +++ b/OsmAnd/src/net/osmand/plus/GPXDatabase.java @@ -13,7 +13,7 @@ import java.util.List; public class GPXDatabase { private static final String DB_NAME = "gpx_database"; - private static final int DB_VERSION = 1; + private static final int DB_VERSION = 2; private static final String GPX_TABLE_NAME = "gpxTable"; private static final String GPX_COL_NAME = "fileName"; private static final String GPX_COL_DIR = "fileDir"; @@ -37,6 +37,8 @@ public class GPXDatabase { private static final String GPX_COL_POINTS = "points"; private static final String GPX_COL_WPT_POINTS = "wptPoints"; + private static final String GPX_COL_COLOR = "color"; + private static final String GPX_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + GPX_TABLE_NAME + " (" + GPX_COL_NAME + " TEXT, " + GPX_COL_DIR + " TEXT, " + @@ -58,14 +60,15 @@ public class GPXDatabase { GPX_COL_AVG_SPEED + " double, " + GPX_COL_POINTS + " int, " + - GPX_COL_WPT_POINTS + " int);"; + GPX_COL_WPT_POINTS + " int, " + + GPX_COL_COLOR + " TEXT);"; private static final String GPX_TABLE_SELECT = "SELECT " + GPX_COL_NAME + ", " + GPX_COL_DIR + "," + GPX_COL_TOTAL_DISTANCE + ", " + GPX_COL_TOTAL_TRACKS + ", " + GPX_COL_START_TIME + ", " + GPX_COL_END_TIME + ", " + GPX_COL_TIME_SPAN + ", " + GPX_COL_TIME_MOVING + ", " + GPX_COL_TOTAL_DISTANCE_MOVING + ", " + GPX_COL_DIFF_ELEVATION_UP + ", " + GPX_COL_DIFF_ELEVATION_DOWN + ", " + GPX_COL_AVG_ELEVATION + ", " + GPX_COL_MIN_ELEVATION + ", " + GPX_COL_MAX_ELEVATION + ", " + GPX_COL_MAX_SPEED + ", " + - GPX_COL_AVG_SPEED + ", " + GPX_COL_POINTS + ", " + GPX_COL_WPT_POINTS + + GPX_COL_AVG_SPEED + ", " + GPX_COL_POINTS + ", " + GPX_COL_WPT_POINTS + ", " + GPX_COL_COLOR + " FROM " + GPX_TABLE_NAME; private OsmandApplication context; @@ -73,6 +76,7 @@ public class GPXDatabase { public static class GpxDataItem { private File file; private GPXTrackAnalysis analysis; + private int color; public GpxDataItem(File file, GPXTrackAnalysis analysis) { this.file = file; @@ -86,6 +90,14 @@ public class GPXDatabase { public GPXTrackAnalysis getAnalysis() { return analysis; } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } } public GPXDatabase(OsmandApplication app) { @@ -110,22 +122,19 @@ public class GPXDatabase { return conn; } - public void onCreate(SQLiteConnection db) { + private void onCreate(SQLiteConnection db) { db.execSQL(GPX_TABLE_CREATE); } - public void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) { - /* - if (newVersion == 2) { - db.execSQL(GPX_TABLE_CREATE); - //... + private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) { + if (oldVersion < 2) { + db.execSQL("ALTER TABLE " + GPX_TABLE_NAME + " ADD " + GPX_COL_COLOR + " TEXT"); } - */ } public boolean rename(File currentFile, File newFile) { SQLiteConnection db = openConnection(false); - if(db != null){ + if (db != null){ try { String newFileName = getFileName(newFile); String newFileDir = getFileDir(newFile); @@ -144,9 +153,28 @@ public class GPXDatabase { return false; } + public boolean updateColor(GpxDataItem item, int color) { + SQLiteConnection db = openConnection(false); + if (db != null){ + try { + String fileName = getFileName(item.file); + String fileDir = getFileDir(item.file); + db.execSQL("UPDATE " + GPX_TABLE_NAME + " SET " + + GPX_COL_COLOR + " = ? " + + " WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?", + new Object[] { (color == 0 ? "" : Algorithms.colorToString(color)), fileName, fileDir }); + item.setColor(color); + } finally { + db.close(); + } + return true; + } + return false; + } + public boolean remove(File file) { SQLiteConnection db = openConnection(false); - if(db != null){ + if (db != null){ try { String fileName = getFileName(file); String fileDir = getFileDir(file); @@ -166,7 +194,7 @@ public class GPXDatabase { public boolean add(GpxDataItem item) { SQLiteConnection db = openConnection(false); - if(db != null){ + if (db != null){ try { insert(item, db); } finally { @@ -190,11 +218,17 @@ public class GPXDatabase { String fileName = getFileName(item.file); String fileDir = getFileDir(item.file); GPXTrackAnalysis a = item.getAnalysis(); + String color; + if (item.color == 0) { + color = ""; + } else { + color = Algorithms.colorToString(item.color); + } db.execSQL( - "INSERT INTO " + GPX_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "INSERT INTO " + GPX_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", new Object[] { fileName, fileDir, a.totalDistance, a.totalTracks, a.startTime, a.endTime, a.timeSpan, a.timeMoving, a.totalDistanceMoving, a.diffElevationUp, a.diffElevationDown, - a.avgElevation, a.minElevation, a.maxElevation, a.maxSpeed, a.avgSpeed, a.points, a.wptPoints }); + a.avgElevation, a.minElevation, a.maxElevation, a.maxSpeed, a.avgSpeed, a.points, a.wptPoints, color }); } private GpxDataItem readItem(SQLiteCursor query) { @@ -216,6 +250,7 @@ public class GPXDatabase { float avgSpeed = (float)query.getDouble(15); int points = (int)query.getInt(16); int wptPoints = (int)query.getInt(17); + String color = query.getString(18); GPXTrackAnalysis a = new GPXTrackAnalysis(); a.totalDistance = totalDistance; @@ -241,7 +276,13 @@ public class GPXDatabase { } else { dir = context.getAppPath(IndexConstants.GPX_INDEX_DIR); } - return new GpxDataItem(new File(dir, fileName), a); + GpxDataItem item = new GpxDataItem(new File(dir, fileName), a); + try { + item.setColor(Algorithms.isEmpty(color) ? 0 : Algorithms.parseColor(color)); + } catch (IllegalArgumentException e) { + item.setColor(0); + } + return item; } public List getItems() { diff --git a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java index 0d7cf17bf6..3e0ff7151d 100644 --- a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java @@ -3,12 +3,19 @@ */ package net.osmand.plus.activities; -import java.io.File; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; import net.osmand.AndroidUtils; +import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GpxSelectionHelper; @@ -23,25 +30,19 @@ import net.osmand.plus.myplaces.TrackPointFragment; import net.osmand.plus.myplaces.TrackSegmentFragment; import net.osmand.plus.views.controls.PagerSlidingTabStrip; -import android.app.Activity; -import android.content.Intent; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.view.ViewPager; -import android.support.v7.widget.Toolbar; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; +import java.io.File; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; public class TrackActivity extends TabActivity { public static final String TRACK_FILE_NAME = "TRACK_FILE_NAME"; public static final String CURRENT_RECORDING = "CURRENT_RECORDING"; - public static String TAB_PARAM = "TAB_PARAM"; - protected List> fragList = new ArrayList>(); + protected List> fragList = new ArrayList<>(); private File file = null; - private GPXFile result; + private GPXFile gpxFile; + private GpxDataItem gpxDataItem; ViewPager mViewPager; private long modifiedTime = -1; private List displayGroups; @@ -58,77 +59,88 @@ public class TrackActivity extends TabActivity { return; } file = null; - if (intent.hasExtra(TRACK_FILE_NAME)) { - file = new File(intent.getStringExtra(TRACK_FILE_NAME)); - String fn = file.getName().replace(".gpx", "").replace("/", " ").replace("_", " "); - getSupportActionBar().setTitle(fn); - } else { - getSupportActionBar().setTitle(getString(R.string.shared_string_currently_recording_track)); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + if (intent.hasExtra(TRACK_FILE_NAME)) { + file = new File(intent.getStringExtra(TRACK_FILE_NAME)); + String fn = file.getName().replace(".gpx", "").replace("/", " ").replace("_", " "); + actionBar.setTitle(fn); + } else { + actionBar.setTitle(getString(R.string.shared_string_currently_recording_track)); + } + actionBar.setElevation(0); } - getSupportActionBar().setElevation(0); setContentView(R.layout.tab_content); - final PagerSlidingTabStrip mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs); - mSlidingTabLayout.setShouldExpand(true); + final PagerSlidingTabStrip slidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs); + if (slidingTabLayout != null) { + slidingTabLayout.setShouldExpand(true); - mViewPager = (ViewPager) findViewById(R.id.pager); + mViewPager = (ViewPager) findViewById(R.id.pager); - setViewPagerAdapter(mViewPager, new ArrayList()); - mSlidingTabLayout.setViewPager(mViewPager); - new AsyncTask() { + setViewPagerAdapter(mViewPager, new ArrayList()); + slidingTabLayout.setViewPager(mViewPager); + new AsyncTask() { - protected void onPreExecute() { - setSupportProgressBarIndeterminateVisibility(true); - - }; - @Override - protected GPXFile doInBackground(Void... params) { - if(file == null) { - return getMyApplication().getSavingTrackHelper().getCurrentGpx(); + protected void onPreExecute() { + setSupportProgressBarIndeterminateVisibility(true); } - return GPXUtilities.loadGPXFile(TrackActivity.this, file); - } - protected void onPostExecute(GPXFile result) { - setSupportProgressBarIndeterminateVisibility(false); - setGpx(result); - for(WeakReference f : fragList) { - Fragment frag = f.get(); - if(frag instanceof SelectedGPXFragment) { - ((SelectedGPXFragment) frag).setContent(); + @Override + protected GPXFile doInBackground(Void... params) { + if (file == null) { + return getMyApplication().getSavingTrackHelper().getCurrentGpx(); + } + return GPXUtilities.loadGPXFile(TrackActivity.this, file); + } + + protected void onPostExecute(GPXFile result) { + setSupportProgressBarIndeterminateVisibility(false); + + setGpx(result); + setGpxDataItem(getMyApplication().getGpxDatabase().getItem(file)); + + for (WeakReference f : fragList) { + Fragment frag = f.get(); + if (frag instanceof SelectedGPXFragment) { + ((SelectedGPXFragment) frag).setContent(); + } + } + ((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab( + getTabIndicator(R.string.info_button, TrackSegmentFragment.class)); + if (isHavingWayPoints() || isHavingRoutePoints()) { + ((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab( + getTabIndicator(R.string.points, TrackPointFragment.class)); + } else { + slidingTabLayout.setVisibility(View.GONE); + getSupportActionBar().setElevation(AndroidUtils.dpToPx(getMyApplication(), 4f)); } } - ((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab( - getTabIndicator(R.string.info_button, TrackSegmentFragment.class)); - if (isHavingWayPoints() || isHavingRoutePoints()) { - ((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab( - getTabIndicator(R.string.points, TrackPointFragment.class)); - } else { - mSlidingTabLayout.setVisibility(View.GONE); - getSupportActionBar().setElevation(AndroidUtils.dpToPx(getMyApplication(), 4f)); - } - }; - }.execute((Void)null); + }.execute((Void) null); + } + } + protected void setGpxDataItem(GpxDataItem gpxDataItem) { + this.gpxDataItem = gpxDataItem; } protected void setGpx(GPXFile result) { - this.result = result; - if(file == null) { - result = getMyApplication().getSavingTrackHelper().getCurrentGpx(); + this.gpxFile = result; + if (file == null) { + this.gpxFile = getMyApplication().getSavingTrackHelper().getCurrentGpx(); } } - public List getResult() { - if(result == null) { - return new ArrayList(); + public List getGpxFile() { + if (gpxFile == null) { + return new ArrayList<>(); } - if (result.modifiedTime != modifiedTime) { - modifiedTime = result.modifiedTime; + if (gpxFile.modifiedTime != modifiedTime) { + modifiedTime = gpxFile.modifiedTime; GpxSelectionHelper selectedGpxHelper = ((OsmandApplication) getApplication()).getSelectedGpxHelper(); - displayGroups = selectedGpxHelper.collectDisplayGroups(result); + displayGroups = selectedGpxHelper.collectDisplayGroups(gpxFile); if (file != null) { - SelectedGpxFile sf = selectedGpxHelper.getSelectedFileByPath(result.path); + SelectedGpxFile sf = selectedGpxHelper.getSelectedFileByPath(gpxFile.path); if (sf != null && file != null && sf.getDisplayGroups() != null) { displayGroups = sf.getDisplayGroups(); } @@ -139,7 +151,7 @@ public class TrackActivity extends TabActivity { @Override public void onAttachFragment(Fragment fragment) { - fragList.add(new WeakReference(fragment)); + fragList.add(new WeakReference<>(fragment)); } @Override @@ -161,9 +173,11 @@ public class TrackActivity extends TabActivity { public Toolbar getClearToolbar(boolean visible) { final Toolbar tb = (Toolbar) findViewById(R.id.bottomControls); - tb.setTitle(null); - tb.getMenu().clear(); - tb.setVisibility(visible? View.VISIBLE : View.GONE); + if (tb != null) { + tb.setTitle(null); + tb.getMenu().clear(); + tb.setVisibility(visible ? View.VISIBLE : View.GONE); + } return tb; } @@ -195,7 +209,11 @@ public class TrackActivity extends TabActivity { } public GPXFile getGpx() { - return result; + return gpxFile; + } + + public GpxDataItem getGpxDataItem() { + return gpxDataItem; } } diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 668a3f506e..8baea89296 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -1267,17 +1267,42 @@ public class ConfigureMapMenu { private OsmandApplication app; private int currentColor; + private GpxAppearanceAdapterType adapterType = GpxAppearanceAdapterType.TRACK_WIDTH_COLOR; - public GpxAppearanceAdapter(Context context, String currentColorValue) { + public enum GpxAppearanceAdapterType { + TRACK_WIDTH, + TRACK_COLOR, + TRACK_WIDTH_COLOR + } + + public GpxAppearanceAdapter(Context context, String currentColorValue, GpxAppearanceAdapterType adapterType) { super(context, R.layout.rendering_prop_menu_item); - app = (OsmandApplication) getContext().getApplicationContext(); + this.app = (OsmandApplication) getContext().getApplicationContext(); + this.adapterType = adapterType; + RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer(); + this.currentColor = parseTrackColor(renderer, currentColorValue); + init(); + } + public GpxAppearanceAdapter(Context context, int currentColor, GpxAppearanceAdapterType adapterType) { + super(context, R.layout.rendering_prop_menu_item); + this.app = (OsmandApplication) getContext().getApplicationContext(); + this.adapterType = adapterType; + this.currentColor = currentColor; + init(); + } + + public void init() { RenderingRuleProperty trackWidthProp = null; RenderingRuleProperty trackColorProp = null; RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer(); if (renderer != null) { - trackWidthProp = renderer.PROPS.getCustomRule(CURRENT_TRACK_WIDTH_ATTR); - trackColorProp = renderer.PROPS.getCustomRule(CURRENT_TRACK_COLOR_ATTR); + if (adapterType == GpxAppearanceAdapterType.TRACK_WIDTH || adapterType == GpxAppearanceAdapterType.TRACK_WIDTH_COLOR) { + trackWidthProp = renderer.PROPS.getCustomRule(CURRENT_TRACK_WIDTH_ATTR); + } + if (adapterType == GpxAppearanceAdapterType.TRACK_COLOR || adapterType == GpxAppearanceAdapterType.TRACK_WIDTH_COLOR) { + trackColorProp = renderer.PROPS.getCustomRule(CURRENT_TRACK_COLOR_ATTR); + } } if (trackWidthProp != null) { @@ -1293,8 +1318,6 @@ public class ConfigureMapMenu { item.setLastItem(true); } if (trackColorProp != null) { - currentColor = parseTrackColor(renderer, currentColorValue); - AppearanceListItem item = new AppearanceListItem(CURRENT_TRACK_COLOR_ATTR, "", SettingsActivity.getStringPropertyValue(getContext(), trackColorProp.getDefaultValueDescription()), parseTrackColor(renderer, "")); diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index a442878ccb..9d7d9dc625 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -556,7 +556,8 @@ public class GpxUiHelper { popup.setVerticalOffset(AndroidUtils.dpToPx(activity, -48f)); popup.setHorizontalOffset(AndroidUtils.dpToPx(activity, -6f)); final GpxAppearanceAdapter gpxApprAdapter = new GpxAppearanceAdapter(activity, - gpxAppearanceParams.containsKey(CURRENT_TRACK_COLOR_ATTR) ? gpxAppearanceParams.get(CURRENT_TRACK_COLOR_ATTR) : prefColor.get()); + gpxAppearanceParams.containsKey(CURRENT_TRACK_COLOR_ATTR) ? gpxAppearanceParams.get(CURRENT_TRACK_COLOR_ATTR) : prefColor.get(), + GpxAppearanceAdapter.GpxAppearanceAdapterType.TRACK_WIDTH_COLOR); popup.setAdapter(gpxApprAdapter); popup.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -1060,6 +1061,8 @@ public class GpxUiHelper { dataSet.setDrawHorizontalHighlightIndicator(false); dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark)); + dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER); + dataSet.setFillFormatter(new IFillFormatter() { @Override public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) { @@ -1192,6 +1195,8 @@ public class GpxUiHelper { dataSet.setDrawHorizontalHighlightIndicator(false); dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark)); + dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER); + if (useRightAxis) { dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SelectedGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/SelectedGPXFragment.java index 3cb5c6b57a..c232191640 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/SelectedGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/SelectedGPXFragment.java @@ -1,17 +1,14 @@ package net.osmand.plus.myplaces; -import android.app.Activity; -import android.content.DialogInterface; +import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.view.MenuItemCompat; -import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -19,33 +16,24 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.EditText; import android.widget.ListView; -import android.widget.Spinner; import android.widget.TextView; -import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; -import net.osmand.plus.FavouritesDbHelper; +import net.osmand.plus.GPXDatabase; +import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXUtilities.GPXFile; -import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; -import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; -import net.osmand.plus.MapMarkersHelper; -import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.base.OsmAndListFragment; -import net.osmand.plus.helpers.ColorDialogs; -import net.osmand.util.Algorithms; import java.io.File; import java.text.Collator; @@ -53,26 +41,19 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import gnu.trove.list.array.TIntArrayList; - public class SelectedGPXFragment extends OsmAndListFragment { - public static final String ARG_TO_EXPAND_TRACK_INFO = "ARG_TO_EXPAND_TRACK_INFO"; public static final String ARG_TO_FILTER_SHORT_TRACKS = "ARG_TO_FILTER_SHORT_TRACKS"; - public static final String ARG_TO_HIDE_CONFIG_BTN = "ARG_TO_HIDE_CONFIG_BTN"; protected OsmandApplication app; - protected ArrayAdapter adapter; - protected TrackActivity activity; + protected ArrayAdapter adapter; private boolean updateEnable; @Override - public void onAttach(Activity activity) { - this.activity = (TrackActivity) activity; - super.onAttach(activity); - + public void onAttach(Context context) { + super.onAttach(context); final Collator collator = Collator.getInstance(); collator.setStrength(Collator.SECONDARY); - app = (OsmandApplication) activity.getApplication(); + app = (OsmandApplication) getActivity().getApplication(); } @Override @@ -84,7 +65,7 @@ public class SelectedGPXFragment extends OsmAndListFragment { } public TrackActivity getMyActivity() { - return activity; + return (TrackActivity) getActivity(); } @Override @@ -132,8 +113,8 @@ public class SelectedGPXFragment extends OsmAndListFragment { protected static List filterGroups(GpxDisplayItemType[] types, @NonNull TrackActivity trackActivity, @Nullable Bundle args) { - List result = trackActivity.getResult(); - List groups = new ArrayList(); + List result = trackActivity.getGpxFile(); + List groups = new ArrayList<>(); for (GpxDisplayGroup group : result) { boolean add = types == null || hasFilterType(types, group.getType()); if (isArgumentTrue(args, ARG_TO_FILTER_SHORT_TRACKS)) { @@ -157,14 +138,25 @@ public class SelectedGPXFragment extends OsmAndListFragment { } public void setContent() { + setContent(getListView()); + } + + public void setContent(ListView listView) { adapter = createSelectedGPXAdapter(); updateContent(); + setupListView(listView); setListAdapter(adapter); } + protected void setupListView(ListView listView) { + if (adapter.getCount() > 0) { + listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false)); + } + } + protected void updateContent() { adapter.clear(); - List groups = filterGroups(filterTypes(), getMyActivity(), getArguments()); + List groups = filterGroups(filterTypes(), getMyActivity(), getArguments()); adapter.setNotifyOnChange(false); for (GpxDisplayItem i : flatten(groups)) { adapter.add(i); @@ -196,7 +188,7 @@ public class SelectedGPXFragment extends OsmAndListFragment { } protected List flatten(List groups) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for(GpxDisplayGroup g : groups) { list.addAll(g.getModifiableList()); } @@ -211,13 +203,11 @@ public class SelectedGPXFragment extends OsmAndListFragment { ListView listView = (ListView) view.findViewById(android.R.id.list); listView.setDivider(null); listView.setDividerHeight(0); - listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false)); TextView tv = new TextView(getActivity()); tv.setText(R.string.none_selected_gpx); tv.setTextSize(24); listView.setEmptyView(tv); - setContent(); - + setContent(listView); return view; } @@ -228,81 +218,10 @@ public class SelectedGPXFragment extends OsmAndListFragment { return super.onOptionsItemSelected(item); } - protected void saveAsFavorites(final GpxDisplayItemType gpxDisplayItemType) { - AlertDialog.Builder b = new AlertDialog.Builder(getMyActivity()); - final EditText editText = new EditText(getMyActivity()); - final List gs = filterGroups(new GpxDisplayItemType[] { gpxDisplayItemType }, getMyActivity(), getArguments()); - if (gs.size() == 0) { - return; - } - String name = gs.get(0).getName(); - if(name.indexOf('\n') > 0) { - name = name.substring(0, name.indexOf('\n')); - } - editText.setText(name); - editText.setPadding(7, 3, 7, 3); - b.setTitle(R.string.save_as_favorites_points); - b.setView(editText); - b.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - saveFavoritesImpl(flatten(gs), editText.getText().toString()); - } - }); - b.setNegativeButton(R.string.shared_string_cancel, null); - b.show(); - } - - protected void saveAsMapMarkers(final GpxDisplayItemType gpxDisplayItemType) { - AlertDialog.Builder b = new AlertDialog.Builder(getMyActivity()); - final List gs = filterGroups(new GpxDisplayItemType[] { gpxDisplayItemType }, getMyActivity(), getArguments()); - if (gs.size() == 0) { - return; - } - b.setMessage(R.string.add_points_to_map_markers_q); - b.setPositiveButton(R.string.shared_string_add, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - saveMapMarkersImpl(flatten(gs)); - } - }); - b.setNegativeButton(R.string.shared_string_cancel, null); - b.show(); - } - - protected void saveFavoritesImpl(List modifiableList, String category) { - FavouritesDbHelper fdb = app.getFavorites(); - for(GpxDisplayItem i : modifiableList) { - if (i.locationStart != null) { - FavouritePoint fp = new FavouritePoint(i.locationStart.lat, i.locationStart.lon, i.name, category); - if (!Algorithms.isEmpty(i.description)) { - fp.setDescription(i.description); - } - fdb.addFavourite(fp, false); - } - } - fdb.saveCurrentPointsIntoFile(); - } - - protected void saveMapMarkersImpl(List modifiableList) { - MapMarkersHelper markersHelper = app.getMapMarkersHelper(); - List points = new ArrayList<>(); - List names = new ArrayList<>(); - for(GpxDisplayItem i : modifiableList) { - if (i.locationStart != null) { - points.add(new LatLon(i.locationStart.lat, i.locationStart.lon)); - names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, i.name)); - } - } - markersHelper.addMapMarkers(points, names); - } - @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); - ((TrackActivity) getActivity()).getClearToolbar(false); + getMyActivity().getClearToolbar(false); if (getGpx() != null && getGpx().path != null && !getGpx().showCurrentTrack) { MenuItem item = menu.add(R.string.shared_string_share).setIcon(R.drawable.ic_action_gshare_dark) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @@ -320,151 +239,15 @@ public class SelectedGPXFragment extends OsmAndListFragment { } } - protected GPXFile getGpx() { - return ((TrackActivity)getActivity()).getGpx(); + return getMyActivity().getGpx(); } - protected void selectSplitDistance() { - final List groups = filterGroups(new GpxDisplayItemType[] { GpxDisplayItemType.TRACK_SEGMENT }, - getMyActivity(), getArguments()); - - View view = getMyActivity().getLayoutInflater().inflate(R.layout.selected_track_edit, null); - - final TIntArrayList list = new TIntArrayList(); - final Spinner colorSpinner = (Spinner) view.findViewById(R.id.ColorSpinner); - ColorDialogs.setupColorSpinner(getActivity(), getGpx().getColor(0), colorSpinner, list); - - final Spinner sp = (Spinner) view.findViewById(R.id.Spinner); - AlertDialog.Builder bld = new AlertDialog.Builder(getMyActivity()); - final List distanceSplit = new ArrayList(); - final TIntArrayList timeSplit = new TIntArrayList(); - if (groups.size() == 0) { - sp.setVisibility(View.GONE); - view.findViewById(R.id.GpxSpinnerRow).setVisibility(View.GONE); - } else { - sp.setVisibility(View.VISIBLE); - - int[] checkedItem = new int[]{!groups.get(0).isSplitDistance() && !groups.get(0).isSplitTime() ? 0 : -1}; - List options = new ArrayList(); - - - options.add(app.getString(R.string.shared_string_none)); - distanceSplit.add(-1d); - timeSplit.add(-1); - addOptionSplit(30, true, options, distanceSplit, timeSplit, checkedItem, groups); // 50 feet, 20 yards, 20 - // m - addOptionSplit(60, true, options, distanceSplit, timeSplit, checkedItem, groups); // 100 feet, 50 yards, - // 50 m - addOptionSplit(150, true, options, distanceSplit, timeSplit, checkedItem, groups); // 200 feet, 100 yards, - // 100 m - addOptionSplit(300, true, options, distanceSplit, timeSplit, checkedItem, groups); // 500 feet, 200 yards, - // 200 m - addOptionSplit(600, true, options, distanceSplit, timeSplit, checkedItem, groups); // 1000 feet, 500 yards, - // 500 m - addOptionSplit(1500, true, options, distanceSplit, timeSplit, checkedItem, groups); // 2000 feet, 1000 yards, 1 km - addOptionSplit(3000, true, options, distanceSplit, timeSplit, checkedItem, groups); // 1 mi, 2 km - addOptionSplit(6000, true, options, distanceSplit, timeSplit, checkedItem, groups); // 2 mi, 5 km - addOptionSplit(15000, true, options, distanceSplit, timeSplit, checkedItem, groups); // 5 mi, 10 km - - addOptionSplit(15, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(30, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(60, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(120, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(150, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(300, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(600, false, options, distanceSplit, timeSplit, checkedItem, groups); - addOptionSplit(900, false, options, distanceSplit, timeSplit, checkedItem, groups); - - ArrayAdapter adapter = new ArrayAdapter(getMyActivity(), - android.R.layout.simple_spinner_item, options); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - sp.setAdapter(adapter); - if (checkedItem[0] > 0) { - sp.setSelection(checkedItem[0]); - } - } - - final CheckBox vis = (CheckBox) view.findViewById(R.id.Visibility); - vis.setChecked(app.getSelectedGpxHelper().getSelectedFileByPath(getGpx().path) != null); - - bld.setView(view); - bld.setNegativeButton(R.string.shared_string_cancel, null); - bld.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false); - int clr = list.get(colorSpinner.getSelectedItemPosition()); - if (vis.isChecked() && clr != 0 && sf.getModifiableGpxFile() != null) { - sf.getModifiableGpxFile().setColor(clr); - sf.processPoints(); - } - if (groups.size() > 0) { - updateSplit(groups, distanceSplit, timeSplit, sp.getSelectedItemPosition(), vis.isChecked() ? sf - : null); - } - if (vis.isChecked() && sf.getGpxFile() != null) { - if (groups.size() > 0 && groups.get(0).getModifiableList().size() > 0) { - GpxDisplayItem item = groups.get(0).getModifiableList().get(0); - app.getSettings().setMapLocationToShow(item.locationStart.lat, item.locationStart.lon, - 15, - new PointDescription(PointDescription.POINT_TYPE_GPX_ITEM, item.group.getGpxName()), - false, - item); //$NON-NLS-1$ - } else { - WptPt wpt = sf.getGpxFile().findPointToShow(); - if (wpt != null) { - app.getSettings().setMapLocationToShow(wpt.getLatitude(), wpt.getLongitude(), - 15, - new PointDescription(PointDescription.POINT_TYPE_WPT, wpt.name), - false, - wpt); //$NON-NLS-1$ - } - } - MapActivity.launchMapActivityMoveToTop(activity); - } - } - }); - - bld.show(); - + protected GpxDataItem getGpxDataItem() { + return getMyActivity().getGpxDataItem(); } - private void updateSplit(List groups, List distanceSplit, - TIntArrayList timeSplit, int which, SelectedGpxFile sf) { - new SplitTrackAsyncTask(sf, this, getMyActivity(), groups, distanceSplit, timeSplit, which) - .execute((Void) null); - } - - private void addOptionSplit(int value, boolean distance, List options, List distanceSplit, - TIntArrayList timeSplit, int[] checkedItem, List model) { - if (distance) { - double dvalue = OsmAndFormatter.calculateRoundedDist(value, app); - options.add(OsmAndFormatter.getFormattedDistance((float) dvalue, app)); - distanceSplit.add(dvalue); - timeSplit.add(-1); - if (Math.abs(model.get(0).getSplitDistance() - dvalue) < 1) { - checkedItem[0] = distanceSplit.size() - 1; - } - } else { - if (value < 60) { - options.add(value + " " + app.getString(R.string.int_seconds)); - } else if (value % 60 == 0) { - options.add((value / 60) + " " + app.getString(R.string.int_min)); - } else { - options.add((value / 60f) + " " + app.getString(R.string.int_min)); - } - distanceSplit.add(-1d); - timeSplit.add(value); - if (model.get(0).getSplitTime() == value) { - checkedItem[0] = distanceSplit.size() - 1; - } - } - - } - - public ArrayAdapter createSelectedGPXAdapter() { + public ArrayAdapter createSelectedGPXAdapter() { return null; } @@ -472,34 +255,35 @@ public class SelectedGPXFragment extends OsmAndListFragment { public void onListItemClick(ListView l, View v, int position, long id) { GpxDisplayItem child = adapter.getItem(position); + if (child != null) { + if (child.group.getGpx() != null) { + app.getSelectedGpxHelper().setGpxFileToDisplay(child.group.getGpx()); + } - if (child.group.getGpx() != null) { - app.getSelectedGpxHelper().setGpxFileToDisplay(child.group.getGpx()); + final OsmandSettings settings = app.getSettings(); + LatLon location = new LatLon(child.locationStart.lat, child.locationStart.lon); + + if (child.group.getType() == GpxDisplayItemType.TRACK_POINTS) { + settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), + settings.getLastKnownMapZoom(), + new PointDescription(PointDescription.POINT_TYPE_WPT, child.locationStart.name), + false, + child.locationStart); + } else if (child.group.getType() == GpxDisplayItemType.TRACK_ROUTE_POINTS) { + settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), + settings.getLastKnownMapZoom(), + new PointDescription(PointDescription.POINT_TYPE_WPT, child.name), + false, + child.locationStart); + } else { + settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), + settings.getLastKnownMapZoom(), + new PointDescription(PointDescription.POINT_TYPE_GPX_ITEM, child.group.getGpxName()), + false, + child); + } + MapActivity.launchMapActivityMoveToTop(getActivity()); } - - final OsmandSettings settings = app.getSettings(); - LatLon location = new LatLon(child.locationStart.lat, child.locationStart.lon); - - if (child.group.getType() == GpxDisplayItemType.TRACK_POINTS) { - settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), - settings.getLastKnownMapZoom(), - new PointDescription(PointDescription.POINT_TYPE_WPT, child.locationStart.name), - false, - child.locationStart); - } else if (child.group.getType() == GpxDisplayItemType.TRACK_ROUTE_POINTS) { - settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), - settings.getLastKnownMapZoom(), - new PointDescription(PointDescription.POINT_TYPE_WPT, child.name), - false, - child.locationStart); - } else { - settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), - settings.getLastKnownMapZoom(), - new PointDescription(PointDescription.POINT_TYPE_GPX_ITEM, child.group.getGpxName()), - false, - child); - } - MapActivity.launchMapActivityMoveToTop(getActivity()); /* // if(child.group.getType() == GpxDisplayItemType.TRACK_POINTS || // child.group.getType() == GpxDisplayItemType.TRACK_ROUTE_POINTS) { @@ -518,63 +302,4 @@ public class SelectedGPXFragment extends OsmAndListFragment { // } */ } - - public static class SplitTrackAsyncTask extends AsyncTask { - @Nullable private final SelectedGpxFile mSelectedGpxFile; - @NonNull private final SelectedGPXFragment mFragment; - @NonNull private final TrackActivity mActivity; - - private final List groups; - private final List distanceSplit; - private final TIntArrayList timeSplit; - private final int which; - - public SplitTrackAsyncTask(@Nullable SelectedGpxFile selectedGpxFile, - SelectedGPXFragment fragment, - TrackActivity activity, - List groups, - List distanceSplit, - TIntArrayList timeSplit, - int which) { - mSelectedGpxFile = selectedGpxFile; - mFragment = fragment; - mActivity = activity; - this.groups = groups; - this.distanceSplit = distanceSplit; - this.timeSplit = timeSplit; - this.which = which; - } - - protected void onPostExecute(Void result) { - if (mSelectedGpxFile != null) { - mSelectedGpxFile.setDisplayGroups(filterGroups(null, mActivity, mFragment.getArguments())); - } - if (mFragment.isVisible()) { - mFragment.updateContent(); - } - if (!mActivity.isFinishing()) { - mActivity.setProgressBarIndeterminateVisibility(false); - } - } - - protected void onPreExecute() { - mActivity.setProgressBarIndeterminateVisibility(true); - } - - @Override - protected Void doInBackground(Void... params) { - for (GpxDisplayGroup model : groups) { - OsmandApplication application = mActivity.getMyApplication(); - if (which == 0) { - model.noSplit(application); - } else if (distanceSplit.get(which) > 0) { - model.splitByDistance(application, distanceSplit.get(which)); - } else if (timeSplit.get(which) > 0) { - model.splitByTime(application, timeSplit.get(which)); - } - } - - return null; - } - } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java index ab76318842..0f0fa39632 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java @@ -1,7 +1,9 @@ package net.osmand.plus.myplaces; +import android.content.DialogInterface; import android.support.annotation.NonNull; import android.support.v4.view.MenuItemCompat; +import android.support.v7.app.AlertDialog; import android.text.Html; import android.view.LayoutInflater; import android.view.Menu; @@ -10,12 +12,19 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.EditText; import android.widget.ImageView; +import android.widget.ListView; import android.widget.TextView; +import net.osmand.data.FavouritePoint; +import net.osmand.data.LatLon; +import net.osmand.data.PointDescription; +import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; +import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.R; import net.osmand.plus.base.FavoriteImageDrawable; import net.osmand.util.Algorithms; @@ -24,7 +33,15 @@ import java.util.ArrayList; import java.util.List; public class TrackPointFragment extends SelectedGPXFragment { - + + @Override + protected void setupListView(ListView listView) { + super.setupListView(listView); + if (adapter.getCount() > 0) { + listView.addHeaderView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_header, null, false)); + } + } + @Override protected GpxDisplayItemType[] filterTypes() { return new GpxDisplayItemType[] { GpxSelectionHelper.GpxDisplayItemType.TRACK_POINTS, GpxSelectionHelper.GpxDisplayItemType.TRACK_ROUTE_POINTS }; @@ -58,6 +75,77 @@ public class TrackPointFragment extends SelectedGPXFragment { } } + protected void saveAsFavorites(final GpxDisplayItemType gpxDisplayItemType) { + AlertDialog.Builder b = new AlertDialog.Builder(getMyActivity()); + final EditText editText = new EditText(getMyActivity()); + final List gs = filterGroups(new GpxDisplayItemType[] { gpxDisplayItemType }, getMyActivity(), getArguments()); + if (gs.size() == 0) { + return; + } + String name = gs.get(0).getName(); + if(name.indexOf('\n') > 0) { + name = name.substring(0, name.indexOf('\n')); + } + editText.setText(name); + editText.setPadding(7, 3, 7, 3); + b.setTitle(R.string.save_as_favorites_points); + b.setView(editText); + b.setPositiveButton(R.string.shared_string_save, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + saveFavoritesImpl(flatten(gs), editText.getText().toString()); + } + }); + b.setNegativeButton(R.string.shared_string_cancel, null); + b.show(); + } + + protected void saveAsMapMarkers(final GpxDisplayItemType gpxDisplayItemType) { + AlertDialog.Builder b = new AlertDialog.Builder(getMyActivity()); + final List gs = filterGroups(new GpxDisplayItemType[] { gpxDisplayItemType }, getMyActivity(), getArguments()); + if (gs.size() == 0) { + return; + } + b.setMessage(R.string.add_points_to_map_markers_q); + b.setPositiveButton(R.string.shared_string_add, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + saveMapMarkersImpl(flatten(gs)); + } + }); + b.setNegativeButton(R.string.shared_string_cancel, null); + b.show(); + } + + protected void saveFavoritesImpl(List modifiableList, String category) { + FavouritesDbHelper fdb = app.getFavorites(); + for(GpxDisplayItem i : modifiableList) { + if (i.locationStart != null) { + FavouritePoint fp = new FavouritePoint(i.locationStart.lat, i.locationStart.lon, i.name, category); + if (!Algorithms.isEmpty(i.description)) { + fp.setDescription(i.description); + } + fdb.addFavourite(fp, false); + } + } + fdb.saveCurrentPointsIntoFile(); + } + + protected void saveMapMarkersImpl(List modifiableList) { + MapMarkersHelper markersHelper = app.getMapMarkersHelper(); + List points = new ArrayList<>(); + List names = new ArrayList<>(); + for(GpxDisplayItem i : modifiableList) { + if (i.locationStart != null) { + points.add(new LatLon(i.locationStart.lat, i.locationStart.lon)); + names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, i.name)); + } + } + markersHelper.addMapMarkers(points, names); + } + @Override public ArrayAdapter createSelectedGPXAdapter() { return new PointGPXAdapter(new ArrayList()); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java index 7d4da055cc..ba770323c9 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java @@ -2,20 +2,24 @@ package net.osmand.plus.myplaces; import android.content.Context; import android.graphics.Matrix; +import android.os.AsyncTask; import android.support.annotation.NonNull; -import android.support.v4.view.MenuItemCompat; +import android.support.annotation.Nullable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewCompat; +import android.support.v7.widget.ListPopupWindow; +import android.support.v7.widget.SwitchCompat; import android.util.SparseArray; +import android.view.Gravity; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.CompoundButton; import android.widget.ImageView; +import android.widget.ListView; import android.widget.TextView; import com.github.mikephil.charting.charts.LineChart; @@ -26,20 +30,31 @@ import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture; import com.github.mikephil.charting.listener.OnChartGestureListener; import net.osmand.AndroidUtils; +import net.osmand.data.PointDescription; +import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXTrackAnalysis; import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.IconsCache; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.TrackActivity; +import net.osmand.plus.dialogs.ConfigureMapMenu.AppearanceListItem; +import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter; +import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet; import net.osmand.plus.views.controls.PagerSlidingTabStrip; import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider; import net.osmand.plus.views.controls.WrapContentHeightViewPager; import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionInterface; +import net.osmand.render.RenderingRulesStorage; import net.osmand.util.Algorithms; import java.text.DateFormat; @@ -47,27 +62,262 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import gnu.trove.list.array.TIntArrayList; + +import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR; + public class TrackSegmentFragment extends SelectedGPXFragment { + private List options = new ArrayList<>(); + private List distanceSplit = new ArrayList<>(); + private TIntArrayList timeSplit = new TIntArrayList(); + private int selectedSplitInterval; + + @Override + protected void setupListView(ListView listView) { + super.setupListView(listView); + if (adapter.getCount() > 0) { + View view = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_list_header, null, false); + listView.addHeaderView(view); + final ImageView imageView = (ImageView) view.findViewById(R.id.imageView); + final View splitIntervalView = view.findViewById(R.id.split_interval_view); + final View colorView = view.findViewById(R.id.color_view); + final SwitchCompat vis = (SwitchCompat) view.findViewById(R.id.showOnMapToggle); + vis.setChecked(app.getSelectedGpxHelper().getSelectedFileByPath(getGpx().path) != null); + vis.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false); + if (vis.isChecked() && sf.getModifiableGpxFile() != null) { + sf.processPoints(); + updateColorView(colorView); + } else { + updateColorView(colorView); + } + } + }); + imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false); + if (vis.isChecked() && sf.getGpxFile() != null) { + final List groups = getGroups(); + if (groups.size() > 0 && groups.get(0).getModifiableList().size() > 0) { + GpxDisplayItem item = groups.get(0).getModifiableList().get(0); + app.getSettings().setMapLocationToShow(item.locationStart.lat, item.locationStart.lon, + 15, + new PointDescription(PointDescription.POINT_TYPE_GPX_ITEM, item.group.getGpxName()), + false, + item); + } else { + GPXUtilities.WptPt wpt = sf.getGpxFile().findPointToShow(); + if (wpt != null) { + app.getSettings().setMapLocationToShow(wpt.getLatitude(), wpt.getLongitude(), + 15, + new PointDescription(PointDescription.POINT_TYPE_WPT, wpt.name), + false, + wpt); + } + } + MapActivity.launchMapActivityMoveToTop(getMyActivity()); + } + } + }); + updateColorView(colorView); + colorView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final ListPopupWindow popup = new ListPopupWindow(getActivity()); + popup.setAnchorView(colorView); + popup.setContentWidth(AndroidUtils.dpToPx(app, 200f)); + popup.setModal(true); + popup.setDropDownGravity(Gravity.RIGHT | Gravity.TOP); + popup.setVerticalOffset(AndroidUtils.dpToPx(app, -48f)); + popup.setHorizontalOffset(AndroidUtils.dpToPx(app, -6f)); + final GpxAppearanceAdapter gpxApprAdapter = new GpxAppearanceAdapter(getActivity(), + getGpx().getColor(0), GpxAppearanceAdapterType.TRACK_COLOR); + popup.setAdapter(gpxApprAdapter); + popup.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + AppearanceListItem item = gpxApprAdapter.getItem(position); + if (item != null) { + if (item.getAttrName() == CURRENT_TRACK_COLOR_ATTR) { + int clr = item.getColor(); + if (vis.isChecked()) { + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false); + if (clr != 0 && sf.getModifiableGpxFile() != null) { + sf.getModifiableGpxFile().setColor(clr); + app.getGpxDatabase().updateColor(getGpxDataItem(), clr); + } + } else { + app.getGpxDatabase().updateColor(getGpxDataItem(), clr); + } + } + } + popup.dismiss(); + updateColorView(colorView); + } + }); + popup.show(); + } + }); + + prepareSplitIntervalAdapterData(); + setupSplitIntervalView(splitIntervalView); + updateSplitIntervalView(splitIntervalView); + splitIntervalView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final ListPopupWindow popup = new ListPopupWindow(getActivity()); + popup.setAnchorView(splitIntervalView); + popup.setContentWidth(AndroidUtils.dpToPx(app, 200f)); + popup.setModal(true); + popup.setDropDownGravity(Gravity.RIGHT | Gravity.TOP); + popup.setVerticalOffset(AndroidUtils.dpToPx(app, -48f)); + popup.setHorizontalOffset(AndroidUtils.dpToPx(app, -6f)); + popup.setAdapter(new ArrayAdapter<>(getMyActivity(), + R.layout.popup_list_text_item, options)); + popup.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + selectedSplitInterval = position; + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false); + final List groups = getGroups(); + if (groups.size() > 0) { + updateSplit(groups, vis.isChecked() ? sf : null); + } + popup.dismiss(); + updateSplitIntervalView(splitIntervalView); + } + }); + popup.show(); + } + }); + } + } + + private List getGroups() { + return filterGroups(new GpxDisplayItemType[] { GpxDisplayItemType.TRACK_SEGMENT }, + getMyActivity(), getArguments()); + } + + private void setupSplitIntervalView(View view) { + final TextView title = (TextView) view.findViewById(R.id.split_interval_title); + final TextView text = (TextView) view.findViewById(R.id.split_interval_text); + final ImageView img = (ImageView) view.findViewById(R.id.split_interval_arrow); + int colorId; + final List groups = getGroups(); + if (groups.size() > 0) { + colorId = app.getSettings().isLightContent() ? + R.color.primary_text_light : R.color.primary_text_dark; + } else { + colorId = app.getSettings().isLightContent() ? + R.color.secondary_text_light : R.color.secondary_text_dark; + } + int color = app.getResources().getColor(colorId); + title.setTextColor(color); + text.setTextColor(color); + img.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_action_arrow_drop_down, colorId)); + } + + private void updateSplitIntervalView(View view) { + final TextView text = (TextView) view.findViewById(R.id.split_interval_text); + if (selectedSplitInterval == 0) { + text.setText(getString(R.string.shared_string_none)); + } else { + text.setText(options.get(selectedSplitInterval)); + } + } + + private void updateColorView(View colorView) { + final ImageView colorImageView = (ImageView) colorView.findViewById(R.id.colorImage); + int color = getGpxDataItem().getColor(); + if (color == 0) { + color = getGpx().getColor(0); + } + if (color == 0) { + final RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer(); + final OsmandSettings.CommonPreference prefColor + = app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR); + color = GpxAppearanceAdapter.parseTrackColor(renderer, prefColor.get()); + } + if (color == 0) { + colorImageView.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_circle)); + } else { + colorImageView.setImageDrawable(app.getIconsCache().getPaintedIcon(R.drawable.ic_action_circle, color)); + } + } + @Override protected GpxDisplayItemType[] filterTypes() { return new GpxDisplayItemType[] { GpxSelectionHelper.GpxDisplayItemType.TRACK_SEGMENT }; } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - MenuItem item = menu.add(R.string.shared_string_show_on_map).setIcon(R.drawable.ic_show_on_map).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - selectSplitDistance(); - return true; + private void prepareSplitIntervalAdapterData() { + final List groups = getGroups(); + + options.add(app.getString(R.string.shared_string_none)); + distanceSplit.add(-1d); + timeSplit.add(-1); + addOptionSplit(30, true, groups); // 50 feet, 20 yards, 20 + // m + addOptionSplit(60, true, groups); // 100 feet, 50 yards, + // 50 m + addOptionSplit(150, true, groups); // 200 feet, 100 yards, + // 100 m + addOptionSplit(300, true, groups); // 500 feet, 200 yards, + // 200 m + addOptionSplit(600, true, groups); // 1000 feet, 500 yards, + // 500 m + addOptionSplit(1500, true, groups); // 2000 feet, 1000 yards, 1 km + addOptionSplit(3000, true, groups); // 1 mi, 2 km + addOptionSplit(6000, true, groups); // 2 mi, 5 km + addOptionSplit(15000, true, groups); // 5 mi, 10 km + + addOptionSplit(15, false, groups); + addOptionSplit(30, false, groups); + addOptionSplit(60, false, groups); + addOptionSplit(120, false, groups); + addOptionSplit(150, false, groups); + addOptionSplit(300, false, groups); + addOptionSplit(600, false, groups); + addOptionSplit(900, false, groups); + } + + private void updateSplit(List groups, SelectedGpxFile sf) { + new SplitTrackAsyncTask(sf, this, getMyActivity(), groups).execute((Void) null); + } + + private void addOptionSplit(int value, boolean distance, List model) { + if (distance) { + double dvalue = OsmAndFormatter.calculateRoundedDist(value, app); + options.add(OsmAndFormatter.getFormattedDistance((float) dvalue, app)); + distanceSplit.add(dvalue); + timeSplit.add(-1); + if (Math.abs(model.get(0).getSplitDistance() - dvalue) < 1) { + selectedSplitInterval = distanceSplit.size() - 1; } - }); - MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); + } else { + if (value < 60) { + options.add(value + " " + app.getString(R.string.int_seconds)); + } else if (value % 60 == 0) { + options.add((value / 60) + " " + app.getString(R.string.int_min)); + } else { + options.add((value / 60f) + " " + app.getString(R.string.int_min)); + } + distanceSplit.add(-1d); + timeSplit.add(value); + if (model.get(0).getSplitTime() == value) { + selectedSplitInterval = distanceSplit.size() - 1; + } + } } @Override @@ -102,8 +352,9 @@ public class TrackSegmentFragment extends SelectedGPXFragment { @Override public View getView(int position, View convertView, @NonNull ViewGroup parent) { View row = convertView; - PagerSlidingTabStrip tabLayout = null; + PagerSlidingTabStrip tabLayout; WrapContentHeightViewPager pager; + boolean create = false; if (row == null) { LayoutInflater inflater = getMyActivity().getLayoutInflater(); row = inflater.inflate(R.layout.gpx_list_item_tab_content, parent, false); @@ -120,16 +371,18 @@ public class TrackSegmentFragment extends SelectedGPXFragment { tabLayout.setTabSelectionType(PagerSlidingTabStrip.TabSelectionType.SOLID_COLOR); pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager); pager.setSwipeable(false); + pager.setOffscreenPageLimit(2); + create = true; } else { + tabLayout = (PagerSlidingTabStrip) row.findViewById(R.id.sliding_tabs); pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager); } - - if (tabLayout != null) { - pager.setAdapter(getPagerAdapter(tabLayout, getItem(position))); - pager.setOffscreenPageLimit(2); + pager.setAdapter(getPagerAdapter(tabLayout, getItem(position))); + if (create) { tabLayout.setViewPager(pager); + } else { + tabLayout.notifyDataSetChanged(true); } - return row; } } @@ -277,7 +530,7 @@ public class TrackSegmentFragment extends SelectedGPXFragment { switch (tabType) { case GPX_TAB_ITEM_GENERAL: if (analysis != null) { - List dataSets = new ArrayList<>(); + List dataSets = new LinkedList<>(); if (analysis.elevationData != null || analysis.isSpeedSpecified()) { GpxUiHelper.setupGPXChart(app, chart, 4); OrderedLineDataSet speedDataSet = null; @@ -526,4 +779,55 @@ public class TrackSegmentFragment extends SelectedGPXFragment { chart.highlightValue(gpxItem.chartHighlightPos, 0); } } + + class SplitTrackAsyncTask extends AsyncTask { + @Nullable + private final SelectedGpxFile mSelectedGpxFile; + @NonNull private final SelectedGPXFragment mFragment; + @NonNull private final TrackActivity mActivity; + + private final List groups; + + SplitTrackAsyncTask(@Nullable SelectedGpxFile selectedGpxFile, + @NonNull SelectedGPXFragment fragment, + @NonNull TrackActivity activity, + List groups) { + mSelectedGpxFile = selectedGpxFile; + mFragment = fragment; + mActivity = activity; + this.groups = groups; + } + + protected void onPostExecute(Void result) { + if (mSelectedGpxFile != null) { + mSelectedGpxFile.setDisplayGroups(filterGroups(null, mActivity, mFragment.getArguments())); + } + if (mFragment.isVisible()) { + mFragment.updateContent(); + } + if (!mActivity.isFinishing()) { + mActivity.setProgressBarIndeterminateVisibility(false); + } + } + + protected void onPreExecute() { + mActivity.setProgressBarIndeterminateVisibility(true); + } + + @Override + protected Void doInBackground(Void... params) { + for (GpxDisplayGroup model : groups) { + OsmandApplication application = mActivity.getMyApplication(); + if (selectedSplitInterval == 0) { + model.noSplit(application); + } else if (distanceSplit.get(selectedSplitInterval) > 0) { + model.splitByDistance(application, distanceSplit.get(selectedSplitInterval)); + } else if (timeSplit.get(selectedSplitInterval) > 0) { + model.splitByTime(application, timeSplit.get(selectedSplitInterval)); + } + } + + return null; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index efc3e0a255..b726789b34 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -23,6 +23,7 @@ import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.data.QuadTree; import net.osmand.data.RotatedTileBox; +import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.TrkSegment; @@ -367,8 +368,13 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex List selectedGPXFiles, DrawSettings settings) { for (SelectedGpxFile g : selectedGPXFiles) { + GpxDataItem gpxDataItem = view.getApplication().getGpxDatabase().getItem(new File(g.getGpxFile().path)); List segments = g.getPointsToDisplay(); for (TrkSegment ts : segments) { + int color = gpxDataItem.getColor(); + if (color == 0) { + color = ts.getColor(cachedColor); + } if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD) && !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how? if (g.isShowCurrentTrack()) { @@ -377,7 +383,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex ts.renders.add(new Renderable.StandardTrack(ts.points, 17.2)); } } - updatePaints(ts.getColor(cachedColor), g.isRoutePoints(), g.isShowCurrentTrack(), settings, tileBox); + updatePaints(color, g.isRoutePoints(), g.isShowCurrentTrack(), settings, tileBox); ts.drawRenderers(view.getZoom(), paint, canvas, tileBox); } } diff --git a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java index d0720a6484..44677e9a72 100644 --- a/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java +++ b/OsmAnd/src/net/osmand/plus/views/controls/PagerSlidingTabStrip.java @@ -247,10 +247,10 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { pager.setOnPageChangeListener(pageListener); pager.getAdapter().registerDataSetObserver(adapterObserver); adapterObserver.setAttached(true); - notifyDataSetChanged(); + notifyDataSetChanged(false); } - public void notifyDataSetChanged() { + public void notifyDataSetChanged(boolean forced) { tabsContainer.removeAllViews(); tabCount = pager.getAdapter().getCount(); View tabView; @@ -266,27 +266,34 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { addTab(i, title, tabView); } - updateTabStyles(); - getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - @SuppressWarnings("deprecation") - @SuppressLint("NewApi") - @Override - public void onGlobalLayout() { + if (forced) { + currentPosition = pager.getCurrentItem(); + currentPositionOffset = 0f; + scrollToChild(currentPosition, 0); + updateSelection(currentPosition); + } else { + getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { - getViewTreeObserver().removeGlobalOnLayoutListener(this); - } else { - getViewTreeObserver().removeOnGlobalLayoutListener(this); + @SuppressWarnings("deprecation") + @SuppressLint("NewApi") + @Override + public void onGlobalLayout() { + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + getViewTreeObserver().removeGlobalOnLayoutListener(this); + } else { + getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + + currentPosition = pager.getCurrentItem(); + currentPositionOffset = 0f; + scrollToChild(currentPosition, 0); + updateSelection(currentPosition); } - - currentPosition = pager.getCurrentItem(); - currentPositionOffset = 0f; - scrollToChild(currentPosition, 0); - updateSelection(currentPosition); - } - }); + }); + } } private void addTab(final int position, CharSequence title, View tabView) { @@ -584,7 +591,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { @Override public void onChanged() { - notifyDataSetChanged(); + notifyDataSetChanged(false); } public void setAttached(boolean attached) { @@ -612,7 +619,11 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { super.onDetachedFromWindow(); if (pager != null) { if (adapterObserver.isAttached()) { - pager.getAdapter().unregisterDataSetObserver(adapterObserver); + try { + pager.getAdapter().unregisterDataSetObserver(adapterObserver); + } catch (IllegalStateException e) { + //ignore + } adapterObserver.setAttached(false); } }