aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jarbin309184 -> 311239 bytes
-rw-r--r--main/res/layout/init.xml31
-rw-r--r--main/res/values-de/strings.xml13
-rw-r--r--main/res/values/strings.xml11
-rw-r--r--main/src/cgeo/geocaching/Settings.java78
-rw-r--r--main/src/cgeo/geocaching/SettingsActivity.java32
-rw-r--r--main/src/cgeo/geocaching/files/FileList.java69
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java72
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleMapView.java11
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java9
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java30
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java13
-rw-r--r--main/src/cgeo/geocaching/utils/FileUtils.java64
13 files changed, 378 insertions, 55 deletions
diff --git a/main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jar b/main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jar
index 70d88f4..ee987cc 100644
--- a/main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jar
+++ b/main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jar
Binary files differ
diff --git a/main/res/layout/init.xml b/main/res/layout/init.xml
index d0617fe..c2887e3 100644
--- a/main/res/layout/init.xml
+++ b/main/res/layout/init.xml
@@ -709,6 +709,31 @@
android:scrollHorizontally="true"
android:inputType="textNoSuggestions" />
</LinearLayout>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="left"
+ android:padding="3dip"
+ android:textSize="14dip"
+ android:textColor="?text_color"
+ android:text="@string/init_rendertheme_folder" />
+ <LinearLayout
+ android:id="@+id/init_themefilegroup"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+ <Button style="@style/button_full"
+ android:id="@+id/select_themefolder"
+ android:text="@string/init_select_themefolder"
+ android:layout_width="wrap_content" />
+ <EditText style="@style/edittext_full"
+ android:id="@+id/themefolder"
+ android:singleLine="true"
+ android:lines="1"
+ android:scrollHorizontally="true"
+ android:inputType="textNoSuggestions" />
+ </LinearLayout>
<!-- ** -->
<RelativeLayout style="@style/separator_horizontal_layout" >
<View style="@style/separator_horizontal" />
@@ -818,7 +843,6 @@
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginBottom="5dip"
- android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:padding="3dip"
android:textSize="14dip"
@@ -836,7 +860,6 @@
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginBottom="5dip"
- android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:padding="3dip"
android:textSize="14dip"
@@ -871,11 +894,11 @@
android:id="@+id/webDeviceName"
android:singleLine="true"
android:lines="1"
- android:maxLength="15"
+ android:maxLength="15"
android:scrollHorizontally="true"
android:inputType="textNoSuggestions" />
<TextView
- android:layout_width="wrap_content"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml
index cf21e28..a1f54a1 100644
--- a/main/res/values-de/strings.xml
+++ b/main/res/values-de/strings.xml
@@ -224,8 +224,9 @@
<string name="warn_load_images">c:geo konnte die Bilder nicht laden.</string>
<string name="warn_invalid_mapfile">Die gewählte Datei ist keine gültige Mapsforge-Karte in der Version 0.3.0.\nOffline Karte ist nicht verfügbar.</string>
<string name="warn_deprecated_mapfile">Es wird eine veraltete Offline-Karte v0.2.4 verwendet.\nBitte zukünftig Offline-Karten in der Version 0.3.0 verwenden.\nDer Support für die alte Version wird im nächsten Release eingestellt.</string>
- <string name="warn_nonexistant_mapfile">Die gewählte Datei existiert nicht.\nOffline Karte ist nicht verfügbar.</string>
-
+ <string name="warn_nonexistant_mapfile">Die gewählte Datei existiert nicht.\nOffline Karte ist nicht verfügbar.</string>
+ <string name="warn_rendertheme_missing">Das gewählte Karten-Theme wurde nicht gefunden.</string>
+
<string name="info_log_posted">Log erfolgreich gesendet.</string>
<string name="info_log_saved">Log erfolgreich gespeichert.</string>
<string name="info_log_cleared">Log wurde geleert.</string>
@@ -427,6 +428,7 @@
<string name="init_mapsources_description">Hier kann die Quelle der benutzen Karte gewählt werden. Alternativ zu Google Maps stehen verschiedene OpenStreetMap-Stile zur Verfügung und daneben auch Karten-Dateien für die Offline-Nutzung (siehe http://code.google.com/p/mapsforge/ für die Details).</string>
<string name="init_mapsource_select">Kartenquelle wählen</string>
<string name="init_select_mapfile">…</string>
+ <string name="init_select_themefolder">…</string>
<string name="init_select_gpx_exportdir">…</string>
<string name="init_select_gpx_importdir">…</string>
<string name="init_gpx_exportdir">Verzeichnis für GPX-Exporte</string>
@@ -457,6 +459,7 @@
<string name="init_dbmove_failed">Fehler beim Verschieben der Datenbank.</string>
<string name="init_plain_logs">Logeinträge ohne Farben anzeigen</string>
<string name="init_use_native_ua">Als Android Browser identifizieren. Löst Login-Probleme einiger Netzanbieter.</string>
+ <string name="init_rendertheme_folder">Wähle den Basisordner für offline Karten Themes</string>
<!-- map sources -->
<string name="map_source_google_map">Google: Karte</string>
@@ -653,6 +656,9 @@
<!-- map file select -->
<string name="map_file_select_title">Kartendatei wählen</string>
+ <!-- theme file select -->
+ <string name="theme_file_select_title">Karten-Theme wählen</string>
+
<!-- import -->
<string name="import_title">Importiere…</string>
<string name="web_import_title">Aus dem Internet importieren</string>
@@ -706,10 +712,13 @@
<string name="map_map">Karte</string>
<string name="map_live">Live-Karte</string>
<string name="map_view_map">Karte</string>
+ <string name="map_modes">Karteneinstellungen</string>
<string name="map_trail_show">Spur einblenden</string>
<string name="map_trail_hide">Spur ausblenden</string>
<string name="map_circles_show">Kreise anzeigen</string>
<string name="map_circles_hide">Kreise verbergen</string>
+ <string name="map_theme_builtin">Eingebaute Kartendarstellung</string>
+ <string name="map_theme_select">Kartendarstellung wählen</string>
<string name="map_live_enable">Aktualisierung einschalten</string>
<string name="map_live_disable">Aktualisierung ausschalten</string>
<string name="map_static_title">Statische Karte</string>
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml
index a61918a..2e48af3 100644
--- a/main/res/values/strings.xml
+++ b/main/res/values/strings.xml
@@ -224,7 +224,8 @@
<string name="warn_load_images">c:geo failed to load images.</string>
<string name="warn_invalid_mapfile">The selected map file is not a valid mapsforge version 0.3.0 map file.\nOffline maps are not available.</string>
<string name="warn_deprecated_mapfile">You are using a deprecated version 0.2.4 map file.\nConsider switching to a version 0.3.0 map.\nWe will drop support for version 0.2.4 in the next release.</string>
- <string name="warn_nonexistant_mapfile">The selected map file does not exist.\nOffline maps are not available.</string>
+ <string name="warn_nonexistant_mapfile">The selected map file does not exist.\nOffline maps are not available.</string>
+ <string name="warn_rendertheme_missing">Map theme not found.</string>
<string name="info_log_posted">c:geo successfully submitted the log.</string>
@@ -428,6 +429,7 @@
<string name="init_mapsources_description">Here you can select the source for your maps. As an alternative to Google maps various OpenStreetMap styles are available and even offline map files (See <a href="http://code.google.com/p/mapsforge/">http://code.google.com/p/mapsforge/</a> for details).</string>
<string name="init_mapsource_select">Select Map Source</string>
<string name="init_select_mapfile">…</string>
+ <string name="init_select_themefolder">…</string>
<string name="init_select_gpx_exportdir">…</string>
<string name="init_select_gpx_importdir">…</string>
<string name="init_gpx_exportdir">GPX Export Directory</string>
@@ -458,6 +460,7 @@
<string name="init_dbmove_failed">Failed to move database</string>
<string name="init_plain_logs">Display log entries without colors</string>
<string name="init_use_native_ua">Identify as Android browser. Solves login problems of some network providers.</string>
+ <string name="init_rendertheme_folder">Select base folder for custom off-line map themes</string>
<!-- map sources -->
<string-array name="map_sources">
@@ -666,6 +669,9 @@
<!-- map file select -->
<string name="map_file_select_title">Select map file</string>
+ <!-- theme file select -->
+ <string name="theme_file_select_title">Select custom map theme file</string>
+
<!-- import -->
<string name="import_title">Import…</string>
<string name="web_import_title">Import from web</string>
@@ -732,10 +738,13 @@
<string name="map_map">Map</string>
<string name="map_live">Live map</string>
<string name="map_view_map">Map view</string>
+ <string name="map_modes">Map modes</string>
<string name="map_trail_show">Show trail</string>
<string name="map_trail_hide">Hide trail</string>
<string name="map_circles_show">Show circles</string>
<string name="map_circles_hide">Hide circles</string>
+ <string name="map_theme_builtin">Builtin map theme</string>
+ <string name="map_theme_select">Select map theme</string>
<string name="map_live_enable">Enable live</string>
<string name="map_live_disable">Disable live</string>
<string name="map_static_title">Static maps</string>
diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java
index b4fc94b..2afd32b 100644
--- a/main/src/cgeo/geocaching/Settings.java
+++ b/main/src/cgeo/geocaching/Settings.java
@@ -12,6 +12,8 @@ import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import cgeo.geocaching.maps.interfaces.MapProvider;
import cgeo.geocaching.maps.mapsforge.MapsforgeMapProvider;
import cgeo.geocaching.utils.CryptUtils;
+import cgeo.geocaching.utils.FileUtils;
+import cgeo.geocaching.utils.FileUtils.FileSelector;
import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -25,6 +27,9 @@ import android.content.res.Resources;
import android.os.Environment;
import android.preference.PreferenceManager;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
/**
@@ -96,6 +101,8 @@ public final class Settings {
private static final String KEY_LAST_TRACKABLE_ACTION = "trackableaction";
private static final String KEY_SHARE_AFTER_EXPORT = "shareafterexport";
private static final String KEY_GPX_EXPORT_DIR = "gpxExportDir";
+ private static final String KEY_RENDER_THEME_PATH = "renderthemepath";
+ private static final String KEY_RENDER_THEME_FILE = "renderthemefile";
private static final String KEY_GPX_IMPORT_DIR = "gpxImportDir";
private static final String KEY_PLAIN_LOGS = "plainLogs";
private static final String KEY_NATIVE_UA = "nativeUa";
@@ -1206,7 +1213,76 @@ public final class Settings {
edit.putInt(KEY_LAST_TRACKABLE_ACTION, trackableAction);
}
});
- }
+ }
+
+ public static String getCustomRenderThemeBasefolder() {
+ return sharedPrefs.getString(KEY_RENDER_THEME_PATH, "");
+ }
+
+ public static void setCustomRenderThemeBasefolder(final String customRenderThemeBasefolder) {
+ editSharedSettings(new PrefRunnable() {
+
+ @Override
+ public void edit(Editor edit) {
+ edit.putString(KEY_RENDER_THEME_PATH, customRenderThemeBasefolder);
+ }
+ });
+ }
+
+ public static String getCustomRenderThemeFile() {
+ return sharedPrefs.getString(KEY_RENDER_THEME_FILE, "");
+ }
+
+ public static void setCustomRenderThemeFile(final String customRenderThemeFile) {
+ editSharedSettings(new PrefRunnable() {
+
+ @Override
+ public void edit(Editor edit) {
+ edit.putString(KEY_RENDER_THEME_FILE, customRenderThemeFile);
+ }
+ });
+ }
+
+ public static File[] getMapThemeFiles() {
+
+ File directory = new File(Settings.getCustomRenderThemeBasefolder());
+
+ List<File> result = new ArrayList<File>();
+
+ FileUtils.listDir(result, directory, new ExtensionsBasedFileSelector(new String[] { "xml" }), null);
+
+ return result.toArray(new File[] {});
+ }
+
+ private static class ExtensionsBasedFileSelector extends FileSelector {
+
+ private final String[] _extensions;
+ private boolean _shouldEnd = false;
+
+ public ExtensionsBasedFileSelector(String[] extensions) {
+ _extensions = extensions;
+ }
+
+ @Override
+ public boolean isSelected(File file) {
+ String filename = file.getName();
+ for (String ext : _extensions) {
+ if (StringUtils.endsWithIgnoreCase(filename, ext)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public synchronized boolean shouldEnd() {
+ return _shouldEnd;
+ }
+
+ public synchronized void setShouldEnd(boolean shouldEnd) {
+ _shouldEnd = shouldEnd;
+ }
+ }
public static String getPreferencesName() {
// there is currently no Android API to get the file name of the shared preferences
diff --git a/main/src/cgeo/geocaching/SettingsActivity.java b/main/src/cgeo/geocaching/SettingsActivity.java
index b0870a4..8e14c47 100644
--- a/main/src/cgeo/geocaching/SettingsActivity.java
+++ b/main/src/cgeo/geocaching/SettingsActivity.java
@@ -59,6 +59,7 @@ public class SettingsActivity extends AbstractActivity {
private final static int SELECT_MAPFILE_REQUEST = 1;
private final static int SELECT_GPX_EXPORT_REQUEST = 2;
private final static int SELECT_GPX_IMPORT_REQUEST = 3;
+ private final static int SELECT_THEMEFOLDER_REQUEST = 4;
private ProgressDialog loginDialog = null;
@@ -581,6 +582,20 @@ public class SettingsActivity extends AbstractActivity {
}
});
+ // Theme folder settings
+ initThemefolderEdittext(false);
+
+ Button selectThemefolder = (Button) findViewById(R.id.select_themefolder);
+ selectThemefolder.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Intent dirChooser = new Intent(SettingsActivity.this, SimpleDirChooser.class);
+ dirChooser.putExtra(SimpleDirChooser.START_DIR, Settings.getCustomRenderThemeBasefolder());
+ startActivityForResult(dirChooser, SELECT_THEMEFOLDER_REQUEST);
+ }
+ });
+
// GPX Export directory
final EditText gpxExportDir = (EditText) findViewById(R.id.gpx_exportdir);
gpxExportDir.setText(Settings.getGpxExportDir());
@@ -743,6 +758,14 @@ public class SettingsActivity extends AbstractActivity {
}
}
+ private void initThemefolderEdittext(boolean setFocus) {
+ EditText themeFileEdit = (EditText) findViewById(R.id.themefolder);
+ themeFileEdit.setText(Settings.getCustomRenderThemeBasefolder());
+ if (setFocus) {
+ themeFileEdit.requestFocus();
+ }
+ }
+
/**
* @param view
* unused here but needed since this method is referenced from XML layout
@@ -968,6 +991,15 @@ public class SettingsActivity extends AbstractActivity {
}
});
}
+ if (requestCode == SELECT_THEMEFOLDER_REQUEST) {
+ checkDirectory(resultCode, data, R.id.themefolder, new RunnableWithArgument<String>() {
+
+ @Override
+ public void run(String directory) {
+ Settings.setCustomRenderThemeBasefolder(directory);
+ }
+ });
+ }
}
private void checkDirectory(int resultCode, Intent data, int textField, RunnableWithArgument<String> runnableSetDir) {
diff --git a/main/src/cgeo/geocaching/files/FileList.java b/main/src/cgeo/geocaching/files/FileList.java
index f3622f9..e7bd807 100644
--- a/main/src/cgeo/geocaching/files/FileList.java
+++ b/main/src/cgeo/geocaching/files/FileList.java
@@ -3,10 +3,10 @@ package cgeo.geocaching.files;
import cgeo.geocaching.R;
import cgeo.geocaching.StoredList;
import cgeo.geocaching.activity.AbstractListActivity;
+import cgeo.geocaching.utils.FileUtils;
import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
@@ -151,8 +151,11 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
protected abstract void setTitle();
private class SearchFilesThread extends Thread {
+
+ private final FileListSelector selector = new FileListSelector();
+
public void notifyEnd() {
- endSearching = true;
+ selector.setShouldEnd(true);
}
@Override
@@ -165,7 +168,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
for (final File dir : getBaseFolders())
{
if (dir.exists() && dir.isDirectory()) {
- listDir(list, dir);
+ FileUtils.listDir(list, dir,selector,changeWaitDialogHandler);
if (!list.isEmpty()) {
loaded = true;
break;
@@ -174,7 +177,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
}
if (!loaded) {
changeWaitDialogHandler.sendMessage(Message.obtain(changeWaitDialogHandler, MSG_SEARCH_WHOLE_SD_CARD, Environment.getExternalStorageDirectory().getName()));
- listDirs(list, getStorages());
+ listDirs(list, getStorages(), selector, changeWaitDialogHandler);
}
} else {
Log.w("No external media mounted.");
@@ -198,44 +201,9 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
}
}
- private void listDirs(List<File> list, List<File> directories) {
+ private void listDirs(List<File> list, List<File> directories, FileListSelector selector, Handler feedbackHandler) {
for (final File dir : directories) {
- listDir(list, dir);
- }
- }
-
- private void listDir(List<File> result, File directory) {
- if (directory == null || !directory.isDirectory() || !directory.canRead()) {
- return;
- }
-
- final File[] files = directory.listFiles();
-
- if (ArrayUtils.isNotEmpty(files)) {
- for (File file : files) {
- if (endSearching) {
- return;
- }
- if (!file.canRead()) {
- continue;
- }
- String name = file.getName();
- if (file.isFile()) {
- if (filenameBelongsToList(name)) {
- result.add(file); // add file to list
- }
- } else if (file.isDirectory()) {
- if (name.charAt(0) == '.') {
- continue; // skip hidden directories
- }
- if (name.length() > 16) {
- name = name.substring(0, 14) + '…';
- }
- changeWaitDialogHandler.sendMessage(Message.obtain(changeWaitDialogHandler, 0, name));
-
- listDir(result, file); // go deeper
- }
- }
+ FileUtils.listDir(list, dir, selector, feedbackHandler);
}
}
@@ -322,4 +290,23 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
}
}
}
+
+ private class FileListSelector extends FileUtils.FileSelector {
+
+ boolean _shouldEnd = false;
+
+ @Override
+ public boolean isSelected(File file) {
+ return filenameBelongsToList(file.getName());
+ }
+
+ @Override
+ public boolean shouldEnd() {
+ return _shouldEnd;
+ }
+
+ public void setShouldEnd(boolean shouldEnd) {
+ _shouldEnd = shouldEnd;
+ }
+ }
}
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index bec7f0b..4f003a5 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -42,6 +42,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import android.app.Activity;
+import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -65,6 +66,7 @@ import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -114,14 +116,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private static final int MENU_SELECT_MAPVIEW = 1;
private static final int MENU_MAP_LIVE = 2;
private static final int MENU_STORE_CACHES = 3;
- private static final int MENU_TRAIL_MODE = 4;
+ private static final int SUBMENU_MODES = 4;
+ private static final int MENU_TRAIL_MODE = 81;
+ private static final int MENU_THEME_MODE = 82;
+ private static final int MENU_CIRCLE_MODE = 83;
private static final int SUBMENU_STRATEGY = 5;
private static final int MENU_STRATEGY_FASTEST = 51;
private static final int MENU_STRATEGY_FAST = 52;
private static final int MENU_STRATEGY_AUTO = 53;
private static final int MENU_STRATEGY_DETAILED = 74;
- private static final int MENU_CIRCLE_MODE = 6;
private static final int MENU_AS_LIST = 7;
private static final String BUNDLE_MAP_SOURCE = "mapSource";
@@ -537,7 +541,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
menu.add(0, MENU_MAP_LIVE, 0, res.getString(R.string.map_live_disable)).setIcon(R.drawable.ic_menu_refresh);
menu.add(0, MENU_STORE_CACHES, 0, res.getString(R.string.caches_store_offline)).setIcon(R.drawable.ic_menu_set_as).setEnabled(false);
- menu.add(0, MENU_TRAIL_MODE, 0, res.getString(R.string.map_trail_hide)).setIcon(R.drawable.ic_menu_trail);
+ SubMenu subMenuModes = menu.addSubMenu(0, SUBMENU_MODES, 0, res.getString(R.string.map_modes)).setIcon(R.drawable.ic_menu_mark);
+ subMenuModes.add(0, MENU_TRAIL_MODE, 0, res.getString(R.string.map_trail_hide)).setIcon(R.drawable.ic_menu_trail);
+ subMenuModes.add(0, MENU_CIRCLE_MODE, 0, res.getString(R.string.map_circles_hide)).setIcon(R.drawable.ic_menu_circle);
+ subMenuModes.add(0, MENU_THEME_MODE, 0, res.getString(R.string.map_theme_select)).setIcon(R.drawable.ic_menu_preferences);
Strategy strategy = Settings.getLiveMapStrategy();
SubMenu subMenuStrategy = menu.addSubMenu(0, SUBMENU_STRATEGY, 0, res.getString(R.string.map_strategy)).setIcon(R.drawable.ic_menu_preferences);
@@ -548,7 +555,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
subMenuStrategy.add(2, MENU_STRATEGY_DETAILED, 0, Strategy.DETAILED.getL10n()).setCheckable(true).setChecked(strategy == Strategy.DETAILED);
subMenuStrategy.setGroupCheckable(2, true, true);
- menu.add(0, MENU_CIRCLE_MODE, 0, res.getString(R.string.map_circles_hide)).setIcon(R.drawable.ic_menu_circle);
menu.add(0, MENU_AS_LIST, 0, res.getString(R.string.map_as_list)).setIcon(R.drawable.ic_menu_agenda);
return true;
@@ -598,6 +604,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
item.setTitle(res.getString(R.string.map_circles_show));
}
+ item = menu.findItem(MENU_THEME_MODE); // show theme selection
+ item.setVisible(mapView.hasMapThemes());
+
menu.findItem(MENU_AS_LIST).setEnabled(isLiveEnabled && !isLoading());
menu.findItem(SUBMENU_STRATEGY).setEnabled(isLiveEnabled);
@@ -693,6 +702,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
mapView.repaintRequired(overlayCaches);
ActivityMixin.invalidateOptionsMenu(activity);
return true;
+ case MENU_THEME_MODE:
+ selectMapTheme();
+ return true;
case MENU_AS_LIST: {
cgeocaches.startActivityMap(activity, new SearchResult(getGeocodesForCachesInViewport()));
return true;
@@ -730,6 +742,57 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
return false;
}
+ private void selectMapTheme() {
+
+ final File[] themeFiles = Settings.getMapThemeFiles();
+
+ String currentTheme = StringUtils.EMPTY;
+ int currentItem = 0;
+ if (StringUtils.isNotEmpty(Settings.getCustomRenderThemeFile())) {
+ File currentThemeFile = new File(Settings.getCustomRenderThemeFile());
+ currentTheme = currentThemeFile.getName();
+ }
+
+ int index = 0;
+ List<String> names = new ArrayList<String>();
+ names.add(res.getString(R.string.map_theme_builtin));
+ for (File file : themeFiles) {
+ index++;
+ if (currentTheme.equalsIgnoreCase(file.getName())) {
+ currentItem = index;
+ }
+ names.add(file.getName());
+ }
+
+ final int selectedItem = currentItem;
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+
+ builder.setTitle(R.string.map_theme_select);
+
+ builder.setSingleChoiceItems(names.toArray(new String[] {}), selectedItem,
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int newItem) {
+ if (newItem == selectedItem) {
+ // no change
+ } else {
+ // Adjust index because of <default> selection
+ if (newItem > 0) {
+ Settings.setCustomRenderThemeFile(themeFiles[newItem - 1].getPath());
+ } else {
+ Settings.setCustomRenderThemeFile(StringUtils.EMPTY);
+ }
+ mapView.setMapTheme();
+ }
+ dialog.cancel();
+ }
+ });
+
+ builder.show();
+ }
+
/**
* @return a Set of geocodes corresponding to the caches that are shown on screen.
*/
@@ -774,6 +837,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
mapRestart();
} else if (mapView != null) {
mapView.setMapSource();
+ ActivityMixin.invalidateOptionsMenu(activity);
}
return restartRequired;
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
index f43b6a4..9c134a4 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
@@ -189,4 +189,15 @@ public class GoogleMapView extends MapView implements MapViewImpl {
public boolean needsInvertedColors() {
return false;
}
+
+ @Override
+ public boolean hasMapThemes() {
+ // Not supported
+ return false;
+ }
+
+ @Override
+ public void setMapTheme() {
+ // Not supported
+ }
}
diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
index ad481cb..5481891 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
@@ -75,4 +75,13 @@ public interface MapViewImpl {
Viewport getViewport();
+ /**
+ * Indicates if the current map view supports different themes
+ * for map rendering
+ *
+ * @return true - supports custom themes, false - does not support custom themes
+ */
+ boolean hasMapThemes();
+
+ void setMapTheme();
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
index 3dd58a7..40b0f11 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
@@ -18,6 +18,7 @@ import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.maps.interfaces.OverlayImpl.overlayType;
import cgeo.geocaching.utils.Log;
+import org.apache.commons.lang3.StringUtils;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.Projection;
import org.mapsforge.android.maps.mapgenerator.MapGenerator;
@@ -37,6 +38,7 @@ import android.view.MotionEvent;
import android.widget.Toast;
import java.io.File;
+import java.io.FileNotFoundException;
public class MapsforgeMapView extends MapView implements MapViewImpl {
private GestureDetector gestureDetector;
private OnMapDragListener onDragListener;
@@ -178,7 +180,7 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
/**
* Get the actual map zoom level
- *
+ *
* @return the current map zoom level with no adjustments
*/
private int getActualMapZoomLevel() {
@@ -221,6 +223,32 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
.show();
}
}
+ if (hasMapThemes()) {
+ setMapTheme();
+ }
+ }
+
+ @Override
+ public boolean hasMapThemes() {
+ return !getMapGenerator().requiresInternetConnection();
+ }
+
+ @Override
+ public void setMapTheme() {
+ String customRenderTheme = Settings.getCustomRenderThemeFile();
+ if (!StringUtils.isEmpty(customRenderTheme)) {
+ try {
+ setRenderTheme(new File(customRenderTheme));
+ } catch (FileNotFoundException e) {
+ Toast.makeText(
+ getContext(),
+ getContext().getResources().getString(R.string.warn_rendertheme_missing),
+ Toast.LENGTH_LONG)
+ .show();
+ }
+ } else {
+ setRenderTheme(DEFAULT_RENDER_THEME);
+ }
}
@Override
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
index a459804..d177a47 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
@@ -161,7 +161,7 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl {
/**
* Get the map zoom level which is compatible with Google Maps.
- *
+ *
* @return the current map zoom level +1
*/
@Override
@@ -247,4 +247,15 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl {
public boolean needsInvertedColors() {
return false;
}
+
+ @Override
+ public boolean hasMapThemes() {
+ // not supported
+ return false;
+ }
+
+ @Override
+ public void setMapTheme() {
+ // not supported
+ }
}
diff --git a/main/src/cgeo/geocaching/utils/FileUtils.java b/main/src/cgeo/geocaching/utils/FileUtils.java
new file mode 100644
index 0000000..6fefc02
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/FileUtils.java
@@ -0,0 +1,64 @@
+package cgeo.geocaching.utils;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Utiliy class for files
+ *
+ * @author rsudev
+ *
+ */
+public class FileUtils {
+
+ public static void listDir(List<File> result, File directory, FileSelector chooser, Handler feedBackHandler) {
+
+ if (directory == null || !directory.isDirectory() || !directory.canRead()
+ || result == null
+ || chooser == null) {
+ return;
+ }
+
+ final File[] files = directory.listFiles();
+
+ if (ArrayUtils.isNotEmpty(files)) {
+ for (File file : files) {
+ if (chooser.shouldEnd()) {
+ return;
+ }
+ if (!file.canRead()) {
+ continue;
+ }
+ String name = file.getName();
+ if (file.isFile()) {
+ if (chooser.isSelected(file)) {
+ result.add(file); // add file to list
+ }
+ } else if (file.isDirectory()) {
+ if (name.charAt(0) == '.') {
+ continue; // skip hidden directories
+ }
+ if (name.length() > 16) {
+ name = name.substring(0, 14) + '…';
+ }
+ if (feedBackHandler != null) {
+ feedBackHandler.sendMessage(Message.obtain(feedBackHandler, 0, name));
+ }
+
+ listDir(result, file, chooser, feedBackHandler); // go deeper
+ }
+ }
+ }
+ }
+
+ public static abstract class FileSelector {
+ public abstract boolean isSelected(File file);
+
+ public abstract boolean shouldEnd();
+ }
+}