diff options
Diffstat (limited to 'main/src')
53 files changed, 1183 insertions, 797 deletions
diff --git a/main/src/cgeo/calendar/ICalendar.java b/main/src/cgeo/calendar/ICalendar.java new file mode 100644 index 0000000..bc08ef4 --- /dev/null +++ b/main/src/cgeo/calendar/ICalendar.java @@ -0,0 +1,16 @@ +package cgeo.calendar; + +public interface ICalendar { + static final String INTENT = "cgeo.calendar.RESERVE"; + + static final String URI_SCHEME = "add"; + static final String URI_HOST = "cgeo.org"; + + static final String PARAM_SHORT_DESC = "shortDesc"; // cache short description + static final String PARAM_HIDDEN_DATE = "hiddenDate"; // cache hidden date in milliseconds + static final String PARAM_URL = "url"; // cache URL + static final String PARAM_NOTE = "note"; // personal note + static final String PARAM_NAME = "name"; // cache name + static final String PARAM_LOCATION = "location"; // cache location, or empty string + static final String PARAM_COORDS = "coords"; // cache coords, or empty string +} diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index 325ef38..1f7edb9 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -1,5 +1,6 @@ package cgeo.geocaching; +import cgeo.calendar.ICalendar; import cgeo.geocaching.cgData.StorageLocation; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.activity.Progress; @@ -9,8 +10,10 @@ import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.enumerations.LogType; +import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.network.HtmlImage; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.CryptUtils; @@ -524,6 +527,7 @@ public class CacheDetailActivity extends AbstractActivity { return true; } else if (menuItem == MENU_CALENDAR) { addToCalendar(); + //addToCalendarWithIntent(); return true; } else if (menuItem == MENU_SHARE) { if (cache != null) { @@ -726,6 +730,23 @@ public class CacheDetailActivity extends AbstractActivity { finish(); } + private void addToCalendarWithIntent() { + // this method is NOT unused :) + final Parameters params = new Parameters( + ICalendar.PARAM_NAME, cache.getName(), + ICalendar.PARAM_NOTE, StringUtils.defaultString(cache.getPersonalNote()), + ICalendar.PARAM_HIDDEN_DATE, String.valueOf(cache.getHiddenDate().getTime()), + ICalendar.PARAM_URL, StringUtils.defaultString(cache.getUrl()), + ICalendar.PARAM_COORDS, cache.getCoords() == null ? "" : cache.getCoords().format(GeopointFormatter.Format.LAT_LON_DECMINUTE_RAW), + ICalendar.PARAM_LOCATION, StringUtils.defaultString(cache.getLocation()), + ICalendar.PARAM_SHORT_DESC, StringUtils.defaultString(cache.getShortDescription()) + ); + + // TODO: Check if addon is installed, if not, tell the user how to get it. + startActivity(new Intent(ICalendar.INTENT, + Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST + "?" + params.toString()))); + } + /** * Adds the cache to the Android-calendar if it is an event. */ @@ -2421,8 +2442,8 @@ public class CacheDetailActivity extends AbstractActivity { // info final List<String> infoTextList = new ArrayList<String>(3); - if (StringUtils.isNotBlank(cgBase.waypointTypes.get(wpt.getWaypointType()))) { - infoTextList.add(cgBase.waypointTypes.get(wpt.getWaypointType())); + if (WaypointType.ALL_TYPES_EXCEPT_OWN.containsKey(wpt.getWaypointType())) { + infoTextList.add(wpt.getWaypointType().getL10n()); } if (cgWaypoint.PREFIX_OWN.equalsIgnoreCase(wpt.getPrefix())) { infoTextList.add(res.getString(R.string.waypoint_custom)); diff --git a/main/src/cgeo/geocaching/GCConstants.java b/main/src/cgeo/geocaching/GCConstants.java index 52815ff..40fc248 100644 --- a/main/src/cgeo/geocaching/GCConstants.java +++ b/main/src/cgeo/geocaching/GCConstants.java @@ -66,7 +66,7 @@ public final class GCConstants { /** * Patterns for parsing trackables */ - public final static Pattern PATTERN_TRACKABLE_ID = Pattern.compile("<a id=\"ctl00_ContentBody_LogLink\" title=\"[^\"]*\" href=\".*log\\.aspx\\?wid=([a-z0-9\\-]+)\"[^>]*>[^<]*</a>"); + public final static Pattern PATTERN_TRACKABLE_GUID = Pattern.compile("<a id=\"ctl00_ContentBody_lnkPrint\" title=\"[^\"]*\" href=\".*sheet\\.aspx\\?guid=([a-z0-9\\-]+)\"[^>]*>[^<]*</a>"); public final static Pattern PATTERN_TRACKABLE_GEOCODE = Pattern.compile("<span id=\"ctl00_ContentBody_BugDetails_BugTBNum\" String=\"[^\"]*\">Use[^<]*<strong>(TB[0-9A-Z]+)[^<]*</strong> to reference this item.[^<]*</span>"); public final static Pattern PATTERN_TRACKABLE_NAME = Pattern.compile("<h2[^>]*>(?:[^<]*<img[^>]*>)?[^<]*<span id=\"ctl00_ContentBody_lbHeading\">([^<]+)</span>[^<]*</h2>"); /** Two groups ! */ diff --git a/main/src/cgeo/geocaching/ParseResult.java b/main/src/cgeo/geocaching/ParseResult.java index ee5bfe5..180b9c4 100644 --- a/main/src/cgeo/geocaching/ParseResult.java +++ b/main/src/cgeo/geocaching/ParseResult.java @@ -3,8 +3,7 @@ package cgeo.geocaching; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import java.util.Set; /** @@ -12,7 +11,7 @@ import java.util.Set; */ public class ParseResult extends SearchResult { - public List<cgCache> cacheList = new ArrayList<cgCache>(); + public Set<cgCache> cacheList = new HashSet<cgCache>(); public ParseResult() { super(); diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java index 4611560..49f36a5 100644 --- a/main/src/cgeo/geocaching/Settings.java +++ b/main/src/cgeo/geocaching/Settings.java @@ -29,6 +29,7 @@ public final class Settings { private static final String KEY_ANYLATITUDE = "anylatitude"; private static final String KEY_PUBLICLOC = "publicloc"; private static final String KEY_USE_OFFLINEMAPS = "offlinemaps"; + private static final String KEY_USE_OFFLINEWPMAPS = "offlinewpmaps"; private static final String KEY_WEB_DEVICE_CODE = "webDeviceCode"; private static final String KEY_WEBDEVICE_NAME = "webDeviceName"; private static final String KEY_MAP_LIVE = "maplive"; @@ -314,7 +315,7 @@ public final class Settings { } public static int getLastList() { - final int listId = sharedPrefs.getInt(KEY_LAST_USED_LIST, -1); + final int listId = sharedPrefs.getInt(KEY_LAST_USED_LIST, StoredList.STANDARD_LIST_ID); return listId; } @@ -545,6 +546,20 @@ public final class Settings { }); } + public static boolean isStoreOfflineWpMaps() { + return 0 != sharedPrefs.getInt(KEY_USE_OFFLINEWPMAPS, 1); + } + + public static void setStoreOfflineWpMaps(final boolean offlineMaps) { + editSharedSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_USE_OFFLINEWPMAPS, offlineMaps ? 1 : 0); + } + }); + } + public static boolean isStoreLogImages() { return sharedPrefs.getBoolean(KEY_STORE_LOG_IMAGES, false); } diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java index b33d17d..8155154 100644 --- a/main/src/cgeo/geocaching/StaticMapsActivity.java +++ b/main/src/cgeo/geocaching/StaticMapsActivity.java @@ -21,6 +21,7 @@ import java.util.List; public class StaticMapsActivity extends AbstractActivity { private final List<Bitmap> maps = new ArrayList<Bitmap>(); + private Integer waypoint_id = null; private String geocode = null; private LayoutInflater inflater = null; private ProgressDialog waitDialog = null; @@ -85,6 +86,9 @@ public class StaticMapsActivity extends AbstractActivity { // try to get data from extras if (extras != null) { geocode = extras.getString("geocode"); + if (extras.containsKey("waypoint")) { + waypoint_id = extras.getInt("waypoint"); + } } if (geocode == null) { @@ -116,9 +120,16 @@ public class StaticMapsActivity extends AbstractActivity { for (int level = 1; level <= 5; level++) { try { - final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, level, false).getPath()); - if (image != null) { - maps.add(image); + if (waypoint_id != null) { + final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, "wp" + waypoint_id + "_", level, false).getPath()); + if (image != null) { + maps.add(image); + } + } else { + final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, "", level, false).getPath()); + if (image != null) { + maps.add(image); + } } } catch (Exception e) { Log.e(Settings.tag, "StaticMapsActivity.LoadMapsThread.run.1: " + e.toString()); @@ -128,9 +139,16 @@ public class StaticMapsActivity extends AbstractActivity { if (maps.isEmpty()) { for (int level = 1; level <= 5; level++) { try { - final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, level, false).getPath()); - if (image != null) { - maps.add(image); + if (waypoint_id != null) { + final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, "wp" + waypoint_id + "_", level, false).getPath()); + if (image != null) { + maps.add(image); + } + } else { + final Bitmap image = BitmapFactory.decodeFile(StaticMapsProvider.getMapFile(geocode, "", level, false).getPath()); + if (image != null) { + maps.add(image); + } } } catch (Exception e) { Log.e(Settings.tag, "StaticMapsActivity.LoadMapsThread.run.2: " + e.toString()); diff --git a/main/src/cgeo/geocaching/StaticMapsProvider.java b/main/src/cgeo/geocaching/StaticMapsProvider.java index 3176c9f..123dbce 100644 --- a/main/src/cgeo/geocaching/StaticMapsProvider.java +++ b/main/src/cgeo/geocaching/StaticMapsProvider.java @@ -3,11 +3,13 @@ package cgeo.geocaching; import cgeo.geocaching.files.LocalStorage; import cgeo.geocaching.geopoint.GeopointFormatter.Format; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import android.app.Activity; import android.content.Context; +import android.util.Log; import android.view.Display; import android.view.WindowManager; @@ -20,25 +22,22 @@ public class StaticMapsProvider { */ private static final int MIN_MAP_IMAGE_BYTES = 6000; - public static File getMapFile(final String geocode, final int level, final boolean createDirs) { - return LocalStorage.getStorageFile(geocode, "map_" + level, false, createDirs); + public static File getMapFile(final String geocode, String prefix, final int level, final boolean createDirs) { + return LocalStorage.getStorageFile(geocode, "map_" + prefix + level, false, createDirs); } - private static void downloadMapsInThread(final cgCache cache, String latlonMap, int edge, String waypoints) { - downloadMap(cache, 20, "satellite", 1, latlonMap, edge, waypoints); - downloadMap(cache, 18, "satellite", 2, latlonMap, edge, waypoints); - downloadMap(cache, 16, "roadmap", 3, latlonMap, edge, waypoints); - downloadMap(cache, 14, "roadmap", 4, latlonMap, edge, waypoints); - downloadMap(cache, 11, "roadmap", 5, latlonMap, edge, waypoints); + private static void downloadMapsInThread(final cgCache cache, String markerUrl, String prefix, String latlonMap, int edge, String waypoints) { + downloadMap(cache, 20, "satellite", markerUrl, prefix, 1, latlonMap, edge, waypoints); + downloadMap(cache, 18, "satellite", markerUrl, prefix, 2, latlonMap, edge, waypoints); + downloadMap(cache, 16, "roadmap", markerUrl, prefix, 3, latlonMap, edge, waypoints); + downloadMap(cache, 14, "roadmap", markerUrl, prefix, 4, latlonMap, edge, waypoints); + downloadMap(cache, 11, "roadmap", markerUrl, prefix, 5, latlonMap, edge, waypoints); } - private static void downloadMap(cgCache cache, int zoom, String mapType, int level, String latlonMap, int edge, String waypoints) { + private static void downloadMap(cgCache cache, int zoom, String mapType, String markerUrl, String prefix, int level, String latlonMap, int edge, String waypoints) { final String mapUrl = "http://maps.google.com/maps/api/staticmap?center=" + latlonMap; - final String markerUrl = getMarkerUrl(cache); - final String url = mapUrl + "&zoom=" + zoom + "&size=" + edge + "x" + edge + "&maptype=" + mapType + "&markers=icon%3A" + markerUrl + "%7C" + latlonMap + waypoints + "&sensor=false"; - - final File file = getMapFile(cache.getGeocode(), level, true); + final File file = getMapFile(cache.getGeocode(), prefix, level, true); final HttpResponse httpResponse = cgBase.request(url, null, false); if (httpResponse != null) { @@ -53,54 +52,85 @@ public class StaticMapsProvider { } public static void downloadMaps(cgCache cache, Activity activity) { - if (!Settings.isStoreOfflineMaps() || cache.getCoords() == null || StringUtils.isBlank(cache.getGeocode())) { + if ((!Settings.isStoreOfflineMaps() && !Settings.isStoreOfflineWpMaps()) || StringUtils.isBlank(cache.getGeocode())) { return; } - final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); - final Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - final int maxWidth = display.getWidth() - 25; - final int maxHeight = display.getHeight() - 25; - int edge = 0; - if (maxWidth > maxHeight) { - edge = maxWidth; - } else { - edge = maxHeight; + int edge = guessMinDisplaySide(activity); + + if (Settings.isStoreOfflineMaps() && cache.getCoords() != null) { + storeCacheStaticMap(cache, edge); } + // download static map for current waypoints + if (Settings.isStoreOfflineWpMaps() && CollectionUtils.isNotEmpty(cache.getWaypoints())) { + for (cgWaypoint waypoint : cache.getWaypoints()) { + storeWaypointStaticMap(cache, edge, waypoint); + } + } + } + + public static void storeWaypointStaticMap(cgCache cache, Activity activity, cgWaypoint waypoint) { + int edge = StaticMapsProvider.guessMinDisplaySide(activity); + storeWaypointStaticMap(cache, edge, waypoint); + } + + private static void storeWaypointStaticMap(cgCache cache, int edge, cgWaypoint waypoint) { + if (waypoint.getCoords() == null) { + return; + } + String wpLatlonMap = waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); + String wpMarkerUrl = getWpMarkerUrl(waypoint); + // download map images in separate background thread for higher performance + downloadMaps(cache, wpMarkerUrl, "wp" + waypoint.getId() + "_", wpLatlonMap, edge, ""); + } + + private static void storeCacheStaticMap(cgCache cache, int edge) { + final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); final StringBuilder waypoints = new StringBuilder(); if (cache.hasWaypoints()) { for (cgWaypoint waypoint : cache.getWaypoints()) { if (waypoint.getCoords() == null) { continue; } - + String wpMarkerUrl = getWpMarkerUrl(waypoint); waypoints.append("&markers=icon%3A"); - waypoints.append(MARKERS_URL); - waypoints.append("marker_waypoint_"); - waypoints.append(waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null); - waypoints.append(".png%7C"); + waypoints.append(wpMarkerUrl); + waypoints.append("%7C"); waypoints.append(waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA)); } } - // download map images in separate background thread for higher performance - downloadMaps(cache, latlonMap, edge, waypoints.toString()); + final String cacheMarkerUrl = getCacheMarkerUrl(cache); + downloadMaps(cache, cacheMarkerUrl, "", latlonMap, edge, waypoints.toString()); + } + + private static int guessMinDisplaySide(Activity activity) { + final Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + final int maxWidth = display.getWidth() - 25; + final int maxHeight = display.getHeight() - 25; + int edge = 0; + if (maxWidth > maxHeight) { + edge = maxWidth; + } else { + edge = maxHeight; + } + return edge; } - private static void downloadMaps(final cgCache cache, final String latlonMap, final int edge, + private static void downloadMaps(final cgCache cache, final String markerUrl, final String prefix, final String latlonMap, final int edge, final String waypoints) { - final Thread staticMapsThread = new Thread("getting static map") { + Thread staticMapsThread = new Thread("getting static map") { @Override public void run() { - downloadMapsInThread(cache, latlonMap, edge, waypoints); + downloadMapsInThread(cache, markerUrl, prefix, latlonMap, edge, waypoints); } }; staticMapsThread.setPriority(Thread.MIN_PRIORITY); staticMapsThread.start(); } - private static String getMarkerUrl(final cgCache cache) { + private static String getCacheMarkerUrl(final cgCache cache) { String type = cache.getType().id; if (cache.isFound()) { type += "_found"; @@ -110,4 +140,21 @@ public class StaticMapsProvider { return cgBase.urlencode_rfc3986(MARKERS_URL + "marker_cache_" + type + ".png"); } + + private static String getWpMarkerUrl(final cgWaypoint waypoint) { + String type = waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null; + return cgBase.urlencode_rfc3986(MARKERS_URL + "marker_waypoint_" + type + ".png"); + } + + public static void removeWpStaticMaps(int wp_id, String geocode) { + for (int level = 1; level <= 5; level++) { + try { + if (wp_id > 0) { + StaticMapsProvider.getMapFile(geocode, "wp" + wp_id + "_", level, false).delete(); + } + } catch (Exception e) { + Log.e(Settings.tag, "StaticMapsProvider.removeWpStaticMaps: " + e.toString()); + } + } + } } diff --git a/main/src/cgeo/geocaching/UsefulAppsActivity.java b/main/src/cgeo/geocaching/UsefulAppsActivity.java new file mode 100644 index 0000000..d4418ab --- /dev/null +++ b/main/src/cgeo/geocaching/UsefulAppsActivity.java @@ -0,0 +1,78 @@ +package cgeo.geocaching; + +import cgeo.geocaching.activity.AbstractActivity; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.Locale; + +public class UsefulAppsActivity extends AbstractActivity { + + private LinearLayout parentLayout; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + setTheme(); + setContentView(R.layout.useful_apps); + setTitle(res.getString(R.string.helpers)); + parentLayout = (LinearLayout) findViewById(R.id.parent); + + final Locale loc = Locale.getDefault(); + final String language = loc.getLanguage(); + + final String tutorialUrl; + if ("de".equalsIgnoreCase(language)) { + tutorialUrl = "gnu.android.app.cgeomanual.de"; + } + else { + tutorialUrl = "gnu.android.app.cgeomanual.en"; + } + addApp(R.string.helper_manual_title, R.string.helper_manual_description, R.drawable.helper_manual, tutorialUrl); + addApp(R.string.helper_calendar_title, R.string.helper_calendar_description, R.drawable.cgeo, "cgeo.calendar"); + addApp(R.string.helper_locus_title, R.string.helper_locus_description, R.drawable.helper_locus, "menion.android.locus"); + addApp(R.string.helper_gpsstatus_title, R.string.helper_gpsstatus_description, R.drawable.helper_gpsstatus, "com.eclipsim.gpsstatus2"); + addApp(R.string.helper_bluetoothgps_title, R.string.helper_bluetoothgps_description, R.drawable.helper_bluetoothgps, "googoo.android.btgps"); + } + + @Override + public void onResume() { + super.onResume(); + + } + + private void installFromMarket(String marketId) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:" + marketId))); + } catch (Exception e) { + // market not available in standard emulator + } + + finish(); + } + + private void addApp(final int titleId, final int descriptionId, final int imageId, final String marketUrl) { + final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.useful_apps_item, null); + ((TextView) layout.findViewById(R.id.title)).setText(res.getString(titleId)); + ((ImageView) layout.findViewById(R.id.image)).setImageDrawable(res.getDrawable(imageId)); + ((TextView) layout.findViewById(R.id.description)).setText(res.getString(descriptionId)); + ((LinearLayout) layout.findViewById(R.id.app_layout)).setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + installFromMarket(marketUrl); + } + }); + parentLayout.addView(layout); + } + +} diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java index d0e8a5e..f3a1cbe 100644 --- a/main/src/cgeo/geocaching/VisitCacheActivity.java +++ b/main/src/cgeo/geocaching/VisitCacheActivity.java @@ -1,12 +1,14 @@ package cgeo.geocaching; -import cgeo.geocaching.LogTemplateProvider.LogTemplate; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.LogTypeTrackable; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.gcvote.GCVote; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.ui.DateDialog; +import cgeo.geocaching.utils.LogTemplateProvider; +import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index 81c53db..e700c72 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -20,6 +20,7 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi protected cgeoapplication app = null; protected Resources res = null; + private boolean keepScreenOn = false; protected AbstractActivity() { this(null); @@ -29,6 +30,11 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi this.helpTopic = helpTopic; } + protected AbstractActivity(final String helpTopic, final boolean keepScreenOn) { + this(helpTopic); + this.keepScreenOn = keepScreenOn; + } + final public void goHome(final View view) { ActivityMixin.goHome(this); } @@ -77,6 +83,8 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi // Restore cookie store if needed cgBase.restoreCookieStore(Settings.getCookieStore()); + + ActivityMixin.keepScreenOn(this, keepScreenOn); } public void addVisitMenu(Menu menu, cgCache cache) { @@ -86,4 +94,5 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi protected static void disableSuggestions(final EditText edit) { Compatibility.disableSuggestions(edit); } + } diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index 10e73a5..00e04cf 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -15,6 +15,7 @@ public abstract class AbstractListActivity extends ListActivity implements IAbstractActivity { private String helpTopic; + private boolean keepScreenOn = false; protected cgeoapplication app = null; protected Resources res = null; @@ -23,6 +24,11 @@ public abstract class AbstractListActivity extends ListActivity implements this(null); } + protected AbstractListActivity(final boolean keepScreenOn) { + this(null); + this.keepScreenOn = keepScreenOn; + } + protected AbstractListActivity(final String helpTopic) { this.helpTopic = helpTopic; } @@ -67,6 +73,8 @@ public abstract class AbstractListActivity extends ListActivity implements res = this.getResources(); app = (cgeoapplication) this.getApplication(); cgBase.initialize(app); + + ActivityMixin.keepScreenOn(this, keepScreenOn); } final public void setTitle(final String title) { diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index a3afc11..30bc7bb 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -19,6 +19,7 @@ import android.view.Gravity; import android.view.Menu; import android.view.SubMenu; import android.view.View; +import android.view.WindowManager; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -146,4 +147,10 @@ public final class ActivityMixin { menu.add(1, IAbstractActivity.MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)).setIcon(MENU_ICON_LOG_VISIT); } } + + public static void keepScreenOn(final Activity abstractActivity, boolean keepScreenOn) { + if (keepScreenOn) { + abstractActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java index 6a29895..0bf2f56 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java @@ -2,10 +2,10 @@ package cgeo.geocaching.apps.cache.navi; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; +import cgeo.geocaching.StaticMapsActivity; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; -import cgeo.geocaching.StaticMapsActivity; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.geopoint.Geopoint; @@ -28,18 +28,24 @@ class StaticMapApp extends AbstractNavigationApp { public boolean invoke(cgGeo geo, Activity activity, cgCache cache, final SearchResult search, cgWaypoint waypoint, final Geopoint coords) { - if (cache == null || cache.getListId() == 0) { + String geocode = null; + if (cache != null && cache.getListId() != 0) { + geocode = cache.getGeocode().toUpperCase(); + } + if (waypoint != null) { + geocode = waypoint.getGeocode().toUpperCase(); + } + if (geocode == null) { ActivityMixin.showToast(activity, getString(R.string.err_detail_no_map_static)); return true; - } - - if (cache.getGeocode() != null) { + } else { final Intent intent = new Intent(activity, StaticMapsActivity.class); - intent.putExtra("geocode", cache.getGeocode().toUpperCase()); + intent.putExtra("geocode", geocode); + if (waypoint != null) { + intent.putExtra("waypoint", waypoint.getId()); + } activity.startActivity(intent); return true; } - return false; } - } diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index c4a2f24..844eed9 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -19,6 +19,7 @@ import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.geopoint.IConversion; import cgeo.geocaching.geopoint.Viewport; import cgeo.geocaching.network.HtmlImage; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.Twitter; import cgeo.geocaching.ui.DirectionImage; import cgeo.geocaching.utils.BaseUtils; @@ -92,6 +93,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import javax.net.ssl.HostnameVerifier; @@ -101,7 +103,6 @@ public class cgBase { private static final String passMatch = "(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+"; - public final static Map<WaypointType, String> waypointTypes = new HashMap<WaypointType, String>(); private final static Map<String, SimpleDateFormat> gcCustomDateFormats; static { final String[] formats = new String[] { @@ -149,12 +150,6 @@ public class cgBase { context = app.getBaseContext(); res = app.getBaseContext().getResources(); - // waypoint types - for (WaypointType wt : WaypointType.values()) { - if (wt != WaypointType.OWN) { - waypointTypes.put(wt, res.getString(wt.stringId)); - } - } try { final PackageManager manager = app.getPackageManager(); @@ -788,7 +783,7 @@ public class cgBase { public static ParseResult parseCache(final String page, final int listId, final CancellableHandler handler) { final ParseResult parseResult = parseCacheFromText(page, listId, handler); if (parseResult != null && !parseResult.cacheList.isEmpty()) { - final cgCache cache = parseResult.cacheList.get(0); + final cgCache cache = cgBase.getFirstElementFromSet(parseResult.cacheList); getExtraOnlineInfo(cache, page, handler); cache.setUpdated(System.currentTimeMillis()); cache.setDetailedUpdate(cache.getUpdated()); @@ -1450,7 +1445,7 @@ public class cgBase { trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase()); // trackable id - trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ID, true, trackable.getGuid())); + trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid())); // trackable icon trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl())); @@ -3076,4 +3071,13 @@ public class cgBase { return starsContainer; } + + @SuppressWarnings("unchecked") + public static <T> T getFirstElementFromSet(Set<T> set) { + if (set != null && set.size() >= 1) { + return ((T[]) set.toArray())[0]; + } + return null; + } + } diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java index fe15c41..c774151 100644 --- a/main/src/cgeo/geocaching/cgCache.java +++ b/main/src/cgeo/geocaching/cgCache.java @@ -13,6 +13,7 @@ import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.geopoint.GeopointParser; import cgeo.geocaching.utils.CryptUtils; +import cgeo.geocaching.utils.LogTemplateProvider; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java index 455b225..e592f7c 100644 --- a/main/src/cgeo/geocaching/cgData.java +++ b/main/src/cgeo/geocaching/cgData.java @@ -1483,7 +1483,8 @@ public class cgData { putCoords(values, oneWaypoint.getCoords()); values.put("note", oneWaypoint.getNote()); - databaseRW.insert(dbTableWaypoints, null, values); + final long rowId = databaseRW.insert(dbTableWaypoints, null, values); + oneWaypoint.setId((int) rowId); } } @@ -1550,7 +1551,8 @@ public class cgData { values.put("note", waypoint.getNote()); if (id <= 0) { - databaseRW.insert(dbTableWaypoints, null, values); + final long rowId = databaseRW.insert(dbTableWaypoints, null, values); + waypoint.setId((int) rowId); ok = true; } else { final int rows = databaseRW.update(dbTableWaypoints, values, "_id = " + id, null); @@ -1845,15 +1847,11 @@ public class cgData { geocodes = null; } - List<cgCache> caches = loadCaches(geocodes, null, null, null, null, loadFlags); - if (CollectionUtils.isNotEmpty(caches)) { - return caches.get(0); - } - - return null; + Set<cgCache> caches = loadCaches(geocodes, null, null, null, null, loadFlags); + return cgBase.getFirstElementFromSet(caches); } - public List<cgCache> loadCaches(final Object[] geocodes, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) { + public Set<cgCache> loadCaches(final Object[] geocodes, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) { init(); // Using more than one of the parametersets results in overly comlex wheres if ((geocodes != null && geocodes.length > 0) @@ -1865,7 +1863,7 @@ public class cgData { } StringBuilder where = new StringBuilder(); Cursor cursor = null; - List<cgCache> caches = new ArrayList<cgCache>(); + Set<cgCache> caches = new HashSet<cgCache>(); try { if (geocodes != null && geocodes.length > 0) { diff --git a/main/src/cgeo/geocaching/cgeo.java b/main/src/cgeo/geocaching/cgeo.java index b337a77..7c80834 100644 --- a/main/src/cgeo/geocaching/cgeo.java +++ b/main/src/cgeo/geocaching/cgeo.java @@ -6,6 +6,7 @@ import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.StatusCode; +import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.maps.CGeoMap; @@ -252,7 +253,7 @@ public class cgeo extends AbstractActivity { showAbout(null); return true; case MENU_HELPERS: - startActivity(new Intent(this, cgeohelpers.class)); + startActivity(new Intent(this, UsefulAppsActivity.class)); return true; case MENU_SETTINGS: startActivity(new Intent(this, cgeoinit.class)); @@ -423,6 +424,9 @@ public class cgeo extends AbstractActivity { for (LogType logType : LogType.values()) { logType.setL10n(); } + for (WaypointType waypointType : WaypointType.values()) { + waypointType.setL10n(); + } Settings.getLogin(); diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java index 021bfca..827e29f 100644 --- a/main/src/cgeo/geocaching/cgeoapplication.java +++ b/main/src/cgeo/geocaching/cgeoapplication.java @@ -341,19 +341,19 @@ public class cgeoapplication extends Application { * only load waypoints for map usage. All other callers should set this to <code>false</code> * @return */ - public List<cgCache> getCaches(final SearchResult search, final boolean loadWaypoints) { + public Set<cgCache> getCaches(final SearchResult search, final boolean loadWaypoints) { return getCaches(search, null, null, null, null, loadWaypoints ? EnumSet.of(LoadFlag.LOADWAYPOINTS, LoadFlag.LOADOFFLINELOG) : EnumSet.of(LoadFlag.LOADOFFLINELOG)); } - public List<cgCache> getCaches(final SearchResult search, Long centerLat, Long centerLon, Long spanLat, Long spanLon) { + public Set<cgCache> getCaches(final SearchResult search, Long centerLat, Long centerLon, Long spanLat, Long spanLon) { return getCaches(search, centerLat, centerLon, spanLat, spanLon, EnumSet.of(LoadFlag.LOADWAYPOINTS, LoadFlag.LOADOFFLINELOG)); } - public List<cgCache> getCaches(final SearchResult search, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) { + public Set<cgCache> getCaches(final SearchResult search, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) { if (search == null) { - List<cgCache> cachesOut = new ArrayList<cgCache>(); + Set<cgCache> cachesOut = new HashSet<cgCache>(); - final List<cgCache> cachesPre = storage.loadCaches(null, centerLat, centerLon, spanLat, spanLon, loadFlags); + final Set<cgCache> cachesPre = storage.loadCaches(null, centerLat, centerLon, spanLat, spanLon, loadFlags); if (cachesPre != null) { cachesOut.addAll(cachesPre); } @@ -361,12 +361,12 @@ public class cgeoapplication extends Application { return cachesOut; } - List<cgCache> cachesOut = new ArrayList<cgCache>(); + Set<cgCache> cachesOut = new HashSet<cgCache>(); final Set<String> geocodeList = search.getGeocodes(); // The list of geocodes is sufficient. more parameters generate an overly complex select. - final List<cgCache> cachesPre = storage.loadCaches(geocodeList.toArray(), null, null, null, null, loadFlags); + final Set<cgCache> cachesPre = storage.loadCaches(geocodeList.toArray(), null, null, null, null, loadFlags); if (cachesPre != null) { cachesOut.addAll(cachesPre); } @@ -453,7 +453,7 @@ public class cgeoapplication extends Application { return storage.saveInventory("---", list); } - public void addSearch(final List<cgCache> cacheList, final int listId) { + public void addSearch(final Set<cgCache> cacheList, final int listId) { if (CollectionUtils.isEmpty(cacheList)) { return; } @@ -494,6 +494,7 @@ public class cgeoapplication extends Application { saveCache = !cache.gatherMissingFrom(oldCache); } return saveCache ? storage.saveCache(cache) : true; + } public void dropStored(int listId) { diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index 01465e9..1940bf9 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -6,20 +6,23 @@ import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.apps.cachelist.CacheListAppFactory; import cgeo.geocaching.enumerations.CacheListType; -import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.files.GPXImporter; -import cgeo.geocaching.filter.FilterBySize; -import cgeo.geocaching.filter.FilterByTrackables; -import cgeo.geocaching.filter.FilterByType; +import cgeo.geocaching.filter.AttributeFilter; import cgeo.geocaching.filter.IFilter; +import cgeo.geocaching.filter.SizeFilter; +import cgeo.geocaching.filter.StateFilter; +import cgeo.geocaching.filter.TrackablesFilter; +import cgeo.geocaching.filter.TypeFilter; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.maps.CGeoMap; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.sorting.CacheComparator; import cgeo.geocaching.sorting.DateComparator; import cgeo.geocaching.sorting.DifficultyComparator; +import cgeo.geocaching.sorting.EventDateComparator; import cgeo.geocaching.sorting.FindsComparator; import cgeo.geocaching.sorting.GeocodeComparator; import cgeo.geocaching.sorting.InventoryComparator; @@ -58,7 +61,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; -import android.view.WindowManager; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.EditText; import android.widget.ListView; @@ -126,6 +128,8 @@ public class cgeocaches extends AbstractListActivity { private static final int MENU_RENAME_LIST = 64; private static final int MENU_DROP_CACHES_AND_LIST = 65; private static final int MENU_DEFAULT_NAVIGATION = 66; + private static final int SUBMENU_FILTER_ATTRIBUTES = 67; + private static final int SUBMENU_FILTER_STATE = 68; private String action = null; private CacheListType type = null; @@ -167,7 +171,7 @@ public class cgeocaches extends AbstractListActivity { setTitle(title + " [" + SearchResult.getCount(search) + "]"); cacheList.clear(); - final List<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = app.getCaches(search, false); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -184,11 +188,8 @@ public class cgeocaches extends AbstractListActivity { if (cacheList == null) { showToast(res.getString(R.string.err_list_load_fail)); - setMoreCaches(false); - } else { - final int count = SearchResult.getTotal(search); - setMoreCaches(count > 0 && cacheList != null && cacheList.size() < count && cacheList.size() < MAX_LIST_ITEMS); } + setMoreCaches(); if (cacheList != null && SearchResult.getError(search) == StatusCode.UNAPPROVED_LICENSE) { AlertDialog.Builder dialog = new AlertDialog.Builder(cgeocaches.this); @@ -258,7 +259,7 @@ public class cgeocaches extends AbstractListActivity { setTitle(title + " [" + SearchResult.getCount(search) + "]"); cacheList.clear(); - final List<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = app.getCaches(search, false); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -275,11 +276,8 @@ public class cgeocaches extends AbstractListActivity { if (cacheList == null) { showToast(res.getString(R.string.err_list_load_fail)); - setMoreCaches(false); - } else { - final int count = SearchResult.getTotal(search); - setMoreCaches(count > 0 && cacheList != null && cacheList.size() < count && cacheList.size() < MAX_LIST_ITEMS); } + setMoreCaches(); if (SearchResult.getError(search) != null) { showToast(res.getString(R.string.err_download_fail) + " " + SearchResult.getError(search).getErrorString(res) + "."); @@ -337,7 +335,7 @@ public class cgeocaches extends AbstractListActivity { } } else { if (cacheList != null && search != null) { - final List<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = app.getCaches(search, false); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.clear(); cacheList.addAll(cacheListTmp); @@ -387,7 +385,6 @@ public class cgeocaches extends AbstractListActivity { waitDialog.dismiss(); waitDialog.setOnCancelListener(null); } - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); showToast(res.getString(R.string.sendToCgeo_download_fail)); finish(); return; @@ -396,7 +393,6 @@ public class cgeocaches extends AbstractListActivity { waitDialog.dismiss(); waitDialog.setOnCancelListener(null); } - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); showToast(res.getString(R.string.sendToCgeo_no_registration)); finish(); return; @@ -407,7 +403,7 @@ public class cgeocaches extends AbstractListActivity { cacheList.clear(); - final List<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = app.getCaches(search, false); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -419,7 +415,6 @@ public class cgeocaches extends AbstractListActivity { waitDialog.dismiss(); waitDialog.setOnCancelListener(null); } - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } }; @@ -435,7 +430,7 @@ public class cgeocaches extends AbstractListActivity { cacheList.clear(); - final List<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = app.getCaches(search, false); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -520,6 +515,10 @@ public class cgeocaches extends AbstractListActivity { */ private MenuItem navigationMenu; + public cgeocaches() { + super(true); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -722,7 +721,7 @@ public class cgeocaches extends AbstractListActivity { } // refresh standard list if it has changed (new caches downloaded) - if (type == CacheListType.OFFLINE && listId == StoredList.STANDARD_LIST_ID && search != null) { + if (type == CacheListType.OFFLINE && listId >= StoredList.STANDARD_LIST_ID && search != null) { SearchResult newSearch = cgBase.searchByOffline(coords, cacheType, listId); if (newSearch != null && newSearch.totalCnt != search.totalCnt) { refreshCurrentList(); @@ -778,6 +777,8 @@ public class cgeocaches extends AbstractListActivity { subMenuFilter.add(0, SUBMENU_FILTER_TYPE, 0, res.getString(R.string.caches_filter_type)); } subMenuFilter.add(0, SUBMENU_FILTER_SIZE, 0, res.getString(R.string.caches_filter_size)); + subMenuFilter.add(0, SUBMENU_FILTER_ATTRIBUTES, 0, res.getString(R.string.cache_attributes)); + subMenuFilter.add(0, SUBMENU_FILTER_STATE, 0, res.getString(R.string.cache_status)); subMenuFilter.add(0, MENU_FILTER_TRACKABLES, 0, res.getString(R.string.caches_filter_track)); subMenuFilter.add(0, MENU_FILTER_CLEAR, 0, res.getString(R.string.caches_filter_clear)); @@ -1045,13 +1046,19 @@ public class cgeocaches extends AbstractListActivity { setComparator(item, new StateComparator()); return true; case SUBMENU_FILTER_TYPE: - showFilterMenu(SUBMENU_FILTER_TYPE); + showFilterMenu(TypeFilter.getAllFilters(), res.getString(R.string.caches_filter_type_title)); return true; case SUBMENU_FILTER_SIZE: - showFilterMenu(SUBMENU_FILTER_SIZE); + showFilterMenu(SizeFilter.getAllFilters(), res.getString(R.string.caches_filter_size_title)); + return true; + case SUBMENU_FILTER_ATTRIBUTES: + showFilterMenu(AttributeFilter.getAllFilters(), res.getString(R.string.cache_attributes)); + return true; + case SUBMENU_FILTER_STATE: + showFilterMenu(StateFilter.getAllFilters(), res.getString(R.string.cache_status)); return true; case MENU_FILTER_TRACKABLES: - setFilter(new FilterByTrackables(res.getString(R.string.caches_filter_track))); + setFilter(new TrackablesFilter(res.getString(R.string.caches_filter_track))); return true; case MENU_FILTER_CLEAR: if (adapter != null) { @@ -1075,40 +1082,20 @@ public class cgeocaches extends AbstractListActivity { return CacheListAppFactory.onMenuItemSelected(item, geo, cacheList, this, search); } - private void showFilterMenu(final int submenu) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - switch (submenu) { - case SUBMENU_FILTER_SIZE: - builder.setTitle(res.getString(R.string.caches_filter_size_title)); - final CacheSize[] cacheSizes = CacheSize.values(); - ArrayList<String> names = new ArrayList<String>(); - for (CacheSize cacheSize : cacheSizes) { - names.add(cacheSize.getL10n()); - } - builder.setItems(names.toArray(new String[names.size()]), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - setFilter(new FilterBySize(cacheSizes[item])); - } - }); - break; - case SUBMENU_FILTER_TYPE: - builder.setTitle(res.getString(R.string.caches_filter_type_title)); - final CacheType[] cacheTypes = CacheType.values(); - ArrayList<String> typeNames = new ArrayList<String>(); - for (CacheType cacheType : cacheTypes) { - if (cacheType != CacheType.ALL) { - typeNames.add(cacheType.getL10n()); - } - } - builder.setItems(typeNames.toArray(new String[typeNames.size()]), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - setFilter(new FilterByType(cacheTypes[item])); - } - }); - break; - default: - break; + private void showFilterMenu(final IFilter[] filters, final String menuTitle) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(menuTitle); + + final String[] names = new String[filters.length]; + for (int i = 0; i < filters.length; i++) { + names[i] = filters[i].getName(); } + builder.setItems(names, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + setFilter(filters[item]); + } + }); + builder.create().show(); } @@ -1362,7 +1349,7 @@ public class cgeocaches extends AbstractListActivity { listFooter.setOnClickListener(null); } - private void setMoreCaches(boolean more) { + private void setMoreCaches() { if (listFooter == null) { return; } @@ -1370,7 +1357,13 @@ public class cgeocaches extends AbstractListActivity { return; } - if (more) { + boolean enableMore = type != CacheListType.OFFLINE && cacheList != null && cacheList.size() < MAX_LIST_ITEMS; + if (enableMore) { + final int count = SearchResult.getTotal(search); + enableMore = enableMore && count > 0 && cacheList.size() < count; + } + + if (enableMore) { listFooterText.setText(res.getString(R.string.caches_more_caches) + " (" + res.getString(R.string.caches_more_caches_currently) + ": " + cacheList.size() + ")"); listFooter.setOnClickListener(new MoreCachesListener()); } else { @@ -1381,7 +1374,7 @@ public class cgeocaches extends AbstractListActivity { } listFooter.setOnClickListener(null); } - listFooter.setClickable(more); + listFooter.setClickable(enableMore); } private void init() { @@ -1394,8 +1387,7 @@ public class cgeocaches extends AbstractListActivity { } if (CollectionUtils.isNotEmpty(cacheList)) { - final int count = SearchResult.getTotal(search); - setMoreCaches(count > 0 && cacheList.size() < count && cacheList.size() < MAX_LIST_ITEMS); + setMoreCaches(); } setTitle(title); @@ -1584,7 +1576,6 @@ public class cgeocaches extends AbstractListActivity { public void importWeb() { detailProgress = 0; - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); showProgress(false); waitDialog = new ProgressDialog(this); waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @@ -2630,12 +2621,12 @@ public class cgeocaches extends AbstractListActivity { } } if (eventsOnly) { - adapter.setComparator(new DateComparator()); + adapter.setComparator(new EventDateComparator()); } else if (type == CacheListType.HISTORY) { adapter.setComparator(new VisitComparator()); } - else if (adapter.getCacheComparator() != null && adapter.getCacheComparator() instanceof DateComparator) { + else if (adapter.getCacheComparator() != null && adapter.getCacheComparator() instanceof EventDateComparator) { adapter.setComparator(null); } } diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java index ab903ec..0ecc9e7 100644 --- a/main/src/cgeo/geocaching/cgeogpxes.java +++ b/main/src/cgeo/geocaching/cgeogpxes.java @@ -1,83 +1,83 @@ -package cgeo.geocaching; - -import cgeo.geocaching.connector.ConnectorFactory; -import cgeo.geocaching.connector.IConnector; -import cgeo.geocaching.files.FileList; -import cgeo.geocaching.files.GPXImporter; -import cgeo.geocaching.ui.GPXListAdapter; - -import org.apache.commons.lang3.StringUtils; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.os.Environment; - -import java.io.File; -import java.util.List; - -public class cgeogpxes extends FileList<GPXListAdapter> { - private static final String EXTRAS_LIST_ID = "list"; - - public cgeogpxes() { - super(new String[] { "gpx", "loc", "zip" }); - } - - private int listId = 1; - - @Override - protected GPXListAdapter getAdapter(List<File> files) { - return new GPXListAdapter(this, files); - } - - @Override - protected File[] getBaseFolders() { - return new File[] { new File(Environment.getExternalStorageDirectory(), "gpx") }; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Bundle extras = getIntent().getExtras(); - if (extras != null) { - listId = extras.getInt(EXTRAS_LIST_ID); - } - if (listId <= 0) { - listId = StoredList.STANDARD_LIST_ID; - } - } - - @Override - protected void setTitle() { - setTitle(res.getString(R.string.gpx_import_title)); - } - - public static void startSubActivity(Activity fromActivity, int listId) { - final Intent intent = new Intent(fromActivity, cgeogpxes.class); - intent.putExtra(EXTRAS_LIST_ID, listId); - fromActivity.startActivityForResult(intent, 0); - } - - @Override - protected boolean filenameBelongsToList(final String filename) { - if (super.filenameBelongsToList(filename)) { - if (StringUtils.endsWithIgnoreCase(filename, GPXImporter.ZIP_FILE_EXTENSION)) { - for (IConnector connector : ConnectorFactory.getConnectors()) { - if (connector.isZippedGPXFile(filename)) { - return true; - } - } - return false; - } - // filter out waypoint files - return !StringUtils.endsWithIgnoreCase(filename, GPXImporter.WAYPOINTS_FILE_SUFFIX_AND_EXTENSION); - } - return false; - } - - public int getListId() { - return listId; - } - -} +package cgeo.geocaching;
+
+import cgeo.geocaching.connector.ConnectorFactory;
+import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.files.FileList;
+import cgeo.geocaching.files.GPXImporter;
+import cgeo.geocaching.ui.GPXListAdapter;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+
+import java.io.File;
+import java.util.List;
+
+public class cgeogpxes extends FileList<GPXListAdapter> {
+ private static final String EXTRAS_LIST_ID = "list";
+
+ public cgeogpxes() {
+ super(new String[] { "gpx", "loc", "zip" });
+ }
+
+ private int listId = 1;
+
+ @Override
+ protected GPXListAdapter getAdapter(List<File> files) {
+ return new GPXListAdapter(this, files);
+ }
+
+ @Override
+ protected File[] getBaseFolders() {
+ return new File[] { new File(Environment.getExternalStorageDirectory(), "gpx") };
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ listId = extras.getInt(EXTRAS_LIST_ID);
+ }
+ if (listId <= 0) {
+ listId = StoredList.STANDARD_LIST_ID;
+ }
+ }
+
+ @Override
+ protected void setTitle() {
+ setTitle(res.getString(R.string.gpx_import_title));
+ }
+
+ public static void startSubActivity(Activity fromActivity, int listId) {
+ final Intent intent = new Intent(fromActivity, cgeogpxes.class);
+ intent.putExtra(EXTRAS_LIST_ID, listId);
+ fromActivity.startActivityForResult(intent, 0);
+ }
+
+ @Override
+ protected boolean filenameBelongsToList(final String filename) {
+ if (super.filenameBelongsToList(filename)) {
+ if (StringUtils.endsWithIgnoreCase(filename, GPXImporter.ZIP_FILE_EXTENSION)) {
+ for (IConnector connector : ConnectorFactory.getConnectors()) {
+ if (connector.isZippedGPXFile(filename)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // filter out waypoint files
+ return !StringUtils.containsIgnoreCase(filename, GPXImporter.WAYPOINTS_FILE_SUFFIX);
+ }
+ return false;
+ }
+
+ public int getListId() {
+ return listId;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/cgeohelpers.java b/main/src/cgeo/geocaching/cgeohelpers.java deleted file mode 100644 index 560ab84..0000000 --- a/main/src/cgeo/geocaching/cgeohelpers.java +++ /dev/null @@ -1,79 +0,0 @@ -package cgeo.geocaching; - -import cgeo.geocaching.activity.AbstractActivity; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.view.View; - -import java.util.Locale; - -public class cgeohelpers extends AbstractActivity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - setTheme(); - setContentView(R.layout.helpers); - setTitle(res.getString(R.string.helpers)); - } - - @Override - public void onResume() { - super.onResume(); - - } - - private void installFromMarket(String marketId) { - try { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:" + marketId))); - } catch (Exception e) { - // market not available in standard emulator - } - - finish(); - } - - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void installManual(View view) { - final Locale loc = Locale.getDefault(); - final String language = loc.getLanguage(); - - if ("de".equalsIgnoreCase(language)) { - installFromMarket("gnu.android.app.cgeomanual.de"); - } - else { - installFromMarket("gnu.android.app.cgeomanual.en"); - } - } - - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void installLocus(View view) { - installFromMarket("menion.android.locus"); - } - - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void installGpsStatus(View view) { - installFromMarket("com.eclipsim.gpsstatus2"); - } - - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void installBluetoothGps(View view) { - installFromMarket("googoo.android.btgps"); - } -} diff --git a/main/src/cgeo/geocaching/cgeoimages.java b/main/src/cgeo/geocaching/cgeoimages.java index 8f65488..79c0e24 100644 --- a/main/src/cgeo/geocaching/cgeoimages.java +++ b/main/src/cgeo/geocaching/cgeoimages.java @@ -71,7 +71,10 @@ public class cgeoimages extends AbstractActivity { for (final cgImage img : images) { rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null); - ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.getTitle())); + if (StringUtils.isNotBlank(img.getTitle())) { + ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.getTitle())); + rowView.findViewById(R.id.titleLayout).setVisibility(View.VISIBLE); + } if (StringUtils.isNotBlank(img.getDescription())) { final TextView descView = (TextView) rowView.findViewById(R.id.description); diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java index add17ed..58db9bd 100644 --- a/main/src/cgeo/geocaching/cgeoinit.java +++ b/main/src/cgeo/geocaching/cgeoinit.java @@ -1,6 +1,5 @@ package cgeo.geocaching; -import cgeo.geocaching.LogTemplateProvider.LogTemplate; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory.NavigationAppsEnum; @@ -8,7 +7,10 @@ import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.maps.MapProviderFactory; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.TwitterAuthorizationActivity; +import cgeo.geocaching.utils.LogTemplateProvider; +import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -464,6 +466,16 @@ public class cgeoinit extends AbstractActivity { } }); + final CheckBox offlineWpButton = (CheckBox) findViewById(R.id.offline_wp); + offlineWpButton.setChecked(Settings.isStoreOfflineWpMaps()); + offlineWpButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + Settings.setStoreOfflineWpMaps(offlineWpButton.isChecked()); + } + }); + final CheckBox saveLogImgButton = (CheckBox) findViewById(R.id.save_log_img); saveLogImgButton.setChecked(Settings.isStoreLogImages()); saveLogImgButton.setOnClickListener(new View.OnClickListener() { diff --git a/main/src/cgeo/geocaching/cgeonavigate.java b/main/src/cgeo/geocaching/cgeonavigate.java index 519521d..e0ffb80 100644 --- a/main/src/cgeo/geocaching/cgeonavigate.java +++ b/main/src/cgeo/geocaching/cgeonavigate.java @@ -17,7 +17,6 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; -import android.view.WindowManager; import android.widget.TextView; import java.util.ArrayList; @@ -67,15 +66,13 @@ public class cgeonavigate extends AbstractActivity { private String geocode; public cgeonavigate() { - super("c:geo-compass"); + super("c:geo-compass", true); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // set layout - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setTheme(); setContentView(R.layout.navigate); setTitle(res.getString(R.string.compass_title)); diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java index 2fe1805..466566d 100644 --- a/main/src/cgeo/geocaching/cgeopopup.java +++ b/main/src/cgeo/geocaching/cgeopopup.java @@ -626,22 +626,12 @@ public class cgeopopup extends AbstractActivity { * @param view * unused here but needed since this method is referenced from XML layout */ - public void goCompass(View view) { + public void goDefaultNavigation(View view) { if (cache == null || cache.getCoords() == null) { showToast(res.getString(R.string.cache_coordinates_no)); return; } - - cgeonavigate navigateActivity = new cgeonavigate(); - - Intent navigateIntent = new Intent(cgeopopup.this, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", cache.getCoords().getLatitude()); - navigateIntent.putExtra("longitude", cache.getCoords().getLongitude()); - navigateIntent.putExtra("geocode", cache.getGeocode().toUpperCase()); - navigateIntent.putExtra("name", cache.getName()); - - startActivity(navigateIntent); - + NavigationAppFactory.startDefaultNavigationApplication(geo, this, cache, null, null, null); finish(); } diff --git a/main/src/cgeo/geocaching/cgeotouch.java b/main/src/cgeo/geocaching/cgeotouch.java index b2163c0..d261687 100644 --- a/main/src/cgeo/geocaching/cgeotouch.java +++ b/main/src/cgeo/geocaching/cgeotouch.java @@ -3,6 +3,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.StatusCode; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.ui.DateDialog; import org.apache.commons.lang3.StringUtils; diff --git a/main/src/cgeo/geocaching/cgeowaypoint.java b/main/src/cgeo/geocaching/cgeowaypoint.java index addc4fe..a96e1ab 100644 --- a/main/src/cgeo/geocaching/cgeowaypoint.java +++ b/main/src/cgeo/geocaching/cgeowaypoint.java @@ -294,7 +294,7 @@ public class cgeowaypoint extends AbstractActivity { } } - private static class update implements UpdateLocationCallback { + private class update implements UpdateLocationCallback { @Override public void updateLocation(cgGeo geo) { @@ -315,6 +315,7 @@ public class cgeowaypoint extends AbstractActivity { public void onClick(View arg0) { if (app.deleteWaypoint(id)) { + StaticMapsProvider.removeWpStaticMaps(id, geocode); cgeoapplication.removeCacheFromCache(geocode); finish(); diff --git a/main/src/cgeo/geocaching/cgeowaypointadd.java b/main/src/cgeo/geocaching/cgeowaypointadd.java index 67618bd..74aee55 100644 --- a/main/src/cgeo/geocaching/cgeowaypointadd.java +++ b/main/src/cgeo/geocaching/cgeowaypointadd.java @@ -127,7 +127,7 @@ public class cgeowaypointadd extends AbstractActivity { Button addWaypoint = (Button) findViewById(R.id.add_waypoint); addWaypoint.setOnClickListener(new coordsListener()); - List<String> wayPointNames = new ArrayList<String>(cgBase.waypointTypes.values()); + List<String> wayPointNames = new ArrayList<String>(WaypointType.ALL_TYPES_EXCEPT_OWN.values()); AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.name); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, wayPointNames); textView.setAdapter(adapter); @@ -192,6 +192,7 @@ public class cgeowaypointadd extends AbstractActivity { @Override public void updateLocation(cgGeo geo) { + Log.d(Settings.tag, "cgeowaypointadd.updateLocation called"); if (geo == null || geo.coordsNow == null) { return; } @@ -316,8 +317,13 @@ public class cgeowaypointadd extends AbstractActivity { waypoint.setLookup(lookup); waypoint.setCoords(coords); waypoint.setNote(note); + waypoint.setId(id); if (app.saveOwnWaypoint(id, geocode, waypoint)) { + StaticMapsProvider.removeWpStaticMaps(id, geocode); + if (Settings.isStoreOfflineWpMaps()) { + StaticMapsProvider.storeWaypointStaticMap(app.getCacheByGeocode(geocode), cgeowaypointadd.this, waypoint); + } finish(); return; } else { diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java index 6a2bc72..f65312c 100644 --- a/main/src/cgeo/geocaching/connector/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/GCConnector.java @@ -1,7 +1,6 @@ package cgeo.geocaching.connector; import cgeo.geocaching.GCConstants; -import cgeo.geocaching.Parameters; import cgeo.geocaching.ParseResult; import cgeo.geocaching.R; import cgeo.geocaching.Settings; @@ -9,6 +8,7 @@ import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.StatusCode; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.CancellableHandler; import org.apache.commons.collections.CollectionUtils; diff --git a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java index dfd474d..c5d7f3c 100644 --- a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java +++ b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java @@ -1,10 +1,10 @@ package cgeo.geocaching.connector.opencaching; -import cgeo.geocaching.Parameters; import cgeo.geocaching.ParseResult; import cgeo.geocaching.Settings; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.CryptUtils; diff --git a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java index 09fc8f1..a69d5c9 100644 --- a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java @@ -1,6 +1,5 @@ package cgeo.geocaching.connector.opencaching; -import cgeo.geocaching.Parameters; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; @@ -14,6 +13,7 @@ import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.geopoint.GeopointParser; +import cgeo.geocaching.network.Parameters; import org.apache.commons.lang3.StringUtils; import org.json.JSONArray; diff --git a/main/src/cgeo/geocaching/enumerations/WaypointType.java b/main/src/cgeo/geocaching/enumerations/WaypointType.java index 4a76723..d5b1333 100644 --- a/main/src/cgeo/geocaching/enumerations/WaypointType.java +++ b/main/src/cgeo/geocaching/enumerations/WaypointType.java @@ -1,6 +1,7 @@ package cgeo.geocaching.enumerations; import cgeo.geocaching.R; +import cgeo.geocaching.cgeoapplication; import java.util.Collections; import java.util.HashMap; @@ -22,11 +23,13 @@ public enum WaypointType { public final String id; public final int stringId; + private String l10n; // not final because the locale can be changed public final int markerId; private WaypointType(String id, int stringId, int markerId) { this.id = id; this.stringId = stringId; + setL10n(); this.markerId = markerId; } @@ -35,10 +38,14 @@ public enum WaypointType { * non public so that <code>null</code> handling can be handled centrally in the enum type itself */ private static final Map<String, WaypointType> FIND_BY_ID; + public static final Map<WaypointType, String> ALL_TYPES_EXCEPT_OWN = new HashMap<WaypointType, String>(); static { final HashMap<String, WaypointType> mapping = new HashMap<String, WaypointType>(); for (WaypointType wt : values()) { mapping.put(wt.id, wt); + if (wt != WaypointType.OWN) { + ALL_TYPES_EXCEPT_OWN.put(wt, wt.getL10n()); + } } FIND_BY_ID = Collections.unmodifiableMap(mapping); } @@ -58,4 +65,15 @@ public enum WaypointType { return waypointType; } + public final String getL10n() { + return l10n; + } + + public void setL10n() { + this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(this.stringId); + if (WaypointType.ALL_TYPES_EXCEPT_OWN != null && WaypointType.ALL_TYPES_EXCEPT_OWN.containsKey(this)) { + WaypointType.ALL_TYPES_EXCEPT_OWN.put(this, this.getL10n()); + } + } + } diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java index e7853f0..8a4a8fc 100644 --- a/main/src/cgeo/geocaching/files/GPXImporter.java +++ b/main/src/cgeo/geocaching/files/GPXImporter.java @@ -1,398 +1,428 @@ -package cgeo.geocaching.files; - -import cgeo.geocaching.R; -import cgeo.geocaching.SearchResult; -import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgeoapplication; -import cgeo.geocaching.activity.IAbstractActivity; -import cgeo.geocaching.activity.Progress; -import cgeo.geocaching.utils.CancellableHandler; - -import org.apache.commons.lang3.StringUtils; - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Handler; -import android.os.Message; -import android.util.Log; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.CancellationException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -public class GPXImporter { - static final int IMPORT_STEP_START = 0; - static final int IMPORT_STEP_READ_FILE = 1; - static final int IMPORT_STEP_READ_WPT_FILE = 2; - static final int IMPORT_STEP_STORE_CACHES = 3; - static final int IMPORT_STEP_FINISHED = 4; - static final int IMPORT_STEP_FINISHED_WITH_ERROR = 5; - static final int IMPORT_STEP_CANCEL = 6; - static final int IMPORT_STEP_CANCELED = 7; - - public static final String GPX_FILE_EXTENSION = ".gpx"; - public static final String ZIP_FILE_EXTENSION = ".zip"; - public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = "-wpts.gpx"; - - private Progress progress = new Progress(); - - private Resources res; - private int listId; - private IAbstractActivity fromActivity; - private Handler importFinishedHandler; - - public GPXImporter(final IAbstractActivity fromActivity, final int listId, final Handler importFinishedHandler) { - this.listId = listId; - this.fromActivity = fromActivity; - res = ((Activity) fromActivity).getResources(); - this.importFinishedHandler = importFinishedHandler; - } - - /** - * Import GPX file. Currently supports *.gpx, *.zip (containing gpx files, e.g. PQ queries) or *.loc files. - * - * @param file - * the file to import - */ - public void importGPX(final File file) { - if (StringUtils.endsWithIgnoreCase(file.getName(), GPX_FILE_EXTENSION)) { - new ImportGpxFileThread(file, listId, importStepHandler, progressHandler).start(); - } else if (StringUtils.endsWithIgnoreCase(file.getName(), ZIP_FILE_EXTENSION)) { - new ImportGpxZipFileThread(file, listId, importStepHandler, progressHandler).start(); - } else { - new ImportLocFileThread(file, listId, importStepHandler, progressHandler).start(); - } - } - - /** - * Import GPX provided via intent of activity that instantiated this GPXImporter. - */ - public void importGPX() { - final ContentResolver contentResolver = ((Activity) fromActivity).getContentResolver(); - final Intent intent = ((Activity) fromActivity).getIntent(); - final Uri uri = intent.getData(); - - String mimeType = intent.getType(); - // if mimetype can't be determined (e.g. for emulators email app), use a default - // contentResolver.getType(uri) doesn't help but throws exception for emulators email app - // Permission Denial: reading com.android.email.provider.EmailProvider uri - // Google search says: there is no solution for this problem - // TODO: check if problem occurs with gmail as well - if (mimeType == null) { - mimeType = "application/zip"; - } - - Log.i(Settings.tag, "importGPX: " + uri + ", mimetype=" + mimeType); - if (StringUtils.equalsIgnoreCase("text/xml", mimeType) || StringUtils.equalsIgnoreCase("application/xml", mimeType)) { - new ImportGpxAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start(); - } else if (StringUtils.equalsIgnoreCase("application/zip", mimeType)) { - new ImportGpxZipAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start(); - } else { - importFinished(); - } - } - - static abstract class ImportThread extends Thread { - final int listId; - final Handler importStepHandler; - final CancellableHandler progressHandler; - - public ImportThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) { - this.listId = listId; - this.importStepHandler = importStepHandler; - this.progressHandler = progressHandler; - } - - @Override - public void run() { - final Collection<cgCache> caches; - try { - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_START)); - caches = doImport(); - - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_STORE_CACHES, R.string.gpx_import_storing, caches.size())); - SearchResult search = storeParsedCaches(caches); - Log.i(Settings.tag, "Imported successfully " + caches.size() + " caches."); - - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, SearchResult.getCount(search), 0, search)); - } catch (IOException e) { - Log.i(Settings.tag, "Importing caches failed - error reading data: " + e.getMessage()); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_io, 0, e.getLocalizedMessage())); - } catch (ParserException e) { - Log.i(Settings.tag, "Importing caches failed - data format error" + e.getMessage()); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_parser, 0, e.getLocalizedMessage())); - } catch (CancellationException e) { - Log.i(Settings.tag, "Importing caches canceled"); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_CANCELED)); - } catch (Exception e) { - Log.e(Settings.tag, "Importing caches failed - unknown error: ", e); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_unexpected, 0, e.getLocalizedMessage())); - } - } - - protected abstract Collection<cgCache> doImport() throws IOException, ParserException; - - private SearchResult storeParsedCaches(Collection<cgCache> caches) { - final SearchResult search = new SearchResult(); - final cgeoapplication app = cgeoapplication.getInstance(); - int storedCaches = 0; - for (cgCache cache : caches) { - // remove from cache because a cache might be re-imported - cgeoapplication.removeCacheFromCache(cache.getGeocode()); - app.addCacheToSearch(search, cache); - - // save memory, imported caches are typically not used immediately - cgeoapplication.removeCacheFromCache(cache.getGeocode()); - - if (progressHandler.isCancelled()) { - throw new CancellationException(); - } - progressHandler.sendMessage(progressHandler.obtainMessage(0, ++storedCaches, 0)); - } - return search; - } - } - - static class ImportLocFileThread extends ImportThread { - private final File file; - - public ImportLocFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - this.file = file; - } - - @Override - protected Collection<cgCache> doImport() throws IOException, ParserException { - Log.i(Settings.tag, "Import LOC file: " + file.getAbsolutePath()); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) file.length())); - LocParser parser = new LocParser(listId); - return parser.parse(file, progressHandler); - } - } - - static abstract class ImportGpxThread extends ImportThread { - - public ImportGpxThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - } - - @Override - protected Collection<cgCache> doImport() throws IOException, ParserException { - try { - // try to parse cache file as GPX 10 - return doImport(new GPX10Parser(listId)); - } catch (ParserException pe) { - // didn't work -> lets try GPX11 - return doImport(new GPX11Parser(listId)); - } - } - - protected abstract Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException; - } - - static class ImportGpxFileThread extends ImportGpxThread { - private final File cacheFile; - - public ImportGpxFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - this.cacheFile = file; - } - - @Override - protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException { - Log.i(Settings.tag, "Import GPX file: " + cacheFile.getAbsolutePath()); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) cacheFile.length())); - Collection<cgCache> caches = parser.parse(cacheFile, progressHandler); - - final File wptsFile = new File(cacheFile.getParentFile(), getWaypointsFileNameForGpxFileName(cacheFile.getName())); - if (wptsFile.canRead()) { - Log.i(Settings.tag, "Import GPX waypoint file: " + wptsFile.getAbsolutePath()); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) wptsFile.length())); - caches = parser.parse(wptsFile, progressHandler); - } - - return caches; - } - } - - static class ImportGpxAttachmentThread extends ImportGpxThread { - private final Uri uri; - private ContentResolver contentResolver; - - public ImportGpxAttachmentThread(Uri uri, ContentResolver contentResolver, int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - this.uri = uri; - this.contentResolver = contentResolver; - } - - @Override - protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException { - Log.i(Settings.tag, "Import GPX from uri: " + uri); - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, -1)); - InputStream is = contentResolver.openInputStream(uri); - try { - return parser.parse(is, progressHandler); - } finally { - is.close(); - } - } - } - - static abstract class ImportGpxZipThread extends ImportGpxThread { - - public ImportGpxZipThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - } - - @Override - protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException { - Collection<cgCache> caches = Collections.emptySet(); - // can't assume that GPX file comes before waypoint file in zip -> so we need two passes - // 1. parse GPX files - ZipInputStream zis = new ZipInputStream(getInputStream()); - try { - for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) { - if (StringUtils.endsWithIgnoreCase(zipEntry.getName(), GPX_FILE_EXTENSION)) { - if (!StringUtils.endsWithIgnoreCase(zipEntry.getName(), WAYPOINTS_FILE_SUFFIX_AND_EXTENSION)) { - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) zipEntry.getSize())); - caches = parser.parse(new NoCloseInputStream(zis), progressHandler); - } - } else { - throw new ParserException("Imported zip is not a GPX zip file."); - } - zis.closeEntry(); - } - } finally { - zis.close(); - } - - // 2. parse waypoint files - zis = new ZipInputStream(getInputStream()); - try { - for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) { - if (StringUtils.endsWithIgnoreCase(zipEntry.getName(), WAYPOINTS_FILE_SUFFIX_AND_EXTENSION)) { - importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) zipEntry.getSize())); - caches = parser.parse(new NoCloseInputStream(zis), progressHandler); - } - zis.closeEntry(); - } - } finally { - zis.close(); - } - - return caches; - } - - protected abstract InputStream getInputStream() throws IOException; - } - - static class ImportGpxZipFileThread extends ImportGpxZipThread { - private final File cacheFile; - - public ImportGpxZipFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - this.cacheFile = file; - Log.i(Settings.tag, "Import zipped GPX: " + file); - } - - @Override - protected InputStream getInputStream() throws IOException { - return new FileInputStream(cacheFile); - } - } - - static class ImportGpxZipAttachmentThread extends ImportGpxZipThread { - private final Uri uri; - private ContentResolver contentResolver; - - public ImportGpxZipAttachmentThread(Uri uri, ContentResolver contentResolver, int listId, Handler importStepHandler, CancellableHandler progressHandler) { - super(listId, importStepHandler, progressHandler); - this.uri = uri; - this.contentResolver = contentResolver; - Log.i(Settings.tag, "Import zipped GPX from uri: " + uri); - } - - @Override - protected InputStream getInputStream() throws IOException { - return contentResolver.openInputStream(uri); - } - } - - final private CancellableHandler progressHandler = new CancellableHandler() { - @Override - public void handleRegularMessage(Message msg) { - progress.setProgress(msg.arg1); - } - }; - - final private Handler importStepHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case IMPORT_STEP_START: - Message cancelMessage = importStepHandler.obtainMessage(IMPORT_STEP_CANCEL); - progress.show((Context) fromActivity, res.getString(R.string.gpx_import_title_reading_file), res.getString(R.string.gpx_import_loading_caches), ProgressDialog.STYLE_HORIZONTAL, cancelMessage); - break; - - case IMPORT_STEP_READ_FILE: - case IMPORT_STEP_READ_WPT_FILE: - case IMPORT_STEP_STORE_CACHES: - progress.setMessage(res.getString(msg.arg1)); - progress.setMaxProgressAndReset(msg.arg2); - break; - - case IMPORT_STEP_FINISHED: - progress.dismiss(); - fromActivity.helpDialog(res.getString(R.string.gpx_import_title_caches_imported), msg.arg1 + " " + res.getString(R.string.gpx_import_caches_imported)); - importFinished(); - break; - - case IMPORT_STEP_FINISHED_WITH_ERROR: - progress.dismiss(); - fromActivity.helpDialog(res.getString(R.string.gpx_import_title_caches_import_failed), res.getString(msg.arg1) + "\n\n" + msg.obj); - importFinished(); - break; - - case IMPORT_STEP_CANCEL: - progress.dismiss(); - progressHandler.cancel(); - break; - - case IMPORT_STEP_CANCELED: - fromActivity.showShortToast(res.getString(R.string.gpx_import_canceled)); - importFinished(); - break; - - default: - break; - } - } - }; - - // 1234567.gpx -> 1234567-wpts.gpx - static String getWaypointsFileNameForGpxFileName(String name) { - if (StringUtils.endsWithIgnoreCase(name, GPX_FILE_EXTENSION) && (StringUtils.length(name) > GPX_FILE_EXTENSION.length())) { - return StringUtils.substringBeforeLast(name, ".") + WAYPOINTS_FILE_SUFFIX_AND_EXTENSION; - } else { - return null; - } - } - - protected void importFinished() { - if (importFinishedHandler != null) { - importFinishedHandler.sendEmptyMessage(0); - } - } -} +package cgeo.geocaching.files;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.activity.IAbstractActivity;
+import cgeo.geocaching.activity.Progress;
+import cgeo.geocaching.utils.CancellableHandler;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CancellationException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class GPXImporter {
+ static final int IMPORT_STEP_START = 0;
+ static final int IMPORT_STEP_READ_FILE = 1;
+ static final int IMPORT_STEP_READ_WPT_FILE = 2;
+ static final int IMPORT_STEP_STORE_CACHES = 3;
+ static final int IMPORT_STEP_FINISHED = 4;
+ static final int IMPORT_STEP_FINISHED_WITH_ERROR = 5;
+ static final int IMPORT_STEP_CANCEL = 6;
+ static final int IMPORT_STEP_CANCELED = 7;
+
+ public static final String GPX_FILE_EXTENSION = ".gpx";
+ public static final String ZIP_FILE_EXTENSION = ".zip";
+ public static final String WAYPOINTS_FILE_SUFFIX = "-wpts";
+ public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = WAYPOINTS_FILE_SUFFIX + GPX_FILE_EXTENSION;
+
+ private static final List<String> GPX_MIME_TYPES = Arrays.asList(new String[] { "text/xml", "application/xml" });
+ private static final List<String> ZIP_MIME_TYPES = Arrays.asList(new String[] { "application/zip", "application/x-compressed", "application/x-zip-compressed", "application/x-zip", "application/octet-stream" });
+
+ private Progress progress = new Progress();
+
+ private Resources res;
+ private int listId;
+ private IAbstractActivity fromActivity;
+ private Handler importFinishedHandler;
+
+ public GPXImporter(final IAbstractActivity fromActivity, final int listId, final Handler importFinishedHandler) {
+ this.listId = listId;
+ this.fromActivity = fromActivity;
+ res = ((Activity) fromActivity).getResources();
+ this.importFinishedHandler = importFinishedHandler;
+ }
+
+ /**
+ * Import GPX file. Currently supports *.gpx, *.zip (containing gpx files, e.g. PQ queries) or *.loc files.
+ *
+ * @param file
+ * the file to import
+ */
+ public void importGPX(final File file) {
+ if (StringUtils.endsWithIgnoreCase(file.getName(), GPX_FILE_EXTENSION)) {
+ new ImportGpxFileThread(file, listId, importStepHandler, progressHandler).start();
+ } else if (StringUtils.endsWithIgnoreCase(file.getName(), ZIP_FILE_EXTENSION)) {
+ new ImportGpxZipFileThread(file, listId, importStepHandler, progressHandler).start();
+ } else {
+ new ImportLocFileThread(file, listId, importStepHandler, progressHandler).start();
+ }
+ }
+
+ /**
+ * Import GPX provided via intent of activity that instantiated this GPXImporter.
+ */
+ public void importGPX() {
+ final ContentResolver contentResolver = ((Activity) fromActivity).getContentResolver();
+ final Intent intent = ((Activity) fromActivity).getIntent();
+ final Uri uri = intent.getData();
+
+ String mimeType = intent.getType();
+ // if mimetype can't be determined (e.g. for emulators email app), derive it from uri file extension
+ // contentResolver.getType(uri) doesn't help but throws exception for emulators email app
+ // Permission Denial: reading com.android.email.provider.EmailProvider uri
+ // Google search says: there is no solution for this problem
+ // Gmail doesn't work at all, see #967
+ if (mimeType == null) {
+ if (StringUtils.endsWithIgnoreCase(uri.getPath(), GPX_FILE_EXTENSION)) {
+ mimeType = "application/xml";
+ } else {
+ // if we can't determine a better type, default to zip import
+ // emulator email sends e.g. content://com.android.email.attachmentprovider/1/1/RAW, mimetype=null
+ mimeType = "application/zip";
+ }
+ }
+
+ Log.i(Settings.tag, "importGPX: " + uri + ", mimetype=" + mimeType);
+ if (GPX_MIME_TYPES.contains(mimeType)) {
+ new ImportGpxAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start();
+ } else if (ZIP_MIME_TYPES.contains(mimeType)) {
+ new ImportGpxZipAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start();
+ } else {
+ importFinished();
+ }
+ }
+
+ static abstract class ImportThread extends Thread {
+ final int listId;
+ final Handler importStepHandler;
+ final CancellableHandler progressHandler;
+
+ public ImportThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ this.listId = listId;
+ this.importStepHandler = importStepHandler;
+ this.progressHandler = progressHandler;
+ }
+
+ @Override
+ public void run() {
+ final Collection<cgCache> caches;
+ try {
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_START));
+ caches = doImport();
+
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_STORE_CACHES, R.string.gpx_import_storing, caches.size()));
+ SearchResult search = storeParsedCaches(caches);
+ Log.i(Settings.tag, "Imported successfully " + caches.size() + " caches.");
+
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, SearchResult.getCount(search), 0, search));
+ } catch (IOException e) {
+ Log.i(Settings.tag, "Importing caches failed - error reading data: " + e.getMessage());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_io, 0, e.getLocalizedMessage()));
+ } catch (ParserException e) {
+ Log.i(Settings.tag, "Importing caches failed - data format error" + e.getMessage());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_parser, 0, e.getLocalizedMessage()));
+ } catch (CancellationException e) {
+ Log.i(Settings.tag, "Importing caches canceled");
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_CANCELED));
+ } catch (Exception e) {
+ Log.e(Settings.tag, "Importing caches failed - unknown error: ", e);
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_unexpected, 0, e.getLocalizedMessage()));
+ }
+ }
+
+ protected abstract Collection<cgCache> doImport() throws IOException, ParserException;
+
+ private SearchResult storeParsedCaches(Collection<cgCache> caches) {
+ final SearchResult search = new SearchResult();
+ final cgeoapplication app = cgeoapplication.getInstance();
+ int storedCaches = 0;
+ for (cgCache cache : caches) {
+ // remove from cache because a cache might be re-imported
+ cgeoapplication.removeCacheFromCache(cache.getGeocode());
+ app.addCacheToSearch(search, cache);
+
+ // save memory, imported caches are typically not used immediately
+ cgeoapplication.removeCacheFromCache(cache.getGeocode());
+
+ if (progressHandler.isCancelled()) {
+ throw new CancellationException();
+ }
+ progressHandler.sendMessage(progressHandler.obtainMessage(0, ++storedCaches, 0));
+ }
+ return search;
+ }
+ }
+
+ static class ImportLocFileThread extends ImportThread {
+ private final File file;
+
+ public ImportLocFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.file = file;
+ }
+
+ @Override
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ Log.i(Settings.tag, "Import LOC file: " + file.getAbsolutePath());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) file.length()));
+ LocParser parser = new LocParser(listId);
+ return parser.parse(file, progressHandler);
+ }
+ }
+
+ static abstract class ImportGpxThread extends ImportThread {
+
+ public ImportGpxThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ }
+
+ @Override
+ protected Collection<cgCache> doImport() throws IOException, ParserException {
+ try {
+ // try to parse cache file as GPX 10
+ return doImport(new GPX10Parser(listId));
+ } catch (ParserException pe) {
+ // didn't work -> lets try GPX11
+ return doImport(new GPX11Parser(listId));
+ }
+ }
+
+ protected abstract Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException;
+ }
+
+ static class ImportGpxFileThread extends ImportGpxThread {
+ private final File cacheFile;
+
+ public ImportGpxFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.cacheFile = file;
+ }
+
+ @Override
+ protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
+ Log.i(Settings.tag, "Import GPX file: " + cacheFile.getAbsolutePath());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) cacheFile.length()));
+ Collection<cgCache> caches = parser.parse(cacheFile, progressHandler);
+
+ final String wptsFilename = getWaypointsFileNameForGpxFile(cacheFile);
+ if (wptsFilename != null) {
+ final File wptsFile = new File(cacheFile.getParentFile(), wptsFilename);
+ if (wptsFile.canRead()) {
+ Log.i(Settings.tag, "Import GPX waypoint file: " + wptsFile.getAbsolutePath());
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) wptsFile.length()));
+ caches = parser.parse(wptsFile, progressHandler);
+ }
+ }
+ return caches;
+ }
+ }
+
+ static class ImportGpxAttachmentThread extends ImportGpxThread {
+ private final Uri uri;
+ private ContentResolver contentResolver;
+
+ public ImportGpxAttachmentThread(Uri uri, ContentResolver contentResolver, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.uri = uri;
+ this.contentResolver = contentResolver;
+ }
+
+ @Override
+ protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
+ Log.i(Settings.tag, "Import GPX from uri: " + uri);
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, -1));
+ InputStream is = contentResolver.openInputStream(uri);
+ try {
+ return parser.parse(is, progressHandler);
+ } finally {
+ is.close();
+ }
+ }
+ }
+
+ static abstract class ImportGpxZipThread extends ImportGpxThread {
+
+ public ImportGpxZipThread(int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ }
+
+ @Override
+ protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
+ Collection<cgCache> caches = Collections.emptySet();
+ // can't assume that GPX file comes before waypoint file in zip -> so we need two passes
+ // 1. parse GPX files
+ ZipInputStream zis = new ZipInputStream(getInputStream());
+ try {
+ for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) {
+ if (StringUtils.endsWithIgnoreCase(zipEntry.getName(), GPX_FILE_EXTENSION)) {
+ if (!StringUtils.endsWithIgnoreCase(zipEntry.getName(), WAYPOINTS_FILE_SUFFIX_AND_EXTENSION)) {
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) zipEntry.getSize()));
+ caches = parser.parse(new NoCloseInputStream(zis), progressHandler);
+ }
+ } else {
+ throw new ParserException("Imported zip is not a GPX zip file.");
+ }
+ zis.closeEntry();
+ }
+ } finally {
+ zis.close();
+ }
+
+ // 2. parse waypoint files
+ zis = new ZipInputStream(getInputStream());
+ try {
+ for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) {
+ if (StringUtils.endsWithIgnoreCase(zipEntry.getName(), WAYPOINTS_FILE_SUFFIX_AND_EXTENSION)) {
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) zipEntry.getSize()));
+ caches = parser.parse(new NoCloseInputStream(zis), progressHandler);
+ }
+ zis.closeEntry();
+ }
+ } finally {
+ zis.close();
+ }
+
+ return caches;
+ }
+
+ protected abstract InputStream getInputStream() throws IOException;
+ }
+
+ static class ImportGpxZipFileThread extends ImportGpxZipThread {
+ private final File cacheFile;
+
+ public ImportGpxZipFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.cacheFile = file;
+ Log.i(Settings.tag, "Import zipped GPX: " + file);
+ }
+
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ return new FileInputStream(cacheFile);
+ }
+ }
+
+ static class ImportGpxZipAttachmentThread extends ImportGpxZipThread {
+ private final Uri uri;
+ private ContentResolver contentResolver;
+
+ public ImportGpxZipAttachmentThread(Uri uri, ContentResolver contentResolver, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
+ super(listId, importStepHandler, progressHandler);
+ this.uri = uri;
+ this.contentResolver = contentResolver;
+ Log.i(Settings.tag, "Import zipped GPX from uri: " + uri);
+ }
+
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ return contentResolver.openInputStream(uri);
+ }
+ }
+
+ final private CancellableHandler progressHandler = new CancellableHandler() {
+ @Override
+ public void handleRegularMessage(Message msg) {
+ progress.setProgress(msg.arg1);
+ }
+ };
+
+ final private Handler importStepHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case IMPORT_STEP_START:
+ Message cancelMessage = importStepHandler.obtainMessage(IMPORT_STEP_CANCEL);
+ progress.show((Context) fromActivity, res.getString(R.string.gpx_import_title_reading_file), res.getString(R.string.gpx_import_loading_caches), ProgressDialog.STYLE_HORIZONTAL, cancelMessage);
+ break;
+
+ case IMPORT_STEP_READ_FILE:
+ case IMPORT_STEP_READ_WPT_FILE:
+ case IMPORT_STEP_STORE_CACHES:
+ progress.setMessage(res.getString(msg.arg1));
+ progress.setMaxProgressAndReset(msg.arg2);
+ break;
+
+ case IMPORT_STEP_FINISHED:
+ progress.dismiss();
+ fromActivity.helpDialog(res.getString(R.string.gpx_import_title_caches_imported), msg.arg1 + " " + res.getString(R.string.gpx_import_caches_imported));
+ importFinished();
+ break;
+
+ case IMPORT_STEP_FINISHED_WITH_ERROR:
+ progress.dismiss();
+ fromActivity.helpDialog(res.getString(R.string.gpx_import_title_caches_import_failed), res.getString(msg.arg1) + "\n\n" + msg.obj);
+ importFinished();
+ break;
+
+ case IMPORT_STEP_CANCEL:
+ progress.dismiss();
+ progressHandler.cancel();
+ break;
+
+ case IMPORT_STEP_CANCELED:
+ fromActivity.showShortToast(res.getString(R.string.gpx_import_canceled));
+ importFinished();
+ break;
+
+ default:
+ break;
+ }
+ }
+ };
+
+ /**
+ * @param gpxfile
+ * the gpx file
+ * @return the expected file name of the waypoints file
+ */
+ static String getWaypointsFileNameForGpxFile(final File gpxfile) {
+ if (gpxfile == null || !gpxfile.canRead()) {
+ return null;
+ }
+ final String gpxFileName = gpxfile.getName();
+ File dir = gpxfile.getParentFile();
+ String[] filenameList = dir.list();
+ for (String filename : filenameList) {
+ if (!StringUtils.containsIgnoreCase(filename, WAYPOINTS_FILE_SUFFIX)) {
+ continue;
+ }
+ String expectedGpxFileName = StringUtils.substringBeforeLast(filename, WAYPOINTS_FILE_SUFFIX)
+ + StringUtils.substringAfterLast(filename, WAYPOINTS_FILE_SUFFIX);
+ if (gpxFileName.equals(expectedGpxFileName)) {
+ return filename;
+ }
+ }
+ return null;
+ }
+
+ protected void importFinished() {
+ if (importFinishedHandler != null) {
+ importFinishedHandler.sendEmptyMessage(0);
+ }
+ }
+}
diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java new file mode 100644 index 0000000..ab4ada0 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java @@ -0,0 +1,50 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgeoapplication; + +import org.apache.commons.lang3.StringUtils; + +import android.content.res.Resources; + +public class AttributeFilter extends AbstractFilter { + + private final String attribute; + + public AttributeFilter(final String name, final String attribute) { + super(name); + this.attribute = attribute; + } + + private static String getName(final String attribute, final Resources res, final String packageName) { + // dynamically search for a translation of the attribute + final int id = res.getIdentifier(attribute, "string", packageName); + if (id > 0) { + final String translated = res.getString(id); + if (StringUtils.isNotBlank(translated)) { + return translated; + } + } + return attribute; + } + + @Override + public boolean accepts(final cgCache cache) { + final cgCache fullCache = cgeoapplication.getInstance().getCacheByGeocode(cache.getGeocode()); + return fullCache.getAttributes().contains(attribute); + } + + public static IFilter[] getAllFilters() { + final String packageName = cgeoapplication.getInstance().getBaseContext().getPackageName(); + final Resources res = cgeoapplication.getInstance().getResources(); + + final String[] ids = res.getStringArray(R.array.attribute_ids); + final IFilter[] filters = new IFilter[ids.length]; + for (int i = 0; i < ids.length; i++) { + filters[i] = new AttributeFilter(getName("attribute_" + ids[i], res, packageName), ids[i]); + } + return filters; + } + +} diff --git a/main/src/cgeo/geocaching/filter/FilterByType.java b/main/src/cgeo/geocaching/filter/FilterByType.java deleted file mode 100644 index 6f6445e..0000000 --- a/main/src/cgeo/geocaching/filter/FilterByType.java +++ /dev/null @@ -1,23 +0,0 @@ -package cgeo.geocaching.filter; - -import cgeo.geocaching.cgCache; -import cgeo.geocaching.enumerations.CacheType; - -public class FilterByType extends AbstractFilter { - private final CacheType cacheType; - - public FilterByType(final CacheType cacheType) { - super(cacheType.id); - this.cacheType = cacheType; - } - - @Override - public boolean accepts(final cgCache cache) { - return cacheType == cache.getType(); - } - - @Override - public String getName() { - return cacheType.getL10n(); - } -} diff --git a/main/src/cgeo/geocaching/filter/FilterBySize.java b/main/src/cgeo/geocaching/filter/SizeFilter.java index a9d6036..638a7c9 100644 --- a/main/src/cgeo/geocaching/filter/FilterBySize.java +++ b/main/src/cgeo/geocaching/filter/SizeFilter.java @@ -3,10 +3,10 @@ package cgeo.geocaching.filter; import cgeo.geocaching.cgCache; import cgeo.geocaching.enumerations.CacheSize; -public class FilterBySize extends AbstractFilter { +public class SizeFilter extends AbstractFilter { private final CacheSize cacheSize; - public FilterBySize(CacheSize cacheSize) { + public SizeFilter(CacheSize cacheSize) { super(cacheSize.id); this.cacheSize = cacheSize; } @@ -20,4 +20,13 @@ public class FilterBySize extends AbstractFilter { public String getName() { return cacheSize.getL10n(); } + + public static AbstractFilter[] getAllFilters() { + final CacheSize[] cacheSizes = CacheSize.values(); + SizeFilter[] filters = new SizeFilter[cacheSizes.length]; + for (int i = 0; i < cacheSizes.length; i++) { + filters[i] = new SizeFilter(cacheSizes[i]); + } + return filters; + } } diff --git a/main/src/cgeo/geocaching/filter/StateFilter.java b/main/src/cgeo/geocaching/filter/StateFilter.java new file mode 100644 index 0000000..454cc92 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/StateFilter.java @@ -0,0 +1,96 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgeoapplication; + +import android.content.res.Resources; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +public abstract class StateFilter extends AbstractFilter { + + public StateFilter(String name) { + super(name); + } + + private static class StateFoundFilter extends StateFilter { + + public StateFoundFilter(String name) { + super(name); + } + + @Override + public boolean accepts(cgCache cache) { + return cache.isFound(); + } + + } + + private static class StateArchivedFilter extends StateFilter { + public StateArchivedFilter(String name) { + super(name); + } + + @Override + public boolean accepts(cgCache cache) { + return cache.isArchived(); + } + } + + private static class StateDisabledFilter extends StateFilter { + public StateDisabledFilter(String name) { + super(name); + } + + @Override + public boolean accepts(cgCache cache) { + return cache.isDisabled(); + } + } + + private static class StatePremiumFilter extends StateFilter { + public StatePremiumFilter(String name) { + super(name); + } + + @Override + public boolean accepts(cgCache cache) { + return cache.isPremiumMembersOnly(); + } + } + + private static class StateOfflineLogFilter extends StateFilter { + public StateOfflineLogFilter(String name) { + super(name); + } + + @Override + public boolean accepts(cgCache cache) { + return cache.isLogOffline(); + } + } + + public static AbstractFilter[] getAllFilters() { + final Resources res = cgeoapplication.getInstance().getResources(); + final ArrayList<StateFilter> filters = new ArrayList<StateFilter>(); + filters.add(new StateFoundFilter(res.getString(R.string.cache_status_found))); + filters.add(new StateArchivedFilter(res.getString(R.string.cache_status_archived))); + filters.add(new StateDisabledFilter(res.getString(R.string.cache_status_disabled))); + filters.add(new StatePremiumFilter(res.getString(R.string.cache_status_premium))); + filters.add(new StateOfflineLogFilter(res.getString(R.string.cache_status_offline_log))); + + Collections.sort(filters, new Comparator<StateFilter>() { + + @Override + public int compare(StateFilter filter1, StateFilter filter2) { + return filter1.getName().compareToIgnoreCase(filter2.getName()); + } + }); + + return filters.toArray(new StateFilter[filters.size()]); + } + +} diff --git a/main/src/cgeo/geocaching/filter/FilterByTrackables.java b/main/src/cgeo/geocaching/filter/TrackablesFilter.java index ad5c806..99d888b 100644 --- a/main/src/cgeo/geocaching/filter/FilterByTrackables.java +++ b/main/src/cgeo/geocaching/filter/TrackablesFilter.java @@ -2,8 +2,8 @@ package cgeo.geocaching.filter; import cgeo.geocaching.cgCache; -public class FilterByTrackables extends AbstractFilter { - public FilterByTrackables(String name) { +public class TrackablesFilter extends AbstractFilter { + public TrackablesFilter(String name) { super(name); } diff --git a/main/src/cgeo/geocaching/filter/TypeFilter.java b/main/src/cgeo/geocaching/filter/TypeFilter.java new file mode 100644 index 0000000..bb32fdd --- /dev/null +++ b/main/src/cgeo/geocaching/filter/TypeFilter.java @@ -0,0 +1,36 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.cgCache; +import cgeo.geocaching.enumerations.CacheType; + +import java.util.ArrayList; + +public class TypeFilter extends AbstractFilter { + private final CacheType cacheType; + + public TypeFilter(final CacheType cacheType) { + super(cacheType.id); + this.cacheType = cacheType; + } + + @Override + public boolean accepts(final cgCache cache) { + return cacheType == cache.getType(); + } + + @Override + public String getName() { + return cacheType.getL10n(); + } + + public static IFilter[] getAllFilters() { + final CacheType[] types = CacheType.values(); + ArrayList<IFilter> filters = new ArrayList<IFilter>(types.length); + for (CacheType cacheType : types) { + if (cacheType != CacheType.ALL) { + filters.add(new TypeFilter(cacheType)); + } + } + return filters.toArray(new TypeFilter[filters.size()]); + } +} diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java index 377014e..077add2 100644 --- a/main/src/cgeo/geocaching/gcvote/GCVote.java +++ b/main/src/cgeo/geocaching/gcvote/GCVote.java @@ -1,9 +1,9 @@ package cgeo.geocaching.gcvote; -import cgeo.geocaching.Parameters; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.LeastRecentlyUsedCache; import org.apache.commons.lang3.StringUtils; diff --git a/main/src/cgeo/geocaching/go4cache/Go4Cache.java b/main/src/cgeo/geocaching/go4cache/Go4Cache.java index 10da7d5..7243383 100644 --- a/main/src/cgeo/geocaching/go4cache/Go4Cache.java +++ b/main/src/cgeo/geocaching/go4cache/Go4Cache.java @@ -1,12 +1,12 @@ package cgeo.geocaching.go4cache; -import cgeo.geocaching.Parameters; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.geopoint.Viewport; +import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.CryptUtils; import org.apache.commons.lang3.StringUtils; diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index b5b648f..6592a3f 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps; +import cgeo.geocaching.ParseResult; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; @@ -52,7 +53,6 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; import android.widget.ImageSwitcher; import android.widget.ImageView; import android.widget.ImageView.ScaleType; @@ -61,8 +61,10 @@ import android.widget.ViewSwitcher.ViewFactory; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * Class representing the Map in c:geo @@ -112,7 +114,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory private WaypointType waypointTypeIntent = null; private int[] mapStateIntent = null; // status data - private SearchResult search = null; + private ParseResult search = null; private String token = null; private boolean noMapTokenShowed = false; // map status data @@ -155,7 +157,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory private static Map<Integer, LayerDrawable> overlaysCache = new HashMap<Integer, LayerDrawable>(); private int cachesCnt = 0; /** List of caches in the viewport */ - private List<cgCache> caches = new ArrayList<cgCache>(); + private Set<cgCache> caches = new HashSet<cgCache>(); /** List of users in the viewport */ private List<Go4CacheUser> users = new ArrayList<Go4CacheUser>(); private List<cgCoord> coordinates = new ArrayList<cgCoord>(); @@ -308,8 +310,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory // reset status noMapTokenShowed = false; - // set layout - activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + ActivityMixin.keepScreenOn(activity, true); // set layout ActivityMixin.setTheme(activity); @@ -1142,12 +1143,12 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory // stage 1 - pull and render from the DB only if (fromDetailIntent || searchIntent != null) { - search = searchIntent; + search = new ParseResult(searchIntent); } else { if (!live || !Settings.isLiveMap()) { - search = app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType()); + search = new ParseResult(app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); } else { - search = app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType()); + search = new ParseResult(app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); } } @@ -1169,13 +1170,11 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory final boolean excludeMine = Settings.isExcludeMyCaches(); final boolean excludeDisabled = Settings.isExcludeDisabledCaches(); - for (int i = caches.size() - 1; i >= 0; i--) { - cgCache cache = caches.get(i); + for (cgCache cache : caches) { if ((cache.isFound() && excludeMine) || (cache.isOwn() && excludeMine) || (cache.isDisabled() && excludeDisabled)) { - caches.remove(i); + caches.remove(cache); } } - } if (stop) { diff --git a/main/src/cgeo/geocaching/network/OAuth.java b/main/src/cgeo/geocaching/network/OAuth.java index 9e0a703..6d82bf7 100644 --- a/main/src/cgeo/geocaching/network/OAuth.java +++ b/main/src/cgeo/geocaching/network/OAuth.java @@ -1,6 +1,5 @@ package cgeo.geocaching.network; -import cgeo.geocaching.Parameters; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.utils.CryptUtils; diff --git a/main/src/cgeo/geocaching/Parameters.java b/main/src/cgeo/geocaching/network/Parameters.java index fdbbe3b..e65bec2 100644 --- a/main/src/cgeo/geocaching/Parameters.java +++ b/main/src/cgeo/geocaching/network/Parameters.java @@ -1,4 +1,4 @@ -package cgeo.geocaching; +package cgeo.geocaching.network; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; diff --git a/main/src/cgeo/geocaching/sorting/EventDateComparator.java b/main/src/cgeo/geocaching/sorting/EventDateComparator.java new file mode 100644 index 0000000..0092901 --- /dev/null +++ b/main/src/cgeo/geocaching/sorting/EventDateComparator.java @@ -0,0 +1,23 @@ +package cgeo.geocaching.sorting; + +import cgeo.geocaching.cgCache; + + +/** + * Compares caches by date. Used only for event caches. + * + * @author campbeb + * + */ +public class EventDateComparator extends DateComparator { + + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return super.canCompare(cache1, cache2); + } + + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + return super.compareCaches(cache1, cache2); + } +} diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java index 2f653f5..a47409f 100644 --- a/main/src/cgeo/geocaching/twitter/Twitter.java +++ b/main/src/cgeo/geocaching/twitter/Twitter.java @@ -1,12 +1,12 @@ package cgeo.geocaching.twitter; -import cgeo.geocaching.Parameters; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.network.OAuth; +import cgeo.geocaching.network.Parameters; import org.apache.http.HttpResponse; diff --git a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java index a3cb61a..83b1569 100644 --- a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java +++ b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java @@ -1,11 +1,11 @@ package cgeo.geocaching.twitter; -import cgeo.geocaching.Parameters; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.network.OAuth; +import cgeo.geocaching.network.Parameters; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java index c2910cf..85856fc 100644 --- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java +++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java @@ -5,11 +5,6 @@ import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; -import cgeo.geocaching.R.color; -import cgeo.geocaching.R.drawable; -import cgeo.geocaching.R.id; -import cgeo.geocaching.R.layout; -import cgeo.geocaching.R.string; import cgeo.geocaching.enumerations.CacheListType; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; diff --git a/main/src/cgeo/geocaching/ui/CompassMiniView.java b/main/src/cgeo/geocaching/ui/CompassMiniView.java index 5f3b8c2..1fa4cfb 100644 --- a/main/src/cgeo/geocaching/ui/CompassMiniView.java +++ b/main/src/cgeo/geocaching/ui/CompassMiniView.java @@ -1,8 +1,6 @@ package cgeo.geocaching.ui; import cgeo.geocaching.R; -import cgeo.geocaching.R.drawable; -import cgeo.geocaching.R.styleable; import cgeo.geocaching.geopoint.Geopoint; import android.content.Context; diff --git a/main/src/cgeo/geocaching/ui/DirectionImage.java b/main/src/cgeo/geocaching/ui/DirectionImage.java index 17c253a..c559531 100644 --- a/main/src/cgeo/geocaching/ui/DirectionImage.java +++ b/main/src/cgeo/geocaching/ui/DirectionImage.java @@ -1,8 +1,8 @@ package cgeo.geocaching.ui; -import cgeo.geocaching.Parameters; import cgeo.geocaching.cgBase; import cgeo.geocaching.files.LocalStorage; +import cgeo.geocaching.network.Parameters; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; diff --git a/main/src/cgeo/geocaching/ui/GPXListAdapter.java b/main/src/cgeo/geocaching/ui/GPXListAdapter.java index 23f38b0..2f50e6c 100644 --- a/main/src/cgeo/geocaching/ui/GPXListAdapter.java +++ b/main/src/cgeo/geocaching/ui/GPXListAdapter.java @@ -3,8 +3,6 @@ package cgeo.geocaching.ui; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.cgeogpxes; -import cgeo.geocaching.R.id; -import cgeo.geocaching.R.layout; import cgeo.geocaching.files.GPXImporter; import android.app.Activity; diff --git a/main/src/cgeo/geocaching/ui/MapfileListAdapter.java b/main/src/cgeo/geocaching/ui/MapfileListAdapter.java index cc16733..9196a41 100644 --- a/main/src/cgeo/geocaching/ui/MapfileListAdapter.java +++ b/main/src/cgeo/geocaching/ui/MapfileListAdapter.java @@ -3,8 +3,6 @@ package cgeo.geocaching.ui; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.cgSelectMapfile; -import cgeo.geocaching.R.id; -import cgeo.geocaching.R.layout; import android.app.Activity; import android.graphics.Typeface; diff --git a/main/src/cgeo/geocaching/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 7d330a3..141e3d9 100644 --- a/main/src/cgeo/geocaching/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -1,4 +1,8 @@ -package cgeo.geocaching; +package cgeo.geocaching.utils; + +import cgeo.geocaching.R; +import cgeo.geocaching.Settings; +import cgeo.geocaching.cgBase; import org.apache.commons.lang3.StringUtils; @@ -21,7 +25,7 @@ public class LogTemplateProvider { this.resourceId = resourceId; } - abstract String getValue(boolean offline); + abstract public String getValue(boolean offline); public int getResourceId() { return resourceId; @@ -51,21 +55,21 @@ public class LogTemplateProvider { new LogTemplate("DATE", R.string.init_signature_template_date) { @Override - String getValue(final boolean offline) { + public String getValue(final boolean offline) { return cgBase.formatFullDate(System.currentTimeMillis()); } }, new LogTemplate("TIME", R.string.init_signature_template_time) { @Override - String getValue(final boolean offline) { + public String getValue(final boolean offline) { return cgBase.formatTime(System.currentTimeMillis()); } }, new LogTemplate("DATETIME", R.string.init_signature_template_datetime) { @Override - String getValue(final boolean offline) { + public String getValue(final boolean offline) { final long currentTime = System.currentTimeMillis(); return cgBase.formatFullDate(currentTime) + " " + cgBase.formatTime(currentTime); } @@ -73,14 +77,14 @@ public class LogTemplateProvider { new LogTemplate("USER", R.string.init_signature_template_user) { @Override - String getValue(final boolean offline) { + public String getValue(final boolean offline) { return Settings.getUsername(); } }, new LogTemplate("NUMBER", R.string.init_signature_template_number) { @Override - String getValue(final boolean offline) { + public String getValue(final boolean offline) { if (offline) { return ""; } |