diff options
Diffstat (limited to 'main')
| -rw-r--r-- | main/libs/mapsforge-map-0.3.0-jar-with-dependencies.jar | bin | 309184 -> 311239 bytes | |||
| -rw-r--r-- | main/res/layout/init.xml | 31 | ||||
| -rw-r--r-- | main/res/values-de/strings.xml | 13 | ||||
| -rw-r--r-- | main/res/values/strings.xml | 11 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/Settings.java | 78 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/SettingsActivity.java | 32 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/FileList.java | 69 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/maps/CGeoMap.java | 72 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/maps/google/GoogleMapView.java | 11 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java | 9 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java | 30 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java | 13 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/FileUtils.java | 64 |
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 Binary files differindex 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 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(); + } +} |
