diff --git a/OsmAnd/res/layout/split_segments_layout.xml b/OsmAnd/res/layout/split_segments_layout.xml index 20fdb8abfe..410bf5fd8c 100644 --- a/OsmAnd/res/layout/split_segments_layout.xml +++ b/OsmAnd/res/layout/split_segments_layout.xml @@ -1,86 +1,125 @@ - - - - - + android:layout_height="@dimen/dashboard_map_toolbar"> + + + + + + + + + + + + + + - - + android:layout_height="wrap_content" + android:orientation="vertical"> - - - - + android:layout_height="48dp" + android:background="?attr/bg_color" + android:orientation="horizontal" + android:paddingLeft="16dp" + android:paddingRight="16dp"> + android:layout_marginBottom="12dp" + android:layout_marginRight="16dp" + android:layout_marginTop="12dp" + tools:src="@drawable/ic_action_split_interval" /> + + + + + + + + + + + + - + - - - \ No newline at end of file + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java index 66d8822c71..aff88e1662 100644 --- a/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/TrackActivity.java @@ -30,7 +30,7 @@ import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.measurementtool.NewGpxData; import net.osmand.plus.myplaces.FavoritesActivity; -import net.osmand.plus.myplaces.SplitSegmentFragment; +import net.osmand.plus.myplaces.SplitSegmentDialogFragment; import net.osmand.plus.myplaces.TrackPointFragment; import net.osmand.plus.myplaces.TrackSegmentFragment; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; @@ -61,10 +61,6 @@ public class TrackActivity extends TabActivity { private boolean openPointsTab = false; private boolean openTracksList = false; - public PagerSlidingTabStrip getSlidingTabLayout() { - return slidingTabLayout; - } - @Override public void onCreate(Bundle icicle) { this.app = getMyApplication(); @@ -294,8 +290,8 @@ public class TrackActivity extends TabActivity { Fragment frag = f.get(); if (frag instanceof TrackSegmentFragment) { ((TrackSegmentFragment) frag).updateContent(); - } else if (frag instanceof SplitSegmentFragment) { - ((SplitSegmentFragment) frag).reloadSplitFragment(); + } else if (frag instanceof SplitSegmentDialogFragment) { + ((SplitSegmentDialogFragment) frag).updateContent(); } else if (frag instanceof TrackPointFragment) { ((TrackPointFragment) frag).setContent(); } @@ -348,23 +344,6 @@ public class TrackActivity extends TabActivity { int itemId = item.getItemId(); switch (itemId) { case android.R.id.home: - int backStackEntriesCount = getSupportFragmentManager().getBackStackEntryCount(); - if (backStackEntriesCount > 0) { - FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1); - if (backStackEntry.getName().equals(SplitSegmentFragment.TAG)) { - for (WeakReference f : fragList) { - Fragment frag = f.get(); - if (frag instanceof TrackSegmentFragment) { - ((TrackSegmentFragment) frag).updateSplitView(); - } - } - getSupportFragmentManager().popBackStack(); - if (isHavingWayPoints() || isHavingRoutePoints()) { - getSlidingTabLayout().setVisibility(View.VISIBLE); - } - return true; - } - } if (getIntent().hasExtra(MapActivity.INTENT_KEY_PARENT_MAP_ACTIVITY) || openTracksList) { OsmAndAppCustomization appCustomization = getMyApplication().getAppCustomization(); final Intent favorites = new Intent(this, appCustomization.getFavoritesActivity()); @@ -379,25 +358,17 @@ public class TrackActivity extends TabActivity { return false; } - @Override - public void onBackPressed() { - int backStackEntriesCount = getSupportFragmentManager().getBackStackEntryCount(); - if (backStackEntriesCount > 0) { - FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1); - if (backStackEntry.getName().equals(SplitSegmentFragment.TAG)) { - for (WeakReference f : fragList) { - Fragment frag = f.get(); - if (frag instanceof TrackSegmentFragment) { - ((TrackSegmentFragment) frag).updateSplitView(); - } - } - getSupportFragmentManager().popBackStack(); - if (isHavingWayPoints() || isHavingRoutePoints()) { - getSlidingTabLayout().setVisibility(View.VISIBLE); - } - return; + public void updateSplitView() { + for (WeakReference f : fragList) { + Fragment frag = f.get(); + if (frag instanceof TrackSegmentFragment) { + ((TrackSegmentFragment) frag).updateSplitView(); } } + } + + @Override + public void onBackPressed() { if (openTracksList) { OsmAndAppCustomization appCustomization = getMyApplication().getAppCustomization(); final Intent favorites = new Intent(this, appCustomization.getFavoritesActivity()); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java new file mode 100644 index 0000000000..29f545e7bb --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java @@ -0,0 +1,719 @@ +package net.osmand.plus.myplaces; + +import android.content.DialogInterface; +import android.content.res.ColorStateList; +import android.graphics.Paint; +import android.graphics.Rect; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.ListPopupWindow; +import android.support.v7.widget.Toolbar; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import net.osmand.AndroidUtils; +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.GpxDisplayItemType; +import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +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.TrackActivity; +import net.osmand.plus.helpers.FontCache; +import net.osmand.util.Algorithms; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import gnu.trove.list.array.TIntArrayList; + +import static net.osmand.plus.myplaces.TrackSegmentFragment.ARG_TO_FILTER_SHORT_TRACKS; + +public class SplitSegmentDialogFragment extends DialogFragment { + + public final static String TAG = "SPLIT_SEGMENT_DIALOG_FRAGMENT"; + private OsmandApplication app; + + private SplitSegmentsAdapter adapter; + private View headerView; + + private GpxDisplayItemType[] filterTypes = {GpxDisplayItemType.TRACK_SEGMENT}; + private List options = new ArrayList<>(); + private List distanceSplit = new ArrayList<>(); + private TIntArrayList timeSplit = new TIntArrayList(); + private int selectedSplitInterval; + private IconsCache ic; + private int minMaxSpeedLayoutWidth; + private Paint minMaxSpeedPaint; + private Rect minMaxSpeedTextBounds; + private ListView listView; + private ProgressBar progressBar; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + app = getMyApplication(); + ic = app.getIconsCache(); + boolean isLightTheme = app.getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME; + int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme; + setStyle(STYLE_NO_FRAME, themeId); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + listView.setBackgroundColor(getResources().getColor( + getMyApplication().getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light + : R.color.ctx_menu_info_view_bg_dark)); + getTrackActivity().onAttachFragment(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + minMaxSpeedPaint = new Paint(); + minMaxSpeedPaint.setTextSize(getResources().getDimension(R.dimen.default_split_segments_data)); + minMaxSpeedPaint.setTypeface(FontCache.getFont(getContext(), "fonts/Roboto-Medium.ttf")); + minMaxSpeedPaint.setStyle(Paint.Style.FILL); + minMaxSpeedTextBounds = new Rect(); + + final View view = getActivity().getLayoutInflater().inflate(R.layout.split_segments_layout, container, false); + + Toolbar toolbar = (Toolbar) view.findViewById(R.id.split_interval_toolbar); + TextView titleTextView = (TextView) toolbar.findViewById(R.id.title); + if (app.getSettings().isLightContent()) { + titleTextView.setTextAppearance(getContext(), R.style.Widget_Styled_LightActionBarHeader); + } else { + titleTextView.setTextAppearance(getContext(), R.style.TextAppearance_AppCompat_Widget_ActionBar_Title); + } + ActionBar trackActivityActionBar = getTrackActivity().getSupportActionBar(); + if (trackActivityActionBar != null) { + titleTextView.setText(trackActivityActionBar.getTitle()); + } + toolbar.setNavigationIcon(getMyApplication().getIconsCache().getIcon(R.drawable.ic_arrow_back)); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + + progressBar = view.findViewById(R.id.progress_bar); + + listView = (ListView) view.findViewById(R.id.list); + listView.setDivider(null); + listView.setDividerHeight(0); + + adapter = new SplitSegmentsAdapter(new ArrayList()); + headerView = view.findViewById(R.id.header_layout); + ((ImageView) headerView.findViewById(R.id.header_split_image)).setImageDrawable(ic.getIcon(R.drawable.ic_action_split_interval, app.getSettings().isLightContent() ? R.color.icon_color : 0)); + + listView.addHeaderView(getActivity().getLayoutInflater().inflate(R.layout.gpx_split_segments_empty_header, null, false)); + listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false)); + + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + int previousYPos = -1; + + @Override + public void onScrollStateChanged(AbsListView absListView, int i) { + if (i == SCROLL_STATE_IDLE) { + previousYPos = -1; + } + } + + @Override + public void onScroll(AbsListView absListView, int i, int i1, int i2) { + View c = absListView.getChildAt(0); + if (c != null) { + int currentYPos = -c.getTop() + absListView.getFirstVisiblePosition() * c.getHeight(); + if (previousYPos == -1) { + previousYPos = currentYPos; + } + + float yTranslationToSet = headerView.getTranslationY() + (previousYPos - currentYPos); + if (yTranslationToSet < 0 && yTranslationToSet > -headerView.getHeight()) { + headerView.setTranslationY(yTranslationToSet); + } else if (yTranslationToSet < -headerView.getHeight()) { + headerView.setTranslationY(-headerView.getHeight()); + } else if (yTranslationToSet > 0) { + headerView.setTranslationY(0); + } + + previousYPos = currentYPos; + } + } + }); + + listView.setAdapter(adapter); + + return view; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + updateContent(); + } + + private void updateHeader() { + final View splitIntervalView = headerView.findViewById(R.id.split_interval_view); + + if (getGpx() != null && !getGpx().showCurrentTrack && adapter.getCount() > 0) { + setupSplitIntervalView(splitIntervalView); + if (options.size() == 0) { + prepareSplitIntervalAdapterData(); + } + 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<>(getTrackActivity(), + 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; + GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), true, false); + final List groups = getDisplayGroups(); + if (groups.size() > 0) { + updateSplit(groups, sf); + } + popup.dismiss(); + updateSplitIntervalView(splitIntervalView); + } + }); + popup.show(); + } + }); + splitIntervalView.setVisibility(View.VISIBLE); + } else { + splitIntervalView.setVisibility(View.GONE); + } + } + + public void updateContent() { + if (getTrackActivity() != null) { + adapter.clear(); + adapter.setNotifyOnChange(false); + GpxDisplayItem overviewSegments = getOverviewSegment(); + adapter.add(overviewSegments); + List splitSegments = getSplitSegments(); + adapter.addAll(splitSegments); + adapter.notifyDataSetChanged(); + listView.setSelection(0); + headerView.setTranslationY(0); + updateHeader(); + } + } + + private void updateSplit(List groups, GpxSelectionHelper.SelectedGpxFile sf) { + new SplitTrackAsyncTask(sf, groups).execute((Void) null); + } + + 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 = getDisplayGroups(); + 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 GPXUtilities.GPXFile getGpx() { + return getTrackActivity().getGpx(); + } + + public TrackActivity getTrackActivity() { + return (TrackActivity) getActivity(); + } + + private void prepareSplitIntervalAdapterData() { + final List groups = getDisplayGroups(); + + 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); + addOptionSplit(1800, false, groups); + addOptionSplit(3600, false, groups); + } + + private List getDisplayGroups() { + return filterGroups(true); + } + + 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; + } + } 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; + } + } + } + + private List filterGroups(boolean useDisplayGroups) { + List groups = new ArrayList<>(); + if (getTrackActivity() != null) { + List result = getTrackActivity().getGpxFile(useDisplayGroups); + for (GpxDisplayGroup group : result) { + boolean add = hasFilterType(group.getType()); + if (isArgumentTrue(ARG_TO_FILTER_SHORT_TRACKS)) { + Iterator item = group.getModifiableList().iterator(); + while (item.hasNext()) { + GpxDisplayItem it2 = item.next(); + if (it2.analysis != null && it2.analysis.totalDistance < 100) { + item.remove(); + } + } + if (group.getModifiableList().isEmpty()) { + add = false; + } + } + if (add) { + groups.add(group); + } + + } + } + return groups; + } + + private List getSplitSegments() { + List result = getTrackActivity().getGpxFile(true); + List splitSegments = new ArrayList<>(); + if (result != null && result.size() > 0) { + if (result.get(0).isSplitDistance() || result.get(0).isSplitTime()) { + splitSegments.addAll(result.get(0).getModifiableList()); + } + } + return splitSegments; + } + + private GpxDisplayItem getOverviewSegment() { + List result = getTrackActivity().getGpxFile(false); + GpxDisplayItem overviewSegment = null; + if (result.size() > 0) { + overviewSegment = result.get(0).getModifiableList().get(0); + } + return overviewSegment; + } + + private boolean isArgumentTrue(@NonNull String arg) { + return getArguments() != null && getArguments().getBoolean(arg); + } + + protected boolean hasFilterType(GpxDisplayItemType filterType) { + for (GpxDisplayItemType type : filterTypes) { + if (type == filterType) { + return true; + } + } + return false; + } + + @Override + public void dismiss() { + getTrackActivity().updateSplitView(); + super.dismiss(); + } + + @Override + public void onCancel(DialogInterface dialog) { + getTrackActivity().updateSplitView(); + super.onCancel(dialog); + } + + private class SplitSegmentsAdapter extends ArrayAdapter { + + SplitSegmentsAdapter(List items) { + super(getActivity(), 0, items); + } + + ColorStateList defaultTextColor; + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + GpxDisplayItem currentGpxDisplayItem = getItem(position); + if (convertView == null) { + convertView = getTrackActivity().getLayoutInflater().inflate(R.layout.gpx_split_segment_fragment, parent, false); + } + convertView.setOnClickListener(null); + TextView overviewTextView = (TextView) convertView.findViewById(R.id.overview_text); + ImageView overviewImageView = (ImageView) convertView.findViewById(R.id.overview_image); + if (position == 0) { + overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + if (defaultTextColor == null) { + defaultTextColor = overviewTextView.getTextColors(); + } + overviewTextView.setTextColor(defaultTextColor); + overviewTextView.setText(app.getString(R.string.shared_string_overview)); + if (currentGpxDisplayItem != null) { + ((TextView) convertView.findViewById(R.id.fragment_count_text)).setText(app.getString(R.string.shared_string_time_span) + ": " + Algorithms.formatDuration((int) (currentGpxDisplayItem.analysis.timeSpan / 1000), app.accessibilityEnabled())); + } + } else { + if (currentGpxDisplayItem != null && currentGpxDisplayItem.analysis != null) { + overviewTextView.setTextColor(app.getSettings().isLightContent() ? app.getResources().getColor(R.color.gpx_split_overview_light) : app.getResources().getColor(R.color.gpx_split_overview_dark)); + if (currentGpxDisplayItem.group.isSplitDistance()) { + overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_overview_light : R.color.gpx_split_overview_dark)); + overviewTextView.setText(""); + double metricStart = currentGpxDisplayItem.analysis.metricEnd - currentGpxDisplayItem.analysis.totalDistance; + overviewTextView.append(OsmAndFormatter.getFormattedDistance((float) metricStart, app)); + overviewTextView.append(" - "); + overviewTextView.append(OsmAndFormatter.getFormattedDistance((float) currentGpxDisplayItem.analysis.metricEnd, app)); + } else if (currentGpxDisplayItem.group.isSplitTime()) { + overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_overview_light : R.color.gpx_split_overview_dark)); + overviewTextView.setText(""); + double metricStart = currentGpxDisplayItem.analysis.metricEnd - (currentGpxDisplayItem.analysis.timeSpan / 1000); + overviewTextView.append(OsmAndFormatter.getFormattedDuration((int) metricStart, app)); + overviewTextView.append(" - "); + overviewTextView.append(OsmAndFormatter.getFormattedDuration((int) currentGpxDisplayItem.analysis.metricEnd, app)); + } + ((TextView) convertView.findViewById(R.id.fragment_count_text)).setText(app.getString(R.string.of, position, adapter.getCount() - 1)); + } + } + + ((ImageView) convertView.findViewById(R.id.start_time_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_start_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.end_time_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_end_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.average_altitude_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_average_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.altitude_range_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_range_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.ascent_descent_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_descent_ascent_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.moving_time_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_moving_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.average_speed_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_speed_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + ((ImageView) convertView.findViewById(R.id.max_speed_image)) + .setImageDrawable(ic.getIcon(R.drawable.ic_action_max_speed_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + + if (currentGpxDisplayItem != null) { + GPXTrackAnalysis analysis = currentGpxDisplayItem.analysis; + if (analysis != null) { + ImageView distanceOrTimeSpanImageView = ((ImageView) convertView.findViewById(R.id.distance_or_timespan_image)); + TextView distanceOrTimeSpanValue = (TextView) convertView.findViewById(R.id.distance_or_time_span_value); + TextView distanceOrTimeSpanText = (TextView) convertView.findViewById(R.id.distance_or_time_span_text); + if (position == 0) { + distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + distanceOrTimeSpanValue.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app)); + distanceOrTimeSpanText.setText(app.getString(R.string.distance)); + } else { + if (currentGpxDisplayItem.group.isSplitDistance()) { + distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + if (analysis.timeSpan > 0) { + distanceOrTimeSpanValue.setText(Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled())); + } else { + distanceOrTimeSpanValue.setText("-"); + } + distanceOrTimeSpanText.setText(app.getString(R.string.shared_string_time_span)); + } else if (currentGpxDisplayItem.group.isSplitTime()) { + distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); + distanceOrTimeSpanValue.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app)); + distanceOrTimeSpanText.setText(app.getString(R.string.distance)); + } + } + + TextView startTimeValue = (TextView) convertView.findViewById(R.id.start_time_value); + TextView startDateValue = (TextView) convertView.findViewById(R.id.start_date_value); + TextView endTimeValue = (TextView) convertView.findViewById(R.id.end_time_value); + TextView endDateValue = (TextView) convertView.findViewById(R.id.end_date_value); + if (analysis.timeSpan > 0) { + DateFormat tf = SimpleDateFormat.getTimeInstance(DateFormat.SHORT); + DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); + + Date start = new Date(analysis.startTime); + startTimeValue.setText(tf.format(start)); + startDateValue.setText(df.format(start)); + + Date end = new Date(analysis.endTime); + endTimeValue.setText(tf.format(end)); + endDateValue.setText(df.format(end)); + } else { + startTimeValue.setText("-"); + startDateValue.setText("-"); + endTimeValue.setText("-"); + endDateValue.setText("-"); + } + + View elevationDivider = convertView.findViewById(R.id.elevation_divider); + View elevationSection = convertView.findViewById(R.id.elevation_layout); + if (analysis.hasElevationData) { + elevationDivider.setVisibility(View.VISIBLE); + elevationSection.setVisibility(View.VISIBLE); + + ((TextView) convertView.findViewById(R.id.average_altitude_value)) + .setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app)); + + String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app); + String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app); + String min_max_elevation = min.substring(0, min.indexOf(" ")).concat("/").concat(max); + if (min_max_elevation.length() > 9) { + (convertView.findViewById(R.id.min_altitude_value)) + .setVisibility(View.VISIBLE); + (convertView.findViewById(R.id.max_altitude_value)) + .setVisibility(View.VISIBLE); + ((TextView) convertView.findViewById(R.id.min_altitude_value)) + .setText(min); + ((TextView) convertView.findViewById(R.id.max_altitude_value)) + .setText(max); + (convertView.findViewById(R.id.min_max_altitude_value)) + .setVisibility(View.GONE); + } else { + (convertView.findViewById(R.id.min_max_altitude_value)) + .setVisibility(View.VISIBLE); + ((TextView) convertView.findViewById(R.id.min_max_altitude_value)) + .setText(min_max_elevation); + (convertView.findViewById(R.id.min_altitude_value)) + .setVisibility(View.GONE); + (convertView.findViewById(R.id.max_altitude_value)) + .setVisibility(View.GONE); + } + + TextView ascentValue = (TextView) convertView.findViewById(R.id.ascent_value); + TextView descentValue = (TextView) convertView.findViewById(R.id.descent_value); + TextView ascentDescentValue = (TextView) convertView.findViewById(R.id.ascent_descent_value); + + String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); + String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + String asc_desc = asc.substring(0, asc.indexOf(" ")).concat("/").concat(desc); + if (asc_desc.length() > 9) { + ascentValue.setVisibility(View.VISIBLE); + descentValue.setVisibility(View.VISIBLE); + ascentValue.setText(asc); + descentValue.setText(desc); + ascentDescentValue.setVisibility(View.GONE); + } else { + ascentDescentValue.setVisibility(View.VISIBLE); + ascentDescentValue.setText(asc_desc); + ascentValue.setVisibility(View.GONE); + descentValue.setVisibility(View.GONE); + } + + } else { + elevationDivider.setVisibility(View.GONE); + elevationSection.setVisibility(View.GONE); + } + + View speedDivider = convertView.findViewById(R.id.speed_divider); + View speedSection = convertView.findViewById(R.id.speed_layout); + if (analysis.hasSpeedData) { + speedDivider.setVisibility(View.VISIBLE); + speedSection.setVisibility(View.VISIBLE); + + ((TextView) convertView.findViewById(R.id.moving_time_value)) + .setText(Algorithms.formatDuration((int) (analysis.timeMoving / 1000), app.accessibilityEnabled())); + ((TextView) convertView.findViewById(R.id.average_speed_value)) + .setText(OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app)); + + String maxSpeed = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); + String minSpeed = OsmAndFormatter.getFormattedSpeed(analysis.minSpeed, app); + String maxMinSpeed; + if (maxSpeed.contains(" ")) { + maxMinSpeed = maxSpeed.substring(0, maxSpeed.indexOf(" ")).concat("/").concat(minSpeed); + } else { + maxMinSpeed = maxSpeed.substring(0, maxSpeed.indexOf("-")).concat("/").concat(minSpeed); + } + + if (minMaxSpeedLayoutWidth == 0) { + DisplayMetrics metrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); + int screenWidth = metrics.widthPixels; + int widthWithoutSidePadding = screenWidth - AndroidUtils.dpToPx(getActivity(), 32); + int singleLayoutWidth = widthWithoutSidePadding / 3; + int twoLayouts = 2 * (singleLayoutWidth + AndroidUtils.dpToPx(getActivity(), 3)); + minMaxSpeedLayoutWidth = widthWithoutSidePadding - twoLayouts - AndroidUtils.dpToPx(getActivity(), 28); + } + + minMaxSpeedPaint.getTextBounds(maxMinSpeed, 0, maxMinSpeed.length(), minMaxSpeedTextBounds); + int minMaxStringWidth = minMaxSpeedTextBounds.width(); + + if (analysis.minSpeed == 0) { + (convertView.findViewById(R.id.max_speed_value)) + .setVisibility(View.VISIBLE); + (convertView.findViewById(R.id.min_speed_value)) + .setVisibility(View.GONE); + ((TextView) convertView.findViewById(R.id.max_speed_value)) + .setText(maxSpeed); + (convertView.findViewById(R.id.max_min_speed_value)) + .setVisibility(View.GONE); + ((TextView) convertView.findViewById(R.id.max_min_speed_text)) + .setText(app.getString(R.string.shared_string_max)); + } else if (minMaxStringWidth > minMaxSpeedLayoutWidth) { + (convertView.findViewById(R.id.max_speed_value)) + .setVisibility(View.VISIBLE); + (convertView.findViewById(R.id.min_speed_value)) + .setVisibility(View.VISIBLE); + ((TextView) convertView.findViewById(R.id.max_speed_value)) + .setText(maxSpeed); + ((TextView) convertView.findViewById(R.id.min_speed_value)) + .setText(minSpeed); + (convertView.findViewById(R.id.max_min_speed_value)) + .setVisibility(View.GONE); + ((TextView) convertView.findViewById(R.id.max_min_speed_text)) + .setText(app.getString(R.string.max_min)); + } else { + (convertView.findViewById(R.id.max_min_speed_value)) + .setVisibility(View.VISIBLE); + ((TextView) convertView.findViewById(R.id.max_min_speed_value)) + .setText(maxMinSpeed); + (convertView.findViewById(R.id.max_speed_value)) + .setVisibility(View.GONE); + (convertView.findViewById(R.id.min_speed_value)) + .setVisibility(View.GONE); + ((TextView) convertView.findViewById(R.id.max_min_speed_text)) + .setText(app.getString(R.string.max_min)); + } + } else { + speedDivider.setVisibility(View.GONE); + speedSection.setVisibility(View.GONE); + } + } + } + return convertView; + } + } + + private class SplitTrackAsyncTask extends AsyncTask { + @Nullable + private final GpxSelectionHelper.SelectedGpxFile mSelectedGpxFile; + + private final List groups; + + SplitTrackAsyncTask(@Nullable GpxSelectionHelper.SelectedGpxFile selectedGpxFile, List groups) { + mSelectedGpxFile = selectedGpxFile; + this.groups = groups; + } + + protected void onPreExecute() { + progressBar.setVisibility(View.VISIBLE); + } + + protected void onPostExecute(Void result) { + progressBar.setVisibility(View.GONE); + if (mSelectedGpxFile != null) { + List groups = getDisplayGroups(); + mSelectedGpxFile.setDisplayGroups(groups); + } + updateContent(); + } + + @Override + protected Void doInBackground(Void... params) { + for (GpxDisplayGroup model : groups) { + if (selectedSplitInterval == 0) { + model.noSplit(app); + } else if (distanceSplit.get(selectedSplitInterval) > 0) { + model.splitByDistance(app, distanceSplit.get(selectedSplitInterval)); + } else if (timeSplit.get(selectedSplitInterval) > 0) { + model.splitByTime(app, timeSplit.get(selectedSplitInterval)); + } + } + + return null; + } + } + + private OsmandApplication getMyApplication() { + return (OsmandApplication) getActivity().getApplication(); + } + + public static boolean showInstance(TrackActivity trackActivity) { + try { + SplitSegmentDialogFragment fragment = new SplitSegmentDialogFragment(); + fragment.show(trackActivity.getSupportFragmentManager(), TAG); + return true; + } catch (RuntimeException e) { + return false; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentFragment.java deleted file mode 100644 index 9edec0db4a..0000000000 --- a/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentFragment.java +++ /dev/null @@ -1,690 +0,0 @@ -package net.osmand.plus.myplaces; - -import android.content.res.ColorStateList; -import android.graphics.Paint; -import android.graphics.Rect; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.widget.ListPopupWindow; -import android.util.DisplayMetrics; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -import net.osmand.AndroidUtils; -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.GpxDisplayItemType; -import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; -import net.osmand.plus.IconsCache; -import net.osmand.plus.OsmAndFormatter; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.activities.TrackActivity; -import net.osmand.plus.base.OsmAndListFragment; -import net.osmand.plus.helpers.FontCache; -import net.osmand.util.Algorithms; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -import gnu.trove.list.array.TIntArrayList; - -import static net.osmand.plus.myplaces.TrackSegmentFragment.ARG_TO_FILTER_SHORT_TRACKS; - -public class SplitSegmentFragment extends OsmAndListFragment { - - public final static String TAG = "SPLIT_SEGMENT_FRAGMENT"; - private OsmandApplication app; - - private SplitSegmentsAdapter adapter; - private View headerView; - - private GpxDisplayItemType[] filterTypes = { GpxDisplayItemType.TRACK_SEGMENT }; - private List options = new ArrayList<>(); - private List distanceSplit = new ArrayList<>(); - private TIntArrayList timeSplit = new TIntArrayList(); - private int selectedSplitInterval; - private IconsCache ic; - private int minMaxSpeedLayoutWidth; - private Paint minMaxSpeedPaint; - private Rect minMaxSpeedTextBounds; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - app = getMyApplication(); - ic = app.getIconsCache(); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - updateContent(); - // Obsolete: updateHeader(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getListView().setBackgroundColor(getResources().getColor( - getMyApplication().getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light - : R.color.ctx_menu_info_view_bg_dark)); - getTrackActivity().onAttachFragment(this); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.clear(); - getTrackActivity().getClearToolbar(false); - } - - @Override - public ArrayAdapter getAdapter() { - return adapter; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - setHasOptionsMenu(true); - - minMaxSpeedPaint = new Paint(); - minMaxSpeedPaint.setTextSize(getResources().getDimension(R.dimen.default_split_segments_data)); - minMaxSpeedPaint.setTypeface(FontCache.getFont(getContext(), "fonts/Roboto-Medium.ttf")); - minMaxSpeedPaint.setStyle(Paint.Style.FILL); - minMaxSpeedTextBounds = new Rect(); - - final View view = getActivity().getLayoutInflater().inflate(R.layout.split_segments_layout, container, false); - - final ListView listView = (ListView) view.findViewById(android.R.id.list); - listView.setDivider(null); - listView.setDividerHeight(0); - - adapter = new SplitSegmentsAdapter(new ArrayList()); - headerView = view.findViewById(R.id.header_layout); - ((ImageView) headerView.findViewById(R.id.header_split_image)).setImageDrawable(ic.getIcon(R.drawable.ic_action_split_interval, app.getSettings().isLightContent() ? R.color.icon_color : 0)); - - listView.addHeaderView(getActivity().getLayoutInflater().inflate(R.layout.gpx_split_segments_empty_header, null, false)); - listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false)); - - setListAdapter(adapter); - - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - int previousYPos = -1; - - @Override - public void onScrollStateChanged(AbsListView absListView, int i) { - if (i == SCROLL_STATE_IDLE) { - previousYPos = -1; - } - } - - @Override - public void onScroll(AbsListView absListView, int i, int i1, int i2) { - View c = absListView.getChildAt(0); - if (c != null) { - int currentYPos = -c.getTop() + absListView.getFirstVisiblePosition() * c.getHeight(); - if (previousYPos == -1) { - previousYPos = currentYPos; - } - - float yTranslationToSet = headerView.getTranslationY() + (previousYPos - currentYPos); - if (yTranslationToSet < 0 && yTranslationToSet > -headerView.getHeight()) { - headerView.setTranslationY(yTranslationToSet); - } else if (yTranslationToSet < -headerView.getHeight()) { - headerView.setTranslationY(-headerView.getHeight()); - } else if (yTranslationToSet > 0) { - headerView.setTranslationY(0); - } - - previousYPos = currentYPos; - } - } - }); - - return view; - } - - private void updateHeader() { - final View splitIntervalView = headerView.findViewById(R.id.split_interval_view); - - if (getGpx() != null && !getGpx().showCurrentTrack && adapter.getCount() > 0) { - setupSplitIntervalView(splitIntervalView); - if (options.size() == 0) { - prepareSplitIntervalAdapterData(); - } - 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<>(getTrackActivity(), - 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; - GpxSelectionHelper.SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), true, false); - final List groups = getDisplayGroups(); - if (groups.size() > 0) { - updateSplit(groups, sf); - } - popup.dismiss(); - updateSplitIntervalView(splitIntervalView); - } - }); - popup.show(); - } - }); - splitIntervalView.setVisibility(View.VISIBLE); - } else { - splitIntervalView.setVisibility(View.GONE); - } - } - - public void updateContent() { - adapter.clear(); - adapter.setNotifyOnChange(false); - GpxDisplayItem overviewSegments = getOverviewSegment(); - adapter.add(overviewSegments); - List splitSegments = getSplitSegments(); - adapter.addAll(splitSegments); - // Obsolete: adapter.setNotifyOnChange(true); - adapter.notifyDataSetChanged(); - getListView().setSelection(0); - headerView.setTranslationY(0); - updateHeader(); - } - - private void updateSplit(List groups, GpxSelectionHelper.SelectedGpxFile sf) { - new SplitTrackAsyncTask(sf, groups).execute((Void) null); - } - - 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 = getDisplayGroups(); - 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 GPXUtilities.GPXFile getGpx() { - return getTrackActivity().getGpx(); - } - - public TrackActivity getTrackActivity() { - return (TrackActivity) getActivity(); - } - - private void prepareSplitIntervalAdapterData() { - final List groups = getDisplayGroups(); - - 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); - addOptionSplit(1800, false, groups); - addOptionSplit(3600, false, groups); - } - - private List getDisplayGroups() { - return filterGroups(true); - } - - 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; - } - } 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; - } - } - } - - private List filterGroups(boolean useDisplayGroups) { - List groups = new ArrayList<>(); - if (getTrackActivity() != null) { - List result = getTrackActivity().getGpxFile(useDisplayGroups); - for (GpxDisplayGroup group : result) { - boolean add = hasFilterType(group.getType()); - if (isArgumentTrue(ARG_TO_FILTER_SHORT_TRACKS)) { - Iterator item = group.getModifiableList().iterator(); - while (item.hasNext()) { - GpxDisplayItem it2 = item.next(); - if (it2.analysis != null && it2.analysis.totalDistance < 100) { - item.remove(); - } - } - if (group.getModifiableList().isEmpty()) { - add = false; - } - } - if (add) { - groups.add(group); - } - - } - } - return groups; - } - - private List getSplitSegments() { - List result = getTrackActivity().getGpxFile(true); - List splitSegments = new ArrayList<>(); - if (result != null && result.size() > 0) { - if (result.get(0).isSplitDistance() || result.get(0).isSplitTime()) { - splitSegments.addAll(result.get(0).getModifiableList()); - } - } - return splitSegments; - } - - private GpxDisplayItem getOverviewSegment() { - List result = getTrackActivity().getGpxFile(false); - GpxDisplayItem overviewSegment = null; - if (result.size() > 0) { - overviewSegment = result.get(0).getModifiableList().get(0); - } - return overviewSegment; - } - - private boolean isArgumentTrue(@NonNull String arg) { - return getArguments() != null && getArguments().getBoolean(arg); - } - - protected boolean hasFilterType(GpxDisplayItemType filterType) { - for (GpxDisplayItemType type : filterTypes) { - if (type == filterType) { - return true; - } - } - return false; - } - - public void reloadSplitFragment() { - getFragmentManager() - .beginTransaction() - .detach(this) - .attach(this) - .commit(); - } - - private class SplitSegmentsAdapter extends ArrayAdapter { - - SplitSegmentsAdapter(List items) { - super(getActivity(), 0, items); - } - - ColorStateList defaultTextColor; - - @NonNull - @Override - public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { - GpxDisplayItem currentGpxDisplayItem = getItem(position); - if (convertView == null) { - convertView = getTrackActivity().getLayoutInflater().inflate(R.layout.gpx_split_segment_fragment, parent, false); - } - convertView.setOnClickListener(null); - TextView overviewTextView = (TextView) convertView.findViewById(R.id.overview_text); - ImageView overviewImageView = (ImageView) convertView.findViewById(R.id.overview_image); - if (position == 0) { - overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - if (defaultTextColor == null) { - defaultTextColor = overviewTextView.getTextColors(); - } - overviewTextView.setTextColor(defaultTextColor); - overviewTextView.setText(app.getString(R.string.shared_string_overview)); - if (currentGpxDisplayItem != null) { - ((TextView) convertView.findViewById(R.id.fragment_count_text)).setText(app.getString(R.string.shared_string_time_span) + ": " + Algorithms.formatDuration((int) (currentGpxDisplayItem.analysis.timeSpan / 1000), app.accessibilityEnabled())); - } - } else { - if (currentGpxDisplayItem != null && currentGpxDisplayItem.analysis != null) { - overviewTextView.setTextColor(app.getSettings().isLightContent() ? app.getResources().getColor(R.color.gpx_split_overview_light) : app.getResources().getColor(R.color.gpx_split_overview_dark)); - if (currentGpxDisplayItem.group.isSplitDistance()) { - overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_overview_light : R.color.gpx_split_overview_dark)); - overviewTextView.setText(""); - double metricStart = currentGpxDisplayItem.analysis.metricEnd - currentGpxDisplayItem.analysis.totalDistance; - overviewTextView.append(OsmAndFormatter.getFormattedDistance((float) metricStart, app)); - overviewTextView.append(" - "); - overviewTextView.append(OsmAndFormatter.getFormattedDistance((float) currentGpxDisplayItem.analysis.metricEnd, app)); - } else if (currentGpxDisplayItem.group.isSplitTime()) { - overviewImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_overview_light : R.color.gpx_split_overview_dark)); - overviewTextView.setText(""); - double metricStart = currentGpxDisplayItem.analysis.metricEnd - (currentGpxDisplayItem.analysis.timeSpan / 1000); - overviewTextView.append(OsmAndFormatter.getFormattedDuration((int) metricStart, app)); - overviewTextView.append(" - "); - overviewTextView.append(OsmAndFormatter.getFormattedDuration((int) currentGpxDisplayItem.analysis.metricEnd, app)); - } - ((TextView) convertView.findViewById(R.id.fragment_count_text)).setText(app.getString(R.string.of, position, adapter.getCount() - 1)); - } - } - - ((ImageView) convertView.findViewById(R.id.start_time_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_start_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.end_time_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_end_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.average_altitude_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_average_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.altitude_range_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_range_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.ascent_descent_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_altitude_descent_ascent_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.moving_time_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_time_moving_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.average_speed_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_speed_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - ((ImageView) convertView.findViewById(R.id.max_speed_image)) - .setImageDrawable(ic.getIcon(R.drawable.ic_action_max_speed_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - - if (currentGpxDisplayItem != null) { - GPXTrackAnalysis analysis = currentGpxDisplayItem.analysis; - if (analysis != null) { - ImageView distanceOrTimeSpanImageView = ((ImageView) convertView.findViewById(R.id.distance_or_timespan_image)); - TextView distanceOrTimeSpanValue = (TextView) convertView.findViewById(R.id.distance_or_time_span_value); - TextView distanceOrTimeSpanText = (TextView) convertView.findViewById(R.id.distance_or_time_span_text); - if (position == 0) { - distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - distanceOrTimeSpanValue.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app)); - distanceOrTimeSpanText.setText(app.getString(R.string.distance)); - } else { - if (currentGpxDisplayItem.group.isSplitDistance()) { - distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_time_span_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - if (analysis.timeSpan > 0) { - distanceOrTimeSpanValue.setText(Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled())); - } else { - distanceOrTimeSpanValue.setText("-"); - } - distanceOrTimeSpanText.setText(app.getString(R.string.shared_string_time_span)); - } else if (currentGpxDisplayItem.group.isSplitTime()) { - distanceOrTimeSpanImageView.setImageDrawable(ic.getIcon(R.drawable.ic_action_track_16, app.getSettings().isLightContent() ? R.color.gpx_split_segment_icon_color : 0)); - distanceOrTimeSpanValue.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app)); - distanceOrTimeSpanText.setText(app.getString(R.string.distance)); - } - } - - TextView startTimeValue = (TextView) convertView.findViewById(R.id.start_time_value); - TextView startDateValue = (TextView) convertView.findViewById(R.id.start_date_value); - TextView endTimeValue = (TextView) convertView.findViewById(R.id.end_time_value); - TextView endDateValue = (TextView) convertView.findViewById(R.id.end_date_value); - if (analysis.timeSpan > 0) { - DateFormat tf = SimpleDateFormat.getTimeInstance(DateFormat.SHORT); - DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); - - Date start = new Date(analysis.startTime); - startTimeValue.setText(tf.format(start)); - startDateValue.setText(df.format(start)); - - Date end = new Date(analysis.endTime); - endTimeValue.setText(tf.format(end)); - endDateValue.setText(df.format(end)); - } else { - startTimeValue.setText("-"); - startDateValue.setText("-"); - endTimeValue.setText("-"); - endDateValue.setText("-"); - } - - View elevationDivider = convertView.findViewById(R.id.elevation_divider); - View elevationSection = convertView.findViewById(R.id.elevation_layout); - if (analysis.hasElevationData) { - elevationDivider.setVisibility(View.VISIBLE); - elevationSection.setVisibility(View.VISIBLE); - - ((TextView) convertView.findViewById(R.id.average_altitude_value)) - .setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app)); - - String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app); - String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app); - String min_max_elevation = min.substring(0, min.indexOf(" ")).concat("/").concat(max); - if (min_max_elevation.length() > 9) { - (convertView.findViewById(R.id.min_altitude_value)) - .setVisibility(View.VISIBLE); - (convertView.findViewById(R.id.max_altitude_value)) - .setVisibility(View.VISIBLE); - ((TextView) convertView.findViewById(R.id.min_altitude_value)) - .setText(min); - ((TextView) convertView.findViewById(R.id.max_altitude_value)) - .setText(max); - (convertView.findViewById(R.id.min_max_altitude_value)) - .setVisibility(View.GONE); - } else { - (convertView.findViewById(R.id.min_max_altitude_value)) - .setVisibility(View.VISIBLE); - ((TextView) convertView.findViewById(R.id.min_max_altitude_value)) - .setText(min_max_elevation); - (convertView.findViewById(R.id.min_altitude_value)) - .setVisibility(View.GONE); - (convertView.findViewById(R.id.max_altitude_value)) - .setVisibility(View.GONE); - } - - TextView ascentValue = (TextView) convertView.findViewById(R.id.ascent_value); - TextView descentValue = (TextView) convertView.findViewById(R.id.descent_value); - TextView ascentDescentValue = (TextView) convertView.findViewById(R.id.ascent_descent_value); - - String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); - String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); - String asc_desc = asc.substring(0, asc.indexOf(" ")).concat("/").concat(desc); - if (asc_desc.length() > 9) { - ascentValue.setVisibility(View.VISIBLE); - descentValue.setVisibility(View.VISIBLE); - ascentValue.setText(asc); - descentValue.setText(desc); - ascentDescentValue.setVisibility(View.GONE); - } else { - ascentDescentValue.setVisibility(View.VISIBLE); - ascentDescentValue.setText(asc_desc); - ascentValue.setVisibility(View.GONE); - descentValue.setVisibility(View.GONE); - } - - } else { - elevationDivider.setVisibility(View.GONE); - elevationSection.setVisibility(View.GONE); - } - - View speedDivider = convertView.findViewById(R.id.speed_divider); - View speedSection = convertView.findViewById(R.id.speed_layout); - if (analysis.hasSpeedData) { - speedDivider.setVisibility(View.VISIBLE); - speedSection.setVisibility(View.VISIBLE); - - ((TextView) convertView.findViewById(R.id.moving_time_value)) - .setText(Algorithms.formatDuration((int) (analysis.timeMoving / 1000), app.accessibilityEnabled())); - ((TextView) convertView.findViewById(R.id.average_speed_value)) - .setText(OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app)); - - String maxSpeed = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); - String minSpeed = OsmAndFormatter.getFormattedSpeed(analysis.minSpeed, app); - String maxMinSpeed; - if (maxSpeed.contains(" ")) { - maxMinSpeed = maxSpeed.substring(0, maxSpeed.indexOf(" ")).concat("/").concat(minSpeed); - } else { - maxMinSpeed = maxSpeed.substring(0, maxSpeed.indexOf("-")).concat("/").concat(minSpeed); - } - - if (minMaxSpeedLayoutWidth == 0) { - DisplayMetrics metrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); - int screenWidth = metrics.widthPixels; - int widthWithoutSidePadding = screenWidth - AndroidUtils.dpToPx(getActivity(), 32); - int singleLayoutWidth = widthWithoutSidePadding / 3; - int twoLayouts = 2 * (singleLayoutWidth + AndroidUtils.dpToPx(getActivity(), 3)); - minMaxSpeedLayoutWidth = widthWithoutSidePadding - twoLayouts - AndroidUtils.dpToPx(getActivity(), 28); - } - - minMaxSpeedPaint.getTextBounds(maxMinSpeed, 0, maxMinSpeed.length(), minMaxSpeedTextBounds); - int minMaxStringWidth = minMaxSpeedTextBounds.width(); - - if (analysis.minSpeed == 0) { - (convertView.findViewById(R.id.max_speed_value)) - .setVisibility(View.VISIBLE); - (convertView.findViewById(R.id.min_speed_value)) - .setVisibility(View.GONE); - ((TextView) convertView.findViewById(R.id.max_speed_value)) - .setText(maxSpeed); - (convertView.findViewById(R.id.max_min_speed_value)) - .setVisibility(View.GONE); - ((TextView) convertView.findViewById(R.id.max_min_speed_text)) - .setText(app.getString(R.string.shared_string_max)); - } else if (minMaxStringWidth > minMaxSpeedLayoutWidth) { - (convertView.findViewById(R.id.max_speed_value)) - .setVisibility(View.VISIBLE); - (convertView.findViewById(R.id.min_speed_value)) - .setVisibility(View.VISIBLE); - ((TextView) convertView.findViewById(R.id.max_speed_value)) - .setText(maxSpeed); - ((TextView) convertView.findViewById(R.id.min_speed_value)) - .setText(minSpeed); - (convertView.findViewById(R.id.max_min_speed_value)) - .setVisibility(View.GONE); - ((TextView) convertView.findViewById(R.id.max_min_speed_text)) - .setText(app.getString(R.string.max_min)); - } else { - (convertView.findViewById(R.id.max_min_speed_value)) - .setVisibility(View.VISIBLE); - ((TextView) convertView.findViewById(R.id.max_min_speed_value)) - .setText(maxMinSpeed); - (convertView.findViewById(R.id.max_speed_value)) - .setVisibility(View.GONE); - (convertView.findViewById(R.id.min_speed_value)) - .setVisibility(View.GONE); - ((TextView) convertView.findViewById(R.id.max_min_speed_text)) - .setText(app.getString(R.string.max_min)); - } - } else { - speedDivider.setVisibility(View.GONE); - speedSection.setVisibility(View.GONE); - } - } - } - return convertView; - } - } - - private class SplitTrackAsyncTask extends AsyncTask { - @Nullable - private final GpxSelectionHelper.SelectedGpxFile mSelectedGpxFile; - @NonNull private final TrackActivity mActivity; - - private final List groups; - - SplitTrackAsyncTask(@Nullable GpxSelectionHelper.SelectedGpxFile selectedGpxFile, List groups) { - mSelectedGpxFile = selectedGpxFile; - mActivity = getTrackActivity(); - this.groups = groups; - } - - protected void onPostExecute(Void result) { - if (!mActivity.isFinishing()) { - mActivity.setSupportProgressBarIndeterminateVisibility(false); - } - if (mSelectedGpxFile != null) { - List groups = getDisplayGroups(); - mSelectedGpxFile.setDisplayGroups(groups); - } - updateContent(); - } - - protected void onPreExecute() { - mActivity.setSupportProgressBarIndeterminateVisibility(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/myplaces/TrackSegmentFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java index a84e07a802..ba5ec52e89 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackSegmentFragment.java @@ -124,7 +124,7 @@ public class TrackSegmentFragment extends OsmAndListFragment { private OsmandApplication app; private SegmentGPXAdapter adapter; - private GpxDisplayItemType[] filterTypes = { GpxSelectionHelper.GpxDisplayItemType.TRACK_SEGMENT }; + private GpxDisplayItemType[] filterTypes = {GpxSelectionHelper.GpxDisplayItemType.TRACK_SEGMENT}; private List options = new ArrayList<>(); private List distanceSplit = new ArrayList<>(); private TIntArrayList timeSplit = new TIntArrayList(); @@ -638,10 +638,10 @@ public class TrackSegmentFragment extends OsmAndListFragment { public void updateSplitView() { if (getGpx() != null) { - SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), ((SwitchCompat)headerView.findViewById(R.id.showOnMapToggle)).isChecked(), false); + SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), ((SwitchCompat) headerView.findViewById(R.id.showOnMapToggle)).isChecked(), false); final List groups = getDisplayGroups(); if (groups.size() > 0) { - updateSplit(groups, ((SwitchCompat)headerView.findViewById(R.id.showOnMapToggle)).isChecked() ? sf : null); + updateSplit(groups, ((SwitchCompat) headerView.findViewById(R.id.showOnMapToggle)).isChecked() ? sf : null); if (getGpxDataItem() != null) { updateSplitInDatabase(); } @@ -840,7 +840,6 @@ public class TrackSegmentFragment extends OsmAndListFragment { for (GpxDisplayItem i : flatten(groups)) { adapter.add(i); } - // Obsolete: adapter.setNotifyOnChange(true); adapter.notifyDataSetChanged(); if (getActivity() != null) { updateHeader(); @@ -849,7 +848,7 @@ public class TrackSegmentFragment extends OsmAndListFragment { protected List flatten(List groups) { ArrayList list = new ArrayList<>(); - for(GpxDisplayGroup g : groups) { + for (GpxDisplayGroup g : groups) { list.addAll(g.getModifiableList()); } return list; @@ -1645,7 +1644,7 @@ public class TrackSegmentFragment extends OsmAndListFragment { @Override public void select(View tab) { - GPXTabItemType tabType = GPXTabItemType.valueOf((String)tab.getTag()); + GPXTabItemType tabType = GPXTabItemType.valueOf((String) tab.getTag()); ImageView img = (ImageView) tab.findViewById(R.id.tab_image); int imageId = getImageId(tabType); switch (tabs.getTabSelectionType()) { @@ -1660,7 +1659,7 @@ public class TrackSegmentFragment extends OsmAndListFragment { @Override public void deselect(View tab) { - GPXTabItemType tabType = GPXTabItemType.valueOf((String)tab.getTag()); + GPXTabItemType tabType = GPXTabItemType.valueOf((String) tab.getTag()); ImageView img = (ImageView) tab.findViewById(R.id.tab_image); int imageId = getImageId(tabType); switch (tabs.getTabSelectionType()) { @@ -1773,12 +1772,7 @@ public class TrackSegmentFragment extends OsmAndListFragment { } void openSplitIntervalScreen() { - getTrackActivity().getSupportFragmentManager() - .beginTransaction() - .replace(R.id.track_activity_layout, new SplitSegmentFragment()) - .addToBackStack(SplitSegmentFragment.TAG) - .commit(); - getTrackActivity().getSlidingTabLayout().setVisibility(View.GONE); + SplitSegmentDialogFragment.showInstance(getTrackActivity()); } private class SaveGpxAsyncTask extends AsyncTask { @@ -1820,8 +1814,10 @@ public class TrackSegmentFragment extends OsmAndListFragment { private class SplitTrackAsyncTask extends AsyncTask { @Nullable private final SelectedGpxFile mSelectedGpxFile; - @NonNull private final TrackSegmentFragment mFragment; - @NonNull private final TrackActivity mActivity; + @NonNull + private final TrackSegmentFragment mFragment; + @NonNull + private final TrackActivity mActivity; private final List groups;