diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b705f95527..6dd592ffc7 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -1,5 +1,12 @@  + Changes in 0.8.0 : +\n\t- Plugin functionality +\n\t- New offline map data support +\n\t- Lots of bug fixes + + This plugin is intented to improve OSM quality. It allows to collect/modify OSM POI objects, open/comment OSM bugs and send recorded GPX (requires OSM credentials). + Osm Editing Vector maps may display faster. May not work well on some devices. Simulate route progression manually Play commands of currently selected voice diff --git a/OsmAnd/src/net/osmand/access/MapExplorer.java b/OsmAnd/src/net/osmand/access/MapExplorer.java index 8989ab8383..9fc06df2af 100644 --- a/OsmAnd/src/net/osmand/access/MapExplorer.java +++ b/OsmAnd/src/net/osmand/access/MapExplorer.java @@ -162,9 +162,4 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider { return mapView.getContext().getString(R.string.i_am_here); } - @Override - public DialogInterface.OnClickListener getActionListener(List actionsList, Object o) { - return null; - } - } diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java new file mode 100644 index 0000000000..c75f6dd56c --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -0,0 +1,77 @@ +package net.osmand.plus; + +import java.util.ArrayList; + +import gnu.trove.list.array.TIntArrayList; +import android.content.Context; + +public class ContextMenuAdapter { + + public interface OnContextMenuClick { + + public void onContextMenuClick(int itemId, int pos, boolean isChecked); + } + + private final Context ctx; + final TIntArrayList items = new TIntArrayList(); + final ArrayList itemNames = new ArrayList(); + final ArrayList listeners = new ArrayList(); + final TIntArrayList selectedList = new TIntArrayList(); + final TIntArrayList iconList = new TIntArrayList(); + + public ContextMenuAdapter(Context ctx) { + this.ctx = ctx; + } + + public int length(){ + return items.size(); + } + + public int getItemId(int pos){ + return items.get(pos); + } + + public OnContextMenuClick getClickAdapter(int i) { + return listeners.get(i); + } + + public String getItemName(int pos){ + return itemNames.get(pos); + } + + public int getSelection(int pos) { + return selectedList.get(pos); + } + + public int getImageId(int pos) { + return iconList.get(pos); + } + + public void registerItem(int stringResId, int icon, OnContextMenuClick listener, int pos) { + registerSelectedItem(stringResId, -1, icon, listener, pos); + } + + + public void registerSelectedItem(int stringResId, int selected, int icon, OnContextMenuClick listener, int pos) { + if(pos >= items.size() || pos < 0) { + pos = items.size(); + } + items.insert(pos, stringResId); + itemNames.add(pos, ctx.getString(stringResId)); + selectedList.insert(pos, selected); + iconList.insert(pos, icon); + } + + public void registerSelectedItem(int stringResId, int selected, int icon) { + registerSelectedItem(stringResId, selected, icon, null, -1); + } + + public void registerItem(int stringResId) { + registerSelectedItem(stringResId, -1, 0); + } + + public String[] getItemNames() { + return itemNames.toArray(new String[itemNames.size()]); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index 037c574b6e..b6b0860ce8 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -1,9 +1,9 @@ package net.osmand.plus; -import gnu.trove.list.array.TIntArrayList; import java.util.ArrayList; import java.util.List; +import java.util.Set; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.osmedit.OsmEditingPlugin; @@ -11,28 +11,23 @@ import net.osmand.plus.views.OsmandMapTileView; public abstract class OsmandPlugin { - private static List plugins = new ArrayList(); + private static List installedPlugins = new ArrayList(); + private static List activePlugins = new ArrayList(); static { - plugins.add(new OsmEditingPlugin()); - } - - public static List getAvailablePlugins(){ - return plugins; - } - - @SuppressWarnings("unchecked") - public static T getEnabledPlugin(Class clz) { - for(OsmandPlugin lr : plugins) { - if(clz.isInstance(lr)){ - return (T) lr; - } - } - return null; + installedPlugins.add(new OsmEditingPlugin()); } public abstract String getId(); + public abstract String getDescription(); + + public abstract String getName(); + + public String getVersion() { + return ""; + } + /** * Initialize plugin runs just after creation */ @@ -40,8 +35,14 @@ public abstract class OsmandPlugin { public static void initPlugins(OsmandApplication app) { - for (OsmandPlugin plugin : plugins) { - plugin.init(app); + OsmandSettings settings = app.getSettings(); + Set enabledPlugins = settings.getEnabledPlugins(); + for (OsmandPlugin plugin : installedPlugins) { + if (enabledPlugins.contains(plugin.getId())) { + if (plugin.init(app)) { + activePlugins.add(plugin); + } + } } } @@ -51,7 +52,7 @@ public abstract class OsmandPlugin { public abstract void updateLayers(OsmandMapTileView mapView); public static void refreshLayers(OsmandMapTileView mapView) { - for (OsmandPlugin plugin : plugins) { + for (OsmandPlugin plugin : activePlugins) { plugin.updateLayers(mapView); } } @@ -59,36 +60,77 @@ public abstract class OsmandPlugin { public abstract void registerLayers(MapActivity activity); - public static void createLayers(OsmandMapTileView mapView, MapActivity activity) { - for (OsmandPlugin plugin : plugins) { - plugin.registerLayers(activity); - } + public void mapActivityCreate(MapActivity activity) { } + + public void mapActivityResume(MapActivity activity) { } + + public void mapActivityPause(MapActivity activity) { } + + public void mapActivityDestroy(MapActivity activity) { } + + + public abstract void registerLayerContextMenuActions(OsmandMapTileView mapView, ContextMenuAdapter adapter); + + public abstract void registerMapContextMenuActions(MapActivity mapActivity, double latitude, double longitude, ContextMenuAdapter adapter, Object selectedObj); + + public static List getAvailablePlugins(){ + return installedPlugins; + } + + public static List getEnabledPlugins(){ + return activePlugins; + } + + @SuppressWarnings("unchecked") + public static T getEnabledPlugin(Class clz) { + for(OsmandPlugin lr : activePlugins) { + if(clz.isInstance(lr)){ + return (T) lr; + } + } + return null; } - public abstract void mapActivityCreate(MapActivity activity); - public static void onMapActivityCreate(MapActivity activity) { - for (OsmandPlugin plugin : plugins) { + for (OsmandPlugin plugin : activePlugins) { plugin.mapActivityCreate(activity); } } - public abstract boolean handleContextMenuAction(int resId, double latitude, double longitude); - - public abstract void registerContextMenuActions(double latitude, double longitude, TIntArrayList list); - - public static void registerContextMenu(double latitude, double longitude, TIntArrayList list) { - for (OsmandPlugin plugin : plugins) { - plugin.registerContextMenuActions(latitude, longitude, list); + public static void onMapActivityResume(MapActivity activity) { + for (OsmandPlugin plugin : activePlugins) { + plugin.mapActivityResume(activity); } } - public static boolean contextMenuAction(int resId, double latitude, double longitude) { - for (OsmandPlugin plugin : plugins) { - if(plugin.handleContextMenuAction(resId, latitude, longitude)){ - return true; - } + public static void onMapActivityPause(MapActivity activity) { + for (OsmandPlugin plugin : activePlugins) { + plugin.mapActivityPause(activity); + } + } + + public static void onMapActivityDestroy(MapActivity activity) { + for (OsmandPlugin plugin : activePlugins) { + plugin.mapActivityDestroy(activity); + } + } + + + public static void createLayers(OsmandMapTileView mapView, MapActivity activity) { + for (OsmandPlugin plugin : activePlugins) { + plugin.registerLayers(activity); + } + } + + public static void registerMapContextMenu(MapActivity map, double latitude, double longitude, ContextMenuAdapter adapter, Object selectedObj) { + for (OsmandPlugin plugin : activePlugins) { + plugin.registerMapContextMenuActions(map, latitude, longitude, adapter, selectedObj); + } + } + + public static void registerLayerContextMenu(OsmandMapTileView mapView, ContextMenuAdapter adapter) { + for (OsmandPlugin plugin : activePlugins) { + plugin.registerLayerContextMenuActions(mapView, adapter); } - return false; } } diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 98814af24e..664b13bfc8 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -4,9 +4,13 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Comparator; +import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; import net.osmand.Version; import net.osmand.access.AccessibilityMode; @@ -73,21 +77,18 @@ public class OsmandSettings { private boolean internetConnectionAvailable = true; private List internetAvailableSourceTemplates = null; - // TODO make all layers profile preferenced???? protected OsmandSettings(OsmandApplication application) { ctx = application; - - //TODO: Is it really intended to keep settings WORLD_READABLE? + + // TODO: Is it really intended to keep settings WORLD_READABLE? globalPreferences = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); // start from default settings currentMode = ApplicationMode.DEFAULT; - + defaultProfilePreferences = getProfilePreferences(ApplicationMode.DEFAULT); profilePreferences = defaultProfilePreferences; -// if(FOLLOW_TO_THE_ROUTE.get()){ - currentMode = readApplicationMode(); - profilePreferences = getProfilePreferences(currentMode); -// } + currentMode = readApplicationMode(); + profilePreferences = getProfilePreferences(currentMode); } public static String getSharedPreferencesName(ApplicationMode mode){ @@ -425,6 +426,39 @@ public class OsmandSettings { } } + + // this value string is synchronized with settings_pref.xml preference name + private final OsmandPreference ENABLED_PLUGINS = + new StringPreference("enabled_plugins", "", true); + + public Set getEnabledPlugins(){ + String plugs = ENABLED_PLUGINS.get(); + StringTokenizer toks = new StringTokenizer(plugs, ","); + Set res = new LinkedHashSet(); + while(toks.hasMoreTokens()) { + res.add(toks.nextToken()); + } + return res; + } + + public void enablePlugin(String pluginId, boolean enable){ + Set set = getEnabledPlugins(); + if(enable){ + set.add(pluginId); + } else { + set.remove(pluginId); + } + StringBuilder serialization = new StringBuilder(); + Iterator it = set.iterator(); + while(it.hasNext()){ + serialization.append(it.next()); + if(it.hasNext()) { + serialization.append(","); + } + } + ENABLED_PLUGINS.set(serialization.toString()); + } + /////////////// PREFERENCES classes //////////////// // this value string is synchronized with settings_pref.xml preference name diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index b8cd5621f9..e3703f7899 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -19,6 +19,7 @@ import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.IMapLocationListener; import net.osmand.osm.LatLon; import net.osmand.plus.BusyIndicator; +import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -316,6 +317,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe getMyApplication().getResourceManager().setBusyIndicator(new BusyIndicator(this, progress)); } + OsmandPlugin.onMapActivityResume(this); getMyApplication().getDaynightHelper().onMapResume(); mapView.refreshMap(true); } @@ -650,6 +652,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe @Override protected void onDestroy() { super.onDestroy(); + OsmandPlugin.onMapActivityDestroy(this); savingTrackHelper.close(); routeAnimation.close(); cancelNotification(); @@ -981,6 +984,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe settings.MAP_ACTIVITY_ENABLED.set(false); getMyApplication().getResourceManager().interruptRendering(); getMyApplication().getResourceManager().setBusyIndicator(null); + OsmandPlugin.onMapActivityPause(this); } public void updateApplicationModeSettings(){ @@ -1315,9 +1319,8 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe mapActions.contextMenuPoint(latitude, longitude, null, null); } - public void contextMenuPoint(final double latitude, final double longitude, List additionalItems, - final DialogInterface.OnClickListener additionalActions) { - mapActions.contextMenuPoint(latitude, longitude, additionalItems, additionalActions); + public void contextMenuPoint(final double latitude, final double longitude, ContextMenuAdapter adapter, Object selectedObj) { + mapActions.contextMenuPoint(latitude, longitude, adapter, selectedObj); } public MapActivityActions getMapActions() { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 1dc4e65602..67377c6c15 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -1,6 +1,5 @@ package net.osmand.plus.activities; -import gnu.trove.list.array.TIntArrayList; import java.io.File; import java.text.MessageFormat; @@ -22,6 +21,8 @@ import net.osmand.map.ITileSource; import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; import net.osmand.plus.AmenityIndexRepositoryOdb; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -715,40 +716,32 @@ public class MapActivityActions implements DialogProvider { } - public void contextMenuPoint(final double latitude, final double longitude, List additionalItems, - final DialogInterface.OnClickListener additionalActions) { + public void contextMenuPoint(final double latitude, final double longitude, final ContextMenuAdapter iadapter, Object selectedObj) { + final ContextMenuAdapter adapter = iadapter == null ? new ContextMenuAdapter(mapActivity) : iadapter; Builder builder = new AlertDialog.Builder(mapActivity); - final int sizeAdditional = additionalActions == null || additionalItems == null ? 0 : additionalItems.size(); - List actions = new ArrayList(); - if (sizeAdditional > 0) { - actions.addAll(additionalItems); - } final OsmandMapTileView mapView = mapActivity.getMapView(); - final TIntArrayList contextMenuStandardActions = new TIntArrayList(); - contextMenuStandardActions.add(new int[] { R.string.context_menu_item_navigate_point, - R.string.context_menu_item_show_route, R.string.context_menu_item_search, R.string.context_menu_item_add_favorite, - R.string.context_menu_item_share_location, R.string.context_menu_item_add_waypoint}); - OsmandPlugin.registerContextMenu(latitude, longitude, contextMenuStandardActions); - if(mapView.getMainLayer() instanceof MapTileLayer) { - contextMenuStandardActions.add(R.string.context_menu_item_update_map); - contextMenuStandardActions.add(R.string.context_menu_item_download_map); + + adapter.registerItem(R.string.context_menu_item_navigate_point); + adapter.registerItem(R.string.context_menu_item_show_route); + adapter.registerItem(R.string.context_menu_item_search); + adapter.registerItem(R.string.context_menu_item_add_favorite); + adapter.registerItem(R.string.context_menu_item_share_location); + adapter.registerItem(R.string.context_menu_item_add_waypoint); + OsmandPlugin.registerMapContextMenu(mapActivity, latitude, longitude, adapter, selectedObj); + + if (mapView.getMainLayer() instanceof MapTileLayer) { + adapter.registerItem(R.string.context_menu_item_update_map); + adapter.registerItem(R.string.context_menu_item_download_map); } - for (int j = 0; j < contextMenuStandardActions.size(); j++) { - actions.add(mapActivity.getString(contextMenuStandardActions.get(j))); - } - - builder.setItems(actions.toArray(new String[actions.size()]), new DialogInterface.OnClickListener() { + builder.setItems(adapter.getItemNames(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (which < sizeAdditional) { - additionalActions.onClick(dialog, which); - return; - } - int standardId = contextMenuStandardActions.get(which - sizeAdditional); - if(OsmandPlugin.contextMenuAction(standardId, latitude, longitude)) { - // Plugin action + int standardId = adapter.getItemId(which ); + OnContextMenuClick click = adapter.getClickAdapter(which); + if(click != null) { + click.onContextMenuClick(standardId, which, false); } else if (standardId == R.string.context_menu_item_navigate_point) { mapActivity.navigateToPoint(new LatLon(latitude, longitude)); } else if (standardId == R.string.context_menu_item_show_route) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 4574a230b4..c60c0e8853 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -1,6 +1,5 @@ package net.osmand.plus.activities; -import gnu.trove.list.array.TIntArrayList; import java.io.File; import java.util.ArrayList; @@ -22,6 +21,8 @@ import net.osmand.access.AccessibleToast; import net.osmand.data.AmenityType; import net.osmand.map.ITileSource; import net.osmand.map.TileSourceManager.TileSourceTemplate; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; @@ -246,68 +247,57 @@ public class MapActivityLayers { } public void openLayerSelectionDialog(final OsmandMapTileView mapView){ - - final TIntArrayList layers = new TIntArrayList(); - final TIntArrayList selectedList = new TIntArrayList(); - final TIntArrayList iconList = new TIntArrayList(); final OsmandSettings settings = getApplication().getSettings(); - layers.add(R.string.layer_map); - iconList.add(R.drawable.list_activities_map_src); - selectedList.add(-1); - layers.add(R.string.layer_poi); - iconList.add(R.drawable.list_activities_poi); - selectedList.add(settings.SHOW_POI_OVER_MAP.get() ? 1 : 0); - if(settings.SHOW_POI_OVER_MAP.get()){ - layers.add(R.string.layer_poi_label); - selectedList.add(settings.SHOW_POI_LABEL.get() ? 1 : 0); - iconList.add(0); - } - layers.add(R.string.layer_favorites); - iconList.add(R.drawable.list_activities_favorites); - selectedList.add(settings.SHOW_FAVORITES.get() ? 1 : 0); - layers.add(R.string.layer_gpx_layer); - selectedList.add(getApplication().getGpxFileToDisplay() != null ? 1 : 0); - iconList.add(R.drawable.list_activities_gpx_tracks); + final ContextMenuAdapter adapter = new ContextMenuAdapter(activity); + adapter.registerSelectedItem(R.string.layer_map, -1, R.drawable.list_activities_map_src); + adapter.registerSelectedItem(R.string.layer_poi, settings.SHOW_POI_OVER_MAP.get() ? 1 : 0, + R.drawable.list_activities_poi); + adapter.registerSelectedItem(R.string.layer_poi_label, settings.SHOW_POI_LABEL.get() ? 1 : 0, + 0); + adapter.registerSelectedItem(R.string.layer_favorites, settings.SHOW_FAVORITES.get() ? 1 : 0, + R.drawable.list_activities_favorites); + adapter.registerSelectedItem(R.string.layer_gpx_layer, + getApplication().getGpxFileToDisplay() != null ? 1 : 0, R.drawable.list_activities_gpx_tracks); if(routeInfoLayer.couldBeVisible()){ - layers.add(R.string.layer_route); - selectedList.add(routeInfoLayer.isUserDefinedVisible() ? 1 : 0); - iconList.add(0); + adapter.registerSelectedItem(R.string.layer_route, + routeInfoLayer.isUserDefinedVisible() ? 1 : 0, 0); } - layers.add(R.string.layer_transport); - selectedList.add(settings.SHOW_TRANSPORT_OVER_MAP.get() ? 1 : 0); - iconList.add(R.drawable.list_activities_transport_stops); + adapter.registerSelectedItem(R.string.layer_transport, settings.SHOW_TRANSPORT_OVER_MAP.get() ? 1 : 0, + R.drawable.list_activities_transport_stops); if(TransportRouteHelper.getInstance().routeIsCalculated()){ - layers.add(R.string.layer_transport_route); - selectedList.add(routeInfoLayer.isUserDefinedVisible() ? 1 : 0); - iconList.add(0); + adapter.registerSelectedItem(R.string.layer_transport_route, + routeInfoLayer.isUserDefinedVisible() ? 1 : 0, 0); } - layers.add(R.string.layer_osm_bugs); - selectedList.add(settings.SHOW_OSM_BUGS.get() ? 1 : 0); - iconList.add(R.drawable.list_activities_osm_bugs); - layers.add(R.string.layer_overlay); - selectedList.add(overlayLayer.getMap() != null ? 1 : 0); - iconList.add(R.drawable.list_activities_overlay_map); - layers.add(R.string.layer_underlay); - selectedList.add(underlayLayer.getMap() != null ? 1 : 0); - iconList.add(R.drawable.list_activities_underlay_map); + + adapter.registerSelectedItem(R.string.layer_overlay, overlayLayer.getMap() != null ? 1 : 0, + R.drawable.list_activities_overlay_map); + adapter.registerSelectedItem(R.string.layer_underlay, underlayLayer.getMap() != null ? 1 : 0, + R.drawable.list_activities_underlay_map); + + OsmandPlugin.registerLayerContextMenu(mapView, adapter); + final OnMultiChoiceClickListener listener = new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int item, boolean isChecked) { - if (layers.get(item) == R.string.layer_map) { + int itemId = adapter.getItemId(item); + OnContextMenuClick clck = adapter.getClickAdapter(item); + if(clck != null) { + clck.onContextMenuClick(itemId, item, isChecked); + } else if (itemId == R.string.layer_map) { dialog.dismiss(); selectMapLayer(mapView); - } else if(layers.get(item) == R.string.layer_poi){ + } else if(itemId == R.string.layer_poi){ if(isChecked){ selectPOIFilterLayer(mapView); } settings.SHOW_POI_OVER_MAP.set(isChecked); - } else if(layers.get(item) == R.string.layer_poi_label){ + } else if(itemId == R.string.layer_poi_label){ settings.SHOW_POI_LABEL.set(isChecked); - } else if(layers.get(item) == R.string.layer_favorites){ + } else if(itemId == R.string.layer_favorites){ settings.SHOW_FAVORITES.set(isChecked); - } else if(layers.get(item) == R.string.layer_gpx_layer){ + } else if(itemId == R.string.layer_gpx_layer){ if(getApplication().getGpxFileToDisplay() != null){ getApplication().setGpxFileToDisplay(null, false); gpxLayer.clearCurrentGPX(); @@ -315,15 +305,13 @@ public class MapActivityLayers { dialog.dismiss(); showGPXFileLayer(mapView); } - } else if(layers.get(item) == R.string.layer_route){ + } else if(itemId == R.string.layer_route){ routeInfoLayer.setVisible(isChecked); - } else if(layers.get(item) == R.string.layer_transport_route){ + } else if(itemId == R.string.layer_transport_route){ transportInfoLayer.setVisible(isChecked); - } else if(layers.get(item) == R.string.layer_transport){ + } else if(itemId == R.string.layer_transport){ settings.SHOW_TRANSPORT_OVER_MAP.set(isChecked); - } else if(layers.get(item) == R.string.layer_osm_bugs){ - settings.SHOW_OSM_BUGS.set(isChecked); - } else if(layers.get(item) == R.string.layer_overlay){ + } else if(itemId == R.string.layer_overlay){ if(overlayLayer.getMap() != null){ settings.MAP_OVERLAY.set(null); updateMapSource(mapView, null); @@ -332,7 +320,7 @@ public class MapActivityLayers { selectMapOverlayLayer(mapView, settings.MAP_OVERLAY, settings.MAP_OVERLAY_TRANSPARENCY, overlayLayer); } - } else if(layers.get(item) == R.string.layer_underlay){ + } else if(itemId == R.string.layer_underlay){ if(underlayLayer.getMap() != null){ settings.MAP_UNDERLAY.set(null); updateMapSource(mapView, null); @@ -351,31 +339,26 @@ public class MapActivityLayers { // list.setBackgroundColor(white); list.setCacheColorHint(activity.getResources().getColor(R.color.color_transparent)); b.setView(list); - final List layerNames = new ArrayList(); - for (int i = 0; i < layers.size(); i++) { - layerNames.add(getString(layers.get(i))); - - } final AlertDialog dlg = b.create(); final int minWidth = activity.getResources().getDrawable(R.drawable.list_activities_favorites).getMinimumWidth(); - ArrayAdapter adapter = new ArrayAdapter(activity, R.layout.layers_list_activity_item, - layerNames) { + ArrayAdapter arrayAdapter = new ArrayAdapter(activity, R.layout.layers_list_activity_item, + adapter.getItemNames()) { @Override public View getView(final int position, View convertView, ViewGroup parent) { View row = activity.getLayoutInflater().inflate(R.layout.layers_list_activity_item, null); - ((TextView) row.findViewById(R.id.title)).setText(layerNames.get(position)); - if(iconList.get(position) != 0) { - Drawable d = activity.getResources().getDrawable(iconList.get(position)); + ((TextView) row.findViewById(R.id.title)).setText(adapter.getItemName(position)); + if(adapter.getImageId(position) != 0) { + Drawable d = activity.getResources().getDrawable(adapter.getImageId(position)); ((ImageView) row.findViewById(R.id.icon)).setImageDrawable(d); } else { LinearLayout.LayoutParams layoutParams = (android.widget.LinearLayout.LayoutParams) ((ImageView) row.findViewById(R.id.icon)).getLayoutParams(); layoutParams.leftMargin = minWidth; } final CheckBox ch = ((CheckBox) row.findViewById(R.id.check_item)); - if(selectedList.get(position) == -1){ + if(adapter.getSelection(position) == -1){ ch.setVisibility(View.INVISIBLE); } else { - ch.setChecked(selectedList.get(position) > 0); + ch.setChecked(adapter.getSelection(position) > 0); ch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -396,15 +379,15 @@ public class MapActivityLayers { return row; } }; - list.setAdapter(adapter); + list.setAdapter(arrayAdapter); list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - if(selectedList.get(position) >= 0) { + if(adapter.getSelection(position) >= 0) { CheckBox ch = ((CheckBox) view.findViewById(R.id.check_item)); ch.setChecked(!ch.isChecked()); } else { - listener.onClick(dlg, position, selectedList.get(position) > 0); + listener.onClick(dlg, position, adapter.getSelection(position) > 0); } } }); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java index a355bbe924..704f1c61a7 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmBugsLayer.java @@ -16,14 +16,14 @@ import java.util.regex.Pattern; import net.osmand.LogUtil; import net.osmand.access.AccessibleToast; import net.osmand.osm.LatLon; -import net.osmand.plus.OsmandApplication; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.DialogProvider; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider; import net.osmand.plus.views.OsmandMapLayer; -import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import org.apache.commons.logging.Log; @@ -33,7 +33,6 @@ import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; @@ -451,25 +450,26 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider return builder.create(); } - @Override - public OnClickListener getActionListener(List actionsList, Object o) { - final OpenStreetBug bug = (OpenStreetBug) o; - actionsList.add(activity.getString(R.string.osb_comment_menu_item)); - actionsList.add(activity.getString(R.string.osb_close_menu_item)); - return new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == 0) { - commentBug(bug); - } else if (which == 1) { - closeBug(bug); + public void populateObjectContextMenu(Object o, ContextMenuAdapter adapter) { + if(o instanceof OpenStreetBug) { + final OpenStreetBug bug = (OpenStreetBug) o; + OnContextMenuClick listener = new OnContextMenuClick() { + + @Override + public void onContextMenuClick(int itemId, int pos, boolean isChecked) { + if (itemId == R.string.osb_comment_menu_item) { + commentBug(bug); + } else if (itemId == R.string.osb_close_menu_item) { + closeBug(bug); + } } - } - }; + }; + adapter.registerItem(R.string.osb_comment_menu_item, 0, listener, -1); + adapter.registerItem(R.string.osb_close_menu_item, 0, listener, -1); + } } - - + @Override public String getObjectDescription(Object o) { if(o instanceof OpenStreetBug){ diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index b6dd0c28e1..e04711d882 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -1,6 +1,8 @@ package net.osmand.plus.osmedit; -import gnu.trove.list.array.TIntArrayList; +import net.osmand.data.Amenity; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; @@ -9,8 +11,9 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.views.OsmandMapTileView; public class OsmEditingPlugin extends OsmandPlugin { - private static final String ID = "osm.editing.plugin"; + private static final String ID = "osm.editing"; private OsmandSettings settings; + private OsmandApplication app; @Override public String getId() { @@ -19,6 +22,7 @@ public class OsmEditingPlugin extends OsmandPlugin { @Override public boolean init(OsmandApplication app) { + this.app = app; settings = app.getSettings(); return true; } @@ -53,23 +57,65 @@ public class OsmEditingPlugin extends OsmandPlugin { public EditingPOIActivity getPoiActions() { return poiActions; } - + @Override - public boolean handleContextMenuAction(int resId, final double latitude, final double longitude) { - if (resId == R.string.context_menu_item_create_poi) { - poiActions.showCreateDialog(latitude, longitude); - return true; - } else if (resId == R.string.context_menu_item_open_bug) { - osmBugsLayer.openBug(latitude, longitude); - return true; + public void registerMapContextMenuActions(MapActivity mapActivity, final double latitude, final double longitude, ContextMenuAdapter adapter, + Object selectedObj) { + if(selectedObj instanceof Amenity) { + final Amenity a = (Amenity) selectedObj; + OnContextMenuClick alist = new OnContextMenuClick() { + + @Override + public void onContextMenuClick(int resId, int pos, boolean isChecked) { + if (resId == R.string.poi_context_menu_delete) { + getPoiActions().showDeleteDialog(a); + } else if (resId == R.string.poi_context_menu_modify) { + getPoiActions().showEditDialog(a); + } + } + }; + adapter.registerItem(R.string.poi_context_menu_modify, 0, alist, 1); + adapter.registerItem(R.string.poi_context_menu_delete, 0, alist, 2); } - return false; + OnContextMenuClick listener = new OnContextMenuClick() { + + @Override + public void onContextMenuClick(int resId, int pos, boolean isChecked) { + if (resId == R.string.context_menu_item_create_poi) { + poiActions.showCreateDialog(latitude, longitude); + } else if (resId == R.string.context_menu_item_open_bug) { + osmBugsLayer.openBug(latitude, longitude); + } + } + }; + adapter.registerItem(R.string.context_menu_item_create_poi, 0, listener, -1); + adapter.registerItem(R.string.context_menu_item_open_bug, 0, listener, -1); } @Override - public void registerContextMenuActions(double latitude, double longitude, TIntArrayList list) { - list.add(R.string.context_menu_item_create_poi); - list.add(R.string.context_menu_item_open_bug); + public void registerLayerContextMenuActions(OsmandMapTileView mapView, ContextMenuAdapter adapter) { + adapter.registerSelectedItem(R.string.layer_osm_bugs, settings.SHOW_OSM_BUGS.get() ? 1 : 0, R.drawable.list_activities_osm_bugs, + new OnContextMenuClick() { + + @Override + public void onContextMenuClick(int itemId, int pos, boolean isChecked) { + if (itemId == R.string.layer_osm_bugs) { + settings.SHOW_OSM_BUGS.set(isChecked); + } + + } + }, 5); + + } + + @Override + public String getDescription() { + return app.getString(R.string.osm_editing_plugin_description); + } + + @Override + public String getName() { + return app.getString(R.string.osm_editing_plugin_name); } } diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java index d1fcc988b3..3077237ce5 100644 --- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import net.osmand.osm.LatLon; +import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import android.app.AlertDialog; @@ -37,7 +38,6 @@ public class ContextMenuLayer extends OsmandMapLayer { public String getObjectName(Object o); - public DialogInterface.OnClickListener getActionListener(List actionsList, Object o); } private LatLon latLon; @@ -284,6 +284,7 @@ public class ContextMenuLayer extends OsmandMapLayer { } private void showContextMenuForSelectedObjects() { + final ContextMenuAdapter menuAdapter = new ContextMenuAdapter(activity); if(selectedObjects.size() > 1){ Builder builder = new AlertDialog.Builder(view.getContext()); String[] d = new String[selectedObjects.size()]; @@ -294,21 +295,22 @@ public class ContextMenuLayer extends OsmandMapLayer { builder.setItems(d, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - // single selection at 0 - selectedObjects.set(0, selectedObjects.get(which)); - ArrayList l = new ArrayList(); - OnClickListener listener = selectedContextProvider.getActionListener(l, selectedObjects.get(0)); - activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude(), l, listener); + Object selectedObj = selectedObjects.get(which); + for(OsmandMapLayer layer : view.getLayers()) { + layer.populateObjectContextMenu(selectedObj, menuAdapter); + } + activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude(), menuAdapter, selectedObj); } }); builder.show(); } else { - ArrayList l = new ArrayList(); - OnClickListener listener = selectedContextProvider.getActionListener(l, selectedObjects.get(0)); - activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude(), l, listener); + Object selectedObj = selectedObjects.get(0); + for(OsmandMapLayer layer : view.getLayers()) { + layer.populateObjectContextMenu(selectedObj, menuAdapter); + } + activity.contextMenuPoint(latLon.getLatitude(), latLon.getLongitude(), menuAdapter, selectedObj); } } - @Override public boolean onTouchEvent(MotionEvent event) { diff --git a/OsmAnd/src/net/osmand/plus/views/FavoritesLayer.java b/OsmAnd/src/net/osmand/plus/views/FavoritesLayer.java index bc410896e9..91e6d19b88 100644 --- a/OsmAnd/src/net/osmand/plus/views/FavoritesLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/FavoritesLayer.java @@ -9,7 +9,6 @@ import net.osmand.osm.LatLon; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.R; import android.content.Context; -import android.content.DialogInterface.OnClickListener; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -125,12 +124,6 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I } - @Override - public OnClickListener getActionListener(List actionsList, Object o) { - return null; - } - - @Override public String getObjectDescription(Object o) { if(o instanceof FavouritePoint){ diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java index d408de1ddd..11b521d7f2 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java @@ -1,5 +1,6 @@ package net.osmand.plus.views; +import net.osmand.plus.ContextMenuAdapter; import android.graphics.Canvas; import android.graphics.PointF; import android.graphics.RectF; @@ -14,6 +15,8 @@ public abstract class OsmandMapLayer { public abstract void destroyLayer(); + public void populateObjectContextMenu(Object o, ContextMenuAdapter adapter) {} + public boolean onSingleTap(PointF point) { return false; } diff --git a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java index dd3cd19b92..6625112840 100644 --- a/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/POIMapLayer.java @@ -11,18 +11,16 @@ import net.osmand.access.AccessibleToast; import net.osmand.data.Amenity; import net.osmand.data.AmenityType; import net.osmand.osm.LatLon; -import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.PoiFilter; import net.osmand.plus.R; import net.osmand.plus.ResourceManager; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.render.RenderingIcons; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -298,62 +296,46 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon public boolean drawInScreenPixels() { return true; } - @Override - public OnClickListener getActionListener(List actionsList, Object o) { - final Amenity a = (Amenity) o; - int ind = 0; - final int phoneIndex = a.getPhone() != null ? ind++ : -1; - final int siteIndex = a.getSite() != null ? ind++ : -1; - final int descriptionIndex = a.getDescription() != null ? ind++ : -1; - if(a.getDescription() != null){ - actionsList.add(this.view.getResources().getString(R.string.poi_context_menu_showdescription)); - } - if(a.getPhone() != null){ - actionsList.add(this.view.getResources().getString(R.string.poi_context_menu_call)); - } - if(a.getSite() != null){ - actionsList.add(this.view.getResources().getString(R.string.poi_context_menu_website)); - } - final OsmEditingPlugin editingPlugin = OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class); - final int modifyInd = editingPlugin != null ? ind++ : -1; - final int deleteInd = editingPlugin != null ? ind++ : -1; - if (editingPlugin != null) { - actionsList.add(this.view.getResources().getString(R.string.poi_context_menu_modify)); - actionsList.add(this.view.getResources().getString(R.string.poi_context_menu_delete)); - } - - return new DialogInterface.OnClickListener(){ - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == phoneIndex) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("tel:"+a.getPhone())); //$NON-NLS-1$ - view.getContext().startActivity(intent); - } catch (RuntimeException e) { - log.error("Failed to invoke call", e); //$NON-NLS-1$ - AccessibleToast.makeText(view.getContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); + public void populateObjectContextMenu(Object o, ContextMenuAdapter adapter) { + if(o instanceof Amenity) { + final Amenity a = (Amenity) o; + OnContextMenuClick listener = new ContextMenuAdapter.OnContextMenuClick() { + @Override + public void onContextMenuClick(int itemId, int pos, boolean isChecked) { + if (itemId == R.string.poi_context_menu_call) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("tel:"+a.getPhone())); //$NON-NLS-1$ + view.getContext().startActivity(intent); + } catch (RuntimeException e) { + log.error("Failed to invoke call", e); //$NON-NLS-1$ + AccessibleToast.makeText(view.getContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } else if (itemId == R.string.poi_context_menu_website) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(a.getSite())); + view.getContext().startActivity(intent); + } catch (RuntimeException e) { + log.error("Failed to invoke call", e); //$NON-NLS-1$ + AccessibleToast.makeText(view.getContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } else if (itemId == R.string.poi_context_menu_showdescription) { + showDescriptionDialog(a); } - } else if (which == siteIndex) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(a.getSite())); - view.getContext().startActivity(intent); - } catch (RuntimeException e) { - log.error("Failed to invoke call", e); //$NON-NLS-1$ - AccessibleToast.makeText(view.getContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); - } - } else if (which == descriptionIndex) { - showDescriptionDialog(a); - } else if (which == modifyInd) { - editingPlugin.getPoiActions().showEditDialog(a); - } else if(which == deleteInd) { - editingPlugin.getPoiActions().showDeleteDialog(a); - } else { } + }; + if(a.getDescription() != null){ + adapter.registerItem(R.string.poi_context_menu_showdescription, 0, listener, -1); } - }; + if(a.getPhone() != null){ + adapter.registerItem(R.string.poi_context_menu_call, 0, listener, -1); + } + if(a.getSite() != null){ + adapter.registerItem(R.string.poi_context_menu_website, 0, listener, -1); + } + } } private void showDescriptionDialog(Amenity a) { diff --git a/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java b/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java index 3b6e29ec04..1f66325cb1 100644 --- a/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/TransportStopsLayer.java @@ -9,7 +9,6 @@ import net.osmand.osm.LatLon; import net.osmand.plus.R; import net.osmand.plus.TransportIndexRepository; import android.content.Context; -import android.content.DialogInterface.OnClickListener; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; @@ -156,12 +155,6 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa return false; } - @Override - public OnClickListener getActionListener(List actionsList, Object o) { - return null; - } - - @Override public String getObjectDescription(Object o) { if(o instanceof TransportStop){