<NME> NavigateAnyPointActivity.java
<BEF> package cgeo.geocaching;

import cgeo.geocaching.activity.AbstractActionBarActivity;
import cgeo.geocaching.activity.INavigationSource;
import cgeo.geocaching.apps.navi.NavigationAppFactory;
import cgeo.geocaching.location.DistanceParser;
import cgeo.geocaching.location.Geopoint;
import cgeo.geocaching.location.GeopointFormatter;
import cgeo.geocaching.models.Destination;
import cgeo.geocaching.permission.PermissionHandler;
import cgeo.geocaching.permission.PermissionRequestContext;
import cgeo.geocaching.permission.RestartLocationPermissionGrantedCallback;
import cgeo.geocaching.sensors.GeoData;
import cgeo.geocaching.sensors.GeoDirHandler;
import cgeo.geocaching.sensors.Sensors;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.storage.DataStore;
import cgeo.geocaching.ui.AbstractViewHolder;
import cgeo.geocaching.ui.NavigationActionProvider;
import cgeo.geocaching.ui.dialog.CoordinatesInputDialog;
import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.AndroidRxUtils;
import cgeo.geocaching.utils.Formatter;
import cgeo.geocaching.utils.Log;

import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.StringUtils;

public class NavigateAnyPointActivity extends AbstractActionBarActivity implements CoordinatesInputDialog.CoordinateUpdate, INavigationSource {

    @BindView(R.id.historyList) protected ListView historyListView;

    // list header fields are optional, due to being expanded later than the list itself
    @Nullable @BindView(R.id.buttonLatitude) protected Button latButton;
    @Nullable @BindView(R.id.buttonLongitude) protected Button lonButton;
    @Nullable @BindView(R.id.distance) protected EditText distanceEditText;
    @Nullable @BindView(R.id.distanceUnit) protected Spinner distanceUnitSelector;
    @Nullable @BindView(R.id.current) protected Button buttonCurrent;
    @Nullable @BindView(R.id.bearing) protected EditText bearingEditText;

    private boolean changed = false;
    private List<Destination> historyOfSearchedLocations;
    private DestinationHistoryAdapter destinationHistoryAdapter;
    private TextView historyFooter;

    private static final int CONTEXT_MENU_NAVIGATE = 1;
    private static final int CONTEXT_MENU_DELETE_WAYPOINT = 2;
    private static final int CONTEXT_MENU_EDIT_WAYPOINT = 3;

    private int contextMenuItemPosition;

    private DistanceParser.DistanceUnit distanceUnit = DistanceParser.DistanceUnit.M;

    protected static class ViewHolder extends AbstractViewHolder {
        @BindView(R.id.simple_way_point_longitude) protected TextView longitude;
        @BindView(R.id.simple_way_point_latitude) protected TextView latitude;
        @BindView(R.id.date) protected TextView date;

        public ViewHolder(final View rowView) {
            super(rowView);
        }
    }

    private static class DestinationHistoryAdapter extends ArrayAdapter<Destination> {
        private LayoutInflater inflater = null;

        DestinationHistoryAdapter(final Context context,
                final List<Destination> objects) {
            super(context, 0, objects);
        }

        @Override
        public View getView(final int position, final View convertView, final ViewGroup parent) {
            View rowView = convertView;

            final ViewHolder viewHolder;
            if (rowView == null) {
                rowView = getInflater().inflate(R.layout.simple_way_point, parent, false);
                viewHolder = new ViewHolder(rowView);
            } else {
                viewHolder = (ViewHolder) rowView.getTag();
            }

            fillViewHolder(viewHolder, getItem(position));

            return rowView;
        }

        private static void fillViewHolder(final ViewHolder viewHolder, final Destination loc) {
            final String lonString = loc.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE);
            final String latString = loc.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE);

            viewHolder.longitude.setText(lonString);
            viewHolder.latitude.setText(latString);
            viewHolder.date.setText(Formatter.formatShortDateTime(loc.getDate()));
        }

        private LayoutInflater getInflater() {
            if (inflater == null) {
                inflater = LayoutInflater.from(getContext());
            }

            return inflater;
        }
    }

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState, R.layout.navigateanypoint_activity);
        ButterKnife.bind(this);

        createHistoryView();
        init();
    }

    private void createHistoryView() {
        final View pointControls = getLayoutInflater().inflate(R.layout.navigateanypoint_header, historyListView, false);
        historyListView.addHeaderView(pointControls, null, false);

        // inject a second time to also find the dynamically expanded views above
        ButterKnife.bind(this);

        if (getHistoryOfSearchedLocations().isEmpty()) {
            historyListView.addFooterView(getEmptyHistoryFooter(), null, false);
        }

        historyListView.setAdapter(getDestinationHistoryAdapter());
        historyListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(final AdapterView<?> arg0, final View arg1, final int arg2,
                    final long arg3) {
                final Object selection = arg0.getItemAtPosition(arg2);
                if (selection instanceof Destination) {
                    navigateTo(((Destination) selection).getCoords());
                }
            }
        });

        historyListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
            @Override
            public void onCreateContextMenu(final ContextMenu menu, final View v,
                    final ContextMenuInfo menuInfo) {
                menu.add(Menu.NONE, CONTEXT_MENU_NAVIGATE, Menu.NONE, res.getString(R.string.cache_menu_navigate));
                menu.add(Menu.NONE, CONTEXT_MENU_EDIT_WAYPOINT, Menu.NONE, R.string.waypoint_edit);
                menu.add(Menu.NONE, CONTEXT_MENU_DELETE_WAYPOINT, Menu.NONE, R.string.waypoint_delete);
            }
        });
    }

    @Override
    public boolean onContextItemSelected(final MenuItem item) {
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        final int position = menuInfo != null ? menuInfo.position : contextMenuItemPosition;
        final Object destination = historyListView.getItemAtPosition(position);

        switch (item.getItemId()) {
            case CONTEXT_MENU_NAVIGATE:
                contextMenuItemPosition = position;
                if (destination instanceof Destination) {
                    NavigationAppFactory.showNavigationMenu(this, null, null, ((Destination) destination).getCoords());
                    return true;
                }
                break;

            case CONTEXT_MENU_DELETE_WAYPOINT:
                if (destination instanceof Destination) {
                    removeFromHistory((Destination) destination);
                }
                return true;

            case CONTEXT_MENU_EDIT_WAYPOINT:
                if (destination instanceof Destination) {
                    final Geopoint gp = ((Destination) destination).getCoords();
                    getLatButton().setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE));
                    getLonButton().setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE));
                }
                return true;
            default:
        }

        return super.onContextItemSelected(item);
    }

    private TextView getEmptyHistoryFooter() {
        if (historyFooter == null) {
            historyFooter = (TextView) getLayoutInflater().inflate(R.layout.cacheslist_footer, historyListView, false);
            historyFooter.setText(R.string.search_history_empty);
        }
        return historyFooter;
    }

    private DestinationHistoryAdapter getDestinationHistoryAdapter() {
        if (destinationHistoryAdapter == null) {
            destinationHistoryAdapter = new DestinationHistoryAdapter(this, getHistoryOfSearchedLocations());
        }
        return destinationHistoryAdapter;
    }

    private List<Destination> getHistoryOfSearchedLocations() {
        if (historyOfSearchedLocations == null) {
            // Load from database
            historyOfSearchedLocations = DataStore.loadHistoryOfSearchedLocations();
        }

        return historyOfSearchedLocations;
    }

    @Override
    public void onConfigurationChanged(final Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        init();
    }

    @Override
    public void onResume() {
        super.onResume();

        // resume location access
        PermissionHandler.executeIfLocationPermissionGranted(this,
                new RestartLocationPermissionGrantedCallback(PermissionRequestContext.NavigateAnyPointActivity) {

                    @Override
                    public void executeAfter() {
                        resumeDisposables(geoDirHandler.start(GeoDirHandler.UPDATE_GEODATA));
                    }
                });

        init();
    }

    private void init() {
        getLatButton().setOnClickListener(new CoordDialogListener());
        getLonButton().setOnClickListener(new CoordDialogListener());

        final Geopoint coords = Settings.getAnyCoordinates();
        if (coords != null) {
            getLatButton().setText(coords.format(GeopointFormatter.Format.LAT_DECMINUTE));
            getLonButton().setText(coords.format(GeopointFormatter.Format.LON_DECMINUTE));
        }

        getButtonCurrent().setOnClickListener(new CurrentListener());

        getDestinationHistoryAdapter().notifyDataSetChanged();
        disableSuggestions(getDistanceEditText());

        initializeDistanceUnitSelector();
    }

    private void initializeDistanceUnitSelector() {
        distanceUnit = Settings.useImperialUnits() ? DistanceParser.DistanceUnit.FT : DistanceParser.DistanceUnit.M;
        getDistanceUnitSelector().setSelection(distanceUnit.getValue());

        getDistanceUnitSelector().setOnItemSelectedListener(new ChangeDistanceUnit(this));
    }

    private class CoordDialogListener implements View.OnClickListener {

        @Override
        public void onClick(final View arg0) {
            Geopoint gp = null;
            if (getLatButton().getText().length() > 0 && getLonButton().getText().length() > 0) {
                gp = new Geopoint(getLatButton().getText().toString() + " " + getLonButton().getText().toString());
            }
            final CoordinatesInputDialog coordsDialog = CoordinatesInputDialog.getInstance(null, gp);
            coordsDialog.setCancelable(true);
            coordsDialog.show(getSupportFragmentManager(), "wpedit_dialog");
        }

    }
    @Override
    public void updateCoordinates(final Geopoint gp) {
        getLatButton().setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE));
        getLonButton().setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE));
        changed = true;
    }

    @Override
    public boolean supportsNullCoordinates() {
        return false;
    }

    private static class ChangeDistanceUnit implements OnItemSelectedListener {

        private ChangeDistanceUnit(final NavigateAnyPointActivity unitView) {
            this.unitView = unitView;
        }

        private final NavigateAnyPointActivity unitView;

        @Override
        public void onItemSelected(final AdapterView<?> arg0, final View arg1, final int arg2,
                final long arg3) {
            unitView.distanceUnit = DistanceParser.DistanceUnit.getById(arg2);
        }

        @Override
        public void onNothingSelected(final AdapterView<?> arg0) {
        }
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        getMenuInflater().inflate(R.menu.navigate_any_point_activity_options, menu);
        final MenuItem menuItem = menu.findItem(R.id.menu_default_navigation);
        menuItem.setTitle(NavigationAppFactory.getDefaultNavigationApplication().getName());
        final NavigationActionProvider navAction = (NavigationActionProvider) MenuItemCompat.getActionProvider(menuItem);
        if (navAction != null) {
            navAction.setNavigationSource(this);
        }
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(final Menu menu) {
        super.onPrepareOptionsMenu(menu);

        try {
            final boolean visible = getDestination() != null;
            menu.findItem(R.id.menu_navigate).setVisible(visible);
            menu.findItem(R.id.menu_default_navigation).setVisible(visible);
            menu.findItem(R.id.menu_caches_around).setVisible(visible);

            menu.findItem(R.id.menu_clear_history).setVisible(!getHistoryOfSearchedLocations().isEmpty());
        } catch (final RuntimeException ignored) {
            // nothing
        }

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        final int menuItem = item.getItemId();
        final Geopoint coords = getDestinationAndAddToHistory();
        switch (menuItem) {
            case R.id.menu_default_navigation:
                navigateTo(coords);
                return true;

            case R.id.menu_caches_around:
                cachesAround(coords);
                return true;

            case R.id.menu_clear_history:
                clearHistory();
                return true;

            case R.id.menu_navigate:
                NavigationAppFactory.showNavigationMenu(this, null, null, coords);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private Geopoint getDestinationAndAddToHistory() {
        final Geopoint coords = getDestination();
        addToHistory(coords);
        return coords;
    }

    private void addToHistory(@Nullable final Geopoint coords) {
        if (coords == null) {
            return;
        }

        // Add locations to history
        final Destination loc = new Destination(coords);

        if (!getHistoryOfSearchedLocations().contains(loc)) {
            getHistoryOfSearchedLocations().add(0, loc);
            AndroidRxUtils.andThenOnUi(Schedulers.io(), () -> {
                // Save location
                DataStore.saveSearchedDestination(loc);
            }, () -> {
                // Ensure to remove the footer
                historyListView.removeFooterView(getEmptyHistoryFooter());
                destinationHistoryAdapter.notifyDataSetChanged();
            });
        }
    }

    private void removeFromHistory(final Destination destination) {
        if (getHistoryOfSearchedLocations().contains(destination)) {
            getHistoryOfSearchedLocations().remove(destination);

            // Save
            DataStore.removeSearchedDestination(destination);

            if (getHistoryOfSearchedLocations().isEmpty() && historyListView.getFooterViewsCount() == 0) {
                historyListView.addFooterView(getEmptyHistoryFooter());
            }

            getDestinationHistoryAdapter().notifyDataSetChanged();

            showToast(res.getString(R.string.search_remove_destination));
        }
    }

    private void clearHistory() {
        if (!getHistoryOfSearchedLocations().isEmpty()) {
            getHistoryOfSearchedLocations().clear();

            // Save
            DataStore.clearSearchedDestinations();

            if (historyListView.getFooterViewsCount() == 0) {
                historyListView.addFooterView(getEmptyHistoryFooter());
            }

            getDestinationHistoryAdapter().notifyDataSetChanged();

            showToast(res.getString(R.string.search_history_cleared));
        }
    }

    private void navigateTo(final Geopoint coords) {
        if (coords == null) {
            showToast(res.getString(R.string.err_location_unknown));
            return;
        }

        NavigationAppFactory.startDefaultNavigationApplication(1, this, coords);
    }

    private void cachesAround(final Geopoint coords) {
        if (coords == null) {
            showToast(res.getString(R.string.err_location_unknown));
            return;
        }

        CacheListActivity.startActivityCoordinates(this, coords, null);

        finish();
    }

    private final GeoDirHandler geoDirHandler = new GeoDirHandler() {
        @Override
        public void updateGeoData(final GeoData geo) {
            try {
                getLatButton().setHint(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
                getLonButton().setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
            } catch (final RuntimeException e) {
                Log.w("Failed to update location", e);
            }
        }
    };

    private class CurrentListener implements View.OnClickListener {

        @Override
        public void onClick(final View arg0) {
            final Geopoint coords = Sensors.getInstance().currentGeo().getCoords();
            getLatButton().setText(coords.format(GeopointFormatter.Format.LAT_DECMINUTE));
            getLonButton().setText(coords.format(GeopointFormatter.Format.LON_DECMINUTE));
            changed = false;
        }
    }

    private Geopoint getDestination() {
        final String bearingText = getBearingEditText().getText().toString();
        final String distanceText = getDistanceEditText().getText().toString();
        final String latText = getLatButton().getText().toString();
        final String lonText = getLonButton().getText().toString();

        if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText)
                && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) {
            showToast(res.getString(R.string.err_point_no_position_given));
            return null;
        }

        // get base coordinates
        Geopoint coords;
        if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) {
            try {
                coords = new Geopoint(latText, lonText);
            } catch (final Geopoint.ParseException e) {
                showToast(res.getString(e.resource));
                return null;
            }
        } else {
            coords = Sensors.getInstance().currentGeo().getCoords();
        }

        // apply projection
        if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) {
            // bearing & distance
            final double bearing;
            try {
                bearing = Double.parseDouble(bearingText);
            } catch (final NumberFormatException ignored) {
                Dialogs.message(this, R.string.err_point_bear_and_dist_title, R.string.err_point_bear_and_dist);
                return null;
            }

            final double distance;
            try {
                distance = DistanceParser.parseDistance(distanceText, distanceUnit);
            } catch (final NumberFormatException ignored) {
                showToast(res.getString(R.string.err_parse_dist));
                return null;
            }

            coords = coords.project(bearing, distance);
        }

        saveCoords(coords);

        return coords;
    }

    private void saveCoords(final Geopoint coords) {
        if (!changed) {
            return;
        }
        Settings.setAnyCoordinates(coords);
    }

    @Override
    public void startDefaultNavigation() {
        navigateTo(getDestinationAndAddToHistory());
    }

    @Override
    public void startDefaultNavigation2() {
        NavigationAppFactory.startDefaultNavigationApplication(2, this, getDestinationAndAddToHistory());
    }

    private Button getLatButton() {
        return latButton;
    }

    private Button getLonButton() {
        return lonButton;
    }

    private EditText getDistanceEditText() {
        return distanceEditText;
    }

    private Spinner getDistanceUnitSelector() {
        return distanceUnitSelector;
    }

    private Button getButtonCurrent() {
        return buttonCurrent;
    }

    private EditText getBearingEditText() {
        return bearingEditText;
    }

}
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;

import java.util.ArrayList;

import de.k3b.geo.api.GeoPointDto;
import de.k3b.geo.api.IGeoPointInfo;
import de.k3b.geo.io.GeoUri;

public class NavigateAnyPointActivity extends AbstractActionBarActivity {
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.cgeo);

        InternalConnector.assertHistoryCacheExists(this);

        // check if "geo" action is requested
        boolean geoActionRequested = false;
        if (getIntent() != null) {
            final GeoUri parser = new GeoUri(GeoUri.OPT_DEFAULT);
            final IGeoPointInfo geo = parser.fromUri(getIntent().getDataString());
            if (geo != null && !GeoPointDto.isEmpty(geo)) {
                Log.i("Received a geo intent: lat=" + geo.getLatitude()
                        + ", lon=" + geo.getLongitude() + ", name=" + geo.getName()
                        + " form " + getIntent().getDataString());
                selectTargetType(this, geo.getLatitude(), geo.getLongitude(), geo.getName());
                geoActionRequested = true;
            }
        }
        if (!geoActionRequested) {
            CacheDetailActivity.startActivity(this, InternalConnector.GEOCODE_HISTORY_CACHE, true);
            finish();
        }
    }

    private static void selectTargetType(final Activity context, final double latitude, final double longitude, @Nullable final String name) {

        final ArrayList<Geocache> items = new ArrayList<>();
        items.add(null);
        items.add(DataStore.loadCache(InternalConnector.GEOCODE_HISTORY_CACHE, LoadFlags.LOAD_CACHE_OR_DB));
        items.addAll(DataStore.loadUDCSorted());

        final ListAdapter adapter = new ArrayAdapter<Geocache>(context, R.layout.cacheslist_item_select, items) {
            @SuppressLint("SetTextI18n")
            @NonNull
            @Override
            public View getView(final int position, final View convertView, @NonNull final ViewGroup parent) {
                final Geocache cache = getItem(position);

                if (cache == null) { // special case: we want to display a "<New cache>" item on top
                    final View view = GeoItemSelectorUtils.getOrCreateView(context, convertView, parent);

                    final TextView title = (TextView) view.findViewById(R.id.text);
                    title.setText("<" + context.getString(R.string.create_internal_cache_short) + ">");

                    final TextView info = (TextView) view.findViewById(R.id.info);
                    info.setText(context.getString(R.string.create_internal_cache));

                    return view;
                }

                return GeoItemSelectorUtils.createGeocacheItemView(context, cache,
                        GeoItemSelectorUtils.getOrCreateView(context, convertView, parent));
            }
        };

        final AlertDialog dialog = Dialogs.newBuilder(context)
                .setTitle(R.string.add_target_to)
                .setAdapter(adapter, (dialog1, which) -> {
                    final String geocode;
                    if (which == 0) {
                        // create new UDC
                        geocode = InternalConnector.createCache(context, name, null, 0, new Geopoint(latitude, longitude), StoredList.STANDARD_LIST_ID);
                    } else {
                        // add to an existing UDC
                        geocode = items.get(which).getGeocode();
                        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
                        final Waypoint newWaypoint = new Waypoint(null != name ? name : Waypoint.getDefaultWaypointName(cache, WaypointType.WAYPOINT), WaypointType.WAYPOINT, true);
                        newWaypoint.setCoords(new Geopoint(latitude, longitude));
                        newWaypoint.setGeocode(geocode);
                        cache.addOrChangeWaypoint(newWaypoint, true);
                    }
                    CacheDetailActivity.startActivity(context, geocode, which != 0);
                    context.finish();
                })
                .create();
        dialog.setCanceledOnTouchOutside(true);
        dialog.show();
    }

}

<MSG> code cleanup NavigateAnyPointActivity
- "go to" shortcut to open the new "go to" waypoint page (fix #7959)
- remove unused code for old NavigateAnyPointActivity

<DFF> @@ -1,581 +1,15 @@
 package cgeo.geocaching;
 
 import cgeo.geocaching.activity.AbstractActionBarActivity;
-import cgeo.geocaching.activity.INavigationSource;
-import cgeo.geocaching.apps.navi.NavigationAppFactory;
-import cgeo.geocaching.location.DistanceParser;
-import cgeo.geocaching.location.Geopoint;
-import cgeo.geocaching.location.GeopointFormatter;
-import cgeo.geocaching.models.Destination;
-import cgeo.geocaching.permission.PermissionHandler;
-import cgeo.geocaching.permission.PermissionRequestContext;
-import cgeo.geocaching.permission.RestartLocationPermissionGrantedCallback;
-import cgeo.geocaching.sensors.GeoData;
-import cgeo.geocaching.sensors.GeoDirHandler;
-import cgeo.geocaching.sensors.Sensors;
-import cgeo.geocaching.settings.Settings;
-import cgeo.geocaching.storage.DataStore;
-import cgeo.geocaching.ui.AbstractViewHolder;
-import cgeo.geocaching.ui.NavigationActionProvider;
-import cgeo.geocaching.ui.dialog.CoordinatesInputDialog;
-import cgeo.geocaching.ui.dialog.Dialogs;
-import cgeo.geocaching.utils.AndroidRxUtils;
-import cgeo.geocaching.utils.Formatter;
-import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.connector.internal.InternalConnector;
 
-import android.content.Context;
-import android.content.res.Configuration;
 import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.view.MenuItemCompat;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnCreateContextMenuListener;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ListView;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import java.util.List;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import io.reactivex.schedulers.Schedulers;
-import org.apache.commons.lang3.StringUtils;
-
-public class NavigateAnyPointActivity extends AbstractActionBarActivity implements CoordinatesInputDialog.CoordinateUpdate, INavigationSource {
-
-    @BindView(R.id.historyList) protected ListView historyListView;
-
-    // list header fields are optional, due to being expanded later than the list itself
-    @Nullable @BindView(R.id.buttonLatitude) protected Button latButton;
-    @Nullable @BindView(R.id.buttonLongitude) protected Button lonButton;
-    @Nullable @BindView(R.id.distance) protected EditText distanceEditText;
-    @Nullable @BindView(R.id.distanceUnit) protected Spinner distanceUnitSelector;
-    @Nullable @BindView(R.id.current) protected Button buttonCurrent;
-    @Nullable @BindView(R.id.bearing) protected EditText bearingEditText;
-
-    private boolean changed = false;
-    private List<Destination> historyOfSearchedLocations;
-    private DestinationHistoryAdapter destinationHistoryAdapter;
-    private TextView historyFooter;
-
-    private static final int CONTEXT_MENU_NAVIGATE = 1;
-    private static final int CONTEXT_MENU_DELETE_WAYPOINT = 2;
-    private static final int CONTEXT_MENU_EDIT_WAYPOINT = 3;
-
-    private int contextMenuItemPosition;
-
-    private DistanceParser.DistanceUnit distanceUnit = DistanceParser.DistanceUnit.M;
-
-    protected static class ViewHolder extends AbstractViewHolder {
-        @BindView(R.id.simple_way_point_longitude) protected TextView longitude;
-        @BindView(R.id.simple_way_point_latitude) protected TextView latitude;
-        @BindView(R.id.date) protected TextView date;
-
-        public ViewHolder(final View rowView) {
-            super(rowView);
-        }
-    }
-
-    private static class DestinationHistoryAdapter extends ArrayAdapter<Destination> {
-        private LayoutInflater inflater = null;
-
-        DestinationHistoryAdapter(final Context context,
-                final List<Destination> objects) {
-            super(context, 0, objects);
-        }
-
-        @Override
-        public View getView(final int position, final View convertView, final ViewGroup parent) {
-            View rowView = convertView;
-
-            final ViewHolder viewHolder;
-            if (rowView == null) {
-                rowView = getInflater().inflate(R.layout.simple_way_point, parent, false);
-                viewHolder = new ViewHolder(rowView);
-            } else {
-                viewHolder = (ViewHolder) rowView.getTag();
-            }
-
-            fillViewHolder(viewHolder, getItem(position));
-
-            return rowView;
-        }
-
-        private static void fillViewHolder(final ViewHolder viewHolder, final Destination loc) {
-            final String lonString = loc.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE);
-            final String latString = loc.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE);
-
-            viewHolder.longitude.setText(lonString);
-            viewHolder.latitude.setText(latString);
-            viewHolder.date.setText(Formatter.formatShortDateTime(loc.getDate()));
-        }
-
-        private LayoutInflater getInflater() {
-            if (inflater == null) {
-                inflater = LayoutInflater.from(getContext());
-            }
-
-            return inflater;
-        }
-    }
 
+public class NavigateAnyPointActivity extends AbstractActionBarActivity {
     @Override
     public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState, R.layout.navigateanypoint_activity);
-        ButterKnife.bind(this);
-
-        createHistoryView();
-        init();
-    }
-
-    private void createHistoryView() {
-        final View pointControls = getLayoutInflater().inflate(R.layout.navigateanypoint_header, historyListView, false);
-        historyListView.addHeaderView(pointControls, null, false);
-
-        // inject a second time to also find the dynamically expanded views above
-        ButterKnife.bind(this);
-
-        if (getHistoryOfSearchedLocations().isEmpty()) {
-            historyListView.addFooterView(getEmptyHistoryFooter(), null, false);
-        }
-
-        historyListView.setAdapter(getDestinationHistoryAdapter());
-        historyListView.setOnItemClickListener(new OnItemClickListener() {
-
-            @Override
-            public void onItemClick(final AdapterView<?> arg0, final View arg1, final int arg2,
-                    final long arg3) {
-                final Object selection = arg0.getItemAtPosition(arg2);
-                if (selection instanceof Destination) {
-                    navigateTo(((Destination) selection).getCoords());
-                }
-            }
-        });
-
-        historyListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
-            @Override
-            public void onCreateContextMenu(final ContextMenu menu, final View v,
-                    final ContextMenuInfo menuInfo) {
-                menu.add(Menu.NONE, CONTEXT_MENU_NAVIGATE, Menu.NONE, res.getString(R.string.cache_menu_navigate));
-                menu.add(Menu.NONE, CONTEXT_MENU_EDIT_WAYPOINT, Menu.NONE, R.string.waypoint_edit);
-                menu.add(Menu.NONE, CONTEXT_MENU_DELETE_WAYPOINT, Menu.NONE, R.string.waypoint_delete);
-            }
-        });
-    }
-
-    @Override
-    public boolean onContextItemSelected(final MenuItem item) {
-        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
-        final int position = menuInfo != null ? menuInfo.position : contextMenuItemPosition;
-        final Object destination = historyListView.getItemAtPosition(position);
-
-        switch (item.getItemId()) {
-            case CONTEXT_MENU_NAVIGATE:
-                contextMenuItemPosition = position;
-                if (destination instanceof Destination) {
-                    NavigationAppFactory.showNavigationMenu(this, null, null, ((Destination) destination).getCoords());
-                    return true;
-                }
-                break;
-
-            case CONTEXT_MENU_DELETE_WAYPOINT:
-                if (destination instanceof Destination) {
-                    removeFromHistory((Destination) destination);
-                }
-                return true;
-
-            case CONTEXT_MENU_EDIT_WAYPOINT:
-                if (destination instanceof Destination) {
-                    final Geopoint gp = ((Destination) destination).getCoords();
-                    getLatButton().setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE));
-                    getLonButton().setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE));
-                }
-                return true;
-            default:
-        }
-
-        return super.onContextItemSelected(item);
-    }
-
-    private TextView getEmptyHistoryFooter() {
-        if (historyFooter == null) {
-            historyFooter = (TextView) getLayoutInflater().inflate(R.layout.cacheslist_footer, historyListView, false);
-            historyFooter.setText(R.string.search_history_empty);
-        }
-        return historyFooter;
-    }
-
-    private DestinationHistoryAdapter getDestinationHistoryAdapter() {
-        if (destinationHistoryAdapter == null) {
-            destinationHistoryAdapter = new DestinationHistoryAdapter(this, getHistoryOfSearchedLocations());
-        }
-        return destinationHistoryAdapter;
-    }
-
-    private List<Destination> getHistoryOfSearchedLocations() {
-        if (historyOfSearchedLocations == null) {
-            // Load from database
-            historyOfSearchedLocations = DataStore.loadHistoryOfSearchedLocations();
-        }
-
-        return historyOfSearchedLocations;
-    }
-
-    @Override
-    public void onConfigurationChanged(final Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        init();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        // resume location access
-        PermissionHandler.executeIfLocationPermissionGranted(this,
-                new RestartLocationPermissionGrantedCallback(PermissionRequestContext.NavigateAnyPointActivity) {
-
-                    @Override
-                    public void executeAfter() {
-                        resumeDisposables(geoDirHandler.start(GeoDirHandler.UPDATE_GEODATA));
-                    }
-                });
-
-        init();
-    }
-
-    private void init() {
-        getLatButton().setOnClickListener(new CoordDialogListener());
-        getLonButton().setOnClickListener(new CoordDialogListener());
-
-        final Geopoint coords = Settings.getAnyCoordinates();
-        if (coords != null) {
-            getLatButton().setText(coords.format(GeopointFormatter.Format.LAT_DECMINUTE));
-            getLonButton().setText(coords.format(GeopointFormatter.Format.LON_DECMINUTE));
-        }
-
-        getButtonCurrent().setOnClickListener(new CurrentListener());
-
-        getDestinationHistoryAdapter().notifyDataSetChanged();
-        disableSuggestions(getDistanceEditText());
-
-        initializeDistanceUnitSelector();
-    }
-
-    private void initializeDistanceUnitSelector() {
-        distanceUnit = Settings.useImperialUnits() ? DistanceParser.DistanceUnit.FT : DistanceParser.DistanceUnit.M;
-        getDistanceUnitSelector().setSelection(distanceUnit.getValue());
-
-        getDistanceUnitSelector().setOnItemSelectedListener(new ChangeDistanceUnit(this));
-    }
-
-    private class CoordDialogListener implements View.OnClickListener {
-
-        @Override
-        public void onClick(final View arg0) {
-            Geopoint gp = null;
-            if (getLatButton().getText().length() > 0 && getLonButton().getText().length() > 0) {
-                gp = new Geopoint(getLatButton().getText().toString() + " " + getLonButton().getText().toString());
-            }
-            final CoordinatesInputDialog coordsDialog = CoordinatesInputDialog.getInstance(null, gp);
-            coordsDialog.setCancelable(true);
-            coordsDialog.show(getSupportFragmentManager(), "wpedit_dialog");
-        }
-
-    }
-    @Override
-    public void updateCoordinates(final Geopoint gp) {
-        getLatButton().setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE));
-        getLonButton().setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE));
-        changed = true;
-    }
-
-    @Override
-    public boolean supportsNullCoordinates() {
-        return false;
-    }
-
-    private static class ChangeDistanceUnit implements OnItemSelectedListener {
-
-        private ChangeDistanceUnit(final NavigateAnyPointActivity unitView) {
-            this.unitView = unitView;
-        }
-
-        private final NavigateAnyPointActivity unitView;
-
-        @Override
-        public void onItemSelected(final AdapterView<?> arg0, final View arg1, final int arg2,
-                final long arg3) {
-            unitView.distanceUnit = DistanceParser.DistanceUnit.getById(arg2);
-        }
-
-        @Override
-        public void onNothingSelected(final AdapterView<?> arg0) {
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(final Menu menu) {
-        getMenuInflater().inflate(R.menu.navigate_any_point_activity_options, menu);
-        final MenuItem menuItem = menu.findItem(R.id.menu_default_navigation);
-        menuItem.setTitle(NavigationAppFactory.getDefaultNavigationApplication().getName());
-        final NavigationActionProvider navAction = (NavigationActionProvider) MenuItemCompat.getActionProvider(menuItem);
-        if (navAction != null) {
-            navAction.setNavigationSource(this);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(final Menu menu) {
-        super.onPrepareOptionsMenu(menu);
-
-        try {
-            final boolean visible = getDestination() != null;
-            menu.findItem(R.id.menu_navigate).setVisible(visible);
-            menu.findItem(R.id.menu_default_navigation).setVisible(visible);
-            menu.findItem(R.id.menu_caches_around).setVisible(visible);
-
-            menu.findItem(R.id.menu_clear_history).setVisible(!getHistoryOfSearchedLocations().isEmpty());
-        } catch (final RuntimeException ignored) {
-            // nothing
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(final MenuItem item) {
-        final int menuItem = item.getItemId();
-        final Geopoint coords = getDestinationAndAddToHistory();
-        switch (menuItem) {
-            case R.id.menu_default_navigation:
-                navigateTo(coords);
-                return true;
-
-            case R.id.menu_caches_around:
-                cachesAround(coords);
-                return true;
-
-            case R.id.menu_clear_history:
-                clearHistory();
-                return true;
-
-            case R.id.menu_navigate:
-                NavigationAppFactory.showNavigationMenu(this, null, null, coords);
-                return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private Geopoint getDestinationAndAddToHistory() {
-        final Geopoint coords = getDestination();
-        addToHistory(coords);
-        return coords;
-    }
-
-    private void addToHistory(@Nullable final Geopoint coords) {
-        if (coords == null) {
-            return;
-        }
-
-        // Add locations to history
-        final Destination loc = new Destination(coords);
-
-        if (!getHistoryOfSearchedLocations().contains(loc)) {
-            getHistoryOfSearchedLocations().add(0, loc);
-            AndroidRxUtils.andThenOnUi(Schedulers.io(), () -> {
-                // Save location
-                DataStore.saveSearchedDestination(loc);
-            }, () -> {
-                // Ensure to remove the footer
-                historyListView.removeFooterView(getEmptyHistoryFooter());
-                destinationHistoryAdapter.notifyDataSetChanged();
-            });
-        }
-    }
-
-    private void removeFromHistory(final Destination destination) {
-        if (getHistoryOfSearchedLocations().contains(destination)) {
-            getHistoryOfSearchedLocations().remove(destination);
-
-            // Save
-            DataStore.removeSearchedDestination(destination);
-
-            if (getHistoryOfSearchedLocations().isEmpty() && historyListView.getFooterViewsCount() == 0) {
-                historyListView.addFooterView(getEmptyHistoryFooter());
-            }
-
-            getDestinationHistoryAdapter().notifyDataSetChanged();
-
-            showToast(res.getString(R.string.search_remove_destination));
-        }
-    }
-
-    private void clearHistory() {
-        if (!getHistoryOfSearchedLocations().isEmpty()) {
-            getHistoryOfSearchedLocations().clear();
-
-            // Save
-            DataStore.clearSearchedDestinations();
-
-            if (historyListView.getFooterViewsCount() == 0) {
-                historyListView.addFooterView(getEmptyHistoryFooter());
-            }
-
-            getDestinationHistoryAdapter().notifyDataSetChanged();
-
-            showToast(res.getString(R.string.search_history_cleared));
-        }
-    }
-
-    private void navigateTo(final Geopoint coords) {
-        if (coords == null) {
-            showToast(res.getString(R.string.err_location_unknown));
-            return;
-        }
-
-        NavigationAppFactory.startDefaultNavigationApplication(1, this, coords);
-    }
-
-    private void cachesAround(final Geopoint coords) {
-        if (coords == null) {
-            showToast(res.getString(R.string.err_location_unknown));
-            return;
-        }
-
-        CacheListActivity.startActivityCoordinates(this, coords, null);
-
+        super.onCreate(savedInstanceState);
+        CacheDetailActivity.startActivity(this, InternalConnector.GEOCODE_HISTORY_CACHE, true);
         finish();
     }
-
-    private final GeoDirHandler geoDirHandler = new GeoDirHandler() {
-        @Override
-        public void updateGeoData(final GeoData geo) {
-            try {
-                getLatButton().setHint(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
-                getLonButton().setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
-            } catch (final RuntimeException e) {
-                Log.w("Failed to update location", e);
-            }
-        }
-    };
-
-    private class CurrentListener implements View.OnClickListener {
-
-        @Override
-        public void onClick(final View arg0) {
-            final Geopoint coords = Sensors.getInstance().currentGeo().getCoords();
-            getLatButton().setText(coords.format(GeopointFormatter.Format.LAT_DECMINUTE));
-            getLonButton().setText(coords.format(GeopointFormatter.Format.LON_DECMINUTE));
-            changed = false;
-        }
-    }
-
-    private Geopoint getDestination() {
-        final String bearingText = getBearingEditText().getText().toString();
-        final String distanceText = getDistanceEditText().getText().toString();
-        final String latText = getLatButton().getText().toString();
-        final String lonText = getLonButton().getText().toString();
-
-        if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText)
-                && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) {
-            showToast(res.getString(R.string.err_point_no_position_given));
-            return null;
-        }
-
-        // get base coordinates
-        Geopoint coords;
-        if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) {
-            try {
-                coords = new Geopoint(latText, lonText);
-            } catch (final Geopoint.ParseException e) {
-                showToast(res.getString(e.resource));
-                return null;
-            }
-        } else {
-            coords = Sensors.getInstance().currentGeo().getCoords();
-        }
-
-        // apply projection
-        if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) {
-            // bearing & distance
-            final double bearing;
-            try {
-                bearing = Double.parseDouble(bearingText);
-            } catch (final NumberFormatException ignored) {
-                Dialogs.message(this, R.string.err_point_bear_and_dist_title, R.string.err_point_bear_and_dist);
-                return null;
-            }
-
-            final double distance;
-            try {
-                distance = DistanceParser.parseDistance(distanceText, distanceUnit);
-            } catch (final NumberFormatException ignored) {
-                showToast(res.getString(R.string.err_parse_dist));
-                return null;
-            }
-
-            coords = coords.project(bearing, distance);
-        }
-
-        saveCoords(coords);
-
-        return coords;
-    }
-
-    private void saveCoords(final Geopoint coords) {
-        if (!changed) {
-            return;
-        }
-        Settings.setAnyCoordinates(coords);
-    }
-
-    @Override
-    public void startDefaultNavigation() {
-        navigateTo(getDestinationAndAddToHistory());
-    }
-
-    @Override
-    public void startDefaultNavigation2() {
-        NavigationAppFactory.startDefaultNavigationApplication(2, this, getDestinationAndAddToHistory());
-    }
-
-    private Button getLatButton() {
-        return latButton;
-    }
-
-    private Button getLonButton() {
-        return lonButton;
-    }
-
-    private EditText getDistanceEditText() {
-        return distanceEditText;
-    }
-
-    private Spinner getDistanceUnitSelector() {
-        return distanceUnitSelector;
-    }
-
-    private Button getButtonCurrent() {
-        return buttonCurrent;
-    }
-
-    private EditText getBearingEditText() {
-        return bearingEditText;
-    }
-
 }

code cleanup NavigateAnyPointActivity - "go to" shortcut to open the new "go to" waypoint page (fix #7959) - remove unused code for old NavigateAnyPointActivity