diff options
| author | SammysHP <sven@sammyshp.de> | 2011-09-14 21:42:32 +0200 |
|---|---|---|
| committer | SammysHP <sven@sammyshp.de> | 2011-09-14 21:42:32 +0200 |
| commit | 4f7c67407019de18fd53b640edb9682a346fbfef (patch) | |
| tree | 5a1d10843e8f5104e4202211f4792b5bfe830cb6 /src | |
| parent | 90e7bf968f6722b8df8b884f37617e7fc78901b5 (diff) | |
| download | cgeo-4f7c67407019de18fd53b640edb9682a346fbfef.zip cgeo-4f7c67407019de18fd53b640edb9682a346fbfef.tar.gz cgeo-4f7c67407019de18fd53b640edb9682a346fbfef.tar.bz2 | |
Formatting
Diffstat (limited to 'src')
178 files changed, 32750 insertions, 32479 deletions
diff --git a/src/cgeo/geocaching/ICache.java b/src/cgeo/geocaching/ICache.java index c91b959..1560700 100644 --- a/src/cgeo/geocaching/ICache.java +++ b/src/cgeo/geocaching/ICache.java @@ -3,81 +3,97 @@ */
package cgeo.geocaching;
-
/**
* Basic interface for caches
+ *
* @author blafoo
- *
+ *
*/
public interface ICache {
- /**
- * @return Geocode like GCxxxx
- */
- public String getGeocode();
- /**
- * @return Tradi, multi etc.
- */
- public String getType();
- /**
- * @return Displayed owner, might differ from the real owner
- */
- public String getOwner();
- /**
- * @return GC username of the owner
- */
- public String getOwnerReal();
- /**
- * @return Micro, small etc.
- */
- public String getSize();
- /**
- * @return Difficulty assessment
- */
- public Float getDifficulty();
- /**
- * @return Terrain assessment
- */
- public Float getTerrain();
- /**
- * @return Latitude, e.g. N 52° 12.345
- */
- public String getLatitude();
- /**
- * @return Longitude, e.g. E 9° 34.567
- */
- public String getLongitude();
- /**
- * @return true if the cache is disabled, false else
- */
- public boolean isDisabled();
- /**
- * @return true if the user is the owner of the cache, false else
- */
- public boolean isOwn();
- /**
- * @return true is the cache is archived, false else
- */
- public boolean isArchived();
- /**
- * @return true is the cache is a Premium Member cache only, false else
- */
- public boolean isMembersOnly();
- /**
- * @return Decrypted hint
- */
- public String getHint();
- /**
- * @return Description
- */
- public String getDescription();
- /**
- * @return Short Description
- */
- public String getShortDescription();
- /**
- * @return Name
- */
- public String getName();
+ /**
+ * @return Geocode like GCxxxx
+ */
+ public String getGeocode();
+
+ /**
+ * @return Tradi, multi etc.
+ */
+ public String getType();
+
+ /**
+ * @return Displayed owner, might differ from the real owner
+ */
+ public String getOwner();
+
+ /**
+ * @return GC username of the owner
+ */
+ public String getOwnerReal();
+
+ /**
+ * @return Micro, small etc.
+ */
+ public String getSize();
+
+ /**
+ * @return Difficulty assessment
+ */
+ public Float getDifficulty();
+
+ /**
+ * @return Terrain assessment
+ */
+ public Float getTerrain();
+
+ /**
+ * @return Latitude, e.g. N 52° 12.345
+ */
+ public String getLatitude();
+
+ /**
+ * @return Longitude, e.g. E 9° 34.567
+ */
+ public String getLongitude();
+
+ /**
+ * @return true if the cache is disabled, false else
+ */
+ public boolean isDisabled();
+
+ /**
+ * @return true if the user is the owner of the cache, false else
+ */
+ public boolean isOwn();
+
+ /**
+ * @return true is the cache is archived, false else
+ */
+ public boolean isArchived();
+
+ /**
+ * @return true is the cache is a Premium Member cache only, false else
+ */
+ public boolean isMembersOnly();
+
+ /**
+ * @return Decrypted hint
+ */
+ public String getHint();
+
+ /**
+ * @return Description
+ */
+ public String getDescription();
+
+ /**
+ * @return Short Description
+ */
+ public String getShortDescription();
+
+ /**
+ * @return Name
+ */
+ public String getName();
}
diff --git a/src/cgeo/geocaching/LogTemplateProvider.java b/src/cgeo/geocaching/LogTemplateProvider.java index 5196aeb..a02f585 100644 --- a/src/cgeo/geocaching/LogTemplateProvider.java +++ b/src/cgeo/geocaching/LogTemplateProvider.java @@ -1,158 +1,155 @@ package cgeo.geocaching;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
import org.apache.commons.lang3.StringUtils;
import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* provides all the available templates for logging
- *
+ *
*/
public class LogTemplateProvider {
- public static abstract class LogTemplate {
- private String template;
- private int resourceId;
-
- protected LogTemplate(String template, int resourceId) {
- this.template = template;
- this.resourceId = resourceId;
- }
-
- abstract String getValue(cgBase base, boolean offline);
-
- public int getResourceId() {
- return resourceId;
- }
-
- public int getItemId() {
- return template.hashCode();
- }
-
- public String getTemplateString() {
- return template;
- }
-
- protected String apply(String input, cgBase base, boolean offline) {
- if (input.contains("[" + template + "]")) {
- return input.replaceAll("\\[" + template + "\\]", getValue(base, offline));
- }
- return input;
- }
- }
-
- private static LogTemplate[] templates;
-
- public static LogTemplate[] getTemplates() {
- if (templates == null) {
- templates = new LogTemplate[] {
- new LogTemplate("DATE", R.string.init_signature_template_date) {
-
- @Override
- String getValue(final cgBase base, final boolean offline) {
- return base.formatFullDate(System.currentTimeMillis());
- }
- },
- new LogTemplate("TIME", R.string.init_signature_template_time) {
-
- @Override
- String getValue(final cgBase base, final boolean offline) {
- return base.formatTime(System.currentTimeMillis());
- }
- },
- new LogTemplate("DATETIME", R.string.init_signature_template_datetime) {
-
- @Override
- String getValue(final cgBase base, final boolean offline) {
- final long currentTime = System.currentTimeMillis();
- return base.formatFullDate(currentTime) + " " + base.formatTime(currentTime);
+ public static abstract class LogTemplate {
+ private String template;
+ private int resourceId;
+
+ protected LogTemplate(String template, int resourceId) {
+ this.template = template;
+ this.resourceId = resourceId;
+ }
+
+ abstract String getValue(cgBase base, boolean offline);
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public int getItemId() {
+ return template.hashCode();
+ }
+
+ public String getTemplateString() {
+ return template;
+ }
+
+ protected String apply(String input, cgBase base, boolean offline) {
+ if (input.contains("[" + template + "]")) {
+ return input.replaceAll("\\[" + template + "\\]", getValue(base, offline));
+ }
+ return input;
+ }
+ }
+
+ private static LogTemplate[] templates;
+
+ public static LogTemplate[] getTemplates() {
+ if (templates == null) {
+ templates = new LogTemplate[] {
+ new LogTemplate("DATE", R.string.init_signature_template_date) {
+
+ @Override
+ String getValue(final cgBase base, final boolean offline) {
+ return base.formatFullDate(System.currentTimeMillis());
+ }
+ },
+ new LogTemplate("TIME", R.string.init_signature_template_time) {
+
+ @Override
+ String getValue(final cgBase base, final boolean offline) {
+ return base.formatTime(System.currentTimeMillis());
+ }
+ },
+ new LogTemplate("DATETIME", R.string.init_signature_template_datetime) {
+
+ @Override
+ String getValue(final cgBase base, final boolean offline) {
+ final long currentTime = System.currentTimeMillis();
+ return base.formatFullDate(currentTime) + " " + base.formatTime(currentTime);
+ }
+ },
+ new LogTemplate("USER", R.string.init_signature_template_user) {
+
+ @Override
+ String getValue(final cgBase base, final boolean offline) {
+ return base.getUserName();
+ }
+ },
+ new LogTemplate("NUMBER", R.string.init_signature_template_number) {
+
+ @Override
+ String getValue(final cgBase base, final boolean offline) {
+ if (offline) {
+ return "";
+ }
+ String findCount = "";
+ final Map<String, String> params = new HashMap<String, String>();
+ final String page = base.request(false, "www.geocaching.com", "/email/", "GET", params, false, false, false).getData();
+ int current = parseFindCount(page);
+
+ if (current >= 0) {
+ findCount = String.valueOf(current + 1);
+ }
+ return findCount;
+ }
+ }
+ };
+ }
+ return templates;
+ }
+
+ public static LogTemplate getTemplate(int itemId) {
+ for (LogTemplate template : getTemplates()) {
+ if (template.getItemId() == itemId) {
+ return template;
+ }
+ }
+ return null;
+ }
+
+ public static String applyTemplates(String signature, cgBase base, boolean offline) {
+ if (signature == null) {
+ return "";
+ }
+ String result = signature;
+ for (LogTemplate template : getTemplates()) {
+ result = template.apply(result, base, offline);
+ }
+ return result;
+ }
+
+ private static int parseFindCount(String page) {
+ if (StringUtils.isBlank(page)) {
+ return -1;
+ }
+
+ int findCount = -1;
+
+ try {
+ final Pattern findPattern = Pattern.compile("<strong><img.+?icon_smile.+?title=\"Caches Found\" /> ([,\\d]+)", Pattern.CASE_INSENSITIVE);
+ final Matcher findMatcher = findPattern.matcher(page);
+ if (findMatcher.find()) {
+ if (findMatcher.groupCount() > 0) {
+ String count = findMatcher.group(1);
+
+ if (count != null) {
+ if (count.length() == 0) {
+ findCount = 0;
+ } else {
+ findCount = Integer.parseInt(count.replaceAll(",", ""));
+ }
+ }
}
- },
- new LogTemplate("USER", R.string.init_signature_template_user) {
-
- @Override
- String getValue(final cgBase base, final boolean offline) {
- return base.getUserName();
- }
- },
- new LogTemplate("NUMBER", R.string.init_signature_template_number) {
-
- @Override
- String getValue(final cgBase base, final boolean offline) {
- if (offline) {
- return "";
- }
- String findCount = "";
- final Map<String, String> params = new HashMap<String, String>();
- final String page = base.request(false, "www.geocaching.com", "/email/", "GET", params, false, false, false).getData();
- int current = parseFindCount(page);
-
- if (current >= 0) {
- findCount = String.valueOf(current + 1);
- }
- return findCount;
- }
- }
- };
- }
- return templates;
- }
-
- public static LogTemplate getTemplate(int itemId) {
- for (LogTemplate template : getTemplates()) {
- if (template.getItemId() == itemId) {
- return template;
- }
- }
- return null;
- }
-
- public static String applyTemplates(String signature, cgBase base, boolean offline) {
- if (signature == null) {
- return "";
- }
- String result = signature;
- for (LogTemplate template : getTemplates()) {
- result = template.apply(result, base, offline);
- }
- return result;
- }
-
- private static int parseFindCount(String page) {
- if (StringUtils.isBlank(page)) {
- return -1;
- }
-
- int findCount = -1;
-
- try {
- final Pattern findPattern = Pattern.compile("<strong><img.+?icon_smile.+?title=\"Caches Found\" /> ([,\\d]+)", Pattern.CASE_INSENSITIVE);
- final Matcher findMatcher = findPattern.matcher(page);
- if (findMatcher.find()) {
- if (findMatcher.groupCount() > 0) {
- String count = findMatcher.group(1);
-
- if (count != null) {
- if (count.length() == 0) {
- findCount = 0;
- } else {
- findCount = Integer.parseInt(count.replaceAll(",", ""));
- }
- }
- }
- }
- } catch (Exception e) {
- Log.w(cgSettings.tag, "cgBase.parseFindCount: " + e.toString());
- }
-
- return findCount;
- }
-
-
+ }
+ } catch (Exception e) {
+ Log.w(cgSettings.tag, "cgBase.parseFindCount: " + e.toString());
+ }
+
+ return findCount;
+ }
}
diff --git a/src/cgeo/geocaching/StaticMapsProvider.java b/src/cgeo/geocaching/StaticMapsProvider.java index ae1962c..7932363 100644 --- a/src/cgeo/geocaching/StaticMapsProvider.java +++ b/src/cgeo/geocaching/StaticMapsProvider.java @@ -1,10 +1,6 @@ package cgeo.geocaching; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Locale; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; @@ -19,168 +15,176 @@ import android.content.Context; import android.util.Log; import android.view.Display; import android.view.WindowManager; -import cgeo.geocaching.utils.CollectionUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; public class StaticMapsProvider { - private static final String MARKERS_URL = "http://cgeo.carnero.cc/_markers/"; - /** - * in my tests the "no image available" image had 5470 bytes, while "street only" maps had at least 20000 bytes - */ - private static final int MIN_MAP_IMAGE_BYTES = 6000; - - private static void downloadMapsInThread(final cgCache cache, String latlonMap, int edge, String waypoints) { - createStorageDirectory(cache); - - 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 createStorageDirectory(final cgCache cache) { - File dir = new File(cgSettings.getStorage()); - if (dir.exists() == false) { - dir.mkdirs(); - } - dir = new File(getStaticMapsDirectory(cache)); - if (dir.exists() == false) { - dir.mkdirs(); - } - } - - private static String getStaticMapsDirectory(final cgCache cache) { - return cgSettings.getStorage() + cache.geocode; - } - - private static void downloadMap(cgCache cache, int zoom, String mapType, int level, String latlonMap, int edge, String waypoints) { - String mapUrl = "http://maps.google.com/maps/api/staticmap?center=" + latlonMap; - String markerUrl = getMarkerUrl(cache); - - String url = mapUrl + "&zoom=" + zoom + "&size=" + edge + "x" + edge + "&maptype=" + mapType + "&markers=icon%3A" + markerUrl + "%7C" + latlonMap + waypoints + "&sensor=false"; - - final String fileName = getStaticMapsDirectory(cache) + "/map_" + level; - HttpClient client = null; - HttpGet getMethod = null; - HttpResponse httpResponse = null; - HttpEntity entity = null; - BufferedHttpEntity bufferedEntity = null; - - boolean ok = false; - - for (int i = 0; i < 3; i ++) { - if (i > 0) Log.w(cgSettings.tag, "cgMapImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); - - try { - client = new DefaultHttpClient(); - getMethod = new HttpGet(url); - httpResponse = client.execute(getMethod); - entity = httpResponse.getEntity(); - - // if image is to small, don't download and save, there is no map data for this zoom level - long contentSize = entity.getContentLength(); - if (contentSize > 0 && contentSize <= MIN_MAP_IMAGE_BYTES) { - break; - } - - bufferedEntity = new BufferedHttpEntity(entity); - if (bufferedEntity != null) { - InputStream is = (InputStream)bufferedEntity.getContent(); - FileOutputStream fos = new FileOutputStream(fileName); - - int fileSize = 0; - try { - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = is.read(buffer)) != -1) { - fos.write(buffer, 0, bytesRead); - fileSize += bytesRead; - } - fos.flush(); - ok = true; - } catch (IOException e) { - Log.e(cgSettings.tag, "cgMapImg.getDrawable (saving to cache): " + e.toString()); - } finally { - is.close(); - fos.close(); - } - - bufferedEntity = null; - - // delete image if it has no contents - if (ok && fileSize < MIN_MAP_IMAGE_BYTES) { - (new File(fileName)).delete(); - } - } - - if (ok) { - break; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapImg.getDrawable (downloading from web): " + e.toString()); - } - } - } - - public static void downloadMaps(cgCache cache, cgSettings settings, Activity activity) { - if (settings.storeOfflineMaps != 1 || cache.coords == null || StringUtils.isBlank(cache.geocode)) { - return; - } - - final String latlonMap = String.format((Locale) null, "%.6f", cache.coords.getLatitude()) + "," + - String.format((Locale) null, "%.6f", cache.coords.getLongitude()); - 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; - } - - final StringBuilder waypoints = new StringBuilder(); - if (CollectionUtils.isNotEmpty(cache.waypoints)) { - for (cgWaypoint waypoint : cache.waypoints) { - if (waypoint.coords == null) { - continue; - } - - waypoints.append("&markers=icon%3A"); - waypoints.append(MARKERS_URL); - waypoints.append("marker_waypoint_"); - waypoints.append(waypoint.type); - waypoints.append(".png%7C"); - waypoints.append(String.format((Locale) null, "%.6f", waypoint.coords.getLatitude())); - waypoints.append(','); - waypoints.append(String.format((Locale) null, "%.6f", waypoint.coords.getLongitude())); - } - } - - // download map images in separate background thread for higher performance - downloadMaps(cache, latlonMap, edge, waypoints.toString()); - } - - private static void downloadMaps(final cgCache cache, final String latlonMap, final int edge, - final String waypoints) { - Thread staticMapsThread = new Thread("getting static map") {@Override - public void run() { - downloadMapsInThread(cache, latlonMap, edge, waypoints); - }}; - staticMapsThread.setPriority(Thread.MIN_PRIORITY); - staticMapsThread.start(); - } - - private static String getMarkerUrl(final cgCache cache) { - String type = "mystery"; - if (cache.found) { - type = cache.type + "_found"; - } else if (cache.disabled) { - type = cache.type + "_disabled"; - } else { - type = cache.type; - } - - return cgBase.urlencode_rfc3986(MARKERS_URL + "marker_cache_" + type + ".png"); - } + private static final String MARKERS_URL = "http://cgeo.carnero.cc/_markers/"; + /** + * in my tests the "no image available" image had 5470 bytes, while "street only" maps had at least 20000 bytes + */ + private static final int MIN_MAP_IMAGE_BYTES = 6000; + + private static void downloadMapsInThread(final cgCache cache, String latlonMap, int edge, String waypoints) { + createStorageDirectory(cache); + + 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 createStorageDirectory(final cgCache cache) { + File dir = new File(cgSettings.getStorage()); + if (dir.exists() == false) { + dir.mkdirs(); + } + dir = new File(getStaticMapsDirectory(cache)); + if (dir.exists() == false) { + dir.mkdirs(); + } + } + + private static String getStaticMapsDirectory(final cgCache cache) { + return cgSettings.getStorage() + cache.geocode; + } + + private static void downloadMap(cgCache cache, int zoom, String mapType, int level, String latlonMap, int edge, String waypoints) { + String mapUrl = "http://maps.google.com/maps/api/staticmap?center=" + latlonMap; + String markerUrl = getMarkerUrl(cache); + + String url = mapUrl + "&zoom=" + zoom + "&size=" + edge + "x" + edge + "&maptype=" + mapType + "&markers=icon%3A" + markerUrl + "%7C" + latlonMap + waypoints + "&sensor=false"; + + final String fileName = getStaticMapsDirectory(cache) + "/map_" + level; + HttpClient client = null; + HttpGet getMethod = null; + HttpResponse httpResponse = null; + HttpEntity entity = null; + BufferedHttpEntity bufferedEntity = null; + + boolean ok = false; + + for (int i = 0; i < 3; i++) { + if (i > 0) + Log.w(cgSettings.tag, "cgMapImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); + + try { + client = new DefaultHttpClient(); + getMethod = new HttpGet(url); + httpResponse = client.execute(getMethod); + entity = httpResponse.getEntity(); + + // if image is to small, don't download and save, there is no map data for this zoom level + long contentSize = entity.getContentLength(); + if (contentSize > 0 && contentSize <= MIN_MAP_IMAGE_BYTES) { + break; + } + + bufferedEntity = new BufferedHttpEntity(entity); + if (bufferedEntity != null) { + InputStream is = (InputStream) bufferedEntity.getContent(); + FileOutputStream fos = new FileOutputStream(fileName); + + int fileSize = 0; + try { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + fos.write(buffer, 0, bytesRead); + fileSize += bytesRead; + } + fos.flush(); + ok = true; + } catch (IOException e) { + Log.e(cgSettings.tag, "cgMapImg.getDrawable (saving to cache): " + e.toString()); + } finally { + is.close(); + fos.close(); + } + + bufferedEntity = null; + + // delete image if it has no contents + if (ok && fileSize < MIN_MAP_IMAGE_BYTES) { + (new File(fileName)).delete(); + } + } + + if (ok) { + break; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapImg.getDrawable (downloading from web): " + e.toString()); + } + } + } + + public static void downloadMaps(cgCache cache, cgSettings settings, Activity activity) { + if (settings.storeOfflineMaps != 1 || cache.coords == null || StringUtils.isBlank(cache.geocode)) { + return; + } + + final String latlonMap = String.format((Locale) null, "%.6f", cache.coords.getLatitude()) + "," + + String.format((Locale) null, "%.6f", cache.coords.getLongitude()); + 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; + } + + final StringBuilder waypoints = new StringBuilder(); + if (CollectionUtils.isNotEmpty(cache.waypoints)) { + for (cgWaypoint waypoint : cache.waypoints) { + if (waypoint.coords == null) { + continue; + } + + waypoints.append("&markers=icon%3A"); + waypoints.append(MARKERS_URL); + waypoints.append("marker_waypoint_"); + waypoints.append(waypoint.type); + waypoints.append(".png%7C"); + waypoints.append(String.format((Locale) null, "%.6f", waypoint.coords.getLatitude())); + waypoints.append(','); + waypoints.append(String.format((Locale) null, "%.6f", waypoint.coords.getLongitude())); + } + } + + // download map images in separate background thread for higher performance + downloadMaps(cache, latlonMap, edge, waypoints.toString()); + } + + private static void downloadMaps(final cgCache cache, final String latlonMap, final int edge, + final String waypoints) { + Thread staticMapsThread = new Thread("getting static map") { + @Override + public void run() { + downloadMapsInThread(cache, latlonMap, edge, waypoints); + } + }; + staticMapsThread.setPriority(Thread.MIN_PRIORITY); + staticMapsThread.start(); + } + + private static String getMarkerUrl(final cgCache cache) { + String type = "mystery"; + if (cache.found) { + type = cache.type + "_found"; + } else if (cache.disabled) { + type = cache.type + "_disabled"; + } else { + type = cache.type; + } + + return cgBase.urlencode_rfc3986(MARKERS_URL + "marker_cache_" + type + ".png"); + } } diff --git a/src/cgeo/geocaching/UnknownTagsHandler.java b/src/cgeo/geocaching/UnknownTagsHandler.java index f1b418c..6fab349 100644 --- a/src/cgeo/geocaching/UnknownTagsHandler.java +++ b/src/cgeo/geocaching/UnknownTagsHandler.java @@ -9,25 +9,25 @@ import android.text.style.StrikethroughSpan; public class UnknownTagsHandler implements TagHandler { - private static final int UNDEFINED_POSITION = -1; - int strikePos = UNDEFINED_POSITION; + private static final int UNDEFINED_POSITION = -1; + int strikePos = UNDEFINED_POSITION; - public void handleTag(boolean opening, String tag, Editable output, + public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { - if(tag.equalsIgnoreCase("strike") || tag.equals("s")) { + if (tag.equalsIgnoreCase("strike") || tag.equals("s")) { handleStrike(opening, output); } } - private void handleStrike(boolean opening, Editable output) { + private void handleStrike(boolean opening, Editable output) { int length = output.length(); - if(opening) { - strikePos = length; + if (opening) { + strikePos = length; } else { - if (strikePos > UNDEFINED_POSITION) { - output.setSpan(new StrikethroughSpan(), strikePos, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - strikePos = UNDEFINED_POSITION; - } + if (strikePos > UNDEFINED_POSITION) { + output.setSpan(new StrikethroughSpan(), strikePos, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + strikePos = UNDEFINED_POSITION; + } } } } diff --git a/src/cgeo/geocaching/activity/AbstractActivity.java b/src/cgeo/geocaching/activity/AbstractActivity.java index 1c2d637..358aba3 100644 --- a/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/src/cgeo/geocaching/activity/AbstractActivity.java @@ -1,5 +1,10 @@ package cgeo.geocaching.activity; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgeoapplication; + import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; @@ -7,79 +12,75 @@ import android.content.res.Resources; import android.os.Bundle; import android.view.Menu; import android.view.View; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgeoapplication; public abstract class AbstractActivity extends Activity implements IAbstractActivity { - private String helpTopic; - - protected cgeoapplication app = null; - protected Resources res = null; - protected cgSettings settings = null; - protected cgBase base = null; - protected SharedPreferences prefs = null; - - protected AbstractActivity() { - this(null); - } - - protected AbstractActivity(final String helpTopic) { - this.helpTopic = helpTopic; - } - - final public void goHome(final View view) { - ActivityMixin.goHome(this); - } - - public void goManual(final View view) { - ActivityMixin.goManual(this, helpTopic); - } - - final public void setTitle(final String title) { - ActivityMixin.setTitle(this, title); - } - - final public void showProgress(final boolean show) { - ActivityMixin.showProgress(this, show); - } - - final public void setTheme() { - ActivityMixin.setTheme(this); - } - - public final void showToast(String text) { - ActivityMixin.showToast(this, text); - } - - public final void showShortToast(String text) { - ActivityMixin.showShortToast(this, text); - } - - public final void helpDialog(String title, String message) { - ActivityMixin.helpDialog(this, title, message); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - res = this.getResources(); - app = (cgeoapplication) this.getApplication(); - prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); - settings = new cgSettings(this, prefs); - base = new cgBase(app, settings, prefs); - } - - final public cgSettings getSettings() { - return settings; - } - - public void addVisitMenu(Menu menu, cgCache cache) { - ActivityMixin.addVisitMenu(this, menu, cache); - } + private String helpTopic; + + protected cgeoapplication app = null; + protected Resources res = null; + protected cgSettings settings = null; + protected cgBase base = null; + protected SharedPreferences prefs = null; + + protected AbstractActivity() { + this(null); + } + + protected AbstractActivity(final String helpTopic) { + this.helpTopic = helpTopic; + } + + final public void goHome(final View view) { + ActivityMixin.goHome(this); + } + + public void goManual(final View view) { + ActivityMixin.goManual(this, helpTopic); + } + + final public void setTitle(final String title) { + ActivityMixin.setTitle(this, title); + } + + final public void showProgress(final boolean show) { + ActivityMixin.showProgress(this, show); + } + + final public void setTheme() { + ActivityMixin.setTheme(this); + } + + public final void showToast(String text) { + ActivityMixin.showToast(this, text); + } + + public final void showShortToast(String text) { + ActivityMixin.showShortToast(this, text); + } + + public final void helpDialog(String title, String message) { + ActivityMixin.helpDialog(this, title, message); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + res = this.getResources(); + app = (cgeoapplication) this.getApplication(); + prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); + settings = new cgSettings(this, prefs); + base = new cgBase(app, settings, prefs); + } + + final public cgSettings getSettings() { + return settings; + } + + public void addVisitMenu(Menu menu, cgCache cache) { + ActivityMixin.addVisitMenu(this, menu, cache); + } } diff --git a/src/cgeo/geocaching/activity/AbstractListActivity.java b/src/cgeo/geocaching/activity/AbstractListActivity.java index 4624d34..0afa69c 100644 --- a/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -1,5 +1,10 @@ package cgeo.geocaching.activity; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgeoapplication; + import android.app.ListActivity; import android.content.Context; import android.content.SharedPreferences; @@ -7,80 +12,76 @@ import android.content.res.Resources; import android.os.Bundle; import android.view.Menu; import android.view.View; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgeoapplication; public abstract class AbstractListActivity extends ListActivity implements - IAbstractActivity { - - private String helpTopic; - - protected cgeoapplication app = null; - protected Resources res = null; - protected cgSettings settings = null; - protected cgBase base = null; - protected SharedPreferences prefs = null; - - protected AbstractListActivity() { - this(null); - } - - protected AbstractListActivity(final String helpTopic) { - this.helpTopic = helpTopic; - } - - final public void goHome(View view) { - ActivityMixin.goHome(this); - } - - public void goManual(View view) { - ActivityMixin.goManual(this, helpTopic); - } - - final public void showProgress(final boolean show) { - ActivityMixin.showProgress(this, show); - } - - final public void setTheme() { - ActivityMixin.setTheme(this); - } - - public final void showToast(String text) { - ActivityMixin.showToast(this, text); - } - - public final void showShortToast(String text) { - ActivityMixin.showShortToast(this, text); - } - - public final void helpDialog(String title, String message) { - ActivityMixin.helpDialog(this, title, message); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - res = this.getResources(); - app = (cgeoapplication) this.getApplication(); - prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); - settings = new cgSettings(this, prefs); - base = new cgBase(app, settings, prefs); - } - - final public void setTitle(final String title) { - ActivityMixin.setTitle(this, title); - } - - final public cgSettings getSettings() { - return settings; - } - - public void addVisitMenu(Menu menu, cgCache cache) { - ActivityMixin.addVisitMenu(this, menu, cache); - } + IAbstractActivity { + + private String helpTopic; + + protected cgeoapplication app = null; + protected Resources res = null; + protected cgSettings settings = null; + protected cgBase base = null; + protected SharedPreferences prefs = null; + + protected AbstractListActivity() { + this(null); + } + + protected AbstractListActivity(final String helpTopic) { + this.helpTopic = helpTopic; + } + + final public void goHome(View view) { + ActivityMixin.goHome(this); + } + + public void goManual(View view) { + ActivityMixin.goManual(this, helpTopic); + } + + final public void showProgress(final boolean show) { + ActivityMixin.showProgress(this, show); + } + + final public void setTheme() { + ActivityMixin.setTheme(this); + } + + public final void showToast(String text) { + ActivityMixin.showToast(this, text); + } + + public final void showShortToast(String text) { + ActivityMixin.showShortToast(this, text); + } + + public final void helpDialog(String title, String message) { + ActivityMixin.helpDialog(this, title, message); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + res = this.getResources(); + app = (cgeoapplication) this.getApplication(); + prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); + settings = new cgSettings(this, prefs); + base = new cgBase(app, settings, prefs); + } + + final public void setTitle(final String title) { + ActivityMixin.setTitle(this, title); + } + + final public cgSettings getSettings() { + return settings; + } + + public void addVisitMenu(Menu menu, cgCache cache) { + ActivityMixin.addVisitMenu(this, menu, cache); + } } diff --git a/src/cgeo/geocaching/activity/ActivityMixin.java b/src/cgeo/geocaching/activity/ActivityMixin.java index 53efd4b..ece589b 100644 --- a/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/src/cgeo/geocaching/activity/ActivityMixin.java @@ -1,8 +1,10 @@ package cgeo.geocaching.activity; -import gnu.android.app.appmanualclient.AppManualReaderClient; - -import java.util.List; +import cgeo.geocaching.R; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgeo; import org.apache.commons.lang3.StringUtils; @@ -19,131 +21,130 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import cgeo.geocaching.R; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgeo; + +import gnu.android.app.appmanualclient.AppManualReaderClient; + +import java.util.List; public final class ActivityMixin { - private static final int MENU_ICON_LOG_VISIT = android.R.drawable.ic_menu_agenda; - - public final static void goHome(final Activity fromActivity) { - final Intent intent = new Intent(fromActivity, cgeo.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - - fromActivity.startActivity(intent); - fromActivity.finish(); - } - - public final static void goManual(final Context context, final String helpTopic) { - if (StringUtils.isBlank(helpTopic)) { - return; - } - try { - AppManualReaderClient.openManual( - "c-geo", - helpTopic, - context, - "http://manual.cgeo.org/"); - } catch (Exception e) { - // nothing - } - } - - public final static void setTitle(final Activity activity, final String text) { - if (StringUtils.isBlank(text)) { - return; - } - - final TextView title = (TextView) activity.findViewById(R.id.actionbar_title); - if (title != null) { - title.setText(text); - } - } - - public final static void showProgress(final Activity activity, final boolean show) { - if (activity == null) { - return; - } - - final ProgressBar progress = (ProgressBar) activity.findViewById(R.id.actionbar_progress); - if (show) { - progress.setVisibility(View.VISIBLE); - } else { - progress.setVisibility(View.GONE); - } - } - - public final static void setTheme(final Activity activity) { - cgSettings settings = new cgSettings(activity, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); - if (settings.skin == 1) { - activity.setTheme(R.style.light); - } else { - activity.setTheme(R.style.dark); - } - } - - public final static void showToast(final Activity activity, final String text) { - if (StringUtils.isNotBlank(text)) { - Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG); - - toast.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM, 0, 100); - toast.show(); - } - } - - public final static void showShortToast(final Activity activity, final String text) { - if (StringUtils.isNotBlank(text)) { - Toast toast = Toast.makeText(activity, text, Toast.LENGTH_SHORT); - - toast.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM, 0, 100); - toast.show(); - } - } - - public static final void helpDialog(final Activity activity, final String title, final String message) { - if (StringUtils.isBlank(message)) { - return; - } - - AlertDialog.Builder dialog = new AlertDialog.Builder(activity); - dialog.setTitle(title); - dialog.setMessage(message); - dialog.setCancelable(true); - dialog.setNeutralButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { + private static final int MENU_ICON_LOG_VISIT = android.R.drawable.ic_menu_agenda; + + public final static void goHome(final Activity fromActivity) { + final Intent intent = new Intent(fromActivity, cgeo.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + + fromActivity.startActivity(intent); + fromActivity.finish(); + } + + public final static void goManual(final Context context, final String helpTopic) { + if (StringUtils.isBlank(helpTopic)) { + return; + } + try { + AppManualReaderClient.openManual( + "c-geo", + helpTopic, + context, + "http://manual.cgeo.org/"); + } catch (Exception e) { + // nothing + } + } + + public final static void setTitle(final Activity activity, final String text) { + if (StringUtils.isBlank(text)) { + return; + } + + final TextView title = (TextView) activity.findViewById(R.id.actionbar_title); + if (title != null) { + title.setText(text); + } + } + + public final static void showProgress(final Activity activity, final boolean show) { + if (activity == null) { + return; + } + + final ProgressBar progress = (ProgressBar) activity.findViewById(R.id.actionbar_progress); + if (show) { + progress.setVisibility(View.VISIBLE); + } else { + progress.setVisibility(View.GONE); + } + } + + public final static void setTheme(final Activity activity) { + cgSettings settings = new cgSettings(activity, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); + if (settings.skin == 1) { + activity.setTheme(R.style.light); + } else { + activity.setTheme(R.style.dark); + } + } + + public final static void showToast(final Activity activity, final String text) { + if (StringUtils.isNotBlank(text)) { + Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG); + + toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100); + toast.show(); + } + } + + public final static void showShortToast(final Activity activity, final String text) { + if (StringUtils.isNotBlank(text)) { + Toast toast = Toast.makeText(activity, text, Toast.LENGTH_SHORT); + + toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 100); + toast.show(); + } + } + + public static final void helpDialog(final Activity activity, final String title, final String message) { + if (StringUtils.isBlank(message)) { + return; + } + + AlertDialog.Builder dialog = new AlertDialog.Builder(activity); + dialog.setTitle(title); + dialog.setMessage(message); + dialog.setCancelable(true); + dialog.setNeutralButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { dialog.cancel(); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - } - - protected static void addVisitMenu(IAbstractActivity activity, Menu menu, cgCache cache) { - if (cache == null) { - return; - } - if (!cache.supportsLogging()) { - return; - } - cgSettings settings = activity.getSettings(); - Resources res = ((Activity)activity).getResources(); - if (settings.isLogin()) { - if (settings.getLogOffline()) { - SubMenu logMenu = menu.addSubMenu(1, IAbstractActivity.MENU_LOG_VISIT_OFFLINE, 0, res.getString(R.string.cache_menu_visit_offline)).setIcon(MENU_ICON_LOG_VISIT); - List<Integer> logTypes = cache.getPossibleLogTypes(settings); - for (Integer logType : logTypes) { - String label = cgBase.logTypes2.get(logType); - logMenu.add(1, IAbstractActivity.MENU_LOG_VISIT_OFFLINE + logType, 0, label); - } - logMenu.add(1, IAbstractActivity.MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)); - } - else { - menu.add(1, IAbstractActivity.MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)).setIcon(MENU_ICON_LOG_VISIT); - } - } - } + } + }); + + AlertDialog alert = dialog.create(); + alert.show(); + } + + protected static void addVisitMenu(IAbstractActivity activity, Menu menu, cgCache cache) { + if (cache == null) { + return; + } + if (!cache.supportsLogging()) { + return; + } + cgSettings settings = activity.getSettings(); + Resources res = ((Activity) activity).getResources(); + if (settings.isLogin()) { + if (settings.getLogOffline()) { + SubMenu logMenu = menu.addSubMenu(1, IAbstractActivity.MENU_LOG_VISIT_OFFLINE, 0, res.getString(R.string.cache_menu_visit_offline)).setIcon(MENU_ICON_LOG_VISIT); + List<Integer> logTypes = cache.getPossibleLogTypes(settings); + for (Integer logType : logTypes) { + String label = cgBase.logTypes2.get(logType); + logMenu.add(1, IAbstractActivity.MENU_LOG_VISIT_OFFLINE + logType, 0, label); + } + logMenu.add(1, IAbstractActivity.MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)); + } + else { + menu.add(1, IAbstractActivity.MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)).setIcon(MENU_ICON_LOG_VISIT); + } + } + } } diff --git a/src/cgeo/geocaching/activity/IAbstractActivity.java b/src/cgeo/geocaching/activity/IAbstractActivity.java index fd6b9a4..dac97f3 100644 --- a/src/cgeo/geocaching/activity/IAbstractActivity.java +++ b/src/cgeo/geocaching/activity/IAbstractActivity.java @@ -1,36 +1,36 @@ package cgeo.geocaching.activity; -import android.view.Menu; -import android.view.View; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgSettings; +import android.view.Menu; +import android.view.View; + public interface IAbstractActivity { - static final int MENU_LOG_VISIT = 100; - static final int MENU_LOG_VISIT_OFFLINE = 101; - - public void goHome(View view); + static final int MENU_LOG_VISIT = 100; + static final int MENU_LOG_VISIT_OFFLINE = 101; + + public void goHome(View view); + + public void goManual(View view); - public void goManual(View view); + public void showProgress(final boolean show); - public void showProgress(final boolean show); + public void setTheme(); - public void setTheme(); + public void showToast(String text); - public void showToast(String text); + public void showShortToast(String text); - public void showShortToast(String text); + public void helpDialog(String title, String message); - public void helpDialog(String title, String message); + public void setTitle(final String title); - public void setTitle(final String title); + /** + * TODO: remove after settings are a singleton + */ + public cgSettings getSettings(); - /** - * TODO: remove after settings are a singleton - */ - public cgSettings getSettings(); - - void addVisitMenu(Menu menu, cgCache cache); - + void addVisitMenu(Menu menu, cgCache cache); } diff --git a/src/cgeo/geocaching/apps/AbstractApp.java b/src/cgeo/geocaching/apps/AbstractApp.java index 190bf5e..f917563 100644 --- a/src/cgeo/geocaching/apps/AbstractApp.java +++ b/src/cgeo/geocaching/apps/AbstractApp.java @@ -1,81 +1,82 @@ package cgeo.geocaching.apps; -import java.util.List; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.utils.CollectionUtils; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.List; public abstract class AbstractApp implements App { - protected String packageName; - - private String intent; - private String name; - - protected AbstractApp(final String name, final String intent, - final String packageName) { - this.name = name; - this.intent = intent; - this.packageName = packageName; - } - - protected AbstractApp(final String name, final String intent) { - this(name, intent, null); - } - - protected Intent getLaunchIntent(Context context) { - if (packageName == null) { - return null; - } - PackageManager packageManager = context.getPackageManager(); - try { - // This can throw an exception where the exception type is only defined on API Level > 3 - // therefore surround with try-catch - Intent intent = packageManager.getLaunchIntentForPackage(packageName); - return intent; - } catch (Exception e) { - return null; - } - } - - public boolean isInstalled(final Context context) { - if (getLaunchIntent(context) != null) { - return true; - } - return isIntentAvailable(context, intent); - } - - private static boolean isIntentAvailable(Context context, String action) { - final Intent intent = new Intent(action); - - return isIntentAvailable(context, intent); - } - - protected static boolean isIntentAvailable(Context context, Intent intent) { - final PackageManager packageManager = context.getPackageManager(); - final List<ResolveInfo> list = packageManager.queryIntentActivities( - intent, PackageManager.MATCH_DEFAULT_ONLY); - - return (CollectionUtils.isNotEmpty(list)); - } - - @Override - public String getName() { - return name; - } - - @Override - public int getId() { - return getName().hashCode(); - } - - protected static cgSettings getSettings(Activity activity) { - return new cgSettings(activity, - activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); - } + protected String packageName; + + private String intent; + private String name; + + protected AbstractApp(final String name, final String intent, + final String packageName) { + this.name = name; + this.intent = intent; + this.packageName = packageName; + } + + protected AbstractApp(final String name, final String intent) { + this(name, intent, null); + } + + protected Intent getLaunchIntent(Context context) { + if (packageName == null) { + return null; + } + PackageManager packageManager = context.getPackageManager(); + try { + // This can throw an exception where the exception type is only defined on API Level > 3 + // therefore surround with try-catch + Intent intent = packageManager.getLaunchIntentForPackage(packageName); + return intent; + } catch (Exception e) { + return null; + } + } + + public boolean isInstalled(final Context context) { + if (getLaunchIntent(context) != null) { + return true; + } + return isIntentAvailable(context, intent); + } + + private static boolean isIntentAvailable(Context context, String action) { + final Intent intent = new Intent(action); + + return isIntentAvailable(context, intent); + } + + protected static boolean isIntentAvailable(Context context, Intent intent) { + final PackageManager packageManager = context.getPackageManager(); + final List<ResolveInfo> list = packageManager.queryIntentActivities( + intent, PackageManager.MATCH_DEFAULT_ONLY); + + return (CollectionUtils.isNotEmpty(list)); + } + + @Override + public String getName() { + return name; + } + + @Override + public int getId() { + return getName().hashCode(); + } + + protected static cgSettings getSettings(Activity activity) { + return new cgSettings(activity, + activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); + } } diff --git a/src/cgeo/geocaching/apps/AbstractAppFactory.java b/src/cgeo/geocaching/apps/AbstractAppFactory.java index 84d708d..bb8b017 100644 --- a/src/cgeo/geocaching/apps/AbstractAppFactory.java +++ b/src/cgeo/geocaching/apps/AbstractAppFactory.java @@ -4,13 +4,13 @@ import android.view.MenuItem; public abstract class AbstractAppFactory { - protected static App getAppFromMenuItem(MenuItem item, final App[] availableApps) { - int id = item.getItemId(); - for (App app : availableApps) { - if (app.getId() == id) { - return app; - } - } - return null; - } + protected static App getAppFromMenuItem(MenuItem item, final App[] availableApps) { + int id = item.getItemId(); + for (App app : availableApps) { + if (app.getId() == id) { + return app; + } + } + return null; + } } diff --git a/src/cgeo/geocaching/apps/AbstractLocusApp.java b/src/cgeo/geocaching/apps/AbstractLocusApp.java index 041894c..b817669 100644 --- a/src/cgeo/geocaching/apps/AbstractLocusApp.java +++ b/src/cgeo/geocaching/apps/AbstractLocusApp.java @@ -1,8 +1,12 @@ package cgeo.geocaching.apps; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.enumerations.CacheSize; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.WaypointType; import menion.android.locus.addon.publiclib.DisplayData; import menion.android.locus.addon.publiclib.LocusUtils; @@ -10,47 +14,49 @@ import menion.android.locus.addon.publiclib.geoData.Point; import menion.android.locus.addon.publiclib.geoData.PointGeocachingData; import menion.android.locus.addon.publiclib.geoData.PointGeocachingDataWaypoint; import menion.android.locus.addon.publiclib.geoData.PointsData; + import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.location.Location; -import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgWaypoint; -import cgeo.geocaching.enumerations.CacheSize; -import cgeo.geocaching.enumerations.CacheType; -import cgeo.geocaching.enumerations.WaypointType; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; /** * for the Locus API: + * * @see http://forum.asamm.cz/viewtopic.php?f=29&t=767 */ public abstract class AbstractLocusApp extends AbstractApp { - private static final String INTENT = Intent.ACTION_VIEW; - private static final SimpleDateFormat ISO8601DATE = new SimpleDateFormat("yyyy-MM-dd'T'"); - - protected AbstractLocusApp(final Resources res) { - super(res.getString(R.string.caches_map_locus), INTENT); - } - - @Override - public boolean isInstalled(Context context) { - return LocusUtils.isLocusAvailable(context); - } - - /** - * Display a list of caches / waypoints in Locus - * - * @param objectsToShow which caches/waypoints to show - * @param withCacheWaypoints wether to give waypoints of caches to Locus or not - * @param activity - * @author koem - */ - protected void showInLocus(List<? extends Object> objectsToShow, boolean withCacheWaypoints, - Activity activity) { - if (objectsToShow == null) return; + private static final String INTENT = Intent.ACTION_VIEW; + private static final SimpleDateFormat ISO8601DATE = new SimpleDateFormat("yyyy-MM-dd'T'"); + + protected AbstractLocusApp(final Resources res) { + super(res.getString(R.string.caches_map_locus), INTENT); + } + + @Override + public boolean isInstalled(Context context) { + return LocusUtils.isLocusAvailable(context); + } + + /** + * Display a list of caches / waypoints in Locus + * + * @param objectsToShow + * which caches/waypoints to show + * @param withCacheWaypoints + * wether to give waypoints of caches to Locus or not + * @param activity + * @author koem + */ + protected void showInLocus(List<? extends Object> objectsToShow, boolean withCacheWaypoints, + Activity activity) { + if (objectsToShow == null) + return; int pc = 0; // counter for points PointsData pd = new PointsData("c:geo"); @@ -64,95 +70,106 @@ public abstract class AbstractLocusApp extends AbstractApp { } else { continue; // no cache, no waypoint => ignore } - if (p == null) continue; + if (p == null) + continue; pd.addPoint(p); ++pc; } if (pc <= 1000) { - DisplayData.sendData(activity, pd, false); + DisplayData.sendData(activity, pd, false); } else { - ArrayList<PointsData> data = new ArrayList<PointsData>(); - data.add(pd); - DisplayData.sendDataCursor(activity, data, - "content://" + LocusDataStorageProvider.class.getCanonicalName().toLowerCase(), - false); + ArrayList<PointsData> data = new ArrayList<PointsData>(); + data.add(pd); + DisplayData.sendDataCursor(activity, data, + "content://" + LocusDataStorageProvider.class.getCanonicalName().toLowerCase(), + false); } - } - - /** - * This method constructs a <code>Point</code> for displaying in Locus - * - * @param cache - * @param withWaypoints whether to give waypoints to Locus or not - * @return null, when the <code>Point</code> could not be constructed - * @author koem - */ - private static Point getPoint(cgCache cache, boolean withWaypoints) { - if (cache == null || cache.coords == null) return null; - - // create one simple point with location - Location loc = new Location(cgSettings.tag); - loc.setLatitude(cache.coords.getLatitude()); - loc.setLongitude(cache.coords.getLongitude()); - - Point p = new Point(cache.name, loc); - PointGeocachingData pg = new PointGeocachingData(); - p.setGeocachingData(pg); - - // set data in Locus' cache - pg.cacheID = cache.geocode; - pg.available = ! cache.disabled; - pg.archived = cache.archived; - pg.premiumOnly = cache.members; - pg.name = cache.name; - pg.placedBy = cache.owner; - if (cache.hidden != null) pg.hidden = ISO8601DATE.format(cache.hidden.getTime()); - int locusId = toLocusId(CacheType.FIND_BY_CGEOID.get(cache.type)); - if (locusId != NO_LOCUS_ID) pg.type = locusId; - locusId = toLocusId(CacheSize.FIND_BY_CGEOID.get(cache.size)); - if (locusId != NO_LOCUS_ID) pg.container = locusId; - if (cache.difficulty != null) pg.difficulty = cache.difficulty; - if (cache.terrain != null) pg.terrain = cache.terrain; - pg.found = cache.found; - - if (withWaypoints && cache.waypoints != null) { - pg.waypoints = new ArrayList<PointGeocachingDataWaypoint>(); - for (cgWaypoint waypoint : cache.waypoints) { - if (waypoint == null || waypoint.coords == null) continue; - PointGeocachingDataWaypoint wp = new PointGeocachingDataWaypoint(); - wp.code = waypoint.geocode; - wp.name = waypoint.name; - String locusWpId = toLocusId(WaypointType.FIND_BY_CGEOID.get(waypoint.type)); - if (locusWpId != null) wp.type = locusWpId; - wp.lat = waypoint.coords.getLatitude(); - wp.lon = waypoint.coords.getLongitude(); - pg.waypoints.add(wp); - } + } + + /** + * This method constructs a <code>Point</code> for displaying in Locus + * + * @param cache + * @param withWaypoints + * whether to give waypoints to Locus or not + * @return null, when the <code>Point</code> could not be constructed + * @author koem + */ + private static Point getPoint(cgCache cache, boolean withWaypoints) { + if (cache == null || cache.coords == null) + return null; + + // create one simple point with location + Location loc = new Location(cgSettings.tag); + loc.setLatitude(cache.coords.getLatitude()); + loc.setLongitude(cache.coords.getLongitude()); + + Point p = new Point(cache.name, loc); + PointGeocachingData pg = new PointGeocachingData(); + p.setGeocachingData(pg); + + // set data in Locus' cache + pg.cacheID = cache.geocode; + pg.available = !cache.disabled; + pg.archived = cache.archived; + pg.premiumOnly = cache.members; + pg.name = cache.name; + pg.placedBy = cache.owner; + if (cache.hidden != null) + pg.hidden = ISO8601DATE.format(cache.hidden.getTime()); + int locusId = toLocusId(CacheType.FIND_BY_CGEOID.get(cache.type)); + if (locusId != NO_LOCUS_ID) + pg.type = locusId; + locusId = toLocusId(CacheSize.FIND_BY_CGEOID.get(cache.size)); + if (locusId != NO_LOCUS_ID) + pg.container = locusId; + if (cache.difficulty != null) + pg.difficulty = cache.difficulty; + if (cache.terrain != null) + pg.terrain = cache.terrain; + pg.found = cache.found; + + if (withWaypoints && cache.waypoints != null) { + pg.waypoints = new ArrayList<PointGeocachingDataWaypoint>(); + for (cgWaypoint waypoint : cache.waypoints) { + if (waypoint == null || waypoint.coords == null) + continue; + PointGeocachingDataWaypoint wp = new PointGeocachingDataWaypoint(); + wp.code = waypoint.geocode; + wp.name = waypoint.name; + String locusWpId = toLocusId(WaypointType.FIND_BY_CGEOID.get(waypoint.type)); + if (locusWpId != null) + wp.type = locusWpId; + wp.lat = waypoint.coords.getLatitude(); + wp.lon = waypoint.coords.getLongitude(); + pg.waypoints.add(wp); + } } - // Other properties of caches, not used yet. When there are many caches to be displayed - // in Locus, using these properties can lead to Exceptions in Locus. - // Examination necessary when to display and when not. E. g.: > 200 caches: don't display - // these properties. + // Other properties of caches, not used yet. When there are many caches to be displayed + // in Locus, using these properties can lead to Exceptions in Locus. + // Examination necessary when to display and when not. E. g.: > 200 caches: don't display + // these properties. //pg.shortDescription = cache.shortdesc; //pg.longDescription = cache.description; //pg.encodedHints = cache.hint; - return p; - } + return p; + } - /** + /** * This method constructs a <code>Point</code> for displaying in Locus - * + * * @param waypoint - * @return null, when the <code>Point</code> could not be constructed + * @return null, when the <code>Point</code> could not be constructed * @author koem */ private static Point getPoint(cgWaypoint waypoint) { - if (waypoint == null || waypoint.coords == null) return null; + if (waypoint == null || waypoint.coords == null) + return null; // create one simple point with location Location loc = new Location(cgSettings.tag); @@ -161,7 +178,7 @@ public abstract class AbstractLocusApp extends AbstractApp { Point p = new Point(waypoint.name, loc); p.setDescription("<a href=\"http://coord.info/" + waypoint.geocode + "\">" - + waypoint.geocode + "</a>"); + + waypoint.geocode + "</a>"); return p; } @@ -170,45 +187,74 @@ public abstract class AbstractLocusApp extends AbstractApp { private static int toLocusId(final CacheType ct) { switch (ct) { - case TRADITIONAL: return PointGeocachingData.CACHE_TYPE_TRADITIONAL; - case MULTI: return PointGeocachingData.CACHE_TYPE_MULTI; - case MYSTERY: return PointGeocachingData.CACHE_TYPE_MYSTERY; - case LETTERBOX: return PointGeocachingData.CACHE_TYPE_LETTERBOX; - case EVENT: return PointGeocachingData.CACHE_TYPE_EVENT; - case MEGA_EVENT: return PointGeocachingData.CACHE_TYPE_MEGA_EVENT; - case EARTH: return PointGeocachingData.CACHE_TYPE_EARTH; - case CITO: return PointGeocachingData.CACHE_TYPE_CACHE_IN_TRASH_OUT; - case WEBCAM: return PointGeocachingData.CACHE_TYPE_WEBCAM; - case VIRTUAL: return PointGeocachingData.CACHE_TYPE_VIRTUAL; - case WHERIGO: return PointGeocachingData.CACHE_TYPE_WHERIGO; - case PROJECT_APE: return PointGeocachingData.CACHE_TYPE_PROJECT_APE; - case GPS_EXHIBIT: return PointGeocachingData.CACHE_TYPE_GPS_ADVENTURE; - default: return NO_LOCUS_ID; + case TRADITIONAL: + return PointGeocachingData.CACHE_TYPE_TRADITIONAL; + case MULTI: + return PointGeocachingData.CACHE_TYPE_MULTI; + case MYSTERY: + return PointGeocachingData.CACHE_TYPE_MYSTERY; + case LETTERBOX: + return PointGeocachingData.CACHE_TYPE_LETTERBOX; + case EVENT: + return PointGeocachingData.CACHE_TYPE_EVENT; + case MEGA_EVENT: + return PointGeocachingData.CACHE_TYPE_MEGA_EVENT; + case EARTH: + return PointGeocachingData.CACHE_TYPE_EARTH; + case CITO: + return PointGeocachingData.CACHE_TYPE_CACHE_IN_TRASH_OUT; + case WEBCAM: + return PointGeocachingData.CACHE_TYPE_WEBCAM; + case VIRTUAL: + return PointGeocachingData.CACHE_TYPE_VIRTUAL; + case WHERIGO: + return PointGeocachingData.CACHE_TYPE_WHERIGO; + case PROJECT_APE: + return PointGeocachingData.CACHE_TYPE_PROJECT_APE; + case GPS_EXHIBIT: + return PointGeocachingData.CACHE_TYPE_GPS_ADVENTURE; + default: + return NO_LOCUS_ID; } } private static int toLocusId(final CacheSize cs) { switch (cs) { - case MICRO: return PointGeocachingData.CACHE_SIZE_MICRO; - case SMALL: return PointGeocachingData.CACHE_SIZE_SMALL; - case REGULAR: return PointGeocachingData.CACHE_SIZE_REGULAR; - case LARGE: return PointGeocachingData.CACHE_SIZE_LARGE; - case NOT_CHOSEN: return PointGeocachingData.CACHE_SIZE_NOT_CHOSEN; - case OTHER: return PointGeocachingData.CACHE_SIZE_OTHER; - default: return NO_LOCUS_ID; + case MICRO: + return PointGeocachingData.CACHE_SIZE_MICRO; + case SMALL: + return PointGeocachingData.CACHE_SIZE_SMALL; + case REGULAR: + return PointGeocachingData.CACHE_SIZE_REGULAR; + case LARGE: + return PointGeocachingData.CACHE_SIZE_LARGE; + case NOT_CHOSEN: + return PointGeocachingData.CACHE_SIZE_NOT_CHOSEN; + case OTHER: + return PointGeocachingData.CACHE_SIZE_OTHER; + default: + return NO_LOCUS_ID; } } private static String toLocusId(final WaypointType wt) { switch (wt) { - case FLAG: return PointGeocachingData.CACHE_WAYPOINT_TYPE_FINAL; - case OWN: return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; - case PKG: return PointGeocachingData.CACHE_WAYPOINT_TYPE_PARKING; - case PUZZLE: return PointGeocachingData.CACHE_WAYPOINT_TYPE_QUESTION; - case STAGE: return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; - case TRAILHEAD: return PointGeocachingData.CACHE_WAYPOINT_TYPE_TRAILHEAD; - case WAYPOINT: return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; - default: return null; + case FLAG: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_FINAL; + case OWN: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; + case PKG: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_PARKING; + case PUZZLE: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_QUESTION; + case STAGE: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; + case TRAILHEAD: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_TRAILHEAD; + case WAYPOINT: + return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES; + default: + return null; } } diff --git a/src/cgeo/geocaching/apps/App.java b/src/cgeo/geocaching/apps/App.java index 4fda041..8241737 100644 --- a/src/cgeo/geocaching/apps/App.java +++ b/src/cgeo/geocaching/apps/App.java @@ -3,7 +3,9 @@ package cgeo.geocaching.apps; import android.content.Context; public interface App { - public boolean isInstalled(final Context context); - public String getName(); - int getId(); + public boolean isInstalled(final Context context); + + public String getName(); + + int getId(); } diff --git a/src/cgeo/geocaching/apps/LocusDataStorageProvider.java b/src/cgeo/geocaching/apps/LocusDataStorageProvider.java index 4b6a91f..9fc794f 100755..100644 --- a/src/cgeo/geocaching/apps/LocusDataStorageProvider.java +++ b/src/cgeo/geocaching/apps/LocusDataStorageProvider.java @@ -1,70 +1,70 @@ package cgeo.geocaching.apps;
-import java.util.ArrayList;
-
import menion.android.locus.addon.publiclib.geoData.PointsData;
import menion.android.locus.addon.publiclib.utils.DataCursor;
import menion.android.locus.addon.publiclib.utils.DataStorage;
+
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
+import java.util.ArrayList;
+
/**
* code provided by menion - developer of Locus
*/
public class LocusDataStorageProvider extends ContentProvider {
-
- @Override
- public Cursor query(Uri aUri, String[] aProjection, String aSelection,
- String[] aSelectionArgs, String aSortOrder) {
-
- DataCursor cursor = new DataCursor(new String[] {"data"});
-
- ArrayList<PointsData> data = DataStorage.getData();
- if (data == null || data.size() == 0)
- return cursor;
-
- for (int i = 0; i < data.size(); i++) {
- // get byte array
- Parcel par = Parcel.obtain();
- data.get(i).writeToParcel(par, 0);
- byte[] byteData = par.marshall();
- // add to row
- cursor.addRow(new Object[] {byteData});
- }
- // data filled to cursor, clear reference to prevent some memory issue
- DataStorage.clearData();
- // now finally return filled cursor
- return cursor;
- }
+ @Override
+ public Cursor query(Uri aUri, String[] aProjection, String aSelection,
+ String[] aSelectionArgs, String aSortOrder) {
+
+ DataCursor cursor = new DataCursor(new String[] { "data" });
+
+ ArrayList<PointsData> data = DataStorage.getData();
+ if (data == null || data.size() == 0)
+ return cursor;
+
+ for (int i = 0; i < data.size(); i++) {
+ // get byte array
+ Parcel par = Parcel.obtain();
+ data.get(i).writeToParcel(par, 0);
+ byte[] byteData = par.marshall();
+ // add to row
+ cursor.addRow(new Object[] { byteData });
+ }
+ // data filled to cursor, clear reference to prevent some memory issue
+ DataStorage.clearData();
+ // now finally return filled cursor
+ return cursor;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
- @Override
- public String getType(Uri uri) {
- return null;
- }
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
- @Override
- public boolean onCreate() {
- return false;
- }
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return 0;
+ }
- @Override
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
- return 0;
- }
-
}
diff --git a/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java b/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java index 5fd8542..8d0d5ae 100644 --- a/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java +++ b/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java @@ -1,33 +1,34 @@ package cgeo.geocaching.apps.cache; -import android.app.Activity; -import android.content.Intent; import cgeo.geocaching.cgCache; import cgeo.geocaching.apps.AbstractApp; +import android.app.Activity; +import android.content.Intent; + abstract class AbstractGeneralApp extends AbstractApp implements GeneralApp { - protected AbstractGeneralApp(String name, String packageName) { - super(name, null); - this.packageName = packageName; - } + protected AbstractGeneralApp(String name, String packageName) { + super(name, null); + this.packageName = packageName; + } - @Override - public boolean isEnabled(cgCache cache) { - return true; - } + @Override + public boolean isEnabled(cgCache cache) { + return true; + } - @Override - public boolean invoke(Activity activity, cgCache cache) { - if (packageName == null) { - return false; - } - Intent intent = getLaunchIntent(activity); - if (intent != null) { - intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - activity.startActivity(intent); - return true; - } - return false; - } + @Override + public boolean invoke(Activity activity, cgCache cache) { + if (packageName == null) { + return false; + } + Intent intent = getLaunchIntent(activity); + if (intent != null) { + intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + activity.startActivity(intent); + return true; + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/GccApp.java b/src/cgeo/geocaching/apps/cache/GccApp.java index 0509d18..06ce6c2 100644 --- a/src/cgeo/geocaching/apps/cache/GccApp.java +++ b/src/cgeo/geocaching/apps/cache/GccApp.java @@ -1,10 +1,11 @@ package cgeo.geocaching.apps.cache; -import android.content.res.Resources; import cgeo.geocaching.R; +import android.content.res.Resources; + class GccApp extends AbstractGeneralApp implements GeneralApp { - GccApp(final Resources res) { - super(res.getString(R.string.cache_menu_gcc), "eisbehr.gcc"); - } + GccApp(final Resources res) { + super(res.getString(R.string.cache_menu_gcc), "eisbehr.gcc"); + } } diff --git a/src/cgeo/geocaching/apps/cache/GeneralApp.java b/src/cgeo/geocaching/apps/cache/GeneralApp.java index 80ac228..805d64c 100644 --- a/src/cgeo/geocaching/apps/cache/GeneralApp.java +++ b/src/cgeo/geocaching/apps/cache/GeneralApp.java @@ -1,13 +1,14 @@ package cgeo.geocaching.apps.cache; -import android.app.Activity; import cgeo.geocaching.cgCache; import cgeo.geocaching.apps.App; +import android.app.Activity; + interface GeneralApp extends App { - boolean isEnabled(final cgCache cache); + boolean isEnabled(final cgCache cache); - public boolean invoke(Activity activity, cgCache cache); + public boolean invoke(Activity activity, cgCache cache); } diff --git a/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java b/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java index c184bd0..eb581ca 100644 --- a/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java +++ b/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java @@ -1,5 +1,9 @@ package cgeo.geocaching.apps.cache; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.apps.AbstractAppFactory; + import org.apache.commons.lang3.ArrayUtils; import android.app.Activity; @@ -7,41 +11,38 @@ import android.content.res.Resources; import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.apps.AbstractAppFactory; public final class GeneralAppsFactory extends AbstractAppFactory { - private static GeneralApp[] apps = new GeneralApp[] {}; - - private static GeneralApp[] getGeneralApps(Resources res) { - if (ArrayUtils.isEmpty(apps)) { - apps = new GeneralApp[] { new GccApp(res), - new WhereYouGoApp(res) }; - } - return apps; - } - - public static void addMenuItems(Menu menu, Activity activity, - Resources res, cgCache cache) { - for (GeneralApp app : getGeneralApps(res)) { - if (app.isInstalled(activity) && app.isEnabled(cache)) { - menu.add(0, app.getId(), 0, app.getName()); - } - } - } - - public static boolean onMenuItemSelected(final MenuItem item, - Activity activity, cgCache cache) { - GeneralApp app = (GeneralApp) getAppFromMenuItem(item, apps); - if (app != null) { - try { - return app.invoke(activity, cache); - } catch (Exception e) { - Log.e(cgSettings.tag, "GeneralAppsFactory.onMenuItemSelected: " + e.toString()); - } - } - return false; - } + private static GeneralApp[] apps = new GeneralApp[] {}; + + private static GeneralApp[] getGeneralApps(Resources res) { + if (ArrayUtils.isEmpty(apps)) { + apps = new GeneralApp[] { new GccApp(res), + new WhereYouGoApp(res) }; + } + return apps; + } + + public static void addMenuItems(Menu menu, Activity activity, + Resources res, cgCache cache) { + for (GeneralApp app : getGeneralApps(res)) { + if (app.isInstalled(activity) && app.isEnabled(cache)) { + menu.add(0, app.getId(), 0, app.getName()); + } + } + } + + public static boolean onMenuItemSelected(final MenuItem item, + Activity activity, cgCache cache) { + GeneralApp app = (GeneralApp) getAppFromMenuItem(item, apps); + if (app != null) { + try { + return app.invoke(activity, cache); + } catch (Exception e) { + Log.e(cgSettings.tag, "GeneralAppsFactory.onMenuItemSelected: " + e.toString()); + } + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java b/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java index 93a86e0..b12a6d1 100644 --- a/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java +++ b/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java @@ -1,16 +1,17 @@ package cgeo.geocaching.apps.cache; -import android.content.res.Resources; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; +import android.content.res.Resources; + class WhereYouGoApp extends AbstractGeneralApp implements GeneralApp { - WhereYouGoApp(Resources res) { - super(res.getString(R.string.cache_menu_whereyougo), "menion.android.whereyougo"); - } + WhereYouGoApp(Resources res) { + super(res.getString(R.string.cache_menu_whereyougo), "menion.android.whereyougo"); + } - @Override - public boolean isEnabled(cgCache cache) { - return cache != null && cache.type != null && cache.type.equalsIgnoreCase("wherigo"); - } + @Override + public boolean isEnabled(cgCache cache) { + return cache != null && cache.type != null && cache.type.equalsIgnoreCase("wherigo"); + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/AbstractInternalMap.java b/src/cgeo/geocaching/apps/cache/navi/AbstractInternalMap.java index 3e5eff6..a1ffc89 100644 --- a/src/cgeo/geocaching/apps/cache/navi/AbstractInternalMap.java +++ b/src/cgeo/geocaching/apps/cache/navi/AbstractInternalMap.java @@ -4,12 +4,12 @@ import android.content.Context; abstract class AbstractInternalMap extends AbstractNavigationApp { - protected AbstractInternalMap(String name, String intent) { - super(name, intent); - } - - @Override - public boolean isInstalled(Context context) { - return true; - } + protected AbstractInternalMap(String name, String intent) { + super(name, intent); + } + + @Override + public boolean isInstalled(Context context) { + return true; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java b/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java index f14c053..3b10f1a 100644 --- a/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java @@ -4,12 +4,12 @@ import cgeo.geocaching.apps.AbstractApp; abstract class AbstractNavigationApp extends AbstractApp implements NavigationApp { - protected AbstractNavigationApp(String name, String intent, String packageName) { - super(name, intent, packageName); - } + protected AbstractNavigationApp(String name, String intent, String packageName) { + super(name, intent, packageName); + } - protected AbstractNavigationApp(String name, String intent) { - super(name, intent); - } + protected AbstractNavigationApp(String name, String intent) { + super(name, intent); + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java b/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java index 6307434..fd9caec 100644 --- a/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java @@ -1,13 +1,5 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.net.Uri; -import android.util.Log; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; @@ -16,49 +8,58 @@ import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.net.Uri; +import android.util.Log; + +import java.util.UUID; + class GoogleMapsApp extends AbstractNavigationApp implements NavigationApp { - GoogleMapsApp(final Resources res) { - super(res.getString(R.string.cache_menu_map_ext), null); - } + GoogleMapsApp(final Resources res) { + super(res.getString(R.string.cache_menu_map_ext), null); + } - @Override - public boolean isInstalled(Context context) { - return true; - } + @Override + public boolean isInstalled(Context context) { + return true; + } - public boolean invoke(cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - if (cache == null && waypoint == null && coords == null) { - return false; - } + public boolean invoke(cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + if (cache == null && waypoint == null && coords == null) { + return false; + } - try { - if (cache != null && cache.coords != null) { - startActivity(activity, cache.coords); - } else if (waypoint != null && waypoint.coords != null) { - startActivity(activity, waypoint.coords); - } + try { + if (cache != null && cache.coords != null) { + startActivity(activity, cache.coords); + } else if (waypoint != null && waypoint.coords != null) { + startActivity(activity, waypoint.coords); + } - return true; - } catch (Exception e) { - // nothing - } + return true; + } catch (Exception e) { + // nothing + } - Log.i(cgSettings.tag, "cgBase.runExternalMap: No maps application available."); + Log.i(cgSettings.tag, "cgBase.runExternalMap: No maps application available."); - if (res != null) { - ActivityMixin.showToast(activity, res.getString(R.string.err_application_no)); - } + if (res != null) { + ActivityMixin.showToast(activity, res.getString(R.string.err_application_no)); + } - return false; - } + return false; + } - private void startActivity(Activity activity, final Geopoint coords) { - activity.startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("geo:" + coords.getLatitude() + "," + coords.getLongitude()))); - // INFO: q parameter works with Google Maps, but breaks cooperation with all other apps - } + private void startActivity(Activity activity, final Geopoint coords) { + activity.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("geo:" + coords.getLatitude() + "," + coords.getLongitude()))); + // INFO: q parameter works with Google Maps, but breaks cooperation with all other apps + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java b/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java index c106988..2cd2b22 100644 --- a/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java @@ -1,13 +1,5 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.net.Uri; -import android.util.Log; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; @@ -16,86 +8,95 @@ import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.net.Uri; +import android.util.Log; + +import java.util.UUID; + class GoogleNavigationApp extends AbstractNavigationApp implements - NavigationApp { - - GoogleNavigationApp(final Resources res) { - super(res.getString(R.string.cache_menu_tbt), null); - } - - @Override - public boolean isInstalled(Context context) { - return true; - } - - @Override - public boolean invoke(final cgGeo geo, final Activity activity, final Resources res, - final cgCache cache, - final UUID searchId, final cgWaypoint waypoint, final Geopoint coords) { - if (activity == null) { - return false; - } - - boolean navigationResult = false; - if (coords != null) { - navigationResult = navigateToCoordinates(geo, activity, coords); - } - else if (waypoint != null) { - navigationResult = navigateToCoordinates(geo, activity, waypoint.coords); - } - else if (cache != null) { - navigationResult = navigateToCoordinates(geo, activity, cache.coords); - } - - if (!navigationResult) { - if (res != null) { - ActivityMixin.showToast(activity, res.getString(R.string.err_navigation_no)); - } - return false; - } - - return true; - } - - private static boolean navigateToCoordinates(cgGeo geo, Activity activity, final Geopoint coords) { - final Geopoint coordsNow = geo == null ? null : geo.coordsNow; - - cgSettings settings = getSettings(activity); - - // Google Navigation - if (settings.useGNavigation == 1) { - try { - activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri - .parse("google.navigation:ll=" + coords.getLatitude() + "," - + coords.getLongitude()))); - - return true; - } catch (Exception e) { - // nothing - } - } - - // Google Maps Directions - try { - if (coordsNow != null) { - activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri - .parse("http://maps.google.com/maps?f=d&saddr=" - + coordsNow.getLatitude() + "," + coordsNow.getLongitude() + "&daddr=" - + coords.getLatitude() + "," + coords.getLongitude()))); - } else { - activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri - .parse("http://maps.google.com/maps?f=d&daddr=" - + coords.getLatitude() + "," + coords.getLongitude()))); - } - - return true; - } catch (Exception e) { - // nothing - } - - Log.i(cgSettings.tag, - "cgBase.runNavigation: No navigation application available."); - return false; - } + NavigationApp { + + GoogleNavigationApp(final Resources res) { + super(res.getString(R.string.cache_menu_tbt), null); + } + + @Override + public boolean isInstalled(Context context) { + return true; + } + + @Override + public boolean invoke(final cgGeo geo, final Activity activity, final Resources res, + final cgCache cache, + final UUID searchId, final cgWaypoint waypoint, final Geopoint coords) { + if (activity == null) { + return false; + } + + boolean navigationResult = false; + if (coords != null) { + navigationResult = navigateToCoordinates(geo, activity, coords); + } + else if (waypoint != null) { + navigationResult = navigateToCoordinates(geo, activity, waypoint.coords); + } + else if (cache != null) { + navigationResult = navigateToCoordinates(geo, activity, cache.coords); + } + + if (!navigationResult) { + if (res != null) { + ActivityMixin.showToast(activity, res.getString(R.string.err_navigation_no)); + } + return false; + } + + return true; + } + + private static boolean navigateToCoordinates(cgGeo geo, Activity activity, final Geopoint coords) { + final Geopoint coordsNow = geo == null ? null : geo.coordsNow; + + cgSettings settings = getSettings(activity); + + // Google Navigation + if (settings.useGNavigation == 1) { + try { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri + .parse("google.navigation:ll=" + coords.getLatitude() + "," + + coords.getLongitude()))); + + return true; + } catch (Exception e) { + // nothing + } + } + + // Google Maps Directions + try { + if (coordsNow != null) { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri + .parse("http://maps.google.com/maps?f=d&saddr=" + + coordsNow.getLatitude() + "," + coordsNow.getLongitude() + "&daddr=" + + coords.getLatitude() + "," + coords.getLongitude()))); + } else { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri + .parse("http://maps.google.com/maps?f=d&daddr=" + + coords.getLatitude() + "," + coords.getLongitude()))); + } + + return true; + } catch (Exception e) { + // nothing + } + + Log.i(cgSettings.tag, + "cgBase.runNavigation: No navigation application available."); + return false; + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/apps/cache/navi/InternalMap.java b/src/cgeo/geocaching/apps/cache/navi/InternalMap.java index 4936842..0aa49db 100644 --- a/src/cgeo/geocaching/apps/cache/navi/InternalMap.java +++ b/src/cgeo/geocaching/apps/cache/navi/InternalMap.java @@ -1,10 +1,5 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.Intent; -import android.content.res.Resources; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; @@ -12,35 +7,41 @@ import cgeo.geocaching.cgSettings; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Intent; +import android.content.res.Resources; + +import java.util.UUID; + class InternalMap extends AbstractInternalMap implements - NavigationApp { - - InternalMap(Resources res) { - super(res.getString(R.string.cache_menu_map), null); - } - - @Override - public boolean invoke(cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - cgSettings settings = getSettings(activity); - Intent mapIntent = new Intent(activity, settings.getMapFactory().getMapClass()); - if (cache != null) { - mapIntent.putExtra("detail", false); - mapIntent.putExtra("geocode", cache.geocode); - } - if (searchId != null) { - mapIntent.putExtra("detail", true); - mapIntent.putExtra("searchid", searchId.toString()); - } - if (waypoint != null) { - mapIntent.putExtra("latitude", waypoint.coords.getLatitude()); - mapIntent.putExtra("longitude", waypoint.coords.getLongitude()); - mapIntent.putExtra("wpttype", waypoint.type); - } - - activity.startActivity(mapIntent); - return true; - } + NavigationApp { + + InternalMap(Resources res) { + super(res.getString(R.string.cache_menu_map), null); + } + + @Override + public boolean invoke(cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + cgSettings settings = getSettings(activity); + Intent mapIntent = new Intent(activity, settings.getMapFactory().getMapClass()); + if (cache != null) { + mapIntent.putExtra("detail", false); + mapIntent.putExtra("geocode", cache.geocode); + } + if (searchId != null) { + mapIntent.putExtra("detail", true); + mapIntent.putExtra("searchid", searchId.toString()); + } + if (waypoint != null) { + mapIntent.putExtra("latitude", waypoint.coords.getLatitude()); + mapIntent.putExtra("longitude", waypoint.coords.getLongitude()); + mapIntent.putExtra("wpttype", waypoint.type); + } + + activity.startActivity(mapIntent); + return true; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/LocusApp.java b/src/cgeo/geocaching/apps/cache/navi/LocusApp.java index 557c298..80ffdf6 100644 --- a/src/cgeo/geocaching/apps/cache/navi/LocusApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/LocusApp.java @@ -1,58 +1,63 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.ArrayList; -import java.util.UUID; - -import android.app.Activity; -import android.content.res.Resources; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.apps.AbstractLocusApp; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.res.Resources; + +import java.util.ArrayList; +import java.util.UUID; + class LocusApp extends AbstractLocusApp implements NavigationApp { - LocusApp(Resources res) { - super(res); - } - - /** - * Show a single cache with waypoints or a single waypoint in Locus. - * This method constructs a list of cache and waypoints only. - * - * @see AbstractLocusApp#showInLocus - * @author koem - */ - @Override - public boolean invoke(cgGeo geo, Activity activity, Resources res, cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - - if (cache == null && waypoint == null && coords == null) { - return false; - } - - if (isInstalled(activity)) { // TODO: is this if-statement really necessary? - final ArrayList<Object> points = new ArrayList<Object>(); - - // add cache if present - if (cache != null) { - if (cache.coords == null) cache.coords = coords; - if (cache.coords != null) points.add(cache); - } - - // add waypoint if present - if (waypoint != null) { - if (waypoint.coords == null) waypoint.coords = coords; - if (waypoint.coords != null) points.add(waypoint); - } - - this.showInLocus(points, true, activity); - - return true; - } - - return false; - } + LocusApp(Resources res) { + super(res); + } + + /** + * Show a single cache with waypoints or a single waypoint in Locus. + * This method constructs a list of cache and waypoints only. + * + * @see AbstractLocusApp#showInLocus + * @author koem + */ + @Override + public boolean invoke(cgGeo geo, Activity activity, Resources res, cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + + if (cache == null && waypoint == null && coords == null) { + return false; + } + + if (isInstalled(activity)) { // TODO: is this if-statement really necessary? + final ArrayList<Object> points = new ArrayList<Object>(); + + // add cache if present + if (cache != null) { + if (cache.coords == null) + cache.coords = coords; + if (cache.coords != null) + points.add(cache); + } + + // add waypoint if present + if (waypoint != null) { + if (waypoint.coords == null) + waypoint.coords = coords; + if (waypoint.coords != null) + points.add(waypoint); + } + + this.showInLocus(points, true, activity); + + return true; + } + + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java b/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java index 8a5bd13..ef0a578 100644 --- a/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java @@ -1,19 +1,20 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.res.Resources; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.apps.App; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.res.Resources; + +import java.util.UUID; + interface NavigationApp extends App { - public boolean invoke(final cgGeo geo, final Activity activity, - final Resources res, - final cgCache cache, - final UUID searchId, final cgWaypoint waypoint, - final Geopoint coords); + public boolean invoke(final cgGeo geo, final Activity activity, + final Resources res, + final cgCache cache, + final UUID searchId, final cgWaypoint waypoint, + final Geopoint coords); } diff --git a/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java index 70609de..63d4b2f 100644 --- a/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java +++ b/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java @@ -1,6 +1,11 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgGeo; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.apps.AbstractAppFactory; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.ArrayUtils; @@ -9,55 +14,51 @@ import android.content.res.Resources; import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgGeo; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgWaypoint; -import cgeo.geocaching.apps.AbstractAppFactory; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.UUID; public final class NavigationAppFactory extends AbstractAppFactory { - private static NavigationApp[] apps = new NavigationApp[] {}; - - private static NavigationApp[] getNavigationApps(Resources res) { - if (ArrayUtils.isEmpty(apps)) { - apps = new NavigationApp[] { - // compass - new RadarApp(res), - new InternalMap(res), - new StaticMapApp(res), - new LocusApp(res), - new RMapsApp(res), - new GoogleMapsApp(res), - new GoogleNavigationApp(res), - new StreetviewApp(res)}; - } - return apps; - } - - public static void addMenuItems(Menu menu, Activity activity, - Resources res) { - for (NavigationApp app : getNavigationApps(res)) { - if (app.isInstalled(activity)) { - menu.add(0, app.getId(), 0, app.getName()); - } - } - } - - public static boolean onMenuItemSelected(final MenuItem item, - final cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint destination) { - NavigationApp app = (NavigationApp) getAppFromMenuItem(item, apps); - if (app != null) { - try { - return app.invoke(geo, activity, res, cache, - searchId, waypoint, destination); - } catch (Exception e) { - Log.e(cgSettings.tag, "NavigationAppFactory.onMenuItemSelected: " + e.toString()); - } - } - return false; - } + private static NavigationApp[] apps = new NavigationApp[] {}; + + private static NavigationApp[] getNavigationApps(Resources res) { + if (ArrayUtils.isEmpty(apps)) { + apps = new NavigationApp[] { + // compass + new RadarApp(res), + new InternalMap(res), + new StaticMapApp(res), + new LocusApp(res), + new RMapsApp(res), + new GoogleMapsApp(res), + new GoogleNavigationApp(res), + new StreetviewApp(res) }; + } + return apps; + } + + public static void addMenuItems(Menu menu, Activity activity, + Resources res) { + for (NavigationApp app : getNavigationApps(res)) { + if (app.isInstalled(activity)) { + menu.add(0, app.getId(), 0, app.getName()); + } + } + } + + public static boolean onMenuItemSelected(final MenuItem item, + final cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint destination) { + NavigationApp app = (NavigationApp) getAppFromMenuItem(item, apps); + if (app != null) { + try { + return app.invoke(geo, activity, res, cache, + searchId, waypoint, destination); + } catch (Exception e) { + Log.e(cgSettings.tag, "NavigationAppFactory.onMenuItemSelected: " + e.toString()); + } + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java b/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java index 37c727d..24263e2 100644 --- a/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java @@ -1,70 +1,71 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.ArrayList; -import java.util.Locale; -import java.util.UUID; - -import android.app.Activity; -import android.content.Intent; -import android.content.res.Resources; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Intent; +import android.content.res.Resources; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.UUID; + class RMapsApp extends AbstractNavigationApp implements NavigationApp { - private static final String INTENT = "com.robert.maps.action.SHOW_POINTS"; + private static final String INTENT = "com.robert.maps.action.SHOW_POINTS"; - RMapsApp(final Resources res) { - super(res.getString(R.string.cache_menu_rmaps), INTENT); - } + RMapsApp(final Resources res) { + super(res.getString(R.string.cache_menu_rmaps), INTENT); + } - @Override - public boolean invoke(cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - if (cache == null && waypoint == null && coords == null) { - return false; - } + @Override + public boolean invoke(cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + if (cache == null && waypoint == null && coords == null) { + return false; + } - try { - if (isInstalled(activity)) { - final ArrayList<String> locations = new ArrayList<String>(); - if (cache != null && cache.coords != null) { - locations.add(String.format((Locale) null, "%.6f", - cache.coords.getLatitude()) - + "," - + String.format((Locale) null, "%.6f", - cache.coords.getLongitude()) - + ";" - + cache.geocode - + ";" + cache.name); - } else if (waypoint != null && waypoint.coords != null) { - locations.add(String.format((Locale) null, "%.6f", - waypoint.coords.getLatitude()) - + "," - + String.format((Locale) null, "%.6f", - waypoint.coords.getLongitude()) - + ";" - + waypoint.lookup - + ";" + waypoint.name); - } + try { + if (isInstalled(activity)) { + final ArrayList<String> locations = new ArrayList<String>(); + if (cache != null && cache.coords != null) { + locations.add(String.format((Locale) null, "%.6f", + cache.coords.getLatitude()) + + "," + + String.format((Locale) null, "%.6f", + cache.coords.getLongitude()) + + ";" + + cache.geocode + + ";" + cache.name); + } else if (waypoint != null && waypoint.coords != null) { + locations.add(String.format((Locale) null, "%.6f", + waypoint.coords.getLatitude()) + + "," + + String.format((Locale) null, "%.6f", + waypoint.coords.getLongitude()) + + ";" + + waypoint.lookup + + ";" + waypoint.name); + } - final Intent intent = new Intent( - "com.robert.maps.action.SHOW_POINTS"); + final Intent intent = new Intent( + "com.robert.maps.action.SHOW_POINTS"); - intent.putStringArrayListExtra("locations", locations); + intent.putStringArrayListExtra("locations", locations); - activity.startActivity(intent); + activity.startActivity(intent); - return true; - } - } catch (Exception e) { - // nothing - } + return true; + } + } catch (Exception e) { + // nothing + } - return false; - } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/RadarApp.java b/src/cgeo/geocaching/apps/cache/navi/RadarApp.java index 1e5278f..c106446 100644 --- a/src/cgeo/geocaching/apps/cache/navi/RadarApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/RadarApp.java @@ -1,52 +1,53 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.Intent; -import android.content.res.Resources; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Intent; +import android.content.res.Resources; + +import java.util.UUID; + class RadarApp extends AbstractNavigationApp implements NavigationApp { - private static final String INTENT = "com.google.android.radar.SHOW_RADAR"; - private static final String PACKAGE_NAME = "com.eclipsim.gpsstatus2"; - - RadarApp(final Resources res) { - super(res.getString(R.string.cache_menu_radar), INTENT, PACKAGE_NAME); - } - - private static void navigateTo(Activity activity, final Geopoint coords) { - Intent radarIntent = new Intent(INTENT); - radarIntent.putExtra("latitude", (float) coords.getLatitude()); - radarIntent.putExtra("longitude", (float) coords.getLongitude()); - activity.startActivity(radarIntent); - } - - @Override - public boolean invoke(cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - if (cache != null) { - if (cache.coords != null) { - navigateTo(activity, cache.coords); - return true; - } - } - if (waypoint != null) { - if (waypoint.coords != null) { - navigateTo(activity, waypoint.coords); - return true; - } - } - if (coords != null) { - navigateTo(activity, coords); - return true; - } - return false; - } + private static final String INTENT = "com.google.android.radar.SHOW_RADAR"; + private static final String PACKAGE_NAME = "com.eclipsim.gpsstatus2"; + + RadarApp(final Resources res) { + super(res.getString(R.string.cache_menu_radar), INTENT, PACKAGE_NAME); + } + + private static void navigateTo(Activity activity, final Geopoint coords) { + Intent radarIntent = new Intent(INTENT); + radarIntent.putExtra("latitude", (float) coords.getLatitude()); + radarIntent.putExtra("longitude", (float) coords.getLongitude()); + activity.startActivity(radarIntent); + } + + @Override + public boolean invoke(cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + if (cache != null) { + if (cache.coords != null) { + navigateTo(activity, cache.coords); + return true; + } + } + if (waypoint != null) { + if (waypoint.coords != null) { + navigateTo(activity, waypoint.coords); + return true; + } + } + if (coords != null) { + navigateTo(activity, coords); + return true; + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java b/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java index e989981..0967925 100644 --- a/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java @@ -1,11 +1,5 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; @@ -14,35 +8,42 @@ import cgeo.geocaching.cgeosmaps; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; + +import java.util.UUID; + class StaticMapApp extends AbstractNavigationApp implements - NavigationApp { - - StaticMapApp(final Resources res) { - super(res.getString(R.string.cache_menu_map_static), null); - } - - @Override - public boolean isInstalled(Context context) { - return true; - } - - @Override - public boolean invoke(cgGeo geo, Activity activity, Resources res, - cgCache cache, - final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { - - if (cache == null || cache.reason == 0) { - ActivityMixin.showToast(activity, res.getString(R.string.err_detail_no_map_static)); - return true; - } - - if (cache.geocode != null) { - Intent smapsIntent = new Intent(activity, cgeosmaps.class); - smapsIntent.putExtra("geocode", cache.geocode.toUpperCase()); - activity.startActivity(smapsIntent); - return true; - } - return false; - } + NavigationApp { + + StaticMapApp(final Resources res) { + super(res.getString(R.string.cache_menu_map_static), null); + } + + @Override + public boolean isInstalled(Context context) { + return true; + } + + @Override + public boolean invoke(cgGeo geo, Activity activity, Resources res, + cgCache cache, + final UUID searchId, cgWaypoint waypoint, final Geopoint coords) { + + if (cache == null || cache.reason == 0) { + ActivityMixin.showToast(activity, res.getString(R.string.err_detail_no_map_static)); + return true; + } + + if (cache.geocode != null) { + Intent smapsIntent = new Intent(activity, cgeosmaps.class); + smapsIntent.putExtra("geocode", cache.geocode.toUpperCase()); + activity.startActivity(smapsIntent); + return true; + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cache/navi/StreetviewApp.java b/src/cgeo/geocaching/apps/cache/navi/StreetviewApp.java index 1b8a101..f699987 100644 --- a/src/cgeo/geocaching/apps/cache/navi/StreetviewApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/StreetviewApp.java @@ -1,6 +1,11 @@ package cgeo.geocaching.apps.cache.navi; -import java.util.UUID; +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgGeo; +import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.geopoint.Geopoint; import android.app.Activity; import android.content.ActivityNotFoundException; @@ -8,12 +13,8 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; -import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgGeo; -import cgeo.geocaching.cgWaypoint; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.UUID; class StreetviewApp extends AbstractNavigationApp implements NavigationApp { @@ -46,12 +47,12 @@ class StreetviewApp extends AbstractNavigationApp implements NavigationApp { ActivityMixin.showToast(activity, res.getString(R.string.err_application_no)); } } - + return false; } - private void startActivity(Activity activity, final Geopoint coords) { - activity.startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("google.streetview:cbll=" + coords.getLatitude() + "," + coords.getLongitude()))); - } + private void startActivity(Activity activity, final Geopoint coords) { + activity.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("google.streetview:cbll=" + coords.getLatitude() + "," + coords.getLongitude()))); + } } diff --git a/src/cgeo/geocaching/apps/cachelist/CacheListApp.java b/src/cgeo/geocaching/apps/cachelist/CacheListApp.java index 74fba64..c4d51d2 100644 --- a/src/cgeo/geocaching/apps/cachelist/CacheListApp.java +++ b/src/cgeo/geocaching/apps/cachelist/CacheListApp.java @@ -1,18 +1,19 @@ package cgeo.geocaching.apps.cachelist; -import java.util.List; -import java.util.UUID; - -import android.app.Activity; -import android.content.res.Resources; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.apps.App; +import android.app.Activity; +import android.content.res.Resources; + +import java.util.List; +import java.util.UUID; + interface CacheListApp extends App { - boolean invoke(final cgGeo geo, final List<cgCache> caches, - final Activity activity, final Resources res, - final UUID searchId); + boolean invoke(final cgGeo geo, final List<cgCache> caches, + final Activity activity, final Resources res, + final UUID searchId); } diff --git a/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java b/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java index 91e547a..5359719 100644 --- a/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java +++ b/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java @@ -1,8 +1,10 @@ package cgeo.geocaching.apps.cachelist; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgGeo; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.apps.AbstractAppFactory; import org.apache.commons.lang3.ArrayUtils; @@ -12,67 +14,66 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; -import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgGeo; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.apps.AbstractAppFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; public final class CacheListAppFactory extends AbstractAppFactory { - private static CacheListApp[] apps = new CacheListApp[] {}; + private static CacheListApp[] apps = new CacheListApp[] {}; - private static CacheListApp[] getMultiPointNavigationApps( - Resources res) { - if (ArrayUtils.isEmpty(apps)) { - apps = new CacheListApp[] { - new InternalCacheListMap(res), - new LocusCacheListApp(res) }; - } - return apps; - } + private static CacheListApp[] getMultiPointNavigationApps( + Resources res) { + if (ArrayUtils.isEmpty(apps)) { + apps = new CacheListApp[] { + new InternalCacheListMap(res), + new LocusCacheListApp(res) }; + } + return apps; + } - /** - * @param menu - * @param activity - * @param res - * @return the added menu item (also for a sub menu, then the menu item in the parent menu is returned) - */ - public static MenuItem addMenuItems(Menu menu, - Activity activity, Resources res) { - List<CacheListApp> activeApps = new ArrayList<CacheListApp>(); - for (CacheListApp app : getMultiPointNavigationApps(res)) { - if (app.isInstalled(activity)) { - activeApps.add(app); - } - } - // use a new sub menu, if more than one app is available - if (activeApps.size() > 1) { - SubMenu subMenu = menu.addSubMenu(0, 101, 0, - res.getString(R.string.caches_on_map)).setIcon( - android.R.drawable.ic_menu_mapmode); - for (CacheListApp app : activeApps) { - subMenu.add(0, app.getId(), 0, app.getName()); - } - return subMenu.getItem(); - } else if (activeApps.size() == 1) { - return menu.add(0, activeApps.get(0).getId(), 0, - activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode); - } - return null; - } + /** + * @param menu + * @param activity + * @param res + * @return the added menu item (also for a sub menu, then the menu item in the parent menu is returned) + */ + public static MenuItem addMenuItems(Menu menu, + Activity activity, Resources res) { + List<CacheListApp> activeApps = new ArrayList<CacheListApp>(); + for (CacheListApp app : getMultiPointNavigationApps(res)) { + if (app.isInstalled(activity)) { + activeApps.add(app); + } + } + // use a new sub menu, if more than one app is available + if (activeApps.size() > 1) { + SubMenu subMenu = menu.addSubMenu(0, 101, 0, + res.getString(R.string.caches_on_map)).setIcon( + android.R.drawable.ic_menu_mapmode); + for (CacheListApp app : activeApps) { + subMenu.add(0, app.getId(), 0, app.getName()); + } + return subMenu.getItem(); + } else if (activeApps.size() == 1) { + return menu.add(0, activeApps.get(0).getId(), 0, + activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode); + } + return null; + } - public static boolean onMenuItemSelected(final MenuItem item, - final cgGeo geo, final List<cgCache> caches, final Activity activity, final Resources res, - final UUID searchId) { - CacheListApp app = (CacheListApp) getAppFromMenuItem(item, apps); - if (app != null) { - try { - return app.invoke(geo, caches, activity, res, searchId); - } catch (Exception e) { - Log.e(cgSettings.tag, "CacheListAppFactory.onMenuItemSelected: " + e.toString()); - } - } - return false; - } + public static boolean onMenuItemSelected(final MenuItem item, + final cgGeo geo, final List<cgCache> caches, final Activity activity, final Resources res, + final UUID searchId) { + CacheListApp app = (CacheListApp) getAppFromMenuItem(item, apps); + if (app != null) { + try { + return app.invoke(geo, caches, activity, res, searchId); + } catch (Exception e) { + Log.e(cgSettings.tag, "CacheListAppFactory.onMenuItemSelected: " + e.toString()); + } + } + return false; + } } diff --git a/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java b/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java index 2fd418e..7eec0f8 100644 --- a/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java +++ b/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java @@ -1,36 +1,37 @@ package cgeo.geocaching.apps.cachelist; -import java.util.List; -import java.util.UUID; +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgGeo; +import cgeo.geocaching.apps.AbstractApp; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Resources; -import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgGeo; -import cgeo.geocaching.apps.AbstractApp; + +import java.util.List; +import java.util.UUID; class InternalCacheListMap extends AbstractApp implements CacheListApp { - InternalCacheListMap(Resources res) { - super(res.getString(R.string.cache_menu_map), null); - } - - @Override - public boolean isInstalled(Context context) { - return true; - } - - @Override - public boolean invoke(cgGeo geo, List<cgCache> caches, Activity activity, Resources res, final UUID searchId) { - Intent mapIntent = new Intent(activity, getSettings(activity).getMapFactory() - .getMapClass()); - mapIntent.putExtra("detail", false); // this is the main difference to the activity for a single point - mapIntent.putExtra("searchid", searchId.toString()); - - activity.startActivity(mapIntent); - return true; - } + InternalCacheListMap(Resources res) { + super(res.getString(R.string.cache_menu_map), null); + } + + @Override + public boolean isInstalled(Context context) { + return true; + } + + @Override + public boolean invoke(cgGeo geo, List<cgCache> caches, Activity activity, Resources res, final UUID searchId) { + Intent mapIntent = new Intent(activity, getSettings(activity).getMapFactory() + .getMapClass()); + mapIntent.putExtra("detail", false); // this is the main difference to the activity for a single point + mapIntent.putExtra("searchid", searchId.toString()); + + activity.startActivity(mapIntent); + return true; + } } diff --git a/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java b/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java index a18010a..ec69180 100644 --- a/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java +++ b/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java @@ -1,34 +1,36 @@ package cgeo.geocaching.apps.cachelist; -import java.util.List; -import java.util.UUID; - -import android.app.Activity; -import android.content.res.Resources; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.apps.AbstractLocusApp; +import android.app.Activity; +import android.content.res.Resources; + +import java.util.List; +import java.util.UUID; + class LocusCacheListApp extends AbstractLocusApp implements CacheListApp { - LocusCacheListApp(Resources res) { - super(res); - } + LocusCacheListApp(Resources res) { + super(res); + } - /** - * show caches in Locus - * + /** + * show caches in Locus + * * @see AbstractLocusApp#showInLocus * @author koem - */ - @Override - public boolean invoke(cgGeo geo, List<cgCache> cacheList, Activity activity, Resources res, - final UUID searchId) { - if (cacheList == null || cacheList.isEmpty()) return false; - - this.showInLocus((List<? extends Object>) cacheList, false, activity); - - return true; - } + */ + @Override + public boolean invoke(cgGeo geo, List<cgCache> cacheList, Activity activity, Resources res, + final UUID searchId) { + if (cacheList == null || cacheList.isEmpty()) + return false; + + this.showInLocus((List<? extends Object>) cacheList, false, activity); + + return true; + } } diff --git a/src/cgeo/geocaching/cgBase.java b/src/cgeo/geocaching/cgBase.java index 4ddae1b..6312acf 100644 --- a/src/cgeo/geocaching/cgBase.java +++ b/src/cgeo/geocaching/cgBase.java @@ -1,5 +1,34 @@ package cgeo.geocaching; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.files.LocParser; +import cgeo.geocaching.geopoint.DistanceParser; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.utils.CollectionUtils; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.json.JSONArray; +import org.json.JSONObject; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Handler; +import android.os.Message; +import android.text.Html; +import android.text.Spannable; +import android.text.format.DateUtils; +import android.text.style.StrikethroughSpan; +import android.util.Log; +import android.widget.EditText; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -48,176 +77,148 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.json.JSONArray; -import org.json.JSONObject; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Handler; -import android.os.Message; -import android.text.Html; -import android.text.Spannable; -import android.text.format.DateUtils; -import android.text.style.StrikethroughSpan; -import android.util.Log; -import android.widget.EditText; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.enumerations.CacheType; -import cgeo.geocaching.files.LocParser; -import cgeo.geocaching.geopoint.DistanceParser; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.utils.CollectionUtils; - public class cgBase { - private final static Pattern patternGeocode = Pattern.compile("<meta name=\"og:url\" content=\"[^\"]+/(GC[0-9A-Z]+)\"[^>]*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternCacheId = Pattern.compile("/seek/log\\.aspx\\?ID=(\\d+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternCacheGuid = Pattern.compile(Pattern.quote("&wid=") + "([0-9a-z\\-]+)" + Pattern.quote("&"), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternType = Pattern.compile("<img src=\"[^\"]*/WptTypes/\\d+\\.gif\" alt=\"([^\"]+)\" (title=\"[^\"]*\" )?width=\"32\" height=\"32\"[^>]*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - - private final static Pattern patternName = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_CacheName\">([^<]+)<\\/span>[^<]*<\\/h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternSize = Pattern.compile("<div class=\"CacheSize[^\"]*\">[^<]*<p[^>]*>[^S]*Size[^:]*:[^<]*<span[^>]*>[^<]*<img src=\"[^\"]*/icons/container/[a-z_]+\\.gif\" alt=\"Size: ([^\"]+)\"[^>]*>[^<]*<small>[^<]*</small>[^<]*</span>[^<]*</p>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternDifficulty = Pattern.compile("<span id=\"ctl00_ContentBody_uxLegendScale\"[^>]*>[^<]*<img src=\"[^\"]*/images/stars/stars([0-9_]+)\\.gif\" alt=\"[^\"]+\"[^>]*>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternTerrain = Pattern.compile("<span id=\"ctl00_ContentBody_Localize6\"[^>]*>[^<]*<img src=\"[^\"]*/images/stars/stars([0-9_]+)\\.gif\" alt=\"[^\"]+\"[^>]*>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternOwner = Pattern.compile("<span class=\"minorCacheDetails\">\\W*An?(\\W*Event)?\\W*cache\\W*by[^<]*<a href=\"[^\"]+\">([^<]+)</a>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternOwnerReal = Pattern.compile("<a id=\"ctl00_ContentBody_uxFindLinksHiddenByThisUser\" href=\"[^\"]*/seek/nearest\\.aspx\\?u=*([^\"]+)\">[^<]+</a>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternHidden = Pattern.compile("<span[^>]*>\\W*Hidden[\\s:]*([^<]+)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternHiddenEvent = Pattern.compile("<span[^>]*>\\W*Event\\W*Date[^:]*:([^<]*)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternFavourite = Pattern.compile("<a id=\"uxFavContainerLink\"[^>]*>[^<]*<div[^<]*<span class=\"favorite-value\">[^\\d]*([0-9]+)[^\\d^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - - private final static Pattern patternFound = Pattern.compile("<p>[^<]*<a id=\"ctl00_ContentBody_hlFoundItLog\"[^<]*<img src=\".*/images/stockholm/16x16/check\\.gif\"[^>]*>[^<]*</a>[^<]*</p>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternFoundAlternative = Pattern.compile("<div class=\"StatusInformationWidget FavoriteWidget\"", Pattern.CASE_INSENSITIVE); - private final static Pattern patternLatLon = Pattern.compile("<span id=\"ctl00_ContentBody_LatLon\"[^>]*>(<b>)?([^<]*)(<\\/b>)?<\\/span>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternLocation = Pattern.compile("<span id=\"ctl00_ContentBody_Location\"[^>]*>In ([^<]*)", Pattern.CASE_INSENSITIVE); - private final static Pattern patternHint = Pattern.compile("<p>([^<]*<strong>)?\\W*Additional Hints([^<]*<\\/strong>)?[^\\(]*\\(<a[^>]+>Encrypt</a>\\)[^<]*<\\/p>[^<]*<div id=\"div_hint\"[^>]*>(.*)</div>[^<]*<div id=[\\'|\"]dk[\\'|\"]", Pattern.CASE_INSENSITIVE); - private final static Pattern patternPersonalNote = Pattern.compile("<p id=\"cache_note\"[^>]*>([^<]*)</p>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternDescShort = Pattern.compile("<div class=\"UserSuppliedContent\">[^<]*<span id=\"ctl00_ContentBody_ShortDescription\"[^>]*>((?:(?!</span>[^\\w^<]*</div>).)*)</span>[^\\w^<]*</div>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternDesc = Pattern.compile("<span id=\"ctl00_ContentBody_LongDescription\"[^>]*>" + "(.*)</span>[^<]*</div>[^<]*<p>[^<]*</p>[^<]*<p>[^<]*<strong>\\W*Additional Hints</strong>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternCountLogs = Pattern.compile("<span id=\"ctl00_ContentBody_lblFindCounts\"><p(.+?)<\\/p><\\/span>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternCountLog = Pattern.compile("src=\"\\/images\\/icons\\/(.+?).gif\"[^>]+> (\\d+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternLog = Pattern.compile("<tr><td class.+?<a href=\"/profile/\\?guid=.+?>(.+?)</a>.+?(?:logOwnerStats[^>]+><img[^>]+icon_smile.+?> ([,\\d]+).+?)?LogType.+?<img.+?/images/icons/([^\\.]+)\\..+?title=\"(.+?)\".+?LogDate.+?>(.+?)<.+?LogText.+?>(.*?)</p>(.*?)</div></div></div></td></tr>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private final static Pattern patternLogImgs = Pattern.compile("href=\"(http://img.geocaching.com/cache/log/.+?)\".+?<span>([^<]*)", Pattern.CASE_INSENSITIVE); - private final static Pattern patternAttributes = Pattern.compile("<h3 class=\"WidgetHeader\">[^<]*<img[^>]+>\\W*Attributes[^<]*</h3>[^<]*<div class=\"WidgetBody\">(([^<]*<img src=\"[^\"]+\" alt=\"[^\"]+\"[^>]*>)+)[^<]*<p", Pattern.CASE_INSENSITIVE); - private final static Pattern patternAttributesInside = Pattern.compile("[^<]*<img src=\"([^\"]+)\" alt=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternSpoilers = Pattern.compile("<span id=\"ctl00_ContentBody_Images\">((<a href=\"[^\"]+\"[^>]*>[^<]*<img[^>]+>[^<]*<span>[^>]+</span>[^<]*</a>[^<]*<br[^>]*>([^<]*(<br[^>]*>)+)?)+)[^<]*</span>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternSpoilersInside = Pattern.compile("[^<]*<a href=\"([^\"]+)\"[^>]*>[^<]*<img[^>]+>[^<]*<span>([^>]+)</span>[^<]*</a>[^<]*<br[^>]*>(([^<]*)(<br[^<]*>)+)?", Pattern.CASE_INSENSITIVE); - private final static Pattern patternInventory = Pattern.compile("<span id=\"ctl00_ContentBody_uxTravelBugList_uxInventoryLabel\">\\W*Inventory[^<]*</span>[^<]*</h3>[^<]*<div class=\"WidgetBody\">([^<]*<ul>(([^<]*<li>[^<]*<a href=\"[^\"]+\"[^>]*>[^<]*<img src=\"[^\"]+\"[^>]*>[^<]*<span>[^<]+<\\/span>[^<]*<\\/a>[^<]*<\\/li>)+)[^<]*<\\/ul>)?", Pattern.CASE_INSENSITIVE); - private final static Pattern patternInventoryInside = Pattern.compile("[^<]*<li>[^<]*<a href=\"[a-z0-9\\-\\_\\.\\?\\/\\:\\@]*\\/track\\/details\\.aspx\\?guid=([0-9a-z\\-]+)[^\"]*\"[^>]*>[^<]*<img src=\"[^\"]+\"[^>]*>[^<]*<span>([^<]+)<\\/span>[^<]*<\\/a>[^<]*<\\/li>", Pattern.CASE_INSENSITIVE); - private final static Pattern patternOnWatchlist = Pattern.compile("<img\\s*src=\"\\/images\\/stockholm\\/16x16\\/icon_stop_watchlist.gif\"", Pattern.CASE_INSENSITIVE); - - private final static Pattern PATTERN_TRACKABLE_TrackableId = Pattern.compile("<a id=\"ctl00_ContentBody_LogLink\" title=\"[^\"]*\" href=\".*log\\.aspx\\?wid=([a-z0-9\\-]+)\"[^>]*>[^<]*</a>", Pattern.CASE_INSENSITIVE); - private 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>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Name = Pattern.compile("<h2>([^<]*<img[^>]*>)?[^<]*<span id=\"ctl00_ContentBody_lbHeading\">([^<]+)</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Owner = Pattern.compile("<dt>\\W*Owner:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugOwner\" title=\"[^\"]*\" href=\"[^\"]*/profile/\\?guid=([a-z0-9\\-]+)\">([^<]+)<\\/a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Released = Pattern.compile("<dt>\\W*Released:[^<]*</dt>[^<]*<dd>[^<]*<span id=\"ctl00_ContentBody_BugDetails_BugReleaseDate\">([^<]+)<\\/span>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Origin = Pattern.compile("<dt>\\W*Origin:[^<]*</dt>[^<]*<dd>[^<]*<span id=\"ctl00_ContentBody_BugDetails_BugOrigin\">([^<]+)<\\/span>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_SpottedCache = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\" title=\"[^\"]*\" href=\"[^\"]*/seek/cache_details.aspx\\?guid=([a-z0-9\\-]+)\">In ([^<]+)</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_SpottedUser = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\" href=\"[^\"]*/profile/\\?guid=([a-z0-9\\-]+)\">In the hands of ([^<]+).</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_SpottedUnknown = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\">Unknown Location[^<]*</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_SpottedOwner = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\">In the hands of the owner[^<]*</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Goal = Pattern.compile("<h3>\\W*Current GOAL[^<]*</h3>[^<]*<p[^>]*>(.*)</p>[^<]*<h3>\\W*About This Item[^<]*</h3>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_DetailsImage = Pattern.compile("<h3>\\W*About This Item[^<]*</h3>([^<]*<p>([^<]*<img id=\"ctl00_ContentBody_BugDetails_BugImage\" class=\"[^\"]+\" src=\"([^\"]+)\"[^>]*>)?[^<]*</p>)?[^<]*<p[^>]*>(.*)</p>[^<]*<div id=\"ctl00_ContentBody_BugDetails_uxAbuseReport\">", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Icon = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Type = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"[^\"]+\" alt=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Distance = Pattern.compile("<h4[^>]*\\W*Tracking History \\(([0-9\\.,]+(km|mi))[^\\)]*\\)", Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_TRACKABLE_Log = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^\\.]+)\\.gif[^>]+> ([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?(?:guid=([^\"]+)\">([^<]+)</a>.+?)?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE); - - public final static Map<String, String> cacheTypes = new HashMap<String, String>(); - public final static Map<String, String> cacheTypesInv = new HashMap<String, String>(); - public final static Map<String, String> cacheIDs = new HashMap<String, String>(); - public final static Map<String, String> cacheIDsChoices = new HashMap<String, String>(); - public final static Map<String, String> waypointTypes = new HashMap<String, String>(); - public final static Map<String, Integer> logTypes = new HashMap<String, Integer>(); - public final static Map<String, Integer> logTypes0 = new HashMap<String, Integer>(); - public final static Map<Integer, String> logTypes1 = new HashMap<Integer, String>(); - public final static Map<Integer, String> logTypes2 = new HashMap<Integer, String>(); - public final static Map<Integer, String> logTypesTrackable = new HashMap<Integer, String>(); - public final static Map<Integer, String> logTypesTrackableAction = new HashMap<Integer, String>(); - public final static Map<Integer, String> errorRetrieve = new HashMap<Integer, String>(); - public final static Map<String, SimpleDateFormat> gcCustomDateFormats; - static { - final String[] formats = new String[] { - "MM/dd/yyyy", - "yyyy-MM-dd", - "yyyy/MM/dd", - "dd/MMM/yyyy", + private final static Pattern patternGeocode = Pattern.compile("<meta name=\"og:url\" content=\"[^\"]+/(GC[0-9A-Z]+)\"[^>]*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternCacheId = Pattern.compile("/seek/log\\.aspx\\?ID=(\\d+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternCacheGuid = Pattern.compile(Pattern.quote("&wid=") + "([0-9a-z\\-]+)" + Pattern.quote("&"), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternType = Pattern.compile("<img src=\"[^\"]*/WptTypes/\\d+\\.gif\" alt=\"([^\"]+)\" (title=\"[^\"]*\" )?width=\"32\" height=\"32\"[^>]*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + + private final static Pattern patternName = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_CacheName\">([^<]+)<\\/span>[^<]*<\\/h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternSize = Pattern.compile("<div class=\"CacheSize[^\"]*\">[^<]*<p[^>]*>[^S]*Size[^:]*:[^<]*<span[^>]*>[^<]*<img src=\"[^\"]*/icons/container/[a-z_]+\\.gif\" alt=\"Size: ([^\"]+)\"[^>]*>[^<]*<small>[^<]*</small>[^<]*</span>[^<]*</p>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternDifficulty = Pattern.compile("<span id=\"ctl00_ContentBody_uxLegendScale\"[^>]*>[^<]*<img src=\"[^\"]*/images/stars/stars([0-9_]+)\\.gif\" alt=\"[^\"]+\"[^>]*>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternTerrain = Pattern.compile("<span id=\"ctl00_ContentBody_Localize6\"[^>]*>[^<]*<img src=\"[^\"]*/images/stars/stars([0-9_]+)\\.gif\" alt=\"[^\"]+\"[^>]*>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternOwner = Pattern.compile("<span class=\"minorCacheDetails\">\\W*An?(\\W*Event)?\\W*cache\\W*by[^<]*<a href=\"[^\"]+\">([^<]+)</a>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternOwnerReal = Pattern.compile("<a id=\"ctl00_ContentBody_uxFindLinksHiddenByThisUser\" href=\"[^\"]*/seek/nearest\\.aspx\\?u=*([^\"]+)\">[^<]+</a>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternHidden = Pattern.compile("<span[^>]*>\\W*Hidden[\\s:]*([^<]+)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternHiddenEvent = Pattern.compile("<span[^>]*>\\W*Event\\W*Date[^:]*:([^<]*)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternFavourite = Pattern.compile("<a id=\"uxFavContainerLink\"[^>]*>[^<]*<div[^<]*<span class=\"favorite-value\">[^\\d]*([0-9]+)[^\\d^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + + private final static Pattern patternFound = Pattern.compile("<p>[^<]*<a id=\"ctl00_ContentBody_hlFoundItLog\"[^<]*<img src=\".*/images/stockholm/16x16/check\\.gif\"[^>]*>[^<]*</a>[^<]*</p>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternFoundAlternative = Pattern.compile("<div class=\"StatusInformationWidget FavoriteWidget\"", Pattern.CASE_INSENSITIVE); + private final static Pattern patternLatLon = Pattern.compile("<span id=\"ctl00_ContentBody_LatLon\"[^>]*>(<b>)?([^<]*)(<\\/b>)?<\\/span>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternLocation = Pattern.compile("<span id=\"ctl00_ContentBody_Location\"[^>]*>In ([^<]*)", Pattern.CASE_INSENSITIVE); + private final static Pattern patternHint = Pattern.compile("<p>([^<]*<strong>)?\\W*Additional Hints([^<]*<\\/strong>)?[^\\(]*\\(<a[^>]+>Encrypt</a>\\)[^<]*<\\/p>[^<]*<div id=\"div_hint\"[^>]*>(.*)</div>[^<]*<div id=[\\'|\"]dk[\\'|\"]", Pattern.CASE_INSENSITIVE); + private final static Pattern patternPersonalNote = Pattern.compile("<p id=\"cache_note\"[^>]*>([^<]*)</p>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternDescShort = Pattern.compile("<div class=\"UserSuppliedContent\">[^<]*<span id=\"ctl00_ContentBody_ShortDescription\"[^>]*>((?:(?!</span>[^\\w^<]*</div>).)*)</span>[^\\w^<]*</div>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternDesc = Pattern.compile("<span id=\"ctl00_ContentBody_LongDescription\"[^>]*>" + "(.*)</span>[^<]*</div>[^<]*<p>[^<]*</p>[^<]*<p>[^<]*<strong>\\W*Additional Hints</strong>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternCountLogs = Pattern.compile("<span id=\"ctl00_ContentBody_lblFindCounts\"><p(.+?)<\\/p><\\/span>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternCountLog = Pattern.compile("src=\"\\/images\\/icons\\/(.+?).gif\"[^>]+> (\\d+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternLog = Pattern.compile("<tr><td class.+?<a href=\"/profile/\\?guid=.+?>(.+?)</a>.+?(?:logOwnerStats[^>]+><img[^>]+icon_smile.+?> ([,\\d]+).+?)?LogType.+?<img.+?/images/icons/([^\\.]+)\\..+?title=\"(.+?)\".+?LogDate.+?>(.+?)<.+?LogText.+?>(.*?)</p>(.*?)</div></div></div></td></tr>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private final static Pattern patternLogImgs = Pattern.compile("href=\"(http://img.geocaching.com/cache/log/.+?)\".+?<span>([^<]*)", Pattern.CASE_INSENSITIVE); + private final static Pattern patternAttributes = Pattern.compile("<h3 class=\"WidgetHeader\">[^<]*<img[^>]+>\\W*Attributes[^<]*</h3>[^<]*<div class=\"WidgetBody\">(([^<]*<img src=\"[^\"]+\" alt=\"[^\"]+\"[^>]*>)+)[^<]*<p", Pattern.CASE_INSENSITIVE); + private final static Pattern patternAttributesInside = Pattern.compile("[^<]*<img src=\"([^\"]+)\" alt=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternSpoilers = Pattern.compile("<span id=\"ctl00_ContentBody_Images\">((<a href=\"[^\"]+\"[^>]*>[^<]*<img[^>]+>[^<]*<span>[^>]+</span>[^<]*</a>[^<]*<br[^>]*>([^<]*(<br[^>]*>)+)?)+)[^<]*</span>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternSpoilersInside = Pattern.compile("[^<]*<a href=\"([^\"]+)\"[^>]*>[^<]*<img[^>]+>[^<]*<span>([^>]+)</span>[^<]*</a>[^<]*<br[^>]*>(([^<]*)(<br[^<]*>)+)?", Pattern.CASE_INSENSITIVE); + private final static Pattern patternInventory = Pattern.compile("<span id=\"ctl00_ContentBody_uxTravelBugList_uxInventoryLabel\">\\W*Inventory[^<]*</span>[^<]*</h3>[^<]*<div class=\"WidgetBody\">([^<]*<ul>(([^<]*<li>[^<]*<a href=\"[^\"]+\"[^>]*>[^<]*<img src=\"[^\"]+\"[^>]*>[^<]*<span>[^<]+<\\/span>[^<]*<\\/a>[^<]*<\\/li>)+)[^<]*<\\/ul>)?", Pattern.CASE_INSENSITIVE); + private final static Pattern patternInventoryInside = Pattern.compile("[^<]*<li>[^<]*<a href=\"[a-z0-9\\-\\_\\.\\?\\/\\:\\@]*\\/track\\/details\\.aspx\\?guid=([0-9a-z\\-]+)[^\"]*\"[^>]*>[^<]*<img src=\"[^\"]+\"[^>]*>[^<]*<span>([^<]+)<\\/span>[^<]*<\\/a>[^<]*<\\/li>", Pattern.CASE_INSENSITIVE); + private final static Pattern patternOnWatchlist = Pattern.compile("<img\\s*src=\"\\/images\\/stockholm\\/16x16\\/icon_stop_watchlist.gif\"", Pattern.CASE_INSENSITIVE); + + private final static Pattern PATTERN_TRACKABLE_TrackableId = Pattern.compile("<a id=\"ctl00_ContentBody_LogLink\" title=\"[^\"]*\" href=\".*log\\.aspx\\?wid=([a-z0-9\\-]+)\"[^>]*>[^<]*</a>", Pattern.CASE_INSENSITIVE); + private 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>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Name = Pattern.compile("<h2>([^<]*<img[^>]*>)?[^<]*<span id=\"ctl00_ContentBody_lbHeading\">([^<]+)</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Owner = Pattern.compile("<dt>\\W*Owner:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugOwner\" title=\"[^\"]*\" href=\"[^\"]*/profile/\\?guid=([a-z0-9\\-]+)\">([^<]+)<\\/a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Released = Pattern.compile("<dt>\\W*Released:[^<]*</dt>[^<]*<dd>[^<]*<span id=\"ctl00_ContentBody_BugDetails_BugReleaseDate\">([^<]+)<\\/span>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Origin = Pattern.compile("<dt>\\W*Origin:[^<]*</dt>[^<]*<dd>[^<]*<span id=\"ctl00_ContentBody_BugDetails_BugOrigin\">([^<]+)<\\/span>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_SpottedCache = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\" title=\"[^\"]*\" href=\"[^\"]*/seek/cache_details.aspx\\?guid=([a-z0-9\\-]+)\">In ([^<]+)</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_SpottedUser = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\" href=\"[^\"]*/profile/\\?guid=([a-z0-9\\-]+)\">In the hands of ([^<]+).</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_SpottedUnknown = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\">Unknown Location[^<]*</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_SpottedOwner = Pattern.compile("<dt>\\W*Recently Spotted:[^<]*</dt>[^<]*<dd>[^<]*<a id=\"ctl00_ContentBody_BugDetails_BugLocation\">In the hands of the owner[^<]*</a>[^<]*</dd>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Goal = Pattern.compile("<h3>\\W*Current GOAL[^<]*</h3>[^<]*<p[^>]*>(.*)</p>[^<]*<h3>\\W*About This Item[^<]*</h3>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_DetailsImage = Pattern.compile("<h3>\\W*About This Item[^<]*</h3>([^<]*<p>([^<]*<img id=\"ctl00_ContentBody_BugDetails_BugImage\" class=\"[^\"]+\" src=\"([^\"]+)\"[^>]*>)?[^<]*</p>)?[^<]*<p[^>]*>(.*)</p>[^<]*<div id=\"ctl00_ContentBody_BugDetails_uxAbuseReport\">", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Icon = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Type = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"[^\"]+\" alt=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Distance = Pattern.compile("<h4[^>]*\\W*Tracking History \\(([0-9\\.,]+(km|mi))[^\\)]*\\)", Pattern.CASE_INSENSITIVE); + private final static Pattern PATTERN_TRACKABLE_Log = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^\\.]+)\\.gif[^>]+> ([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?(?:guid=([^\"]+)\">([^<]+)</a>.+?)?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE); + + public final static Map<String, String> cacheTypes = new HashMap<String, String>(); + public final static Map<String, String> cacheTypesInv = new HashMap<String, String>(); + public final static Map<String, String> cacheIDs = new HashMap<String, String>(); + public final static Map<String, String> cacheIDsChoices = new HashMap<String, String>(); + public final static Map<String, String> waypointTypes = new HashMap<String, String>(); + public final static Map<String, Integer> logTypes = new HashMap<String, Integer>(); + public final static Map<String, Integer> logTypes0 = new HashMap<String, Integer>(); + public final static Map<Integer, String> logTypes1 = new HashMap<Integer, String>(); + public final static Map<Integer, String> logTypes2 = new HashMap<Integer, String>(); + public final static Map<Integer, String> logTypesTrackable = new HashMap<Integer, String>(); + public final static Map<Integer, String> logTypesTrackableAction = new HashMap<Integer, String>(); + public final static Map<Integer, String> errorRetrieve = new HashMap<Integer, String>(); + public final static Map<String, SimpleDateFormat> gcCustomDateFormats; + static { + final String[] formats = new String[] { + "MM/dd/yyyy", + "yyyy-MM-dd", + "yyyy/MM/dd", + "dd/MMM/yyyy", "MMM/dd/yyyy", - "dd MMM yy", - "dd/MM/yyyy" - }; - - Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>(); - - for (String format : formats) - { - map.put(format, new SimpleDateFormat(format, Locale.ENGLISH)); - } - - gcCustomDateFormats = Collections.unmodifiableMap(map); - } - public final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 - public final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 - public final static SimpleDateFormat dateSqlIn = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2010-07-25 14:44:01 - private Resources res = null; - private Map<String, String> cookies = new HashMap<String, String>(); - private static final String passMatch = "[/\\?&]*[Pp]ass(word)?=[^&^#^$]+"; - private static final Pattern patternLoggedIn = Pattern.compile("<span class=\"Success\">You are logged in as[^<]*<strong[^>]*>([^<]+)</strong>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private static final Pattern patternLogged2In = Pattern.compile("<strong>\\W*Hello,[^<]*<a[^>]+>([^<]+)</a>[^<]*</strong>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private static final Pattern patternViewstateFieldCount = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private static final Pattern patternViewstates = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - private static final Pattern patternIsPremium = Pattern.compile("<span id=\"ctl00_litPMLevel\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - public static final float miles2km = 1.609344f; - public static final float feet2km = 0.0003048f; - public static final float yards2km = 0.0009144f; - public static final double deg2rad = Math.PI / 180; - public static final double rad2deg = 180 / Math.PI; - public static final float erad = 6371.0f; - private cgeoapplication app = null; - private cgSettings settings = null; - private SharedPreferences prefs = null; - public String version = null; - private String idBrowser = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.86 Safari/533.4"; - Context context = null; - final private static Map<String, Integer> gcIcons = new HashMap<String, Integer>(); - final private static Map<String, Integer> wpIcons = new HashMap<String, Integer>(); - - public static final int LOG_FOUND_IT = 2; - public static final int LOG_DIDNT_FIND_IT = 3; - public static final int LOG_NOTE = 4; - public static final int LOG_PUBLISH_LISTING = 1003; // unknown ID; used number doesn't match any GC.com's ID - public static final int LOG_ENABLE_LISTING = 23; - public static final int LOG_ARCHIVE = 5; - public static final int LOG_TEMP_DISABLE_LISTING = 22; - public static final int LOG_NEEDS_ARCHIVE = 7; - public static final int LOG_WILL_ATTEND = 9; - public static final int LOG_ATTENDED = 10; - public static final int LOG_RETRIEVED_IT = 13; - public static final int LOG_PLACED_IT = 14; - public static final int LOG_GRABBED_IT = 19; - public static final int LOG_NEEDS_MAINTENANCE = 45; - public static final int LOG_OWNER_MAINTENANCE = 46; - public static final int LOG_UPDATE_COORDINATES = 47; - public static final int LOG_DISCOVERED_IT = 48; - public static final int LOG_POST_REVIEWER_NOTE = 18; - public static final int LOG_VISIT = 1001; // unknown ID; used number doesn't match any GC.com's ID - public static final int LOG_WEBCAM_PHOTO_TAKEN = 11; - public static final int LOG_ANNOUNCEMENT = 74; - - public cgBase(cgeoapplication appIn, cgSettings settingsIn, SharedPreferences prefsIn) { - context = appIn.getBaseContext(); - res = appIn.getBaseContext().getResources(); - - // setup cache type mappings - - final String CACHETYPE_ALL_GUID = "9a79e6ce-3344-409c-bbe9-496530baf758"; + "dd MMM yy", + "dd/MM/yyyy" + }; + + Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>(); + + for (String format : formats) + { + map.put(format, new SimpleDateFormat(format, Locale.ENGLISH)); + } + + gcCustomDateFormats = Collections.unmodifiableMap(map); + } + public final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 + public final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 + public final static SimpleDateFormat dateSqlIn = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2010-07-25 14:44:01 + private Resources res = null; + private Map<String, String> cookies = new HashMap<String, String>(); + private static final String passMatch = "[/\\?&]*[Pp]ass(word)?=[^&^#^$]+"; + private static final Pattern patternLoggedIn = Pattern.compile("<span class=\"Success\">You are logged in as[^<]*<strong[^>]*>([^<]+)</strong>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private static final Pattern patternLogged2In = Pattern.compile("<strong>\\W*Hello,[^<]*<a[^>]+>([^<]+)</a>[^<]*</strong>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private static final Pattern patternViewstateFieldCount = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private static final Pattern patternViewstates = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + private static final Pattern patternIsPremium = Pattern.compile("<span id=\"ctl00_litPMLevel\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + public static final float miles2km = 1.609344f; + public static final float feet2km = 0.0003048f; + public static final float yards2km = 0.0009144f; + public static final double deg2rad = Math.PI / 180; + public static final double rad2deg = 180 / Math.PI; + public static final float erad = 6371.0f; + private cgeoapplication app = null; + private cgSettings settings = null; + private SharedPreferences prefs = null; + public String version = null; + private String idBrowser = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.86 Safari/533.4"; + Context context = null; + final private static Map<String, Integer> gcIcons = new HashMap<String, Integer>(); + final private static Map<String, Integer> wpIcons = new HashMap<String, Integer>(); + + public static final int LOG_FOUND_IT = 2; + public static final int LOG_DIDNT_FIND_IT = 3; + public static final int LOG_NOTE = 4; + public static final int LOG_PUBLISH_LISTING = 1003; // unknown ID; used number doesn't match any GC.com's ID + public static final int LOG_ENABLE_LISTING = 23; + public static final int LOG_ARCHIVE = 5; + public static final int LOG_TEMP_DISABLE_LISTING = 22; + public static final int LOG_NEEDS_ARCHIVE = 7; + public static final int LOG_WILL_ATTEND = 9; + public static final int LOG_ATTENDED = 10; + public static final int LOG_RETRIEVED_IT = 13; + public static final int LOG_PLACED_IT = 14; + public static final int LOG_GRABBED_IT = 19; + public static final int LOG_NEEDS_MAINTENANCE = 45; + public static final int LOG_OWNER_MAINTENANCE = 46; + public static final int LOG_UPDATE_COORDINATES = 47; + public static final int LOG_DISCOVERED_IT = 48; + public static final int LOG_POST_REVIEWER_NOTE = 18; + public static final int LOG_VISIT = 1001; // unknown ID; used number doesn't match any GC.com's ID + public static final int LOG_WEBCAM_PHOTO_TAKEN = 11; + public static final int LOG_ANNOUNCEMENT = 74; + + public cgBase(cgeoapplication appIn, cgSettings settingsIn, SharedPreferences prefsIn) { + context = appIn.getBaseContext(); + res = appIn.getBaseContext().getResources(); + + // setup cache type mappings + + final String CACHETYPE_ALL_GUID = "9a79e6ce-3344-409c-bbe9-496530baf758"; cacheIDs.put("all", CACHETYPE_ALL_GUID); cacheIDsChoices.put(res.getString(R.string.all), CACHETYPE_ALL_GUID); @@ -230,1596 +231,1592 @@ public class cgBase { cacheIDsChoices.put(l10n, ct.guid); } - // waypoint types - waypointTypes.put("flag", res.getString(R.string.wp_final)); - waypointTypes.put("stage", res.getString(R.string.wp_stage)); - waypointTypes.put("puzzle", res.getString(R.string.wp_puzzle)); - waypointTypes.put("pkg", res.getString(R.string.wp_pkg)); - waypointTypes.put("trailhead", res.getString(R.string.wp_trailhead)); - waypointTypes.put("waypoint", res.getString(R.string.wp_waypoint)); - - // log types - logTypes.put("icon_smile", LOG_FOUND_IT); - logTypes.put("icon_sad", LOG_DIDNT_FIND_IT); - logTypes.put("icon_note", LOG_NOTE); - logTypes.put("icon_greenlight", LOG_PUBLISH_LISTING); - logTypes.put("icon_enabled", LOG_ENABLE_LISTING); - logTypes.put("traffic_cone", LOG_ARCHIVE); - logTypes.put("icon_disabled", LOG_TEMP_DISABLE_LISTING); - logTypes.put("icon_remove", LOG_NEEDS_ARCHIVE); - logTypes.put("icon_rsvp", LOG_WILL_ATTEND); - logTypes.put("icon_attended", LOG_ATTENDED); - logTypes.put("picked_up", LOG_RETRIEVED_IT); - logTypes.put("dropped_off", LOG_PLACED_IT); - logTypes.put("transfer", LOG_GRABBED_IT); - logTypes.put("icon_needsmaint", LOG_NEEDS_MAINTENANCE); - logTypes.put("icon_maint", LOG_OWNER_MAINTENANCE); - logTypes.put("coord_update", LOG_UPDATE_COORDINATES); - logTypes.put("icon_discovered", LOG_DISCOVERED_IT); - logTypes.put("big_smile", LOG_POST_REVIEWER_NOTE); - logTypes.put("icon_visited", LOG_VISIT); // unknown ID; used number doesn't match any GC.com's ID - logTypes.put("icon_camera", LOG_WEBCAM_PHOTO_TAKEN); // unknown ID; used number doesn't match any GC.com's ID - logTypes.put("icon_announcement", LOG_ANNOUNCEMENT); // unknown ID; used number doesn't match any GC.com's ID - - logTypes0.put("found it", LOG_FOUND_IT); - logTypes0.put("didn't find it", LOG_DIDNT_FIND_IT); - logTypes0.put("write note", LOG_NOTE); - logTypes0.put("publish listing", LOG_PUBLISH_LISTING); - logTypes0.put("enable listing", LOG_ENABLE_LISTING); - logTypes0.put("archive", LOG_ARCHIVE); - logTypes0.put("temporarily disable listing", LOG_TEMP_DISABLE_LISTING); - logTypes0.put("needs archived", LOG_NEEDS_ARCHIVE); - logTypes0.put("will attend", LOG_WILL_ATTEND); - logTypes0.put("attended", LOG_ATTENDED); - logTypes0.put("retrieved it", LOG_RETRIEVED_IT); - logTypes0.put("placed it", LOG_PLACED_IT); - logTypes0.put("grabbed it", LOG_GRABBED_IT); - logTypes0.put("needs maintenance", LOG_NEEDS_MAINTENANCE); - logTypes0.put("owner maintenance", LOG_OWNER_MAINTENANCE); - logTypes0.put("update coordinates", LOG_UPDATE_COORDINATES); - logTypes0.put("discovered it", LOG_DISCOVERED_IT); - logTypes0.put("post reviewer note", LOG_POST_REVIEWER_NOTE); - logTypes0.put("visit", LOG_VISIT); // unknown ID; used number doesn't match any GC.com's ID - logTypes0.put("webcam photo taken", LOG_WEBCAM_PHOTO_TAKEN); // unknown ID; used number doesn't match any GC.com's ID - logTypes0.put("announcement", LOG_ANNOUNCEMENT); // unknown ID; used number doesn't match any GC.com's ID - - logTypes1.put(LOG_FOUND_IT, res.getString(R.string.log_found)); - logTypes1.put(LOG_DIDNT_FIND_IT, res.getString(R.string.log_dnf)); - logTypes1.put(LOG_NOTE, res.getString(R.string.log_note)); - logTypes1.put(LOG_PUBLISH_LISTING, res.getString(R.string.log_published)); - logTypes1.put(LOG_ENABLE_LISTING, res.getString(R.string.log_enabled)); - logTypes1.put(LOG_ARCHIVE, res.getString(R.string.log_archived)); - logTypes1.put(LOG_TEMP_DISABLE_LISTING, res.getString(R.string.log_disabled)); - logTypes1.put(LOG_NEEDS_ARCHIVE, res.getString(R.string.log_needs_archived)); - logTypes1.put(LOG_WILL_ATTEND, res.getString(R.string.log_attend)); - logTypes1.put(LOG_ATTENDED, res.getString(R.string.log_attended)); - logTypes1.put(LOG_RETRIEVED_IT, res.getString(R.string.log_retrieved)); - logTypes1.put(LOG_PLACED_IT, res.getString(R.string.log_placed)); - logTypes1.put(LOG_GRABBED_IT, res.getString(R.string.log_grabbed)); - logTypes1.put(LOG_NEEDS_MAINTENANCE, res.getString(R.string.log_maintenance_needed)); - logTypes1.put(LOG_OWNER_MAINTENANCE, res.getString(R.string.log_maintained)); - logTypes1.put(LOG_UPDATE_COORDINATES, res.getString(R.string.log_update)); - logTypes1.put(LOG_DISCOVERED_IT, res.getString(R.string.log_discovered)); - logTypes1.put(LOG_POST_REVIEWER_NOTE, res.getString(R.string.log_reviewed)); - logTypes1.put(LOG_VISIT, res.getString(R.string.log_taken)); - logTypes1.put(LOG_WEBCAM_PHOTO_TAKEN, res.getString(R.string.log_webcam)); - logTypes1.put(LOG_ANNOUNCEMENT, res.getString(R.string.log_announcement)); - - logTypes2.put(LOG_FOUND_IT, res.getString(R.string.log_found)); // traditional, multi, unknown, earth, wherigo, virtual, letterbox - logTypes2.put(LOG_DIDNT_FIND_IT, res.getString(R.string.log_dnf)); // traditional, multi, unknown, earth, wherigo, virtual, letterbox, webcam - logTypes2.put(LOG_NOTE, res.getString(R.string.log_note)); // traditional, multi, unknown, earth, wherigo, virtual, event, letterbox, webcam, trackable - logTypes2.put(LOG_PUBLISH_LISTING, res.getString(R.string.log_published)); // X - logTypes2.put(LOG_ENABLE_LISTING, res.getString(R.string.log_enabled)); // owner - logTypes2.put(LOG_ARCHIVE, res.getString(R.string.log_archived)); // traditional, multi, unknown, earth, event, wherigo, virtual, letterbox, webcam - logTypes2.put(LOG_TEMP_DISABLE_LISTING, res.getString(R.string.log_disabled)); // owner - logTypes2.put(LOG_NEEDS_ARCHIVE, res.getString(R.string.log_needs_archived)); // traditional, multi, unknown, earth, event, wherigo, virtual, letterbox, webcam - logTypes2.put(LOG_WILL_ATTEND, res.getString(R.string.log_attend)); // event - logTypes2.put(LOG_ATTENDED, res.getString(R.string.log_attended)); // event - logTypes2.put(LOG_WEBCAM_PHOTO_TAKEN, res.getString(R.string.log_webcam)); // webcam - logTypes2.put(LOG_RETRIEVED_IT, res.getString(R.string.log_retrieved)); //trackable - logTypes2.put(LOG_GRABBED_IT, res.getString(R.string.log_grabbed)); //trackable - logTypes2.put(LOG_NEEDS_MAINTENANCE, res.getString(R.string.log_maintenance_needed)); // traditional, unknown, multi, wherigo, virtual, letterbox, webcam - logTypes2.put(LOG_OWNER_MAINTENANCE, res.getString(R.string.log_maintained)); // owner - logTypes2.put(LOG_DISCOVERED_IT, res.getString(R.string.log_discovered)); //trackable - logTypes2.put(LOG_POST_REVIEWER_NOTE, res.getString(R.string.log_reviewed)); // X - logTypes2.put(LOG_ANNOUNCEMENT, res.getString(R.string.log_announcement)); // X - - // trackables for logs - logTypesTrackable.put(0, res.getString(R.string.log_tb_nothing)); // do nothing - logTypesTrackable.put(1, res.getString(R.string.log_tb_visit)); // visit cache - logTypesTrackable.put(2, res.getString(R.string.log_tb_drop)); // drop here - logTypesTrackableAction.put(0, ""); // do nothing - logTypesTrackableAction.put(1, "_Visited"); // visit cache - logTypesTrackableAction.put(2, "_DroppedOff"); // drop here - - // retrieving errors (because of ____ ) - errorRetrieve.put(1, res.getString(R.string.err_none)); - errorRetrieve.put(0, res.getString(R.string.err_start)); - errorRetrieve.put(-1, res.getString(R.string.err_parse)); - errorRetrieve.put(-2, res.getString(R.string.err_server)); - errorRetrieve.put(-3, res.getString(R.string.err_login)); - errorRetrieve.put(-4, res.getString(R.string.err_unknown)); - errorRetrieve.put(-5, res.getString(R.string.err_comm)); - errorRetrieve.put(-6, res.getString(R.string.err_wrong)); - errorRetrieve.put(-7, res.getString(R.string.err_license)); - - // init - app = appIn; - settings = settingsIn; - prefs = prefsIn; - - try { - PackageManager manager = app.getPackageManager(); - PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0); - version = info.versionName; - } catch (Exception e) { - // nothing - } - - if (settings.asBrowser == 1) { - final long rndBrowser = Math.round(Math.random() * 6); - if (rndBrowser == 0) { - idBrowser = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.322.2 Safari/533.1"; - } else if (rndBrowser == 1) { - idBrowser = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MDDC)"; - } else if (rndBrowser == 2) { - idBrowser = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"; - } else if (rndBrowser == 3) { - idBrowser = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"; - } else if (rndBrowser == 4) { - idBrowser = "Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11a Safari/525.20"; - } else if (rndBrowser == 5) { - idBrowser = "Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2"; - } else if (rndBrowser == 6) { - idBrowser = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.86 Safari/533.4"; - } else { - idBrowser = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.307.11 Safari/532.9"; - } - } - } - - /** - * read all viewstates from page - * - * @return String[] with all view states - */ - public static String[] getViewstates(String page) { - // Get the number of viewstates. - // If there is only one viewstate, __VIEWSTATEFIELDCOUNT is not present - int count = 1; - final Matcher matcherViewstateCount = patternViewstateFieldCount.matcher(page); - if (matcherViewstateCount.find()) - count = Integer.parseInt(matcherViewstateCount.group(1)); - - String[] viewstates = new String[count]; - - // Get the viewstates - int no; - final Matcher matcherViewstates = patternViewstates.matcher(page); - while (matcherViewstates.find()) { - String sno = matcherViewstates.group(1); // number of viewstate - if ("".equals(sno)) - no = 0; - else - no = Integer.parseInt(sno); - viewstates[no] = matcherViewstates.group(2); - } - - if (viewstates.length == 1 && viewstates[0] == null) - // no viewstates were present - return null; - else - return viewstates; - } - - /** - * put viewstates into request parameters - */ - private static void setViewstates(String[] viewstates, Map<String, String> params) { - if (ArrayUtils.isEmpty(viewstates)) - return; - params.put("__VIEWSTATE", viewstates[0]); - if (viewstates.length > 1) { - for (int i = 1; i < viewstates.length; i++) - params.put("__VIEWSTATE" + i, viewstates[i]); - params.put("__VIEWSTATEFIELDCOUNT", viewstates.length + ""); - } - } - - /** - * transfers the viewstates variables from a page (response) to parameters - * (next request) - */ - public static void transferViewstates(String page, Map<String, String> params) { - setViewstates(getViewstates(page), params); - } - - /** - * checks if an Array of Strings is empty or not. Empty means: - * - Array is null - * - or all elements are null or empty strings - */ - public static boolean isEmpty(String[] a) { - if (a == null) - return true; - - for (String s: a) { - if (StringUtils.isNotEmpty(s)) { - return false; - } - } - return true; - } - - - public class loginThread extends Thread { - - @Override - public void run() { - login(); - } - } - - public int login() { - final String host = "www.geocaching.com"; - final String path = "/login/default.aspx"; - cgResponse loginResponse = null; - String loginData = null; - - String[] viewstates = null; - - final Map<String, String> loginStart = settings.getLogin(); - - if (loginStart == null) { - return -3; // no login information stored - } - - loginResponse = request(true, host, path, "GET", new HashMap<String, String>(), false, false, false); - loginData = loginResponse.getData(); - if (StringUtils.isNotBlank(loginData)) { - if (checkLogin(loginData)) { - Log.i(cgSettings.tag, "Already logged in Geocaching.com as " + loginStart.get("username")); - - switchToEnglish(viewstates); - - return 1; // logged in - } - - viewstates = getViewstates(loginData); - - if (isEmpty(viewstates)) { - Log.e(cgSettings.tag, "cgeoBase.login: Failed to find viewstates"); - return -1; // no viewstates - } - } else { - Log.e(cgSettings.tag, "cgeoBase.login: Failed to retrieve login page (1st)"); - return -2; // no loginpage - } - - final Map<String, String> login = settings.getLogin(); - final Map<String, String> params = new HashMap<String, String>(); - - if (login == null || StringUtils.isEmpty(login.get("username")) || StringUtils.isEmpty(login.get("password"))) { - Log.e(cgSettings.tag, "cgeoBase.login: No login information stored"); - return -3; - } - - settings.deleteCookies(); - - params.put("__EVENTTARGET", ""); - params.put("__EVENTARGUMENT", ""); - setViewstates(viewstates, params); - params.put("ctl00$SiteContent$tbUsername", login.get("username")); - params.put("ctl00$SiteContent$tbPassword", login.get("password")); - params.put("ctl00$SiteContent$cbRememberMe", "on"); - params.put("ctl00$SiteContent$btnSignIn", "Login"); - - loginResponse = request(true, host, path, "POST", params, false, false, false); - loginData = loginResponse.getData(); - - if (StringUtils.isNotBlank(loginData)) { - if (checkLogin(loginData)) { - Log.i(cgSettings.tag, "Successfully logged in Geocaching.com as " + login.get("username")); - - switchToEnglish(getViewstates(loginData)); - - return 1; // logged in - } else { - if (loginData.indexOf("Your username/password combination does not match.") != -1) { - Log.i(cgSettings.tag, "Failed to log in Geocaching.com as " + login.get("username") + " because of wrong username/password"); - - return -6; // wrong login - } else { - Log.i(cgSettings.tag, "Failed to log in Geocaching.com as " + login.get("username") + " for some unknown reason"); - - return -4; // can't login - } - } - } else { - Log.e(cgSettings.tag, "cgeoBase.login: Failed to retrieve login page (2nd)"); - - return -5; // no login page - } - } - - public static Boolean isPremium(String page) - { - if (checkLogin(page)) { - final Matcher matcherIsPremium = patternIsPremium.matcher(page); - return matcherIsPremium.find(); - } else - return false; - } - - public static Boolean checkLogin(String page) { - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.checkLogin: No page given"); - return false; - } - - // on every page - final Matcher matcherLogged2In = patternLogged2In.matcher(page); - if (matcherLogged2In.find()) { - return true; - } - - // after login - final Matcher matcherLoggedIn = patternLoggedIn.matcher(page); - if (matcherLoggedIn.find()) { - return true; - } - - return false; - } - - public String switchToEnglish(String[] viewstates) { - final String host = "www.geocaching.com"; - final String path = "/default.aspx"; - final Map<String, String> params = new HashMap<String, String>(); - - setViewstates(viewstates, params); - params.put("__EVENTTARGET", "ctl00$uxLocaleList$uxLocaleList$ctl00$uxLocaleItem"); // switch to english - params.put("__EVENTARGUMENT", ""); - - return request(false, host, path, "POST", params, false, false, false).getData(); - } - - public cgCacheWrap parseSearch(cgSearchThread thread, String url, String page, boolean showCaptcha) { - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.parseSearch: No page given"); - return null; - } - - final cgCacheWrap caches = new cgCacheWrap(); - final List<String> cids = new ArrayList<String>(); - final List<String> guids = new ArrayList<String>(); - String recaptchaChallenge = null; - String recaptchaText = null; - - caches.url = url; - - final Pattern patternCacheType = Pattern.compile("<td class=\"Merge\">[^<]*<a href=\"[^\"]*/seek/cache_details\\.aspx\\?guid=[^\"]+\"[^>]+>[^<]*<img src=\"[^\"]*/images/wpttypes/[^\\.]+\\.gif\" alt=\"([^\"]+)\" title=\"[^\"]+\"[^>]*>[^<]*</a>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - final Pattern patternGuidAndDisabled = Pattern.compile("<img src=\"[^\"]*/images/wpttypes/[^>]*>[^<]*</a></td><td class=\"Merge\">[^<]*<a href=\"[^\"]*/seek/cache_details\\.aspx\\?guid=([a-z0-9\\-]+)\" class=\"lnk([^\"]*)\">([^<]*<span>)?([^<]*)(</span>[^<]*)?</a>[^<]+<br />([^<]*)<span[^>]+>([^<]*)</span>([^<]*<img[^>]+>)?[^<]*<br />[^<]*</td>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - final Pattern patternTbs = Pattern.compile("<a id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxTravelBugList\" class=\"tblist\" data-tbcount=\"([0-9]+)\" data-id=\"[^\"]*\"[^>]*>(.*)</a>", Pattern.CASE_INSENSITIVE); - final Pattern patternTbsInside = Pattern.compile("(<img src=\"[^\"]+\" alt=\"([^\"]+)\" title=\"[^\"]*\" />[^<]*)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - final Pattern patternDirection = Pattern.compile("<img id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxDistanceAndHeading\" title=\"[^\"]*\" src=\"[^\"]*/seek/CacheDir\\.ashx\\?k=([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); - final Pattern patternCode = Pattern.compile("\\|\\W*(GC[a-z0-9]+)[^\\|]*\\|", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - final Pattern patternId = Pattern.compile("name=\"CID\"[^v]*value=\"([0-9]+)\"", Pattern.CASE_INSENSITIVE); - final Pattern patternFavourite = Pattern.compile("<span id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxFavoritesValue\" title=\"[^\"]*\" class=\"favorite-rank\">([0-9]+)</span>", Pattern.CASE_INSENSITIVE); - final Pattern patternTotalCnt = Pattern.compile("<td class=\"PageBuilderWidget\"><span>Total Records[^<]*<b>(\\d+)<\\/b>", Pattern.CASE_INSENSITIVE); - final Pattern patternRecaptcha = Pattern.compile("<script[^>]*src=\"[^\"]*/recaptcha/api/challenge\\?k=([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); - final Pattern patternRecaptchaChallenge = Pattern.compile("challenge : '([^']+)'", Pattern.CASE_INSENSITIVE); - - caches.viewstates = getViewstates(page); - - // recaptcha - if (showCaptcha) { - try { - String recaptchaJsParam = null; - final Matcher matcherRecaptcha = patternRecaptcha.matcher(page); - while (matcherRecaptcha.find()) { - if (matcherRecaptcha.groupCount() > 0) { - recaptchaJsParam = matcherRecaptcha.group(1); - } - } - - if (recaptchaJsParam != null) { - final String recaptchaJs = request(false, "www.google.com", "/recaptcha/api/challenge", "GET", "k=" + urlencode_rfc3986(recaptchaJsParam.trim()), 0, true).getData(); - - if (StringUtils.isNotBlank(recaptchaJs)) { - final Matcher matcherRecaptchaChallenge = patternRecaptchaChallenge.matcher(recaptchaJs); - while (matcherRecaptchaChallenge.find()) { - if (matcherRecaptchaChallenge.groupCount() > 0) { - recaptchaChallenge = matcherRecaptchaChallenge.group(1).trim(); - } - } - } - } - } catch (Exception e) { - // failed to parse recaptcha challenge - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse recaptcha challenge"); - } - - if (thread != null && StringUtils.isNotBlank(recaptchaChallenge)) { - thread.setChallenge(recaptchaChallenge); - thread.notifyNeed(); - } - } - - if (page.indexOf("SearchResultsTable") < 0) { - // there are no results. aborting here avoids a wrong error log in the next parsing step - return caches; - } - - int startPos = page.indexOf("<div id=\"ctl00_ContentBody_ResultsPanel\""); - if (startPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_dlResults\" not found on page"); - return null; - } - - page = page.substring(startPos); // cut on <table - - startPos = page.indexOf(">"); - int endPos = page.indexOf("ctl00_ContentBody_UnitTxt"); - if (startPos == -1 || endPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_UnitTxt\" not found on page"); - return null; - } - - page = page.substring(startPos + 1, endPos - startPos + 1); // cut between <table> and </table> - - final String[] rows = page.split("<tr class="); - final int rows_count = rows.length; - - for (int z = 1; z < rows_count; z++) { - cgCache cache = new cgCache(); - String row = rows[z]; - - // check for cache type presence - if (row.indexOf("images/wpttypes") == -1) { - continue; - } - - try { - final Matcher matcherGuidAndDisabled = patternGuidAndDisabled.matcher(row); - - while (matcherGuidAndDisabled.find()) { - if (matcherGuidAndDisabled.groupCount() > 0) { - guids.add(matcherGuidAndDisabled.group(1)); - - cache.guid = matcherGuidAndDisabled.group(1); - if (matcherGuidAndDisabled.group(4) != null) { - cache.name = Html.fromHtml(matcherGuidAndDisabled.group(4).trim()).toString(); - } - if (matcherGuidAndDisabled.group(6) != null) { - cache.location = Html.fromHtml(matcherGuidAndDisabled.group(6).trim()).toString(); - } - - final String attr = matcherGuidAndDisabled.group(2); - if (attr != null) { - if (attr.contains("Strike")) { - cache.disabled = true; - } else { - cache.disabled = false; - } - - if (attr.contains("OldWarning")) { - cache.archived = true; - } else { - cache.archived = false; - } - } - } - } - } catch (Exception e) { - // failed to parse GUID and/or Disabled - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse GUID and/or Disabled data"); - } - - if (settings.excludeDisabled == 1 && (cache.disabled || cache.archived)) { - // skip disabled and archived caches - cache = null; - continue; - } - - String inventoryPre = null; - - // GC* code - try { - final Matcher matcherCode = patternCode.matcher(row); - while (matcherCode.find()) { - if (matcherCode.groupCount() > 0) { - cache.geocode = matcherCode.group(1).toUpperCase(); - } - } - } catch (Exception e) { - // failed to parse code - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache code"); - } - - // cache type - try { - final Matcher matcherCacheType = patternCacheType.matcher(row); - while (matcherCacheType.find()) { - if (matcherCacheType.groupCount() > 0) { - cache.type = cacheTypes.get(matcherCacheType.group(1).toLowerCase()); - } - } - } catch (Exception e) { - // failed to parse type - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache type"); - } - - // cache direction - image - if (settings.getLoadDirImg()) - { - try { - final Matcher matcherDirection = patternDirection.matcher(row); - while (matcherDirection.find()) { - if (matcherDirection.groupCount() > 0) { - cache.directionImg = matcherDirection.group(1); - } - } - } catch (Exception e) { - // failed to parse direction image - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache direction image"); - } - } - - // cache inventory - try { - final Matcher matcherTbs = patternTbs.matcher(row); - while (matcherTbs.find()) { - if (matcherTbs.groupCount() > 0) { - cache.inventoryItems = Integer.parseInt(matcherTbs.group(1)); - inventoryPre = matcherTbs.group(2); - } - } - } catch (Exception e) { - // failed to parse inventory - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache inventory (1)"); - } - - if (StringUtils.isNotBlank(inventoryPre)) { - try { - final Matcher matcherTbsInside = patternTbsInside.matcher(inventoryPre); - while (matcherTbsInside.find()) { - if (matcherTbsInside.groupCount() == 2 && matcherTbsInside.group(2) != null) { - final String inventoryItem = matcherTbsInside.group(2).toLowerCase(); - if (inventoryItem.equals("premium member only cache")) { - continue; - } else { - if (cache.inventoryItems <= 0) { - cache.inventoryItems = 1; - } - } - } - } - } catch (Exception e) { - // failed to parse cache inventory info - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache inventory info"); - } - } - - // premium cache - if (row.indexOf("/images/small_profile.gif") != -1) { - cache.members = true; - } else { - cache.members = false; - } - - // found it - if (row.indexOf("/images/icons/icon_smile") != -1) { - cache.found = true; - } else { - cache.found = false; - } - - // own it - if (row.indexOf("/images/silk/star.png") != -1) { - cache.own = true; - } else { - cache.own = false; - } - - // id - try { - final Matcher matcherId = patternId.matcher(row); - while (matcherId.find()) { - if (matcherId.groupCount() > 0) { - cache.cacheId = matcherId.group(1); - cids.add(cache.cacheId); - } - } - } catch (Exception e) { - // failed to parse cache id - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache id"); - } - - // favourite count - try { - final Matcher matcherFavourite = patternFavourite.matcher(row); - while (matcherFavourite.find()) { - if (matcherFavourite.groupCount() > 0) { - cache.favouriteCnt = Integer.parseInt(matcherFavourite.group(1)); - } - } - } catch (Exception e) { - // failed to parse favourite count - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse favourite count"); - } - - if (cache.nameSp == null) { - cache.nameSp = (new Spannable.Factory()).newSpannable(cache.name); - if (cache.disabled || cache.archived) { // strike - cache.nameSp.setSpan(new StrikethroughSpan(), 0, cache.nameSp.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } - - caches.cacheList.add(cache); - } - - // total caches found - try { - final Matcher matcherTotalCnt = patternTotalCnt.matcher(page); - while (matcherTotalCnt.find()) { - if (matcherTotalCnt.groupCount() > 0) { - if (matcherTotalCnt.group(1) != null) { - caches.totalCnt = Integer.valueOf(matcherTotalCnt.group(1)); - } - } - } - } catch (Exception e) { - // failed to parse cache count - Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache count"); - } - - if (thread != null && recaptchaChallenge != null) { - if (thread.getText() == null) { - thread.waitForUser(); - } - - recaptchaText = thread.getText(); - } - - if (cids.size() > 0 && (recaptchaChallenge == null || (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)))) { - Log.i(cgSettings.tag, "Trying to get .loc for " + cids.size() + " caches"); - - try { - // get coordinates for parsed caches - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final StringBuilder params = new StringBuilder(); - params.append("__EVENTTARGET=&__EVENTARGUMENT="); - if (ArrayUtils.isNotEmpty(caches.viewstates)) { - params.append("&__VIEWSTATE="); - params.append(urlencode_rfc3986(caches.viewstates[0])); - if (caches.viewstates.length > 1) { - for (int i = 1; i < caches.viewstates.length; i++) { - params.append("&__VIEWSTATE" + i + "="); - params.append(urlencode_rfc3986(caches.viewstates[i])); - } - params.append("&__VIEWSTATEFIELDCOUNT=" + caches.viewstates.length); - } - } - for (String cid : cids) { - params.append("&CID="); - params.append(urlencode_rfc3986(cid)); - } - - if (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)) { - params.append("&recaptcha_challenge_field="); - params.append(urlencode_rfc3986(recaptchaChallenge)); - params.append("&recaptcha_response_field="); - params.append(urlencode_rfc3986(recaptchaText)); - } - params.append("&ctl00%24ContentBody%24uxDownloadLoc=Download+Waypoints"); - - final String coordinates = request(false, host, path, "POST", params.toString(), 0, true).getData(); - - if ( StringUtils.isNotBlank(coordinates)) { - if (coordinates.indexOf("You have not agreed to the license agreement. The license agreement is required before you can start downloading GPX or LOC files from Geocaching.com") > -1) { - Log.i(cgSettings.tag, "User has not agreed to the license agreement. Can\'t download .loc file."); - - caches.error = errorRetrieve.get(-7); - - return caches; - } - } - - LocParser.parseLoc(caches, coordinates); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.parseSearch.CIDs: " + e.toString()); - } - } - - // get direction images - if (settings.getLoadDirImg()) - { - for (cgCache oneCache : caches.cacheList) { - if (oneCache.coords == null && oneCache.directionImg != null) { - cgDirectionImg.getDrawable(oneCache.geocode, oneCache.directionImg); - } - } - } - - // get ratings - if (guids.size() > 0) { - Log.i(cgSettings.tag, "Trying to get ratings for " + cids.size() + " caches"); - - try { - final Map<String, cgRating> ratings = getRating(guids, null); - - if (CollectionUtils.isNotEmpty(ratings)) { - // save found cache coordinates - for (cgCache oneCache : caches.cacheList) { - if (ratings.containsKey(oneCache.guid)) { - cgRating thisRating = ratings.get(oneCache.guid); - - oneCache.rating = thisRating.rating; - oneCache.votes = thisRating.votes; - oneCache.myVote = thisRating.myVote; - } - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.parseSearch.GCvote: " + e.toString()); - } - } - - return caches; - } - - public static cgCacheWrap parseMapJSON(String url, String data) { - if (StringUtils.isEmpty(data)) { - Log.e(cgSettings.tag, "cgeoBase.parseMapJSON: No page given"); - return null; - } - - final cgCacheWrap caches = new cgCacheWrap(); - caches.url = url; - - try { - final JSONObject yoDawg = new JSONObject(data); - final String json = yoDawg.getString("d"); - - if (StringUtils.isBlank(json)) { - Log.e(cgSettings.tag, "cgeoBase.parseMapJSON: No JSON inside JSON"); - return null; - } - - final JSONObject dataJSON = new JSONObject(json); - final JSONObject extra = dataJSON.getJSONObject("cs"); - if (extra != null && extra.length() > 0) { - int count = extra.getInt("count"); - - if (count > 0 && extra.has("cc")) { - final JSONArray cachesData = extra.getJSONArray("cc"); - if (cachesData != null && cachesData.length() > 0) { - JSONObject oneCache = null; - for (int i = 0; i < count; i++) { - oneCache = cachesData.getJSONObject(i); - if (oneCache == null) { - break; - } - - final cgCache cacheToAdd = new cgCache(); - cacheToAdd.reliableLatLon = false; - cacheToAdd.geocode = oneCache.getString("gc"); - cacheToAdd.coords = new Geopoint(oneCache.getDouble("lat"), oneCache.getDouble("lon")); - cacheToAdd.name = oneCache.getString("nn"); - cacheToAdd.found = oneCache.getBoolean("f"); - cacheToAdd.own = oneCache.getBoolean("o"); - cacheToAdd.disabled = !oneCache.getBoolean("ia"); - int ctid = oneCache.getInt("ctid"); - if (ctid == 2) { - cacheToAdd.type = "traditional"; - } else if (ctid == 3) { - cacheToAdd.type = "multi"; - } else if (ctid == 4) { - cacheToAdd.type = "virtual"; - } else if (ctid == 5) { - cacheToAdd.type = "letterbox"; - } else if (ctid == 6) { - cacheToAdd.type = "event"; - } else if (ctid == 8) { - cacheToAdd.type = "mystery"; - } else if (ctid == 11) { - cacheToAdd.type = "webcam"; - } else if (ctid == 13) { - cacheToAdd.type = "cito"; - } else if (ctid == 137) { - cacheToAdd.type = "earth"; - } else if (ctid == 453) { - cacheToAdd.type = "mega"; - } else if (ctid == 1858) { - cacheToAdd.type = "wherigo"; - } else if (ctid == 3653) { - cacheToAdd.type = "lost"; - } - - caches.cacheList.add(cacheToAdd); - } - } - } else { - Log.w(cgSettings.tag, "There are no caches in viewport"); - } - caches.totalCnt = caches.cacheList.size(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.parseMapJSON: " + e.toString()); - } - - return caches; - } - - public cgCacheWrap parseCache(String page, int reason) { - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.parseCache: No page given"); - return null; - } - - final cgCacheWrap caches = new cgCacheWrap(); - final cgCache cache = new cgCache(); - - if (page.indexOf("Cache is Unpublished") > -1) { - caches.error = "cache was unpublished"; - return caches; - } - - if (page.indexOf("Sorry, the owner of this listing has made it viewable to Premium Members only.") != -1) { - caches.error = "requested cache is for premium members only"; - return caches; - } - - if (page.indexOf("has chosen to make this cache listing visible to Premium Members only.") != -1) { - caches.error = "requested cache is for premium members only"; - return caches; - } - - if (page.indexOf("<li>This cache is temporarily unavailable.") != -1) { - cache.disabled = true; - } else { - cache.disabled = false; - } - - if (page.indexOf("<li>This cache has been archived,") != -1) { - cache.archived = true; - } else { - cache.archived = false; - } - - if (page.indexOf("<p class=\"Warning\">This is a Premium Member Only cache.</p>") != -1) { - cache.members = true; - } else { - cache.members = false; - } - - cache.reason = reason; - - // cache geocode - try { - final Matcher matcherGeocode = patternGeocode.matcher(page); - if (matcherGeocode.find() && matcherGeocode.groupCount() > 0) { - cache.geocode = getMatch(matcherGeocode.group(1)); - } - } catch (Exception e) { - // failed to parse cache geocode - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache geocode"); - } - - // cache id - try { - final Matcher matcherCacheId = patternCacheId.matcher(page); - if (matcherCacheId.find() && matcherCacheId.groupCount() > 0) { - cache.cacheId = getMatch(matcherCacheId.group(1)); - } - } catch (Exception e) { - // failed to parse cache id - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache id"); - } - - // cache guid - try { - final Matcher matcherCacheGuid = patternCacheGuid.matcher(page); - if (matcherCacheGuid.find() && matcherCacheGuid.groupCount() > 0) { - cache.guid = getMatch(matcherCacheGuid.group(1)); - } - } catch (Exception e) { - // failed to parse cache guid - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache guid"); - } - - // name - try { - final Matcher matcherName = patternName.matcher(page); - if (matcherName.find() && matcherName.groupCount() > 0) { - cache.name = Html.fromHtml(matcherName.group(1)).toString(); - } - } catch (Exception e) { - // failed to parse cache name - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache name"); - } - - // owner real name - try { - final Matcher matcherOwnerReal = patternOwnerReal.matcher(page); - if (matcherOwnerReal.find() && matcherOwnerReal.groupCount() > 0) { - cache.ownerReal = URLDecoder.decode(matcherOwnerReal.group(1)); - } - } catch (Exception e) { - // failed to parse owner real name - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache owner real name"); - } - - final String username = settings.getUsername(); - if (cache.ownerReal != null && username != null && cache.ownerReal.equalsIgnoreCase(username)) { - cache.own = true; - } - - int pos = -1; - String tableInside = page; - - pos = tableInside.indexOf("id=\"cacheDetails\""); - if (pos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseCache: ID \"cacheDetails\" not found on page"); - return null; - } - - tableInside = tableInside.substring(pos); - - pos = tableInside.indexOf("<div class=\"CacheInformationTable\""); - if (pos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseCache: ID \"CacheInformationTable\" not found on page"); - return null; - } - - tableInside = tableInside.substring(0, pos); - - if (StringUtils.isNotBlank(tableInside)) { - // cache terrain - try { - final Matcher matcherTerrain = patternTerrain.matcher(tableInside); - if (matcherTerrain.find() && matcherTerrain.groupCount() > 0) { - cache.terrain = new Float(Pattern.compile("_").matcher(matcherTerrain.group(1)).replaceAll(".")); - } - } catch (Exception e) { - // failed to parse terrain - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache terrain"); - } - - // cache difficulty - try { - final Matcher matcherDifficulty = patternDifficulty.matcher(tableInside); - if (matcherDifficulty.find() && matcherDifficulty.groupCount() > 0) { - cache.difficulty = new Float(Pattern.compile("_").matcher(matcherDifficulty.group(1)).replaceAll(".")); - } - } catch (Exception e) { - // failed to parse difficulty - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache difficulty"); - } - - // owner - try { - final Matcher matcherOwner = patternOwner.matcher(tableInside); - if (matcherOwner.find() && matcherOwner.groupCount() > 0) { - cache.owner = Html.fromHtml(matcherOwner.group(2)).toString(); - } - } catch (Exception e) { - // failed to parse owner - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache owner"); - } - - // hidden - try { - final Matcher matcherHidden = patternHidden.matcher(tableInside); - if (matcherHidden.find() && matcherHidden.groupCount() > 0) { - cache.hidden = parseGcCustomDate(matcherHidden.group(1)); - } - } catch (ParseException e) { - // failed to parse cache hidden date - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache hidden date"); - } - - if (cache.hidden == null) { - // event date - try { - final Matcher matcherHiddenEvent = patternHiddenEvent.matcher(tableInside); - if (matcherHiddenEvent.find() && matcherHiddenEvent.groupCount() > 0) { - cache.hidden = parseGcCustomDate(matcherHiddenEvent.group(1)); - } - } catch (ParseException e) { - // failed to parse cache event date - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache event date"); - } - } - - // favourite - try { - final Matcher matcherFavourite = patternFavourite.matcher(tableInside); - if (matcherFavourite.find() && matcherFavourite.groupCount() > 0) { - cache.favouriteCnt = Integer.parseInt(matcherFavourite.group(1)); - } - } catch (Exception e) { - // failed to parse favourite count - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse favourite count"); - } - - // cache size - try { - final Matcher matcherSize = patternSize.matcher(tableInside); - if (matcherSize.find() && matcherSize.groupCount() > 0) { - cache.size = getMatch(matcherSize.group(1)).toLowerCase(); - } - } catch (Exception e) { - // failed to parse size - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache size"); - } - } - - // cache found - cache.found = patternFound.matcher(page).find() || patternFoundAlternative.matcher(page).find(); - - // cache type - try { - final Matcher matcherType = patternType.matcher(page); - if (matcherType.find() && matcherType.groupCount() > 0) { - cache.type = cacheTypes.get(matcherType.group(1).toLowerCase()); - } - } catch (Exception e) { - // failed to parse type - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache type"); - } - - // on watchlist - try { - final Matcher matcher = patternOnWatchlist.matcher(page); - cache.onWatchlist = matcher.find(); - } catch (Exception e) { - // failed to parse watchlist state - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse watchlist state"); - } - - // latitude and logitude - try { - final Matcher matcherLatLon = patternLatLon.matcher(page); - if (matcherLatLon.find() && matcherLatLon.groupCount() > 0) { - cache.latlon = getMatch(matcherLatLon.group(2)); // first is <b> - - Map<String, Object> tmp = cgBase.parseLatlon(cache.latlon); - if (tmp.size() > 0) { - cache.coords = new Geopoint((Double) tmp.get("latitude"), (Double) tmp.get("longitude")); - cache.latitudeString = (String) tmp.get("latitudeString"); - cache.longitudeString = (String) tmp.get("longitudeString"); - cache.reliableLatLon = true; - } - tmp = null; - } - } catch (Exception e) { - // failed to parse latitude and/or longitude - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache coordinates"); - } - - // cache location - try { - final Matcher matcherLocation = patternLocation.matcher(page); - if (matcherLocation.find() && matcherLocation.groupCount() > 0) { - cache.location = getMatch(matcherLocation.group(1)); - } - } catch (Exception e) { - // failed to parse location - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache location"); - } - - // cache hint - try { - final Matcher matcherHint = patternHint.matcher(page); - if (matcherHint.find() && matcherHint.groupCount() > 2 && matcherHint.group(3) != null) { - // replace linebreak and paragraph tags - String hint = Pattern.compile("<(br|p)[^>]*>").matcher(matcherHint.group(3)).replaceAll("\n"); - if (hint != null) { - cache.hint = hint.replaceAll(Pattern.quote("</p>"), "").trim(); - } - } - } catch (Exception e) { - // failed to parse hint - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache hint"); - } - - checkFields(cache); - /* - // short info debug - Log.d(cgSettings.tag, "gc-code: " + cache.geocode); - Log.d(cgSettings.tag, "id: " + cache.cacheid); - Log.d(cgSettings.tag, "guid: " + cache.guid); - Log.d(cgSettings.tag, "name: " + cache.name); - Log.d(cgSettings.tag, "terrain: " + cache.terrain); - Log.d(cgSettings.tag, "difficulty: " + cache.difficulty); - Log.d(cgSettings.tag, "owner: " + cache.owner); - Log.d(cgSettings.tag, "owner (real): " + cache.ownerReal); - Log.d(cgSettings.tag, "hidden: " + dateOutShort.format(cache.hidden)); - Log.d(cgSettings.tag, "favorite: " + cache.favouriteCnt); - Log.d(cgSettings.tag, "size: " + cache.size); - if (cache.found) { - Log.d(cgSettings.tag, "found!"); - } else { - Log.d(cgSettings.tag, "not found"); - } - Log.d(cgSettings.tag, "type: " + cache.type); - Log.d(cgSettings.tag, "latitude: " + String.format("%.6f", cache.latitude)); - Log.d(cgSettings.tag, "longitude: " + String.format("%.6f", cache.longitude)); - Log.d(cgSettings.tag, "location: " + cache.location); - Log.d(cgSettings.tag, "hint: " + cache.hint); - */ - - // cache personal note - try { - final Matcher matcherPersonalNote = patternPersonalNote.matcher(page); - if (matcherPersonalNote.find() && matcherPersonalNote.groupCount() > 0) { - cache.personalNote = getMatch(matcherPersonalNote.group(1)); - } - } catch (Exception e) { - // failed to parse cache personal note - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache personal note"); - } - - // cache short description - try { - final Matcher matcherDescShort = patternDescShort.matcher(page); - if (matcherDescShort.find() && matcherDescShort.groupCount() > 0) { - cache.shortdesc = getMatch(matcherDescShort.group(1)); - } - } catch (Exception e) { - // failed to parse short description - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache short description"); - } - - // cache description - try { - final Matcher matcherDesc = patternDesc.matcher(page); - if (matcherDesc.find() && matcherDesc.groupCount() > 0) { - cache.description = getMatch(matcherDesc.group(1)); - } - } catch (Exception e) { - // failed to parse short description - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache description"); - } - - // cache attributes - try { - final Matcher matcherAttributes = patternAttributes.matcher(page); - if (matcherAttributes.find() && matcherAttributes.groupCount() > 0) { - final String attributesPre = matcherAttributes.group(1); - final Matcher matcherAttributesInside = patternAttributesInside.matcher(attributesPre); - - while (matcherAttributesInside.find()) { - if (matcherAttributesInside.groupCount() > 1 && matcherAttributesInside.group(2).equalsIgnoreCase("blank") != true) { - if (cache.attributes == null) { - cache.attributes = new ArrayList<String>(); - } - // by default, use the tooltip of the attribute - String attribute = matcherAttributesInside.group(2).toLowerCase(); - - // if the image name can be recognized, use the image name as attribute - String imageName = matcherAttributesInside.group(1).trim(); - if (imageName.length() > 0) { - int start = imageName.lastIndexOf('/'); - int end = imageName.lastIndexOf('.'); - if (start >= 0 && end>= 0) { - attribute = imageName.substring(start + 1, end).replace('-', '_').toLowerCase(); - } - } - cache.attributes.add(attribute); - } - } - } - } catch (Exception e) { - // failed to parse cache attributes - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache attributes"); - } - - // cache spoilers - try { - final Matcher matcherSpoilers = patternSpoilers.matcher(page); - if (matcherSpoilers.find() && matcherSpoilers.groupCount() > 0) { - final String spoilersPre = matcherSpoilers.group(1); - final Matcher matcherSpoilersInside = patternSpoilersInside.matcher(spoilersPre); - - while (matcherSpoilersInside.find()) { - if (matcherSpoilersInside.groupCount() > 0) { - final cgImage spoiler = new cgImage(); - spoiler.url = matcherSpoilersInside.group(1); - - if (matcherSpoilersInside.group(2) != null) { - spoiler.title = matcherSpoilersInside.group(2); - } - if (matcherSpoilersInside.group(4) != null) { - spoiler.description = matcherSpoilersInside.group(4); - } - - if (cache.spoilers == null) { - cache.spoilers = new ArrayList<cgImage>(); - } - cache.spoilers.add(spoiler); - } - } - } - } catch (Exception e) { - // failed to parse cache spoilers - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache spoilers"); - } - - // cache inventory - try { - cache.inventoryItems = 0; - - final Matcher matcherInventory = patternInventory.matcher(page); - if (matcherInventory.find()) { - if (cache.inventory == null) { - cache.inventory = new ArrayList<cgTrackable>(); - } - - if (matcherInventory.groupCount() > 1) { - final String inventoryPre = matcherInventory.group(2); - - if (StringUtils.isNotBlank(inventoryPre)) { - final Matcher matcherInventoryInside = patternInventoryInside.matcher(inventoryPre); - - while (matcherInventoryInside.find()) { - if (matcherInventoryInside.groupCount() > 0) { - final cgTrackable inventoryItem = new cgTrackable(); - inventoryItem.guid = matcherInventoryInside.group(1); - inventoryItem.name = matcherInventoryInside.group(2); - - cache.inventory.add(inventoryItem); - cache.inventoryItems++; - } - } - } - } - } - } catch (Exception e) { - // failed to parse cache inventory - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache inventory (2)"); - } - - // cache logs counts - try - { - final Matcher matcherLogCounts = patternCountLogs.matcher(page); - - if (matcherLogCounts.find()) - { - final Matcher matcherLog = patternCountLog.matcher(matcherLogCounts.group(1)); - - while (matcherLog.find()) - { - String typeStr = matcherLog.group(1); - String countStr = matcherLog.group(2); - - if (StringUtils.isNotBlank(typeStr) - && logTypes.containsKey(typeStr.toLowerCase()) - && StringUtils.isNotBlank(countStr)) - { - cache.logCounts.put(logTypes.get(typeStr.toLowerCase()), Integer.parseInt(countStr)); - } - } - } - } - catch (Exception e) - { - // failed to parse logs - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache log count"); - } - - // cache logs - try - { - /* - 1- Author - 2- Finds-count - 3- Log type image name (e.g. "icon_smile") - 4- Type string (e.g. "Found it") - 5- Date string (e.g. "04/28/2010") - 6- Log text - 7- The rest (e.g. log-images, maybe faster) - */ - final Matcher matcherLog = patternLog.matcher(page);//(matcherLogs.group(1)); - - while (matcherLog.find()) - { - final cgLog logDone = new cgLog(); - - final String logIconName = matcherLog.group(3).toLowerCase(); - if (logTypes.containsKey(logIconName)) - { - logDone.type = logTypes.get(logIconName); - } - else - { - logDone.type = logTypes.get("icon_note"); - } - - try - { - logDone.date = parseGcCustomDate(matcherLog.group(5)).getTime(); - } - catch (ParseException e) - { - Log.w(cgSettings.tag, "Failed to parse log date."); - } - - logDone.author = Html.fromHtml(matcherLog.group(1)).toString(); - - if (null != matcherLog.group(2)) - { - logDone.found = Integer.parseInt(matcherLog.group(2).replaceAll(",", "")); - } - - logDone.log = matcherLog.group(6); - - final Matcher matcherImg = patternLogImgs.matcher(matcherLog.group(7)); - while (matcherImg.find()) - { - final cgImage logImage = new cgImage(); - logImage.url = matcherImg.group(1); - logImage.title = matcherImg.group(2); - if (logDone.logImages == null) - { - logDone.logImages = new ArrayList<cgImage>(); - } - logDone.logImages.add(logImage); - } - - if (null == cache.logs) - { - cache.logs = new ArrayList<cgLog>(); - } - cache.logs.add(logDone); - } - } - catch (Exception e) - { - // failed to parse logs - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache logs", e); - } - - int wpBegin = 0; - int wpEnd = 0; - - wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">"); - if (wpBegin != -1) { // parse waypoints - final Pattern patternWpType = Pattern.compile("\\/wpttypes\\/sm\\/(.+)\\.jpg", Pattern.CASE_INSENSITIVE); - final Pattern patternWpPrefixOrLookupOrLatlon = Pattern.compile(">([^<]*<[^>]+>)?([^<]+)(<[^>]+>[^<]*)?<\\/td>", Pattern.CASE_INSENSITIVE); - final Pattern patternWpName = Pattern.compile(">[^<]*<a[^>]+>([^<]*)<\\/a>", Pattern.CASE_INSENSITIVE); - final Pattern patternWpNote = Pattern.compile("colspan=\"6\">(.*)<\\/td>", Pattern.CASE_INSENSITIVE); - - String wpList = page.substring(wpBegin); - - wpEnd = wpList.indexOf("</p>"); - if (wpEnd > -1 && wpEnd <= wpList.length()) { - wpList = wpList.substring(0, wpEnd); - } - - if (wpList.indexOf("No additional waypoints to display.") == -1) { - wpEnd = wpList.indexOf("</table>"); - wpList = wpList.substring(0, wpEnd); - - wpBegin = wpList.indexOf("<tbody>"); - wpEnd = wpList.indexOf("</tbody>"); - if (wpBegin >= 0 && wpEnd >= 0 && wpEnd <= wpList.length()) { - wpList = wpList.substring(wpBegin + 7, wpEnd); - } - - final String[] wpItems = wpList.split("<tr"); - - String[] wp; - for (int j = 1; j < wpItems.length; j++) { - final cgWaypoint waypoint = new cgWaypoint(); - - wp = wpItems[j].split("<td"); - - // waypoint type - try { - final Matcher matcherWpType = patternWpType.matcher(wp[3]); - if (matcherWpType.find() && matcherWpType.groupCount() > 0) { - waypoint.type = matcherWpType.group(1).trim(); - } - } catch (Exception e) { - // failed to parse type - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint type"); - } - - // waypoint prefix - try { - final Matcher matcherWpPrefix = patternWpPrefixOrLookupOrLatlon.matcher(wp[4]); - if (matcherWpPrefix.find() && matcherWpPrefix.groupCount() > 1) { - waypoint.prefix = matcherWpPrefix.group(2).trim(); - } - } catch (Exception e) { - // failed to parse prefix - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint prefix"); - } - - // waypoint lookup - try { - final Matcher matcherWpLookup = patternWpPrefixOrLookupOrLatlon.matcher(wp[5]); - if (matcherWpLookup.find() && matcherWpLookup.groupCount() > 1) { - waypoint.lookup = matcherWpLookup.group(2).trim(); - } - } catch (Exception e) { - // failed to parse lookup - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint lookup"); - } - - // waypoint name - try { - final Matcher matcherWpName = patternWpName.matcher(wp[6]); - while (matcherWpName.find()) { - if (matcherWpName.groupCount() > 0) { - waypoint.name = matcherWpName.group(1); - if (StringUtils.isNotBlank(waypoint.name)) { - waypoint.name = waypoint.name.trim(); - } - } - if (matcherWpName.find() && matcherWpName.groupCount() > 0) { - waypoint.name = matcherWpName.group(1).trim(); - } - } - } catch (Exception e) { - // failed to parse name - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint name"); - } - - // waypoint latitude and logitude - try { - final Matcher matcherWpLatLon = patternWpPrefixOrLookupOrLatlon.matcher(wp[7]); - if (matcherWpLatLon.find() && matcherWpLatLon.groupCount() > 1) { - waypoint.latlon = Html.fromHtml(matcherWpLatLon.group(2)).toString(); - - final Map<String, Object> tmp = cgBase.parseLatlon(waypoint.latlon); - if (tmp.size() > 0) { - waypoint.coords = new Geopoint((Double) tmp.get("latitude"), (Double) tmp.get("longitude")); - waypoint.latitudeString = (String) tmp.get("latitudeString"); - waypoint.longitudeString = (String) tmp.get("longitudeString"); - } - } - } catch (Exception e) { - // failed to parse latitude and/or longitude - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint coordinates"); - } - - j++; - if (wpItems.length > j) { - wp = wpItems[j].split("<td"); - } - - // waypoint note - try { - final Matcher matcherWpNote = patternWpNote.matcher(wp[3]); - if (matcherWpNote.find() && matcherWpNote.groupCount() > 0) { - waypoint.note = matcherWpNote.group(1).trim(); - } - } catch (Exception e) { - // failed to parse note - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint note"); - } - - if (cache.waypoints == null) { - cache.waypoints = new ArrayList<cgWaypoint>(); - } - cache.waypoints.add(waypoint); - } - } - } - - if (cache.coords != null) { - cache.elevation = getElevation(cache.coords); - } - - final cgRating rating = getRating(cache.guid, cache.geocode); - if (rating != null) { - cache.rating = rating.rating; - cache.votes = rating.votes; - cache.myVote = rating.myVote; - } - - cache.updated = System.currentTimeMillis(); - cache.detailedUpdate = System.currentTimeMillis(); - cache.detailed = true; - caches.cacheList.add(cache); - - return caches; - } - - private static void checkFields(cgCache cache) { - if (StringUtils.isBlank(cache.geocode)) { - Log.w(cgSettings.tag, "geo code not parsed correctly"); - } - if (StringUtils.isBlank(cache.name)) { - Log.w(cgSettings.tag, "name not parsed correctly"); - } - if (StringUtils.isBlank(cache.guid)) { - Log.w(cgSettings.tag, "guid not parsed correctly"); - } - if (cache.terrain == null || cache.terrain == 0.0) { - Log.w(cgSettings.tag, "terrain not parsed correctly"); - } - if (cache.difficulty == null || cache.difficulty == 0.0) { - Log.w(cgSettings.tag, "difficulty not parsed correctly"); - } - if (StringUtils.isBlank(cache.owner)) { - Log.w(cgSettings.tag, "owner not parsed correctly"); - } - if (StringUtils.isBlank(cache.ownerReal)) { - Log.w(cgSettings.tag, "owner real not parsed correctly"); - } - if (cache.hidden == null) { - Log.w(cgSettings.tag, "hidden not parsed correctly"); - } - if (cache.favouriteCnt == null) { - Log.w(cgSettings.tag, "favoriteCount not parsed correctly"); - } - if (StringUtils.isBlank(cache.size)) { - Log.w(cgSettings.tag, "size not parsed correctly"); - } - if (StringUtils.isBlank(cache.type)) { - Log.w(cgSettings.tag, "type not parsed correctly"); - } - if (cache.coords == null) { - Log.w(cgSettings.tag, "coordinates not parsed correctly"); - } - if (StringUtils.isBlank(cache.location)) { - Log.w(cgSettings.tag, "location not parsed correctly"); - } - } - - private static String getMatch(String match) { - // creating a new String via String constructor is necessary here!! - return new String(match.trim()); - // Java copies the whole page String, when matching with regular expressions - // later this would block the garbage collector, as we only need tiny parts of the page - // see http://developer.android.com/reference/java/lang/String.html#backing_array - - // And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler! - } - - public Date parseGcCustomDate(String input) - throws ParseException - { - if (StringUtils.isBlank(input)) - { - throw new ParseException("Input is null", 0); - } - - input = input.trim(); - - if (null != settings - //&& null != settings.getGcCustomDate() - && gcCustomDateFormats.containsKey(settings.getGcCustomDate())) - { - try + // waypoint types + waypointTypes.put("flag", res.getString(R.string.wp_final)); + waypointTypes.put("stage", res.getString(R.string.wp_stage)); + waypointTypes.put("puzzle", res.getString(R.string.wp_puzzle)); + waypointTypes.put("pkg", res.getString(R.string.wp_pkg)); + waypointTypes.put("trailhead", res.getString(R.string.wp_trailhead)); + waypointTypes.put("waypoint", res.getString(R.string.wp_waypoint)); + + // log types + logTypes.put("icon_smile", LOG_FOUND_IT); + logTypes.put("icon_sad", LOG_DIDNT_FIND_IT); + logTypes.put("icon_note", LOG_NOTE); + logTypes.put("icon_greenlight", LOG_PUBLISH_LISTING); + logTypes.put("icon_enabled", LOG_ENABLE_LISTING); + logTypes.put("traffic_cone", LOG_ARCHIVE); + logTypes.put("icon_disabled", LOG_TEMP_DISABLE_LISTING); + logTypes.put("icon_remove", LOG_NEEDS_ARCHIVE); + logTypes.put("icon_rsvp", LOG_WILL_ATTEND); + logTypes.put("icon_attended", LOG_ATTENDED); + logTypes.put("picked_up", LOG_RETRIEVED_IT); + logTypes.put("dropped_off", LOG_PLACED_IT); + logTypes.put("transfer", LOG_GRABBED_IT); + logTypes.put("icon_needsmaint", LOG_NEEDS_MAINTENANCE); + logTypes.put("icon_maint", LOG_OWNER_MAINTENANCE); + logTypes.put("coord_update", LOG_UPDATE_COORDINATES); + logTypes.put("icon_discovered", LOG_DISCOVERED_IT); + logTypes.put("big_smile", LOG_POST_REVIEWER_NOTE); + logTypes.put("icon_visited", LOG_VISIT); // unknown ID; used number doesn't match any GC.com's ID + logTypes.put("icon_camera", LOG_WEBCAM_PHOTO_TAKEN); // unknown ID; used number doesn't match any GC.com's ID + logTypes.put("icon_announcement", LOG_ANNOUNCEMENT); // unknown ID; used number doesn't match any GC.com's ID + + logTypes0.put("found it", LOG_FOUND_IT); + logTypes0.put("didn't find it", LOG_DIDNT_FIND_IT); + logTypes0.put("write note", LOG_NOTE); + logTypes0.put("publish listing", LOG_PUBLISH_LISTING); + logTypes0.put("enable listing", LOG_ENABLE_LISTING); + logTypes0.put("archive", LOG_ARCHIVE); + logTypes0.put("temporarily disable listing", LOG_TEMP_DISABLE_LISTING); + logTypes0.put("needs archived", LOG_NEEDS_ARCHIVE); + logTypes0.put("will attend", LOG_WILL_ATTEND); + logTypes0.put("attended", LOG_ATTENDED); + logTypes0.put("retrieved it", LOG_RETRIEVED_IT); + logTypes0.put("placed it", LOG_PLACED_IT); + logTypes0.put("grabbed it", LOG_GRABBED_IT); + logTypes0.put("needs maintenance", LOG_NEEDS_MAINTENANCE); + logTypes0.put("owner maintenance", LOG_OWNER_MAINTENANCE); + logTypes0.put("update coordinates", LOG_UPDATE_COORDINATES); + logTypes0.put("discovered it", LOG_DISCOVERED_IT); + logTypes0.put("post reviewer note", LOG_POST_REVIEWER_NOTE); + logTypes0.put("visit", LOG_VISIT); // unknown ID; used number doesn't match any GC.com's ID + logTypes0.put("webcam photo taken", LOG_WEBCAM_PHOTO_TAKEN); // unknown ID; used number doesn't match any GC.com's ID + logTypes0.put("announcement", LOG_ANNOUNCEMENT); // unknown ID; used number doesn't match any GC.com's ID + + logTypes1.put(LOG_FOUND_IT, res.getString(R.string.log_found)); + logTypes1.put(LOG_DIDNT_FIND_IT, res.getString(R.string.log_dnf)); + logTypes1.put(LOG_NOTE, res.getString(R.string.log_note)); + logTypes1.put(LOG_PUBLISH_LISTING, res.getString(R.string.log_published)); + logTypes1.put(LOG_ENABLE_LISTING, res.getString(R.string.log_enabled)); + logTypes1.put(LOG_ARCHIVE, res.getString(R.string.log_archived)); + logTypes1.put(LOG_TEMP_DISABLE_LISTING, res.getString(R.string.log_disabled)); + logTypes1.put(LOG_NEEDS_ARCHIVE, res.getString(R.string.log_needs_archived)); + logTypes1.put(LOG_WILL_ATTEND, res.getString(R.string.log_attend)); + logTypes1.put(LOG_ATTENDED, res.getString(R.string.log_attended)); + logTypes1.put(LOG_RETRIEVED_IT, res.getString(R.string.log_retrieved)); + logTypes1.put(LOG_PLACED_IT, res.getString(R.string.log_placed)); + logTypes1.put(LOG_GRABBED_IT, res.getString(R.string.log_grabbed)); + logTypes1.put(LOG_NEEDS_MAINTENANCE, res.getString(R.string.log_maintenance_needed)); + logTypes1.put(LOG_OWNER_MAINTENANCE, res.getString(R.string.log_maintained)); + logTypes1.put(LOG_UPDATE_COORDINATES, res.getString(R.string.log_update)); + logTypes1.put(LOG_DISCOVERED_IT, res.getString(R.string.log_discovered)); + logTypes1.put(LOG_POST_REVIEWER_NOTE, res.getString(R.string.log_reviewed)); + logTypes1.put(LOG_VISIT, res.getString(R.string.log_taken)); + logTypes1.put(LOG_WEBCAM_PHOTO_TAKEN, res.getString(R.string.log_webcam)); + logTypes1.put(LOG_ANNOUNCEMENT, res.getString(R.string.log_announcement)); + + logTypes2.put(LOG_FOUND_IT, res.getString(R.string.log_found)); // traditional, multi, unknown, earth, wherigo, virtual, letterbox + logTypes2.put(LOG_DIDNT_FIND_IT, res.getString(R.string.log_dnf)); // traditional, multi, unknown, earth, wherigo, virtual, letterbox, webcam + logTypes2.put(LOG_NOTE, res.getString(R.string.log_note)); // traditional, multi, unknown, earth, wherigo, virtual, event, letterbox, webcam, trackable + logTypes2.put(LOG_PUBLISH_LISTING, res.getString(R.string.log_published)); // X + logTypes2.put(LOG_ENABLE_LISTING, res.getString(R.string.log_enabled)); // owner + logTypes2.put(LOG_ARCHIVE, res.getString(R.string.log_archived)); // traditional, multi, unknown, earth, event, wherigo, virtual, letterbox, webcam + logTypes2.put(LOG_TEMP_DISABLE_LISTING, res.getString(R.string.log_disabled)); // owner + logTypes2.put(LOG_NEEDS_ARCHIVE, res.getString(R.string.log_needs_archived)); // traditional, multi, unknown, earth, event, wherigo, virtual, letterbox, webcam + logTypes2.put(LOG_WILL_ATTEND, res.getString(R.string.log_attend)); // event + logTypes2.put(LOG_ATTENDED, res.getString(R.string.log_attended)); // event + logTypes2.put(LOG_WEBCAM_PHOTO_TAKEN, res.getString(R.string.log_webcam)); // webcam + logTypes2.put(LOG_RETRIEVED_IT, res.getString(R.string.log_retrieved)); //trackable + logTypes2.put(LOG_GRABBED_IT, res.getString(R.string.log_grabbed)); //trackable + logTypes2.put(LOG_NEEDS_MAINTENANCE, res.getString(R.string.log_maintenance_needed)); // traditional, unknown, multi, wherigo, virtual, letterbox, webcam + logTypes2.put(LOG_OWNER_MAINTENANCE, res.getString(R.string.log_maintained)); // owner + logTypes2.put(LOG_DISCOVERED_IT, res.getString(R.string.log_discovered)); //trackable + logTypes2.put(LOG_POST_REVIEWER_NOTE, res.getString(R.string.log_reviewed)); // X + logTypes2.put(LOG_ANNOUNCEMENT, res.getString(R.string.log_announcement)); // X + + // trackables for logs + logTypesTrackable.put(0, res.getString(R.string.log_tb_nothing)); // do nothing + logTypesTrackable.put(1, res.getString(R.string.log_tb_visit)); // visit cache + logTypesTrackable.put(2, res.getString(R.string.log_tb_drop)); // drop here + logTypesTrackableAction.put(0, ""); // do nothing + logTypesTrackableAction.put(1, "_Visited"); // visit cache + logTypesTrackableAction.put(2, "_DroppedOff"); // drop here + + // retrieving errors (because of ____ ) + errorRetrieve.put(1, res.getString(R.string.err_none)); + errorRetrieve.put(0, res.getString(R.string.err_start)); + errorRetrieve.put(-1, res.getString(R.string.err_parse)); + errorRetrieve.put(-2, res.getString(R.string.err_server)); + errorRetrieve.put(-3, res.getString(R.string.err_login)); + errorRetrieve.put(-4, res.getString(R.string.err_unknown)); + errorRetrieve.put(-5, res.getString(R.string.err_comm)); + errorRetrieve.put(-6, res.getString(R.string.err_wrong)); + errorRetrieve.put(-7, res.getString(R.string.err_license)); + + // init + app = appIn; + settings = settingsIn; + prefs = prefsIn; + + try { + PackageManager manager = app.getPackageManager(); + PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0); + version = info.versionName; + } catch (Exception e) { + // nothing + } + + if (settings.asBrowser == 1) { + final long rndBrowser = Math.round(Math.random() * 6); + if (rndBrowser == 0) { + idBrowser = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.322.2 Safari/533.1"; + } else if (rndBrowser == 1) { + idBrowser = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MDDC)"; + } else if (rndBrowser == 2) { + idBrowser = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"; + } else if (rndBrowser == 3) { + idBrowser = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"; + } else if (rndBrowser == 4) { + idBrowser = "Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11a Safari/525.20"; + } else if (rndBrowser == 5) { + idBrowser = "Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2"; + } else if (rndBrowser == 6) { + idBrowser = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.86 Safari/533.4"; + } else { + idBrowser = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.307.11 Safari/532.9"; + } + } + } + + /** + * read all viewstates from page + * + * @return String[] with all view states + */ + public static String[] getViewstates(String page) { + // Get the number of viewstates. + // If there is only one viewstate, __VIEWSTATEFIELDCOUNT is not present + int count = 1; + final Matcher matcherViewstateCount = patternViewstateFieldCount.matcher(page); + if (matcherViewstateCount.find()) + count = Integer.parseInt(matcherViewstateCount.group(1)); + + String[] viewstates = new String[count]; + + // Get the viewstates + int no; + final Matcher matcherViewstates = patternViewstates.matcher(page); + while (matcherViewstates.find()) { + String sno = matcherViewstates.group(1); // number of viewstate + if ("".equals(sno)) + no = 0; + else + no = Integer.parseInt(sno); + viewstates[no] = matcherViewstates.group(2); + } + + if (viewstates.length == 1 && viewstates[0] == null) + // no viewstates were present + return null; + else + return viewstates; + } + + /** + * put viewstates into request parameters + */ + private static void setViewstates(String[] viewstates, Map<String, String> params) { + if (ArrayUtils.isEmpty(viewstates)) + return; + params.put("__VIEWSTATE", viewstates[0]); + if (viewstates.length > 1) { + for (int i = 1; i < viewstates.length; i++) + params.put("__VIEWSTATE" + i, viewstates[i]); + params.put("__VIEWSTATEFIELDCOUNT", viewstates.length + ""); + } + } + + /** + * transfers the viewstates variables from a page (response) to parameters + * (next request) + */ + public static void transferViewstates(String page, Map<String, String> params) { + setViewstates(getViewstates(page), params); + } + + /** + * checks if an Array of Strings is empty or not. Empty means: + * - Array is null + * - or all elements are null or empty strings + */ + public static boolean isEmpty(String[] a) { + if (a == null) + return true; + + for (String s : a) { + if (StringUtils.isNotEmpty(s)) { + return false; + } + } + return true; + } + + public class loginThread extends Thread { + + @Override + public void run() { + login(); + } + } + + public int login() { + final String host = "www.geocaching.com"; + final String path = "/login/default.aspx"; + cgResponse loginResponse = null; + String loginData = null; + + String[] viewstates = null; + + final Map<String, String> loginStart = settings.getLogin(); + + if (loginStart == null) { + return -3; // no login information stored + } + + loginResponse = request(true, host, path, "GET", new HashMap<String, String>(), false, false, false); + loginData = loginResponse.getData(); + if (StringUtils.isNotBlank(loginData)) { + if (checkLogin(loginData)) { + Log.i(cgSettings.tag, "Already logged in Geocaching.com as " + loginStart.get("username")); + + switchToEnglish(viewstates); + + return 1; // logged in + } + + viewstates = getViewstates(loginData); + + if (isEmpty(viewstates)) { + Log.e(cgSettings.tag, "cgeoBase.login: Failed to find viewstates"); + return -1; // no viewstates + } + } else { + Log.e(cgSettings.tag, "cgeoBase.login: Failed to retrieve login page (1st)"); + return -2; // no loginpage + } + + final Map<String, String> login = settings.getLogin(); + final Map<String, String> params = new HashMap<String, String>(); + + if (login == null || StringUtils.isEmpty(login.get("username")) || StringUtils.isEmpty(login.get("password"))) { + Log.e(cgSettings.tag, "cgeoBase.login: No login information stored"); + return -3; + } + + settings.deleteCookies(); + + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); + setViewstates(viewstates, params); + params.put("ctl00$SiteContent$tbUsername", login.get("username")); + params.put("ctl00$SiteContent$tbPassword", login.get("password")); + params.put("ctl00$SiteContent$cbRememberMe", "on"); + params.put("ctl00$SiteContent$btnSignIn", "Login"); + + loginResponse = request(true, host, path, "POST", params, false, false, false); + loginData = loginResponse.getData(); + + if (StringUtils.isNotBlank(loginData)) { + if (checkLogin(loginData)) { + Log.i(cgSettings.tag, "Successfully logged in Geocaching.com as " + login.get("username")); + + switchToEnglish(getViewstates(loginData)); + + return 1; // logged in + } else { + if (loginData.indexOf("Your username/password combination does not match.") != -1) { + Log.i(cgSettings.tag, "Failed to log in Geocaching.com as " + login.get("username") + " because of wrong username/password"); + + return -6; // wrong login + } else { + Log.i(cgSettings.tag, "Failed to log in Geocaching.com as " + login.get("username") + " for some unknown reason"); + + return -4; // can't login + } + } + } else { + Log.e(cgSettings.tag, "cgeoBase.login: Failed to retrieve login page (2nd)"); + + return -5; // no login page + } + } + + public static Boolean isPremium(String page) + { + if (checkLogin(page)) { + final Matcher matcherIsPremium = patternIsPremium.matcher(page); + return matcherIsPremium.find(); + } else + return false; + } + + public static Boolean checkLogin(String page) { + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.checkLogin: No page given"); + return false; + } + + // on every page + final Matcher matcherLogged2In = patternLogged2In.matcher(page); + if (matcherLogged2In.find()) { + return true; + } + + // after login + final Matcher matcherLoggedIn = patternLoggedIn.matcher(page); + if (matcherLoggedIn.find()) { + return true; + } + + return false; + } + + public String switchToEnglish(String[] viewstates) { + final String host = "www.geocaching.com"; + final String path = "/default.aspx"; + final Map<String, String> params = new HashMap<String, String>(); + + setViewstates(viewstates, params); + params.put("__EVENTTARGET", "ctl00$uxLocaleList$uxLocaleList$ctl00$uxLocaleItem"); // switch to english + params.put("__EVENTARGUMENT", ""); + + return request(false, host, path, "POST", params, false, false, false).getData(); + } + + public cgCacheWrap parseSearch(cgSearchThread thread, String url, String page, boolean showCaptcha) { + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.parseSearch: No page given"); + return null; + } + + final cgCacheWrap caches = new cgCacheWrap(); + final List<String> cids = new ArrayList<String>(); + final List<String> guids = new ArrayList<String>(); + String recaptchaChallenge = null; + String recaptchaText = null; + + caches.url = url; + + final Pattern patternCacheType = Pattern.compile("<td class=\"Merge\">[^<]*<a href=\"[^\"]*/seek/cache_details\\.aspx\\?guid=[^\"]+\"[^>]+>[^<]*<img src=\"[^\"]*/images/wpttypes/[^\\.]+\\.gif\" alt=\"([^\"]+)\" title=\"[^\"]+\"[^>]*>[^<]*</a>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + final Pattern patternGuidAndDisabled = Pattern.compile("<img src=\"[^\"]*/images/wpttypes/[^>]*>[^<]*</a></td><td class=\"Merge\">[^<]*<a href=\"[^\"]*/seek/cache_details\\.aspx\\?guid=([a-z0-9\\-]+)\" class=\"lnk([^\"]*)\">([^<]*<span>)?([^<]*)(</span>[^<]*)?</a>[^<]+<br />([^<]*)<span[^>]+>([^<]*)</span>([^<]*<img[^>]+>)?[^<]*<br />[^<]*</td>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + final Pattern patternTbs = Pattern.compile("<a id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxTravelBugList\" class=\"tblist\" data-tbcount=\"([0-9]+)\" data-id=\"[^\"]*\"[^>]*>(.*)</a>", Pattern.CASE_INSENSITIVE); + final Pattern patternTbsInside = Pattern.compile("(<img src=\"[^\"]+\" alt=\"([^\"]+)\" title=\"[^\"]*\" />[^<]*)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + final Pattern patternDirection = Pattern.compile("<img id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxDistanceAndHeading\" title=\"[^\"]*\" src=\"[^\"]*/seek/CacheDir\\.ashx\\?k=([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); + final Pattern patternCode = Pattern.compile("\\|\\W*(GC[a-z0-9]+)[^\\|]*\\|", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + final Pattern patternId = Pattern.compile("name=\"CID\"[^v]*value=\"([0-9]+)\"", Pattern.CASE_INSENSITIVE); + final Pattern patternFavourite = Pattern.compile("<span id=\"ctl00_ContentBody_dlResults_ctl[0-9]+_uxFavoritesValue\" title=\"[^\"]*\" class=\"favorite-rank\">([0-9]+)</span>", Pattern.CASE_INSENSITIVE); + final Pattern patternTotalCnt = Pattern.compile("<td class=\"PageBuilderWidget\"><span>Total Records[^<]*<b>(\\d+)<\\/b>", Pattern.CASE_INSENSITIVE); + final Pattern patternRecaptcha = Pattern.compile("<script[^>]*src=\"[^\"]*/recaptcha/api/challenge\\?k=([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE); + final Pattern patternRecaptchaChallenge = Pattern.compile("challenge : '([^']+)'", Pattern.CASE_INSENSITIVE); + + caches.viewstates = getViewstates(page); + + // recaptcha + if (showCaptcha) { + try { + String recaptchaJsParam = null; + final Matcher matcherRecaptcha = patternRecaptcha.matcher(page); + while (matcherRecaptcha.find()) { + if (matcherRecaptcha.groupCount() > 0) { + recaptchaJsParam = matcherRecaptcha.group(1); + } + } + + if (recaptchaJsParam != null) { + final String recaptchaJs = request(false, "www.google.com", "/recaptcha/api/challenge", "GET", "k=" + urlencode_rfc3986(recaptchaJsParam.trim()), 0, true).getData(); + + if (StringUtils.isNotBlank(recaptchaJs)) { + final Matcher matcherRecaptchaChallenge = patternRecaptchaChallenge.matcher(recaptchaJs); + while (matcherRecaptchaChallenge.find()) { + if (matcherRecaptchaChallenge.groupCount() > 0) { + recaptchaChallenge = matcherRecaptchaChallenge.group(1).trim(); + } + } + } + } + } catch (Exception e) { + // failed to parse recaptcha challenge + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse recaptcha challenge"); + } + + if (thread != null && StringUtils.isNotBlank(recaptchaChallenge)) { + thread.setChallenge(recaptchaChallenge); + thread.notifyNeed(); + } + } + + if (page.indexOf("SearchResultsTable") < 0) { + // there are no results. aborting here avoids a wrong error log in the next parsing step + return caches; + } + + int startPos = page.indexOf("<div id=\"ctl00_ContentBody_ResultsPanel\""); + if (startPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_dlResults\" not found on page"); + return null; + } + + page = page.substring(startPos); // cut on <table + + startPos = page.indexOf(">"); + int endPos = page.indexOf("ctl00_ContentBody_UnitTxt"); + if (startPos == -1 || endPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_UnitTxt\" not found on page"); + return null; + } + + page = page.substring(startPos + 1, endPos - startPos + 1); // cut between <table> and </table> + + final String[] rows = page.split("<tr class="); + final int rows_count = rows.length; + + for (int z = 1; z < rows_count; z++) { + cgCache cache = new cgCache(); + String row = rows[z]; + + // check for cache type presence + if (row.indexOf("images/wpttypes") == -1) { + continue; + } + + try { + final Matcher matcherGuidAndDisabled = patternGuidAndDisabled.matcher(row); + + while (matcherGuidAndDisabled.find()) { + if (matcherGuidAndDisabled.groupCount() > 0) { + guids.add(matcherGuidAndDisabled.group(1)); + + cache.guid = matcherGuidAndDisabled.group(1); + if (matcherGuidAndDisabled.group(4) != null) { + cache.name = Html.fromHtml(matcherGuidAndDisabled.group(4).trim()).toString(); + } + if (matcherGuidAndDisabled.group(6) != null) { + cache.location = Html.fromHtml(matcherGuidAndDisabled.group(6).trim()).toString(); + } + + final String attr = matcherGuidAndDisabled.group(2); + if (attr != null) { + if (attr.contains("Strike")) { + cache.disabled = true; + } else { + cache.disabled = false; + } + + if (attr.contains("OldWarning")) { + cache.archived = true; + } else { + cache.archived = false; + } + } + } + } + } catch (Exception e) { + // failed to parse GUID and/or Disabled + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse GUID and/or Disabled data"); + } + + if (settings.excludeDisabled == 1 && (cache.disabled || cache.archived)) { + // skip disabled and archived caches + cache = null; + continue; + } + + String inventoryPre = null; + + // GC* code + try { + final Matcher matcherCode = patternCode.matcher(row); + while (matcherCode.find()) { + if (matcherCode.groupCount() > 0) { + cache.geocode = matcherCode.group(1).toUpperCase(); + } + } + } catch (Exception e) { + // failed to parse code + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache code"); + } + + // cache type + try { + final Matcher matcherCacheType = patternCacheType.matcher(row); + while (matcherCacheType.find()) { + if (matcherCacheType.groupCount() > 0) { + cache.type = cacheTypes.get(matcherCacheType.group(1).toLowerCase()); + } + } + } catch (Exception e) { + // failed to parse type + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache type"); + } + + // cache direction - image + if (settings.getLoadDirImg()) { - return gcCustomDateFormats.get(settings.getGcCustomDate()).parse(input); - } - catch (ParseException e) {} - } - - for (SimpleDateFormat format : gcCustomDateFormats.values()) - { - try - { - return format.parse(input); - } - catch (ParseException e) {} - } - - throw new ParseException("No matching pattern", 0); - } - - public void detectGcCustomDate() - { - final String host = "www.geocaching.com"; + try { + final Matcher matcherDirection = patternDirection.matcher(row); + while (matcherDirection.find()) { + if (matcherDirection.groupCount() > 0) { + cache.directionImg = matcherDirection.group(1); + } + } + } catch (Exception e) { + // failed to parse direction image + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache direction image"); + } + } + + // cache inventory + try { + final Matcher matcherTbs = patternTbs.matcher(row); + while (matcherTbs.find()) { + if (matcherTbs.groupCount() > 0) { + cache.inventoryItems = Integer.parseInt(matcherTbs.group(1)); + inventoryPre = matcherTbs.group(2); + } + } + } catch (Exception e) { + // failed to parse inventory + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache inventory (1)"); + } + + if (StringUtils.isNotBlank(inventoryPre)) { + try { + final Matcher matcherTbsInside = patternTbsInside.matcher(inventoryPre); + while (matcherTbsInside.find()) { + if (matcherTbsInside.groupCount() == 2 && matcherTbsInside.group(2) != null) { + final String inventoryItem = matcherTbsInside.group(2).toLowerCase(); + if (inventoryItem.equals("premium member only cache")) { + continue; + } else { + if (cache.inventoryItems <= 0) { + cache.inventoryItems = 1; + } + } + } + } + } catch (Exception e) { + // failed to parse cache inventory info + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache inventory info"); + } + } + + // premium cache + if (row.indexOf("/images/small_profile.gif") != -1) { + cache.members = true; + } else { + cache.members = false; + } + + // found it + if (row.indexOf("/images/icons/icon_smile") != -1) { + cache.found = true; + } else { + cache.found = false; + } + + // own it + if (row.indexOf("/images/silk/star.png") != -1) { + cache.own = true; + } else { + cache.own = false; + } + + // id + try { + final Matcher matcherId = patternId.matcher(row); + while (matcherId.find()) { + if (matcherId.groupCount() > 0) { + cache.cacheId = matcherId.group(1); + cids.add(cache.cacheId); + } + } + } catch (Exception e) { + // failed to parse cache id + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache id"); + } + + // favourite count + try { + final Matcher matcherFavourite = patternFavourite.matcher(row); + while (matcherFavourite.find()) { + if (matcherFavourite.groupCount() > 0) { + cache.favouriteCnt = Integer.parseInt(matcherFavourite.group(1)); + } + } + } catch (Exception e) { + // failed to parse favourite count + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse favourite count"); + } + + if (cache.nameSp == null) { + cache.nameSp = (new Spannable.Factory()).newSpannable(cache.name); + if (cache.disabled || cache.archived) { // strike + cache.nameSp.setSpan(new StrikethroughSpan(), 0, cache.nameSp.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + caches.cacheList.add(cache); + } + + // total caches found + try { + final Matcher matcherTotalCnt = patternTotalCnt.matcher(page); + while (matcherTotalCnt.find()) { + if (matcherTotalCnt.groupCount() > 0) { + if (matcherTotalCnt.group(1) != null) { + caches.totalCnt = Integer.valueOf(matcherTotalCnt.group(1)); + } + } + } + } catch (Exception e) { + // failed to parse cache count + Log.w(cgSettings.tag, "cgeoBase.parseSearch: Failed to parse cache count"); + } + + if (thread != null && recaptchaChallenge != null) { + if (thread.getText() == null) { + thread.waitForUser(); + } + + recaptchaText = thread.getText(); + } + + if (cids.size() > 0 && (recaptchaChallenge == null || (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)))) { + Log.i(cgSettings.tag, "Trying to get .loc for " + cids.size() + " caches"); + + try { + // get coordinates for parsed caches + final String host = "www.geocaching.com"; + final String path = "/seek/nearest.aspx"; + final StringBuilder params = new StringBuilder(); + params.append("__EVENTTARGET=&__EVENTARGUMENT="); + if (ArrayUtils.isNotEmpty(caches.viewstates)) { + params.append("&__VIEWSTATE="); + params.append(urlencode_rfc3986(caches.viewstates[0])); + if (caches.viewstates.length > 1) { + for (int i = 1; i < caches.viewstates.length; i++) { + params.append("&__VIEWSTATE" + i + "="); + params.append(urlencode_rfc3986(caches.viewstates[i])); + } + params.append("&__VIEWSTATEFIELDCOUNT=" + caches.viewstates.length); + } + } + for (String cid : cids) { + params.append("&CID="); + params.append(urlencode_rfc3986(cid)); + } + + if (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)) { + params.append("&recaptcha_challenge_field="); + params.append(urlencode_rfc3986(recaptchaChallenge)); + params.append("&recaptcha_response_field="); + params.append(urlencode_rfc3986(recaptchaText)); + } + params.append("&ctl00%24ContentBody%24uxDownloadLoc=Download+Waypoints"); + + final String coordinates = request(false, host, path, "POST", params.toString(), 0, true).getData(); + + if (StringUtils.isNotBlank(coordinates)) { + if (coordinates.indexOf("You have not agreed to the license agreement. The license agreement is required before you can start downloading GPX or LOC files from Geocaching.com") > -1) { + Log.i(cgSettings.tag, "User has not agreed to the license agreement. Can\'t download .loc file."); + + caches.error = errorRetrieve.get(-7); + + return caches; + } + } + + LocParser.parseLoc(caches, coordinates); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.parseSearch.CIDs: " + e.toString()); + } + } + + // get direction images + if (settings.getLoadDirImg()) + { + for (cgCache oneCache : caches.cacheList) { + if (oneCache.coords == null && oneCache.directionImg != null) { + cgDirectionImg.getDrawable(oneCache.geocode, oneCache.directionImg); + } + } + } + + // get ratings + if (guids.size() > 0) { + Log.i(cgSettings.tag, "Trying to get ratings for " + cids.size() + " caches"); + + try { + final Map<String, cgRating> ratings = getRating(guids, null); + + if (CollectionUtils.isNotEmpty(ratings)) { + // save found cache coordinates + for (cgCache oneCache : caches.cacheList) { + if (ratings.containsKey(oneCache.guid)) { + cgRating thisRating = ratings.get(oneCache.guid); + + oneCache.rating = thisRating.rating; + oneCache.votes = thisRating.votes; + oneCache.myVote = thisRating.myVote; + } + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.parseSearch.GCvote: " + e.toString()); + } + } + + return caches; + } + + public static cgCacheWrap parseMapJSON(String url, String data) { + if (StringUtils.isEmpty(data)) { + Log.e(cgSettings.tag, "cgeoBase.parseMapJSON: No page given"); + return null; + } + + final cgCacheWrap caches = new cgCacheWrap(); + caches.url = url; + + try { + final JSONObject yoDawg = new JSONObject(data); + final String json = yoDawg.getString("d"); + + if (StringUtils.isBlank(json)) { + Log.e(cgSettings.tag, "cgeoBase.parseMapJSON: No JSON inside JSON"); + return null; + } + + final JSONObject dataJSON = new JSONObject(json); + final JSONObject extra = dataJSON.getJSONObject("cs"); + if (extra != null && extra.length() > 0) { + int count = extra.getInt("count"); + + if (count > 0 && extra.has("cc")) { + final JSONArray cachesData = extra.getJSONArray("cc"); + if (cachesData != null && cachesData.length() > 0) { + JSONObject oneCache = null; + for (int i = 0; i < count; i++) { + oneCache = cachesData.getJSONObject(i); + if (oneCache == null) { + break; + } + + final cgCache cacheToAdd = new cgCache(); + cacheToAdd.reliableLatLon = false; + cacheToAdd.geocode = oneCache.getString("gc"); + cacheToAdd.coords = new Geopoint(oneCache.getDouble("lat"), oneCache.getDouble("lon")); + cacheToAdd.name = oneCache.getString("nn"); + cacheToAdd.found = oneCache.getBoolean("f"); + cacheToAdd.own = oneCache.getBoolean("o"); + cacheToAdd.disabled = !oneCache.getBoolean("ia"); + int ctid = oneCache.getInt("ctid"); + if (ctid == 2) { + cacheToAdd.type = "traditional"; + } else if (ctid == 3) { + cacheToAdd.type = "multi"; + } else if (ctid == 4) { + cacheToAdd.type = "virtual"; + } else if (ctid == 5) { + cacheToAdd.type = "letterbox"; + } else if (ctid == 6) { + cacheToAdd.type = "event"; + } else if (ctid == 8) { + cacheToAdd.type = "mystery"; + } else if (ctid == 11) { + cacheToAdd.type = "webcam"; + } else if (ctid == 13) { + cacheToAdd.type = "cito"; + } else if (ctid == 137) { + cacheToAdd.type = "earth"; + } else if (ctid == 453) { + cacheToAdd.type = "mega"; + } else if (ctid == 1858) { + cacheToAdd.type = "wherigo"; + } else if (ctid == 3653) { + cacheToAdd.type = "lost"; + } + + caches.cacheList.add(cacheToAdd); + } + } + } else { + Log.w(cgSettings.tag, "There are no caches in viewport"); + } + caches.totalCnt = caches.cacheList.size(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.parseMapJSON: " + e.toString()); + } + + return caches; + } + + public cgCacheWrap parseCache(String page, int reason) { + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.parseCache: No page given"); + return null; + } + + final cgCacheWrap caches = new cgCacheWrap(); + final cgCache cache = new cgCache(); + + if (page.indexOf("Cache is Unpublished") > -1) { + caches.error = "cache was unpublished"; + return caches; + } + + if (page.indexOf("Sorry, the owner of this listing has made it viewable to Premium Members only.") != -1) { + caches.error = "requested cache is for premium members only"; + return caches; + } + + if (page.indexOf("has chosen to make this cache listing visible to Premium Members only.") != -1) { + caches.error = "requested cache is for premium members only"; + return caches; + } + + if (page.indexOf("<li>This cache is temporarily unavailable.") != -1) { + cache.disabled = true; + } else { + cache.disabled = false; + } + + if (page.indexOf("<li>This cache has been archived,") != -1) { + cache.archived = true; + } else { + cache.archived = false; + } + + if (page.indexOf("<p class=\"Warning\">This is a Premium Member Only cache.</p>") != -1) { + cache.members = true; + } else { + cache.members = false; + } + + cache.reason = reason; + + // cache geocode + try { + final Matcher matcherGeocode = patternGeocode.matcher(page); + if (matcherGeocode.find() && matcherGeocode.groupCount() > 0) { + cache.geocode = getMatch(matcherGeocode.group(1)); + } + } catch (Exception e) { + // failed to parse cache geocode + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache geocode"); + } + + // cache id + try { + final Matcher matcherCacheId = patternCacheId.matcher(page); + if (matcherCacheId.find() && matcherCacheId.groupCount() > 0) { + cache.cacheId = getMatch(matcherCacheId.group(1)); + } + } catch (Exception e) { + // failed to parse cache id + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache id"); + } + + // cache guid + try { + final Matcher matcherCacheGuid = patternCacheGuid.matcher(page); + if (matcherCacheGuid.find() && matcherCacheGuid.groupCount() > 0) { + cache.guid = getMatch(matcherCacheGuid.group(1)); + } + } catch (Exception e) { + // failed to parse cache guid + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache guid"); + } + + // name + try { + final Matcher matcherName = patternName.matcher(page); + if (matcherName.find() && matcherName.groupCount() > 0) { + cache.name = Html.fromHtml(matcherName.group(1)).toString(); + } + } catch (Exception e) { + // failed to parse cache name + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache name"); + } + + // owner real name + try { + final Matcher matcherOwnerReal = patternOwnerReal.matcher(page); + if (matcherOwnerReal.find() && matcherOwnerReal.groupCount() > 0) { + cache.ownerReal = URLDecoder.decode(matcherOwnerReal.group(1)); + } + } catch (Exception e) { + // failed to parse owner real name + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache owner real name"); + } + + final String username = settings.getUsername(); + if (cache.ownerReal != null && username != null && cache.ownerReal.equalsIgnoreCase(username)) { + cache.own = true; + } + + int pos = -1; + String tableInside = page; + + pos = tableInside.indexOf("id=\"cacheDetails\""); + if (pos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseCache: ID \"cacheDetails\" not found on page"); + return null; + } + + tableInside = tableInside.substring(pos); + + pos = tableInside.indexOf("<div class=\"CacheInformationTable\""); + if (pos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseCache: ID \"CacheInformationTable\" not found on page"); + return null; + } + + tableInside = tableInside.substring(0, pos); + + if (StringUtils.isNotBlank(tableInside)) { + // cache terrain + try { + final Matcher matcherTerrain = patternTerrain.matcher(tableInside); + if (matcherTerrain.find() && matcherTerrain.groupCount() > 0) { + cache.terrain = new Float(Pattern.compile("_").matcher(matcherTerrain.group(1)).replaceAll(".")); + } + } catch (Exception e) { + // failed to parse terrain + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache terrain"); + } + + // cache difficulty + try { + final Matcher matcherDifficulty = patternDifficulty.matcher(tableInside); + if (matcherDifficulty.find() && matcherDifficulty.groupCount() > 0) { + cache.difficulty = new Float(Pattern.compile("_").matcher(matcherDifficulty.group(1)).replaceAll(".")); + } + } catch (Exception e) { + // failed to parse difficulty + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache difficulty"); + } + + // owner + try { + final Matcher matcherOwner = patternOwner.matcher(tableInside); + if (matcherOwner.find() && matcherOwner.groupCount() > 0) { + cache.owner = Html.fromHtml(matcherOwner.group(2)).toString(); + } + } catch (Exception e) { + // failed to parse owner + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache owner"); + } + + // hidden + try { + final Matcher matcherHidden = patternHidden.matcher(tableInside); + if (matcherHidden.find() && matcherHidden.groupCount() > 0) { + cache.hidden = parseGcCustomDate(matcherHidden.group(1)); + } + } catch (ParseException e) { + // failed to parse cache hidden date + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache hidden date"); + } + + if (cache.hidden == null) { + // event date + try { + final Matcher matcherHiddenEvent = patternHiddenEvent.matcher(tableInside); + if (matcherHiddenEvent.find() && matcherHiddenEvent.groupCount() > 0) { + cache.hidden = parseGcCustomDate(matcherHiddenEvent.group(1)); + } + } catch (ParseException e) { + // failed to parse cache event date + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache event date"); + } + } + + // favourite + try { + final Matcher matcherFavourite = patternFavourite.matcher(tableInside); + if (matcherFavourite.find() && matcherFavourite.groupCount() > 0) { + cache.favouriteCnt = Integer.parseInt(matcherFavourite.group(1)); + } + } catch (Exception e) { + // failed to parse favourite count + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse favourite count"); + } + + // cache size + try { + final Matcher matcherSize = patternSize.matcher(tableInside); + if (matcherSize.find() && matcherSize.groupCount() > 0) { + cache.size = getMatch(matcherSize.group(1)).toLowerCase(); + } + } catch (Exception e) { + // failed to parse size + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache size"); + } + } + + // cache found + cache.found = patternFound.matcher(page).find() || patternFoundAlternative.matcher(page).find(); + + // cache type + try { + final Matcher matcherType = patternType.matcher(page); + if (matcherType.find() && matcherType.groupCount() > 0) { + cache.type = cacheTypes.get(matcherType.group(1).toLowerCase()); + } + } catch (Exception e) { + // failed to parse type + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache type"); + } + + // on watchlist + try { + final Matcher matcher = patternOnWatchlist.matcher(page); + cache.onWatchlist = matcher.find(); + } catch (Exception e) { + // failed to parse watchlist state + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse watchlist state"); + } + + // latitude and logitude + try { + final Matcher matcherLatLon = patternLatLon.matcher(page); + if (matcherLatLon.find() && matcherLatLon.groupCount() > 0) { + cache.latlon = getMatch(matcherLatLon.group(2)); // first is <b> + + Map<String, Object> tmp = cgBase.parseLatlon(cache.latlon); + if (tmp.size() > 0) { + cache.coords = new Geopoint((Double) tmp.get("latitude"), (Double) tmp.get("longitude")); + cache.latitudeString = (String) tmp.get("latitudeString"); + cache.longitudeString = (String) tmp.get("longitudeString"); + cache.reliableLatLon = true; + } + tmp = null; + } + } catch (Exception e) { + // failed to parse latitude and/or longitude + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache coordinates"); + } + + // cache location + try { + final Matcher matcherLocation = patternLocation.matcher(page); + if (matcherLocation.find() && matcherLocation.groupCount() > 0) { + cache.location = getMatch(matcherLocation.group(1)); + } + } catch (Exception e) { + // failed to parse location + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache location"); + } + + // cache hint + try { + final Matcher matcherHint = patternHint.matcher(page); + if (matcherHint.find() && matcherHint.groupCount() > 2 && matcherHint.group(3) != null) { + // replace linebreak and paragraph tags + String hint = Pattern.compile("<(br|p)[^>]*>").matcher(matcherHint.group(3)).replaceAll("\n"); + if (hint != null) { + cache.hint = hint.replaceAll(Pattern.quote("</p>"), "").trim(); + } + } + } catch (Exception e) { + // failed to parse hint + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache hint"); + } + + checkFields(cache); + /* + * // short info debug + * Log.d(cgSettings.tag, "gc-code: " + cache.geocode); + * Log.d(cgSettings.tag, "id: " + cache.cacheid); + * Log.d(cgSettings.tag, "guid: " + cache.guid); + * Log.d(cgSettings.tag, "name: " + cache.name); + * Log.d(cgSettings.tag, "terrain: " + cache.terrain); + * Log.d(cgSettings.tag, "difficulty: " + cache.difficulty); + * Log.d(cgSettings.tag, "owner: " + cache.owner); + * Log.d(cgSettings.tag, "owner (real): " + cache.ownerReal); + * Log.d(cgSettings.tag, "hidden: " + dateOutShort.format(cache.hidden)); + * Log.d(cgSettings.tag, "favorite: " + cache.favouriteCnt); + * Log.d(cgSettings.tag, "size: " + cache.size); + * if (cache.found) { + * Log.d(cgSettings.tag, "found!"); + * } else { + * Log.d(cgSettings.tag, "not found"); + * } + * Log.d(cgSettings.tag, "type: " + cache.type); + * Log.d(cgSettings.tag, "latitude: " + String.format("%.6f", cache.latitude)); + * Log.d(cgSettings.tag, "longitude: " + String.format("%.6f", cache.longitude)); + * Log.d(cgSettings.tag, "location: " + cache.location); + * Log.d(cgSettings.tag, "hint: " + cache.hint); + */ + + // cache personal note + try { + final Matcher matcherPersonalNote = patternPersonalNote.matcher(page); + if (matcherPersonalNote.find() && matcherPersonalNote.groupCount() > 0) { + cache.personalNote = getMatch(matcherPersonalNote.group(1)); + } + } catch (Exception e) { + // failed to parse cache personal note + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache personal note"); + } + + // cache short description + try { + final Matcher matcherDescShort = patternDescShort.matcher(page); + if (matcherDescShort.find() && matcherDescShort.groupCount() > 0) { + cache.shortdesc = getMatch(matcherDescShort.group(1)); + } + } catch (Exception e) { + // failed to parse short description + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache short description"); + } + + // cache description + try { + final Matcher matcherDesc = patternDesc.matcher(page); + if (matcherDesc.find() && matcherDesc.groupCount() > 0) { + cache.description = getMatch(matcherDesc.group(1)); + } + } catch (Exception e) { + // failed to parse short description + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache description"); + } + + // cache attributes + try { + final Matcher matcherAttributes = patternAttributes.matcher(page); + if (matcherAttributes.find() && matcherAttributes.groupCount() > 0) { + final String attributesPre = matcherAttributes.group(1); + final Matcher matcherAttributesInside = patternAttributesInside.matcher(attributesPre); + + while (matcherAttributesInside.find()) { + if (matcherAttributesInside.groupCount() > 1 && matcherAttributesInside.group(2).equalsIgnoreCase("blank") != true) { + if (cache.attributes == null) { + cache.attributes = new ArrayList<String>(); + } + // by default, use the tooltip of the attribute + String attribute = matcherAttributesInside.group(2).toLowerCase(); + + // if the image name can be recognized, use the image name as attribute + String imageName = matcherAttributesInside.group(1).trim(); + if (imageName.length() > 0) { + int start = imageName.lastIndexOf('/'); + int end = imageName.lastIndexOf('.'); + if (start >= 0 && end >= 0) { + attribute = imageName.substring(start + 1, end).replace('-', '_').toLowerCase(); + } + } + cache.attributes.add(attribute); + } + } + } + } catch (Exception e) { + // failed to parse cache attributes + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache attributes"); + } + + // cache spoilers + try { + final Matcher matcherSpoilers = patternSpoilers.matcher(page); + if (matcherSpoilers.find() && matcherSpoilers.groupCount() > 0) { + final String spoilersPre = matcherSpoilers.group(1); + final Matcher matcherSpoilersInside = patternSpoilersInside.matcher(spoilersPre); + + while (matcherSpoilersInside.find()) { + if (matcherSpoilersInside.groupCount() > 0) { + final cgImage spoiler = new cgImage(); + spoiler.url = matcherSpoilersInside.group(1); + + if (matcherSpoilersInside.group(2) != null) { + spoiler.title = matcherSpoilersInside.group(2); + } + if (matcherSpoilersInside.group(4) != null) { + spoiler.description = matcherSpoilersInside.group(4); + } + + if (cache.spoilers == null) { + cache.spoilers = new ArrayList<cgImage>(); + } + cache.spoilers.add(spoiler); + } + } + } + } catch (Exception e) { + // failed to parse cache spoilers + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache spoilers"); + } + + // cache inventory + try { + cache.inventoryItems = 0; + + final Matcher matcherInventory = patternInventory.matcher(page); + if (matcherInventory.find()) { + if (cache.inventory == null) { + cache.inventory = new ArrayList<cgTrackable>(); + } + + if (matcherInventory.groupCount() > 1) { + final String inventoryPre = matcherInventory.group(2); + + if (StringUtils.isNotBlank(inventoryPre)) { + final Matcher matcherInventoryInside = patternInventoryInside.matcher(inventoryPre); + + while (matcherInventoryInside.find()) { + if (matcherInventoryInside.groupCount() > 0) { + final cgTrackable inventoryItem = new cgTrackable(); + inventoryItem.guid = matcherInventoryInside.group(1); + inventoryItem.name = matcherInventoryInside.group(2); + + cache.inventory.add(inventoryItem); + cache.inventoryItems++; + } + } + } + } + } + } catch (Exception e) { + // failed to parse cache inventory + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache inventory (2)"); + } + + // cache logs counts + try + { + final Matcher matcherLogCounts = patternCountLogs.matcher(page); + + if (matcherLogCounts.find()) + { + final Matcher matcherLog = patternCountLog.matcher(matcherLogCounts.group(1)); + + while (matcherLog.find()) + { + String typeStr = matcherLog.group(1); + String countStr = matcherLog.group(2); + + if (StringUtils.isNotBlank(typeStr) + && logTypes.containsKey(typeStr.toLowerCase()) + && StringUtils.isNotBlank(countStr)) + { + cache.logCounts.put(logTypes.get(typeStr.toLowerCase()), Integer.parseInt(countStr)); + } + } + } + } catch (Exception e) + { + // failed to parse logs + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache log count"); + } + + // cache logs + try + { + /* + * 1- Author + * 2- Finds-count + * 3- Log type image name (e.g. "icon_smile") + * 4- Type string (e.g. "Found it") + * 5- Date string (e.g. "04/28/2010") + * 6- Log text + * 7- The rest (e.g. log-images, maybe faster) + */ + final Matcher matcherLog = patternLog.matcher(page);//(matcherLogs.group(1)); + + while (matcherLog.find()) + { + final cgLog logDone = new cgLog(); + + final String logIconName = matcherLog.group(3).toLowerCase(); + if (logTypes.containsKey(logIconName)) + { + logDone.type = logTypes.get(logIconName); + } + else + { + logDone.type = logTypes.get("icon_note"); + } + + try + { + logDone.date = parseGcCustomDate(matcherLog.group(5)).getTime(); + } catch (ParseException e) + { + Log.w(cgSettings.tag, "Failed to parse log date."); + } + + logDone.author = Html.fromHtml(matcherLog.group(1)).toString(); + + if (null != matcherLog.group(2)) + { + logDone.found = Integer.parseInt(matcherLog.group(2).replaceAll(",", "")); + } + + logDone.log = matcherLog.group(6); + + final Matcher matcherImg = patternLogImgs.matcher(matcherLog.group(7)); + while (matcherImg.find()) + { + final cgImage logImage = new cgImage(); + logImage.url = matcherImg.group(1); + logImage.title = matcherImg.group(2); + if (logDone.logImages == null) + { + logDone.logImages = new ArrayList<cgImage>(); + } + logDone.logImages.add(logImage); + } + + if (null == cache.logs) + { + cache.logs = new ArrayList<cgLog>(); + } + cache.logs.add(logDone); + } + } catch (Exception e) + { + // failed to parse logs + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache logs", e); + } + + int wpBegin = 0; + int wpEnd = 0; + + wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">"); + if (wpBegin != -1) { // parse waypoints + final Pattern patternWpType = Pattern.compile("\\/wpttypes\\/sm\\/(.+)\\.jpg", Pattern.CASE_INSENSITIVE); + final Pattern patternWpPrefixOrLookupOrLatlon = Pattern.compile(">([^<]*<[^>]+>)?([^<]+)(<[^>]+>[^<]*)?<\\/td>", Pattern.CASE_INSENSITIVE); + final Pattern patternWpName = Pattern.compile(">[^<]*<a[^>]+>([^<]*)<\\/a>", Pattern.CASE_INSENSITIVE); + final Pattern patternWpNote = Pattern.compile("colspan=\"6\">(.*)<\\/td>", Pattern.CASE_INSENSITIVE); + + String wpList = page.substring(wpBegin); + + wpEnd = wpList.indexOf("</p>"); + if (wpEnd > -1 && wpEnd <= wpList.length()) { + wpList = wpList.substring(0, wpEnd); + } + + if (wpList.indexOf("No additional waypoints to display.") == -1) { + wpEnd = wpList.indexOf("</table>"); + wpList = wpList.substring(0, wpEnd); + + wpBegin = wpList.indexOf("<tbody>"); + wpEnd = wpList.indexOf("</tbody>"); + if (wpBegin >= 0 && wpEnd >= 0 && wpEnd <= wpList.length()) { + wpList = wpList.substring(wpBegin + 7, wpEnd); + } + + final String[] wpItems = wpList.split("<tr"); + + String[] wp; + for (int j = 1; j < wpItems.length; j++) { + final cgWaypoint waypoint = new cgWaypoint(); + + wp = wpItems[j].split("<td"); + + // waypoint type + try { + final Matcher matcherWpType = patternWpType.matcher(wp[3]); + if (matcherWpType.find() && matcherWpType.groupCount() > 0) { + waypoint.type = matcherWpType.group(1).trim(); + } + } catch (Exception e) { + // failed to parse type + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint type"); + } + + // waypoint prefix + try { + final Matcher matcherWpPrefix = patternWpPrefixOrLookupOrLatlon.matcher(wp[4]); + if (matcherWpPrefix.find() && matcherWpPrefix.groupCount() > 1) { + waypoint.prefix = matcherWpPrefix.group(2).trim(); + } + } catch (Exception e) { + // failed to parse prefix + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint prefix"); + } + + // waypoint lookup + try { + final Matcher matcherWpLookup = patternWpPrefixOrLookupOrLatlon.matcher(wp[5]); + if (matcherWpLookup.find() && matcherWpLookup.groupCount() > 1) { + waypoint.lookup = matcherWpLookup.group(2).trim(); + } + } catch (Exception e) { + // failed to parse lookup + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint lookup"); + } + + // waypoint name + try { + final Matcher matcherWpName = patternWpName.matcher(wp[6]); + while (matcherWpName.find()) { + if (matcherWpName.groupCount() > 0) { + waypoint.name = matcherWpName.group(1); + if (StringUtils.isNotBlank(waypoint.name)) { + waypoint.name = waypoint.name.trim(); + } + } + if (matcherWpName.find() && matcherWpName.groupCount() > 0) { + waypoint.name = matcherWpName.group(1).trim(); + } + } + } catch (Exception e) { + // failed to parse name + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint name"); + } + + // waypoint latitude and logitude + try { + final Matcher matcherWpLatLon = patternWpPrefixOrLookupOrLatlon.matcher(wp[7]); + if (matcherWpLatLon.find() && matcherWpLatLon.groupCount() > 1) { + waypoint.latlon = Html.fromHtml(matcherWpLatLon.group(2)).toString(); + + final Map<String, Object> tmp = cgBase.parseLatlon(waypoint.latlon); + if (tmp.size() > 0) { + waypoint.coords = new Geopoint((Double) tmp.get("latitude"), (Double) tmp.get("longitude")); + waypoint.latitudeString = (String) tmp.get("latitudeString"); + waypoint.longitudeString = (String) tmp.get("longitudeString"); + } + } + } catch (Exception e) { + // failed to parse latitude and/or longitude + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint coordinates"); + } + + j++; + if (wpItems.length > j) { + wp = wpItems[j].split("<td"); + } + + // waypoint note + try { + final Matcher matcherWpNote = patternWpNote.matcher(wp[3]); + if (matcherWpNote.find() && matcherWpNote.groupCount() > 0) { + waypoint.note = matcherWpNote.group(1).trim(); + } + } catch (Exception e) { + // failed to parse note + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse waypoint note"); + } + + if (cache.waypoints == null) { + cache.waypoints = new ArrayList<cgWaypoint>(); + } + cache.waypoints.add(waypoint); + } + } + } + + if (cache.coords != null) { + cache.elevation = getElevation(cache.coords); + } + + final cgRating rating = getRating(cache.guid, cache.geocode); + if (rating != null) { + cache.rating = rating.rating; + cache.votes = rating.votes; + cache.myVote = rating.myVote; + } + + cache.updated = System.currentTimeMillis(); + cache.detailedUpdate = System.currentTimeMillis(); + cache.detailed = true; + caches.cacheList.add(cache); + + return caches; + } + + private static void checkFields(cgCache cache) { + if (StringUtils.isBlank(cache.geocode)) { + Log.w(cgSettings.tag, "geo code not parsed correctly"); + } + if (StringUtils.isBlank(cache.name)) { + Log.w(cgSettings.tag, "name not parsed correctly"); + } + if (StringUtils.isBlank(cache.guid)) { + Log.w(cgSettings.tag, "guid not parsed correctly"); + } + if (cache.terrain == null || cache.terrain == 0.0) { + Log.w(cgSettings.tag, "terrain not parsed correctly"); + } + if (cache.difficulty == null || cache.difficulty == 0.0) { + Log.w(cgSettings.tag, "difficulty not parsed correctly"); + } + if (StringUtils.isBlank(cache.owner)) { + Log.w(cgSettings.tag, "owner not parsed correctly"); + } + if (StringUtils.isBlank(cache.ownerReal)) { + Log.w(cgSettings.tag, "owner real not parsed correctly"); + } + if (cache.hidden == null) { + Log.w(cgSettings.tag, "hidden not parsed correctly"); + } + if (cache.favouriteCnt == null) { + Log.w(cgSettings.tag, "favoriteCount not parsed correctly"); + } + if (StringUtils.isBlank(cache.size)) { + Log.w(cgSettings.tag, "size not parsed correctly"); + } + if (StringUtils.isBlank(cache.type)) { + Log.w(cgSettings.tag, "type not parsed correctly"); + } + if (cache.coords == null) { + Log.w(cgSettings.tag, "coordinates not parsed correctly"); + } + if (StringUtils.isBlank(cache.location)) { + Log.w(cgSettings.tag, "location not parsed correctly"); + } + } + + private static String getMatch(String match) { + // creating a new String via String constructor is necessary here!! + return new String(match.trim()); + // Java copies the whole page String, when matching with regular expressions + // later this would block the garbage collector, as we only need tiny parts of the page + // see http://developer.android.com/reference/java/lang/String.html#backing_array + + // And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler! + } + + public Date parseGcCustomDate(String input) + throws ParseException + { + if (StringUtils.isBlank(input)) + { + throw new ParseException("Input is null", 0); + } + + input = input.trim(); + + if (null != settings + //&& null != settings.getGcCustomDate() + && gcCustomDateFormats.containsKey(settings.getGcCustomDate())) + { + try + { + return gcCustomDateFormats.get(settings.getGcCustomDate()).parse(input); + } catch (ParseException e) { + } + } + + for (SimpleDateFormat format : gcCustomDateFormats.values()) + { + try + { + return format.parse(input); + } catch (ParseException e) { + } + } + + throw new ParseException("No matching pattern", 0); + } + + public void detectGcCustomDate() + { + final String host = "www.geocaching.com"; final String path = "/account/ManagePreferences.aspx"; final String result = request(false, host, path, "GET", null, false, false, false).getData(); @@ -1831,355 +1828,355 @@ public class cgBase { { settings.setGcCustomDate(matcher.group(1)); } - } - - public cgRating getRating(String guid, String geocode) { - List<String> guids = null; - List<String> geocodes = null; - - if (StringUtils.isNotBlank(guid)) { - guids = new ArrayList<String>(); - guids.add(guid); - } else if (StringUtils.isNotBlank(geocode)) { - geocodes = new ArrayList<String>(); - geocodes.add(geocode); - } else { - return null; - } - - final Map<String, cgRating> ratings = getRating(guids, geocodes); - if(ratings != null){ - for (Entry<String, cgRating> entry : ratings.entrySet()) { - return entry.getValue(); - } - } - - return null; - } - - public Map<String, cgRating> getRating(List<String> guids, List<String> geocodes) { - if (guids == null && geocodes == null) { - return null; - } - - final Map<String, cgRating> ratings = new HashMap<String, cgRating>(); - - try { - final Map<String, String> params = new HashMap<String, String>(); - if (settings.isLogin()) { - final Map<String, String> login = settings.getGCvoteLogin(); - if (login != null) { - params.put("userName", login.get("username")); - params.put("password", login.get("password")); - } - } - if (CollectionUtils.isNotEmpty(guids)) { - params.put("cacheIds", implode(",", guids.toArray())); - } else { - params.put("waypoints", implode(",", geocodes.toArray())); - } - params.put("version", "cgeo"); - final String votes = request(false, "gcvote.com", "/getVotes.php", "GET", params, false, false, false).getData(); - if (votes == null) { - return null; - } - - final Pattern patternLogIn = Pattern.compile("loggedIn='([^']+)'", Pattern.CASE_INSENSITIVE); - final Pattern patternGuid = Pattern.compile("cacheId='([^']+)'", Pattern.CASE_INSENSITIVE); - final Pattern patternRating = Pattern.compile("voteAvg='([0-9\\.]+)'", Pattern.CASE_INSENSITIVE); - final Pattern patternVotes = Pattern.compile("voteCnt='([0-9]+)'", Pattern.CASE_INSENSITIVE); - final Pattern patternVote = Pattern.compile("voteUser='([0-9\\.]+)'", Pattern.CASE_INSENSITIVE); - - String voteData = null; - final Pattern patternVoteElement = Pattern.compile("<vote ([^>]+)>", Pattern.CASE_INSENSITIVE); - final Matcher matcherVoteElement = patternVoteElement.matcher(votes); - while (matcherVoteElement.find()) { - if (matcherVoteElement.groupCount() > 0) { - voteData = matcherVoteElement.group(1); - } - - if (voteData == null) { - continue; - } - - String guid = null; - cgRating rating = new cgRating(); - boolean loggedIn = false; - - try { - final Matcher matcherGuid = patternGuid.matcher(voteData); - if (matcherGuid.find()) { - if (matcherGuid.groupCount() > 0) { - guid = (String) matcherGuid.group(1); - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse guid"); - } - - try { - final Matcher matcherLoggedIn = patternLogIn.matcher(votes); - if (matcherLoggedIn.find()) { - if (matcherLoggedIn.groupCount() > 0) { - if (matcherLoggedIn.group(1).equalsIgnoreCase("true")) { - loggedIn = true; - } - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse loggedIn"); - } - - try { - final Matcher matcherRating = patternRating.matcher(voteData); - if (matcherRating.find()) { - if (matcherRating.groupCount() > 0) { - rating.rating = Float.parseFloat(matcherRating.group(1)); - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse rating"); - } - - try { - final Matcher matcherVotes = patternVotes.matcher(voteData); - if (matcherVotes.find()) { - if (matcherVotes.groupCount() > 0) { - rating.votes = Integer.parseInt(matcherVotes.group(1)); - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse vote count"); - } - - if (loggedIn) { - try { - final Matcher matcherVote = patternVote.matcher(voteData); - if (matcherVote.find()) { - if (matcherVote.groupCount() > 0) { - rating.myVote = Float.parseFloat(matcherVote.group(1)); - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse user's vote"); - } - } - - if (StringUtils.isNotBlank(guid)) { - ratings.put(guid, rating); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.getRating: " + e.toString()); - } - - return ratings; - } - - public cgTrackable parseTrackable(String page) { - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.parseTrackable: No page given"); - return null; - } - - final cgTrackable trackable = new cgTrackable(); - - // trackable geocode - try { - final Matcher matcherGeocode = PATTERN_TRACKABLE_Geocode.matcher(page); - if (matcherGeocode.find() && matcherGeocode.groupCount() > 0) { - trackable.geocode = matcherGeocode.group(1).toUpperCase(); - } - } catch (Exception e) { - // failed to parse trackable geocode - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable geocode"); - } - - // trackable id - try { - final Matcher matcherTrackableId = PATTERN_TRACKABLE_TrackableId.matcher(page); - if (matcherTrackableId.find() && matcherTrackableId.groupCount() > 0) { - trackable.guid = matcherTrackableId.group(1); - } - } catch (Exception e) { - // failed to parse trackable id - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable id"); - } - - // trackable icon - try { - final Matcher matcherTrackableIcon = PATTERN_TRACKABLE_Icon.matcher(page); - if (matcherTrackableIcon.find() && matcherTrackableIcon.groupCount() > 0) { - trackable.iconUrl = matcherTrackableIcon.group(1); - } - } catch (Exception e) { - // failed to parse trackable icon - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable icon"); - } - - // trackable name - try { - final Matcher matcherName = PATTERN_TRACKABLE_Name.matcher(page); - if (matcherName.find() && matcherName.groupCount() > 1) { - trackable.name = matcherName.group(2); - } - } catch (Exception e) { - // failed to parse trackable name - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable name"); - } - - // trackable type - if (StringUtils.isNotBlank(trackable.name)) { - try { - final Matcher matcherType = PATTERN_TRACKABLE_Type.matcher(page); - if (matcherType.find() && matcherType.groupCount() > 0) { - trackable.type = matcherType.group(1); - } - } catch (Exception e) { - // failed to parse trackable type - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable type"); - } - } - - // trackable owner name - try { - final Matcher matcherOwner = PATTERN_TRACKABLE_Owner.matcher(page); - if (matcherOwner.find() && matcherOwner.groupCount() > 0) { - trackable.ownerGuid = matcherOwner.group(1); - trackable.owner = matcherOwner.group(2); - } - } catch (Exception e) { - // failed to parse trackable owner name - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable owner name"); - } - - // trackable origin - try { - final Matcher matcherOrigin = PATTERN_TRACKABLE_Origin.matcher(page); - if (matcherOrigin.find() && matcherOrigin.groupCount() > 0) { - trackable.origin = matcherOrigin.group(1); - } - } catch (Exception e) { - // failed to parse trackable origin - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable origin"); - } - - // trackable spotted - try { - final Matcher matcherSpottedCache = PATTERN_TRACKABLE_SpottedCache.matcher(page); - if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) { - trackable.spottedGuid = matcherSpottedCache.group(1); - trackable.spottedName = matcherSpottedCache.group(2); - trackable.spottedType = cgTrackable.SPOTTED_CACHE; - } - - final Matcher matcherSpottedUser = PATTERN_TRACKABLE_SpottedUser.matcher(page); - if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) { - trackable.spottedGuid = matcherSpottedUser.group(1); - trackable.spottedName = matcherSpottedUser.group(2); - trackable.spottedType = cgTrackable.SPOTTED_USER; - } - - final Matcher matcherSpottedUnknown = PATTERN_TRACKABLE_SpottedUnknown.matcher(page); - if (matcherSpottedUnknown.find()) { - trackable.spottedType = cgTrackable.SPOTTED_UNKNOWN; - } - - final Matcher matcherSpottedOwner = PATTERN_TRACKABLE_SpottedOwner.matcher(page); - if (matcherSpottedOwner.find()) { - trackable.spottedType = cgTrackable.SPOTTED_OWNER; - } - } catch (Exception e) { - // failed to parse trackable last known place - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable last known place"); - } - - // released - try { - final Matcher matcherReleased = PATTERN_TRACKABLE_Released.matcher(page); - if (matcherReleased.find() && matcherReleased.groupCount() > 0 && matcherReleased.group(1) != null) { - try { - if (trackable.released == null) { - trackable.released = dateTbIn1.parse(matcherReleased.group(1)); - } - } catch (Exception e) { - // - } - - try { - if (trackable.released == null) { - trackable.released = dateTbIn2.parse(matcherReleased.group(1)); - } - } catch (Exception e) { - // - } - } - } catch (Exception e) { - // failed to parse trackable released date - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable released date"); - } - - // trackable distance - try { - final Matcher matcherDistance = PATTERN_TRACKABLE_Distance.matcher(page); - if (matcherDistance.find() && matcherDistance.groupCount() > 0) { - try { - trackable.distance = DistanceParser.parseDistance(matcherDistance.group(1), settings.units); - } catch (NumberFormatException e) { - trackable.distance = null; - throw e; - } - } - } catch (Exception e) { - // failed to parse trackable distance - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable distance"); - } - - // trackable goal - try { - final Matcher matcherGoal = PATTERN_TRACKABLE_Goal.matcher(page); - if (matcherGoal.find() && matcherGoal.groupCount() > 0) { - trackable.goal = matcherGoal.group(1); - } - } catch (Exception e) { - // failed to parse trackable goal - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable goal"); - } - - // trackable details & image - try { - final Matcher matcherDetailsImage = PATTERN_TRACKABLE_DetailsImage.matcher(page); - if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) { - final String image = matcherDetailsImage.group(3); - final String details = matcherDetailsImage.group(4); - - if (image != null) { - trackable.image = image; - } - if (details != null) { - trackable.details = details; - } - } - } catch (Exception e) { - // failed to parse trackable details & image - Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable details & image"); - } - - // trackable logs - try - { - final Matcher matcherLogs = PATTERN_TRACKABLE_Log.matcher(page); - /* - 1. Type (img) - 2. Date - 3. Author - 4. Cache-GUID - 5. Cache-name - 6. Logtext - */ - while (matcherLogs.find()) - { - final cgLog logDone = new cgLog(); + } + + public cgRating getRating(String guid, String geocode) { + List<String> guids = null; + List<String> geocodes = null; + + if (StringUtils.isNotBlank(guid)) { + guids = new ArrayList<String>(); + guids.add(guid); + } else if (StringUtils.isNotBlank(geocode)) { + geocodes = new ArrayList<String>(); + geocodes.add(geocode); + } else { + return null; + } + + final Map<String, cgRating> ratings = getRating(guids, geocodes); + if (ratings != null) { + for (Entry<String, cgRating> entry : ratings.entrySet()) { + return entry.getValue(); + } + } + + return null; + } + + public Map<String, cgRating> getRating(List<String> guids, List<String> geocodes) { + if (guids == null && geocodes == null) { + return null; + } + + final Map<String, cgRating> ratings = new HashMap<String, cgRating>(); + + try { + final Map<String, String> params = new HashMap<String, String>(); + if (settings.isLogin()) { + final Map<String, String> login = settings.getGCvoteLogin(); + if (login != null) { + params.put("userName", login.get("username")); + params.put("password", login.get("password")); + } + } + if (CollectionUtils.isNotEmpty(guids)) { + params.put("cacheIds", implode(",", guids.toArray())); + } else { + params.put("waypoints", implode(",", geocodes.toArray())); + } + params.put("version", "cgeo"); + final String votes = request(false, "gcvote.com", "/getVotes.php", "GET", params, false, false, false).getData(); + if (votes == null) { + return null; + } + + final Pattern patternLogIn = Pattern.compile("loggedIn='([^']+)'", Pattern.CASE_INSENSITIVE); + final Pattern patternGuid = Pattern.compile("cacheId='([^']+)'", Pattern.CASE_INSENSITIVE); + final Pattern patternRating = Pattern.compile("voteAvg='([0-9\\.]+)'", Pattern.CASE_INSENSITIVE); + final Pattern patternVotes = Pattern.compile("voteCnt='([0-9]+)'", Pattern.CASE_INSENSITIVE); + final Pattern patternVote = Pattern.compile("voteUser='([0-9\\.]+)'", Pattern.CASE_INSENSITIVE); + + String voteData = null; + final Pattern patternVoteElement = Pattern.compile("<vote ([^>]+)>", Pattern.CASE_INSENSITIVE); + final Matcher matcherVoteElement = patternVoteElement.matcher(votes); + while (matcherVoteElement.find()) { + if (matcherVoteElement.groupCount() > 0) { + voteData = matcherVoteElement.group(1); + } + + if (voteData == null) { + continue; + } + + String guid = null; + cgRating rating = new cgRating(); + boolean loggedIn = false; + + try { + final Matcher matcherGuid = patternGuid.matcher(voteData); + if (matcherGuid.find()) { + if (matcherGuid.groupCount() > 0) { + guid = (String) matcherGuid.group(1); + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse guid"); + } + + try { + final Matcher matcherLoggedIn = patternLogIn.matcher(votes); + if (matcherLoggedIn.find()) { + if (matcherLoggedIn.groupCount() > 0) { + if (matcherLoggedIn.group(1).equalsIgnoreCase("true")) { + loggedIn = true; + } + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse loggedIn"); + } + + try { + final Matcher matcherRating = patternRating.matcher(voteData); + if (matcherRating.find()) { + if (matcherRating.groupCount() > 0) { + rating.rating = Float.parseFloat(matcherRating.group(1)); + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse rating"); + } + + try { + final Matcher matcherVotes = patternVotes.matcher(voteData); + if (matcherVotes.find()) { + if (matcherVotes.groupCount() > 0) { + rating.votes = Integer.parseInt(matcherVotes.group(1)); + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse vote count"); + } + + if (loggedIn) { + try { + final Matcher matcherVote = patternVote.matcher(voteData); + if (matcherVote.find()) { + if (matcherVote.groupCount() > 0) { + rating.myVote = Float.parseFloat(matcherVote.group(1)); + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getRating: Failed to parse user's vote"); + } + } + + if (StringUtils.isNotBlank(guid)) { + ratings.put(guid, rating); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.getRating: " + e.toString()); + } + + return ratings; + } + + public cgTrackable parseTrackable(String page) { + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.parseTrackable: No page given"); + return null; + } + + final cgTrackable trackable = new cgTrackable(); + + // trackable geocode + try { + final Matcher matcherGeocode = PATTERN_TRACKABLE_Geocode.matcher(page); + if (matcherGeocode.find() && matcherGeocode.groupCount() > 0) { + trackable.geocode = matcherGeocode.group(1).toUpperCase(); + } + } catch (Exception e) { + // failed to parse trackable geocode + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable geocode"); + } + + // trackable id + try { + final Matcher matcherTrackableId = PATTERN_TRACKABLE_TrackableId.matcher(page); + if (matcherTrackableId.find() && matcherTrackableId.groupCount() > 0) { + trackable.guid = matcherTrackableId.group(1); + } + } catch (Exception e) { + // failed to parse trackable id + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable id"); + } + + // trackable icon + try { + final Matcher matcherTrackableIcon = PATTERN_TRACKABLE_Icon.matcher(page); + if (matcherTrackableIcon.find() && matcherTrackableIcon.groupCount() > 0) { + trackable.iconUrl = matcherTrackableIcon.group(1); + } + } catch (Exception e) { + // failed to parse trackable icon + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable icon"); + } + + // trackable name + try { + final Matcher matcherName = PATTERN_TRACKABLE_Name.matcher(page); + if (matcherName.find() && matcherName.groupCount() > 1) { + trackable.name = matcherName.group(2); + } + } catch (Exception e) { + // failed to parse trackable name + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable name"); + } + + // trackable type + if (StringUtils.isNotBlank(trackable.name)) { + try { + final Matcher matcherType = PATTERN_TRACKABLE_Type.matcher(page); + if (matcherType.find() && matcherType.groupCount() > 0) { + trackable.type = matcherType.group(1); + } + } catch (Exception e) { + // failed to parse trackable type + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable type"); + } + } + + // trackable owner name + try { + final Matcher matcherOwner = PATTERN_TRACKABLE_Owner.matcher(page); + if (matcherOwner.find() && matcherOwner.groupCount() > 0) { + trackable.ownerGuid = matcherOwner.group(1); + trackable.owner = matcherOwner.group(2); + } + } catch (Exception e) { + // failed to parse trackable owner name + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable owner name"); + } + + // trackable origin + try { + final Matcher matcherOrigin = PATTERN_TRACKABLE_Origin.matcher(page); + if (matcherOrigin.find() && matcherOrigin.groupCount() > 0) { + trackable.origin = matcherOrigin.group(1); + } + } catch (Exception e) { + // failed to parse trackable origin + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable origin"); + } + + // trackable spotted + try { + final Matcher matcherSpottedCache = PATTERN_TRACKABLE_SpottedCache.matcher(page); + if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) { + trackable.spottedGuid = matcherSpottedCache.group(1); + trackable.spottedName = matcherSpottedCache.group(2); + trackable.spottedType = cgTrackable.SPOTTED_CACHE; + } + + final Matcher matcherSpottedUser = PATTERN_TRACKABLE_SpottedUser.matcher(page); + if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) { + trackable.spottedGuid = matcherSpottedUser.group(1); + trackable.spottedName = matcherSpottedUser.group(2); + trackable.spottedType = cgTrackable.SPOTTED_USER; + } + + final Matcher matcherSpottedUnknown = PATTERN_TRACKABLE_SpottedUnknown.matcher(page); + if (matcherSpottedUnknown.find()) { + trackable.spottedType = cgTrackable.SPOTTED_UNKNOWN; + } + + final Matcher matcherSpottedOwner = PATTERN_TRACKABLE_SpottedOwner.matcher(page); + if (matcherSpottedOwner.find()) { + trackable.spottedType = cgTrackable.SPOTTED_OWNER; + } + } catch (Exception e) { + // failed to parse trackable last known place + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable last known place"); + } + + // released + try { + final Matcher matcherReleased = PATTERN_TRACKABLE_Released.matcher(page); + if (matcherReleased.find() && matcherReleased.groupCount() > 0 && matcherReleased.group(1) != null) { + try { + if (trackable.released == null) { + trackable.released = dateTbIn1.parse(matcherReleased.group(1)); + } + } catch (Exception e) { + // + } + + try { + if (trackable.released == null) { + trackable.released = dateTbIn2.parse(matcherReleased.group(1)); + } + } catch (Exception e) { + // + } + } + } catch (Exception e) { + // failed to parse trackable released date + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable released date"); + } + + // trackable distance + try { + final Matcher matcherDistance = PATTERN_TRACKABLE_Distance.matcher(page); + if (matcherDistance.find() && matcherDistance.groupCount() > 0) { + try { + trackable.distance = DistanceParser.parseDistance(matcherDistance.group(1), settings.units); + } catch (NumberFormatException e) { + trackable.distance = null; + throw e; + } + } + } catch (Exception e) { + // failed to parse trackable distance + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable distance"); + } + + // trackable goal + try { + final Matcher matcherGoal = PATTERN_TRACKABLE_Goal.matcher(page); + if (matcherGoal.find() && matcherGoal.groupCount() > 0) { + trackable.goal = matcherGoal.group(1); + } + } catch (Exception e) { + // failed to parse trackable goal + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable goal"); + } + + // trackable details & image + try { + final Matcher matcherDetailsImage = PATTERN_TRACKABLE_DetailsImage.matcher(page); + if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) { + final String image = matcherDetailsImage.group(3); + final String details = matcherDetailsImage.group(4); + + if (image != null) { + trackable.image = image; + } + if (details != null) { + trackable.details = details; + } + } + } catch (Exception e) { + // failed to parse trackable details & image + Log.w(cgSettings.tag, "cgeoBase.parseTrackable: Failed to parse trackable details & image"); + } + + // trackable logs + try + { + final Matcher matcherLogs = PATTERN_TRACKABLE_Log.matcher(page); + /* + * 1. Type (img) + * 2. Date + * 3. Author + * 4. Cache-GUID + * 5. Cache-name + * 6. Logtext + */ + while (matcherLogs.find()) + { + final cgLog logDone = new cgLog(); if (logTypes.containsKey(matcherLogs.group(1).toLowerCase())) { @@ -2190,1276 +2187,1277 @@ public class cgBase { logDone.type = logTypes.get("icon_note"); } - logDone.author = Html.fromHtml(matcherLogs.group(3)).toString(); - - try - { - logDone.date = parseGcCustomDate(matcherLogs.group(2)).getTime(); - } - catch (ParseException e) {} - - logDone.log = matcherLogs.group(6).trim(); - - if (matcherLogs.group(4) != null && matcherLogs.group(5) != null) - { - logDone.cacheGuid = matcherLogs.group(4); - logDone.cacheName = matcherLogs.group(5); - } - - trackable.logs.add(logDone); - } - } catch (Exception e) { - // failed to parse logs - Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache logs"); - } - - app.saveTrackable(trackable); - - return trackable; - } - - public static List<Integer> parseTypes(String page) { - if (StringUtils.isEmpty(page)) { - return null; - } - - final List<Integer> types = new ArrayList<Integer>(); - - final Pattern typeBoxPattern = Pattern.compile("<select name=\"ctl00\\$ContentBody\\$LogBookPanel1\\$ddLogType\" id=\"ctl00_ContentBody_LogBookPanel1_ddLogType\"[^>]*>" - + "(([^<]*<option[^>]*>[^<]+</option>)+)[^<]*</select>", Pattern.CASE_INSENSITIVE); - final Matcher typeBoxMatcher = typeBoxPattern.matcher(page); - String typesText = null; - if (typeBoxMatcher.find()) { - if (typeBoxMatcher.groupCount() > 0) { - typesText = typeBoxMatcher.group(1); - } - } - - if (typesText != null) { - final Pattern typePattern = Pattern.compile("<option( selected=\"selected\")? value=\"(\\d+)\">[^<]+</option>", Pattern.CASE_INSENSITIVE); - final Matcher typeMatcher = typePattern.matcher(typesText); - while (typeMatcher.find()) { - if (typeMatcher.groupCount() > 1) { - final int type = Integer.parseInt(typeMatcher.group(2)); - - if (type > 0) { - types.add(type); - } - } - } - } - - return types; - } - - public static List<cgTrackableLog> parseTrackableLog(String page) { - if (StringUtils.isEmpty(page)) { - return null; - } - - final List<cgTrackableLog> trackables = new ArrayList<cgTrackableLog>(); - - int startPos = -1; - int endPos = -1; - - startPos = page.indexOf("<table id=\"tblTravelBugs\""); - if (startPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: ID \"tblTravelBugs\" not found on page"); - return null; - } - - page = page.substring(startPos); // cut on <table - - endPos = page.indexOf("</table>"); - if (endPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: end of ID \"tblTravelBugs\" not found on page"); - return null; - } - - page = page.substring(0, endPos); // cut on </table> - - startPos = page.indexOf("<tbody>"); - if (startPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: tbody not found on page"); - return null; - } - - page = page.substring(startPos); // cut on <tbody> - - endPos = page.indexOf("</tbody>"); - if (endPos == -1) { - Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: end of tbody not found on page"); - return null; - } - - page = page.substring(0, endPos); // cut on </tbody> - - final Pattern trackablePattern = Pattern.compile("<tr id=\"ctl00_ContentBody_LogBookPanel1_uxTrackables_repTravelBugs_ctl[0-9]+_row\"[^>]*>" - + "[^<]*<td>[^<]*<a href=\"[^\"]+\">([A-Z0-9]+)</a>[^<]*</td>[^<]*<td>([^<]+)</td>[^<]*<td>" - + "[^<]*<select name=\"ctl00\\$ContentBody\\$LogBookPanel1\\$uxTrackables\\$repTravelBugs\\$ctl([0-9]+)\\$ddlAction\"[^>]*>" - + "([^<]*<option value=\"([0-9]+)(_[a-z]+)?\">[^<]+</option>)+" - + "[^<]*</select>[^<]*</td>[^<]*</tr>", Pattern.CASE_INSENSITIVE); - final Matcher trackableMatcher = trackablePattern.matcher(page); - while (trackableMatcher.find()) { - if (trackableMatcher.groupCount() > 0) { - final cgTrackableLog trackable = new cgTrackableLog(); - - if (trackableMatcher.group(1) != null) { - trackable.trackCode = trackableMatcher.group(1); - } else { - continue; - } - if (trackableMatcher.group(2) != null) { - trackable.name = Html.fromHtml(trackableMatcher.group(2)).toString(); - } else { - continue; - } - if (trackableMatcher.group(3) != null) { - trackable.ctl = Integer.valueOf(trackableMatcher.group(3)); - } else { - continue; - } - if (trackableMatcher.group(5) != null) { - trackable.id = Integer.valueOf(trackableMatcher.group(5)); - } else { - continue; - } - - Log.i(cgSettings.tag, "Trackable in inventory (#" + trackable.ctl + "/" + trackable.id + "): " + trackable.trackCode + " - " + trackable.name); - - trackables.add(trackable); - } - } - - return trackables; - } - - public static String stripParagraphs(String text) { - if (StringUtils.isBlank(text)) { - return ""; - } - - final Pattern patternP = Pattern.compile("(<p>|</p>|<br \\/>|<br>)", Pattern.CASE_INSENSITIVE); - final Pattern patternP2 = Pattern.compile("([ ]+)", Pattern.CASE_INSENSITIVE); - final Matcher matcherP = patternP.matcher(text); - final Matcher matcherP2 = patternP2.matcher(text); - - matcherP.replaceAll(" "); - matcherP2.replaceAll(" "); - - return text.trim(); - } - - public static String stripTags(String text) { - if (StringUtils.isBlank(text)) { - return ""; - } - - final Pattern patternP = Pattern.compile("(<[^>]+>)", Pattern.CASE_INSENSITIVE); - final Matcher matcherP = patternP.matcher(text); - - matcherP.replaceAll(" "); - - return text.trim(); - } - - public String getHumanDistance(Float distance) { - if (distance == null) { - return "?"; - } - - if (settings.units == cgSettings.unitsImperial) { - distance /= miles2km; - if (distance > 100) { - return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance))) + " mi"; - } else if (distance > 0.5) { - return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 10.0) / 10.0)) + " mi"; - } else if (distance > 0.1) { - return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 100.0) / 100.0)) + " mi"; - } else if (distance > 0.05) { - return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance * 5280.0))) + " ft"; - } else if (distance > 0.01) { - return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 5280 * 10.0) / 10.0)) + " ft"; - } else { - return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 5280 * 100.0) / 100.0)) + " ft"; - } - } else { - if (distance > 100) { - return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance))) + " km"; - } else if (distance > 10) { - return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 10.0) / 10.0)) + " km"; - } else if (distance > 1) { - return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 100.0) / 100.0)) + " km"; - } else if (distance > 0.1) { - return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance * 1000.0))) + " m"; - } else if (distance > 0.01) { - return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 1000.0 * 10.0) / 10.0)) + " m"; - } else { - return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 1000.0 * 100.0) / 100.0)) + " m"; - } - } - } - - public String getHumanSpeed(float speed) { - double kph = speed * 3.6; - String unit = "km/h"; - - if (this.settings.units == cgSettings.unitsImperial) { - kph /= miles2km; - unit = "mph"; - } - - if (kph < 10.0) { - return String.format(Locale.getDefault(), "%.1f", Double.valueOf((Math.round(kph * 10.0) / 10.0))) + " " + unit; - } else { - return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(kph))) + " " + unit; - } - } - - public static Map<String, Object> parseLatlon(String latlon) { - final Map<String, Object> result = new HashMap<String, Object>(); - final Pattern patternLatlon = Pattern.compile("([NS])[^\\d]*(\\d+)[^°]*° (\\d+)\\.(\\d+) ([WE])[^\\d]*(\\d+)[^°]*° (\\d+)\\.(\\d+)", Pattern.CASE_INSENSITIVE); - final Matcher matcherLatlon = patternLatlon.matcher(latlon); - - while (matcherLatlon.find()) { - if (matcherLatlon.groupCount() > 0) { - result.put("latitudeString", (String) (matcherLatlon.group(1) + " " + matcherLatlon.group(2) + "° " + matcherLatlon.group(3) + "." + matcherLatlon.group(4))); - result.put("longitudeString", (String) (matcherLatlon.group(5) + " " + matcherLatlon.group(6) + "° " + matcherLatlon.group(7) + "." + matcherLatlon.group(8))); - int latNegative = -1; - int lonNegative = -1; - if (matcherLatlon.group(1).equalsIgnoreCase("N")) { - latNegative = 1; - } - if (matcherLatlon.group(5).equalsIgnoreCase("E")) { - lonNegative = 1; - } - result.put("latitude", Double.valueOf(latNegative * (Float.valueOf(matcherLatlon.group(2)) + Float.valueOf(matcherLatlon.group(3) + "." + matcherLatlon.group(4)) / 60))); - result.put("longitude", Double.valueOf(lonNegative * (Float.valueOf(matcherLatlon.group(6)) + Float.valueOf(matcherLatlon.group(7) + "." + matcherLatlon.group(8)) / 60))); - } else { - Log.w(cgSettings.tag, "cgBase.parseLatlon: Failed to parse coordinates."); - } - } - - return result; - } - - private static String formatCoordinate(final Double coordIn, final boolean degrees, final String direction, final String digitsFormat) { - if (coordIn == null) { - return ""; - } - StringBuilder formatted = new StringBuilder(direction); - - double coordAbs = Math.abs(coordIn); - Locale locale = Locale.getDefault(); - double floor = Math.floor(coordAbs); - - formatted.append(String.format(locale, digitsFormat, floor)); - - if (degrees) { - formatted.append("° "); - } else { - formatted.append(" "); - } - formatted.append(String.format(locale, "%06.3f", ((coordAbs - floor) * 60))); - - return formatted.toString(); - } - - public static String formatLatitude(final Double coord, final boolean degrees) { - return formatCoordinate(coord, degrees, (coord >= 0) ? "N " : "S ", "%02.0f"); - } - - public static String formatLongitude(final Double coord, final boolean degrees) { - return formatCoordinate(coord, degrees, (coord >= 0) ? "E " : "W ", "%03.0f"); - } - - public static String formatCoords(final Geopoint coords, final boolean degrees) { - return formatLatitude(coords.getLatitude(), degrees) + " | " + formatLongitude(coords.getLongitude(), degrees); - } - - // TODO Use android.util.Pair<Double, String> if needed rather than a Map here. - public static Map<String, Object> parseCoordinate(String coord, String latlon) { - final Map<String, Object> coords = new HashMap<String, Object>(); - - final Pattern patternA = Pattern.compile("^([NSWE])[^\\d]*(\\d+)°? +(\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); - final Pattern patternB = Pattern.compile("^([NSWE])[^\\d]*(\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); - final Pattern patternC = Pattern.compile("^(-?\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); - final Pattern patternD = Pattern.compile("^([NSWE])[^\\d]*(\\d+)°?$", Pattern.CASE_INSENSITIVE); - final Pattern patternE = Pattern.compile("^(-?\\d+)°?$", Pattern.CASE_INSENSITIVE); - final Pattern patternF = Pattern.compile("^([NSWE])[^\\d]*(\\d+)$", Pattern.CASE_INSENSITIVE); - final Pattern pattern0 = Pattern.compile("^(-?\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); - - coord = coord.trim().toUpperCase(); - - final Matcher matcherA = patternA.matcher(coord); - final Matcher matcherB = patternB.matcher(coord); - final Matcher matcherC = patternC.matcher(coord); - final Matcher matcherD = patternD.matcher(coord); - final Matcher matcherE = patternE.matcher(coord); - final Matcher matcherF = patternF.matcher(coord); - final Matcher matcher0 = pattern0.matcher(coord); - - int latlonNegative; - if (matcherA.find() && matcherA.groupCount() > 0) { - if (matcherA.group(1).equalsIgnoreCase("N") || matcherA.group(1).equalsIgnoreCase("E")) { - latlonNegative = 1; - } else { - latlonNegative = -1; - } - - if (matcherA.groupCount() < 5 || matcherA.group(5) == null) { - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherA.group(2)) + Double.valueOf(matcherA.group(3) + ".0") / 60))); - coords.put("string", matcherA.group(1) + " " + matcherA.group(2) + "° " + matcherA.group(3) + ".000"); - } else { - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherA.group(2)) + Double.valueOf(matcherA.group(3) + "." + matcherA.group(5)) / 60))); - coords.put("string", matcherA.group(1) + " " + matcherA.group(2) + "° " + matcherA.group(3) + "." + matcherA.group(5)); - } - - return coords; - } else if (matcherB.find() && matcherB.groupCount() > 0) { - if (matcherB.group(1).equalsIgnoreCase("N") || matcherB.group(1).equalsIgnoreCase("E")) { - latlonNegative = 1; - } else { - latlonNegative = -1; - } - - if (matcherB.groupCount() < 4 || matcherB.group(4) == null) { - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2) + ".0")))); - } else { - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2) + "." + matcherB.group(4))))); - } - } else if (matcherC.find() && matcherC.groupCount() > 0) { - if (matcherC.groupCount() < 3 || matcherC.group(3) == null) { - coords.put("coordinate", Double.valueOf(new Float(matcherC.group(1) + ".0"))); - } else { - coords.put("coordinate", Double.valueOf(new Float(matcherC.group(1) + "." + matcherC.group(3)))); - } - } else if (matcherD.find() && matcherD.groupCount() > 0) { - if (matcherD.group(1).equalsIgnoreCase("N") || matcherD.group(1).equalsIgnoreCase("E")) { - latlonNegative = 1; - } else { - latlonNegative = -1; - } - - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2))))); - } else if (matcherE.find() && matcherE.groupCount() > 0) { - coords.put("coordinate", Double.valueOf(matcherE.group(1))); - } else if (matcherF.find() && matcherF.groupCount() > 0) { - if (matcherF.group(1).equalsIgnoreCase("N") || matcherF.group(1).equalsIgnoreCase("E")) { - latlonNegative = 1; - } else { - latlonNegative = -1; - } - - coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2))))); - } else { - return null; - } - - if (matcher0.find() && matcher0.groupCount() > 0) { - String tmpDir = null; - Float tmpCoord; - if (matcher0.groupCount() < 3 || matcher0.group(3) == null) { - tmpCoord = new Float("0.0"); - } else { - tmpCoord = new Float("0." + matcher0.group(3)); - } - - if (latlon.equalsIgnoreCase("lat")) { - if (matcher0.group(1).equals("+")) { - tmpDir = "N"; - } - if (matcher0.group(1).equals("-")) { - tmpDir = "S"; - } - } else if (latlon.equalsIgnoreCase("lon")) { - if (matcher0.group(1).equals("+")) { - tmpDir = "E"; - } - if (matcher0.group(1).equals("-")) { - tmpDir = "W"; - } - } - - coords.put("string", tmpDir + " " + matcher0.group(1) + "° " + (Math.round(tmpCoord / (1 / 60) * 1000) * 1000)); - - return coords; - } else { - return new HashMap<String, Object>(); - } - } - - public UUID searchByNextPage(cgSearchThread thread, final UUID searchId, int reason, boolean showCaptcha) { - final String[] viewstates = app.getViewstates(searchId); - - String url = app.getUrl(searchId); - - if (StringUtils.isBlank(url)) { - Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No url found"); - return searchId; - } - - if (isEmpty(viewstates)) { - Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No viewstate given"); - return searchId; - } - - String host = "www.geocaching.com"; - String path = "/"; - final String method = "POST"; - - int dash = -1; - if (url.indexOf("http://") > -1) { - url = url.substring(7); - } - - dash = url.indexOf("/"); - if (dash > -1) { - host = url.substring(0, dash); - url = url.substring(dash); - } else { - host = url; - url = ""; - } - - dash = url.indexOf("?"); - if (dash > -1) { - path = url.substring(0, dash); - } else { - path = url; - } - - final Map<String, String> params = new HashMap<String, String>(); - setViewstates(viewstates, params); - params.put("__EVENTTARGET", "ctl00$ContentBody$pgrBottom$ctl08"); - params.put("__EVENTARGUMENT", ""); - - String page = request(false, host, path, method, params, false, false, true).getData(); - if (checkLogin(page) == false) { - int loginState = login(); - if (loginState == 1) { - page = request(false, host, path, method, params, false, false, true).getData(); - } else if (loginState == -3) { - Log.i(cgSettings.tag, "Working as guest."); - } else { - app.setError(searchId, errorRetrieve.get(loginState)); - Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: Can not log in geocaching"); - return searchId; - } - } - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No data from server"); - return searchId; - } - - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No cache parsed"); - return searchId; - } - - // save to application - app.setError(searchId, caches.error); - app.setViewstates(searchId, caches.viewstates); - - final List<cgCache> cacheList = new ArrayList<cgCache>(); - for (cgCache cache : caches.cacheList) { - app.addGeocode(searchId, cache.geocode); - cacheList.add(cache); - } - - app.addSearch(searchId, cacheList, true, reason); - - return searchId; - } - - public UUID searchByGeocode(Map<String, String> parameters, int reason, boolean forceReload) { - final cgSearch search = new cgSearch(); - String geocode = parameters.get("geocode"); - String guid = parameters.get("guid"); - - if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { - Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No geocode nor guid given"); - return null; - } - - if (forceReload == false && reason == 0 && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { - if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { - geocode = app.getGeocode(guid); - } - - List<cgCache> cacheList = new ArrayList<cgCache>(); - cacheList.add(app.getCacheByGeocode(geocode, true, true, true, true, true, true)); - search.addGeocode(geocode); - - app.addSearch(search, cacheList, false, reason); - - cacheList.clear(); - cacheList = null; - - return search.getCurrentId(); - } - - final String host = "www.geocaching.com"; - final String path = "/seek/cache_details.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (StringUtils.isNotBlank(geocode)) { - params.put("wp", geocode); - } else if (StringUtils.isNotBlank(guid)) { - params.put("guid", guid); - } - params.put("decrypt", "y"); - params.put("log", "y"); // download logs (more than 5 - params.put("numlogs", "35"); // 35 logs - - String page = requestLogged(false, host, path, method, params, false, false, false); - - if (StringUtils.isEmpty(page)) { - if (app.isThere(geocode, guid, true, false)) { - if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { - Log.i(cgSettings.tag, "Loading old cache from cache."); - - geocode = app.getGeocode(guid); - } - - final List<cgCache> cacheList = new ArrayList<cgCache>(); - cacheList.add(app.getCacheByGeocode(geocode)); - search.addGeocode(geocode); - search.error = null; - - app.addSearch(search, cacheList, false, reason); - - cacheList.clear(); - - return search.getCurrentId(); - } - - Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No data from server"); - return null; - } - - final cgCacheWrap caches = parseCache(page, reason); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - if (caches != null && StringUtils.isNotBlank(caches.error)) { - search.error = caches.error; - } - if (caches != null && StringUtils.isNotBlank(caches.url)) { - search.url = caches.url; - } - - app.addSearch(search, null, true, reason); - - Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No cache parsed"); - return null; - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, 0, 0, null); - - app.addSearch(search, cacheList, true, reason); - - page = null; - cacheList.clear(); - - return search.getCurrentId(); - } - - public UUID searchByOffline(Map<String, Object> parameters) { - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByOffline: No application found"); - return null; - } - - Geopoint coords = null; - String cachetype = null; - Integer list = 1; - - if (parameters.containsKey("latitude") && parameters.containsKey("longitude")) { - coords = new Geopoint((Double) parameters.get("latitude"), (Double) parameters.get("longitude")); - } - - if (parameters.containsKey("cachetype")) { - cachetype = (String) parameters.get("cachetype"); - } - - if (parameters.containsKey("list")) { - list = (Integer) parameters.get("list"); - } - - final cgSearch search = app.getBatchOfStoredCaches(true, coords, cachetype, list); - search.totalCnt = app.getAllStoredCachesCount(true, cachetype, list); - - return search.getCurrentId(); - } - - public UUID searchByHistory(Map<String, Object> parameters) { - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByHistory: No application found"); - return null; - } - - String cachetype = null; - - if (parameters.containsKey("cachetype")) { - cachetype = (String) parameters.get("cachetype"); - } - - final cgSearch search = app.getHistoryOfCaches(true, cachetype); - search.totalCnt = app.getAllHistoricCachesCount(true, cachetype); - - return search.getCurrentId(); - } - - public UUID searchByCoords(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { - final cgSearch search = new cgSearch(); - final String latitude = parameters.get("latitude"); - final String longitude = parameters.get("longitude"); - String cacheType = parameters.get("cachetype"); - - if (StringUtils.isBlank(latitude)) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No latitude given"); - return null; - } - - if (StringUtils.isBlank(longitude)) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No longitude given"); - return null; - } - - if (StringUtils.isBlank(cacheType)) { - cacheType = null; - } - - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (cacheType != null && cacheIDs.containsKey(cacheType)) { - params.put("tx", cacheIDs.get(cacheType)); - } else { - params.put("tx", cacheIDs.get("all")); - } - params.put("lat", latitude); - params.put("lng", longitude); - - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - String page = requestLogged(false, host, path, method, params, false, false, true); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No data from server"); - return null; - } - - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No cache parsed"); - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); - - app.addSearch(search, cacheList, true, reason); - - return search.getCurrentId(); - } - - public UUID searchByKeyword(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { - final cgSearch search = new cgSearch(); - final String keyword = parameters.get("keyword"); - String cacheType = parameters.get("cachetype"); - - if (StringUtils.isBlank(keyword)) { - Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No keyword given"); - return null; - } - - if (StringUtils.isBlank(cacheType)) { - cacheType = null; - } - - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (cacheType != null && cacheIDs.containsKey(cacheType)) { - params.put("tx", cacheIDs.get(cacheType)); - } else { - params.put("tx", cacheIDs.get("all")); - } - params.put("key", keyword); - - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - String page = requestLogged(false, host, path, method, params, false, false, true); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No data from server"); - return null; - } - - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No cache parsed"); - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); - - app.addSearch(search, cacheList, true, reason); - - return search.getCurrentId(); - } - - public UUID searchByUsername(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { - final cgSearch search = new cgSearch(); - final String userName = parameters.get("username"); - String cacheType = parameters.get("cachetype"); - - if (StringUtils.isBlank(userName)) { - Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No user name given"); - return null; - } - - if (StringUtils.isBlank(cacheType)) { - cacheType = null; - } - - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (cacheType != null && cacheIDs.containsKey(cacheType)) { - params.put("tx", cacheIDs.get(cacheType)); - } else { - params.put("tx", cacheIDs.get("all")); - } - params.put("ul", userName); - - boolean my = false; - if (userName.equalsIgnoreCase(settings.getLogin().get("username"))) { - my = true; - Log.i(cgSettings.tag, "cgBase.searchByUsername: Overriding users choice, downloading all caches."); - } - - final String url = "http://" + host + path + "?" + prepareParameters(params, my, true); - String page = requestLogged(false, host, path, method, params, false, my, true); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No data from server"); - return null; - } - - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No cache parsed"); - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); - - app.addSearch(search, cacheList, true, reason); - - return search.getCurrentId(); - } - - public UUID searchByOwner(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { - final cgSearch search = new cgSearch(); - final String userName = parameters.get("username"); - String cacheType = parameters.get("cachetype"); - - if (StringUtils.isBlank(userName)) { - Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No user name given"); - return null; - } - - if (StringUtils.isBlank(cacheType)) { - cacheType = null; - } - - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (cacheType != null && cacheIDs.containsKey(cacheType)) { - params.put("tx", cacheIDs.get(cacheType)); - } else { - params.put("tx", cacheIDs.get("all")); - } - params.put("u", userName); - - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - String page = requestLogged(false, host, path, method, params, false, false, true); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No data from server"); - return null; - } - - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); - if (caches == null || caches.cacheList == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No cache parsed"); - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); - - app.addSearch(search, cacheList, true, reason); - - return search.getCurrentId(); - } - - public UUID searchByViewport(Map<String, String> parameters, int reason) { - final cgSearch search = new cgSearch(); - final String latMin = parameters.get("latitude-min"); - final String latMax = parameters.get("latitude-max"); - final String lonMin = parameters.get("longitude-min"); - final String lonMax = parameters.get("longitude-max"); - - String usertoken = null; - if (parameters.get("usertoken") != null) { - usertoken = parameters.get("usertoken"); - } else { - usertoken = ""; - } - - String page = null; - - if (StringUtils.isBlank(latMin) || StringUtils.isBlank(latMax) || StringUtils.isBlank(lonMin) || StringUtils.isBlank(lonMax)) { - Log.e(cgSettings.tag, "cgeoBase.searchByViewport: Not enough parameters to recognize viewport"); - return null; - } - - final String host = "www.geocaching.com"; - final String path = "/map/default.aspx/MapAction"; - - String params = "{\"dto\":{\"data\":{\"c\":1,\"m\":\"\",\"d\":\"" + latMax + "|" + latMin + "|" + lonMax + "|" + lonMin + "\"},\"ut\":\"" + usertoken + "\"}}"; - - final String url = "http://" + host + path + "?" + params; - page = requestJSONgc(host, path, params); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No data from server"); - return null; - } - - final cgCacheWrap caches = parseMapJSON(url, page); - if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { - Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No cache parsed"); - } - - if (app == null) { - Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No application found"); - return null; - } - - List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, settings.excludeMine, settings.cacheType); - - app.addSearch(search, cacheList, true, reason); - - return search.getCurrentId(); - } - - public List<cgUser> getGeocachersInViewport(String username, Double latMin, Double latMax, Double lonMin, Double lonMax) { - final List<cgUser> users = new ArrayList<cgUser>(); - - if (username == null) { - return users; - } - if (latMin == null || latMax == null || lonMin == null || lonMax == null) { - return users; - } - - final String host = "api.go4cache.com"; - final String path = "/get.php"; - final String method = "POST"; - final Map<String, String> params = new HashMap<String, String>(); - - params.put("u", username); - params.put("ltm", String.format((Locale) null, "%.6f", latMin)); - params.put("ltx", String.format((Locale) null, "%.6f", latMax)); - params.put("lnm", String.format((Locale) null, "%.6f", lonMin)); - params.put("lnx", String.format((Locale) null, "%.6f", lonMax)); - - final String data = request(false, host, path, method, params, false, false, false).getData(); - - if (StringUtils.isBlank(data)) { - Log.e(cgSettings.tag, "cgeoBase.getGeocachersInViewport: No data from server"); - return null; - } - - try { - final JSONObject dataJSON = new JSONObject(data); - - final JSONArray usersData = dataJSON.getJSONArray("users"); - if (usersData != null && usersData.length() > 0) { - int count = usersData.length(); - JSONObject oneUser = null; - for (int i = 0; i < count; i++) { - final cgUser user = new cgUser(); - oneUser = usersData.getJSONObject(i); - if (oneUser != null) { - final String located = oneUser.getString("located"); - if (located != null) { - user.located = dateSqlIn.parse(located); - } else { - user.located = new Date(); - } - user.username = oneUser.getString("user"); - user.coords = new Geopoint(oneUser.getDouble("latitude"), oneUser.getDouble("longitude")); - user.action = oneUser.getString("action"); - user.client = oneUser.getString("client"); - - if (user.coords != null) { - users.add(user); - } - } - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.getGeocachersInViewport: " + e.toString()); - } - - return users; - } - - public List<cgCache> processSearchResults(cgSearch search, cgCacheWrap caches, int excludeDisabled, int excludeMine, String cacheType) { - List<cgCache> cacheList = new ArrayList<cgCache>(); - if (caches != null) { - if (StringUtils.isNotBlank(caches.error)) { - search.error = caches.error; - } - if (StringUtils.isNotBlank(caches.url)) { - search.url = caches.url; - } - search.viewstates = caches.viewstates; - search.totalCnt = caches.totalCnt; - - if (CollectionUtils.isNotEmpty(caches.cacheList)) { - for (cgCache cache : caches.cacheList) { - if ((excludeDisabled == 0 || (excludeDisabled == 1 && cache.disabled == false)) - && (excludeMine == 0 || (excludeMine == 1 && cache.own == false)) - && (excludeMine == 0 || (excludeMine == 1 && cache.found == false)) - && (cacheType == null || (cacheType.equals(cache.type)))) { - search.addGeocode(cache.geocode); - cacheList.add(cache); - } - } - } - } - return cacheList; - } - - public cgTrackable searchTrackable(Map<String, String> parameters) { - final String geocode = parameters.get("geocode"); - final String guid = parameters.get("guid"); - final String id = parameters.get("id"); - cgTrackable trackable = new cgTrackable(); - - if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) { - Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No geocode nor guid nor id given"); - return null; - } - - final String host = "www.geocaching.com"; - final String path = "/track/details.aspx"; - final String method = "GET"; - final Map<String, String> params = new HashMap<String, String>(); - if (StringUtils.isNotBlank(geocode)) { - params.put("tracker", geocode); - } else if (StringUtils.isNotBlank(guid)) { - params.put("guid", guid); - } else if (StringUtils.isNotBlank(id)) { - params.put("id", id); - } - - String page = requestLogged(false, host, path, method, params, false, false, false); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No data from server"); - return trackable; - } - - trackable = parseTrackable(page); - if (trackable == null) { - Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No trackable parsed"); - return trackable; - } - - return trackable; - } - - public int postLog(cgeoapplication app, String geocode, String cacheid, String[] viewstates, - int logType, int year, int month, int day, String log, List<cgTrackableLog> trackables) { - if (isEmpty(viewstates)) { - Log.e(cgSettings.tag, "cgeoBase.postLog: No viewstate given"); - return 1000; - } - - if (logTypes2.containsKey(logType) == false) { - Log.e(cgSettings.tag, "cgeoBase.postLog: Unknown logtype"); - return 1000; - } - - if (StringUtils.isBlank(log)) { - Log.e(cgSettings.tag, "cgeoBase.postLog: No log text given"); - return 1001; - } - - // fix log (non-Latin characters converted to HTML entities) - final int logLen = log.length(); - final StringBuilder logUpdated = new StringBuilder(); - - for (int i = 0; i < logLen; i++) { - char c = log.charAt(i); - - if (c > 300) { - logUpdated.append("&#"); - logUpdated.append(Integer.toString((int) c)); - logUpdated.append(';'); - } else { - logUpdated.append(c); - } - } - log = logUpdated.toString(); - - log = log.replace("\n", "\r\n"); // windows' eol - - if (trackables != null) { - Log.i(cgSettings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log + "; trackables: " + trackables.size()); - } else { - Log.i(cgSettings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log + "; trackables: 0"); - } - - final String host = "www.geocaching.com"; - final String path = "/seek/log.aspx?ID=" + cacheid; - final String method = "POST"; - final Map<String, String> params = new HashMap<String, String>(); - - setViewstates(viewstates, params); - params.put("__EVENTTARGET", ""); - params.put("__EVENTARGUMENT", ""); - params.put("__LASTFOCUS", ""); - params.put("ctl00$ContentBody$LogBookPanel1$ddLogType", Integer.toString(logType)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", String.format("%02d", month) + "/" + String.format("%02d", day) + "/" + String.format("%04d", year)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Month", Integer.toString(month)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Day", Integer.toString(day)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Year", Integer.toString(year)); - params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); - params.put("ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry"); - params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); - if (trackables != null && trackables.isEmpty() == false) { // we have some trackables to proceed - final StringBuilder hdnSelected = new StringBuilder(); - - for (cgTrackableLog tb : trackables) { - final String action = Integer.toString(tb.id) + logTypesTrackableAction.get(tb.action); - - if (tb.action > 0) { - hdnSelected.append(action); - hdnSelected.append(','); - } - } - - params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnSelectedActions", hdnSelected.toString()); // selected trackables - params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); - } - - String page = request(false, host, path, method, params, false, false, false).getData(); - if (checkLogin(page) == false) { - int loginState = login(); - if (loginState == 1) { - page = request(false, host, path, method, params, false, false, false).getData(); - } else { - Log.e(cgSettings.tag, "cgeoBase.postLog: Can not log in geocaching (error: " + loginState + ")"); - return loginState; - } - } - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.postLog: No data from server"); - return 1002; - } - - // maintenance, archived needs to be confirmed - final Pattern pattern = Pattern.compile("<span id=\"ctl00_ContentBody_LogBookPanel1_lbConfirm\"[^>]*>([^<]*<font[^>]*>)?([^<]+)(</font>[^<]*)?</span>", Pattern.CASE_INSENSITIVE); - final Matcher matcher = pattern.matcher(page); - - try { - if (matcher.find() && matcher.groupCount() > 0) { - final String[] viewstatesConfirm = getViewstates(page); - - if (isEmpty(viewstatesConfirm)) { - Log.e(cgSettings.tag, "cgeoBase.postLog: No viewstate for confirm log"); - return 1000; - } - - params.clear(); - setViewstates(viewstatesConfirm, params); - params.put("__EVENTTARGET", ""); - params.put("__EVENTARGUMENT", ""); - params.put("__LASTFOCUS", ""); - params.put("ctl00$ContentBody$LogBookPanel1$btnConfirm", "Yes"); - params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); - params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); - if (trackables != null && trackables.isEmpty() == false) { // we have some trackables to proceed - final StringBuilder hdnSelected = new StringBuilder(); - - for (cgTrackableLog tb : trackables) { - String ctl = null; - final String action = Integer.toString(tb.id) + logTypesTrackableAction.get(tb.action); - - if (tb.ctl < 10) { - ctl = "0" + Integer.toString(tb.ctl); - } else { - ctl = Integer.toString(tb.ctl); - } - - params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$repTravelBugs$ctl" + ctl + "$ddlAction", action); - if (tb.action > 0) { - hdnSelected.append(action); - hdnSelected.append(','); - } - } - - params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnSelectedActions", hdnSelected.toString()); // selected trackables - params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); - } - - page = request(false, host, path, method, params, false, false, false).getData(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.postLog.confim: " + e.toString()); - } - - try { - final Pattern patternOk = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_lbHeading\"[^>]*>[^<]*</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - final Matcher matcherOk = patternOk.matcher(page); - if (matcherOk.find()) { - Log.i(cgSettings.tag, "Log successfully posted to cache #" + cacheid); - - if (app != null && geocode != null) { - app.saveVisitDate(geocode); - } - - return 1; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.postLog.check: " + e.toString()); - } - - Log.e(cgSettings.tag, "cgeoBase.postLog: Failed to post log because of unknown error"); - return 1000; - } - - public int postLogTrackable(String tbid, String trackingCode, String[] viewstates, - int logType, int year, int month, int day, String log) { - if (isEmpty(viewstates)) { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No viewstate given"); - return 1000; - } - - if (logTypes2.containsKey(logType) == false) { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Unknown logtype"); - return 1000; - } - - if (StringUtils.isBlank(log)) { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No log text given"); - return 1001; - } - - Log.i(cgSettings.tag, "Trying to post log for trackable #" + trackingCode + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log); - - log = log.replace("\n", "\r\n"); // windows' eol - - final Calendar currentDate = Calendar.getInstance(); - final String host = "www.geocaching.com"; - final String path = "/track/log.aspx?wid=" + tbid; - final String method = "POST"; - final Map<String, String> params = new HashMap<String, String>(); - - setViewstates(viewstates, params); - params.put("__EVENTTARGET", ""); - params.put("__EVENTARGUMENT", ""); - params.put("__LASTFOCUS", ""); - params.put("ctl00$ContentBody$LogBookPanel1$ddLogType", Integer.toString(logType)); - params.put("ctl00$ContentBody$LogBookPanel1$tbCode", trackingCode); - if (currentDate.get(Calendar.YEAR) == year && (currentDate.get(Calendar.MONTH) + 1) == month && currentDate.get(Calendar.DATE) == day) { - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", ""); - } else { - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", Integer.toString(month) + "/" + Integer.toString(day) + "/" + Integer.toString(year)); - } - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Day", Integer.toString(day)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Month", Integer.toString(month)); - params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Year", Integer.toString(year)); - params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); - params.put("ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry"); - params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); - - String page = request(false, host, path, method, params, false, false, false).getData(); - if (checkLogin(page) == false) { - int loginState = login(); - if (loginState == 1) { - page = request(false, host, path, method, params, false, false, false).getData(); - } else { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Can not log in geocaching (error: " + loginState + ")"); - return loginState; - } - } - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No data from server"); - return 1002; - } - - try { - final Pattern patternOk = Pattern.compile("<div id=[\"|']ctl00_ContentBody_LogBookPanel1_ViewLogPanel[\"|']>", Pattern.CASE_INSENSITIVE); - final Matcher matcherOk = patternOk.matcher(page); - if (matcherOk.find()) { - Log.i(cgSettings.tag, "Log successfully posted to trackable #" + trackingCode); - return 1; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable.check: " + e.toString()); - } - - Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Failed to post log because of unknown error"); - return 1000; - } + logDone.author = Html.fromHtml(matcherLogs.group(3)).toString(); + + try + { + logDone.date = parseGcCustomDate(matcherLogs.group(2)).getTime(); + } catch (ParseException e) { + } + + logDone.log = matcherLogs.group(6).trim(); + + if (matcherLogs.group(4) != null && matcherLogs.group(5) != null) + { + logDone.cacheGuid = matcherLogs.group(4); + logDone.cacheName = matcherLogs.group(5); + } + + trackable.logs.add(logDone); + } + } catch (Exception e) { + // failed to parse logs + Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse cache logs"); + } + + app.saveTrackable(trackable); + + return trackable; + } + + public static List<Integer> parseTypes(String page) { + if (StringUtils.isEmpty(page)) { + return null; + } + + final List<Integer> types = new ArrayList<Integer>(); + + final Pattern typeBoxPattern = Pattern.compile("<select name=\"ctl00\\$ContentBody\\$LogBookPanel1\\$ddLogType\" id=\"ctl00_ContentBody_LogBookPanel1_ddLogType\"[^>]*>" + + "(([^<]*<option[^>]*>[^<]+</option>)+)[^<]*</select>", Pattern.CASE_INSENSITIVE); + final Matcher typeBoxMatcher = typeBoxPattern.matcher(page); + String typesText = null; + if (typeBoxMatcher.find()) { + if (typeBoxMatcher.groupCount() > 0) { + typesText = typeBoxMatcher.group(1); + } + } + + if (typesText != null) { + final Pattern typePattern = Pattern.compile("<option( selected=\"selected\")? value=\"(\\d+)\">[^<]+</option>", Pattern.CASE_INSENSITIVE); + final Matcher typeMatcher = typePattern.matcher(typesText); + while (typeMatcher.find()) { + if (typeMatcher.groupCount() > 1) { + final int type = Integer.parseInt(typeMatcher.group(2)); + + if (type > 0) { + types.add(type); + } + } + } + } + + return types; + } + + public static List<cgTrackableLog> parseTrackableLog(String page) { + if (StringUtils.isEmpty(page)) { + return null; + } + + final List<cgTrackableLog> trackables = new ArrayList<cgTrackableLog>(); + + int startPos = -1; + int endPos = -1; + + startPos = page.indexOf("<table id=\"tblTravelBugs\""); + if (startPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: ID \"tblTravelBugs\" not found on page"); + return null; + } + + page = page.substring(startPos); // cut on <table + + endPos = page.indexOf("</table>"); + if (endPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: end of ID \"tblTravelBugs\" not found on page"); + return null; + } + + page = page.substring(0, endPos); // cut on </table> + + startPos = page.indexOf("<tbody>"); + if (startPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: tbody not found on page"); + return null; + } + + page = page.substring(startPos); // cut on <tbody> + + endPos = page.indexOf("</tbody>"); + if (endPos == -1) { + Log.e(cgSettings.tag, "cgeoBase.parseTrackableLog: end of tbody not found on page"); + return null; + } + + page = page.substring(0, endPos); // cut on </tbody> + + final Pattern trackablePattern = Pattern.compile("<tr id=\"ctl00_ContentBody_LogBookPanel1_uxTrackables_repTravelBugs_ctl[0-9]+_row\"[^>]*>" + + "[^<]*<td>[^<]*<a href=\"[^\"]+\">([A-Z0-9]+)</a>[^<]*</td>[^<]*<td>([^<]+)</td>[^<]*<td>" + + "[^<]*<select name=\"ctl00\\$ContentBody\\$LogBookPanel1\\$uxTrackables\\$repTravelBugs\\$ctl([0-9]+)\\$ddlAction\"[^>]*>" + + "([^<]*<option value=\"([0-9]+)(_[a-z]+)?\">[^<]+</option>)+" + + "[^<]*</select>[^<]*</td>[^<]*</tr>", Pattern.CASE_INSENSITIVE); + final Matcher trackableMatcher = trackablePattern.matcher(page); + while (trackableMatcher.find()) { + if (trackableMatcher.groupCount() > 0) { + final cgTrackableLog trackable = new cgTrackableLog(); + + if (trackableMatcher.group(1) != null) { + trackable.trackCode = trackableMatcher.group(1); + } else { + continue; + } + if (trackableMatcher.group(2) != null) { + trackable.name = Html.fromHtml(trackableMatcher.group(2)).toString(); + } else { + continue; + } + if (trackableMatcher.group(3) != null) { + trackable.ctl = Integer.valueOf(trackableMatcher.group(3)); + } else { + continue; + } + if (trackableMatcher.group(5) != null) { + trackable.id = Integer.valueOf(trackableMatcher.group(5)); + } else { + continue; + } + + Log.i(cgSettings.tag, "Trackable in inventory (#" + trackable.ctl + "/" + trackable.id + "): " + trackable.trackCode + " - " + trackable.name); + + trackables.add(trackable); + } + } + + return trackables; + } + + public static String stripParagraphs(String text) { + if (StringUtils.isBlank(text)) { + return ""; + } + + final Pattern patternP = Pattern.compile("(<p>|</p>|<br \\/>|<br>)", Pattern.CASE_INSENSITIVE); + final Pattern patternP2 = Pattern.compile("([ ]+)", Pattern.CASE_INSENSITIVE); + final Matcher matcherP = patternP.matcher(text); + final Matcher matcherP2 = patternP2.matcher(text); + + matcherP.replaceAll(" "); + matcherP2.replaceAll(" "); + + return text.trim(); + } + + public static String stripTags(String text) { + if (StringUtils.isBlank(text)) { + return ""; + } + + final Pattern patternP = Pattern.compile("(<[^>]+>)", Pattern.CASE_INSENSITIVE); + final Matcher matcherP = patternP.matcher(text); + + matcherP.replaceAll(" "); + + return text.trim(); + } + + public String getHumanDistance(Float distance) { + if (distance == null) { + return "?"; + } + + if (settings.units == cgSettings.unitsImperial) { + distance /= miles2km; + if (distance > 100) { + return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance))) + " mi"; + } else if (distance > 0.5) { + return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 10.0) / 10.0)) + " mi"; + } else if (distance > 0.1) { + return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 100.0) / 100.0)) + " mi"; + } else if (distance > 0.05) { + return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance * 5280.0))) + " ft"; + } else if (distance > 0.01) { + return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 5280 * 10.0) / 10.0)) + " ft"; + } else { + return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 5280 * 100.0) / 100.0)) + " ft"; + } + } else { + if (distance > 100) { + return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance))) + " km"; + } else if (distance > 10) { + return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 10.0) / 10.0)) + " km"; + } else if (distance > 1) { + return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 100.0) / 100.0)) + " km"; + } else if (distance > 0.1) { + return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance * 1000.0))) + " m"; + } else if (distance > 0.01) { + return String.format(Locale.getDefault(), "%.1f", Double.valueOf(Math.round(distance * 1000.0 * 10.0) / 10.0)) + " m"; + } else { + return String.format(Locale.getDefault(), "%.2f", Double.valueOf(Math.round(distance * 1000.0 * 100.0) / 100.0)) + " m"; + } + } + } + + public String getHumanSpeed(float speed) { + double kph = speed * 3.6; + String unit = "km/h"; + + if (this.settings.units == cgSettings.unitsImperial) { + kph /= miles2km; + unit = "mph"; + } + + if (kph < 10.0) { + return String.format(Locale.getDefault(), "%.1f", Double.valueOf((Math.round(kph * 10.0) / 10.0))) + " " + unit; + } else { + return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(kph))) + " " + unit; + } + } + + public static Map<String, Object> parseLatlon(String latlon) { + final Map<String, Object> result = new HashMap<String, Object>(); + final Pattern patternLatlon = Pattern.compile("([NS])[^\\d]*(\\d+)[^°]*° (\\d+)\\.(\\d+) ([WE])[^\\d]*(\\d+)[^°]*° (\\d+)\\.(\\d+)", Pattern.CASE_INSENSITIVE); + final Matcher matcherLatlon = patternLatlon.matcher(latlon); + + while (matcherLatlon.find()) { + if (matcherLatlon.groupCount() > 0) { + result.put("latitudeString", (String) (matcherLatlon.group(1) + " " + matcherLatlon.group(2) + "° " + matcherLatlon.group(3) + "." + matcherLatlon.group(4))); + result.put("longitudeString", (String) (matcherLatlon.group(5) + " " + matcherLatlon.group(6) + "° " + matcherLatlon.group(7) + "." + matcherLatlon.group(8))); + int latNegative = -1; + int lonNegative = -1; + if (matcherLatlon.group(1).equalsIgnoreCase("N")) { + latNegative = 1; + } + if (matcherLatlon.group(5).equalsIgnoreCase("E")) { + lonNegative = 1; + } + result.put("latitude", Double.valueOf(latNegative * (Float.valueOf(matcherLatlon.group(2)) + Float.valueOf(matcherLatlon.group(3) + "." + matcherLatlon.group(4)) / 60))); + result.put("longitude", Double.valueOf(lonNegative * (Float.valueOf(matcherLatlon.group(6)) + Float.valueOf(matcherLatlon.group(7) + "." + matcherLatlon.group(8)) / 60))); + } else { + Log.w(cgSettings.tag, "cgBase.parseLatlon: Failed to parse coordinates."); + } + } + + return result; + } + + private static String formatCoordinate(final Double coordIn, final boolean degrees, final String direction, final String digitsFormat) { + if (coordIn == null) { + return ""; + } + StringBuilder formatted = new StringBuilder(direction); + + double coordAbs = Math.abs(coordIn); + Locale locale = Locale.getDefault(); + double floor = Math.floor(coordAbs); + + formatted.append(String.format(locale, digitsFormat, floor)); + + if (degrees) { + formatted.append("° "); + } else { + formatted.append(" "); + } + formatted.append(String.format(locale, "%06.3f", ((coordAbs - floor) * 60))); + + return formatted.toString(); + } + + public static String formatLatitude(final Double coord, final boolean degrees) { + return formatCoordinate(coord, degrees, (coord >= 0) ? "N " : "S ", "%02.0f"); + } + + public static String formatLongitude(final Double coord, final boolean degrees) { + return formatCoordinate(coord, degrees, (coord >= 0) ? "E " : "W ", "%03.0f"); + } + + public static String formatCoords(final Geopoint coords, final boolean degrees) { + return formatLatitude(coords.getLatitude(), degrees) + " | " + formatLongitude(coords.getLongitude(), degrees); + } + + // TODO Use android.util.Pair<Double, String> if needed rather than a Map here. + public static Map<String, Object> parseCoordinate(String coord, String latlon) { + final Map<String, Object> coords = new HashMap<String, Object>(); + + final Pattern patternA = Pattern.compile("^([NSWE])[^\\d]*(\\d+)°? +(\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); + final Pattern patternB = Pattern.compile("^([NSWE])[^\\d]*(\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); + final Pattern patternC = Pattern.compile("^(-?\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); + final Pattern patternD = Pattern.compile("^([NSWE])[^\\d]*(\\d+)°?$", Pattern.CASE_INSENSITIVE); + final Pattern patternE = Pattern.compile("^(-?\\d+)°?$", Pattern.CASE_INSENSITIVE); + final Pattern patternF = Pattern.compile("^([NSWE])[^\\d]*(\\d+)$", Pattern.CASE_INSENSITIVE); + final Pattern pattern0 = Pattern.compile("^(-?\\d+)([\\.|,](\\d+))?$", Pattern.CASE_INSENSITIVE); + + coord = coord.trim().toUpperCase(); + + final Matcher matcherA = patternA.matcher(coord); + final Matcher matcherB = patternB.matcher(coord); + final Matcher matcherC = patternC.matcher(coord); + final Matcher matcherD = patternD.matcher(coord); + final Matcher matcherE = patternE.matcher(coord); + final Matcher matcherF = patternF.matcher(coord); + final Matcher matcher0 = pattern0.matcher(coord); + + int latlonNegative; + if (matcherA.find() && matcherA.groupCount() > 0) { + if (matcherA.group(1).equalsIgnoreCase("N") || matcherA.group(1).equalsIgnoreCase("E")) { + latlonNegative = 1; + } else { + latlonNegative = -1; + } + + if (matcherA.groupCount() < 5 || matcherA.group(5) == null) { + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherA.group(2)) + Double.valueOf(matcherA.group(3) + ".0") / 60))); + coords.put("string", matcherA.group(1) + " " + matcherA.group(2) + "° " + matcherA.group(3) + ".000"); + } else { + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherA.group(2)) + Double.valueOf(matcherA.group(3) + "." + matcherA.group(5)) / 60))); + coords.put("string", matcherA.group(1) + " " + matcherA.group(2) + "° " + matcherA.group(3) + "." + matcherA.group(5)); + } + + return coords; + } else if (matcherB.find() && matcherB.groupCount() > 0) { + if (matcherB.group(1).equalsIgnoreCase("N") || matcherB.group(1).equalsIgnoreCase("E")) { + latlonNegative = 1; + } else { + latlonNegative = -1; + } + + if (matcherB.groupCount() < 4 || matcherB.group(4) == null) { + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2) + ".0")))); + } else { + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2) + "." + matcherB.group(4))))); + } + } else if (matcherC.find() && matcherC.groupCount() > 0) { + if (matcherC.groupCount() < 3 || matcherC.group(3) == null) { + coords.put("coordinate", Double.valueOf(new Float(matcherC.group(1) + ".0"))); + } else { + coords.put("coordinate", Double.valueOf(new Float(matcherC.group(1) + "." + matcherC.group(3)))); + } + } else if (matcherD.find() && matcherD.groupCount() > 0) { + if (matcherD.group(1).equalsIgnoreCase("N") || matcherD.group(1).equalsIgnoreCase("E")) { + latlonNegative = 1; + } else { + latlonNegative = -1; + } + + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2))))); + } else if (matcherE.find() && matcherE.groupCount() > 0) { + coords.put("coordinate", Double.valueOf(matcherE.group(1))); + } else if (matcherF.find() && matcherF.groupCount() > 0) { + if (matcherF.group(1).equalsIgnoreCase("N") || matcherF.group(1).equalsIgnoreCase("E")) { + latlonNegative = 1; + } else { + latlonNegative = -1; + } + + coords.put("coordinate", Double.valueOf(latlonNegative * (Double.valueOf(matcherB.group(2))))); + } else { + return null; + } + + if (matcher0.find() && matcher0.groupCount() > 0) { + String tmpDir = null; + Float tmpCoord; + if (matcher0.groupCount() < 3 || matcher0.group(3) == null) { + tmpCoord = new Float("0.0"); + } else { + tmpCoord = new Float("0." + matcher0.group(3)); + } + + if (latlon.equalsIgnoreCase("lat")) { + if (matcher0.group(1).equals("+")) { + tmpDir = "N"; + } + if (matcher0.group(1).equals("-")) { + tmpDir = "S"; + } + } else if (latlon.equalsIgnoreCase("lon")) { + if (matcher0.group(1).equals("+")) { + tmpDir = "E"; + } + if (matcher0.group(1).equals("-")) { + tmpDir = "W"; + } + } + + coords.put("string", tmpDir + " " + matcher0.group(1) + "° " + (Math.round(tmpCoord / (1 / 60) * 1000) * 1000)); + + return coords; + } else { + return new HashMap<String, Object>(); + } + } + + public UUID searchByNextPage(cgSearchThread thread, final UUID searchId, int reason, boolean showCaptcha) { + final String[] viewstates = app.getViewstates(searchId); + + String url = app.getUrl(searchId); + + if (StringUtils.isBlank(url)) { + Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No url found"); + return searchId; + } + + if (isEmpty(viewstates)) { + Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No viewstate given"); + return searchId; + } + + String host = "www.geocaching.com"; + String path = "/"; + final String method = "POST"; + + int dash = -1; + if (url.indexOf("http://") > -1) { + url = url.substring(7); + } + + dash = url.indexOf("/"); + if (dash > -1) { + host = url.substring(0, dash); + url = url.substring(dash); + } else { + host = url; + url = ""; + } + + dash = url.indexOf("?"); + if (dash > -1) { + path = url.substring(0, dash); + } else { + path = url; + } + + final Map<String, String> params = new HashMap<String, String>(); + setViewstates(viewstates, params); + params.put("__EVENTTARGET", "ctl00$ContentBody$pgrBottom$ctl08"); + params.put("__EVENTARGUMENT", ""); + + String page = request(false, host, path, method, params, false, false, true).getData(); + if (checkLogin(page) == false) { + int loginState = login(); + if (loginState == 1) { + page = request(false, host, path, method, params, false, false, true).getData(); + } else if (loginState == -3) { + Log.i(cgSettings.tag, "Working as guest."); + } else { + app.setError(searchId, errorRetrieve.get(loginState)); + Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: Can not log in geocaching"); + return searchId; + } + } + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No data from server"); + return searchId; + } + + final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No cache parsed"); + return searchId; + } + + // save to application + app.setError(searchId, caches.error); + app.setViewstates(searchId, caches.viewstates); + + final List<cgCache> cacheList = new ArrayList<cgCache>(); + for (cgCache cache : caches.cacheList) { + app.addGeocode(searchId, cache.geocode); + cacheList.add(cache); + } + + app.addSearch(searchId, cacheList, true, reason); + + return searchId; + } + + public UUID searchByGeocode(Map<String, String> parameters, int reason, boolean forceReload) { + final cgSearch search = new cgSearch(); + String geocode = parameters.get("geocode"); + String guid = parameters.get("guid"); + + if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { + Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No geocode nor guid given"); + return null; + } + + if (forceReload == false && reason == 0 && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { + if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { + geocode = app.getGeocode(guid); + } + + List<cgCache> cacheList = new ArrayList<cgCache>(); + cacheList.add(app.getCacheByGeocode(geocode, true, true, true, true, true, true)); + search.addGeocode(geocode); + + app.addSearch(search, cacheList, false, reason); + + cacheList.clear(); + cacheList = null; + + return search.getCurrentId(); + } + + final String host = "www.geocaching.com"; + final String path = "/seek/cache_details.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (StringUtils.isNotBlank(geocode)) { + params.put("wp", geocode); + } else if (StringUtils.isNotBlank(guid)) { + params.put("guid", guid); + } + params.put("decrypt", "y"); + params.put("log", "y"); // download logs (more than 5 + params.put("numlogs", "35"); // 35 logs + + String page = requestLogged(false, host, path, method, params, false, false, false); + + if (StringUtils.isEmpty(page)) { + if (app.isThere(geocode, guid, true, false)) { + if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { + Log.i(cgSettings.tag, "Loading old cache from cache."); + + geocode = app.getGeocode(guid); + } + + final List<cgCache> cacheList = new ArrayList<cgCache>(); + cacheList.add(app.getCacheByGeocode(geocode)); + search.addGeocode(geocode); + search.error = null; + + app.addSearch(search, cacheList, false, reason); + + cacheList.clear(); + + return search.getCurrentId(); + } + + Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No data from server"); + return null; + } + + final cgCacheWrap caches = parseCache(page, reason); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + if (caches != null && StringUtils.isNotBlank(caches.error)) { + search.error = caches.error; + } + if (caches != null && StringUtils.isNotBlank(caches.url)) { + search.url = caches.url; + } + + app.addSearch(search, null, true, reason); + + Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No cache parsed"); + return null; + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByGeocode: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, 0, 0, null); + + app.addSearch(search, cacheList, true, reason); + + page = null; + cacheList.clear(); + + return search.getCurrentId(); + } + + public UUID searchByOffline(Map<String, Object> parameters) { + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByOffline: No application found"); + return null; + } + + Geopoint coords = null; + String cachetype = null; + Integer list = 1; + + if (parameters.containsKey("latitude") && parameters.containsKey("longitude")) { + coords = new Geopoint((Double) parameters.get("latitude"), (Double) parameters.get("longitude")); + } + + if (parameters.containsKey("cachetype")) { + cachetype = (String) parameters.get("cachetype"); + } + + if (parameters.containsKey("list")) { + list = (Integer) parameters.get("list"); + } + + final cgSearch search = app.getBatchOfStoredCaches(true, coords, cachetype, list); + search.totalCnt = app.getAllStoredCachesCount(true, cachetype, list); + + return search.getCurrentId(); + } + + public UUID searchByHistory(Map<String, Object> parameters) { + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByHistory: No application found"); + return null; + } + + String cachetype = null; + + if (parameters.containsKey("cachetype")) { + cachetype = (String) parameters.get("cachetype"); + } + + final cgSearch search = app.getHistoryOfCaches(true, cachetype); + search.totalCnt = app.getAllHistoricCachesCount(true, cachetype); + + return search.getCurrentId(); + } + + public UUID searchByCoords(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { + final cgSearch search = new cgSearch(); + final String latitude = parameters.get("latitude"); + final String longitude = parameters.get("longitude"); + String cacheType = parameters.get("cachetype"); + + if (StringUtils.isBlank(latitude)) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No latitude given"); + return null; + } + + if (StringUtils.isBlank(longitude)) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No longitude given"); + return null; + } + + if (StringUtils.isBlank(cacheType)) { + cacheType = null; + } + + final String host = "www.geocaching.com"; + final String path = "/seek/nearest.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (cacheType != null && cacheIDs.containsKey(cacheType)) { + params.put("tx", cacheIDs.get(cacheType)); + } else { + params.put("tx", cacheIDs.get("all")); + } + params.put("lat", latitude); + params.put("lng", longitude); + + final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); + String page = requestLogged(false, host, path, method, params, false, false, true); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No data from server"); + return null; + } + + final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No cache parsed"); + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); + + app.addSearch(search, cacheList, true, reason); + + return search.getCurrentId(); + } + + public UUID searchByKeyword(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { + final cgSearch search = new cgSearch(); + final String keyword = parameters.get("keyword"); + String cacheType = parameters.get("cachetype"); + + if (StringUtils.isBlank(keyword)) { + Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No keyword given"); + return null; + } + + if (StringUtils.isBlank(cacheType)) { + cacheType = null; + } + + final String host = "www.geocaching.com"; + final String path = "/seek/nearest.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (cacheType != null && cacheIDs.containsKey(cacheType)) { + params.put("tx", cacheIDs.get(cacheType)); + } else { + params.put("tx", cacheIDs.get("all")); + } + params.put("key", keyword); + + final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); + String page = requestLogged(false, host, path, method, params, false, false, true); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No data from server"); + return null; + } + + final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No cache parsed"); + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); + + app.addSearch(search, cacheList, true, reason); + + return search.getCurrentId(); + } + + public UUID searchByUsername(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { + final cgSearch search = new cgSearch(); + final String userName = parameters.get("username"); + String cacheType = parameters.get("cachetype"); + + if (StringUtils.isBlank(userName)) { + Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No user name given"); + return null; + } + + if (StringUtils.isBlank(cacheType)) { + cacheType = null; + } + + final String host = "www.geocaching.com"; + final String path = "/seek/nearest.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (cacheType != null && cacheIDs.containsKey(cacheType)) { + params.put("tx", cacheIDs.get(cacheType)); + } else { + params.put("tx", cacheIDs.get("all")); + } + params.put("ul", userName); + + boolean my = false; + if (userName.equalsIgnoreCase(settings.getLogin().get("username"))) { + my = true; + Log.i(cgSettings.tag, "cgBase.searchByUsername: Overriding users choice, downloading all caches."); + } + + final String url = "http://" + host + path + "?" + prepareParameters(params, my, true); + String page = requestLogged(false, host, path, method, params, false, my, true); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No data from server"); + return null; + } + + final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No cache parsed"); + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); + + app.addSearch(search, cacheList, true, reason); + + return search.getCurrentId(); + } + + public UUID searchByOwner(cgSearchThread thread, Map<String, String> parameters, int reason, boolean showCaptcha) { + final cgSearch search = new cgSearch(); + final String userName = parameters.get("username"); + String cacheType = parameters.get("cachetype"); + + if (StringUtils.isBlank(userName)) { + Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No user name given"); + return null; + } + + if (StringUtils.isBlank(cacheType)) { + cacheType = null; + } + + final String host = "www.geocaching.com"; + final String path = "/seek/nearest.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (cacheType != null && cacheIDs.containsKey(cacheType)) { + params.put("tx", cacheIDs.get(cacheType)); + } else { + params.put("tx", cacheIDs.get("all")); + } + params.put("u", userName); + + final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); + String page = requestLogged(false, host, path, method, params, false, false, true); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No data from server"); + return null; + } + + final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + if (caches == null || caches.cacheList == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No cache parsed"); + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, 0, null); + + app.addSearch(search, cacheList, true, reason); + + return search.getCurrentId(); + } + + public UUID searchByViewport(Map<String, String> parameters, int reason) { + final cgSearch search = new cgSearch(); + final String latMin = parameters.get("latitude-min"); + final String latMax = parameters.get("latitude-max"); + final String lonMin = parameters.get("longitude-min"); + final String lonMax = parameters.get("longitude-max"); + + String usertoken = null; + if (parameters.get("usertoken") != null) { + usertoken = parameters.get("usertoken"); + } else { + usertoken = ""; + } + + String page = null; + + if (StringUtils.isBlank(latMin) || StringUtils.isBlank(latMax) || StringUtils.isBlank(lonMin) || StringUtils.isBlank(lonMax)) { + Log.e(cgSettings.tag, "cgeoBase.searchByViewport: Not enough parameters to recognize viewport"); + return null; + } + + final String host = "www.geocaching.com"; + final String path = "/map/default.aspx/MapAction"; + + String params = "{\"dto\":{\"data\":{\"c\":1,\"m\":\"\",\"d\":\"" + latMax + "|" + latMin + "|" + lonMax + "|" + lonMin + "\"},\"ut\":\"" + usertoken + "\"}}"; + + final String url = "http://" + host + path + "?" + params; + page = requestJSONgc(host, path, params); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No data from server"); + return null; + } + + final cgCacheWrap caches = parseMapJSON(url, page); + if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { + Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No cache parsed"); + } + + if (app == null) { + Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No application found"); + return null; + } + + List<cgCache> cacheList = processSearchResults(search, caches, settings.excludeDisabled, settings.excludeMine, settings.cacheType); + + app.addSearch(search, cacheList, true, reason); + + return search.getCurrentId(); + } + + public List<cgUser> getGeocachersInViewport(String username, Double latMin, Double latMax, Double lonMin, Double lonMax) { + final List<cgUser> users = new ArrayList<cgUser>(); + + if (username == null) { + return users; + } + if (latMin == null || latMax == null || lonMin == null || lonMax == null) { + return users; + } + + final String host = "api.go4cache.com"; + final String path = "/get.php"; + final String method = "POST"; + final Map<String, String> params = new HashMap<String, String>(); + + params.put("u", username); + params.put("ltm", String.format((Locale) null, "%.6f", latMin)); + params.put("ltx", String.format((Locale) null, "%.6f", latMax)); + params.put("lnm", String.format((Locale) null, "%.6f", lonMin)); + params.put("lnx", String.format((Locale) null, "%.6f", lonMax)); + + final String data = request(false, host, path, method, params, false, false, false).getData(); + + if (StringUtils.isBlank(data)) { + Log.e(cgSettings.tag, "cgeoBase.getGeocachersInViewport: No data from server"); + return null; + } + + try { + final JSONObject dataJSON = new JSONObject(data); + + final JSONArray usersData = dataJSON.getJSONArray("users"); + if (usersData != null && usersData.length() > 0) { + int count = usersData.length(); + JSONObject oneUser = null; + for (int i = 0; i < count; i++) { + final cgUser user = new cgUser(); + oneUser = usersData.getJSONObject(i); + if (oneUser != null) { + final String located = oneUser.getString("located"); + if (located != null) { + user.located = dateSqlIn.parse(located); + } else { + user.located = new Date(); + } + user.username = oneUser.getString("user"); + user.coords = new Geopoint(oneUser.getDouble("latitude"), oneUser.getDouble("longitude")); + user.action = oneUser.getString("action"); + user.client = oneUser.getString("client"); + + if (user.coords != null) { + users.add(user); + } + } + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.getGeocachersInViewport: " + e.toString()); + } + + return users; + } + + public List<cgCache> processSearchResults(cgSearch search, cgCacheWrap caches, int excludeDisabled, int excludeMine, String cacheType) { + List<cgCache> cacheList = new ArrayList<cgCache>(); + if (caches != null) { + if (StringUtils.isNotBlank(caches.error)) { + search.error = caches.error; + } + if (StringUtils.isNotBlank(caches.url)) { + search.url = caches.url; + } + search.viewstates = caches.viewstates; + search.totalCnt = caches.totalCnt; + + if (CollectionUtils.isNotEmpty(caches.cacheList)) { + for (cgCache cache : caches.cacheList) { + if ((excludeDisabled == 0 || (excludeDisabled == 1 && cache.disabled == false)) + && (excludeMine == 0 || (excludeMine == 1 && cache.own == false)) + && (excludeMine == 0 || (excludeMine == 1 && cache.found == false)) + && (cacheType == null || (cacheType.equals(cache.type)))) { + search.addGeocode(cache.geocode); + cacheList.add(cache); + } + } + } + } + return cacheList; + } + + public cgTrackable searchTrackable(Map<String, String> parameters) { + final String geocode = parameters.get("geocode"); + final String guid = parameters.get("guid"); + final String id = parameters.get("id"); + cgTrackable trackable = new cgTrackable(); + + if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) { + Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No geocode nor guid nor id given"); + return null; + } + + final String host = "www.geocaching.com"; + final String path = "/track/details.aspx"; + final String method = "GET"; + final Map<String, String> params = new HashMap<String, String>(); + if (StringUtils.isNotBlank(geocode)) { + params.put("tracker", geocode); + } else if (StringUtils.isNotBlank(guid)) { + params.put("guid", guid); + } else if (StringUtils.isNotBlank(id)) { + params.put("id", id); + } + + String page = requestLogged(false, host, path, method, params, false, false, false); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No data from server"); + return trackable; + } + + trackable = parseTrackable(page); + if (trackable == null) { + Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No trackable parsed"); + return trackable; + } + + return trackable; + } + + public int postLog(cgeoapplication app, String geocode, String cacheid, String[] viewstates, + int logType, int year, int month, int day, String log, List<cgTrackableLog> trackables) { + if (isEmpty(viewstates)) { + Log.e(cgSettings.tag, "cgeoBase.postLog: No viewstate given"); + return 1000; + } + + if (logTypes2.containsKey(logType) == false) { + Log.e(cgSettings.tag, "cgeoBase.postLog: Unknown logtype"); + return 1000; + } + + if (StringUtils.isBlank(log)) { + Log.e(cgSettings.tag, "cgeoBase.postLog: No log text given"); + return 1001; + } + + // fix log (non-Latin characters converted to HTML entities) + final int logLen = log.length(); + final StringBuilder logUpdated = new StringBuilder(); + + for (int i = 0; i < logLen; i++) { + char c = log.charAt(i); + + if (c > 300) { + logUpdated.append("&#"); + logUpdated.append(Integer.toString((int) c)); + logUpdated.append(';'); + } else { + logUpdated.append(c); + } + } + log = logUpdated.toString(); + + log = log.replace("\n", "\r\n"); // windows' eol + + if (trackables != null) { + Log.i(cgSettings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log + "; trackables: " + trackables.size()); + } else { + Log.i(cgSettings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log + "; trackables: 0"); + } + + final String host = "www.geocaching.com"; + final String path = "/seek/log.aspx?ID=" + cacheid; + final String method = "POST"; + final Map<String, String> params = new HashMap<String, String>(); + + setViewstates(viewstates, params); + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); + params.put("__LASTFOCUS", ""); + params.put("ctl00$ContentBody$LogBookPanel1$ddLogType", Integer.toString(logType)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", String.format("%02d", month) + "/" + String.format("%02d", day) + "/" + String.format("%04d", year)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Month", Integer.toString(month)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Day", Integer.toString(day)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Year", Integer.toString(year)); + params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); + params.put("ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry"); + params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); + if (trackables != null && trackables.isEmpty() == false) { // we have some trackables to proceed + final StringBuilder hdnSelected = new StringBuilder(); + + for (cgTrackableLog tb : trackables) { + final String action = Integer.toString(tb.id) + logTypesTrackableAction.get(tb.action); + + if (tb.action > 0) { + hdnSelected.append(action); + hdnSelected.append(','); + } + } + + params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnSelectedActions", hdnSelected.toString()); // selected trackables + params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); + } + + String page = request(false, host, path, method, params, false, false, false).getData(); + if (checkLogin(page) == false) { + int loginState = login(); + if (loginState == 1) { + page = request(false, host, path, method, params, false, false, false).getData(); + } else { + Log.e(cgSettings.tag, "cgeoBase.postLog: Can not log in geocaching (error: " + loginState + ")"); + return loginState; + } + } + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.postLog: No data from server"); + return 1002; + } + + // maintenance, archived needs to be confirmed + final Pattern pattern = Pattern.compile("<span id=\"ctl00_ContentBody_LogBookPanel1_lbConfirm\"[^>]*>([^<]*<font[^>]*>)?([^<]+)(</font>[^<]*)?</span>", Pattern.CASE_INSENSITIVE); + final Matcher matcher = pattern.matcher(page); + + try { + if (matcher.find() && matcher.groupCount() > 0) { + final String[] viewstatesConfirm = getViewstates(page); + + if (isEmpty(viewstatesConfirm)) { + Log.e(cgSettings.tag, "cgeoBase.postLog: No viewstate for confirm log"); + return 1000; + } + + params.clear(); + setViewstates(viewstatesConfirm, params); + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); + params.put("__LASTFOCUS", ""); + params.put("ctl00$ContentBody$LogBookPanel1$btnConfirm", "Yes"); + params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); + params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); + if (trackables != null && trackables.isEmpty() == false) { // we have some trackables to proceed + final StringBuilder hdnSelected = new StringBuilder(); + + for (cgTrackableLog tb : trackables) { + String ctl = null; + final String action = Integer.toString(tb.id) + logTypesTrackableAction.get(tb.action); + + if (tb.ctl < 10) { + ctl = "0" + Integer.toString(tb.ctl); + } else { + ctl = Integer.toString(tb.ctl); + } + + params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$repTravelBugs$ctl" + ctl + "$ddlAction", action); + if (tb.action > 0) { + hdnSelected.append(action); + hdnSelected.append(','); + } + } + + params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnSelectedActions", hdnSelected.toString()); // selected trackables + params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); + } + + page = request(false, host, path, method, params, false, false, false).getData(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.postLog.confim: " + e.toString()); + } + + try { + final Pattern patternOk = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_lbHeading\"[^>]*>[^<]*</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + final Matcher matcherOk = patternOk.matcher(page); + if (matcherOk.find()) { + Log.i(cgSettings.tag, "Log successfully posted to cache #" + cacheid); + + if (app != null && geocode != null) { + app.saveVisitDate(geocode); + } + + return 1; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.postLog.check: " + e.toString()); + } + + Log.e(cgSettings.tag, "cgeoBase.postLog: Failed to post log because of unknown error"); + return 1000; + } + + public int postLogTrackable(String tbid, String trackingCode, String[] viewstates, + int logType, int year, int month, int day, String log) { + if (isEmpty(viewstates)) { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No viewstate given"); + return 1000; + } + + if (logTypes2.containsKey(logType) == false) { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Unknown logtype"); + return 1000; + } + + if (StringUtils.isBlank(log)) { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No log text given"); + return 1001; + } + + Log.i(cgSettings.tag, "Trying to post log for trackable #" + trackingCode + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log); + + log = log.replace("\n", "\r\n"); // windows' eol + + final Calendar currentDate = Calendar.getInstance(); + final String host = "www.geocaching.com"; + final String path = "/track/log.aspx?wid=" + tbid; + final String method = "POST"; + final Map<String, String> params = new HashMap<String, String>(); + + setViewstates(viewstates, params); + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); + params.put("__LASTFOCUS", ""); + params.put("ctl00$ContentBody$LogBookPanel1$ddLogType", Integer.toString(logType)); + params.put("ctl00$ContentBody$LogBookPanel1$tbCode", trackingCode); + if (currentDate.get(Calendar.YEAR) == year && (currentDate.get(Calendar.MONTH) + 1) == month && currentDate.get(Calendar.DATE) == day) { + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", ""); + } else { + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", Integer.toString(month) + "/" + Integer.toString(day) + "/" + Integer.toString(year)); + } + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Day", Integer.toString(day)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Month", Integer.toString(month)); + params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged$Year", Integer.toString(year)); + params.put("ctl00$ContentBody$LogBookPanel1$uxLogInfo", log); + params.put("ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry"); + params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); + + String page = request(false, host, path, method, params, false, false, false).getData(); + if (checkLogin(page) == false) { + int loginState = login(); + if (loginState == 1) { + page = request(false, host, path, method, params, false, false, false).getData(); + } else { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Can not log in geocaching (error: " + loginState + ")"); + return loginState; + } + } + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: No data from server"); + return 1002; + } + + try { + final Pattern patternOk = Pattern.compile("<div id=[\"|']ctl00_ContentBody_LogBookPanel1_ViewLogPanel[\"|']>", Pattern.CASE_INSENSITIVE); + final Matcher matcherOk = patternOk.matcher(page); + if (matcherOk.find()) { + Log.i(cgSettings.tag, "Log successfully posted to trackable #" + trackingCode); + return 1; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable.check: " + e.toString()); + } + + Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Failed to post log because of unknown error"); + return 1000; + } /** * Adds the cache to the watchlist of the user. - * - * @param cache the cache to add - * @return -1: error occured + * + * @param cache + * the cache to add + * @return -1: error occured */ - public int addToWatchlist(cgCache cache) { + public int addToWatchlist(cgCache cache) { String page = requestLogged(false, "www.geocaching.com", "/my/watchlist.aspx?w=" + cache.cacheId, "POST", null, false, false, false); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgBase.addToWatchlist: No data from server"); - return -1; // error + return -1; // error } boolean guidOnPage = cache.isGuidContainedInPage(page); @@ -3470,1524 +3468,1538 @@ public class cgBase { Log.e(cgSettings.tag, "cgBase.addToWatchlist: cache is not on watchlist"); } return guidOnPage ? 1 : -1; // on watchlist (=added) / else: error - } - - /** - * Removes the cache from the watchlist - * - * @param cache the cache to remove - * @return -1: error occured - */ - public int removeFromWatchlist(cgCache cache) { - String host = "www.geocaching.com"; - String path = "/my/watchlist.aspx?ds=1&action=rem&id=" + cache.cacheId; - String method = "POST"; - - String page = requestLogged(false, host, path, method, null, false, false, false); - - if (StringUtils.isBlank(page)) { - Log.e(cgSettings.tag, "cgBase.removeFromWatchlist: No data from server"); - return -1; // error - } - - // removing cache from list needs approval by hitting "Yes" button - final Map<String, String> params = new HashMap<String, String>(); - transferViewstates(page, params); - params.put("__EVENTTARGET", ""); - params.put("__EVENTARGUMENT", ""); - params.put("ctl00$ContentBody$btnYes", "Yes"); - - page = request(false, host, path, method, params, false, false, false).getData(); - boolean guidOnPage = cache.isGuidContainedInPage(page); - if (! guidOnPage) { - Log.i(cgSettings.tag, "cgBase.removeFromWatchlist: cache removed from watchlist"); - cache.onWatchlist = false; - } else { - Log.e(cgSettings.tag, "cgBase.removeFromWatchlist: cache not removed from watchlist"); - } - return guidOnPage ? -1 : 0; // on watchlist (=error) / not on watchlist - } - - final public static HostnameVerifier doNotVerify = new HostnameVerifier() { - - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - public static void trustAllHosts() { - TrustManager[] trustAllCerts = new TrustManager[]{ - new X509TrustManager() { - - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[]{}; - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - } - }; - - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.trustAllHosts: " + e.toString()); - } - } - - public static void postTweetCache(cgeoapplication app, cgSettings settings, String geocode) { - final cgCache cache = app.getCacheByGeocode(geocode); - String name = cache.name; - if (name.length() > 84) { - name = name.substring(0, 81) + "..."; - } - final String status = "I found " + name + " (http://coord.info/" + cache.geocode.toUpperCase() + ")! #cgeo #geocaching"; // 56 chars + cache name - - postTweet(app, settings, status, null); - } - - public static void postTweetTrackable(cgeoapplication app, cgSettings settings, String geocode) { - final cgTrackable trackable = app.getTrackableByGeocode(geocode); - String name = trackable.name; - if (name.length() > 82) { - name = name.substring(0, 79) + "..."; - } - final String status = "I touched " + name + " (http://coord.info/" + trackable.geocode.toUpperCase() + ")! #cgeo #geocaching"; // 58 chars + trackable name - - postTweet(app, settings, status, null); - } - - public static void postTweet(cgeoapplication app, cgSettings settings, String status, final Geopoint coords) { - if (app == null) { - return; - } - if (settings == null || StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret)) { - return; - } - - try { - Map<String, String> parameters = new HashMap<String, String>(); - - parameters.put("status", status); - if (coords != null) { - parameters.put("lat", String.format("%.6f", coords.getLatitude())); - parameters.put("long", String.format("%.6f", coords.getLongitude())); - parameters.put("display_coordinates", "true"); - } - - final String paramsDone = cgOAuth.signOAuth("api.twitter.com", "/1/statuses/update.json", "POST", false, parameters, settings.tokenPublic, settings.tokenSecret); - - HttpURLConnection connection = null; - try { - final StringBuffer buffer = new StringBuffer(); - final URL u = new URL("http://api.twitter.com/1/statuses/update.json"); - final URLConnection uc = u.openConnection(); - - uc.setRequestProperty("Host", "api.twitter.com"); - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(30000); - connection.setRequestMethod("POST"); - HttpURLConnection.setFollowRedirects(true); - connection.setDoInput(true); - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(paramsDone); - wr.flush(); - wr.close(); - - Log.i(cgSettings.tag, "Twitter.com: " + connection.getResponseCode() + " " + connection.getResponseMessage()); - - InputStream ins; - final String encoding = connection.getContentEncoding(); - - if (encoding != null && encoding.equalsIgnoreCase("gzip")) { - ins = new GZIPInputStream(connection.getInputStream()); - } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { - ins = new InflaterInputStream(connection.getInputStream(), new Inflater(true)); - } else { - ins = connection.getInputStream(); - } - - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr); - - readIntoBuffer(br, buffer); - - br.close(); - ins.close(); - inr.close(); - connection.disconnect(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgBase.postTweet.IO: " + connection.getResponseCode() + ": " + connection.getResponseMessage() + " ~ " + e.toString()); - - final InputStream ins = connection.getErrorStream(); - final StringBuffer buffer = new StringBuffer(); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr); - - readIntoBuffer(br, buffer); - - br.close(); - ins.close(); - inr.close(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.postTweet.inner: " + e.toString()); - } - - connection.disconnect(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.postTweet: " + e.toString()); - } - } - - private static void readIntoBuffer(BufferedReader br, StringBuffer buffer) throws IOException { - int bufferSize = 1024*16; - char[] bytes = new char[bufferSize]; - int bytesRead; - while ((bytesRead = br.read(bytes)) > 0) { - if (bytesRead == bufferSize) { - buffer.append(bytes); - } - else { - buffer.append(bytes, 0, bytesRead); - } - } - } - - public static String getLocalIpAddress() { - try { - for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { - NetworkInterface intf = en.nextElement(); - for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress()) { - return inetAddress.getHostAddress(); - } - } - } - } catch (SocketException e) { - // nothing - } - - return null; - } - - public static String implode(String delim, Object[] array) { - StringBuilder out = new StringBuilder(); - - try { - for (int i = 0; i < array.length; i++) { - if (i != 0) { - out.append(delim); - } - out.append(array[i].toString()); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.implode: " + e.toString()); - } - return out.toString(); - } - - public static String urlencode_rfc3986(String text) { - final String encoded = URLEncoder.encode(text).replace("+", "%20").replaceAll("%7E", "~"); - - return encoded; - } - - public String prepareParameters(Map<String, String> params, boolean my, boolean addF) { - String paramsDone = null; - - if (my != true && settings.excludeMine > 0) { - if (params == null) { - params = new HashMap<String, String>(); - } - if (addF) { - params.put("f", "1"); - } - - Log.i(cgSettings.tag, "Skipping caches found or hidden by user."); - } - - if (params != null) { - Set<Map.Entry<String, String>> entrySet = params.entrySet(); - List<String> paramsEncoded = new ArrayList<String>(); - - for(Map.Entry<String, String> entry : entrySet) - { - String key = entry.getKey(); - String value = entry.getValue(); - - if (key.charAt(0) == '^') { - key = ""; - } - if (value == null) { - value = ""; - } - - paramsEncoded.add(key + "=" + urlencode_rfc3986(value)); - } - - paramsDone = implode("&", paramsEncoded.toArray()); - } else { - paramsDone = ""; - } - - return paramsDone; - } - - public String[] requestViewstates(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my) { - final cgResponse response = request(secure, host, path, method, params, xContentType, my, false); - - return getViewstates(response.getData()); - } - - public String requestLogged(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { - cgResponse response = request(secure, host, path, method, params, xContentType, my, addF); - String data = response.getData(); - - if (checkLogin(data) == false) { - int loginState = login(); - if (loginState == 1) { - response = request(secure, host, path, method, params, xContentType, my, addF); - data = response.getData(); - } else { - Log.i(cgSettings.tag, "Working as guest."); - } - } - - return data; - } - - public cgResponse request(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { - // prepare parameters - final String paramsDone = prepareParameters(params, my, addF); - - return request(secure, host, path, method, paramsDone, 0, xContentType); - } - - public cgResponse request(boolean secure, String host, String path, String method, Map<String, String> params, int requestId, boolean xContentType, boolean my, boolean addF) { - // prepare parameters - final String paramsDone = prepareParameters(params, my, addF); - - return request(secure, host, path, method, paramsDone, requestId, xContentType); - } - - public cgResponse request(boolean secure, String host, String path, String method, String params, int requestId, Boolean xContentType) { - URL u = null; - int httpCode = -1; - String httpMessage = null; - String httpLocation = null; - - if (requestId == 0) { - requestId = (int) (Math.random() * 1000); - } - - if (method == null || (method.equalsIgnoreCase("GET") == false && method.equalsIgnoreCase("POST") == false)) { - method = "POST"; - } else { - method = method.toUpperCase(); - } - - // https - String scheme = "http://"; - if (secure) { - scheme = "https://"; - } - - String cookiesDone = getCookiesAsString(); - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - StringBuffer buffer = null; - - for (int i = 0; i < 5; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); - } - - buffer = new StringBuffer(); - timeout = 30000 + (i * 10000); - - try { - if (method.equals("GET")) { - // GET - u = new URL(scheme + host + path + "?" + params); - uc = u.openConnection(); - - uc.setRequestProperty("Host", host); - uc.setRequestProperty("Cookie", cookiesDone); - if (xContentType) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - } - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); - // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); - connection.setDoInput(true); - connection.setDoOutput(false); - } else { - // POST - u = new URL(scheme + host + path); - uc = u.openConnection(); - - uc.setRequestProperty("Host", host); - uc.setRequestProperty("Cookie", cookiesDone); - if (xContentType) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - } - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); - // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); - connection.setDoInput(true); - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - } - - String headerName = null; - final SharedPreferences.Editor prefsEditor = prefs.edit(); - for (int j = 1; (headerName = uc.getHeaderFieldKey(j)) != null; j++) { - if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie")) { - int index; - String cookie = uc.getHeaderField(j); - - index = cookie.indexOf(";"); - if (index > -1) { - cookie = cookie.substring(0, cookie.indexOf(";")); - } - - index = cookie.indexOf("="); - if (index > - 1 && cookie.length() > (index + 1)) { - String name = cookie.substring(0, cookie.indexOf("=")); - String value = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); - - cookies.put(name, value); - prefsEditor.putString("cookie_" + name, value); - } - } - } - prefsEditor.commit(); - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr, 16 * 1024); - - readIntoBuffer(br, buffer); - - httpCode = connection.getResponseCode(); - httpMessage = connection.getResponseMessage(); - httpLocation = uc.getHeaderField("Location"); - - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + "|" + requestId, "[" + method + " " + (int)(params.length() / 1024) + "k | " + httpCode + " | " + (int)(buffer.length() / 1024) + "k] Downloaded " + scheme + host + path + "?" + paramsLog); - - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgeoBase.request.IOException: " + e.toString()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.request: " + e.toString()); - } - - if (buffer.length() > 0) { - break; - } - } - - cgResponse response = new cgResponse(); - - try { - if (httpCode == 302 && httpLocation != null) { - final Uri newLocation = Uri.parse(httpLocation); - if (newLocation.isRelative()) { - response = request(secure, host, path, "GET", new HashMap<String, String>(), requestId, false, false, false); - } else { - boolean secureRedir = false; - if (newLocation.getScheme().equals("https")) { - secureRedir = true; - } - response = request(secureRedir, newLocation.getHost(), newLocation.getPath(), "GET", new HashMap<String, String>(), requestId, false, false, false); - } - } else { - if (StringUtils.isNotEmpty(buffer)) { - replaceWhitespace(buffer); - String data = buffer.toString(); - buffer = null; - - if (data != null) { - response.setData(data); - } else { - response.setData(""); - } - response.setStatusCode(httpCode); - response.setStatusMessage(httpMessage); - response.setUrl(u.toString()); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.page: " + e.toString()); - } - - return response; - } - - private String getCookiesAsString() { - // prepare cookies - String cookiesDone = null; - if (cookies == null || cookies.isEmpty()) { - if (cookies == null) { - cookies = new HashMap<String, String>(); - } - - final Map<String, ?> prefsAll = prefs.getAll(); - final Set<? extends Map.Entry<String, ?>> entrySet = prefsAll.entrySet(); - - for(Map.Entry<String, ?> entry : entrySet){ - String key = entry.getKey(); - if (key.matches("cookie_.+")) { - final String cookieKey = key.substring(7); - final String cookieValue = (String) entry.getValue(); - - cookies.put(cookieKey, cookieValue); - } - } - } - - if (cookies != null) { - final Set<Map.Entry<String, String>> entrySet = cookies.entrySet(); - final List<String> cookiesEncoded = new ArrayList<String>(); - - for(Map.Entry<String, String> entry : entrySet){ - cookiesEncoded.add(entry.getKey() + "=" + entry.getValue()); - } - - if (cookiesEncoded.size() > 0) { - cookiesDone = implode("; ", cookiesEncoded.toArray()); - } - } - - if (cookiesDone == null) { - Map<String, ?> prefsValues = prefs.getAll(); - - if (CollectionUtils.isNotEmpty(prefsValues)) { - final Set<? extends Map.Entry<String, ?>> entrySet = prefsValues.entrySet(); - final List<String> cookiesEncoded = new ArrayList<String>(); - - for(Map.Entry<String, ?> entry : entrySet){ - String key = entry.getKey(); - if (key.length() > 7 && key.substring(0, 7).equals("cookie_")) { - cookiesEncoded.add(key + "=" + entry.getValue()); - } - } - - if (cookiesEncoded.size() > 0) { - cookiesDone = implode("; ", cookiesEncoded.toArray()); - } - } - } - - if (cookiesDone == null) { - cookiesDone = ""; - } - return cookiesDone; - } - - /** - * Replace the characters \n, \r and \t with a space - * @param buffer The data - */ - public static void replaceWhitespace(final StringBuffer buffer) { - final int length = buffer.length(); - final char[] chars = new char[length]; - buffer.getChars(0, length, chars, 0); - int resultSize = 0; - boolean lastWasWhitespace = false; - for (char c : chars) { - if (c == ' ' || c == '\n' || c == '\r' || c == '\t') { - if (!lastWasWhitespace) { - chars[resultSize++] =' '; - } - lastWasWhitespace = true; - } else { - chars[resultSize++] = c; - lastWasWhitespace = false; - } - } - buffer.setLength(0); - buffer.append(chars); - } - - public String requestJSONgc(String host, String path, String params) { - int httpCode = -1; - String httpLocation = null; - - String cookiesDone = getCookiesAsString(); - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - final StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < 3; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); - } - - buffer.delete(0, buffer.length()); - timeout = 30000 + (i * 15000); - - try { - // POST - final URL u = new URL("http://" + host + path); - uc = u.openConnection(); - - uc.setRequestProperty("Host", host); - uc.setRequestProperty("Cookie", cookiesDone); - uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); - uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); - uc.setRequestProperty("Referer", host + "/" + path); - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod("POST"); - HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) - connection.setDoInput(true); - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - - String headerName = null; - final SharedPreferences.Editor prefsEditor = prefs.edit(); - for (int j = 1; (headerName = uc.getHeaderFieldKey(j)) != null; j++) { - if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie")) { - int index; - String cookie = uc.getHeaderField(j); - - index = cookie.indexOf(";"); - if (index > -1) { - cookie = cookie.substring(0, cookie.indexOf(";")); - } - - index = cookie.indexOf("="); - if (index > - 1 && cookie.length() > (index + 1)) { - String name = cookie.substring(0, cookie.indexOf("=")); - String value = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); - - cookies.put(name, value); - prefsEditor.putString("cookie_" + name, value); - } - } - } - prefsEditor.commit(); - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr); - - readIntoBuffer(br, buffer); - - httpCode = connection.getResponseCode(); - httpLocation = uc.getHeaderField("Location"); - - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + " | JSON", "[POST " + (int)(params.length() / 1024) + "k | " + httpCode + " | " + (int)(buffer.length() / 1024) + "k] Downloaded " + "http://" + host + path + "?" + paramsLog); - - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSONgc.IOException: " + e.toString()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSONgc: " + e.toString()); - } - - if (buffer != null && buffer.length() > 0) { - break; - } - } - - String page = null; - if (httpCode == 302 && httpLocation != null) { - final Uri newLocation = Uri.parse(httpLocation); - if (newLocation.isRelative()) { - page = requestJSONgc(host, path, params); - } else { - page = requestJSONgc(newLocation.getHost(), newLocation.getPath(), params); - } - } else { - replaceWhitespace(buffer); - page = buffer.toString(); - } - - if (page != null) { - return page; - } else { - return ""; - } - } - - private static InputStream getInputstreamFromConnection(HttpURLConnection connection) throws IOException { - final String encoding = connection.getContentEncoding(); - InputStream ins; - - if (encoding != null && encoding.equalsIgnoreCase("gzip")) { - ins = new GZIPInputStream(connection.getInputStream()); - } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { - ins = new InflaterInputStream(connection.getInputStream(), new Inflater(true)); - } else { - ins = connection.getInputStream(); - } - return ins; - } - - public static String requestJSON(String host, String path, String params) { - return requestJSON("http://", host, path, "GET", params); - } - - public static String requestJSON(String scheme, String host, String path, String method, String params) { - int httpCode = -1; - //String httpLocation = null; - - if (method == null) { - method = "GET"; - } else { - method = method.toUpperCase(); - } - - boolean methodPost = false; - if (method.equalsIgnoreCase("POST")) { - methodPost = true; - } - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - final StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < 3; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); - } - - buffer.delete(0, buffer.length()); - timeout = 30000 + (i * 15000); - - try { - try { - URL u = null; - if (methodPost) { - u = new URL(scheme + host + path); - } else { - u = new URL(scheme + host + path + "?" + params); - } - - if (u.getProtocol().toLowerCase().equals("https")) { - trustAllHosts(); - HttpsURLConnection https = (HttpsURLConnection) u.openConnection(); - https.setHostnameVerifier(doNotVerify); - uc = https; - } else { - uc = (HttpURLConnection) u.openConnection(); - } - - uc.setRequestProperty("Host", host); - uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); - if (methodPost) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - uc.setRequestProperty("Content-Length", Integer.toString(params.length())); - uc.setRequestProperty("X-HTTP-Method-Override", "GET"); - } else { - uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - } - uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) - connection.setDoInput(true); - if (methodPost) { - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - } else { - connection.setDoOutput(false); - } - - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr, 1024); - - readIntoBuffer(br, buffer); - - httpCode = connection.getResponseCode(); - - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + " | JSON", "[POST " + (int)(params.length() / 1024) + "k | " + httpCode + " | " + (int)(buffer.length() / 1024) + "k] Downloaded " + "http://" + host + path + "?" + paramsLog); - - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - httpCode = connection.getResponseCode(); - - Log.e(cgSettings.tag, "cgeoBase.requestJSON.IOException: " + httpCode + ": " + connection.getResponseMessage() + " ~ " + e.toString()); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSON: " + e.toString()); - } - - if (StringUtils.isNotBlank(buffer)) { - break; - } - - if (httpCode == 403) { - // we're not allowed to download content, so let's move - break; - } - } - - String page = null; - //This is reported as beeing deadCode (httpLocation is always null) - //2011-08-09 - 302 is redirect so something should probably be done - /*if (httpCode == 302 && httpLocation != null) { - final Uri newLocation = Uri.parse(httpLocation); - if (newLocation.isRelative()) { - page = requestJSONgc(host, path, params); - } else { - page = requestJSONgc(newLocation.getHost(), newLocation.getPath(), params); - } - } else {*/ - replaceWhitespace(buffer); - page = buffer.toString(); - //} - - if (page != null) { - return page; - } else { - return ""; - } - } - - public static String rot13(String text) { - final StringBuilder result = new StringBuilder(); - // plaintext flag (do not convert) - boolean plaintext = false; - - int length = text.length(); - for (int index = 0; index < length; index++) { - int c = text.charAt(index); - if (c == '[') { - plaintext = true; - } else if (c == ']') { - plaintext = false; - } else if (!plaintext) { - int capitalized = c & 32; - c &= ~capitalized; - c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) - | capitalized; - } - result.append((char) c); - } - return result.toString(); - } - - public static String md5(String text) { - String hashed = ""; - - try { - MessageDigest digest = MessageDigest.getInstance("MD5"); - digest.update(text.getBytes(), 0, text.length()); - hashed = new BigInteger(1, digest.digest()).toString(16); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.md5: " + e.toString()); - } - - return hashed; - } - - public static String sha1(String text) { - String hashed = ""; - - try { - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.update(text.getBytes(), 0, text.length()); - hashed = new BigInteger(1, digest.digest()).toString(16); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.sha1: " + e.toString()); - } - - return hashed; - } - - public static byte[] hashHmac(String text, String salt) { - byte[] macBytes = {}; - - try { - SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(), "HmacSHA1"); - Mac mac = Mac.getInstance("HmacSHA1"); - mac.init(secretKeySpec); - macBytes = mac.doFinal(text.getBytes()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.hashHmac: " + e.toString()); - } - - return macBytes; - } - - public static boolean deleteDirectory(File path) { - if (path.exists()) { - File[] files = path.listFiles(); - - for (File file : files) { - if (file.isDirectory()) { - deleteDirectory(file); - } else { - file.delete(); - } - } - } - - return (path.delete()); - } - - public void storeCache(cgeoapplication app, Activity activity, cgCache cache, String geocode, int listId, Handler handler) { - try { - // get cache details, they may not yet be complete - if (cache != null) { - // only reload the cache, if it was already stored or has not all details (by checking the description) - if (cache.reason > 0 || StringUtils.isBlank(cache.description)) { - final Map<String, String> params = new HashMap<String, String>(); - params.put("geocode", cache.geocode); - final UUID searchId = searchByGeocode(params, listId, false); - cache = app.getCache(searchId); - } - } else if (StringUtils.isNotBlank(geocode)) { - final Map<String, String> params = new HashMap<String, String>(); - params.put("geocode", geocode); - final UUID searchId = searchByGeocode(params, listId, false); - cache = app.getCache(searchId); - } - - if (cache == null) { - if (handler != null) { - handler.sendMessage(new Message()); - } - - return; - } - - final cgHtmlImg imgGetter = new cgHtmlImg(activity, cache.geocode, false, listId, true); - - // store images from description - if (StringUtils.isNotBlank(cache.description)) { - Html.fromHtml(cache.description, imgGetter, null); - } - - // store spoilers - if (CollectionUtils.isNotEmpty(cache.spoilers)) { - for (cgImage oneSpoiler : cache.spoilers) { - imgGetter.getDrawable(oneSpoiler.url); - } - } - - // store images from logs - if (settings.storelogimages) { - for (cgLog log : cache.logs) { - if (CollectionUtils.isNotEmpty(log.logImages)) { - for (cgImage oneLogImg : log.logImages) { - imgGetter.getDrawable(oneLogImg.url); - } - } - } - } - - // store map previews - StaticMapsProvider.downloadMaps(cache, settings, activity); - - app.markStored(cache.geocode, listId); - app.removeCacheFromCache(cache.geocode); - - if (handler != null) { - handler.sendMessage(new Message()); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.storeCache: " + e.toString()); - } - } - - public static void dropCache(cgeoapplication app, Activity activity, cgCache cache, Handler handler) { - try { - app.markDropped(cache.geocode); - app.removeCacheFromCache(cache.geocode); - - handler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.dropCache: " + e.toString()); - } - } - - public static boolean isInViewPort(int centerLat1, int centerLon1, int centerLat2, int centerLon2, int spanLat1, int spanLon1, int spanLat2, int spanLon2) { - try { - // expects coordinates in E6 format - final int left1 = centerLat1 - (spanLat1 / 2); - final int right1 = centerLat1 + (spanLat1 / 2); - final int top1 = centerLon1 + (spanLon1 / 2); - final int bottom1 = centerLon1 - (spanLon1 / 2); - - final int left2 = centerLat2 - (spanLat2 / 2); - final int right2 = centerLat2 + (spanLat2 / 2); - final int top2 = centerLon2 + (spanLon2 / 2); - final int bottom2 = centerLon2 - (spanLon2 / 2); - - if (left2 <= left1) { - return false; - } - if (right2 >= right1) { - return false; - } - if (top2 >= top1) { - return false; - } - if (bottom2 <= bottom1) { - return false; - } - - return true; - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.isInViewPort: " + e.toString()); - return false; - } - } - - public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint cacheCoords) { - if (cacheCoords == null) { - return false; - } - - // viewport is defined by center, span and some (10%) reserve on every side - int minLat = centerLat - (spanLat / 2) - (spanLat / 10); - int maxLat = centerLat + (spanLat / 2) + (spanLat / 10); - int minLon = centerLon - (spanLon / 2) - (spanLon / 10); - int maxLon = centerLon + (spanLon / 2) + (spanLon / 10); - final int cLat = cacheCoords.getLatitudeE6(); - final int cLon = cacheCoords.getLongitudeE6(); - int mid = 0; - - if (maxLat < minLat) { - mid = minLat; - minLat = maxLat; - maxLat = mid; - } - - if (maxLon < minLon) { - mid = minLon; - minLon = maxLon; - maxLon = mid; - } - - boolean latOk = false; - boolean lonOk = false; - - if (cLat >= minLat && cLat <= maxLat) { - latOk = true; - } - if (cLon >= minLon && cLon <= maxLon) { - lonOk = true; - } - - if (latOk && lonOk) { - return true; - } else { - return false; - } - } - private static char[] base64map1 = new char[64]; - - static { - int i = 0; - for (char c = 'A'; c <= 'Z'; c++) { - base64map1[i++] = c; - } - for (char c = 'a'; c <= 'z'; c++) { - base64map1[i++] = c; - } - for (char c = '0'; c <= '9'; c++) { - base64map1[i++] = c; - } - base64map1[i++] = '+'; - base64map1[i++] = '/'; - } - private static byte[] base64map2 = new byte[128]; - - static { - for (int i = 0; i < base64map2.length; i++) { - base64map2[i] = -1; - } - for (int i = 0; i < 64; i++) { - base64map2[base64map1[i]] = (byte) i; - } - } - - public static String base64Encode(byte[] in) { - int iLen = in.length; - int oDataLen = (iLen * 4 + 2) / 3; // output length without padding - int oLen = ((iLen + 2) / 3) * 4; // output length including padding - char[] out = new char[oLen]; - int ip = 0; - int op = 0; - - while (ip < iLen) { - int i0 = in[ip++] & 0xff; - int i1 = ip < iLen ? in[ip++] & 0xff : 0; - int i2 = ip < iLen ? in[ip++] & 0xff : 0; - int o0 = i0 >>> 2; - int o1 = ((i0 & 3) << 4) | (i1 >>> 4); - int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); - int o3 = i2 & 0x3F; - out[op++] = base64map1[o0]; - out[op++] = base64map1[o1]; - out[op] = op < oDataLen ? base64map1[o2] : '='; - op++; - out[op] = op < oDataLen ? base64map1[o3] : '='; - op++; - } - - return new String(out); - } - - public static byte[] base64Decode(String text) { - char[] in = text.toCharArray(); - - int iLen = in.length; - if (iLen % 4 != 0) { - throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); - } - while (iLen > 0 && in[iLen - 1] == '=') { - iLen--; - } - int oLen = (iLen * 3) / 4; - byte[] out = new byte[oLen]; - int ip = 0; - int op = 0; - while (ip < iLen) { - int i0 = in[ip++]; - int i1 = in[ip++]; - int i2 = ip < iLen ? in[ip++] : 'A'; - int i3 = ip < iLen ? in[ip++] : 'A'; - if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) { - throw new IllegalArgumentException("Illegal character in Base64 encoded data."); - } - int b0 = base64map2[i0]; - int b1 = base64map2[i1]; - int b2 = base64map2[i2]; - int b3 = base64map2[i3]; - if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) { - throw new IllegalArgumentException("Illegal character in Base64 encoded data."); - } - int o0 = (b0 << 2) | (b1 >>> 4); - int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); - int o2 = ((b2 & 3) << 6) | b3; - out[op++] = (byte) o0; - if (op < oLen) { - out[op++] = (byte) o1; - } - if (op < oLen) { - out[op++] = (byte) o2; - } - } - return out; - } - - public static int getCacheIcon(final String type) { - fillIconsMap(); - Integer iconId = gcIcons.get("type_" + type); - if (iconId != null) { - return iconId; - } - // fallback to traditional if some icon type is not correct - return gcIcons.get("type_traditional"); - } - - public static int getMarkerIcon(final boolean cache, final String type, final boolean own, final boolean found, final boolean disabled) { - fillIconsMap(); - - if (wpIcons.isEmpty()) { - wpIcons.put("waypoint", R.drawable.marker_waypoint_waypoint); - wpIcons.put("flag", R.drawable.marker_waypoint_flag); - wpIcons.put("pkg", R.drawable.marker_waypoint_pkg); - wpIcons.put("puzzle", R.drawable.marker_waypoint_puzzle); - wpIcons.put("stage", R.drawable.marker_waypoint_stage); - wpIcons.put("trailhead", R.drawable.marker_waypoint_trailhead); - } - - int icon = -1; - String iconTxt = null; - - if (cache) { - if (StringUtils.isNotBlank(type)) { - if (own) { - iconTxt = type + "-own"; - } else if (found) { - iconTxt = type + "-found"; - } else if (disabled) { - iconTxt = type + "-disabled"; - } else { - iconTxt = type; - } - } else { - iconTxt = "traditional"; - } - - if (gcIcons.containsKey(iconTxt)) { - icon = gcIcons.get(iconTxt); - } else { - icon = gcIcons.get("traditional"); - } - } else { - if (StringUtils.isNotBlank(type)) { - iconTxt = type; - } else { - iconTxt = "waypoint"; - } - - if (wpIcons.containsKey(iconTxt)) { - icon = wpIcons.get(iconTxt); - } else { - icon = wpIcons.get("waypoint"); - } - } - - return icon; - } - - private static void fillIconsMap() { - if (gcIcons.isEmpty()) { - gcIcons.put("type_ape", R.drawable.type_ape); - gcIcons.put("type_cito", R.drawable.type_cito); - gcIcons.put("type_earth", R.drawable.type_earth); - gcIcons.put("type_event", R.drawable.type_event); - gcIcons.put("type_letterbox", R.drawable.type_letterbox); - gcIcons.put("type_locationless", R.drawable.type_locationless); - gcIcons.put("type_mega", R.drawable.type_mega); - gcIcons.put("type_multi", R.drawable.type_multi); - gcIcons.put("type_traditional", R.drawable.type_traditional); - gcIcons.put("type_virtual", R.drawable.type_virtual); - gcIcons.put("type_webcam", R.drawable.type_webcam); - gcIcons.put("type_wherigo", R.drawable.type_wherigo); - gcIcons.put("type_mystery", R.drawable.type_mystery); - gcIcons.put("type_gchq", R.drawable.type_hq); - // default markers - gcIcons.put("ape", R.drawable.marker_cache_ape); - gcIcons.put("cito", R.drawable.marker_cache_cito); - gcIcons.put("earth", R.drawable.marker_cache_earth); - gcIcons.put("event", R.drawable.marker_cache_event); - gcIcons.put("letterbox", R.drawable.marker_cache_letterbox); - gcIcons.put("locationless", R.drawable.marker_cache_locationless); - gcIcons.put("mega", R.drawable.marker_cache_mega); - gcIcons.put("multi", R.drawable.marker_cache_multi); - gcIcons.put("traditional", R.drawable.marker_cache_traditional); - gcIcons.put("virtual", R.drawable.marker_cache_virtual); - gcIcons.put("webcam", R.drawable.marker_cache_webcam); - gcIcons.put("wherigo", R.drawable.marker_cache_wherigo); - gcIcons.put("mystery", R.drawable.marker_cache_mystery); - gcIcons.put("gchq", R.drawable.marker_cache_gchq); - // own cache markers - gcIcons.put("ape-own", R.drawable.marker_cache_ape_own); - gcIcons.put("cito-own", R.drawable.marker_cache_cito_own); - gcIcons.put("earth-own", R.drawable.marker_cache_earth_own); - gcIcons.put("event-own", R.drawable.marker_cache_event_own); - gcIcons.put("letterbox-own", R.drawable.marker_cache_letterbox_own); - gcIcons.put("locationless-own", R.drawable.marker_cache_locationless_own); - gcIcons.put("mega-own", R.drawable.marker_cache_mega_own); - gcIcons.put("multi-own", R.drawable.marker_cache_multi_own); - gcIcons.put("traditional-own", R.drawable.marker_cache_traditional_own); - gcIcons.put("virtual-own", R.drawable.marker_cache_virtual_own); - gcIcons.put("webcam-own", R.drawable.marker_cache_webcam_own); - gcIcons.put("wherigo-own", R.drawable.marker_cache_wherigo_own); - gcIcons.put("mystery-own", R.drawable.marker_cache_mystery_own); - gcIcons.put("gchq-own", R.drawable.marker_cache_gchq_own); - // found cache markers - gcIcons.put("ape-found", R.drawable.marker_cache_ape_found); - gcIcons.put("cito-found", R.drawable.marker_cache_cito_found); - gcIcons.put("earth-found", R.drawable.marker_cache_earth_found); - gcIcons.put("event-found", R.drawable.marker_cache_event_found); - gcIcons.put("letterbox-found", R.drawable.marker_cache_letterbox_found); - gcIcons.put("locationless-found", R.drawable.marker_cache_locationless_found); - gcIcons.put("mega-found", R.drawable.marker_cache_mega_found); - gcIcons.put("multi-found", R.drawable.marker_cache_multi_found); - gcIcons.put("traditional-found", R.drawable.marker_cache_traditional_found); - gcIcons.put("virtual-found", R.drawable.marker_cache_virtual_found); - gcIcons.put("webcam-found", R.drawable.marker_cache_webcam_found); - gcIcons.put("wherigo-found", R.drawable.marker_cache_wherigo_found); - gcIcons.put("mystery-found", R.drawable.marker_cache_mystery_found); - gcIcons.put("gchq-found", R.drawable.marker_cache_gchq_found); - // disabled cache markers - gcIcons.put("ape-disabled", R.drawable.marker_cache_ape_disabled); - gcIcons.put("cito-disabled", R.drawable.marker_cache_cito_disabled); - gcIcons.put("earth-disabled", R.drawable.marker_cache_earth_disabled); - gcIcons.put("event-disabled", R.drawable.marker_cache_event_disabled); - gcIcons.put("letterbox-disabled", R.drawable.marker_cache_letterbox_disabled); - gcIcons.put("locationless-disabled", R.drawable.marker_cache_locationless_disabled); - gcIcons.put("mega-disabled", R.drawable.marker_cache_mega_disabled); - gcIcons.put("multi-disabled", R.drawable.marker_cache_multi_disabled); - gcIcons.put("traditional-disabled", R.drawable.marker_cache_traditional_disabled); - gcIcons.put("virtual-disabled", R.drawable.marker_cache_virtual_disabled); - gcIcons.put("webcam-disabled", R.drawable.marker_cache_webcam_disabled); - gcIcons.put("wherigo-disabled", R.drawable.marker_cache_wherigo_disabled); - gcIcons.put("mystery-disabled", R.drawable.marker_cache_mystery_disabled); - gcIcons.put("gchq-disabled", R.drawable.marker_cache_gchq_disabled); - } - } - - public static boolean runNavigation(Activity activity, Resources res, cgSettings settings, final Geopoint coords) { - return runNavigation(activity, res, settings, coords, null); - } - - public static boolean runNavigation(Activity activity, Resources res, cgSettings settings, final Geopoint coords, final Geopoint coordsNow) { - if (activity == null) { - return false; - } - if (settings == null) { - return false; - } - - // Google Navigation - if (settings.useGNavigation == 1) { - try { - activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:ll=" + coords.getLatitude() + "," + coords.getLongitude()))); - - return true; - } catch (Exception e) { - // nothing - } - } - - // Google Maps Directions - try { - if (coordsNow != null) { - activity.startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("http://maps.google.com/maps?f=d&saddr=" + coordsNow.getLatitude() + "," + coordsNow.getLongitude() + - "&daddr=" + coords.getLatitude() + "," + coords.getLongitude()))); - } else { - activity.startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("http://maps.google.com/maps?f=d&daddr=" + coords.getLatitude() + "," + coords.getLongitude()))); - } - - return true; - } catch (Exception e) { - // nothing - } - - Log.i(cgSettings.tag, "cgBase.runNavigation: No navigation application available."); - - if (res != null) { - ActivityMixin.showToast(activity, res.getString(R.string.err_navigation_no)); - } - - return false; - } - - public String getMapUserToken(Handler noTokenHandler) { - final cgResponse response = request(false, "www.geocaching.com", "/map/default.aspx", "GET", "", 0, false); - final String data = response.getData(); - String usertoken = null; - - if (StringUtils.isNotBlank(data)) { - final Pattern pattern = Pattern.compile("var userToken[^=]*=[^']*'([^']+)';", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - - final Matcher matcher = pattern.matcher(data); - while (matcher.find()) { - if (matcher.groupCount() > 0) { - usertoken = matcher.group(1); - } - } - } - - if (noTokenHandler != null && StringUtils.isBlank(usertoken)) { - noTokenHandler.sendEmptyMessage(0); - } - - return usertoken; - } - - public static Double getElevation(final Geopoint coords) { - try { - final String host = "maps.googleapis.com"; - final String path = "/maps/api/elevation/json"; - final String params = "sensor=false&locations=" + - String.format((Locale) null, "%.6f", coords.getLatitude()) + "," + - String.format((Locale) null, "%.6f", coords.getLongitude()); - - final String data = requestJSON(host, path, params); - - if (StringUtils.isBlank(data)) { - return null; - } - - JSONObject response = new JSONObject(data); - String status = response.getString("status"); - - if (status == null || status.equalsIgnoreCase("OK") == false) { - return null; - } - - if (response.has("results")) { - JSONArray results = response.getJSONArray("results"); - JSONObject result = results.getJSONObject(0); - return result.getDouble("elevation"); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgBase.getElevation: " + e.toString()); - } - - return null; - } - - /** - * Generate a time string according to system-wide settings (locale, 12/24 hour) - * such as "13:24". - * - * @param date milliseconds since the epoch - * @return the formatted string - */ - public String formatTime(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME); - } - - /** - * Generate a date string according to system-wide settings (locale, date format) - * such as "20 December" or "20 December 2010". The year will only be included when necessary. - * - * @param date milliseconds since the epoch - * @return the formatted string - */ - public String formatDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE); - } - - /** - * Generate a date string according to system-wide settings (locale, date format) - * such as "20 December 2010". The year will always be included, making it suitable - * to generate long-lived log entries. - * - * @param date milliseconds since the epoch - * @return the formatted string - */ - public String formatFullDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_SHOW_YEAR); - } - - /** - * Generate a numeric date string according to system-wide settings (locale, date format) - * such as "10/20/2010". - * - * @param date milliseconds since the epoch - * @return the formatted string - */ - public String formatShortDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_NUMERIC_DATE); - } - - /** - * Generate a numeric date and time string according to system-wide settings (locale, - * date format) such as "7 sept. à 12:35". - * - * @param context a Context - * @param date milliseconds since the epoch - * @return the formatted string - */ - public static String formatShortDateTime(Context context, long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL); - } - - /** - * TODO This method is only needed until the settings are a singleton - * @return - */ - public String getUserName() { - return settings.getUsername(); - } - - /** - * insert text into the EditText at the current cursor position - * @param editText - * @param insertText - * @param addSpace add a space character, if there is no whitespace before the current cursor position - */ - static void insertAtPosition(final EditText editText, String insertText, final boolean addSpace) { - int selectionStart = editText.getSelectionStart(); - int selectionEnd = editText.getSelectionEnd(); - int start = Math.min(selectionStart, selectionEnd); - int end = Math.max(selectionStart, selectionEnd); - - String content = editText.getText().toString(); - if (start > 0 && !Character.isWhitespace(content.charAt(start - 1))) { - insertText = " " + insertText; - } - - editText.getText().replace(start, end, insertText); - int newCursor = start + insertText.length(); - editText.setSelection(newCursor, newCursor); - } + } + + /** + * Removes the cache from the watchlist + * + * @param cache + * the cache to remove + * @return -1: error occured + */ + public int removeFromWatchlist(cgCache cache) { + String host = "www.geocaching.com"; + String path = "/my/watchlist.aspx?ds=1&action=rem&id=" + cache.cacheId; + String method = "POST"; + + String page = requestLogged(false, host, path, method, null, false, false, false); + + if (StringUtils.isBlank(page)) { + Log.e(cgSettings.tag, "cgBase.removeFromWatchlist: No data from server"); + return -1; // error + } + + // removing cache from list needs approval by hitting "Yes" button + final Map<String, String> params = new HashMap<String, String>(); + transferViewstates(page, params); + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); + params.put("ctl00$ContentBody$btnYes", "Yes"); + + page = request(false, host, path, method, params, false, false, false).getData(); + boolean guidOnPage = cache.isGuidContainedInPage(page); + if (!guidOnPage) { + Log.i(cgSettings.tag, "cgBase.removeFromWatchlist: cache removed from watchlist"); + cache.onWatchlist = false; + } else { + Log.e(cgSettings.tag, "cgBase.removeFromWatchlist: cache not removed from watchlist"); + } + return guidOnPage ? -1 : 0; // on watchlist (=error) / not on watchlist + } + + final public static HostnameVerifier doNotVerify = new HostnameVerifier() { + + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + public static void trustAllHosts() { + TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() { + + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[] {}; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + } + }; + + try { + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.trustAllHosts: " + e.toString()); + } + } + + public static void postTweetCache(cgeoapplication app, cgSettings settings, String geocode) { + final cgCache cache = app.getCacheByGeocode(geocode); + String name = cache.name; + if (name.length() > 84) { + name = name.substring(0, 81) + "..."; + } + final String status = "I found " + name + " (http://coord.info/" + cache.geocode.toUpperCase() + ")! #cgeo #geocaching"; // 56 chars + cache name + + postTweet(app, settings, status, null); + } + + public static void postTweetTrackable(cgeoapplication app, cgSettings settings, String geocode) { + final cgTrackable trackable = app.getTrackableByGeocode(geocode); + String name = trackable.name; + if (name.length() > 82) { + name = name.substring(0, 79) + "..."; + } + final String status = "I touched " + name + " (http://coord.info/" + trackable.geocode.toUpperCase() + ")! #cgeo #geocaching"; // 58 chars + trackable name + + postTweet(app, settings, status, null); + } + + public static void postTweet(cgeoapplication app, cgSettings settings, String status, final Geopoint coords) { + if (app == null) { + return; + } + if (settings == null || StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret)) { + return; + } + + try { + Map<String, String> parameters = new HashMap<String, String>(); + + parameters.put("status", status); + if (coords != null) { + parameters.put("lat", String.format("%.6f", coords.getLatitude())); + parameters.put("long", String.format("%.6f", coords.getLongitude())); + parameters.put("display_coordinates", "true"); + } + + final String paramsDone = cgOAuth.signOAuth("api.twitter.com", "/1/statuses/update.json", "POST", false, parameters, settings.tokenPublic, settings.tokenSecret); + + HttpURLConnection connection = null; + try { + final StringBuffer buffer = new StringBuffer(); + final URL u = new URL("http://api.twitter.com/1/statuses/update.json"); + final URLConnection uc = u.openConnection(); + + uc.setRequestProperty("Host", "api.twitter.com"); + + connection = (HttpURLConnection) uc; + connection.setReadTimeout(30000); + connection.setRequestMethod("POST"); + HttpURLConnection.setFollowRedirects(true); + connection.setDoInput(true); + connection.setDoOutput(true); + + final OutputStream out = connection.getOutputStream(); + final OutputStreamWriter wr = new OutputStreamWriter(out); + wr.write(paramsDone); + wr.flush(); + wr.close(); + + Log.i(cgSettings.tag, "Twitter.com: " + connection.getResponseCode() + " " + connection.getResponseMessage()); + + InputStream ins; + final String encoding = connection.getContentEncoding(); + + if (encoding != null && encoding.equalsIgnoreCase("gzip")) { + ins = new GZIPInputStream(connection.getInputStream()); + } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { + ins = new InflaterInputStream(connection.getInputStream(), new Inflater(true)); + } else { + ins = connection.getInputStream(); + } + + final InputStreamReader inr = new InputStreamReader(ins); + final BufferedReader br = new BufferedReader(inr); + + readIntoBuffer(br, buffer); + + br.close(); + ins.close(); + inr.close(); + connection.disconnect(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgBase.postTweet.IO: " + connection.getResponseCode() + ": " + connection.getResponseMessage() + " ~ " + e.toString()); + + final InputStream ins = connection.getErrorStream(); + final StringBuffer buffer = new StringBuffer(); + final InputStreamReader inr = new InputStreamReader(ins); + final BufferedReader br = new BufferedReader(inr); + + readIntoBuffer(br, buffer); + + br.close(); + ins.close(); + inr.close(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.postTweet.inner: " + e.toString()); + } + + connection.disconnect(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.postTweet: " + e.toString()); + } + } + + private static void readIntoBuffer(BufferedReader br, StringBuffer buffer) throws IOException { + int bufferSize = 1024 * 16; + char[] bytes = new char[bufferSize]; + int bytesRead; + while ((bytesRead = br.read(bytes)) > 0) { + if (bytesRead == bufferSize) { + buffer.append(bytes); + } + else { + buffer.append(bytes, 0, bytesRead); + } + } + } + + public static String getLocalIpAddress() { + try { + for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { + NetworkInterface intf = en.nextElement(); + for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) { + return inetAddress.getHostAddress(); + } + } + } + } catch (SocketException e) { + // nothing + } + + return null; + } + + public static String implode(String delim, Object[] array) { + StringBuilder out = new StringBuilder(); + + try { + for (int i = 0; i < array.length; i++) { + if (i != 0) { + out.append(delim); + } + out.append(array[i].toString()); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.implode: " + e.toString()); + } + return out.toString(); + } + + public static String urlencode_rfc3986(String text) { + final String encoded = URLEncoder.encode(text).replace("+", "%20").replaceAll("%7E", "~"); + + return encoded; + } + + public String prepareParameters(Map<String, String> params, boolean my, boolean addF) { + String paramsDone = null; + + if (my != true && settings.excludeMine > 0) { + if (params == null) { + params = new HashMap<String, String>(); + } + if (addF) { + params.put("f", "1"); + } + + Log.i(cgSettings.tag, "Skipping caches found or hidden by user."); + } + + if (params != null) { + Set<Map.Entry<String, String>> entrySet = params.entrySet(); + List<String> paramsEncoded = new ArrayList<String>(); + + for (Map.Entry<String, String> entry : entrySet) + { + String key = entry.getKey(); + String value = entry.getValue(); + + if (key.charAt(0) == '^') { + key = ""; + } + if (value == null) { + value = ""; + } + + paramsEncoded.add(key + "=" + urlencode_rfc3986(value)); + } + + paramsDone = implode("&", paramsEncoded.toArray()); + } else { + paramsDone = ""; + } + + return paramsDone; + } + + public String[] requestViewstates(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my) { + final cgResponse response = request(secure, host, path, method, params, xContentType, my, false); + + return getViewstates(response.getData()); + } + + public String requestLogged(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { + cgResponse response = request(secure, host, path, method, params, xContentType, my, addF); + String data = response.getData(); + + if (checkLogin(data) == false) { + int loginState = login(); + if (loginState == 1) { + response = request(secure, host, path, method, params, xContentType, my, addF); + data = response.getData(); + } else { + Log.i(cgSettings.tag, "Working as guest."); + } + } + + return data; + } + + public cgResponse request(boolean secure, String host, String path, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { + // prepare parameters + final String paramsDone = prepareParameters(params, my, addF); + + return request(secure, host, path, method, paramsDone, 0, xContentType); + } + + public cgResponse request(boolean secure, String host, String path, String method, Map<String, String> params, int requestId, boolean xContentType, boolean my, boolean addF) { + // prepare parameters + final String paramsDone = prepareParameters(params, my, addF); + + return request(secure, host, path, method, paramsDone, requestId, xContentType); + } + + public cgResponse request(boolean secure, String host, String path, String method, String params, int requestId, Boolean xContentType) { + URL u = null; + int httpCode = -1; + String httpMessage = null; + String httpLocation = null; + + if (requestId == 0) { + requestId = (int) (Math.random() * 1000); + } + + if (method == null || (method.equalsIgnoreCase("GET") == false && method.equalsIgnoreCase("POST") == false)) { + method = "POST"; + } else { + method = method.toUpperCase(); + } + + // https + String scheme = "http://"; + if (secure) { + scheme = "https://"; + } + + String cookiesDone = getCookiesAsString(); + + URLConnection uc = null; + HttpURLConnection connection = null; + Integer timeout = 30000; + StringBuffer buffer = null; + + for (int i = 0; i < 5; i++) { + if (i > 0) { + Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); + } + + buffer = new StringBuffer(); + timeout = 30000 + (i * 10000); + + try { + if (method.equals("GET")) { + // GET + u = new URL(scheme + host + path + "?" + params); + uc = u.openConnection(); + + uc.setRequestProperty("Host", host); + uc.setRequestProperty("Cookie", cookiesDone); + if (xContentType) { + uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + } + + if (settings.asBrowser == 1) { + uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); + // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network + uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); + uc.setRequestProperty("Accept-Language", "en-US"); + uc.setRequestProperty("User-Agent", idBrowser); + uc.setRequestProperty("Connection", "keep-alive"); + uc.setRequestProperty("Keep-Alive", "300"); + } + + connection = (HttpURLConnection) uc; + connection.setReadTimeout(timeout); + connection.setRequestMethod(method); + HttpURLConnection.setFollowRedirects(false); + connection.setDoInput(true); + connection.setDoOutput(false); + } else { + // POST + u = new URL(scheme + host + path); + uc = u.openConnection(); + + uc.setRequestProperty("Host", host); + uc.setRequestProperty("Cookie", cookiesDone); + if (xContentType) { + uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + } + + if (settings.asBrowser == 1) { + uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); + // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network + uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); + uc.setRequestProperty("Accept-Language", "en-US"); + uc.setRequestProperty("User-Agent", idBrowser); + uc.setRequestProperty("Connection", "keep-alive"); + uc.setRequestProperty("Keep-Alive", "300"); + } + + connection = (HttpURLConnection) uc; + connection.setReadTimeout(timeout); + connection.setRequestMethod(method); + HttpURLConnection.setFollowRedirects(false); + connection.setDoInput(true); + connection.setDoOutput(true); + + final OutputStream out = connection.getOutputStream(); + final OutputStreamWriter wr = new OutputStreamWriter(out); + wr.write(params); + wr.flush(); + wr.close(); + } + + String headerName = null; + final SharedPreferences.Editor prefsEditor = prefs.edit(); + for (int j = 1; (headerName = uc.getHeaderFieldKey(j)) != null; j++) { + if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie")) { + int index; + String cookie = uc.getHeaderField(j); + + index = cookie.indexOf(";"); + if (index > -1) { + cookie = cookie.substring(0, cookie.indexOf(";")); + } + + index = cookie.indexOf("="); + if (index > -1 && cookie.length() > (index + 1)) { + String name = cookie.substring(0, cookie.indexOf("=")); + String value = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); + + cookies.put(name, value); + prefsEditor.putString("cookie_" + name, value); + } + } + } + prefsEditor.commit(); + + InputStream ins = getInputstreamFromConnection(connection); + final InputStreamReader inr = new InputStreamReader(ins); + final BufferedReader br = new BufferedReader(inr, 16 * 1024); + + readIntoBuffer(br, buffer); + + httpCode = connection.getResponseCode(); + httpMessage = connection.getResponseMessage(); + httpLocation = uc.getHeaderField("Location"); + + final String paramsLog = params.replaceAll(passMatch, "password=***"); + Log.i(cgSettings.tag + "|" + requestId, "[" + method + " " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + scheme + host + path + "?" + paramsLog); + + connection.disconnect(); + br.close(); + ins.close(); + inr.close(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgeoBase.request.IOException: " + e.toString()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.request: " + e.toString()); + } + + if (buffer.length() > 0) { + break; + } + } + + cgResponse response = new cgResponse(); + + try { + if (httpCode == 302 && httpLocation != null) { + final Uri newLocation = Uri.parse(httpLocation); + if (newLocation.isRelative()) { + response = request(secure, host, path, "GET", new HashMap<String, String>(), requestId, false, false, false); + } else { + boolean secureRedir = false; + if (newLocation.getScheme().equals("https")) { + secureRedir = true; + } + response = request(secureRedir, newLocation.getHost(), newLocation.getPath(), "GET", new HashMap<String, String>(), requestId, false, false, false); + } + } else { + if (StringUtils.isNotEmpty(buffer)) { + replaceWhitespace(buffer); + String data = buffer.toString(); + buffer = null; + + if (data != null) { + response.setData(data); + } else { + response.setData(""); + } + response.setStatusCode(httpCode); + response.setStatusMessage(httpMessage); + response.setUrl(u.toString()); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.page: " + e.toString()); + } + + return response; + } + + private String getCookiesAsString() { + // prepare cookies + String cookiesDone = null; + if (cookies == null || cookies.isEmpty()) { + if (cookies == null) { + cookies = new HashMap<String, String>(); + } + + final Map<String, ?> prefsAll = prefs.getAll(); + final Set<? extends Map.Entry<String, ?>> entrySet = prefsAll.entrySet(); + + for (Map.Entry<String, ?> entry : entrySet) { + String key = entry.getKey(); + if (key.matches("cookie_.+")) { + final String cookieKey = key.substring(7); + final String cookieValue = (String) entry.getValue(); + + cookies.put(cookieKey, cookieValue); + } + } + } + + if (cookies != null) { + final Set<Map.Entry<String, String>> entrySet = cookies.entrySet(); + final List<String> cookiesEncoded = new ArrayList<String>(); + + for (Map.Entry<String, String> entry : entrySet) { + cookiesEncoded.add(entry.getKey() + "=" + entry.getValue()); + } + + if (cookiesEncoded.size() > 0) { + cookiesDone = implode("; ", cookiesEncoded.toArray()); + } + } + + if (cookiesDone == null) { + Map<String, ?> prefsValues = prefs.getAll(); + + if (CollectionUtils.isNotEmpty(prefsValues)) { + final Set<? extends Map.Entry<String, ?>> entrySet = prefsValues.entrySet(); + final List<String> cookiesEncoded = new ArrayList<String>(); + + for (Map.Entry<String, ?> entry : entrySet) { + String key = entry.getKey(); + if (key.length() > 7 && key.substring(0, 7).equals("cookie_")) { + cookiesEncoded.add(key + "=" + entry.getValue()); + } + } + + if (cookiesEncoded.size() > 0) { + cookiesDone = implode("; ", cookiesEncoded.toArray()); + } + } + } + + if (cookiesDone == null) { + cookiesDone = ""; + } + return cookiesDone; + } + + /** + * Replace the characters \n, \r and \t with a space + * + * @param buffer + * The data + */ + public static void replaceWhitespace(final StringBuffer buffer) { + final int length = buffer.length(); + final char[] chars = new char[length]; + buffer.getChars(0, length, chars, 0); + int resultSize = 0; + boolean lastWasWhitespace = false; + for (char c : chars) { + if (c == ' ' || c == '\n' || c == '\r' || c == '\t') { + if (!lastWasWhitespace) { + chars[resultSize++] = ' '; + } + lastWasWhitespace = true; + } else { + chars[resultSize++] = c; + lastWasWhitespace = false; + } + } + buffer.setLength(0); + buffer.append(chars); + } + + public String requestJSONgc(String host, String path, String params) { + int httpCode = -1; + String httpLocation = null; + + String cookiesDone = getCookiesAsString(); + + URLConnection uc = null; + HttpURLConnection connection = null; + Integer timeout = 30000; + final StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < 3; i++) { + if (i > 0) { + Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); + } + + buffer.delete(0, buffer.length()); + timeout = 30000 + (i * 15000); + + try { + // POST + final URL u = new URL("http://" + host + path); + uc = u.openConnection(); + + uc.setRequestProperty("Host", host); + uc.setRequestProperty("Cookie", cookiesDone); + uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); + uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); + uc.setRequestProperty("Referer", host + "/" + path); + + if (settings.asBrowser == 1) { + uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); + uc.setRequestProperty("Accept-Language", "en-US"); + uc.setRequestProperty("User-Agent", idBrowser); + uc.setRequestProperty("Connection", "keep-alive"); + uc.setRequestProperty("Keep-Alive", "300"); + } + + connection = (HttpURLConnection) uc; + connection.setReadTimeout(timeout); + connection.setRequestMethod("POST"); + HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) + connection.setDoInput(true); + connection.setDoOutput(true); + + final OutputStream out = connection.getOutputStream(); + final OutputStreamWriter wr = new OutputStreamWriter(out); + wr.write(params); + wr.flush(); + wr.close(); + + String headerName = null; + final SharedPreferences.Editor prefsEditor = prefs.edit(); + for (int j = 1; (headerName = uc.getHeaderFieldKey(j)) != null; j++) { + if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie")) { + int index; + String cookie = uc.getHeaderField(j); + + index = cookie.indexOf(";"); + if (index > -1) { + cookie = cookie.substring(0, cookie.indexOf(";")); + } + + index = cookie.indexOf("="); + if (index > -1 && cookie.length() > (index + 1)) { + String name = cookie.substring(0, cookie.indexOf("=")); + String value = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); + + cookies.put(name, value); + prefsEditor.putString("cookie_" + name, value); + } + } + } + prefsEditor.commit(); + + InputStream ins = getInputstreamFromConnection(connection); + final InputStreamReader inr = new InputStreamReader(ins); + final BufferedReader br = new BufferedReader(inr); + + readIntoBuffer(br, buffer); + + httpCode = connection.getResponseCode(); + httpLocation = uc.getHeaderField("Location"); + + final String paramsLog = params.replaceAll(passMatch, "password=***"); + Log.i(cgSettings.tag + " | JSON", "[POST " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + "http://" + host + path + "?" + paramsLog); + + connection.disconnect(); + br.close(); + ins.close(); + inr.close(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgeoBase.requestJSONgc.IOException: " + e.toString()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.requestJSONgc: " + e.toString()); + } + + if (buffer != null && buffer.length() > 0) { + break; + } + } + + String page = null; + if (httpCode == 302 && httpLocation != null) { + final Uri newLocation = Uri.parse(httpLocation); + if (newLocation.isRelative()) { + page = requestJSONgc(host, path, params); + } else { + page = requestJSONgc(newLocation.getHost(), newLocation.getPath(), params); + } + } else { + replaceWhitespace(buffer); + page = buffer.toString(); + } + + if (page != null) { + return page; + } else { + return ""; + } + } + + private static InputStream getInputstreamFromConnection(HttpURLConnection connection) throws IOException { + final String encoding = connection.getContentEncoding(); + InputStream ins; + + if (encoding != null && encoding.equalsIgnoreCase("gzip")) { + ins = new GZIPInputStream(connection.getInputStream()); + } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { + ins = new InflaterInputStream(connection.getInputStream(), new Inflater(true)); + } else { + ins = connection.getInputStream(); + } + return ins; + } + + public static String requestJSON(String host, String path, String params) { + return requestJSON("http://", host, path, "GET", params); + } + + public static String requestJSON(String scheme, String host, String path, String method, String params) { + int httpCode = -1; + //String httpLocation = null; + + if (method == null) { + method = "GET"; + } else { + method = method.toUpperCase(); + } + + boolean methodPost = false; + if (method.equalsIgnoreCase("POST")) { + methodPost = true; + } + + URLConnection uc = null; + HttpURLConnection connection = null; + Integer timeout = 30000; + final StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < 3; i++) { + if (i > 0) { + Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); + } + + buffer.delete(0, buffer.length()); + timeout = 30000 + (i * 15000); + + try { + try { + URL u = null; + if (methodPost) { + u = new URL(scheme + host + path); + } else { + u = new URL(scheme + host + path + "?" + params); + } + + if (u.getProtocol().toLowerCase().equals("https")) { + trustAllHosts(); + HttpsURLConnection https = (HttpsURLConnection) u.openConnection(); + https.setHostnameVerifier(doNotVerify); + uc = https; + } else { + uc = (HttpURLConnection) u.openConnection(); + } + + uc.setRequestProperty("Host", host); + uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); + if (methodPost) { + uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + uc.setRequestProperty("Content-Length", Integer.toString(params.length())); + uc.setRequestProperty("X-HTTP-Method-Override", "GET"); + } else { + uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + } + uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); + + connection = (HttpURLConnection) uc; + connection.setReadTimeout(timeout); + connection.setRequestMethod(method); + HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) + connection.setDoInput(true); + if (methodPost) { + connection.setDoOutput(true); + + final OutputStream out = connection.getOutputStream(); + final OutputStreamWriter wr = new OutputStreamWriter(out); + wr.write(params); + wr.flush(); + wr.close(); + } else { + connection.setDoOutput(false); + } + + InputStream ins = getInputstreamFromConnection(connection); + final InputStreamReader inr = new InputStreamReader(ins); + final BufferedReader br = new BufferedReader(inr, 1024); + + readIntoBuffer(br, buffer); + + httpCode = connection.getResponseCode(); + + final String paramsLog = params.replaceAll(passMatch, "password=***"); + Log.i(cgSettings.tag + " | JSON", "[POST " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + "http://" + host + path + "?" + paramsLog); + + connection.disconnect(); + br.close(); + ins.close(); + inr.close(); + } catch (IOException e) { + httpCode = connection.getResponseCode(); + + Log.e(cgSettings.tag, "cgeoBase.requestJSON.IOException: " + httpCode + ": " + connection.getResponseMessage() + " ~ " + e.toString()); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoBase.requestJSON: " + e.toString()); + } + + if (StringUtils.isNotBlank(buffer)) { + break; + } + + if (httpCode == 403) { + // we're not allowed to download content, so let's move + break; + } + } + + String page = null; + //This is reported as beeing deadCode (httpLocation is always null) + //2011-08-09 - 302 is redirect so something should probably be done + /* + * if (httpCode == 302 && httpLocation != null) { + * final Uri newLocation = Uri.parse(httpLocation); + * if (newLocation.isRelative()) { + * page = requestJSONgc(host, path, params); + * } else { + * page = requestJSONgc(newLocation.getHost(), newLocation.getPath(), params); + * } + * } else { + */ + replaceWhitespace(buffer); + page = buffer.toString(); + //} + + if (page != null) { + return page; + } else { + return ""; + } + } + + public static String rot13(String text) { + final StringBuilder result = new StringBuilder(); + // plaintext flag (do not convert) + boolean plaintext = false; + + int length = text.length(); + for (int index = 0; index < length; index++) { + int c = text.charAt(index); + if (c == '[') { + plaintext = true; + } else if (c == ']') { + plaintext = false; + } else if (!plaintext) { + int capitalized = c & 32; + c &= ~capitalized; + c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) + | capitalized; + } + result.append((char) c); + } + return result.toString(); + } + + public static String md5(String text) { + String hashed = ""; + + try { + MessageDigest digest = MessageDigest.getInstance("MD5"); + digest.update(text.getBytes(), 0, text.length()); + hashed = new BigInteger(1, digest.digest()).toString(16); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.md5: " + e.toString()); + } + + return hashed; + } + + public static String sha1(String text) { + String hashed = ""; + + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(text.getBytes(), 0, text.length()); + hashed = new BigInteger(1, digest.digest()).toString(16); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.sha1: " + e.toString()); + } + + return hashed; + } + + public static byte[] hashHmac(String text, String salt) { + byte[] macBytes = {}; + + try { + SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(secretKeySpec); + macBytes = mac.doFinal(text.getBytes()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.hashHmac: " + e.toString()); + } + + return macBytes; + } + + public static boolean deleteDirectory(File path) { + if (path.exists()) { + File[] files = path.listFiles(); + + for (File file : files) { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + file.delete(); + } + } + } + + return (path.delete()); + } + + public void storeCache(cgeoapplication app, Activity activity, cgCache cache, String geocode, int listId, Handler handler) { + try { + // get cache details, they may not yet be complete + if (cache != null) { + // only reload the cache, if it was already stored or has not all details (by checking the description) + if (cache.reason > 0 || StringUtils.isBlank(cache.description)) { + final Map<String, String> params = new HashMap<String, String>(); + params.put("geocode", cache.geocode); + final UUID searchId = searchByGeocode(params, listId, false); + cache = app.getCache(searchId); + } + } else if (StringUtils.isNotBlank(geocode)) { + final Map<String, String> params = new HashMap<String, String>(); + params.put("geocode", geocode); + final UUID searchId = searchByGeocode(params, listId, false); + cache = app.getCache(searchId); + } + + if (cache == null) { + if (handler != null) { + handler.sendMessage(new Message()); + } + + return; + } + + final cgHtmlImg imgGetter = new cgHtmlImg(activity, cache.geocode, false, listId, true); + + // store images from description + if (StringUtils.isNotBlank(cache.description)) { + Html.fromHtml(cache.description, imgGetter, null); + } + + // store spoilers + if (CollectionUtils.isNotEmpty(cache.spoilers)) { + for (cgImage oneSpoiler : cache.spoilers) { + imgGetter.getDrawable(oneSpoiler.url); + } + } + + // store images from logs + if (settings.storelogimages) { + for (cgLog log : cache.logs) { + if (CollectionUtils.isNotEmpty(log.logImages)) { + for (cgImage oneLogImg : log.logImages) { + imgGetter.getDrawable(oneLogImg.url); + } + } + } + } + + // store map previews + StaticMapsProvider.downloadMaps(cache, settings, activity); + + app.markStored(cache.geocode, listId); + app.removeCacheFromCache(cache.geocode); + + if (handler != null) { + handler.sendMessage(new Message()); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.storeCache: " + e.toString()); + } + } + + public static void dropCache(cgeoapplication app, Activity activity, cgCache cache, Handler handler) { + try { + app.markDropped(cache.geocode); + app.removeCacheFromCache(cache.geocode); + + handler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.dropCache: " + e.toString()); + } + } + + public static boolean isInViewPort(int centerLat1, int centerLon1, int centerLat2, int centerLon2, int spanLat1, int spanLon1, int spanLat2, int spanLon2) { + try { + // expects coordinates in E6 format + final int left1 = centerLat1 - (spanLat1 / 2); + final int right1 = centerLat1 + (spanLat1 / 2); + final int top1 = centerLon1 + (spanLon1 / 2); + final int bottom1 = centerLon1 - (spanLon1 / 2); + + final int left2 = centerLat2 - (spanLat2 / 2); + final int right2 = centerLat2 + (spanLat2 / 2); + final int top2 = centerLon2 + (spanLon2 / 2); + final int bottom2 = centerLon2 - (spanLon2 / 2); + + if (left2 <= left1) { + return false; + } + if (right2 >= right1) { + return false; + } + if (top2 >= top1) { + return false; + } + if (bottom2 <= bottom1) { + return false; + } + + return true; + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.isInViewPort: " + e.toString()); + return false; + } + } + + public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint cacheCoords) { + if (cacheCoords == null) { + return false; + } + + // viewport is defined by center, span and some (10%) reserve on every side + int minLat = centerLat - (spanLat / 2) - (spanLat / 10); + int maxLat = centerLat + (spanLat / 2) + (spanLat / 10); + int minLon = centerLon - (spanLon / 2) - (spanLon / 10); + int maxLon = centerLon + (spanLon / 2) + (spanLon / 10); + final int cLat = cacheCoords.getLatitudeE6(); + final int cLon = cacheCoords.getLongitudeE6(); + int mid = 0; + + if (maxLat < minLat) { + mid = minLat; + minLat = maxLat; + maxLat = mid; + } + + if (maxLon < minLon) { + mid = minLon; + minLon = maxLon; + maxLon = mid; + } + + boolean latOk = false; + boolean lonOk = false; + + if (cLat >= minLat && cLat <= maxLat) { + latOk = true; + } + if (cLon >= minLon && cLon <= maxLon) { + lonOk = true; + } + + if (latOk && lonOk) { + return true; + } else { + return false; + } + } + + private static char[] base64map1 = new char[64]; + + static { + int i = 0; + for (char c = 'A'; c <= 'Z'; c++) { + base64map1[i++] = c; + } + for (char c = 'a'; c <= 'z'; c++) { + base64map1[i++] = c; + } + for (char c = '0'; c <= '9'; c++) { + base64map1[i++] = c; + } + base64map1[i++] = '+'; + base64map1[i++] = '/'; + } + private static byte[] base64map2 = new byte[128]; + + static { + for (int i = 0; i < base64map2.length; i++) { + base64map2[i] = -1; + } + for (int i = 0; i < 64; i++) { + base64map2[base64map1[i]] = (byte) i; + } + } + + public static String base64Encode(byte[] in) { + int iLen = in.length; + int oDataLen = (iLen * 4 + 2) / 3; // output length without padding + int oLen = ((iLen + 2) / 3) * 4; // output length including padding + char[] out = new char[oLen]; + int ip = 0; + int op = 0; + + while (ip < iLen) { + int i0 = in[ip++] & 0xff; + int i1 = ip < iLen ? in[ip++] & 0xff : 0; + int i2 = ip < iLen ? in[ip++] & 0xff : 0; + int o0 = i0 >>> 2; + int o1 = ((i0 & 3) << 4) | (i1 >>> 4); + int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); + int o3 = i2 & 0x3F; + out[op++] = base64map1[o0]; + out[op++] = base64map1[o1]; + out[op] = op < oDataLen ? base64map1[o2] : '='; + op++; + out[op] = op < oDataLen ? base64map1[o3] : '='; + op++; + } + + return new String(out); + } + + public static byte[] base64Decode(String text) { + char[] in = text.toCharArray(); + + int iLen = in.length; + if (iLen % 4 != 0) { + throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); + } + while (iLen > 0 && in[iLen - 1] == '=') { + iLen--; + } + int oLen = (iLen * 3) / 4; + byte[] out = new byte[oLen]; + int ip = 0; + int op = 0; + while (ip < iLen) { + int i0 = in[ip++]; + int i1 = in[ip++]; + int i2 = ip < iLen ? in[ip++] : 'A'; + int i3 = ip < iLen ? in[ip++] : 'A'; + if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int b0 = base64map2[i0]; + int b1 = base64map2[i1]; + int b2 = base64map2[i2]; + int b3 = base64map2[i3]; + if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int o0 = (b0 << 2) | (b1 >>> 4); + int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); + int o2 = ((b2 & 3) << 6) | b3; + out[op++] = (byte) o0; + if (op < oLen) { + out[op++] = (byte) o1; + } + if (op < oLen) { + out[op++] = (byte) o2; + } + } + return out; + } + + public static int getCacheIcon(final String type) { + fillIconsMap(); + Integer iconId = gcIcons.get("type_" + type); + if (iconId != null) { + return iconId; + } + // fallback to traditional if some icon type is not correct + return gcIcons.get("type_traditional"); + } + + public static int getMarkerIcon(final boolean cache, final String type, final boolean own, final boolean found, final boolean disabled) { + fillIconsMap(); + + if (wpIcons.isEmpty()) { + wpIcons.put("waypoint", R.drawable.marker_waypoint_waypoint); + wpIcons.put("flag", R.drawable.marker_waypoint_flag); + wpIcons.put("pkg", R.drawable.marker_waypoint_pkg); + wpIcons.put("puzzle", R.drawable.marker_waypoint_puzzle); + wpIcons.put("stage", R.drawable.marker_waypoint_stage); + wpIcons.put("trailhead", R.drawable.marker_waypoint_trailhead); + } + + int icon = -1; + String iconTxt = null; + + if (cache) { + if (StringUtils.isNotBlank(type)) { + if (own) { + iconTxt = type + "-own"; + } else if (found) { + iconTxt = type + "-found"; + } else if (disabled) { + iconTxt = type + "-disabled"; + } else { + iconTxt = type; + } + } else { + iconTxt = "traditional"; + } + + if (gcIcons.containsKey(iconTxt)) { + icon = gcIcons.get(iconTxt); + } else { + icon = gcIcons.get("traditional"); + } + } else { + if (StringUtils.isNotBlank(type)) { + iconTxt = type; + } else { + iconTxt = "waypoint"; + } + + if (wpIcons.containsKey(iconTxt)) { + icon = wpIcons.get(iconTxt); + } else { + icon = wpIcons.get("waypoint"); + } + } + + return icon; + } + + private static void fillIconsMap() { + if (gcIcons.isEmpty()) { + gcIcons.put("type_ape", R.drawable.type_ape); + gcIcons.put("type_cito", R.drawable.type_cito); + gcIcons.put("type_earth", R.drawable.type_earth); + gcIcons.put("type_event", R.drawable.type_event); + gcIcons.put("type_letterbox", R.drawable.type_letterbox); + gcIcons.put("type_locationless", R.drawable.type_locationless); + gcIcons.put("type_mega", R.drawable.type_mega); + gcIcons.put("type_multi", R.drawable.type_multi); + gcIcons.put("type_traditional", R.drawable.type_traditional); + gcIcons.put("type_virtual", R.drawable.type_virtual); + gcIcons.put("type_webcam", R.drawable.type_webcam); + gcIcons.put("type_wherigo", R.drawable.type_wherigo); + gcIcons.put("type_mystery", R.drawable.type_mystery); + gcIcons.put("type_gchq", R.drawable.type_hq); + // default markers + gcIcons.put("ape", R.drawable.marker_cache_ape); + gcIcons.put("cito", R.drawable.marker_cache_cito); + gcIcons.put("earth", R.drawable.marker_cache_earth); + gcIcons.put("event", R.drawable.marker_cache_event); + gcIcons.put("letterbox", R.drawable.marker_cache_letterbox); + gcIcons.put("locationless", R.drawable.marker_cache_locationless); + gcIcons.put("mega", R.drawable.marker_cache_mega); + gcIcons.put("multi", R.drawable.marker_cache_multi); + gcIcons.put("traditional", R.drawable.marker_cache_traditional); + gcIcons.put("virtual", R.drawable.marker_cache_virtual); + gcIcons.put("webcam", R.drawable.marker_cache_webcam); + gcIcons.put("wherigo", R.drawable.marker_cache_wherigo); + gcIcons.put("mystery", R.drawable.marker_cache_mystery); + gcIcons.put("gchq", R.drawable.marker_cache_gchq); + // own cache markers + gcIcons.put("ape-own", R.drawable.marker_cache_ape_own); + gcIcons.put("cito-own", R.drawable.marker_cache_cito_own); + gcIcons.put("earth-own", R.drawable.marker_cache_earth_own); + gcIcons.put("event-own", R.drawable.marker_cache_event_own); + gcIcons.put("letterbox-own", R.drawable.marker_cache_letterbox_own); + gcIcons.put("locationless-own", R.drawable.marker_cache_locationless_own); + gcIcons.put("mega-own", R.drawable.marker_cache_mega_own); + gcIcons.put("multi-own", R.drawable.marker_cache_multi_own); + gcIcons.put("traditional-own", R.drawable.marker_cache_traditional_own); + gcIcons.put("virtual-own", R.drawable.marker_cache_virtual_own); + gcIcons.put("webcam-own", R.drawable.marker_cache_webcam_own); + gcIcons.put("wherigo-own", R.drawable.marker_cache_wherigo_own); + gcIcons.put("mystery-own", R.drawable.marker_cache_mystery_own); + gcIcons.put("gchq-own", R.drawable.marker_cache_gchq_own); + // found cache markers + gcIcons.put("ape-found", R.drawable.marker_cache_ape_found); + gcIcons.put("cito-found", R.drawable.marker_cache_cito_found); + gcIcons.put("earth-found", R.drawable.marker_cache_earth_found); + gcIcons.put("event-found", R.drawable.marker_cache_event_found); + gcIcons.put("letterbox-found", R.drawable.marker_cache_letterbox_found); + gcIcons.put("locationless-found", R.drawable.marker_cache_locationless_found); + gcIcons.put("mega-found", R.drawable.marker_cache_mega_found); + gcIcons.put("multi-found", R.drawable.marker_cache_multi_found); + gcIcons.put("traditional-found", R.drawable.marker_cache_traditional_found); + gcIcons.put("virtual-found", R.drawable.marker_cache_virtual_found); + gcIcons.put("webcam-found", R.drawable.marker_cache_webcam_found); + gcIcons.put("wherigo-found", R.drawable.marker_cache_wherigo_found); + gcIcons.put("mystery-found", R.drawable.marker_cache_mystery_found); + gcIcons.put("gchq-found", R.drawable.marker_cache_gchq_found); + // disabled cache markers + gcIcons.put("ape-disabled", R.drawable.marker_cache_ape_disabled); + gcIcons.put("cito-disabled", R.drawable.marker_cache_cito_disabled); + gcIcons.put("earth-disabled", R.drawable.marker_cache_earth_disabled); + gcIcons.put("event-disabled", R.drawable.marker_cache_event_disabled); + gcIcons.put("letterbox-disabled", R.drawable.marker_cache_letterbox_disabled); + gcIcons.put("locationless-disabled", R.drawable.marker_cache_locationless_disabled); + gcIcons.put("mega-disabled", R.drawable.marker_cache_mega_disabled); + gcIcons.put("multi-disabled", R.drawable.marker_cache_multi_disabled); + gcIcons.put("traditional-disabled", R.drawable.marker_cache_traditional_disabled); + gcIcons.put("virtual-disabled", R.drawable.marker_cache_virtual_disabled); + gcIcons.put("webcam-disabled", R.drawable.marker_cache_webcam_disabled); + gcIcons.put("wherigo-disabled", R.drawable.marker_cache_wherigo_disabled); + gcIcons.put("mystery-disabled", R.drawable.marker_cache_mystery_disabled); + gcIcons.put("gchq-disabled", R.drawable.marker_cache_gchq_disabled); + } + } + + public static boolean runNavigation(Activity activity, Resources res, cgSettings settings, final Geopoint coords) { + return runNavigation(activity, res, settings, coords, null); + } + + public static boolean runNavigation(Activity activity, Resources res, cgSettings settings, final Geopoint coords, final Geopoint coordsNow) { + if (activity == null) { + return false; + } + if (settings == null) { + return false; + } + + // Google Navigation + if (settings.useGNavigation == 1) { + try { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:ll=" + coords.getLatitude() + "," + coords.getLongitude()))); + + return true; + } catch (Exception e) { + // nothing + } + } + + // Google Maps Directions + try { + if (coordsNow != null) { + activity.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("http://maps.google.com/maps?f=d&saddr=" + coordsNow.getLatitude() + "," + coordsNow.getLongitude() + + "&daddr=" + coords.getLatitude() + "," + coords.getLongitude()))); + } else { + activity.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("http://maps.google.com/maps?f=d&daddr=" + coords.getLatitude() + "," + coords.getLongitude()))); + } + + return true; + } catch (Exception e) { + // nothing + } + + Log.i(cgSettings.tag, "cgBase.runNavigation: No navigation application available."); + + if (res != null) { + ActivityMixin.showToast(activity, res.getString(R.string.err_navigation_no)); + } + + return false; + } + + public String getMapUserToken(Handler noTokenHandler) { + final cgResponse response = request(false, "www.geocaching.com", "/map/default.aspx", "GET", "", 0, false); + final String data = response.getData(); + String usertoken = null; + + if (StringUtils.isNotBlank(data)) { + final Pattern pattern = Pattern.compile("var userToken[^=]*=[^']*'([^']+)';", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + + final Matcher matcher = pattern.matcher(data); + while (matcher.find()) { + if (matcher.groupCount() > 0) { + usertoken = matcher.group(1); + } + } + } + + if (noTokenHandler != null && StringUtils.isBlank(usertoken)) { + noTokenHandler.sendEmptyMessage(0); + } + + return usertoken; + } + + public static Double getElevation(final Geopoint coords) { + try { + final String host = "maps.googleapis.com"; + final String path = "/maps/api/elevation/json"; + final String params = "sensor=false&locations=" + + String.format((Locale) null, "%.6f", coords.getLatitude()) + "," + + String.format((Locale) null, "%.6f", coords.getLongitude()); + + final String data = requestJSON(host, path, params); + + if (StringUtils.isBlank(data)) { + return null; + } + + JSONObject response = new JSONObject(data); + String status = response.getString("status"); + + if (status == null || status.equalsIgnoreCase("OK") == false) { + return null; + } + + if (response.has("results")) { + JSONArray results = response.getJSONArray("results"); + JSONObject result = results.getJSONObject(0); + return result.getDouble("elevation"); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgBase.getElevation: " + e.toString()); + } + + return null; + } + + /** + * Generate a time string according to system-wide settings (locale, 12/24 hour) + * such as "13:24". + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public String formatTime(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME); + } + + /** + * Generate a date string according to system-wide settings (locale, date format) + * such as "20 December" or "20 December 2010". The year will only be included when necessary. + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public String formatDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE); + } + + /** + * Generate a date string according to system-wide settings (locale, date format) + * such as "20 December 2010". The year will always be included, making it suitable + * to generate long-lived log entries. + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public String formatFullDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_YEAR); + } + + /** + * Generate a numeric date string according to system-wide settings (locale, date format) + * such as "10/20/2010". + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public String formatShortDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE); + } + + /** + * Generate a numeric date and time string according to system-wide settings (locale, + * date format) such as "7 sept. à 12:35". + * + * @param context + * a Context + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatShortDateTime(Context context, long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL); + } + + /** + * TODO This method is only needed until the settings are a singleton + * + * @return + */ + public String getUserName() { + return settings.getUsername(); + } + + /** + * insert text into the EditText at the current cursor position + * + * @param editText + * @param insertText + * @param addSpace + * add a space character, if there is no whitespace before the current cursor position + */ + static void insertAtPosition(final EditText editText, String insertText, final boolean addSpace) { + int selectionStart = editText.getSelectionStart(); + int selectionEnd = editText.getSelectionEnd(); + int start = Math.min(selectionStart, selectionEnd); + int end = Math.max(selectionStart, selectionEnd); + + String content = editText.getText().toString(); + if (start > 0 && !Character.isWhitespace(content.charAt(start - 1))) { + insertText = " " + insertText; + } + + editText.getText().replace(start, end, insertText); + int newCursor = start + insertText.length(); + editText.setSelection(newCursor, newCursor); + } } diff --git a/src/cgeo/geocaching/cgCache.java b/src/cgeo/geocaching/cgCache.java index d07ef1d..1aff470 100644 --- a/src/cgeo/geocaching/cgCache.java +++ b/src/cgeo/geocaching/cgCache.java @@ -1,13 +1,9 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import cgeo.geocaching.activity.IAbstractActivity; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; @@ -17,270 +13,278 @@ import android.content.res.Resources; import android.net.Uri; import android.text.Spannable; import android.util.Log; -import cgeo.geocaching.activity.IAbstractActivity; -import cgeo.geocaching.connector.ConnectorFactory; -import cgeo.geocaching.connector.IConnector; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Internal c:geo representation of a "cache" */ public class cgCache implements ICache { - public Long updated = null; - public Long detailedUpdate = null; - public Long visitedDate = null; - public Integer reason = 0; - public Boolean detailed = false; - /** + public Long updated = null; + public Long detailedUpdate = null; + public Long visitedDate = null; + public Integer reason = 0; + public Boolean detailed = false; + /** * Code of the cache like GCABCD */ - public String geocode = ""; - public String cacheId = ""; - public String guid = ""; - public String type = ""; - public String name = ""; - public Spannable nameSp = null; - public String owner = ""; - public String ownerReal = ""; - public Date hidden = null; - public String hint = ""; - public String size = ""; - public Float difficulty = Float.valueOf(0); - public Float terrain = Float.valueOf(0); - public Float direction = null; - public Float distance = null; - public String latlon = ""; - public String latitudeString = ""; - public String longitudeString = ""; - public String location = ""; - public Geopoint coords = null; - public boolean reliableLatLon = false; - public Double elevation = null; - public String personalNote = null; - public String shortdesc = ""; - public String description = ""; - public boolean disabled = false; - public boolean archived = false; - public boolean members = false; - public boolean found = false; - public boolean favourite = false; - public boolean own = false; - public Integer favouriteCnt = null; - public Float rating = null; - public Integer votes = null; - public Float myVote = null; - public int inventoryItems = 0; - public boolean onWatchlist = false; - public List<String> attributes = null; - public List<cgWaypoint> waypoints = null; - public List<cgImage> spoilers = null; - public List<cgLog> logs = null; - public List<cgTrackable> inventory = null; - public Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); - public boolean logOffline = false; - // temporary values - public boolean statusChecked = false; - public boolean statusCheckedView = false; - public String directionImg = null; - - /** - * Gather missing information from another cache object. - * - * @param other the other version, or null if non-existent - */ - public void gatherMissingFrom(final cgCache other) { - if (other == null) { - return; - } - - updated = System.currentTimeMillis(); - if (detailed == false && other.detailed) { - detailed = true; - detailedUpdate = updated; - } - - if (visitedDate == null || visitedDate == 0) { - visitedDate = other.visitedDate; - } - if (reason == null || reason == 0) { - reason = other.reason; - } - if (StringUtils.isBlank(geocode)) { - geocode = other.geocode; - } - if (StringUtils.isBlank(cacheId)) { - cacheId = other.cacheId; - } - if (StringUtils.isBlank(guid)) { - guid = other.guid; - } - if (StringUtils.isBlank(type)) { - type = other.type; - } - if (StringUtils.isBlank(name)) { - name = other.name; - } - if (StringUtils.isBlank(nameSp)) { - nameSp = other.nameSp; - } - if (StringUtils.isBlank(owner)) { - owner = other.owner; - } - if (StringUtils.isBlank(ownerReal)) { - ownerReal = other.ownerReal; - } - if (hidden == null) { - hidden = other.hidden; - } - if (StringUtils.isBlank(hint)) { - hint = other.hint; - } - if (StringUtils.isBlank(size)) { - size = other.size; - } - if (difficulty == null || difficulty == 0) { - difficulty = other.difficulty; - } - if (terrain == null || terrain == 0) { - terrain = other.terrain; - } - if (direction == null) { - direction = other.direction; - } - if (distance == null) { - distance = other.distance; - } - if (StringUtils.isBlank(latlon)) { - latlon = other.latlon; - } - if (StringUtils.isBlank(latitudeString)) { - latitudeString = other.latitudeString; - } - if (StringUtils.isBlank(longitudeString)) { - longitudeString = other.longitudeString; - } - if (StringUtils.isBlank(location)) { - location = other.location; - } - if (coords == null) { - coords = other.coords; - } - if (elevation == null) { - elevation = other.elevation; - } - if (StringUtils.isNotBlank(personalNote)) { - personalNote = other.personalNote; - } - if (StringUtils.isBlank(shortdesc)) { - shortdesc = other.shortdesc; - } - if (StringUtils.isBlank(description)) { - description = other.description; - } - if (favouriteCnt == null) { - favouriteCnt = other.favouriteCnt; - } - if (rating == null) { - rating = other.rating; - } - if (votes == null) { - votes = other.votes; - } - if (myVote == null) { - myVote = other.myVote; - } - if (attributes == null) { - attributes = other.attributes; - } - if (waypoints == null) { - waypoints = other.waypoints; - } - cgWaypoint.mergeWayPoints(waypoints, other.waypoints); - if (spoilers == null) { - spoilers = other.spoilers; - } - if (inventory == null) { - // If inventoryItems is 0, it can mean both - // "don't know" or "0 items". Since we cannot distinguish - // them here, only populate inventoryItems from - // old data when we have to do it for inventory. - inventory = other.inventory; - inventoryItems = other.inventoryItems; - } - if (logs == null || logs.isEmpty()) { // keep last known logs if none - logs = other.logs; - } - } - - public boolean hasTrackables(){ - return inventoryItems > 0; - } - - public boolean canBeAddedToCalendar() { - // is event type? - if (!isEventCache()) { - return false; - } - // has event date set? - if (hidden == null) { - return false; - } - // is in future? - Date today = new Date(); - today.setHours(0); - today.setMinutes(0); - today.setSeconds(0); - if (hidden.compareTo(today) <= 0) { - return false; - } - return true; - } - - /** - * checks if a page contains the guid of a cache - * - * @param cache the cache to look for - * @param page the page to search in - * - * @return true: page contains guid of cache, false: otherwise - */ - boolean isGuidContainedInPage(final String page) { - // check if the guid of the cache is anywhere in the page - if (StringUtils.isBlank(guid)) { - return false; - } - Pattern patternOk = Pattern.compile(guid, Pattern.CASE_INSENSITIVE); - Matcher matcherOk = patternOk.matcher(page); - if (matcherOk.find()) { - Log.i(cgSettings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' found"); - return true; - } else { - Log.i(cgSettings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' not found"); - return false; - } - } - - public boolean isEventCache() { - return "event".equalsIgnoreCase(type) || "mega".equalsIgnoreCase(type) || "cito".equalsIgnoreCase(type); - } - - public boolean logVisit(IAbstractActivity fromActivity) { - if (StringUtils.isBlank(cacheId)) { - fromActivity.showToast(((Activity)fromActivity).getResources().getString(R.string.err_cannot_log_visit)); - return true; - } - Intent logVisitIntent = new Intent((Activity)fromActivity, cgeovisit.class); - logVisitIntent.putExtra(cgeovisit.EXTRAS_ID, cacheId); - logVisitIntent.putExtra(cgeovisit.EXTRAS_GEOCODE, geocode.toUpperCase()); - logVisitIntent.putExtra(cgeovisit.EXTRAS_FOUND, found); - - ((Activity)fromActivity).startActivity(logVisitIntent); - - return true; - } - - public boolean logOffline(final IAbstractActivity fromActivity, final int logType, final cgSettings settings, final cgBase base) { + public String geocode = ""; + public String cacheId = ""; + public String guid = ""; + public String type = ""; + public String name = ""; + public Spannable nameSp = null; + public String owner = ""; + public String ownerReal = ""; + public Date hidden = null; + public String hint = ""; + public String size = ""; + public Float difficulty = Float.valueOf(0); + public Float terrain = Float.valueOf(0); + public Float direction = null; + public Float distance = null; + public String latlon = ""; + public String latitudeString = ""; + public String longitudeString = ""; + public String location = ""; + public Geopoint coords = null; + public boolean reliableLatLon = false; + public Double elevation = null; + public String personalNote = null; + public String shortdesc = ""; + public String description = ""; + public boolean disabled = false; + public boolean archived = false; + public boolean members = false; + public boolean found = false; + public boolean favourite = false; + public boolean own = false; + public Integer favouriteCnt = null; + public Float rating = null; + public Integer votes = null; + public Float myVote = null; + public int inventoryItems = 0; + public boolean onWatchlist = false; + public List<String> attributes = null; + public List<cgWaypoint> waypoints = null; + public List<cgImage> spoilers = null; + public List<cgLog> logs = null; + public List<cgTrackable> inventory = null; + public Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); + public boolean logOffline = false; + // temporary values + public boolean statusChecked = false; + public boolean statusCheckedView = false; + public String directionImg = null; + + /** + * Gather missing information from another cache object. + * + * @param other + * the other version, or null if non-existent + */ + public void gatherMissingFrom(final cgCache other) { + if (other == null) { + return; + } + + updated = System.currentTimeMillis(); + if (detailed == false && other.detailed) { + detailed = true; + detailedUpdate = updated; + } + + if (visitedDate == null || visitedDate == 0) { + visitedDate = other.visitedDate; + } + if (reason == null || reason == 0) { + reason = other.reason; + } + if (StringUtils.isBlank(geocode)) { + geocode = other.geocode; + } + if (StringUtils.isBlank(cacheId)) { + cacheId = other.cacheId; + } + if (StringUtils.isBlank(guid)) { + guid = other.guid; + } + if (StringUtils.isBlank(type)) { + type = other.type; + } + if (StringUtils.isBlank(name)) { + name = other.name; + } + if (StringUtils.isBlank(nameSp)) { + nameSp = other.nameSp; + } + if (StringUtils.isBlank(owner)) { + owner = other.owner; + } + if (StringUtils.isBlank(ownerReal)) { + ownerReal = other.ownerReal; + } + if (hidden == null) { + hidden = other.hidden; + } + if (StringUtils.isBlank(hint)) { + hint = other.hint; + } + if (StringUtils.isBlank(size)) { + size = other.size; + } + if (difficulty == null || difficulty == 0) { + difficulty = other.difficulty; + } + if (terrain == null || terrain == 0) { + terrain = other.terrain; + } + if (direction == null) { + direction = other.direction; + } + if (distance == null) { + distance = other.distance; + } + if (StringUtils.isBlank(latlon)) { + latlon = other.latlon; + } + if (StringUtils.isBlank(latitudeString)) { + latitudeString = other.latitudeString; + } + if (StringUtils.isBlank(longitudeString)) { + longitudeString = other.longitudeString; + } + if (StringUtils.isBlank(location)) { + location = other.location; + } + if (coords == null) { + coords = other.coords; + } + if (elevation == null) { + elevation = other.elevation; + } + if (StringUtils.isNotBlank(personalNote)) { + personalNote = other.personalNote; + } + if (StringUtils.isBlank(shortdesc)) { + shortdesc = other.shortdesc; + } + if (StringUtils.isBlank(description)) { + description = other.description; + } + if (favouriteCnt == null) { + favouriteCnt = other.favouriteCnt; + } + if (rating == null) { + rating = other.rating; + } + if (votes == null) { + votes = other.votes; + } + if (myVote == null) { + myVote = other.myVote; + } + if (attributes == null) { + attributes = other.attributes; + } + if (waypoints == null) { + waypoints = other.waypoints; + } + cgWaypoint.mergeWayPoints(waypoints, other.waypoints); + if (spoilers == null) { + spoilers = other.spoilers; + } + if (inventory == null) { + // If inventoryItems is 0, it can mean both + // "don't know" or "0 items". Since we cannot distinguish + // them here, only populate inventoryItems from + // old data when we have to do it for inventory. + inventory = other.inventory; + inventoryItems = other.inventoryItems; + } + if (logs == null || logs.isEmpty()) { // keep last known logs if none + logs = other.logs; + } + } + + public boolean hasTrackables() { + return inventoryItems > 0; + } + + public boolean canBeAddedToCalendar() { + // is event type? + if (!isEventCache()) { + return false; + } + // has event date set? + if (hidden == null) { + return false; + } + // is in future? + Date today = new Date(); + today.setHours(0); + today.setMinutes(0); + today.setSeconds(0); + if (hidden.compareTo(today) <= 0) { + return false; + } + return true; + } + + /** + * checks if a page contains the guid of a cache + * + * @param cache + * the cache to look for + * @param page + * the page to search in + * + * @return true: page contains guid of cache, false: otherwise + */ + boolean isGuidContainedInPage(final String page) { + // check if the guid of the cache is anywhere in the page + if (StringUtils.isBlank(guid)) { + return false; + } + Pattern patternOk = Pattern.compile(guid, Pattern.CASE_INSENSITIVE); + Matcher matcherOk = patternOk.matcher(page); + if (matcherOk.find()) { + Log.i(cgSettings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' found"); + return true; + } else { + Log.i(cgSettings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' not found"); + return false; + } + } + + public boolean isEventCache() { + return "event".equalsIgnoreCase(type) || "mega".equalsIgnoreCase(type) || "cito".equalsIgnoreCase(type); + } + + public boolean logVisit(IAbstractActivity fromActivity) { + if (StringUtils.isBlank(cacheId)) { + fromActivity.showToast(((Activity) fromActivity).getResources().getString(R.string.err_cannot_log_visit)); + return true; + } + Intent logVisitIntent = new Intent((Activity) fromActivity, cgeovisit.class); + logVisitIntent.putExtra(cgeovisit.EXTRAS_ID, cacheId); + logVisitIntent.putExtra(cgeovisit.EXTRAS_GEOCODE, geocode.toUpperCase()); + logVisitIntent.putExtra(cgeovisit.EXTRAS_FOUND, found); + + ((Activity) fromActivity).startActivity(logVisitIntent); + + return true; + } + + public boolean logOffline(final IAbstractActivity fromActivity, final int logType, final cgSettings settings, final cgBase base) { String log = ""; if (StringUtils.isNotBlank(settings.getSignature()) && settings.signatureAutoinsert) { @@ -288,171 +292,169 @@ public class cgCache implements ICache { } logOffline(fromActivity, log, Calendar.getInstance(), logType); return true; - } - - void logOffline(final IAbstractActivity fromActivity, final String log, Calendar date, final int logType) { - if (logType <= 0) { - return; - } - cgeoapplication app = (cgeoapplication)((Activity)fromActivity).getApplication(); - final boolean status = app.saveLogOffline(geocode, date.getTime(), logType, log); - - Resources res = ((Activity)fromActivity).getResources(); - if (status) { - fromActivity.showToast(res.getString(R.string.info_log_saved)); - app.saveVisitDate(geocode); - } else { - fromActivity.showToast(res.getString(R.string.err_log_post_failed)); - } - } - - public List<Integer> getPossibleLogTypes(cgSettings settings) { - boolean isOwner = owner != null && owner.equalsIgnoreCase(settings.getUsername()); - List<Integer> types = new ArrayList<Integer>(); - if ("event".equals(type) || "mega".equals(type) || "cito".equals(type) || "lostfound".equals(type)) { - types.add(cgBase.LOG_WILL_ATTEND); - types.add(cgBase.LOG_NOTE); - types.add(cgBase.LOG_ATTENDED); - types.add(cgBase.LOG_NEEDS_ARCHIVE); - if (isOwner) { - types.add(cgBase.LOG_ANNOUNCEMENT); - } - } else if ("webcam".equals(type)) { - types.add(cgBase.LOG_WEBCAM_PHOTO_TAKEN); - types.add(cgBase.LOG_DIDNT_FIND_IT); - types.add(cgBase.LOG_NOTE); - types.add(cgBase.LOG_NEEDS_ARCHIVE); - types.add(cgBase.LOG_NEEDS_MAINTENANCE); - } else { - types.add(cgBase.LOG_FOUND_IT); - types.add(cgBase.LOG_DIDNT_FIND_IT); - types.add(cgBase.LOG_NOTE); - types.add(cgBase.LOG_NEEDS_ARCHIVE); - types.add(cgBase.LOG_NEEDS_MAINTENANCE); - } - if (isOwner) { - types.add(cgBase.LOG_OWNER_MAINTENANCE); - types.add(cgBase.LOG_TEMP_DISABLE_LISTING); - types.add(cgBase.LOG_ENABLE_LISTING); - types.add(cgBase.LOG_ARCHIVE); - types.remove(Integer.valueOf(cgBase.LOG_UPDATE_COORDINATES)); - } - return types; - } - - public void openInBrowser(Activity fromActivity) { - fromActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getCacheUrl()))); - } - - private String getCacheUrl() { - return getConnector().getCacheUrl(this); - } - - private IConnector getConnector() { - return ConnectorFactory.getConnector(this); - } - - public boolean canOpenInBrowser() { - return getCacheUrl() != null; - } - - public boolean supportsRefresh() { - return getConnector().supportsRefreshCache(this); - } - - public boolean supportsWatchList() { - return getConnector().supportsWatchList(); - } - - public boolean supportsLogging() { - return getConnector().supportsLogging(); - } - - @Override
- public Float getDifficulty() {
- return difficulty;
- }
-
- @Override
- public String getGeocode() {
- return geocode;
- }
-
- @Override
- public String getLatitude() {
- return latitudeString;
- }
-
- @Override
- public String getLongitude() {
- return longitudeString;
- }
-
- @Override
- public String getOwner() {
- return owner;
- }
-
- @Override
- public String getSize() {
- return size;
- }
-
- @Override
- public Float getTerrain() {
- return terrain;
- }
-
- @Override
- public String getType() {
- return type;
- }
-
- @Override
- public boolean isArchived() {
- return archived;
- }
-
- @Override
- public boolean isDisabled() {
- return disabled;
- }
-
- @Override
- public boolean isMembersOnly() {
- return members;
- }
-
- @Override
- public boolean isOwn() {
- return own;
- } - - @Override - public String getOwnerReal() { - return ownerReal; - } - - @Override - public String getHint() { - return hint; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public String getShortDescription() { - return shortdesc; - } - - @Override - public String getName() { - return name; - }
-
-}
- -
+ } + + void logOffline(final IAbstractActivity fromActivity, final String log, Calendar date, final int logType) { + if (logType <= 0) { + return; + } + cgeoapplication app = (cgeoapplication) ((Activity) fromActivity).getApplication(); + final boolean status = app.saveLogOffline(geocode, date.getTime(), logType, log); + + Resources res = ((Activity) fromActivity).getResources(); + if (status) { + fromActivity.showToast(res.getString(R.string.info_log_saved)); + app.saveVisitDate(geocode); + } else { + fromActivity.showToast(res.getString(R.string.err_log_post_failed)); + } + } + + public List<Integer> getPossibleLogTypes(cgSettings settings) { + boolean isOwner = owner != null && owner.equalsIgnoreCase(settings.getUsername()); + List<Integer> types = new ArrayList<Integer>(); + if ("event".equals(type) || "mega".equals(type) || "cito".equals(type) || "lostfound".equals(type)) { + types.add(cgBase.LOG_WILL_ATTEND); + types.add(cgBase.LOG_NOTE); + types.add(cgBase.LOG_ATTENDED); + types.add(cgBase.LOG_NEEDS_ARCHIVE); + if (isOwner) { + types.add(cgBase.LOG_ANNOUNCEMENT); + } + } else if ("webcam".equals(type)) { + types.add(cgBase.LOG_WEBCAM_PHOTO_TAKEN); + types.add(cgBase.LOG_DIDNT_FIND_IT); + types.add(cgBase.LOG_NOTE); + types.add(cgBase.LOG_NEEDS_ARCHIVE); + types.add(cgBase.LOG_NEEDS_MAINTENANCE); + } else { + types.add(cgBase.LOG_FOUND_IT); + types.add(cgBase.LOG_DIDNT_FIND_IT); + types.add(cgBase.LOG_NOTE); + types.add(cgBase.LOG_NEEDS_ARCHIVE); + types.add(cgBase.LOG_NEEDS_MAINTENANCE); + } + if (isOwner) { + types.add(cgBase.LOG_OWNER_MAINTENANCE); + types.add(cgBase.LOG_TEMP_DISABLE_LISTING); + types.add(cgBase.LOG_ENABLE_LISTING); + types.add(cgBase.LOG_ARCHIVE); + types.remove(Integer.valueOf(cgBase.LOG_UPDATE_COORDINATES)); + } + return types; + } + + public void openInBrowser(Activity fromActivity) { + fromActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getCacheUrl()))); + } + + private String getCacheUrl() { + return getConnector().getCacheUrl(this); + } + + private IConnector getConnector() { + return ConnectorFactory.getConnector(this); + } + + public boolean canOpenInBrowser() { + return getCacheUrl() != null; + } + + public boolean supportsRefresh() { + return getConnector().supportsRefreshCache(this); + } + + public boolean supportsWatchList() { + return getConnector().supportsWatchList(); + } + + public boolean supportsLogging() { + return getConnector().supportsLogging(); + } + + @Override + public Float getDifficulty() { + return difficulty; + } + + @Override + public String getGeocode() { + return geocode; + } + + @Override + public String getLatitude() { + return latitudeString; + } + + @Override + public String getLongitude() { + return longitudeString; + } + + @Override + public String getOwner() { + return owner; + } + + @Override + public String getSize() { + return size; + } + + @Override + public Float getTerrain() { + return terrain; + } + + @Override + public String getType() { + return type; + } + + @Override + public boolean isArchived() { + return archived; + } + + @Override + public boolean isDisabled() { + return disabled; + } + + @Override + public boolean isMembersOnly() { + return members; + } + + @Override + public boolean isOwn() { + return own; + } + + @Override + public String getOwnerReal() { + return ownerReal; + } + + @Override + public String getHint() { + return hint; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getShortDescription() { + return shortdesc; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/src/cgeo/geocaching/cgCacheListAdapter.java b/src/cgeo/geocaching/cgCacheListAdapter.java index f6a8e2c..1063766 100644 --- a/src/cgeo/geocaching/cgCacheListAdapter.java +++ b/src/cgeo/geocaching/cgCacheListAdapter.java @@ -1,11 +1,11 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import cgeo.geocaching.filter.cgFilter; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.sorting.CacheComparator; +import cgeo.geocaching.sorting.DistanceComparator; +import cgeo.geocaching.sorting.VisitComparator; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -34,877 +34,879 @@ import android.widget.CheckBox; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; -import cgeo.geocaching.filter.cgFilter; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.sorting.CacheComparator; -import cgeo.geocaching.sorting.DistanceComparator; -import cgeo.geocaching.sorting.VisitComparator; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; public class cgCacheListAdapter extends ArrayAdapter<cgCache> { - private Resources res = null; - private List<cgCache> list = null; - private cgSettings settings = null; - private cgCacheView holder = null; - private LayoutInflater inflater = null; - private Activity activity = null; - private cgBase base = null; - private CacheComparator statComparator = null; - private boolean historic = false; - private Geopoint coords = null; - private float azimuth = 0; - private long lastSort = 0L; - private boolean sort = true; - private int checked = 0; - private boolean selectMode = false; - private static Map<String, Drawable> gcIconDrawables = new HashMap<String, Drawable>(); - private List<cgCompassMini> compasses = new ArrayList<cgCompassMini>(); - private List<cgDistanceView> distances = new ArrayList<cgDistanceView>(); - private int[] ratingBcgs = new int[3]; - private float pixelDensity = 1f; - private static final int SWIPE_MIN_DISTANCE = 60; - private static final int SWIPE_MAX_OFF_PATH = 100; - private static final int SWIPE_DISTANCE = 80; - private static final float SWIPE_OPACITY = 0.5f; - private cgFilter currentFilter = null; - private List<cgCache> originalList = null; - - public cgCacheListAdapter(Activity activityIn, cgSettings settingsIn, List<cgCache> listIn, cgBase baseIn) { - super(activityIn, 0, listIn); - - res = activityIn.getResources(); - activity = activityIn; - settings = settingsIn; - list = listIn; - base = baseIn; - - DisplayMetrics metrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); - pixelDensity = metrics.density; - - if (gcIconDrawables == null || gcIconDrawables.isEmpty()) { - for (String cacheType : cgBase.cacheTypesInv.keySet()) { - gcIconDrawables.put(cacheType, (Drawable) activity.getResources().getDrawable(cgBase.getCacheIcon(cacheType))); - } - } - - if (settings.skin == 0) { - ratingBcgs[0] = R.drawable.favourite_background_red_dark; - ratingBcgs[1] = R.drawable.favourite_background_orange_dark; - ratingBcgs[2] = R.drawable.favourite_background_green_dark; - } else { - ratingBcgs[0] = R.drawable.favourite_background_red_light; - ratingBcgs[1] = R.drawable.favourite_background_orange_light; - ratingBcgs[2] = R.drawable.favourite_background_green_light; - } - } - - public void setComparator(CacheComparator comparator) { - statComparator = comparator; - - forceSort(coords); - } - - /** - * Called when a new page of caches was loaded. - */ - public void reFilter(){ - if(currentFilter != null){ - // Back up the list again - originalList = new ArrayList<cgCache>(list); - - currentFilter.filter(list); - } - } - - /** - * Called after a user action on the filter menu. - */ - public void setFilter(cgFilter filter){ - // Backup current caches list if it isn't backed up yet - if (originalList == null) { - originalList = new ArrayList<cgCache>(list); - } - - // If there is already a filter in place, this is a request to change or clear the filter, so we have to - // replace the original cache list - if (currentFilter != null) { - list.clear(); - list.addAll(originalList); - } - - // Do the filtering or clear it - if (filter != null) { - filter.filter(list); - } - currentFilter = filter; - - notifyDataSetChanged(); - } - - public void clearFilter() { - if (originalList != null) { - list.clear(); - list.addAll(originalList); - - currentFilter = null; - } - - notifyDataSetChanged(); - } - - public boolean isFilter() { - if (currentFilter != null) { - return true; - } else { - return false; - } - } - - public String getFilterName() { - return currentFilter.getFilterName(); - } - - public void setHistoric(boolean historicIn) { - historic = historicIn; - - if (historic) { - statComparator = new VisitComparator(); - } else { - statComparator = null; - } - } - - public int getChecked() { - return checked; - } - - public boolean setSelectMode(boolean status, boolean clear) { - selectMode = status; - - if (selectMode == false && clear) { - for (cgCache cache : list) { - cache.statusChecked = false; - cache.statusCheckedView = false; - } - checked = 0; - } else if (selectMode) { - for (cgCache cache : list) { - cache.statusCheckedView = false; - } - } - checkChecked(0); - - notifyDataSetChanged(); - - return selectMode; - } - - public boolean getSelectMode() { - return selectMode; - } - - public void switchSelectMode() { - selectMode = !selectMode; - - if (selectMode == false) { - for (cgCache cache : list) { - cache.statusChecked = false; - cache.statusCheckedView = false; - } - checked = 0; - } else if (selectMode) { - for (cgCache cache : list) { - cache.statusCheckedView = false; - } - } - checkChecked(0); - - notifyDataSetChanged(); - } - - public void invertSelection() { - int check = 0; - - for (cgCache cache : list) { - if (cache.statusChecked) { - cache.statusChecked = false; - cache.statusCheckedView = false; - } else { - cache.statusChecked = true; - cache.statusCheckedView = true; - - check++; - } - } - checkChecked(check); - - notifyDataSetChanged(); - } - - public void forceSort(final Geopoint coordsIn) { - if (list == null || list.isEmpty()) { - return; - } - if (sort == false) { - return; - } - - try { - if (statComparator != null) { - Collections.sort((List<cgCache>) list, statComparator); - } else { - if (coordsIn == null) { - return; - } - - final DistanceComparator dstComparator = new DistanceComparator(coordsIn); - Collections.sort((List<cgCache>) list, dstComparator); - } - notifyDataSetChanged(); - } catch (Exception e) { - Log.w(cgSettings.tag, "cgCacheListAdapter.setActualCoordinates: failed to sort caches in list"); - } - } - - public void setActualCoordinates(final Geopoint coordsIn) { - if (coordsIn == null) { - return; - } - - coords = coordsIn; - - if (list != null && list.isEmpty() == false && (System.currentTimeMillis() - lastSort) > 1000 && sort) { - try { - if (statComparator != null) { - Collections.sort((List<cgCache>) list, statComparator); - } else { - final DistanceComparator dstComparator = new DistanceComparator(coordsIn); - Collections.sort((List<cgCache>) list, dstComparator); - } - notifyDataSetChanged(); - } catch (Exception e) { - Log.w(cgSettings.tag, "cgCacheListAdapter.setActualCoordinates: failed to sort caches in list"); - } - - lastSort = System.currentTimeMillis(); - } - - if (CollectionUtils.isNotEmpty(distances)) { - for (cgDistanceView distance : distances) { - distance.update(coordsIn); - } - } - - if (CollectionUtils.isNotEmpty(compasses)) { - for (cgCompassMini compass : compasses) { - compass.updateCoords(coordsIn); - } - } - } - - public void setActualHeading(Float directionNow) { - if (directionNow == null) { - return; - } - - azimuth = directionNow; - - if (CollectionUtils.isNotEmpty(compasses)) { - for (cgCompassMini compass : compasses) { - compass.updateAzimuth(azimuth); - } - } - } - - /** - * clear all check marks - * @return - */ - public boolean resetChecks() { - if (list.isEmpty()) { - return false; - } - if (checked <= 0) { - return false; - } - - boolean status = getSelectMode(); - int cleared = 0; - for (cgCache cache : list) { - if (cache.statusChecked) { - cache.statusChecked = false; - - checkChecked(-1); - cleared++; - } - } - setSelectMode(false, false); - notifyDataSetChanged(); - - if (cleared > 0 || status) { - return true; - } else { - return false; - } - } - - @Override - public View getView(int position, View rowView, ViewGroup parent) { - if (inflater == null) { - inflater = ((Activity) getContext()).getLayoutInflater(); - } - - if (position > getCount()) { - Log.w(cgSettings.tag, "cgCacheListAdapter.getView: Attempt to access missing item #" + position); - return null; - } - - cgCache cache = getItem(position); - - if (rowView == null) { - rowView = (View) inflater.inflate(R.layout.cache, null); - - holder = new cgCacheView(); - holder.oneCache = (RelativeLayout) rowView.findViewById(R.id.one_cache); - holder.checkbox = (CheckBox) rowView.findViewById(R.id.checkbox); - holder.oneInfo = (RelativeLayout) rowView.findViewById(R.id.one_info); - holder.oneCheckbox = (RelativeLayout) rowView.findViewById(R.id.one_checkbox); - holder.logStatusMark = (ImageView) rowView.findViewById(R.id.log_status_mark); - holder.oneCache = (RelativeLayout) rowView.findViewById(R.id.one_cache); - holder.text = (TextView) rowView.findViewById(R.id.text); - holder.directionLayout = (RelativeLayout) rowView.findViewById(R.id.direction_layout); - holder.distance = (cgDistanceView) rowView.findViewById(R.id.distance); - holder.direction = (cgCompassMini) rowView.findViewById(R.id.direction); - holder.dirImgLayout = (RelativeLayout) rowView.findViewById(R.id.dirimg_layout); - holder.dirImg = (ImageView) rowView.findViewById(R.id.dirimg); - holder.inventory = (RelativeLayout) rowView.findViewById(R.id.inventory); - holder.favourite = (TextView) rowView.findViewById(R.id.favourite); - holder.info = (TextView) rowView.findViewById(R.id.info); - - rowView.setTag(holder); - } else { - holder = (cgCacheView) rowView.getTag(); - } - - if (cache.own) { - if (settings.skin == 1) { - holder.oneInfo.setBackgroundResource(R.color.owncache_background_light); - holder.oneCheckbox.setBackgroundResource(R.color.owncache_background_light); - } else { - holder.oneInfo.setBackgroundResource(R.color.owncache_background_dark); - holder.oneCheckbox.setBackgroundResource(R.color.owncache_background_dark); - } - } else { - if (settings.skin == 1) { - holder.oneInfo.setBackgroundResource(R.color.background_light); - holder.oneCheckbox.setBackgroundResource(R.color.background_light); - } else { - holder.oneInfo.setBackgroundResource(R.color.background_dark); - holder.oneCheckbox.setBackgroundResource(R.color.background_dark); - } - } - - final touchListener touchLst = new touchListener(cache.geocode, cache.name, cache); - rowView.setOnClickListener(touchLst); - rowView.setOnLongClickListener(touchLst); - rowView.setOnTouchListener(touchLst); - rowView.setLongClickable(true); - - if (selectMode) { - if (cache.statusCheckedView) { - moveRight(holder, cache, true); // move fast when already slided - } else { - moveRight(holder, cache, false); - } - } else if (cache.statusChecked) { - holder.checkbox.setChecked(true); - if (cache.statusCheckedView) { - moveRight(holder, cache, true); // move fast when already slided - } else { - moveRight(holder, cache, false); - } - } else { - holder.checkbox.setChecked(false); - if (cache.statusCheckedView == false) { - holder.oneInfo.clearAnimation(); - } else { - moveLeft(holder, cache, false); - } - } - - holder.checkbox.setOnClickListener(new checkBoxListener(cache)); - - if (distances.contains(holder.distance) == false) { - distances.add(holder.distance); - } - holder.distance.setContent(base, cache.coords); - if (compasses.contains(holder.direction) == false) { - compasses.add(holder.direction); - } - holder.direction.setContent(cache.coords); - - if (cache.found && cache.logOffline) { - holder.logStatusMark.setImageResource(R.drawable.mark_green_red); - holder.logStatusMark.setVisibility(View.VISIBLE); - } else if (cache.found) { - holder.logStatusMark.setImageResource(R.drawable.mark_green); - holder.logStatusMark.setVisibility(View.VISIBLE); - } else if (cache.logOffline) { + private Resources res = null; + private List<cgCache> list = null; + private cgSettings settings = null; + private cgCacheView holder = null; + private LayoutInflater inflater = null; + private Activity activity = null; + private cgBase base = null; + private CacheComparator statComparator = null; + private boolean historic = false; + private Geopoint coords = null; + private float azimuth = 0; + private long lastSort = 0L; + private boolean sort = true; + private int checked = 0; + private boolean selectMode = false; + private static Map<String, Drawable> gcIconDrawables = new HashMap<String, Drawable>(); + private List<cgCompassMini> compasses = new ArrayList<cgCompassMini>(); + private List<cgDistanceView> distances = new ArrayList<cgDistanceView>(); + private int[] ratingBcgs = new int[3]; + private float pixelDensity = 1f; + private static final int SWIPE_MIN_DISTANCE = 60; + private static final int SWIPE_MAX_OFF_PATH = 100; + private static final int SWIPE_DISTANCE = 80; + private static final float SWIPE_OPACITY = 0.5f; + private cgFilter currentFilter = null; + private List<cgCache> originalList = null; + + public cgCacheListAdapter(Activity activityIn, cgSettings settingsIn, List<cgCache> listIn, cgBase baseIn) { + super(activityIn, 0, listIn); + + res = activityIn.getResources(); + activity = activityIn; + settings = settingsIn; + list = listIn; + base = baseIn; + + DisplayMetrics metrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + pixelDensity = metrics.density; + + if (gcIconDrawables == null || gcIconDrawables.isEmpty()) { + for (String cacheType : cgBase.cacheTypesInv.keySet()) { + gcIconDrawables.put(cacheType, (Drawable) activity.getResources().getDrawable(cgBase.getCacheIcon(cacheType))); + } + } + + if (settings.skin == 0) { + ratingBcgs[0] = R.drawable.favourite_background_red_dark; + ratingBcgs[1] = R.drawable.favourite_background_orange_dark; + ratingBcgs[2] = R.drawable.favourite_background_green_dark; + } else { + ratingBcgs[0] = R.drawable.favourite_background_red_light; + ratingBcgs[1] = R.drawable.favourite_background_orange_light; + ratingBcgs[2] = R.drawable.favourite_background_green_light; + } + } + + public void setComparator(CacheComparator comparator) { + statComparator = comparator; + + forceSort(coords); + } + + /** + * Called when a new page of caches was loaded. + */ + public void reFilter() { + if (currentFilter != null) { + // Back up the list again + originalList = new ArrayList<cgCache>(list); + + currentFilter.filter(list); + } + } + + /** + * Called after a user action on the filter menu. + */ + public void setFilter(cgFilter filter) { + // Backup current caches list if it isn't backed up yet + if (originalList == null) { + originalList = new ArrayList<cgCache>(list); + } + + // If there is already a filter in place, this is a request to change or clear the filter, so we have to + // replace the original cache list + if (currentFilter != null) { + list.clear(); + list.addAll(originalList); + } + + // Do the filtering or clear it + if (filter != null) { + filter.filter(list); + } + currentFilter = filter; + + notifyDataSetChanged(); + } + + public void clearFilter() { + if (originalList != null) { + list.clear(); + list.addAll(originalList); + + currentFilter = null; + } + + notifyDataSetChanged(); + } + + public boolean isFilter() { + if (currentFilter != null) { + return true; + } else { + return false; + } + } + + public String getFilterName() { + return currentFilter.getFilterName(); + } + + public void setHistoric(boolean historicIn) { + historic = historicIn; + + if (historic) { + statComparator = new VisitComparator(); + } else { + statComparator = null; + } + } + + public int getChecked() { + return checked; + } + + public boolean setSelectMode(boolean status, boolean clear) { + selectMode = status; + + if (selectMode == false && clear) { + for (cgCache cache : list) { + cache.statusChecked = false; + cache.statusCheckedView = false; + } + checked = 0; + } else if (selectMode) { + for (cgCache cache : list) { + cache.statusCheckedView = false; + } + } + checkChecked(0); + + notifyDataSetChanged(); + + return selectMode; + } + + public boolean getSelectMode() { + return selectMode; + } + + public void switchSelectMode() { + selectMode = !selectMode; + + if (selectMode == false) { + for (cgCache cache : list) { + cache.statusChecked = false; + cache.statusCheckedView = false; + } + checked = 0; + } else if (selectMode) { + for (cgCache cache : list) { + cache.statusCheckedView = false; + } + } + checkChecked(0); + + notifyDataSetChanged(); + } + + public void invertSelection() { + int check = 0; + + for (cgCache cache : list) { + if (cache.statusChecked) { + cache.statusChecked = false; + cache.statusCheckedView = false; + } else { + cache.statusChecked = true; + cache.statusCheckedView = true; + + check++; + } + } + checkChecked(check); + + notifyDataSetChanged(); + } + + public void forceSort(final Geopoint coordsIn) { + if (list == null || list.isEmpty()) { + return; + } + if (sort == false) { + return; + } + + try { + if (statComparator != null) { + Collections.sort((List<cgCache>) list, statComparator); + } else { + if (coordsIn == null) { + return; + } + + final DistanceComparator dstComparator = new DistanceComparator(coordsIn); + Collections.sort((List<cgCache>) list, dstComparator); + } + notifyDataSetChanged(); + } catch (Exception e) { + Log.w(cgSettings.tag, "cgCacheListAdapter.setActualCoordinates: failed to sort caches in list"); + } + } + + public void setActualCoordinates(final Geopoint coordsIn) { + if (coordsIn == null) { + return; + } + + coords = coordsIn; + + if (list != null && list.isEmpty() == false && (System.currentTimeMillis() - lastSort) > 1000 && sort) { + try { + if (statComparator != null) { + Collections.sort((List<cgCache>) list, statComparator); + } else { + final DistanceComparator dstComparator = new DistanceComparator(coordsIn); + Collections.sort((List<cgCache>) list, dstComparator); + } + notifyDataSetChanged(); + } catch (Exception e) { + Log.w(cgSettings.tag, "cgCacheListAdapter.setActualCoordinates: failed to sort caches in list"); + } + + lastSort = System.currentTimeMillis(); + } + + if (CollectionUtils.isNotEmpty(distances)) { + for (cgDistanceView distance : distances) { + distance.update(coordsIn); + } + } + + if (CollectionUtils.isNotEmpty(compasses)) { + for (cgCompassMini compass : compasses) { + compass.updateCoords(coordsIn); + } + } + } + + public void setActualHeading(Float directionNow) { + if (directionNow == null) { + return; + } + + azimuth = directionNow; + + if (CollectionUtils.isNotEmpty(compasses)) { + for (cgCompassMini compass : compasses) { + compass.updateAzimuth(azimuth); + } + } + } + + /** + * clear all check marks + * + * @return + */ + public boolean resetChecks() { + if (list.isEmpty()) { + return false; + } + if (checked <= 0) { + return false; + } + + boolean status = getSelectMode(); + int cleared = 0; + for (cgCache cache : list) { + if (cache.statusChecked) { + cache.statusChecked = false; + + checkChecked(-1); + cleared++; + } + } + setSelectMode(false, false); + notifyDataSetChanged(); + + if (cleared > 0 || status) { + return true; + } else { + return false; + } + } + + @Override + public View getView(int position, View rowView, ViewGroup parent) { + if (inflater == null) { + inflater = ((Activity) getContext()).getLayoutInflater(); + } + + if (position > getCount()) { + Log.w(cgSettings.tag, "cgCacheListAdapter.getView: Attempt to access missing item #" + position); + return null; + } + + cgCache cache = getItem(position); + + if (rowView == null) { + rowView = (View) inflater.inflate(R.layout.cache, null); + + holder = new cgCacheView(); + holder.oneCache = (RelativeLayout) rowView.findViewById(R.id.one_cache); + holder.checkbox = (CheckBox) rowView.findViewById(R.id.checkbox); + holder.oneInfo = (RelativeLayout) rowView.findViewById(R.id.one_info); + holder.oneCheckbox = (RelativeLayout) rowView.findViewById(R.id.one_checkbox); + holder.logStatusMark = (ImageView) rowView.findViewById(R.id.log_status_mark); + holder.oneCache = (RelativeLayout) rowView.findViewById(R.id.one_cache); + holder.text = (TextView) rowView.findViewById(R.id.text); + holder.directionLayout = (RelativeLayout) rowView.findViewById(R.id.direction_layout); + holder.distance = (cgDistanceView) rowView.findViewById(R.id.distance); + holder.direction = (cgCompassMini) rowView.findViewById(R.id.direction); + holder.dirImgLayout = (RelativeLayout) rowView.findViewById(R.id.dirimg_layout); + holder.dirImg = (ImageView) rowView.findViewById(R.id.dirimg); + holder.inventory = (RelativeLayout) rowView.findViewById(R.id.inventory); + holder.favourite = (TextView) rowView.findViewById(R.id.favourite); + holder.info = (TextView) rowView.findViewById(R.id.info); + + rowView.setTag(holder); + } else { + holder = (cgCacheView) rowView.getTag(); + } + + if (cache.own) { + if (settings.skin == 1) { + holder.oneInfo.setBackgroundResource(R.color.owncache_background_light); + holder.oneCheckbox.setBackgroundResource(R.color.owncache_background_light); + } else { + holder.oneInfo.setBackgroundResource(R.color.owncache_background_dark); + holder.oneCheckbox.setBackgroundResource(R.color.owncache_background_dark); + } + } else { + if (settings.skin == 1) { + holder.oneInfo.setBackgroundResource(R.color.background_light); + holder.oneCheckbox.setBackgroundResource(R.color.background_light); + } else { + holder.oneInfo.setBackgroundResource(R.color.background_dark); + holder.oneCheckbox.setBackgroundResource(R.color.background_dark); + } + } + + final touchListener touchLst = new touchListener(cache.geocode, cache.name, cache); + rowView.setOnClickListener(touchLst); + rowView.setOnLongClickListener(touchLst); + rowView.setOnTouchListener(touchLst); + rowView.setLongClickable(true); + + if (selectMode) { + if (cache.statusCheckedView) { + moveRight(holder, cache, true); // move fast when already slided + } else { + moveRight(holder, cache, false); + } + } else if (cache.statusChecked) { + holder.checkbox.setChecked(true); + if (cache.statusCheckedView) { + moveRight(holder, cache, true); // move fast when already slided + } else { + moveRight(holder, cache, false); + } + } else { + holder.checkbox.setChecked(false); + if (cache.statusCheckedView == false) { + holder.oneInfo.clearAnimation(); + } else { + moveLeft(holder, cache, false); + } + } + + holder.checkbox.setOnClickListener(new checkBoxListener(cache)); + + if (distances.contains(holder.distance) == false) { + distances.add(holder.distance); + } + holder.distance.setContent(base, cache.coords); + if (compasses.contains(holder.direction) == false) { + compasses.add(holder.direction); + } + holder.direction.setContent(cache.coords); + + if (cache.found && cache.logOffline) { + holder.logStatusMark.setImageResource(R.drawable.mark_green_red); + holder.logStatusMark.setVisibility(View.VISIBLE); + } else if (cache.found) { + holder.logStatusMark.setImageResource(R.drawable.mark_green); + holder.logStatusMark.setVisibility(View.VISIBLE); + } else if (cache.logOffline) { holder.logStatusMark.setImageResource(R.drawable.mark_red); - holder.logStatusMark.setVisibility(View.VISIBLE); + holder.logStatusMark.setVisibility(View.VISIBLE); + } else { + holder.logStatusMark.setVisibility(View.GONE); + } + + if (cache.nameSp == null) { + cache.nameSp = (new Spannable.Factory()).newSpannable(cache.name); + if (cache.disabled || cache.archived) { // strike + cache.nameSp.setSpan(new StrikethroughSpan(), 0, cache.nameSp.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + holder.text.setText(cache.nameSp, TextView.BufferType.SPANNABLE); + if (gcIconDrawables.containsKey(cache.type)) { // cache icon + holder.text.setCompoundDrawablesWithIntrinsicBounds(gcIconDrawables.get(cache.type), null, null, null); + } else { // unknown cache type, "mystery" icon + holder.text.setCompoundDrawablesWithIntrinsicBounds(gcIconDrawables.get("mystery"), null, null, null); + } + + if (holder.inventory.getChildCount() > 0) { + holder.inventory.removeAllViews(); + } + + ImageView tbIcon = null; + if (cache.inventoryItems > 0) { + tbIcon = (ImageView) inflater.inflate(R.layout.trackable_icon, null); + tbIcon.setImageResource(R.drawable.trackable_all); + + holder.inventory.addView(tbIcon); + holder.inventory.setVisibility(View.VISIBLE); + } else { + holder.inventory.setVisibility(View.GONE); + } + + boolean setDiDi = false; + if (cache.coords != null) { + holder.direction.setVisibility(View.VISIBLE); + holder.direction.updateAzimuth(azimuth); + if (coords != null) { + holder.distance.update(coords); + holder.direction.updateCoords(coords); + } + setDiDi = true; + } else { + if (cache.distance != null) { + holder.distance.setDistance(cache.distance); + setDiDi = true; + } + if (cache.direction != null) { + holder.direction.setVisibility(View.VISIBLE); + holder.direction.updateAzimuth(azimuth); + holder.direction.updateHeading(cache.direction); + setDiDi = true; + } + } + + if (setDiDi) { + holder.directionLayout.setVisibility(View.VISIBLE); + holder.dirImgLayout.setVisibility(View.GONE); + } else { + holder.directionLayout.setVisibility(View.GONE); + holder.distance.clear(); + + Bitmap dirImgPre = null; + Bitmap dirImg = null; + try { + dirImgPre = BitmapFactory.decodeFile(cgSettings.getStorage() + cache.geocode + "/direction.png"); + dirImg = dirImgPre.copy(Bitmap.Config.ARGB_8888, true); + + dirImgPre.recycle(); + dirImgPre = null; + } catch (Exception e) { + // nothing + } + + if (dirImg != null) { + if (settings.skin == 0) { + int length = dirImg.getWidth() * dirImg.getHeight(); + int[] pixels = new int[length]; + dirImg.getPixels(pixels, 0, dirImg.getWidth(), 0, 0, dirImg.getWidth(), dirImg.getHeight()); + for (int i = 0; i < length; i++) { + if (pixels[i] == 0xff000000) { // replace black with white + pixels[i] = 0xffffffff; + } + } + dirImg.setPixels(pixels, 0, dirImg.getWidth(), 0, 0, dirImg.getWidth(), dirImg.getHeight()); + } + + holder.dirImg.setImageBitmap(dirImg); + holder.dirImgLayout.setVisibility(View.VISIBLE); + } else { + holder.dirImg.setImageBitmap(null); + holder.dirImgLayout.setVisibility(View.GONE); + } + } + + if (cache.favouriteCnt != null) { + holder.favourite.setText(String.format("%d", cache.favouriteCnt)); + } else { + holder.favourite.setText("---"); + } + + int favoriteBack; + // set default background, neither vote nor rating may be available + if (settings.skin == 1) { + favoriteBack = R.drawable.favourite_background_light; + } else { + favoriteBack = R.drawable.favourite_background_dark; + } + if (cache.myVote != null && cache.myVote > 0) { + if (cache.myVote >= 4) { + favoriteBack = ratingBcgs[2]; + } else if (cache.myVote >= 3) { + favoriteBack = ratingBcgs[1]; + } else if (cache.myVote > 0) { + favoriteBack = ratingBcgs[0]; + } + } else if (cache.rating != null && cache.rating > 0) { + if (cache.rating >= 3.5) { + favoriteBack = ratingBcgs[2]; + } else if (cache.rating >= 2.1) { + favoriteBack = ratingBcgs[1]; + } else if (cache.rating > 0.0) { + favoriteBack = ratingBcgs[0]; + } + } + holder.favourite.setBackgroundResource(favoriteBack); + + StringBuilder cacheInfo = new StringBuilder(); + if (historic && cache.visitedDate != null) { + cacheInfo.append(base.formatTime(cache.visitedDate)); + cacheInfo.append("; "); + cacheInfo.append(base.formatDate(cache.visitedDate)); + } else { + if (StringUtils.isNotBlank(cache.geocode)) { + cacheInfo.append(cache.geocode); + } + if (StringUtils.isNotBlank(cache.size)) { + if (cacheInfo.length() > 0) { + cacheInfo.append(" | "); + } + cacheInfo.append(cache.size); + } + if ((cache.difficulty != null && cache.difficulty > 0f) || (cache.terrain != null && cache.terrain > 0f) || (cache.rating != null && cache.rating > 0f)) { + if (cacheInfo.length() > 0 && ((cache.difficulty != null && cache.difficulty > 0f) || (cache.terrain != null && cache.terrain > 0f))) { + cacheInfo.append(" |"); + } + + if (cache.difficulty != null && cache.difficulty > 0f) { + cacheInfo.append(" D:"); + cacheInfo.append(String.format(Locale.getDefault(), "%.1f", cache.difficulty)); + } + if (cache.terrain != null && cache.terrain > 0f) { + cacheInfo.append(" T:"); + cacheInfo.append(String.format(Locale.getDefault(), "%.1f", cache.terrain)); + } + } + if (cache.members) { + if (cacheInfo.length() > 0) { + cacheInfo.append(" | "); + } + cacheInfo.append(res.getString(R.string.cache_premium)); + } + if (cache.reason != null && cache.reason == 1) { + if (cacheInfo.length() > 0) { + cacheInfo.append(" | "); + } + cacheInfo.append(res.getString(R.string.cache_offline)); + } + } + holder.info.setText(cacheInfo.toString()); + + return rowView; + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + + checked = 0; + for (cgCache cache : list) { + if (cache.statusChecked) { + checked++; + } + } + + distances.clear(); + compasses.clear(); + } + + private class checkBoxListener implements View.OnClickListener { + + private cgCache cache = null; + + public checkBoxListener(cgCache cacheIn) { + cache = cacheIn; + } + + public void onClick(View view) { + final boolean checkNow = ((CheckBox) view).isChecked(); + + if (checkNow) { + cache.statusChecked = true; + checked++; + } else { + cache.statusChecked = false; + checked--; + } + } + } + + private class touchListener implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener { + + private String geocode = null; + private String name = null; + private cgCache cache = null; + private boolean touch = true; + private GestureDetector gestureDetector = null; + + public touchListener(String geocodeIn, String nameIn, cgCache cacheIn) { + geocode = geocodeIn; + name = nameIn; + cache = cacheIn; + + final detectGesture dGesture = new detectGesture(holder, cache); + gestureDetector = new GestureDetector(dGesture); + } + + // tap on item + public void onClick(View view) { + if (touch == false) { + touch = true; + + return; + } + + if (getSelectMode() || getChecked() > 0) { + return; + } + + // load cache details + Intent cachesIntent = new Intent(getContext(), cgeodetail.class); + cachesIntent.putExtra("geocode", geocode); + cachesIntent.putExtra("name", name); + getContext().startActivity(cachesIntent); + } + + // long tap on item + public boolean onLongClick(View view) { + if (touch == false) { + touch = true; + + return true; + } + + return view.showContextMenu(); + } + + // swipe on item + public boolean onTouch(View view, MotionEvent event) { + if (gestureDetector.onTouchEvent(event)) { + touch = false; + + return true; + } + + return false; + } + } + + class detectGesture extends GestureDetector.SimpleOnGestureListener { + + private cgCacheView holder = null; + private cgCache cache = null; + + public detectGesture(cgCacheView holderIn, cgCache cacheIn) { + holder = holderIn; + cache = cacheIn; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + try { + if (getSelectMode()) { + return false; + } + + if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) { + return false; + } + + if ((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { + // left to right swipe + if (cache.statusChecked) { + return true; + } + + if (holder != null && holder.oneInfo != null) { + checkChecked(+1); + holder.checkbox.setChecked(true); + cache.statusChecked = true; + moveRight(holder, cache, false); + } + + return true; + } else if ((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { + // right to left swipe + if (cache.statusChecked == false) { + return true; + } + + if (holder != null && holder.oneInfo != null) { + if (getSelectMode()) { + setSelectMode(false, false); + } + + checkChecked(-1); + holder.checkbox.setChecked(false); + cache.statusChecked = false; + moveLeft(holder, cache, false); + } + + return true; + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgCacheListAdapter.detectGesture.onFling: " + e.toString()); + } + + return false; + } + } + + private void checkChecked(int cnt) { + // check how many caches are selected, if any block sorting of list + boolean statusChecked = false; + boolean statusSort = false; + checked += cnt; + + if (checked > 0) { + statusChecked = false; + } else { + statusChecked = true; + } + + if (getSelectMode()) { + statusSort = false; + } else { + statusSort = true; + } + + if (statusChecked == false || statusSort == false) { + sort = false; } else { - holder.logStatusMark.setVisibility(View.GONE); - } - - if (cache.nameSp == null) { - cache.nameSp = (new Spannable.Factory()).newSpannable(cache.name); - if (cache.disabled || cache.archived) { // strike - cache.nameSp.setSpan(new StrikethroughSpan(), 0, cache.nameSp.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } - - holder.text.setText(cache.nameSp, TextView.BufferType.SPANNABLE); - if (gcIconDrawables.containsKey(cache.type)) { // cache icon - holder.text.setCompoundDrawablesWithIntrinsicBounds(gcIconDrawables.get(cache.type), null, null, null); - } else { // unknown cache type, "mystery" icon - holder.text.setCompoundDrawablesWithIntrinsicBounds(gcIconDrawables.get("mystery"), null, null, null); - } - - if (holder.inventory.getChildCount() > 0) { - holder.inventory.removeAllViews(); - } - - ImageView tbIcon = null; - if (cache.inventoryItems > 0) { - tbIcon = (ImageView) inflater.inflate(R.layout.trackable_icon, null); - tbIcon.setImageResource(R.drawable.trackable_all); - - holder.inventory.addView(tbIcon); - holder.inventory.setVisibility(View.VISIBLE); - } else { - holder.inventory.setVisibility(View.GONE); - } - - boolean setDiDi = false; - if (cache.coords != null) { - holder.direction.setVisibility(View.VISIBLE); - holder.direction.updateAzimuth(azimuth); - if (coords != null) { - holder.distance.update(coords); - holder.direction.updateCoords(coords); - } - setDiDi = true; - } else { - if (cache.distance != null) { - holder.distance.setDistance(cache.distance); - setDiDi = true; - } - if (cache.direction != null) { - holder.direction.setVisibility(View.VISIBLE); - holder.direction.updateAzimuth(azimuth); - holder.direction.updateHeading(cache.direction); - setDiDi = true; - } - } - - if (setDiDi) { - holder.directionLayout.setVisibility(View.VISIBLE); - holder.dirImgLayout.setVisibility(View.GONE); - } else { - holder.directionLayout.setVisibility(View.GONE); - holder.distance.clear(); - - Bitmap dirImgPre = null; - Bitmap dirImg = null; - try { - dirImgPre = BitmapFactory.decodeFile(cgSettings.getStorage() + cache.geocode + "/direction.png"); - dirImg = dirImgPre.copy(Bitmap.Config.ARGB_8888, true); - - dirImgPre.recycle(); - dirImgPre = null; - } catch (Exception e) { - // nothing - } - - if (dirImg != null) { - if (settings.skin == 0) { - int length = dirImg.getWidth() * dirImg.getHeight(); - int[] pixels = new int[length]; - dirImg.getPixels(pixels, 0, dirImg.getWidth(), 0, 0, dirImg.getWidth(), dirImg.getHeight()); - for (int i = 0; i < length; i++) { - if (pixels[i] == 0xff000000) { // replace black with white - pixels[i] = 0xffffffff; - } - } - dirImg.setPixels(pixels, 0, dirImg.getWidth(), 0, 0, dirImg.getWidth(), dirImg.getHeight()); - } - - holder.dirImg.setImageBitmap(dirImg); - holder.dirImgLayout.setVisibility(View.VISIBLE); - } else { - holder.dirImg.setImageBitmap(null); - holder.dirImgLayout.setVisibility(View.GONE); - } - } - - if (cache.favouriteCnt != null) { - holder.favourite.setText(String.format("%d", cache.favouriteCnt)); - } else { - holder.favourite.setText("---"); - } - - int favoriteBack; - // set default background, neither vote nor rating may be available - if (settings.skin == 1) { - favoriteBack = R.drawable.favourite_background_light; - } else { - favoriteBack = R.drawable.favourite_background_dark; - } - if (cache.myVote != null && cache.myVote > 0) { - if (cache.myVote >= 4) { - favoriteBack = ratingBcgs[2]; - } else if (cache.myVote >= 3) { - favoriteBack = ratingBcgs[1]; - } else if (cache.myVote > 0) { - favoriteBack = ratingBcgs[0]; - } - } else if (cache.rating != null && cache.rating > 0) { - if (cache.rating >= 3.5) { - favoriteBack = ratingBcgs[2]; - } else if (cache.rating >= 2.1) { - favoriteBack = ratingBcgs[1]; - } else if (cache.rating > 0.0) { - favoriteBack = ratingBcgs[0]; - } - } - holder.favourite.setBackgroundResource(favoriteBack); - - StringBuilder cacheInfo = new StringBuilder(); - if (historic && cache.visitedDate != null) { - cacheInfo.append(base.formatTime(cache.visitedDate)); - cacheInfo.append("; "); - cacheInfo.append(base.formatDate(cache.visitedDate)); - } else { - if (StringUtils.isNotBlank(cache.geocode)) { - cacheInfo.append(cache.geocode); - } - if (StringUtils.isNotBlank(cache.size)) { - if (cacheInfo.length() > 0) { - cacheInfo.append(" | "); - } - cacheInfo.append(cache.size); - } - if ((cache.difficulty != null && cache.difficulty > 0f) || (cache.terrain != null && cache.terrain > 0f) || (cache.rating != null && cache.rating > 0f)) { - if (cacheInfo.length() > 0 && ((cache.difficulty != null && cache.difficulty > 0f) || (cache.terrain != null && cache.terrain > 0f))) { - cacheInfo.append(" |"); - } - - if (cache.difficulty != null && cache.difficulty > 0f) { - cacheInfo.append(" D:"); - cacheInfo.append(String.format(Locale.getDefault(), "%.1f", cache.difficulty)); - } - if (cache.terrain != null && cache.terrain > 0f) { - cacheInfo.append(" T:"); - cacheInfo.append(String.format(Locale.getDefault(), "%.1f", cache.terrain)); - } - } - if (cache.members) { - if (cacheInfo.length() > 0) { - cacheInfo.append(" | "); - } - cacheInfo.append(res.getString(R.string.cache_premium)); - } - if (cache.reason != null && cache.reason == 1) { - if (cacheInfo.length() > 0) { - cacheInfo.append(" | "); - } - cacheInfo.append(res.getString(R.string.cache_offline)); - } - } - holder.info.setText(cacheInfo.toString()); - - return rowView; - } - - @Override - public void notifyDataSetChanged() { - super.notifyDataSetChanged(); - - checked = 0; - for (cgCache cache : list) { - if (cache.statusChecked) { - checked++; - } - } - - distances.clear(); - compasses.clear(); - } - - private class checkBoxListener implements View.OnClickListener { - - private cgCache cache = null; - - public checkBoxListener(cgCache cacheIn) { - cache = cacheIn; - } - - public void onClick(View view) { - final boolean checkNow = ((CheckBox) view).isChecked(); - - if (checkNow) { - cache.statusChecked = true; - checked++; - } else { - cache.statusChecked = false; - checked--; - } - } - } - - private class touchListener implements View.OnLongClickListener, View.OnClickListener, View.OnTouchListener { - - private String geocode = null; - private String name = null; - private cgCache cache = null; - private boolean touch = true; - private GestureDetector gestureDetector = null; - - public touchListener(String geocodeIn, String nameIn, cgCache cacheIn) { - geocode = geocodeIn; - name = nameIn; - cache = cacheIn; - - final detectGesture dGesture = new detectGesture(holder, cache); - gestureDetector = new GestureDetector(dGesture); - } - - // tap on item - public void onClick(View view) { - if (touch == false) { - touch = true; - - return; - } - - if (getSelectMode() || getChecked() > 0) { - return; - } - - // load cache details - Intent cachesIntent = new Intent(getContext(), cgeodetail.class); - cachesIntent.putExtra("geocode", geocode); - cachesIntent.putExtra("name", name); - getContext().startActivity(cachesIntent); - } - - // long tap on item - public boolean onLongClick(View view) { - if (touch == false) { - touch = true; - - return true; - } - - return view.showContextMenu(); - } - - // swipe on item - public boolean onTouch(View view, MotionEvent event) { - if (gestureDetector.onTouchEvent(event)) { - touch = false; - - return true; - } - - return false; - } - } - - class detectGesture extends GestureDetector.SimpleOnGestureListener { - - private cgCacheView holder = null; - private cgCache cache = null; - - public detectGesture(cgCacheView holderIn, cgCache cacheIn) { - holder = holderIn; - cache = cacheIn; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - try { - if (getSelectMode()) { - return false; - } - - if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) { - return false; - } - - if ((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { - // left to right swipe - if (cache.statusChecked) { - return true; - } - - if (holder != null && holder.oneInfo != null) { - checkChecked(+1); - holder.checkbox.setChecked(true); - cache.statusChecked = true; - moveRight(holder, cache, false); - } - - return true; - } else if ((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { - // right to left swipe - if (cache.statusChecked == false) { - return true; - } - - if (holder != null && holder.oneInfo != null) { - if (getSelectMode()) { - setSelectMode(false, false); - } - - checkChecked(-1); - holder.checkbox.setChecked(false); - cache.statusChecked = false; - moveLeft(holder, cache, false); - } - - return true; - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgCacheListAdapter.detectGesture.onFling: " + e.toString()); - } - - return false; - } - } - - private void checkChecked(int cnt) { - // check how many caches are selected, if any block sorting of list - boolean statusChecked = false; - boolean statusSort = false; - checked += cnt; - - if (checked > 0) { - statusChecked = false; - } else { - statusChecked = true; - } - - if (getSelectMode()) { - statusSort = false; - } else { - statusSort = true; - } - - if (statusChecked == false || statusSort == false) { - sort = false; - } else { - sort = true; - } - - if (sort) { - forceSort(coords); - } - } - - private void moveRight(cgCacheView holder, cgCache cache, boolean force) { - if (cache == null) { - return; - } - - try { - holder.checkbox.setChecked(cache.statusChecked); - - // slide cache info - Animation showCheckbox = new TranslateAnimation(0, (int) (SWIPE_DISTANCE * pixelDensity), 0, 0); - showCheckbox.setRepeatCount(0); - if (force) { - showCheckbox.setDuration(0); - } else { - showCheckbox.setDuration(400); - } - showCheckbox.setFillEnabled(true); - showCheckbox.setFillAfter(true); - showCheckbox.setInterpolator(new AccelerateDecelerateInterpolator()); - - // dim cache info - Animation dimInfo = new AlphaAnimation(1.0f, SWIPE_OPACITY); - dimInfo.setRepeatCount(0); - if (force) { - dimInfo.setDuration(0); - } else { - dimInfo.setDuration(400); - } - dimInfo.setFillEnabled(true); - dimInfo.setFillAfter(true); - dimInfo.setInterpolator(new AccelerateDecelerateInterpolator()); - - // animation set (container) - AnimationSet selectAnimation = new AnimationSet(true); - selectAnimation.setFillEnabled(true); - selectAnimation.setFillAfter(true); - - selectAnimation.addAnimation(showCheckbox); - selectAnimation.addAnimation(dimInfo); - - holder.oneInfo.startAnimation(selectAnimation); - cache.statusCheckedView = true; - } catch (Exception e) { - // nothing - } - } - - private void moveLeft(cgCacheView holder, cgCache cache, boolean force) { - if (cache == null) { - return; - } - - try { - holder.checkbox.setChecked(cache.statusChecked); - - // slide cache info - Animation hideCheckbox = new TranslateAnimation((int) (SWIPE_DISTANCE * pixelDensity), 0, 0, 0); - hideCheckbox.setRepeatCount(0); - if (force) { - hideCheckbox.setDuration(0); - } else { - hideCheckbox.setDuration(400); - } - hideCheckbox.setFillEnabled(true); - hideCheckbox.setFillAfter(true); - hideCheckbox.setInterpolator(new AccelerateDecelerateInterpolator()); - - // brighten cache info - Animation brightenInfo = new AlphaAnimation(SWIPE_OPACITY, 1.0f); - brightenInfo.setRepeatCount(0); - if (force) { - brightenInfo.setDuration(0); - } else { - brightenInfo.setDuration(400); - } - brightenInfo.setFillEnabled(true); - brightenInfo.setFillAfter(true); - brightenInfo.setInterpolator(new AccelerateDecelerateInterpolator()); - - // animation set (container) - AnimationSet selectAnimation = new AnimationSet(true); - selectAnimation.setFillEnabled(true); - selectAnimation.setFillAfter(true); - - selectAnimation.addAnimation(hideCheckbox); - selectAnimation.addAnimation(brightenInfo); - - holder.oneInfo.startAnimation(selectAnimation); - cache.statusCheckedView = false; - } catch (Exception e) { - // nothing - } - } + sort = true; + } + + if (sort) { + forceSort(coords); + } + } + + private void moveRight(cgCacheView holder, cgCache cache, boolean force) { + if (cache == null) { + return; + } + + try { + holder.checkbox.setChecked(cache.statusChecked); + + // slide cache info + Animation showCheckbox = new TranslateAnimation(0, (int) (SWIPE_DISTANCE * pixelDensity), 0, 0); + showCheckbox.setRepeatCount(0); + if (force) { + showCheckbox.setDuration(0); + } else { + showCheckbox.setDuration(400); + } + showCheckbox.setFillEnabled(true); + showCheckbox.setFillAfter(true); + showCheckbox.setInterpolator(new AccelerateDecelerateInterpolator()); + + // dim cache info + Animation dimInfo = new AlphaAnimation(1.0f, SWIPE_OPACITY); + dimInfo.setRepeatCount(0); + if (force) { + dimInfo.setDuration(0); + } else { + dimInfo.setDuration(400); + } + dimInfo.setFillEnabled(true); + dimInfo.setFillAfter(true); + dimInfo.setInterpolator(new AccelerateDecelerateInterpolator()); + + // animation set (container) + AnimationSet selectAnimation = new AnimationSet(true); + selectAnimation.setFillEnabled(true); + selectAnimation.setFillAfter(true); + + selectAnimation.addAnimation(showCheckbox); + selectAnimation.addAnimation(dimInfo); + + holder.oneInfo.startAnimation(selectAnimation); + cache.statusCheckedView = true; + } catch (Exception e) { + // nothing + } + } + + private void moveLeft(cgCacheView holder, cgCache cache, boolean force) { + if (cache == null) { + return; + } + + try { + holder.checkbox.setChecked(cache.statusChecked); + + // slide cache info + Animation hideCheckbox = new TranslateAnimation((int) (SWIPE_DISTANCE * pixelDensity), 0, 0, 0); + hideCheckbox.setRepeatCount(0); + if (force) { + hideCheckbox.setDuration(0); + } else { + hideCheckbox.setDuration(400); + } + hideCheckbox.setFillEnabled(true); + hideCheckbox.setFillAfter(true); + hideCheckbox.setInterpolator(new AccelerateDecelerateInterpolator()); + + // brighten cache info + Animation brightenInfo = new AlphaAnimation(SWIPE_OPACITY, 1.0f); + brightenInfo.setRepeatCount(0); + if (force) { + brightenInfo.setDuration(0); + } else { + brightenInfo.setDuration(400); + } + brightenInfo.setFillEnabled(true); + brightenInfo.setFillAfter(true); + brightenInfo.setInterpolator(new AccelerateDecelerateInterpolator()); + + // animation set (container) + AnimationSet selectAnimation = new AnimationSet(true); + selectAnimation.setFillEnabled(true); + selectAnimation.setFillAfter(true); + + selectAnimation.addAnimation(hideCheckbox); + selectAnimation.addAnimation(brightenInfo); + + holder.oneInfo.startAnimation(selectAnimation); + cache.statusCheckedView = false; + } catch (Exception e) { + // nothing + } + } } diff --git a/src/cgeo/geocaching/cgCacheView.java b/src/cgeo/geocaching/cgCacheView.java index 08c9d17..6b3b433 100644 --- a/src/cgeo/geocaching/cgCacheView.java +++ b/src/cgeo/geocaching/cgCacheView.java @@ -6,23 +6,23 @@ import android.widget.RelativeLayout; import android.widget.TextView; public class cgCacheView { - // layouts & views - public RelativeLayout oneCache; - public RelativeLayout oneInfo; - public RelativeLayout oneCheckbox; - public CheckBox checkbox; - public ImageView logStatusMark; - public TextView text; - public TextView favourite; - public TextView info; - public RelativeLayout inventory; - public RelativeLayout directionLayout; - public cgDistanceView distance; - public cgCompassMini direction; - public RelativeLayout dirImgLayout; - public ImageView dirImg; + // layouts & views + public RelativeLayout oneCache; + public RelativeLayout oneInfo; + public RelativeLayout oneCheckbox; + public CheckBox checkbox; + public ImageView logStatusMark; + public TextView text; + public TextView favourite; + public TextView info; + public RelativeLayout inventory; + public RelativeLayout directionLayout; + public cgDistanceView distance; + public cgCompassMini direction; + public RelativeLayout dirImgLayout; + public ImageView dirImg; - // status - public float startX = -1; - public float prevX = -1; + // status + public float startX = -1; + public float prevX = -1; } diff --git a/src/cgeo/geocaching/cgCacheWrap.java b/src/cgeo/geocaching/cgCacheWrap.java index ccf6fa7..e8668b5 100644 --- a/src/cgeo/geocaching/cgCacheWrap.java +++ b/src/cgeo/geocaching/cgCacheWrap.java @@ -8,8 +8,8 @@ import java.util.List; */ public class cgCacheWrap { public String error = null; - public String url = ""; - public String[] viewstates = null; - public int totalCnt = 0; - public List<cgCache> cacheList = new ArrayList<cgCache>(); + public String url = ""; + public String[] viewstates = null; + public int totalCnt = 0; + public List<cgCache> cacheList = new ArrayList<cgCache>(); }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgCompass.java b/src/cgeo/geocaching/cgCompass.java index f45501d..e748bef 100644 --- a/src/cgeo/geocaching/cgCompass.java +++ b/src/cgeo/geocaching/cgCompass.java @@ -14,255 +14,258 @@ import android.view.View; public class cgCompass extends View { - private changeThread watchdog = null; - private volatile boolean wantStop = false; - private Context context = null; - private Bitmap compassUnderlay = null; - private Bitmap compassRose = null; - private Bitmap compassArrow = null; - private Bitmap compassOverlay = null; - private double azimuth = 0.0; - private double heading = 0.0; - private double cacheHeading = 0.0; - private double northHeading = 0.0; - private PaintFlagsDrawFilter setfil = null; - private PaintFlagsDrawFilter remfil = null; - private int compassUnderlayWidth = 0; - private int compassUnderlayHeight = 0; - private int compassRoseWidth = 0; - private int compassRoseHeight = 0; - private int compassArrowWidth = 0; - private int compassArrowHeight = 0; - private int compassOverlayWidth = 0; - private int compassOverlayHeight = 0; - private boolean initialDisplay; - private Handler changeHandler = new Handler() { - - @Override - public void handleMessage(Message message) { - try { - invalidate(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgCompass.changeHandler: " + e.toString()); - } - } - }; - - public cgCompass(Context contextIn) { - super(contextIn); - context = contextIn; - } - - public cgCompass(Context contextIn, AttributeSet attrs) { - super(contextIn, attrs); - context = contextIn; - } - - @Override - public void onAttachedToWindow() { - compassUnderlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_underlay); - compassRose = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_rose); - compassArrow = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_arrow); - compassOverlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_overlay); - - compassUnderlayWidth = compassUnderlay.getWidth(); - compassUnderlayHeight = compassUnderlay.getWidth(); - compassRoseWidth = compassRose.getWidth(); - compassRoseHeight = compassRose.getWidth(); - compassArrowWidth = compassArrow.getWidth(); - compassArrowHeight = compassArrow.getWidth(); - compassOverlayWidth = compassOverlay.getWidth(); - compassOverlayHeight = compassOverlay.getWidth(); - - setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); - remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); - - initialDisplay = true; - wantStop = false; - - watchdog = new changeThread(); - watchdog.start(); - } - - @Override - public void onDetachedFromWindow() { - wantStop = true; - - if (compassUnderlay != null) { - compassUnderlay.recycle(); - } - - if (compassRose != null) { - compassRose.recycle(); - } - - if (compassArrow != null) { - compassArrow.recycle(); - } - - if (compassOverlay != null) { - compassOverlay.recycle(); - } - } - - protected synchronized void updateNorth(double northHeadingIn, double cacheHeadingIn) { - if (initialDisplay) { - // We will force the compass to move brutally if this is the first - // update since it is visible. - azimuth = northHeadingIn; - heading = cacheHeadingIn; - initialDisplay = false; - } - northHeading = northHeadingIn; - cacheHeading = cacheHeadingIn; - } - - /** - * Compute the new value, moving by small increments. - * @param goal the goal to reach - * @param actual the actual value - * @return the new value - */ - static protected double smoothUpdate(double goal, double actual) { - double diff = goal - actual; - final boolean largeDiff = Math.abs(diff) > 5; - - double offset = 0.0; - - if (diff < 0.0) { - diff = diff + 360.0; - } else if (diff >= 360.0) { - diff = diff - 360.0; - } - - // If the difference is smaller than 1 degree, do nothing as it - // causes the arrow to vibrate. - if (diff > 1.0 && diff <= 180.0) { - offset = largeDiff ? 2.0 : 1.0; - } else if (diff > 180.0 && diff < 359.0) { - offset = largeDiff ? -2.0 : -1.0; - } - - return actual + offset; - } - - private class changeThread extends Thread { - - @Override - public void run() { - while (wantStop == false) { - try { - sleep(50); - } catch (Exception e) { - // nothing - } - - synchronized(cgCompass.this) { - azimuth = smoothUpdate(northHeading, azimuth); - heading = smoothUpdate(cacheHeading, heading); - } - - changeHandler.sendMessage(new Message()); - } - } - } - - @Override - protected void onDraw(Canvas canvas) { - double currentAzimuth; - double currentHeading; - - synchronized(this) { - currentAzimuth = azimuth; - currentHeading = heading; - } - - double azimuthTemp = currentAzimuth; - double azimuthRelative = azimuthTemp - currentHeading; - if (azimuthRelative < 0) { - azimuthRelative = azimuthRelative + 360; - } else if (azimuthRelative >= 360) { - azimuthRelative = azimuthRelative - 360; - } - - // compass margins - int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2); - int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2); - - int marginLeftTemp = 0; - int marginTopTemp = 0; - - super.onDraw(canvas); - - canvas.save(); - canvas.setDrawFilter(setfil); - - marginLeftTemp = (getWidth() - compassUnderlayWidth) / 2; - marginTopTemp = (getHeight() - compassUnderlayHeight) / 2; - - canvas.drawBitmap(compassUnderlay, marginLeftTemp, marginTopTemp, null); - - marginLeftTemp = (getWidth() - compassRoseWidth) / 2; - marginTopTemp = (getHeight() - compassRoseHeight) / 2; - - canvas.rotate((float) -azimuthTemp, canvasCenterX, canvasCenterY); - canvas.drawBitmap(compassRose, marginLeftTemp, marginTopTemp, null); - canvas.rotate((float) azimuthTemp, canvasCenterX, canvasCenterY); - - marginLeftTemp = (getWidth() - compassArrowWidth) / 2; - marginTopTemp = (getHeight() - compassArrowHeight) / 2; - - canvas.rotate((float) -azimuthRelative, canvasCenterX, canvasCenterY); - canvas.drawBitmap(compassArrow, marginLeftTemp, marginTopTemp, null); - canvas.rotate((float) azimuthRelative, canvasCenterX, canvasCenterY); - - marginLeftTemp = (getWidth() - compassOverlayWidth) / 2; - marginTopTemp = (getHeight() - compassOverlayHeight) / 2; - - canvas.drawBitmap(compassOverlay, marginLeftTemp, marginTopTemp, null); - - canvas.setDrawFilter(remfil); - canvas.restore(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); - } - - private int measureWidth(int measureSpec) { - int result = 0; - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - if (specMode == MeasureSpec.EXACTLY) { - result = specSize; - } else { - result = compassArrow.getWidth() + getPaddingLeft() + getPaddingRight(); - - if (specMode == MeasureSpec.AT_MOST) { - result = Math.min(result, specSize); - } - } - - return result; - } - - private int measureHeight(int measureSpec) { - int result = 0; - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - if (specMode == MeasureSpec.EXACTLY) { - result = specSize; - } else { - result = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom(); - - if (specMode == MeasureSpec.AT_MOST) { - result = Math.min(result, specSize); - } - } + private changeThread watchdog = null; + private volatile boolean wantStop = false; + private Context context = null; + private Bitmap compassUnderlay = null; + private Bitmap compassRose = null; + private Bitmap compassArrow = null; + private Bitmap compassOverlay = null; + private double azimuth = 0.0; + private double heading = 0.0; + private double cacheHeading = 0.0; + private double northHeading = 0.0; + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + private int compassUnderlayWidth = 0; + private int compassUnderlayHeight = 0; + private int compassRoseWidth = 0; + private int compassRoseHeight = 0; + private int compassArrowWidth = 0; + private int compassArrowHeight = 0; + private int compassOverlayWidth = 0; + private int compassOverlayHeight = 0; + private boolean initialDisplay; + private Handler changeHandler = new Handler() { + + @Override + public void handleMessage(Message message) { + try { + invalidate(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgCompass.changeHandler: " + e.toString()); + } + } + }; + + public cgCompass(Context contextIn) { + super(contextIn); + context = contextIn; + } + + public cgCompass(Context contextIn, AttributeSet attrs) { + super(contextIn, attrs); + context = contextIn; + } + + @Override + public void onAttachedToWindow() { + compassUnderlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_underlay); + compassRose = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_rose); + compassArrow = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_arrow); + compassOverlay = BitmapFactory.decodeResource(context.getResources(), R.drawable.compass_overlay); + + compassUnderlayWidth = compassUnderlay.getWidth(); + compassUnderlayHeight = compassUnderlay.getWidth(); + compassRoseWidth = compassRose.getWidth(); + compassRoseHeight = compassRose.getWidth(); + compassArrowWidth = compassArrow.getWidth(); + compassArrowHeight = compassArrow.getWidth(); + compassOverlayWidth = compassOverlay.getWidth(); + compassOverlayHeight = compassOverlay.getWidth(); + + setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + + initialDisplay = true; + wantStop = false; + + watchdog = new changeThread(); + watchdog.start(); + } + + @Override + public void onDetachedFromWindow() { + wantStop = true; + + if (compassUnderlay != null) { + compassUnderlay.recycle(); + } + + if (compassRose != null) { + compassRose.recycle(); + } + + if (compassArrow != null) { + compassArrow.recycle(); + } + + if (compassOverlay != null) { + compassOverlay.recycle(); + } + } + + protected synchronized void updateNorth(double northHeadingIn, double cacheHeadingIn) { + if (initialDisplay) { + // We will force the compass to move brutally if this is the first + // update since it is visible. + azimuth = northHeadingIn; + heading = cacheHeadingIn; + initialDisplay = false; + } + northHeading = northHeadingIn; + cacheHeading = cacheHeadingIn; + } + + /** + * Compute the new value, moving by small increments. + * + * @param goal + * the goal to reach + * @param actual + * the actual value + * @return the new value + */ + static protected double smoothUpdate(double goal, double actual) { + double diff = goal - actual; + final boolean largeDiff = Math.abs(diff) > 5; + + double offset = 0.0; + + if (diff < 0.0) { + diff = diff + 360.0; + } else if (diff >= 360.0) { + diff = diff - 360.0; + } + + // If the difference is smaller than 1 degree, do nothing as it + // causes the arrow to vibrate. + if (diff > 1.0 && diff <= 180.0) { + offset = largeDiff ? 2.0 : 1.0; + } else if (diff > 180.0 && diff < 359.0) { + offset = largeDiff ? -2.0 : -1.0; + } + + return actual + offset; + } + + private class changeThread extends Thread { + + @Override + public void run() { + while (wantStop == false) { + try { + sleep(50); + } catch (Exception e) { + // nothing + } + + synchronized (cgCompass.this) { + azimuth = smoothUpdate(northHeading, azimuth); + heading = smoothUpdate(cacheHeading, heading); + } + + changeHandler.sendMessage(new Message()); + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + double currentAzimuth; + double currentHeading; + + synchronized (this) { + currentAzimuth = azimuth; + currentHeading = heading; + } + + double azimuthTemp = currentAzimuth; + double azimuthRelative = azimuthTemp - currentHeading; + if (azimuthRelative < 0) { + azimuthRelative = azimuthRelative + 360; + } else if (azimuthRelative >= 360) { + azimuthRelative = azimuthRelative - 360; + } + + // compass margins + int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2); + int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2); + + int marginLeftTemp = 0; + int marginTopTemp = 0; + + super.onDraw(canvas); + + canvas.save(); + canvas.setDrawFilter(setfil); + + marginLeftTemp = (getWidth() - compassUnderlayWidth) / 2; + marginTopTemp = (getHeight() - compassUnderlayHeight) / 2; + + canvas.drawBitmap(compassUnderlay, marginLeftTemp, marginTopTemp, null); + + marginLeftTemp = (getWidth() - compassRoseWidth) / 2; + marginTopTemp = (getHeight() - compassRoseHeight) / 2; + + canvas.rotate((float) -azimuthTemp, canvasCenterX, canvasCenterY); + canvas.drawBitmap(compassRose, marginLeftTemp, marginTopTemp, null); + canvas.rotate((float) azimuthTemp, canvasCenterX, canvasCenterY); + + marginLeftTemp = (getWidth() - compassArrowWidth) / 2; + marginTopTemp = (getHeight() - compassArrowHeight) / 2; + + canvas.rotate((float) -azimuthRelative, canvasCenterX, canvasCenterY); + canvas.drawBitmap(compassArrow, marginLeftTemp, marginTopTemp, null); + canvas.rotate((float) azimuthRelative, canvasCenterX, canvasCenterY); + + marginLeftTemp = (getWidth() - compassOverlayWidth) / 2; + marginTopTemp = (getHeight() - compassOverlayHeight) / 2; + + canvas.drawBitmap(compassOverlay, marginLeftTemp, marginTopTemp, null); + + canvas.setDrawFilter(remfil); + canvas.restore(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); + } + + private int measureWidth(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } else { + result = compassArrow.getWidth() + getPaddingLeft() + getPaddingRight(); + + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } + + return result; + } + + private int measureHeight(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } else { + result = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom(); + + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } - return result; - } + return result; + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgCompassMini.java b/src/cgeo/geocaching/cgCompassMini.java index bd3cad0..2a9f550 100644 --- a/src/cgeo/geocaching/cgCompassMini.java +++ b/src/cgeo/geocaching/cgCompassMini.java @@ -1,5 +1,7 @@ package cgeo.geocaching; +import cgeo.geocaching.geopoint.Geopoint; + import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -9,79 +11,81 @@ import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.util.AttributeSet; import android.view.View; -import cgeo.geocaching.geopoint.Geopoint; public class cgCompassMini extends View { - private int arrowSkin = R.drawable.compass_arrow_mini_white; - private Context context = null; - private Geopoint cacheCoords = null; - private Bitmap compassArrow = null; - private float azimuth = 0; - private float heading = 0; - private PaintFlagsDrawFilter setfil = null; - private PaintFlagsDrawFilter remfil = null; - - public cgCompassMini(Context contextIn) { - super(contextIn); - context = contextIn; - } - - public cgCompassMini(Context contextIn, AttributeSet attrs) { - super(contextIn, attrs); - context = contextIn; - - TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.cgCompassMini); - int usedSkin = attributes.getInt(R.styleable.cgCompassMini_skin, 0); - if (usedSkin == 1) arrowSkin = R.drawable.compass_arrow_mini_black; - else arrowSkin = R.drawable.compass_arrow_mini_white; - } - - @Override - public void onAttachedToWindow() { - compassArrow = BitmapFactory.decodeResource(context.getResources(), arrowSkin); - - setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); - remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); - } - - @Override - public void onDetachedFromWindow() { - if (compassArrow != null) { - compassArrow.recycle(); - compassArrow = null; - } - } - - public void setContent(final Geopoint cacheCoordsIn) { - cacheCoords = cacheCoordsIn; - } - - protected void updateAzimuth(float azimuthIn) { - azimuth = azimuthIn; - - updateDirection(); - } - - protected void updateHeading(float headingIn) { - heading = headingIn; - - updateDirection(); - } - - protected void updateCoords(final Geopoint coordsIn) { - if (coordsIn == null || cacheCoords == null) { - return; - } - - heading = coordsIn.bearingTo(cacheCoords); - - updateDirection(); - } - - protected void updateDirection() { - if (compassArrow == null || compassArrow.isRecycled()) { - return; - } + private int arrowSkin = R.drawable.compass_arrow_mini_white; + private Context context = null; + private Geopoint cacheCoords = null; + private Bitmap compassArrow = null; + private float azimuth = 0; + private float heading = 0; + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + + public cgCompassMini(Context contextIn) { + super(contextIn); + context = contextIn; + } + + public cgCompassMini(Context contextIn, AttributeSet attrs) { + super(contextIn, attrs); + context = contextIn; + + TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.cgCompassMini); + int usedSkin = attributes.getInt(R.styleable.cgCompassMini_skin, 0); + if (usedSkin == 1) { + arrowSkin = R.drawable.compass_arrow_mini_black; + } else { + arrowSkin = R.drawable.compass_arrow_mini_white; + } + } + + @Override + public void onAttachedToWindow() { + compassArrow = BitmapFactory.decodeResource(context.getResources(), arrowSkin); + + setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + } + + @Override + public void onDetachedFromWindow() { + if (compassArrow != null) { + compassArrow.recycle(); + compassArrow = null; + } + } + + public void setContent(final Geopoint cacheCoordsIn) { + cacheCoords = cacheCoordsIn; + } + + protected void updateAzimuth(float azimuthIn) { + azimuth = azimuthIn; + + updateDirection(); + } + + protected void updateHeading(float headingIn) { + heading = headingIn; + + updateDirection(); + } + + protected void updateCoords(final Geopoint coordsIn) { + if (coordsIn == null || cacheCoords == null) { + return; + } + + heading = coordsIn.bearingTo(cacheCoords); + + updateDirection(); + } + + protected void updateDirection() { + if (compassArrow == null || compassArrow.isRecycled()) { + return; + } // compass margins int compassRoseWidth = compassArrow.getWidth(); @@ -90,40 +94,40 @@ public class cgCompassMini extends View { int marginTop = (getHeight() - compassRoseHeight) / 2; invalidate(marginLeft, marginTop, (marginLeft + compassRoseWidth), (marginTop + compassRoseHeight)); - } - - @Override - protected void onDraw(Canvas canvas){ - super.onDraw(canvas); + } - float azimuthRelative = azimuth - heading; - if (azimuthRelative < 0) { - azimuthRelative = azimuthRelative + 360; - } else if (azimuthRelative >= 360) { - azimuthRelative = azimuthRelative - 360; - } + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + float azimuthRelative = azimuth - heading; + if (azimuthRelative < 0) { + azimuthRelative = azimuthRelative + 360; + } else if (azimuthRelative >= 360) { + azimuthRelative = azimuthRelative - 360; + } - // compass margins - canvas.setDrawFilter(setfil); + // compass margins + canvas.setDrawFilter(setfil); - int marginLeft = 0; - int marginTop = 0; + int marginLeft = 0; + int marginTop = 0; - int compassArrowWidth = compassArrow.getWidth(); - int compassArrowHeight = compassArrow.getWidth(); + int compassArrowWidth = compassArrow.getWidth(); + int compassArrowHeight = compassArrow.getWidth(); - int canvasCenterX = (compassArrowWidth / 2) + ((getWidth() - compassArrowWidth) / 2); - int canvasCenterY = (compassArrowHeight / 2) + ((getHeight() - compassArrowHeight) / 2); + int canvasCenterX = (compassArrowWidth / 2) + ((getWidth() - compassArrowWidth) / 2); + int canvasCenterY = (compassArrowHeight / 2) + ((getHeight() - compassArrowHeight) / 2); - marginLeft = (getWidth() - compassArrowWidth) / 2; - marginTop = (getHeight() - compassArrowHeight) / 2; + marginLeft = (getWidth() - compassArrowWidth) / 2; + marginTop = (getHeight() - compassArrowHeight) / 2; - canvas.rotate(-azimuthRelative, canvasCenterX, canvasCenterY); - canvas.drawBitmap(compassArrow, marginLeft, marginTop, null); - canvas.rotate(azimuthRelative, canvasCenterX, canvasCenterY); + canvas.rotate(-azimuthRelative, canvasCenterX, canvasCenterY); + canvas.drawBitmap(compassArrow, marginLeft, marginTop, null); + canvas.rotate(azimuthRelative, canvasCenterX, canvasCenterY); - canvas.setDrawFilter(remfil); - } + canvas.setDrawFilter(remfil); + } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { diff --git a/src/cgeo/geocaching/cgCoord.java b/src/cgeo/geocaching/cgCoord.java index d321001..09c9d91 100644 --- a/src/cgeo/geocaching/cgCoord.java +++ b/src/cgeo/geocaching/cgCoord.java @@ -4,42 +4,42 @@ import cgeo.geocaching.geopoint.Geopoint; public class cgCoord {
- public Integer id = null;
- public String geocode = "";
- public String type = "cache";
- public String typeSpec = "traditional";
- public String name = "";
- public boolean found = false;
- public boolean disabled = false;
- public Geopoint coords = new Geopoint(0, 0);
- public Float difficulty = null;
- public Float terrain = null;
- public String size = null;
+ public Integer id = null;
+ public String geocode = "";
+ public String type = "cache";
+ public String typeSpec = "traditional";
+ public String name = "";
+ public boolean found = false;
+ public boolean disabled = false;
+ public Geopoint coords = new Geopoint(0, 0);
+ public Float difficulty = null;
+ public Float terrain = null;
+ public String size = null;
- public cgCoord() {
- }
+ public cgCoord() {
+ }
- public cgCoord(cgCache cache) {
- disabled = cache.disabled;
- found = cache.found;
- geocode = cache.geocode;
- coords = cache.coords;
- name = cache.name;
- type = "cache";
- typeSpec = cache.type;
- difficulty = cache.difficulty;
- terrain = cache.terrain;
- size = cache.size;
- }
+ public cgCoord(cgCache cache) {
+ disabled = cache.disabled;
+ found = cache.found;
+ geocode = cache.geocode;
+ coords = cache.coords;
+ name = cache.name;
+ type = "cache";
+ typeSpec = cache.type;
+ difficulty = cache.difficulty;
+ terrain = cache.terrain;
+ size = cache.size;
+ }
- public cgCoord(cgWaypoint waypoint) {
- id = waypoint.id;
- disabled = false;
- found = false;
- geocode = "";
- coords = waypoint.coords;
- name = waypoint.name;
- type = "waypoint";
- typeSpec = waypoint.type;
- }
+ public cgCoord(cgWaypoint waypoint) {
+ id = waypoint.id;
+ disabled = false;
+ found = false;
+ geocode = "";
+ coords = waypoint.coords;
+ name = waypoint.name;
+ type = "waypoint";
+ typeSpec = waypoint.type;
+ }
}
diff --git a/src/cgeo/geocaching/cgData.java b/src/cgeo/geocaching/cgData.java index 6d44841..035be0b 100644 --- a/src/cgeo/geocaching/cgData.java +++ b/src/cgeo/geocaching/cgData.java @@ -1,5 +1,21 @@ package cgeo.geocaching; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.utils.CollectionUtils; + +import org.apache.commons.lang3.StringUtils; + +import android.content.ContentValues; +import android.content.Context; +import android.content.res.Resources; +import android.database.Cursor; +import android.database.DatabaseUtils.InsertHelper; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.database.sqlite.SQLiteStatement; +import android.os.Environment; +import android.util.Log; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -18,1380 +34,1367 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.apache.commons.lang3.StringUtils; +public class cgData { -import android.content.ContentValues; -import android.content.Context; -import android.content.res.Resources; -import android.database.Cursor; -import android.database.DatabaseUtils.InsertHelper; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.database.sqlite.SQLiteStatement; -import android.os.Environment; -import android.util.Log; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.utils.CollectionUtils; + /** The list of fields needed for mapping. */ + private static final String[] CACHE_COLUMNS = new String[] { + "_id", "updated", "reason", "detailed", "detailedupdate", "visiteddate", "geocode", "cacheid", "guid", "type", "name", "own", "owner", "owner_real", "hidden", "hint", "size", + "difficulty", "distance", "direction", "terrain", "latlon", "latitude_string", "longitude_string", "location", "latitude", "longitude", "elevation", "shortdesc", + "description", "favourite_cnt", "rating", "votes", "myvote", "disabled", "archived", "members", "found", "favourite", "inventorycoins", "inventorytags", + "inventoryunknown", "onWatchlist", "personal_note", "reliable_latlon" + }; + public cgCacheWrap caches; + private Context context = null; + private String path = null; + private cgDbHelper dbHelper = null; + private SQLiteDatabase databaseRO = null; + private SQLiteDatabase databaseRW = null; + private static final int dbVersion = 57; + private static final String dbName = "data"; + private static final String dbTableCaches = "cg_caches"; + private static final String dbTableLists = "cg_lists"; + private static final String dbTableAttributes = "cg_attributes"; + private static final String dbTableWaypoints = "cg_waypoints"; + private static final String dbTableSpoilers = "cg_spoilers"; + private static final String dbTableLogs = "cg_logs"; + private static final String dbTableLogCount = "cg_logCount"; + private static final String dbTableLogImages = "cg_logImages"; + private static final String dbTableLogsOffline = "cg_logs_offline"; + private static final String dbTableTrackables = "cg_trackables"; + private static final String dbTableSearchDestionationHistory = "cg_search_destination_history"; + private static final String dbCreateCaches = "" + + "create table " + dbTableCaches + " (" + + "_id integer primary key autoincrement, " + + "updated long not null, " + + "detailed integer not null default 0, " + + "detailedupdate long, " + + "visiteddate long, " + + "geocode text unique not null, " + + "reason integer not null default 0, " // cached, favourite... + + "cacheid text, " + + "guid text, " + + "type text, " + + "name text, " + + "own integer not null default 0, " + + "owner text, " + + "owner_real text, " + + "hidden long, " + + "hint text, " + + "size text, " + + "difficulty float, " + + "terrain float, " + + "latlon text, " + + "latitude_string text, " + + "longitude_string text, " + + "location text, " + + "direction double, " + + "distance double, " + + "latitude double, " + + "longitude double, " + + "reliable_latlon integer, " + + "elevation double, " + + "personal_note text, " + + "shortdesc text, " + + "description text, " + + "favourite_cnt integer, " + + "rating float, " + + "votes integer, " + + "myvote float, " + + "disabled integer not null default 0, " + + "archived integer not null default 0, " + + "members integer not null default 0, " + + "found integer not null default 0, " + + "favourite integer not null default 0, " + + "inventorycoins integer default 0, " + + "inventorytags integer default 0, " + + "inventoryunknown integer default 0, " + + "onWatchlist integer default 0 " + + "); "; + private static final String dbCreateLists = "" + + "create table " + dbTableLists + " (" + + "_id integer primary key autoincrement, " + + "title text not null, " + + "updated long not null, " + + "latitude double, " + + "longitude double " + + "); "; + private static final String dbCreateAttributes = "" + + "create table " + dbTableAttributes + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "attribute text " + + "); "; + private final static int ATTRIBUTES_GEOCODE = 2; + private final static int ATTRIBUTES_UPDATED = 3; + private final static int ATTRIBUTES_ATTRIBUTE = 4; + + private static final String dbCreateWaypoints = "" + + "create table " + dbTableWaypoints + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "type text not null default 'waypoint', " + + "prefix text, " + + "lookup text, " + + "name text, " + + "latlon text, " + + "latitude_string text, " + + "longitude_string text, " + + "latitude double, " + + "longitude double, " + + "note text " + + "); "; + private static final String dbCreateSpoilers = "" + + "create table " + dbTableSpoilers + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "url text, " + + "title text, " + + "description text " + + "); "; + private static final String dbCreateLogs = "" + + "create table " + dbTableLogs + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "type integer not null default 4, " + + "author text, " + + "log text, " + + "date long, " + + "found integer not null default 0 " + + "); "; + private final static int LOGS_GEOCODE = 2; + private final static int LOGS_UPDATED = 3; + private final static int LOGS_TYPE = 4; + private final static int LOGS_AUTHOR = 5; + private final static int LOGS_LOG = 6; + private final static int LOGS_DATE = 7; + private final static int LOGS_FOUND = 8; + + private static final String dbCreateLogCount = "" + + "create table " + dbTableLogCount + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "type integer not null default 4, " + + "count integer not null default 0 " + + "); "; + private static final String dbCreateLogImages = "" + + "create table " + dbTableLogImages + " (" + + "_id integer primary key autoincrement, " + + "log_id integer not null, " + + "title text not null, " + + "url text not null" + + "); "; + private static final String dbCreateLogsOffline = "" + + "create table " + dbTableLogsOffline + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "type integer not null default 4, " + + "log text, " + + "date long " + + "); "; + private static final String dbCreateTrackables = "" + + "create table " + dbTableTrackables + " (" + + "_id integer primary key autoincrement, " + + "updated long not null, " // date of save + + "tbcode text not null, " + + "guid text, " + + "title text, " + + "owner text, " + + "released long, " + + "goal text, " + + "description text, " + + "geocode text " + + "); "; + + private static final String dbCreateSearchDestinationHistory = "" + + "create table " + dbTableSearchDestionationHistory + " (" + + "_id integer primary key autoincrement, " + + "date long not null, " + + "latitude double, " + + "longitude double " + + "); "; + + public boolean initialized = false; + + public cgData(Context contextIn) { + context = contextIn; + } -public class cgData { + public synchronized void init() { + if (databaseRW == null || databaseRW.isOpen() == false) { + try { + if (dbHelper == null) { + dbHelper = new cgDbHelper(context); + } + databaseRW = dbHelper.getWritableDatabase(); + + if (databaseRW != null && databaseRW.isOpen()) { + Log.i(cgSettings.tag, "Connection to RW database established."); + } else { + Log.e(cgSettings.tag, "Failed to open connection to RW database."); + } + + if (databaseRW != null && databaseRW.inTransaction()) { + databaseRW.endTransaction(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.openDb.RW: " + e.toString()); + } + } + + if (databaseRO == null || !databaseRO.isOpen()) { + try { + if (dbHelper == null) { + dbHelper = new cgDbHelper(context); + } + databaseRO = dbHelper.getReadableDatabase(); + + if (databaseRO.needUpgrade(dbVersion)) { + databaseRO = null; + } + + if (databaseRO != null && databaseRO.isOpen()) { + Log.i(cgSettings.tag, "Connection to RO database established."); + } else { + Log.e(cgSettings.tag, "Failed to open connection to RO database."); + } + + if (databaseRO != null && databaseRO.inTransaction()) { + databaseRO.endTransaction(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.openDb.RO: " + e.toString()); + } + } + + initialized = true; + } + + public void closeDb() { + if (databaseRO != null) { + path = databaseRO.getPath(); + + if (databaseRO.inTransaction()) { + databaseRO.endTransaction(); + } + + databaseRO.close(); + databaseRO = null; + SQLiteDatabase.releaseMemory(); + + Log.d(cgSettings.tag, "Closing RO database"); + } + + if (databaseRW != null) { + path = databaseRW.getPath(); + + if (databaseRW.inTransaction()) { + databaseRW.endTransaction(); + } + + databaseRW.close(); + databaseRW = null; + SQLiteDatabase.releaseMemory(); - /**The list of fields needed for mapping.*/ - private static final String[] CACHE_COLUMNS = new String[]{ - "_id", "updated", "reason", "detailed", "detailedupdate", "visiteddate", "geocode", "cacheid", "guid", "type", "name", "own", "owner", "owner_real", "hidden", "hint", "size", - "difficulty", "distance", "direction", "terrain", "latlon", "latitude_string", "longitude_string", "location", "latitude", "longitude", "elevation", "shortdesc", - "description", "favourite_cnt", "rating", "votes", "myvote", "disabled", "archived", "members", "found", "favourite", "inventorycoins", "inventorytags", - "inventoryunknown", "onWatchlist", "personal_note", "reliable_latlon" - }; - public cgCacheWrap caches; - private Context context = null; - private String path = null; - private cgDbHelper dbHelper = null; - private SQLiteDatabase databaseRO = null; - private SQLiteDatabase databaseRW = null; - private static final int dbVersion = 57; - private static final String dbName = "data"; - private static final String dbTableCaches = "cg_caches"; - private static final String dbTableLists = "cg_lists"; - private static final String dbTableAttributes = "cg_attributes"; - private static final String dbTableWaypoints = "cg_waypoints"; - private static final String dbTableSpoilers = "cg_spoilers"; - private static final String dbTableLogs = "cg_logs"; - private static final String dbTableLogCount = "cg_logCount"; - private static final String dbTableLogImages = "cg_logImages"; - private static final String dbTableLogsOffline = "cg_logs_offline"; - private static final String dbTableTrackables = "cg_trackables"; - private static final String dbTableSearchDestionationHistory = "cg_search_destination_history"; - private static final String dbCreateCaches = "" - + "create table " + dbTableCaches + " (" - + "_id integer primary key autoincrement, " - + "updated long not null, " - + "detailed integer not null default 0, " - + "detailedupdate long, " - + "visiteddate long, " - + "geocode text unique not null, " - + "reason integer not null default 0, " // cached, favourite... - + "cacheid text, " - + "guid text, " - + "type text, " - + "name text, " - + "own integer not null default 0, " - + "owner text, " - + "owner_real text, " - + "hidden long, " - + "hint text, " - + "size text, " - + "difficulty float, " - + "terrain float, " - + "latlon text, " - + "latitude_string text, " - + "longitude_string text, " - + "location text, " - + "direction double, " - + "distance double, " - + "latitude double, " - + "longitude double, " - + "reliable_latlon integer, " - + "elevation double, " - + "personal_note text, " - + "shortdesc text, " - + "description text, " - + "favourite_cnt integer, " - + "rating float, " - + "votes integer, " - + "myvote float, " - + "disabled integer not null default 0, " - + "archived integer not null default 0, " - + "members integer not null default 0, " - + "found integer not null default 0, " - + "favourite integer not null default 0, " - + "inventorycoins integer default 0, " - + "inventorytags integer default 0, " - + "inventoryunknown integer default 0, " - + "onWatchlist integer default 0 " - + "); "; - private static final String dbCreateLists = "" - + "create table " + dbTableLists + " (" - + "_id integer primary key autoincrement, " - + "title text not null, " - + "updated long not null, " - + "latitude double, " - + "longitude double " - + "); "; - private static final String dbCreateAttributes = "" - + "create table " + dbTableAttributes + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "attribute text " - + "); "; - private final static int ATTRIBUTES_GEOCODE = 2; - private final static int ATTRIBUTES_UPDATED = 3; - private final static int ATTRIBUTES_ATTRIBUTE = 4; - - private static final String dbCreateWaypoints = "" - + "create table " + dbTableWaypoints + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "type text not null default 'waypoint', " - + "prefix text, " - + "lookup text, " - + "name text, " - + "latlon text, " - + "latitude_string text, " - + "longitude_string text, " - + "latitude double, " - + "longitude double, " - + "note text " - + "); "; - private static final String dbCreateSpoilers = "" - + "create table " + dbTableSpoilers + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "url text, " - + "title text, " - + "description text " - + "); "; - private static final String dbCreateLogs = "" - + "create table " + dbTableLogs + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "type integer not null default 4, " - + "author text, " - + "log text, " - + "date long, " - + "found integer not null default 0 " - + "); "; - private final static int LOGS_GEOCODE = 2; - private final static int LOGS_UPDATED = 3; - private final static int LOGS_TYPE = 4; - private final static int LOGS_AUTHOR = 5; - private final static int LOGS_LOG = 6; - private final static int LOGS_DATE = 7; - private final static int LOGS_FOUND = 8; - - private static final String dbCreateLogCount = "" - + "create table " + dbTableLogCount + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "type integer not null default 4, " - + "count integer not null default 0 " - + "); "; - private static final String dbCreateLogImages = "" - + "create table " + dbTableLogImages + " (" - + "_id integer primary key autoincrement, " - + "log_id integer not null, " - + "title text not null, " - + "url text not null" - + "); "; - private static final String dbCreateLogsOffline = "" - + "create table " + dbTableLogsOffline + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "type integer not null default 4, " - + "log text, " - + "date long " - + "); "; - private static final String dbCreateTrackables = "" - + "create table " + dbTableTrackables + " (" - + "_id integer primary key autoincrement, " - + "updated long not null, " // date of save - + "tbcode text not null, " - + "guid text, " - + "title text, " - + "owner text, " - + "released long, " - + "goal text, " - + "description text, " - + "geocode text " - + "); "; - - private static final String dbCreateSearchDestinationHistory = "" - + "create table " + dbTableSearchDestionationHistory + " (" - + "_id integer primary key autoincrement, " - + "date long not null, " - + "latitude double, " - + "longitude double " - + "); "; - - public boolean initialized = false; - - public cgData(Context contextIn) { - context = contextIn; - } - - public synchronized void init() { - if (databaseRW == null || databaseRW.isOpen() == false) { - try { - if (dbHelper == null) { - dbHelper = new cgDbHelper(context); - } - databaseRW = dbHelper.getWritableDatabase(); - - if (databaseRW != null && databaseRW.isOpen()) { - Log.i(cgSettings.tag, "Connection to RW database established."); - } else { - Log.e(cgSettings.tag, "Failed to open connection to RW database."); - } - - if (databaseRW != null && databaseRW.inTransaction()) { - databaseRW.endTransaction(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.openDb.RW: " + e.toString()); - } - } - - if (databaseRO == null || !databaseRO.isOpen()) { - try { - if (dbHelper == null) { - dbHelper = new cgDbHelper(context); - } - databaseRO = dbHelper.getReadableDatabase(); - - if (databaseRO.needUpgrade(dbVersion)) { - databaseRO = null; - } - - if (databaseRO != null && databaseRO.isOpen()) { - Log.i(cgSettings.tag, "Connection to RO database established."); - } else { - Log.e(cgSettings.tag, "Failed to open connection to RO database."); - } - - if (databaseRO != null && databaseRO.inTransaction()) { - databaseRO.endTransaction(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.openDb.RO: " + e.toString()); - } - } - - initialized = true; - } - - public void closeDb() { - if (databaseRO != null) { - path = databaseRO.getPath(); - - if (databaseRO.inTransaction()) { - databaseRO.endTransaction(); - } - - databaseRO.close(); - databaseRO = null; - SQLiteDatabase.releaseMemory(); - - Log.d(cgSettings.tag, "Closing RO database"); - } - - if (databaseRW != null) { - path = databaseRW.getPath(); - - if (databaseRW.inTransaction()) { - databaseRW.endTransaction(); - } - - databaseRW.close(); - databaseRW = null; - SQLiteDatabase.releaseMemory(); - - Log.d(cgSettings.tag, "Closing RW database"); - } - - if (dbHelper != null) { - dbHelper.close(); - dbHelper = null; - } - } - - public String backupDatabase() { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) == false) { - Log.w(cgSettings.tag, "Database wasn't backed up: no external memory"); - - return null; - } - - closeDb(); - - boolean backupDone = false; - final String directoryImg = cgSettings.cache; - final String directoryTarget = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/"; - final String fileTarget = directoryTarget + "cgeo.sqlite"; - final String fileSource = path; - - File directoryTargetFile = new File(directoryTarget); - if (directoryTargetFile.exists() == false) { - directoryTargetFile.mkdir(); - } - - InputStream input = null; - OutputStream output = null; - try { - input = new FileInputStream(fileSource); - output = new FileOutputStream(fileTarget); - } catch (FileNotFoundException e) { - Log.e(cgSettings.tag, "Database wasn't backed up, could not open file: " + e.toString()); - } - - byte[] buffer = new byte[1024]; - int length; - if ((input != null) && (output != null)) { - try { - while ((length = input.read(buffer)) > 0) { - output.write(buffer, 0, length); - } - output.flush(); - backupDone = true; - } catch (IOException e) { - Log.e(cgSettings.tag, "Database wasn't backed up, could not read/write file: " + e.toString()); - } - } - - try { - if (output != null) { + Log.d(cgSettings.tag, "Closing RW database"); + } + + if (dbHelper != null) { + dbHelper.close(); + dbHelper = null; + } + } + + public String backupDatabase() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) == false) { + Log.w(cgSettings.tag, "Database wasn't backed up: no external memory"); + + return null; + } + + closeDb(); + + boolean backupDone = false; + final String directoryImg = cgSettings.cache; + final String directoryTarget = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/"; + final String fileTarget = directoryTarget + "cgeo.sqlite"; + final String fileSource = path; + + File directoryTargetFile = new File(directoryTarget); + if (directoryTargetFile.exists() == false) { + directoryTargetFile.mkdir(); + } + + InputStream input = null; + OutputStream output = null; + try { + input = new FileInputStream(fileSource); + output = new FileOutputStream(fileTarget); + } catch (FileNotFoundException e) { + Log.e(cgSettings.tag, "Database wasn't backed up, could not open file: " + e.toString()); + } + + byte[] buffer = new byte[1024]; + int length; + if ((input != null) && (output != null)) { + try { + while ((length = input.read(buffer)) > 0) { + output.write(buffer, 0, length); + } + output.flush(); + backupDone = true; + } catch (IOException e) { + Log.e(cgSettings.tag, "Database wasn't backed up, could not read/write file: " + e.toString()); + } + } + + try { + if (output != null) { output.close(); } - if (input != null) { + if (input != null) { input.close(); } - } catch (IOException e) { - Log.e(cgSettings.tag, "Database wasn't backed up, could not close file: " + e.toString()); - } + } catch (IOException e) { + Log.e(cgSettings.tag, "Database wasn't backed up, could not close file: " + e.toString()); + } - if (backupDone) { + if (backupDone) { Log.i(cgSettings.tag, "Database was copied to " + fileTarget); } - init(); - - return backupDone ? fileTarget : null; - } - - public static File isRestoreFile() { - final String directoryImg = cgSettings.cache; - final String fileSource = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/cgeo.sqlite"; - - File fileSourceFile = new File(fileSource); - if (fileSourceFile.exists()) { - return fileSourceFile; - } else { - return null; - } - } - - public boolean restoreDatabase() { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) == false) { - Log.w(cgSettings.tag, "Database wasn't restored: no external memory"); - - return false; - } - - closeDb(); - - boolean restoreDone = false; - - final String directoryImg = cgSettings.cache; - final String fileSource = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/cgeo.sqlite"; - final String fileTarget = path; - - File fileSourceFile = new File(fileSource); - if (fileSourceFile.exists() == false) { - Log.w(cgSettings.tag, "Database backup was not found"); - - init(); - - return restoreDone; - } - - InputStream input = null; - OutputStream output = null; - try { - input = new FileInputStream(fileSource); - output = new FileOutputStream(fileTarget); - } catch (FileNotFoundException e) { - Log.e(cgSettings.tag, "Database wasn't restored, could not open file: " + e.toString()); - } - - byte[] buffer = new byte[1024]; - int length; - if ((input != null) && (output != null)) { - try { - while ((length = input.read(buffer)) > 0) { - output.write(buffer, 0, length); - } - output.flush(); - restoreDone = true; - } catch (IOException e) { - Log.e(cgSettings.tag, "Database wasn't restored, could not read/write file: " + e.toString()); - } - } - - try { - if (output != null) { + init(); + + return backupDone ? fileTarget : null; + } + + public static File isRestoreFile() { + final String directoryImg = cgSettings.cache; + final String fileSource = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/cgeo.sqlite"; + + File fileSourceFile = new File(fileSource); + if (fileSourceFile.exists()) { + return fileSourceFile; + } else { + return null; + } + } + + public boolean restoreDatabase() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) == false) { + Log.w(cgSettings.tag, "Database wasn't restored: no external memory"); + + return false; + } + + closeDb(); + + boolean restoreDone = false; + + final String directoryImg = cgSettings.cache; + final String fileSource = Environment.getExternalStorageDirectory() + "/" + directoryImg + "/cgeo.sqlite"; + final String fileTarget = path; + + File fileSourceFile = new File(fileSource); + if (fileSourceFile.exists() == false) { + Log.w(cgSettings.tag, "Database backup was not found"); + + init(); + + return restoreDone; + } + + InputStream input = null; + OutputStream output = null; + try { + input = new FileInputStream(fileSource); + output = new FileOutputStream(fileTarget); + } catch (FileNotFoundException e) { + Log.e(cgSettings.tag, "Database wasn't restored, could not open file: " + e.toString()); + } + + byte[] buffer = new byte[1024]; + int length; + if ((input != null) && (output != null)) { + try { + while ((length = input.read(buffer)) > 0) { + output.write(buffer, 0, length); + } + output.flush(); + restoreDone = true; + } catch (IOException e) { + Log.e(cgSettings.tag, "Database wasn't restored, could not read/write file: " + e.toString()); + } + } + + try { + if (output != null) { output.close(); } - if (input != null) { + if (input != null) { input.close(); } - } catch (IOException e) { - Log.e(cgSettings.tag, "Database wasn't restored, could not close file: " + e.toString()); - } + } catch (IOException e) { + Log.e(cgSettings.tag, "Database wasn't restored, could not close file: " + e.toString()); + } - if (restoreDone) { + if (restoreDone) { Log.i(cgSettings.tag, "Database was restored"); } - init(); - - return restoreDone; - } - - private static class cgDbHelper extends SQLiteOpenHelper { - - cgDbHelper(Context context) { - super(context, dbName, null, dbVersion); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL(dbCreateCaches); - db.execSQL(dbCreateLists); - db.execSQL(dbCreateAttributes); - db.execSQL(dbCreateWaypoints); - db.execSQL(dbCreateSpoilers); - db.execSQL(dbCreateLogs); - db.execSQL(dbCreateLogCount); - db.execSQL(dbCreateLogImages); - db.execSQL(dbCreateLogsOffline); - db.execSQL(dbCreateTrackables); - db.execSQL(dbCreateSearchDestinationHistory); - - db.execSQL("create index if not exists in_caches_geo on " + dbTableCaches + " (geocode)"); - db.execSQL("create index if not exists in_caches_guid on " + dbTableCaches + " (guid)"); - db.execSQL("create index if not exists in_caches_reason on " + dbTableCaches + " (reason)"); - db.execSQL("create index if not exists in_caches_detailed on " + dbTableCaches + " (detailed)"); - db.execSQL("create index if not exists in_caches_type on " + dbTableCaches + " (type)"); - db.execSQL("create index if not exists in_caches_visit_detail on " + dbTableCaches + " (visiteddate, detailedupdate)"); - db.execSQL("create index if not exists in_attr_geo on " + dbTableAttributes + " (geocode)"); - db.execSQL("create index if not exists in_wpts_geo on " + dbTableWaypoints + " (geocode)"); - db.execSQL("create index if not exists in_wpts_geo_type on " + dbTableWaypoints + " (geocode, type)"); - db.execSQL("create index if not exists in_spoil_geo on " + dbTableSpoilers + " (geocode)"); - db.execSQL("create index if not exists in_logs_geo on " + dbTableLogs + " (geocode)"); - db.execSQL("create index if not exists in_logcount_geo on " + dbTableLogCount + " (geocode)"); - db.execSQL("create index if not exists in_logsoff_geo on " + dbTableLogsOffline + " (geocode)"); - db.execSQL("create index if not exists in_trck_geo on " + dbTableTrackables + " (geocode)"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.i(cgSettings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": start"); - - try { - if (db.isReadOnly()) { - return; - } - - db.beginTransaction(); - - if (oldVersion <= 0) { // new table - dropDatabase(db); - onCreate(db); - - Log.i(cgSettings.tag, "Database structure created."); - } - - if (oldVersion > 0) { - db.execSQL("delete from " + dbTableCaches + " where reason = 0"); - - if (oldVersion < 34) { // upgrade to 34 - try { - db.execSQL("create index if not exists in_a on " + dbTableCaches + " (geocode)"); - db.execSQL("create index if not exists in_b on " + dbTableCaches + " (guid)"); - db.execSQL("create index if not exists in_c on " + dbTableCaches + " (reason)"); - db.execSQL("create index if not exists in_d on " + dbTableCaches + " (detailed)"); - db.execSQL("create index if not exists in_e on " + dbTableCaches + " (type)"); - db.execSQL("create index if not exists in_a on " + dbTableAttributes + " (geocode)"); - db.execSQL("create index if not exists in_a on " + dbTableWaypoints + " (geocode)"); - db.execSQL("create index if not exists in_b on " + dbTableWaypoints + " (geocode, type)"); - db.execSQL("create index if not exists in_a on " + dbTableSpoilers + " (geocode)"); - db.execSQL("create index if not exists in_a on " + dbTableLogs + " (geocode)"); - db.execSQL("create index if not exists in_a on " + dbTableTrackables + " (geocode)"); - - Log.i(cgSettings.tag, "Indexes added."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 34: " + e.toString()); - } - } - - if (oldVersion < 37) { // upgrade to 37 - try { - db.execSQL("alter table " + dbTableCaches + " add column direction text"); - db.execSQL("alter table " + dbTableCaches + " add column distance double"); - - Log.i(cgSettings.tag, "Columns direction and distance added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 37: " + e.toString()); - } - } - - if (oldVersion < 38) { // upgrade to 38 - try { - db.execSQL("drop table " + dbTableLogs); - db.execSQL(dbCreateLogs); - - Log.i(cgSettings.tag, "Changed type column in " + dbTableLogs + " to integer."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 38: " + e.toString()); - } - } - - if (oldVersion < 39) { // upgrade to 39 - try { - db.execSQL(dbCreateLists); - - Log.i(cgSettings.tag, "Created lists table."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 39: " + e.toString()); - } - } - - if (oldVersion < 40) { // upgrade to 40 - try { - db.execSQL("drop table " + dbTableTrackables); - db.execSQL(dbCreateTrackables); - - Log.i(cgSettings.tag, "Changed type of geocode column in trackables table."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 40: " + e.toString()); - } - } - - if (oldVersion < 41) { // upgrade to 41 - try { - db.execSQL("alter table " + dbTableCaches + " add column rating float"); - db.execSQL("alter table " + dbTableCaches + " add column votes integer"); - db.execSQL("alter table " + dbTableCaches + " add column vote integer"); - - Log.i(cgSettings.tag, "Added columns for GCvote."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 41: " + e.toString()); - } - } - - if (oldVersion < 42) { // upgrade to 42 - try { - db.execSQL(dbCreateLogsOffline); - - Log.i(cgSettings.tag, "Added table for offline logs"); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 42: " + e.toString()); - } - } - - if (oldVersion < 43) { // upgrade to 43 - try { - final String dbTableCachesTemp = dbTableCaches + "_temp"; - final String dbCreateCachesTemp = "" - + "create temporary table " + dbTableCachesTemp + " (" - + "_id integer primary key autoincrement, " - + "updated long not null, " - + "detailed integer not null default 0, " - + "detailedupdate long, " - + "geocode text unique not null, " - + "reason integer not null default 0, " // cached, favourite... - + "cacheid text, " - + "guid text, " - + "type text, " - + "name text, " - + "owner text, " - + "hidden long, " - + "hint text, " - + "size text, " - + "difficulty float, " - + "terrain float, " - + "latlon text, " - + "latitude_string text, " - + "longitude_string text, " - + "location text, " - + "distance double, " - + "latitude double, " - + "longitude double, " - + "shortdesc text, " - + "description text, " - + "rating float, " - + "votes integer, " - + "vote integer, " - + "disabled integer not null default 0, " - + "archived integer not null default 0, " - + "members integer not null default 0, " - + "found integer not null default 0, " - + "favourite integer not null default 0, " - + "inventorycoins integer default 0, " - + "inventorytags integer default 0, " - + "inventoryunknown integer default 0 " - + "); "; - final String dbCreateCachesNew = "" - + "create table " + dbTableCaches + " (" - + "_id integer primary key autoincrement, " - + "updated long not null, " - + "detailed integer not null default 0, " - + "detailedupdate long, " - + "geocode text unique not null, " - + "reason integer not null default 0, " // cached, favourite... - + "cacheid text, " - + "guid text, " - + "type text, " - + "name text, " - + "owner text, " - + "hidden long, " - + "hint text, " - + "size text, " - + "difficulty float, " - + "terrain float, " - + "latlon text, " - + "latitude_string text, " - + "longitude_string text, " - + "location text, " - + "direction double, " - + "distance double, " - + "latitude double, " - + "longitude double, " - + "shortdesc text, " - + "description text, " - + "rating float, " - + "votes integer, " - + "vote integer, " - + "disabled integer not null default 0, " - + "archived integer not null default 0, " - + "members integer not null default 0, " - + "found integer not null default 0, " - + "favourite integer not null default 0, " - + "inventorycoins integer default 0, " - + "inventorytags integer default 0, " - + "inventoryunknown integer default 0 " - + "); "; - - db.beginTransaction(); - db.execSQL(dbCreateCachesTemp); - db.execSQL("insert into " + dbTableCachesTemp + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCaches); - db.execSQL("drop table " + dbTableCaches); - db.execSQL(dbCreateCachesNew); - db.execSQL("insert into " + dbTableCaches + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, null, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCachesTemp); - db.execSQL("drop table " + dbTableCachesTemp); - db.setTransactionSuccessful(); - - Log.i(cgSettings.tag, "Changed direction column"); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 43: " + e.toString()); - } finally { - db.endTransaction(); - } - } - - if (oldVersion < 44) { // upgrade to 44 - try { - db.execSQL("alter table " + dbTableCaches + " add column favourite_cnt integer"); - - Log.i(cgSettings.tag, "Column favourite_cnt added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 44: " + e.toString()); - } - } - - if (oldVersion < 45) { // upgrade to 45 - try { - db.execSQL("alter table " + dbTableCaches + " add column owner_real text"); - - Log.i(cgSettings.tag, "Column owner_real added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 45: " + e.toString()); - } - } - - if (oldVersion < 46) { // upgrade to 46 - try { - db.execSQL("alter table " + dbTableCaches + " add column visiteddate long"); - db.execSQL("create index if not exists in_f on " + dbTableCaches + " (visiteddate, detailedupdate)"); - - Log.i(cgSettings.tag, "Added column for date of visit."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 46: " + e.toString()); - } - } - if (oldVersion < 47) { // upgrade to 47 - try { - db.execSQL("alter table " + dbTableCaches + " add column own integer not null default 0"); - - Log.i(cgSettings.tag, "Added column own."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 47: " + e.toString()); - } - } - - if (oldVersion < 48) { // upgrade to 48 - try { - db.execSQL("alter table " + dbTableCaches + " add column elevation double"); - - Log.i(cgSettings.tag, "Column elevation added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 48: " + e.toString()); - } - } - - if (oldVersion < 49) { // upgrade to 49 - try { - db.execSQL(dbCreateLogCount); - - Log.i(cgSettings.tag, "Created table " + dbTableLogCount + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 49: " + e.toString()); - } - } - - if (oldVersion < 50) { // upgrade to 50 - try { - db.execSQL("alter table " + dbTableCaches + " add column myvote float"); - - Log.i(cgSettings.tag, "Added float column for votes to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 50: " + e.toString()); - } - } - - if (oldVersion < 51) { // upgrade to 51 - try { - db.execSQL("alter table " + dbTableCaches + " add column reliable_latlon integer"); - - Log.i(cgSettings.tag, "Column reliable_latlon added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 51: " + e.toString()); - } - } - - if (oldVersion < 52) { // upgrade to 52 - try { - db.execSQL(dbCreateSearchDestinationHistory); - - Log.i(cgSettings.tag, "Added table " +dbTableSearchDestionationHistory +"."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 52", e); - } - } - - if (oldVersion < 53) { // upgrade to 53 - try { - db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer"); - - Log.i(cgSettings.tag, "Column onWatchlist added to " + dbTableCaches +"."); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 53", e); - } - } - - if (oldVersion < 54) { // update to 54 - try { - db.execSQL(dbCreateLogImages); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 54: " + e.toString()); - - } - } - - if (oldVersion < 55) { // update to 55 - try { - db.execSQL("alter table " + dbTableCaches + " add column personal_note text"); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 55: " + e.toString()); - - } - } - - // make all internal attribute names lowercase - // @see issue #299 - if (oldVersion < 56) { // update to 56 - try { - db.execSQL("update " + dbTableAttributes + " set attribute = " + - "lower(attribute) where attribute like \"%_yes\" " + - "or attribute like \"%_no\""); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 56: " + e.toString()); - } - } - - // Create missing indices. See issue #435 - if (oldVersion < 57) { // update to 57 - try { - db.execSQL("drop index in_a"); - db.execSQL("drop index in_b"); - db.execSQL("drop index in_c"); - db.execSQL("drop index in_d"); - db.execSQL("drop index in_e"); - db.execSQL("drop index in_f"); - db.execSQL("create index if not exists in_caches_geo on " + dbTableCaches + " (geocode)"); - db.execSQL("create index if not exists in_caches_guid on " + dbTableCaches + " (guid)"); - db.execSQL("create index if not exists in_caches_reason on " + dbTableCaches + " (reason)"); - db.execSQL("create index if not exists in_caches_detailed on " + dbTableCaches + " (detailed)"); - db.execSQL("create index if not exists in_caches_type on " + dbTableCaches + " (type)"); - db.execSQL("create index if not exists in_caches_visit_detail on " + dbTableCaches + " (visiteddate, detailedupdate)"); - db.execSQL("create index if not exists in_attr_geo on " + dbTableAttributes + " (geocode)"); - db.execSQL("create index if not exists in_wpts_geo on " + dbTableWaypoints + " (geocode)"); - db.execSQL("create index if not exists in_wpts_geo_type on " + dbTableWaypoints + " (geocode, type)"); - db.execSQL("create index if not exists in_spoil_geo on " + dbTableSpoilers + " (geocode)"); - db.execSQL("create index if not exists in_logs_geo on " + dbTableLogs + " (geocode)"); - db.execSQL("create index if not exists in_logcount_geo on " + dbTableLogCount + " (geocode)"); - db.execSQL("create index if not exists in_logsoff_geo on " + dbTableLogsOffline + " (geocode)"); - db.execSQL("create index if not exists in_trck_geo on " + dbTableTrackables + " (geocode)"); - } catch (Exception e) { - Log.e(cgSettings.tag, "Failed to upgrade to ver. 57: " + e.toString()); - } - } - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - Log.i(cgSettings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed"); - } - } - - private static void dropDatabase(SQLiteDatabase db) { - db.execSQL("drop table if exists " + dbTableCaches); - db.execSQL("drop table if exists " + dbTableAttributes); - db.execSQL("drop table if exists " + dbTableWaypoints); - db.execSQL("drop table if exists " + dbTableSpoilers); - db.execSQL("drop table if exists " + dbTableLogs); - db.execSQL("drop table if exists " + dbTableLogCount); - db.execSQL("drop table if exists " + dbTableLogsOffline); - db.execSQL("drop table if exists " + dbTableTrackables); - } - - public String[] allDetailedThere() { - init(); - - Cursor cursor = null; - List<String> list = new ArrayList<String>(); - - try { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - "(detailed = 1 and detailedupdate > " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + ") or reason > 0", - null, - null, - null, - "detailedupdate desc", - "100"); - - if (cursor != null) { - int index = 0; - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + init(); + + return restoreDone; + } + + private static class cgDbHelper extends SQLiteOpenHelper { + + cgDbHelper(Context context) { + super(context, dbName, null, dbVersion); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(dbCreateCaches); + db.execSQL(dbCreateLists); + db.execSQL(dbCreateAttributes); + db.execSQL(dbCreateWaypoints); + db.execSQL(dbCreateSpoilers); + db.execSQL(dbCreateLogs); + db.execSQL(dbCreateLogCount); + db.execSQL(dbCreateLogImages); + db.execSQL(dbCreateLogsOffline); + db.execSQL(dbCreateTrackables); + db.execSQL(dbCreateSearchDestinationHistory); + + db.execSQL("create index if not exists in_caches_geo on " + dbTableCaches + " (geocode)"); + db.execSQL("create index if not exists in_caches_guid on " + dbTableCaches + " (guid)"); + db.execSQL("create index if not exists in_caches_reason on " + dbTableCaches + " (reason)"); + db.execSQL("create index if not exists in_caches_detailed on " + dbTableCaches + " (detailed)"); + db.execSQL("create index if not exists in_caches_type on " + dbTableCaches + " (type)"); + db.execSQL("create index if not exists in_caches_visit_detail on " + dbTableCaches + " (visiteddate, detailedupdate)"); + db.execSQL("create index if not exists in_attr_geo on " + dbTableAttributes + " (geocode)"); + db.execSQL("create index if not exists in_wpts_geo on " + dbTableWaypoints + " (geocode)"); + db.execSQL("create index if not exists in_wpts_geo_type on " + dbTableWaypoints + " (geocode, type)"); + db.execSQL("create index if not exists in_spoil_geo on " + dbTableSpoilers + " (geocode)"); + db.execSQL("create index if not exists in_logs_geo on " + dbTableLogs + " (geocode)"); + db.execSQL("create index if not exists in_logcount_geo on " + dbTableLogCount + " (geocode)"); + db.execSQL("create index if not exists in_logsoff_geo on " + dbTableLogsOffline + " (geocode)"); + db.execSQL("create index if not exists in_trck_geo on " + dbTableTrackables + " (geocode)"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.i(cgSettings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": start"); + + try { + if (db.isReadOnly()) { + return; + } + + db.beginTransaction(); + + if (oldVersion <= 0) { // new table + dropDatabase(db); + onCreate(db); + + Log.i(cgSettings.tag, "Database structure created."); + } + + if (oldVersion > 0) { + db.execSQL("delete from " + dbTableCaches + " where reason = 0"); + + if (oldVersion < 34) { // upgrade to 34 + try { + db.execSQL("create index if not exists in_a on " + dbTableCaches + " (geocode)"); + db.execSQL("create index if not exists in_b on " + dbTableCaches + " (guid)"); + db.execSQL("create index if not exists in_c on " + dbTableCaches + " (reason)"); + db.execSQL("create index if not exists in_d on " + dbTableCaches + " (detailed)"); + db.execSQL("create index if not exists in_e on " + dbTableCaches + " (type)"); + db.execSQL("create index if not exists in_a on " + dbTableAttributes + " (geocode)"); + db.execSQL("create index if not exists in_a on " + dbTableWaypoints + " (geocode)"); + db.execSQL("create index if not exists in_b on " + dbTableWaypoints + " (geocode, type)"); + db.execSQL("create index if not exists in_a on " + dbTableSpoilers + " (geocode)"); + db.execSQL("create index if not exists in_a on " + dbTableLogs + " (geocode)"); + db.execSQL("create index if not exists in_a on " + dbTableTrackables + " (geocode)"); + + Log.i(cgSettings.tag, "Indexes added."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 34: " + e.toString()); + } + } + + if (oldVersion < 37) { // upgrade to 37 + try { + db.execSQL("alter table " + dbTableCaches + " add column direction text"); + db.execSQL("alter table " + dbTableCaches + " add column distance double"); + + Log.i(cgSettings.tag, "Columns direction and distance added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 37: " + e.toString()); + } + } + + if (oldVersion < 38) { // upgrade to 38 + try { + db.execSQL("drop table " + dbTableLogs); + db.execSQL(dbCreateLogs); + + Log.i(cgSettings.tag, "Changed type column in " + dbTableLogs + " to integer."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 38: " + e.toString()); + } + } + + if (oldVersion < 39) { // upgrade to 39 + try { + db.execSQL(dbCreateLists); + + Log.i(cgSettings.tag, "Created lists table."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 39: " + e.toString()); + } + } + + if (oldVersion < 40) { // upgrade to 40 + try { + db.execSQL("drop table " + dbTableTrackables); + db.execSQL(dbCreateTrackables); + + Log.i(cgSettings.tag, "Changed type of geocode column in trackables table."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 40: " + e.toString()); + } + } + + if (oldVersion < 41) { // upgrade to 41 + try { + db.execSQL("alter table " + dbTableCaches + " add column rating float"); + db.execSQL("alter table " + dbTableCaches + " add column votes integer"); + db.execSQL("alter table " + dbTableCaches + " add column vote integer"); + + Log.i(cgSettings.tag, "Added columns for GCvote."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 41: " + e.toString()); + } + } + + if (oldVersion < 42) { // upgrade to 42 + try { + db.execSQL(dbCreateLogsOffline); + + Log.i(cgSettings.tag, "Added table for offline logs"); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 42: " + e.toString()); + } + } + + if (oldVersion < 43) { // upgrade to 43 + try { + final String dbTableCachesTemp = dbTableCaches + "_temp"; + final String dbCreateCachesTemp = "" + + "create temporary table " + dbTableCachesTemp + " (" + + "_id integer primary key autoincrement, " + + "updated long not null, " + + "detailed integer not null default 0, " + + "detailedupdate long, " + + "geocode text unique not null, " + + "reason integer not null default 0, " // cached, favourite... + + "cacheid text, " + + "guid text, " + + "type text, " + + "name text, " + + "owner text, " + + "hidden long, " + + "hint text, " + + "size text, " + + "difficulty float, " + + "terrain float, " + + "latlon text, " + + "latitude_string text, " + + "longitude_string text, " + + "location text, " + + "distance double, " + + "latitude double, " + + "longitude double, " + + "shortdesc text, " + + "description text, " + + "rating float, " + + "votes integer, " + + "vote integer, " + + "disabled integer not null default 0, " + + "archived integer not null default 0, " + + "members integer not null default 0, " + + "found integer not null default 0, " + + "favourite integer not null default 0, " + + "inventorycoins integer default 0, " + + "inventorytags integer default 0, " + + "inventoryunknown integer default 0 " + + "); "; + final String dbCreateCachesNew = "" + + "create table " + dbTableCaches + " (" + + "_id integer primary key autoincrement, " + + "updated long not null, " + + "detailed integer not null default 0, " + + "detailedupdate long, " + + "geocode text unique not null, " + + "reason integer not null default 0, " // cached, favourite... + + "cacheid text, " + + "guid text, " + + "type text, " + + "name text, " + + "owner text, " + + "hidden long, " + + "hint text, " + + "size text, " + + "difficulty float, " + + "terrain float, " + + "latlon text, " + + "latitude_string text, " + + "longitude_string text, " + + "location text, " + + "direction double, " + + "distance double, " + + "latitude double, " + + "longitude double, " + + "shortdesc text, " + + "description text, " + + "rating float, " + + "votes integer, " + + "vote integer, " + + "disabled integer not null default 0, " + + "archived integer not null default 0, " + + "members integer not null default 0, " + + "found integer not null default 0, " + + "favourite integer not null default 0, " + + "inventorycoins integer default 0, " + + "inventorytags integer default 0, " + + "inventoryunknown integer default 0 " + + "); "; + + db.beginTransaction(); + db.execSQL(dbCreateCachesTemp); + db.execSQL("insert into " + dbTableCachesTemp + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCaches); + db.execSQL("drop table " + dbTableCaches); + db.execSQL(dbCreateCachesNew); + db.execSQL("insert into " + dbTableCaches + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, null, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCachesTemp); + db.execSQL("drop table " + dbTableCachesTemp); + db.setTransactionSuccessful(); + + Log.i(cgSettings.tag, "Changed direction column"); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 43: " + e.toString()); + } finally { + db.endTransaction(); + } + } + + if (oldVersion < 44) { // upgrade to 44 + try { + db.execSQL("alter table " + dbTableCaches + " add column favourite_cnt integer"); + + Log.i(cgSettings.tag, "Column favourite_cnt added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 44: " + e.toString()); + } + } + + if (oldVersion < 45) { // upgrade to 45 + try { + db.execSQL("alter table " + dbTableCaches + " add column owner_real text"); + + Log.i(cgSettings.tag, "Column owner_real added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 45: " + e.toString()); + } + } + + if (oldVersion < 46) { // upgrade to 46 + try { + db.execSQL("alter table " + dbTableCaches + " add column visiteddate long"); + db.execSQL("create index if not exists in_f on " + dbTableCaches + " (visiteddate, detailedupdate)"); + + Log.i(cgSettings.tag, "Added column for date of visit."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 46: " + e.toString()); + } + } + if (oldVersion < 47) { // upgrade to 47 + try { + db.execSQL("alter table " + dbTableCaches + " add column own integer not null default 0"); + + Log.i(cgSettings.tag, "Added column own."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 47: " + e.toString()); + } + } + + if (oldVersion < 48) { // upgrade to 48 + try { + db.execSQL("alter table " + dbTableCaches + " add column elevation double"); + + Log.i(cgSettings.tag, "Column elevation added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 48: " + e.toString()); + } + } + + if (oldVersion < 49) { // upgrade to 49 + try { + db.execSQL(dbCreateLogCount); + + Log.i(cgSettings.tag, "Created table " + dbTableLogCount + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 49: " + e.toString()); + } + } + + if (oldVersion < 50) { // upgrade to 50 + try { + db.execSQL("alter table " + dbTableCaches + " add column myvote float"); + + Log.i(cgSettings.tag, "Added float column for votes to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 50: " + e.toString()); + } + } + + if (oldVersion < 51) { // upgrade to 51 + try { + db.execSQL("alter table " + dbTableCaches + " add column reliable_latlon integer"); + + Log.i(cgSettings.tag, "Column reliable_latlon added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 51: " + e.toString()); + } + } + + if (oldVersion < 52) { // upgrade to 52 + try { + db.execSQL(dbCreateSearchDestinationHistory); + + Log.i(cgSettings.tag, "Added table " + dbTableSearchDestionationHistory + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 52", e); + } + } + + if (oldVersion < 53) { // upgrade to 53 + try { + db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer"); + + Log.i(cgSettings.tag, "Column onWatchlist added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 53", e); + } + } + + if (oldVersion < 54) { // update to 54 + try { + db.execSQL(dbCreateLogImages); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 54: " + e.toString()); + + } + } + + if (oldVersion < 55) { // update to 55 + try { + db.execSQL("alter table " + dbTableCaches + " add column personal_note text"); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 55: " + e.toString()); + + } + } + + // make all internal attribute names lowercase + // @see issue #299 + if (oldVersion < 56) { // update to 56 + try { + db.execSQL("update " + dbTableAttributes + " set attribute = " + + "lower(attribute) where attribute like \"%_yes\" " + + "or attribute like \"%_no\""); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 56: " + e.toString()); + } + } + + // Create missing indices. See issue #435 + if (oldVersion < 57) { // update to 57 + try { + db.execSQL("drop index in_a"); + db.execSQL("drop index in_b"); + db.execSQL("drop index in_c"); + db.execSQL("drop index in_d"); + db.execSQL("drop index in_e"); + db.execSQL("drop index in_f"); + db.execSQL("create index if not exists in_caches_geo on " + dbTableCaches + " (geocode)"); + db.execSQL("create index if not exists in_caches_guid on " + dbTableCaches + " (guid)"); + db.execSQL("create index if not exists in_caches_reason on " + dbTableCaches + " (reason)"); + db.execSQL("create index if not exists in_caches_detailed on " + dbTableCaches + " (detailed)"); + db.execSQL("create index if not exists in_caches_type on " + dbTableCaches + " (type)"); + db.execSQL("create index if not exists in_caches_visit_detail on " + dbTableCaches + " (visiteddate, detailedupdate)"); + db.execSQL("create index if not exists in_attr_geo on " + dbTableAttributes + " (geocode)"); + db.execSQL("create index if not exists in_wpts_geo on " + dbTableWaypoints + " (geocode)"); + db.execSQL("create index if not exists in_wpts_geo_type on " + dbTableWaypoints + " (geocode, type)"); + db.execSQL("create index if not exists in_spoil_geo on " + dbTableSpoilers + " (geocode)"); + db.execSQL("create index if not exists in_logs_geo on " + dbTableLogs + " (geocode)"); + db.execSQL("create index if not exists in_logcount_geo on " + dbTableLogCount + " (geocode)"); + db.execSQL("create index if not exists in_logsoff_geo on " + dbTableLogsOffline + " (geocode)"); + db.execSQL("create index if not exists in_trck_geo on " + dbTableTrackables + " (geocode)"); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 57: " + e.toString()); + } + } + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + Log.i(cgSettings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed"); + } + } + + private static void dropDatabase(SQLiteDatabase db) { + db.execSQL("drop table if exists " + dbTableCaches); + db.execSQL("drop table if exists " + dbTableAttributes); + db.execSQL("drop table if exists " + dbTableWaypoints); + db.execSQL("drop table if exists " + dbTableSpoilers); + db.execSQL("drop table if exists " + dbTableLogs); + db.execSQL("drop table if exists " + dbTableLogCount); + db.execSQL("drop table if exists " + dbTableLogsOffline); + db.execSQL("drop table if exists " + dbTableTrackables); + } + + public String[] allDetailedThere() { + init(); + + Cursor cursor = null; + List<String> list = new ArrayList<String>(); + + try { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + "(detailed = 1 and detailedupdate > " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + ") or reason > 0", + null, + null, + null, + "detailedupdate desc", + "100"); + + if (cursor != null) { + int index = 0; + + if (cursor.getCount() > 0) { + cursor.moveToFirst(); index = cursor.getColumnIndex("geocode"); - do { - list.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } else { - if (cursor != null) { - cursor.close(); - } - - return null; - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.allDetailedThere: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - return list.toArray(new String[list.size()]); - } - - public boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { - init(); - - Cursor cursor = null; - - int cnt = 0; - long dataUpdated = 0; - long dataDetailedUpdate = 0; - int dataDetailed = 0; - - try { - if (StringUtils.isNotBlank(geocode)) { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "detailed", "detailedupdate", "updated"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "1"); - } else if (StringUtils.isNotBlank(guid)) { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "detailed", "detailedupdate", "updated"}, - "guid = \"" + guid + "\"", - null, - null, - null, - null, - "1"); - } else { - return false; - } - - if (cursor != null) { - int index = 0; - cnt = cursor.getCount(); - - if (cnt > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("updated"); - dataUpdated = (long) cursor.getLong(index); - index = cursor.getColumnIndex("detailedupdate"); - dataDetailedUpdate = (long) cursor.getLong(index); - index = cursor.getColumnIndex("detailed"); - dataDetailed = (int) cursor.getInt(index); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.isThere: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - if (cnt > 0) { - if (detailed && dataDetailed == 0) { - // we want details, but these are not stored - return false; - } - - if (checkTime && detailed && dataDetailedUpdate < (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000))) { - // we want to check time for detailed cache, but data are older than 3 hours - return false; - } - - if (checkTime && detailed == false && dataUpdated < (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000))) { - // we want to check time for short cache, but data are older than 3 hours - return false; - } - - // we have some cache - return true; - } - - // we have no such cache stored in cache - return false; - } - - public boolean isOffline(String geocode, String guid) { - init(); - - Cursor cursor = null; - long reason = 0; - - try { - if (StringUtils.isNotBlank(geocode)) { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"reason"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "1"); - } else if (StringUtils.isNotBlank(guid)) { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"reason"}, - "guid = \"" + guid + "\"", - null, - null, - null, - null, - "1"); - } else { - return false; - } - - if (cursor != null) { - final int cnt = cursor.getCount(); - int index = 0; - - if (cnt > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("reason"); - reason = (long) cursor.getLong(index); - } - - cursor.close(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.isOffline: " + e.toString()); - } - - if (reason >= 1) { - return true; - } else { - return false; - } - } - - public String getGeocodeForGuid(String guid) { - if (StringUtils.isBlank(guid)) { - return null; - } - - init(); - - Cursor cursor = null; - String geocode = null; - - try { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - "guid = \"" + guid + "\"", - null, - null, - null, - null, - "1"); - - if (cursor != null) { - int index = 0; - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("geocode"); - geocode = (String) cursor.getString(index); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getGeocodeForGuid: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - return geocode; - } - - public String getCacheidForGeocode(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - Cursor cursor = null; - String cacheid = null; - - try { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "cacheid"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "1"); - - if (cursor != null) { - int index = 0; - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("cacheid"); - cacheid = (String) cursor.getString(index); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getCacheidForGeocode: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - return cacheid; - } - - public boolean saveCache(cgCache cache) { - //LeeB - writing to the DB is slow - if (cache == null) { - return false; - } - - ContentValues values = new ContentValues(); - - if (cache.updated == null) { - values.put("updated", System.currentTimeMillis()); - } else { - values.put("updated", cache.updated); - } - values.put("reason", cache.reason); - values.put("detailed", cache.detailed ? 1 : 0); - values.put("detailedupdate", cache.detailedUpdate); - values.put("visiteddate", cache.visitedDate); - values.put("geocode", cache.geocode); - values.put("cacheid", cache.cacheId); - values.put("guid", cache.guid); - values.put("type", cache.type); - values.put("name", cache.name); - values.put("own", cache.own ? 1 : 0); - values.put("owner", cache.owner); - values.put("owner_real", cache.ownerReal); - if (cache.hidden == null) { - values.put("hidden", 0); - } else { - values.put("hidden", cache.hidden.getTime()); - } - values.put("hint", cache.hint); - values.put("size", cache.size); - values.put("difficulty", cache.difficulty); - values.put("terrain", cache.terrain); - values.put("latlon", cache.latlon); - values.put("latitude_string", cache.latitudeString); - values.put("longitude_string", cache.longitudeString); - values.put("location", cache.location); - values.put("distance", cache.distance); - values.put("direction", cache.direction); - putCoords(values, cache.coords); - values.put("reliable_latlon", cache.reliableLatLon ? 1 : 0); - values.put("elevation", cache.elevation); - values.put("shortdesc", cache.shortdesc); - values.put("personal_note", cache.personalNote); - values.put("description", cache.description); - values.put("favourite_cnt", cache.favouriteCnt); - values.put("rating", cache.rating); - values.put("votes", cache.votes); - values.put("myvote", cache.myVote); - values.put("disabled", cache.disabled ? 1 : 0); - values.put("archived", cache.archived ? 1 : 0); - values.put("members", cache.members ? 1 : 0); - values.put("found", cache.found ? 1 : 0); - values.put("favourite", cache.favourite ? 1 : 0); - values.put("inventoryunknown", cache.inventoryItems); - values.put("onWatchlist", cache.onWatchlist ? 1 : 0); - - boolean statusOk = true; - - if (cache.attributes != null) { - if (!saveAttributes(cache.geocode, cache.attributes)) { - statusOk = false; - } - } - - if (cache.waypoints != null) { - if (!saveWaypoints(cache.geocode, cache.waypoints, true)) { - statusOk = false; - } - } - - if (cache.spoilers != null) { - if (!saveSpoilers(cache.geocode, cache.spoilers)) { - statusOk = false; - } - } - - if (cache.logs != null) { - if (!saveLogs(cache.geocode, cache.logs)) { - statusOk = false; - } - } - - if (cache.logCounts != null && cache.logCounts.isEmpty() == false) { - if (!saveLogCount(cache.geocode, cache.logCounts)) { - statusOk = false; - } - } - - if (cache.inventory != null) { - if (!saveInventory(cache.geocode, cache.inventory)) { - statusOk = false; - } - } - - if (statusOk == false) { - cache.detailed = false; - cache.detailedUpdate = 0L; - } - - init(); - - //try to update record else insert fresh.. - try { - int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {cache.geocode}); - if (rows > 0) { - values = null; - return true; - } - } catch (Exception e) { - // nothing - } - - try { - long id = databaseRW.insert(dbTableCaches, null, values); - if (id > 0) { - values = null; - return true; - } - } catch (Exception e) { - // nothing - } - - values = null; - - return false; - } - - public boolean saveAttributes(String geocode, List<String> attributes) { - init(); - - if (StringUtils.isBlank(geocode) || attributes == null) { - return false; - } - - databaseRW.beginTransaction(); - try { - databaseRW.delete(dbTableAttributes, "geocode = ?", new String[] {geocode}); - - if (!attributes.isEmpty()) { - - InsertHelper helper = new InsertHelper(databaseRW, dbTableAttributes); - long timeStamp = System.currentTimeMillis(); - - for (String attribute : attributes) { - helper.prepareForInsert(); - - helper.bind(ATTRIBUTES_GEOCODE, geocode); - helper.bind(ATTRIBUTES_UPDATED, timeStamp); - helper.bind(ATTRIBUTES_ATTRIBUTE, attribute); - - helper.execute(); - } - helper.close(); - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return true; - } - - /** - * Persists the given <code>destination</code> into the database. - * - * @param destinations - * @return <code>true</code> if the given destination was successfully - * persisted <code>false</code> otherwise. - */ - public boolean saveSearchedDestination(cgDestination destination) { - boolean success = true; - - if (destination == null) { - success = false; - } else { - init(); - - databaseRW.beginTransaction(); - - try { - ContentValues values = new ContentValues(); - values.put("date", destination.getDate()); - putCoords(values, destination.getCoords()); - - long id = databaseRW.insert(dbTableSearchDestionationHistory, null, values); - destination.setId(id); - databaseRW.setTransactionSuccessful(); - } catch (Exception e) { - success = false; - Log.e(cgSettings.tag, "Updating searchedDestinations db failed", e); - } finally { - databaseRW.endTransaction(); - } - } - - return success; - } - - public boolean saveWaypoints(String geocode,List <cgWaypoint> waypoints, boolean drop) { - init(); - - if (StringUtils.isBlank(geocode) || waypoints == null) { - return false; - } - - boolean ok = false; - databaseRW.beginTransaction(); - try { - if (drop) { - databaseRW.delete(dbTableWaypoints, "geocode = ? and type <> ?", new String[] {geocode, "own"}); - } - - if (!waypoints.isEmpty()) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (cgWaypoint oneWaypoint : waypoints) { - if (oneWaypoint.isUserDefined()) { - continue; - } - - values.clear(); - values.put("geocode", geocode); - values.put("updated", timeStamp); - values.put("type", oneWaypoint.type); - values.put("prefix", oneWaypoint.prefix); - values.put("lookup", oneWaypoint.lookup); - values.put("name", oneWaypoint.name); - values.put("latlon", oneWaypoint.latlon); - values.put("latitude_string", oneWaypoint.latitudeString); - values.put("longitude_string", oneWaypoint.longitudeString); - putCoords(values, oneWaypoint.coords); - values.put("note", oneWaypoint.note); - - databaseRW.insert(dbTableWaypoints, null, values); - } - } - - databaseRW.setTransactionSuccessful(); - ok = true; - } finally { - databaseRW.endTransaction(); - } - - return ok; - } + do { + list.add((String) cursor.getString(index)); + } while (cursor.moveToNext()); + } else { + if (cursor != null) { + cursor.close(); + } + + return null; + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.allDetailedThere: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + return list.toArray(new String[list.size()]); + } + + public boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { + init(); + + Cursor cursor = null; + + int cnt = 0; + long dataUpdated = 0; + long dataDetailedUpdate = 0; + int dataDetailed = 0; + + try { + if (StringUtils.isNotBlank(geocode)) { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "detailed", "detailedupdate", "updated" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "1"); + } else if (StringUtils.isNotBlank(guid)) { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "detailed", "detailedupdate", "updated" }, + "guid = \"" + guid + "\"", + null, + null, + null, + null, + "1"); + } else { + return false; + } + + if (cursor != null) { + int index = 0; + cnt = cursor.getCount(); + + if (cnt > 0) { + cursor.moveToFirst(); + + index = cursor.getColumnIndex("updated"); + dataUpdated = (long) cursor.getLong(index); + index = cursor.getColumnIndex("detailedupdate"); + dataDetailedUpdate = (long) cursor.getLong(index); + index = cursor.getColumnIndex("detailed"); + dataDetailed = (int) cursor.getInt(index); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.isThere: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + if (cnt > 0) { + if (detailed && dataDetailed == 0) { + // we want details, but these are not stored + return false; + } + + if (checkTime && detailed && dataDetailedUpdate < (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000))) { + // we want to check time for detailed cache, but data are older than 3 hours + return false; + } + + if (checkTime && detailed == false && dataUpdated < (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000))) { + // we want to check time for short cache, but data are older than 3 hours + return false; + } + + // we have some cache + return true; + } + + // we have no such cache stored in cache + return false; + } + + public boolean isOffline(String geocode, String guid) { + init(); + + Cursor cursor = null; + long reason = 0; + + try { + if (StringUtils.isNotBlank(geocode)) { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "reason" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "1"); + } else if (StringUtils.isNotBlank(guid)) { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "reason" }, + "guid = \"" + guid + "\"", + null, + null, + null, + null, + "1"); + } else { + return false; + } + + if (cursor != null) { + final int cnt = cursor.getCount(); + int index = 0; + + if (cnt > 0) { + cursor.moveToFirst(); + + index = cursor.getColumnIndex("reason"); + reason = (long) cursor.getLong(index); + } + + cursor.close(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.isOffline: " + e.toString()); + } + + if (reason >= 1) { + return true; + } else { + return false; + } + } + + public String getGeocodeForGuid(String guid) { + if (StringUtils.isBlank(guid)) { + return null; + } + + init(); + + Cursor cursor = null; + String geocode = null; + + try { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + "guid = \"" + guid + "\"", + null, + null, + null, + null, + "1"); + + if (cursor != null) { + int index = 0; + + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + + index = cursor.getColumnIndex("geocode"); + geocode = (String) cursor.getString(index); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getGeocodeForGuid: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + return geocode; + } + + public String getCacheidForGeocode(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + Cursor cursor = null; + String cacheid = null; + + try { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "cacheid" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "1"); + + if (cursor != null) { + int index = 0; + + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + + index = cursor.getColumnIndex("cacheid"); + cacheid = (String) cursor.getString(index); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getCacheidForGeocode: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + return cacheid; + } + + public boolean saveCache(cgCache cache) { + //LeeB - writing to the DB is slow + if (cache == null) { + return false; + } + + ContentValues values = new ContentValues(); + + if (cache.updated == null) { + values.put("updated", System.currentTimeMillis()); + } else { + values.put("updated", cache.updated); + } + values.put("reason", cache.reason); + values.put("detailed", cache.detailed ? 1 : 0); + values.put("detailedupdate", cache.detailedUpdate); + values.put("visiteddate", cache.visitedDate); + values.put("geocode", cache.geocode); + values.put("cacheid", cache.cacheId); + values.put("guid", cache.guid); + values.put("type", cache.type); + values.put("name", cache.name); + values.put("own", cache.own ? 1 : 0); + values.put("owner", cache.owner); + values.put("owner_real", cache.ownerReal); + if (cache.hidden == null) { + values.put("hidden", 0); + } else { + values.put("hidden", cache.hidden.getTime()); + } + values.put("hint", cache.hint); + values.put("size", cache.size); + values.put("difficulty", cache.difficulty); + values.put("terrain", cache.terrain); + values.put("latlon", cache.latlon); + values.put("latitude_string", cache.latitudeString); + values.put("longitude_string", cache.longitudeString); + values.put("location", cache.location); + values.put("distance", cache.distance); + values.put("direction", cache.direction); + putCoords(values, cache.coords); + values.put("reliable_latlon", cache.reliableLatLon ? 1 : 0); + values.put("elevation", cache.elevation); + values.put("shortdesc", cache.shortdesc); + values.put("personal_note", cache.personalNote); + values.put("description", cache.description); + values.put("favourite_cnt", cache.favouriteCnt); + values.put("rating", cache.rating); + values.put("votes", cache.votes); + values.put("myvote", cache.myVote); + values.put("disabled", cache.disabled ? 1 : 0); + values.put("archived", cache.archived ? 1 : 0); + values.put("members", cache.members ? 1 : 0); + values.put("found", cache.found ? 1 : 0); + values.put("favourite", cache.favourite ? 1 : 0); + values.put("inventoryunknown", cache.inventoryItems); + values.put("onWatchlist", cache.onWatchlist ? 1 : 0); + + boolean statusOk = true; + + if (cache.attributes != null) { + if (!saveAttributes(cache.geocode, cache.attributes)) { + statusOk = false; + } + } + + if (cache.waypoints != null) { + if (!saveWaypoints(cache.geocode, cache.waypoints, true)) { + statusOk = false; + } + } + + if (cache.spoilers != null) { + if (!saveSpoilers(cache.geocode, cache.spoilers)) { + statusOk = false; + } + } + + if (cache.logs != null) { + if (!saveLogs(cache.geocode, cache.logs)) { + statusOk = false; + } + } + + if (cache.logCounts != null && cache.logCounts.isEmpty() == false) { + if (!saveLogCount(cache.geocode, cache.logCounts)) { + statusOk = false; + } + } + + if (cache.inventory != null) { + if (!saveInventory(cache.geocode, cache.inventory)) { + statusOk = false; + } + } + + if (statusOk == false) { + cache.detailed = false; + cache.detailedUpdate = 0L; + } + + init(); + + //try to update record else insert fresh.. + try { + int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { cache.geocode }); + if (rows > 0) { + values = null; + return true; + } + } catch (Exception e) { + // nothing + } + + try { + long id = databaseRW.insert(dbTableCaches, null, values); + if (id > 0) { + values = null; + return true; + } + } catch (Exception e) { + // nothing + } + + values = null; + + return false; + } + + public boolean saveAttributes(String geocode, List<String> attributes) { + init(); + + if (StringUtils.isBlank(geocode) || attributes == null) { + return false; + } + + databaseRW.beginTransaction(); + try { + databaseRW.delete(dbTableAttributes, "geocode = ?", new String[] { geocode }); + + if (!attributes.isEmpty()) { + + InsertHelper helper = new InsertHelper(databaseRW, dbTableAttributes); + long timeStamp = System.currentTimeMillis(); + + for (String attribute : attributes) { + helper.prepareForInsert(); + + helper.bind(ATTRIBUTES_GEOCODE, geocode); + helper.bind(ATTRIBUTES_UPDATED, timeStamp); + helper.bind(ATTRIBUTES_ATTRIBUTE, attribute); + + helper.execute(); + } + helper.close(); + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return true; + } + + /** + * Persists the given <code>destination</code> into the database. + * + * @param destinations + * @return <code>true</code> if the given destination was successfully + * persisted <code>false</code> otherwise. + */ + public boolean saveSearchedDestination(cgDestination destination) { + boolean success = true; + + if (destination == null) { + success = false; + } else { + init(); + + databaseRW.beginTransaction(); + + try { + ContentValues values = new ContentValues(); + values.put("date", destination.getDate()); + putCoords(values, destination.getCoords()); + + long id = databaseRW.insert(dbTableSearchDestionationHistory, null, values); + destination.setId(id); + databaseRW.setTransactionSuccessful(); + } catch (Exception e) { + success = false; + Log.e(cgSettings.tag, "Updating searchedDestinations db failed", e); + } finally { + databaseRW.endTransaction(); + } + } + + return success; + } + + public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) { + init(); + + if (StringUtils.isBlank(geocode) || waypoints == null) { + return false; + } + + boolean ok = false; + databaseRW.beginTransaction(); + try { + if (drop) { + databaseRW.delete(dbTableWaypoints, "geocode = ? and type <> ?", new String[] { geocode, "own" }); + } + + if (!waypoints.isEmpty()) { + ContentValues values = new ContentValues(); + long timeStamp = System.currentTimeMillis(); + for (cgWaypoint oneWaypoint : waypoints) { + if (oneWaypoint.isUserDefined()) { + continue; + } + + values.clear(); + values.put("geocode", geocode); + values.put("updated", timeStamp); + values.put("type", oneWaypoint.type); + values.put("prefix", oneWaypoint.prefix); + values.put("lookup", oneWaypoint.lookup); + values.put("name", oneWaypoint.name); + values.put("latlon", oneWaypoint.latlon); + values.put("latitude_string", oneWaypoint.latitudeString); + values.put("longitude_string", oneWaypoint.longitudeString); + putCoords(values, oneWaypoint.coords); + values.put("note", oneWaypoint.note); + + databaseRW.insert(dbTableWaypoints, null, values); + } + } + + databaseRW.setTransactionSuccessful(); + ok = true; + } finally { + databaseRW.endTransaction(); + } + + return ok; + } /** * Save coordinates into a ContentValues - * - * @param values a ContentValues to save coordinates in - * @param oneWaypoint coordinates to save, or null to save empty coordinates + * + * @param values + * a ContentValues to save coordinates in + * @param oneWaypoint + * coordinates to save, or null to save empty coordinates */ private static void putCoords(final ContentValues values, final Geopoint coords) { values.put("latitude", coords == null ? null : coords.getLatitude()); @@ -1400,8 +1403,9 @@ public class cgData { /** * Retrieve coordinates from a Cursor - * - * @param cursor a Cursor representing a row in the database + * + * @param cursor + * a Cursor representing a row in the database * @return the coordinates, or null if latitude or longitude is null */ private static Geopoint getCoords(final Cursor cursor) { @@ -1414,857 +1418,859 @@ public class cgData { } } - public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { - init(); - - if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { - return false; - } - - boolean ok = false; - databaseRW.beginTransaction(); - try { - ContentValues values = new ContentValues(); - values.put("geocode", geocode); - values.put("updated", System.currentTimeMillis()); - values.put("type", waypoint.type); - values.put("prefix", waypoint.prefix); - values.put("lookup", waypoint.lookup); - values.put("name", waypoint.name); - values.put("latlon", waypoint.latlon); - values.put("latitude_string", waypoint.latitudeString); - values.put("longitude_string", waypoint.longitudeString); - putCoords(values, waypoint.coords); - values.put("note", waypoint.note); - - if (id <= 0) { - databaseRW.insert(dbTableWaypoints, null, values); - ok = true; - } else { - final int rows = databaseRW.update(dbTableWaypoints, values, "_id = " + id, null); - if (rows > 0) { - ok = true; - } else { - ok = false; - } - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return ok; - } - - public boolean deleteWaypoint(int id) { - init(); - - if (id == 0) { - return false; - } - - int deleted = databaseRW.delete(dbTableWaypoints, "_id = " + id, null); - - if (deleted > 0) { - return true; - } - - return false; - } - - public boolean saveSpoilers(String geocode, List<cgImage> spoilers) { - init(); - - if (StringUtils.isBlank(geocode) || spoilers == null) { - return false; - } - - databaseRW.beginTransaction(); - try { - databaseRW.delete(dbTableSpoilers, "geocode = ?", new String[] {geocode}); - - if (!spoilers.isEmpty()) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (cgImage oneSpoiler : spoilers) { - values.clear(); - values.put("geocode", geocode); - values.put("updated", timeStamp); - values.put("url", oneSpoiler.url); - values.put("title", oneSpoiler.title); - values.put("description", oneSpoiler.description); - - databaseRW.insert(dbTableSpoilers, null, values); - } - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return true; - } - - public boolean saveLogs(String geocode, List<cgLog> logs) { - return saveLogs(geocode, logs, true); - } - - public boolean saveLogs(String geocode, List<cgLog> logs, boolean drop) { - init(); - - if (StringUtils.isBlank(geocode) || logs == null) { - return false; - } - - databaseRW.beginTransaction(); - try { - if (drop) { - // TODO delete logimages referring these logs - databaseRW.delete(dbTableLogs, "geocode = ?", new String[] {geocode}); - } - - if (!logs.isEmpty()) { - InsertHelper helper = new InsertHelper(databaseRW, dbTableLogs); - long timeStamp = System.currentTimeMillis(); - for (cgLog log : logs) { - helper.prepareForInsert(); - - helper.bind(LOGS_GEOCODE, geocode); - helper.bind(LOGS_UPDATED, timeStamp); - helper.bind(LOGS_TYPE, log.type); - helper.bind(LOGS_AUTHOR, log.author); - helper.bind(LOGS_LOG, log.log); - helper.bind(LOGS_DATE, log.date); - helper.bind(LOGS_FOUND, log.found); - - long log_id = helper.execute(); - - if (CollectionUtils.isNotEmpty(log.logImages)) { - ContentValues values = new ContentValues(); - for (cgImage img : log.logImages) { - values.clear(); - values.put("log_id", log_id); - values.put("title", img.title); - values.put("url", img.url); - databaseRW.insert(dbTableLogImages, null, values); - } - } - } - helper.close(); - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return true; - } - - public boolean saveLogCount(String geocode, Map<Integer, Integer> logCounts) { - return saveLogCount(geocode, logCounts, true); - } - - public boolean saveLogCount(String geocode, Map<Integer, Integer> logCounts, boolean drop) { - init(); - - if (StringUtils.isBlank(geocode) || CollectionUtils.isEmpty(logCounts)) { - return false; - } - - databaseRW.beginTransaction(); - try { - if (drop) { - databaseRW.delete(dbTableLogCount, "geocode = ?", new String[] {geocode}); - } - - ContentValues values = new ContentValues(); - - Set<Entry<Integer, Integer>> logCountsItems = logCounts.entrySet(); - long timeStamp = System.currentTimeMillis(); - for (Entry<Integer, Integer> pair : logCountsItems) { - values.clear(); - values.put("geocode", geocode); - values.put("updated", timeStamp); - values.put("type", pair.getKey().intValue()); - values.put("count", pair.getValue().intValue()); - - databaseRW.insert(dbTableLogCount, null, values); - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return true; - } - - public boolean saveInventory(String geocode, List<cgTrackable> trackables) { - init(); - - if (trackables == null) { - return false; - } - - databaseRW.beginTransaction(); - try { - if (geocode != null) { - databaseRW.delete(dbTableTrackables, "geocode = ?", new String[] {geocode}); - } - - if (!trackables.isEmpty()) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (cgTrackable oneTrackable : trackables) { - values.clear(); - if (geocode != null) { - values.put("geocode", geocode); - } - values.put("updated", timeStamp); - values.put("tbcode", oneTrackable.geocode); - values.put("guid", oneTrackable.guid); - values.put("title", oneTrackable.name); - values.put("owner", oneTrackable.owner); - if (oneTrackable.released != null) { - values.put("released", oneTrackable.released.getTime()); - } else { - values.put("released", 0L); - } - values.put("goal", oneTrackable.goal); - values.put("description", oneTrackable.details); - - databaseRW.insert(dbTableTrackables, null, values); - - saveLogs(oneTrackable.geocode, oneTrackable.logs); - } - } - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return true; - } - - public List<Object> getBounds(Object[] geocodes) { - init(); - - Cursor cursor = null; - - final List<Object> viewport = new ArrayList<Object>(); - - try { - final StringBuilder where = new StringBuilder(); - - if (geocodes != null && geocodes.length > 0) { - StringBuilder all = new StringBuilder(); - for (Object one : geocodes) { - if (all.length() > 0) { - all.append(", "); - } - all.append('"'); - all.append((String) one); - all.append('"'); - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("geocode in ("); - where.append(all); - where.append(')'); - } - - cursor = databaseRO.query( - dbTableCaches, - new String[]{"count(_id) as cnt", "min(latitude) as latMin", "max(latitude) as latMax", "min(longitude) as lonMin", "max(longitude) as lonMax"}, - where.toString(), - null, - null, - null, - null, - null); - - if (cursor != null) { - int cnt = cursor.getCount(); - - if (cnt > 0) { - cursor.moveToFirst(); - - viewport.add((Integer) cursor.getInt(cursor.getColumnIndex("cnt"))); - viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("latMin"))); - viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("latMax"))); - viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("lonMin"))); - viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("lonMax"))); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getBounds: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - return viewport; - } - - public cgCache loadCache(String geocode, String guid) { - return loadCache(geocode, guid, false, true, false, false, false, false); - } - - /** - * Loads a single Cache. - * @param geocode The Geocode GCXXXX - * @param guid - * @param loadA - * @param loadW - * @param loadS - * @param loadL - * @param loadI - * @param loadO - * @return the loaded cache - */ - - public cgCache loadCache(String geocode, String guid, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { - Object[] geocodes = new Object[1]; - Object[] guids = new Object[1]; - - if (StringUtils.isNotBlank(geocode)) { - geocodes[0] = geocode; - } else { - geocodes = null; - } - - if (StringUtils.isNotBlank(guid)) { - guids[0] = guid; - } else { - guids = null; - } - - List<cgCache> caches = loadCaches(geocodes, null, null, null, null, null, loadA, loadW, loadS, loadL, loadI, loadO); - if (caches != null && caches.isEmpty() == false) { - return caches.get(0); - } - - return null; - } - - public List<cgCache> loadCaches(Object[] geocodes, Object[] guids) { - return loadCaches(geocodes, guids, null, null, null, null, false, true, false, false, false, false); - } - - public List<cgCache> loadCaches(Object[] geocodes, Object[] guids, boolean lite) { - if (lite) { - return loadCaches(geocodes, guids, null, null, null, null, false, true, false, false, false, false); - } else { - return loadCaches(geocodes, guids, null, null, null, null, true, true, true, true, true, true); - } - } - - public List<cgCache> loadCaches(Object[] geocodes, Object[] guids, Long centerLat, Long centerLon, Long spanLat, Long spanLon, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { - init(); -// Using more than one of the parametersets results in overly comlex wheres - if (((geocodes != null && geocodes.length > 0) && (guids != null && guids.length > 0))) { - throw new IllegalArgumentException("Please use only one parameter"); - } - if (((geocodes != null && geocodes.length > 0) || (guids != null && guids.length > 0)) - && centerLat != null - && centerLon != null - && spanLat != null - && spanLon != null) { - throw new IllegalArgumentException("Please use only one parameter"); - } - StringBuilder where = new StringBuilder(); - Cursor cursor = null; - List<cgCache> caches = new ArrayList<cgCache>(); - - try { - if (geocodes != null && geocodes.length > 0) { - StringBuilder all = new StringBuilder(); - for (Object one : geocodes) { - if (all.length() > 0) { - all.append(", "); - } - all.append('"'); - all.append((String) one); - all.append('"'); - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("geocode in ("); - where.append(all); - where.append(')'); - } else if (guids != null && guids.length > 0) { - StringBuilder all = new StringBuilder(); - for (Object one : guids) { - if (all.length() > 0) { - all.append(", "); - } - all.append('"'); - all.append((String) one); - all.append('"'); - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("guid in ("); - where.append(all); - where.append(')'); - } else { - return caches; - } - - // viewport limitation - if (centerLat != null && centerLon != null && spanLat != null && spanLon != null) { - double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); - double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); - double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); - double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); - double llCache; - - if (latMin > latMax) { - llCache = latMax; - latMax = latMin; - latMin = llCache; - } - if (lonMin > lonMax) { - llCache = lonMax; - lonMax = lonMin; - lonMin = llCache; - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("(latitude >= "); - where.append(String.format((Locale) null, "%.6f", latMin)); - where.append(" and latitude <= "); - where.append(String.format((Locale) null, "%.6f", latMax)); - where.append(" and longitude >= "); - where.append(String.format((Locale) null, "%.6f", lonMin)); - where.append(" and longitude <= "); - where.append(String.format((Locale) null, "%.6f", lonMax)); - where.append(')'); - } - cursor = databaseRO.query( - dbTableCaches, - CACHE_COLUMNS, - where.toString(), - null, - null, - null, - null, - null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - - do { - //Extracted Method - cgCache cache = createCacheFromDatabaseContent(cursor); - - if (loadA) { - List<String> attributes = loadAttributes(cache.geocode); - if (attributes != null && attributes.isEmpty() == false) { - if (cache.attributes == null) { + public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { + init(); + + if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { + return false; + } + + boolean ok = false; + databaseRW.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put("geocode", geocode); + values.put("updated", System.currentTimeMillis()); + values.put("type", waypoint.type); + values.put("prefix", waypoint.prefix); + values.put("lookup", waypoint.lookup); + values.put("name", waypoint.name); + values.put("latlon", waypoint.latlon); + values.put("latitude_string", waypoint.latitudeString); + values.put("longitude_string", waypoint.longitudeString); + putCoords(values, waypoint.coords); + values.put("note", waypoint.note); + + if (id <= 0) { + databaseRW.insert(dbTableWaypoints, null, values); + ok = true; + } else { + final int rows = databaseRW.update(dbTableWaypoints, values, "_id = " + id, null); + if (rows > 0) { + ok = true; + } else { + ok = false; + } + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return ok; + } + + public boolean deleteWaypoint(int id) { + init(); + + if (id == 0) { + return false; + } + + int deleted = databaseRW.delete(dbTableWaypoints, "_id = " + id, null); + + if (deleted > 0) { + return true; + } + + return false; + } + + public boolean saveSpoilers(String geocode, List<cgImage> spoilers) { + init(); + + if (StringUtils.isBlank(geocode) || spoilers == null) { + return false; + } + + databaseRW.beginTransaction(); + try { + databaseRW.delete(dbTableSpoilers, "geocode = ?", new String[] { geocode }); + + if (!spoilers.isEmpty()) { + ContentValues values = new ContentValues(); + long timeStamp = System.currentTimeMillis(); + for (cgImage oneSpoiler : spoilers) { + values.clear(); + values.put("geocode", geocode); + values.put("updated", timeStamp); + values.put("url", oneSpoiler.url); + values.put("title", oneSpoiler.title); + values.put("description", oneSpoiler.description); + + databaseRW.insert(dbTableSpoilers, null, values); + } + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return true; + } + + public boolean saveLogs(String geocode, List<cgLog> logs) { + return saveLogs(geocode, logs, true); + } + + public boolean saveLogs(String geocode, List<cgLog> logs, boolean drop) { + init(); + + if (StringUtils.isBlank(geocode) || logs == null) { + return false; + } + + databaseRW.beginTransaction(); + try { + if (drop) { + // TODO delete logimages referring these logs + databaseRW.delete(dbTableLogs, "geocode = ?", new String[] { geocode }); + } + + if (!logs.isEmpty()) { + InsertHelper helper = new InsertHelper(databaseRW, dbTableLogs); + long timeStamp = System.currentTimeMillis(); + for (cgLog log : logs) { + helper.prepareForInsert(); + + helper.bind(LOGS_GEOCODE, geocode); + helper.bind(LOGS_UPDATED, timeStamp); + helper.bind(LOGS_TYPE, log.type); + helper.bind(LOGS_AUTHOR, log.author); + helper.bind(LOGS_LOG, log.log); + helper.bind(LOGS_DATE, log.date); + helper.bind(LOGS_FOUND, log.found); + + long log_id = helper.execute(); + + if (CollectionUtils.isNotEmpty(log.logImages)) { + ContentValues values = new ContentValues(); + for (cgImage img : log.logImages) { + values.clear(); + values.put("log_id", log_id); + values.put("title", img.title); + values.put("url", img.url); + databaseRW.insert(dbTableLogImages, null, values); + } + } + } + helper.close(); + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return true; + } + + public boolean saveLogCount(String geocode, Map<Integer, Integer> logCounts) { + return saveLogCount(geocode, logCounts, true); + } + + public boolean saveLogCount(String geocode, Map<Integer, Integer> logCounts, boolean drop) { + init(); + + if (StringUtils.isBlank(geocode) || CollectionUtils.isEmpty(logCounts)) { + return false; + } + + databaseRW.beginTransaction(); + try { + if (drop) { + databaseRW.delete(dbTableLogCount, "geocode = ?", new String[] { geocode }); + } + + ContentValues values = new ContentValues(); + + Set<Entry<Integer, Integer>> logCountsItems = logCounts.entrySet(); + long timeStamp = System.currentTimeMillis(); + for (Entry<Integer, Integer> pair : logCountsItems) { + values.clear(); + values.put("geocode", geocode); + values.put("updated", timeStamp); + values.put("type", pair.getKey().intValue()); + values.put("count", pair.getValue().intValue()); + + databaseRW.insert(dbTableLogCount, null, values); + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return true; + } + + public boolean saveInventory(String geocode, List<cgTrackable> trackables) { + init(); + + if (trackables == null) { + return false; + } + + databaseRW.beginTransaction(); + try { + if (geocode != null) { + databaseRW.delete(dbTableTrackables, "geocode = ?", new String[] { geocode }); + } + + if (!trackables.isEmpty()) { + ContentValues values = new ContentValues(); + long timeStamp = System.currentTimeMillis(); + for (cgTrackable oneTrackable : trackables) { + values.clear(); + if (geocode != null) { + values.put("geocode", geocode); + } + values.put("updated", timeStamp); + values.put("tbcode", oneTrackable.geocode); + values.put("guid", oneTrackable.guid); + values.put("title", oneTrackable.name); + values.put("owner", oneTrackable.owner); + if (oneTrackable.released != null) { + values.put("released", oneTrackable.released.getTime()); + } else { + values.put("released", 0L); + } + values.put("goal", oneTrackable.goal); + values.put("description", oneTrackable.details); + + databaseRW.insert(dbTableTrackables, null, values); + + saveLogs(oneTrackable.geocode, oneTrackable.logs); + } + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return true; + } + + public List<Object> getBounds(Object[] geocodes) { + init(); + + Cursor cursor = null; + + final List<Object> viewport = new ArrayList<Object>(); + + try { + final StringBuilder where = new StringBuilder(); + + if (geocodes != null && geocodes.length > 0) { + StringBuilder all = new StringBuilder(); + for (Object one : geocodes) { + if (all.length() > 0) { + all.append(", "); + } + all.append('"'); + all.append((String) one); + all.append('"'); + } + + if (where.length() > 0) { + where.append(" and "); + } + where.append("geocode in ("); + where.append(all); + where.append(')'); + } + + cursor = databaseRO.query( + dbTableCaches, + new String[] { "count(_id) as cnt", "min(latitude) as latMin", "max(latitude) as latMax", "min(longitude) as lonMin", "max(longitude) as lonMax" }, + where.toString(), + null, + null, + null, + null, + null); + + if (cursor != null) { + int cnt = cursor.getCount(); + + if (cnt > 0) { + cursor.moveToFirst(); + + viewport.add((Integer) cursor.getInt(cursor.getColumnIndex("cnt"))); + viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("latMin"))); + viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("latMax"))); + viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("lonMin"))); + viewport.add((Double) cursor.getDouble(cursor.getColumnIndex("lonMax"))); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getBounds: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + return viewport; + } + + public cgCache loadCache(String geocode, String guid) { + return loadCache(geocode, guid, false, true, false, false, false, false); + } + + /** + * Loads a single Cache. + * + * @param geocode + * The Geocode GCXXXX + * @param guid + * @param loadA + * @param loadW + * @param loadS + * @param loadL + * @param loadI + * @param loadO + * @return the loaded cache + */ + + public cgCache loadCache(String geocode, String guid, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { + Object[] geocodes = new Object[1]; + Object[] guids = new Object[1]; + + if (StringUtils.isNotBlank(geocode)) { + geocodes[0] = geocode; + } else { + geocodes = null; + } + + if (StringUtils.isNotBlank(guid)) { + guids[0] = guid; + } else { + guids = null; + } + + List<cgCache> caches = loadCaches(geocodes, null, null, null, null, null, loadA, loadW, loadS, loadL, loadI, loadO); + if (caches != null && caches.isEmpty() == false) { + return caches.get(0); + } + + return null; + } + + public List<cgCache> loadCaches(Object[] geocodes, Object[] guids) { + return loadCaches(geocodes, guids, null, null, null, null, false, true, false, false, false, false); + } + + public List<cgCache> loadCaches(Object[] geocodes, Object[] guids, boolean lite) { + if (lite) { + return loadCaches(geocodes, guids, null, null, null, null, false, true, false, false, false, false); + } else { + return loadCaches(geocodes, guids, null, null, null, null, true, true, true, true, true, true); + } + } + + public List<cgCache> loadCaches(Object[] geocodes, Object[] guids, Long centerLat, Long centerLon, Long spanLat, Long spanLon, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { + init(); + // Using more than one of the parametersets results in overly comlex wheres + if (((geocodes != null && geocodes.length > 0) && (guids != null && guids.length > 0))) { + throw new IllegalArgumentException("Please use only one parameter"); + } + if (((geocodes != null && geocodes.length > 0) || (guids != null && guids.length > 0)) + && centerLat != null + && centerLon != null + && spanLat != null + && spanLon != null) { + throw new IllegalArgumentException("Please use only one parameter"); + } + StringBuilder where = new StringBuilder(); + Cursor cursor = null; + List<cgCache> caches = new ArrayList<cgCache>(); + + try { + if (geocodes != null && geocodes.length > 0) { + StringBuilder all = new StringBuilder(); + for (Object one : geocodes) { + if (all.length() > 0) { + all.append(", "); + } + all.append('"'); + all.append((String) one); + all.append('"'); + } + + if (where.length() > 0) { + where.append(" and "); + } + where.append("geocode in ("); + where.append(all); + where.append(')'); + } else if (guids != null && guids.length > 0) { + StringBuilder all = new StringBuilder(); + for (Object one : guids) { + if (all.length() > 0) { + all.append(", "); + } + all.append('"'); + all.append((String) one); + all.append('"'); + } + + if (where.length() > 0) { + where.append(" and "); + } + where.append("guid in ("); + where.append(all); + where.append(')'); + } else { + return caches; + } + + // viewport limitation + if (centerLat != null && centerLon != null && spanLat != null && spanLon != null) { + double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); + double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); + double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); + double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); + double llCache; + + if (latMin > latMax) { + llCache = latMax; + latMax = latMin; + latMin = llCache; + } + if (lonMin > lonMax) { + llCache = lonMax; + lonMax = lonMin; + lonMin = llCache; + } + + if (where.length() > 0) { + where.append(" and "); + } + where.append("(latitude >= "); + where.append(String.format((Locale) null, "%.6f", latMin)); + where.append(" and latitude <= "); + where.append(String.format((Locale) null, "%.6f", latMax)); + where.append(" and longitude >= "); + where.append(String.format((Locale) null, "%.6f", lonMin)); + where.append(" and longitude <= "); + where.append(String.format((Locale) null, "%.6f", lonMax)); + where.append(')'); + } + cursor = databaseRO.query( + dbTableCaches, + CACHE_COLUMNS, + where.toString(), + null, + null, + null, + null, + null); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + + do { + //Extracted Method + cgCache cache = createCacheFromDatabaseContent(cursor); + + if (loadA) { + List<String> attributes = loadAttributes(cache.geocode); + if (attributes != null && attributes.isEmpty() == false) { + if (cache.attributes == null) { cache.attributes = new ArrayList<String>(); } else { cache.attributes.clear(); } - cache.attributes.addAll(attributes); - } - } - - if (loadW) { - List<cgWaypoint> waypoints = loadWaypoints(cache.geocode); - if (waypoints != null && waypoints.isEmpty() == false) { - if (cache.waypoints == null) { + cache.attributes.addAll(attributes); + } + } + + if (loadW) { + List<cgWaypoint> waypoints = loadWaypoints(cache.geocode); + if (waypoints != null && waypoints.isEmpty() == false) { + if (cache.waypoints == null) { cache.waypoints = new ArrayList<cgWaypoint>(); } else { cache.waypoints.clear(); } - cache.waypoints.addAll(waypoints); - } - } - - if (loadS) { - List<cgImage> spoilers = loadSpoilers(cache.geocode); - if (spoilers != null && spoilers.isEmpty() == false) { - if (cache.spoilers == null) { + cache.waypoints.addAll(waypoints); + } + } + + if (loadS) { + List<cgImage> spoilers = loadSpoilers(cache.geocode); + if (spoilers != null && spoilers.isEmpty() == false) { + if (cache.spoilers == null) { cache.spoilers = new ArrayList<cgImage>(); } else { cache.spoilers.clear(); } - cache.spoilers.addAll(spoilers); - } - } - - if (loadL) { - List<cgLog> logs = loadLogs(cache.geocode); - if (logs != null && logs.isEmpty() == false) { - if (cache.logs == null) { + cache.spoilers.addAll(spoilers); + } + } + + if (loadL) { + List<cgLog> logs = loadLogs(cache.geocode); + if (logs != null && logs.isEmpty() == false) { + if (cache.logs == null) { cache.logs = new ArrayList<cgLog>(); } else { cache.logs.clear(); } - cache.logs.addAll(logs); - } - Map<Integer, Integer> logCounts = loadLogCounts(cache.geocode); - if (logCounts != null && logCounts.isEmpty() == false) { - cache.logCounts.clear(); - cache.logCounts.putAll(logCounts); - } - } - - if (loadI) { - List<cgTrackable> inventory = loadInventory(cache.geocode); - if (inventory != null && inventory.isEmpty() == false) { - if (cache.inventory == null) { + cache.logs.addAll(logs); + } + Map<Integer, Integer> logCounts = loadLogCounts(cache.geocode); + if (logCounts != null && logCounts.isEmpty() == false) { + cache.logCounts.clear(); + cache.logCounts.putAll(logCounts); + } + } + + if (loadI) { + List<cgTrackable> inventory = loadInventory(cache.geocode); + if (inventory != null && inventory.isEmpty() == false) { + if (cache.inventory == null) { cache.inventory = new ArrayList<cgTrackable>(); } else { cache.inventory.clear(); } - cache.inventory.addAll(inventory); - } - } - - if (loadO) { - cache.logOffline = hasLogOffline(cache.geocode); - } - - caches.add(cache); - } while (cursor.moveToNext()); - } else { - if (cursor != null) { - cursor.close(); - } - - return null; - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.loadCaches: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); - } - - return caches; - } - - /** - * maps a Cache from the cursor. Doesn't next. - * @param cursor - * @return - */ - - private static cgCache createCacheFromDatabaseContent(Cursor cursor) { - int index; - cgCache cache = new cgCache(); - - cache.updated = (long) cursor.getLong(cursor.getColumnIndex("updated")); - cache.reason = (int) cursor.getInt(cursor.getColumnIndex("reason")); - cache.detailed = cursor.getInt(cursor.getColumnIndex("detailed")) == 1; - cache.detailedUpdate = (Long) cursor.getLong(cursor.getColumnIndex("detailedupdate")); - cache.visitedDate = (Long) cursor.getLong(cursor.getColumnIndex("visiteddate")); - cache.geocode = (String) cursor.getString(cursor.getColumnIndex("geocode")); - cache.cacheId = (String) cursor.getString(cursor.getColumnIndex("cacheid")); - cache.guid = (String) cursor.getString(cursor.getColumnIndex("guid")); - cache.type = (String) cursor.getString(cursor.getColumnIndex("type")); - cache.name = (String) cursor.getString(cursor.getColumnIndex("name")); - cache.own = cursor.getInt(cursor.getColumnIndex("own")) == 1; - cache.owner = (String) cursor.getString(cursor.getColumnIndex("owner")); - cache.ownerReal = (String) cursor.getString(cursor.getColumnIndex("owner_real")); - cache.hidden = new Date((long) cursor.getLong(cursor.getColumnIndex("hidden"))); - cache.hint = (String) cursor.getString(cursor.getColumnIndex("hint")); - cache.size = (String) cursor.getString(cursor.getColumnIndex("size")); - cache.difficulty = (Float) cursor.getFloat(cursor.getColumnIndex("difficulty")); - index = cursor.getColumnIndex("direction"); - if (cursor.isNull(index)) { - cache.direction = null; - } else { - cache.direction = cursor.getFloat(index); - } - index = cursor.getColumnIndex("distance"); - if (cursor.isNull(index)) { - cache.distance = null; - } else { - cache.distance = cursor.getFloat(index); - } - cache.terrain = (Float) cursor.getFloat(cursor.getColumnIndex("terrain")); - cache.latlon = (String) cursor.getString(cursor.getColumnIndex("latlon")); - cache.latitudeString = (String) cursor.getString(cursor.getColumnIndex("latitude_string")); - cache.longitudeString = (String) cursor.getString(cursor.getColumnIndex("longitude_string")); - cache.location = (String) cursor.getString(cursor.getColumnIndex("location")); - cache.coords = getCoords(cursor); - index = cursor.getColumnIndex("elevation"); - if (cursor.isNull(index)) { - cache.elevation = null; - } else { - cache.elevation = (Double) cursor.getDouble(index); - } - cache.personalNote = (String) cursor.getString(cursor.getColumnIndex("personal_note")); - cache.shortdesc = (String) cursor.getString(cursor.getColumnIndex("shortdesc")); - cache.description = (String) cursor.getString(cursor.getColumnIndex("description")); - cache.favouriteCnt = (Integer) cursor.getInt(cursor.getColumnIndex("favourite_cnt")); - cache.rating = (Float) cursor.getFloat(cursor.getColumnIndex("rating")); - cache.votes = (Integer) cursor.getInt(cursor.getColumnIndex("votes")); - cache.myVote = (Float) cursor.getFloat(cursor.getColumnIndex("myvote")); - cache.disabled = cursor.getLong(cursor.getColumnIndex("disabled")) == 1l; - cache.archived = cursor.getLong(cursor.getColumnIndex("archived")) == 1l; - cache.members = cursor.getLong(cursor.getColumnIndex("members")) == 1l; - cache.found = cursor.getLong(cursor.getColumnIndex("found")) == 1l; - cache.favourite = cursor.getLong(cursor.getColumnIndex("favourite")) == 1l; - cache.inventoryItems = (Integer) cursor.getInt(cursor.getColumnIndex("inventoryunknown")); - cache.onWatchlist = cursor.getLong(cursor.getColumnIndex("onWatchlist")) == 1l; - cache.reliableLatLon = cursor.getInt(cursor.getColumnIndex("reliable_latlon"))>0; - return cache; - } - - public List<String> loadAttributes(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - ArrayList<String> attributes = new ArrayList<String>(); - - Cursor cursor = databaseRO.query( - dbTableAttributes, - new String[]{"_id", "attribute"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "100"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); + cache.inventory.addAll(inventory); + } + } + + if (loadO) { + cache.logOffline = hasLogOffline(cache.geocode); + } + + caches.add(cache); + } while (cursor.moveToNext()); + } else { + if (cursor != null) { + cursor.close(); + } + + return null; + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.loadCaches: " + e.toString()); + } + + if (cursor != null) { + cursor.close(); + } + + return caches; + } + + /** + * maps a Cache from the cursor. Doesn't next. + * + * @param cursor + * @return + */ + + private static cgCache createCacheFromDatabaseContent(Cursor cursor) { + int index; + cgCache cache = new cgCache(); + + cache.updated = (long) cursor.getLong(cursor.getColumnIndex("updated")); + cache.reason = (int) cursor.getInt(cursor.getColumnIndex("reason")); + cache.detailed = cursor.getInt(cursor.getColumnIndex("detailed")) == 1; + cache.detailedUpdate = (Long) cursor.getLong(cursor.getColumnIndex("detailedupdate")); + cache.visitedDate = (Long) cursor.getLong(cursor.getColumnIndex("visiteddate")); + cache.geocode = (String) cursor.getString(cursor.getColumnIndex("geocode")); + cache.cacheId = (String) cursor.getString(cursor.getColumnIndex("cacheid")); + cache.guid = (String) cursor.getString(cursor.getColumnIndex("guid")); + cache.type = (String) cursor.getString(cursor.getColumnIndex("type")); + cache.name = (String) cursor.getString(cursor.getColumnIndex("name")); + cache.own = cursor.getInt(cursor.getColumnIndex("own")) == 1; + cache.owner = (String) cursor.getString(cursor.getColumnIndex("owner")); + cache.ownerReal = (String) cursor.getString(cursor.getColumnIndex("owner_real")); + cache.hidden = new Date((long) cursor.getLong(cursor.getColumnIndex("hidden"))); + cache.hint = (String) cursor.getString(cursor.getColumnIndex("hint")); + cache.size = (String) cursor.getString(cursor.getColumnIndex("size")); + cache.difficulty = (Float) cursor.getFloat(cursor.getColumnIndex("difficulty")); + index = cursor.getColumnIndex("direction"); + if (cursor.isNull(index)) { + cache.direction = null; + } else { + cache.direction = cursor.getFloat(index); + } + index = cursor.getColumnIndex("distance"); + if (cursor.isNull(index)) { + cache.distance = null; + } else { + cache.distance = cursor.getFloat(index); + } + cache.terrain = (Float) cursor.getFloat(cursor.getColumnIndex("terrain")); + cache.latlon = (String) cursor.getString(cursor.getColumnIndex("latlon")); + cache.latitudeString = (String) cursor.getString(cursor.getColumnIndex("latitude_string")); + cache.longitudeString = (String) cursor.getString(cursor.getColumnIndex("longitude_string")); + cache.location = (String) cursor.getString(cursor.getColumnIndex("location")); + cache.coords = getCoords(cursor); + index = cursor.getColumnIndex("elevation"); + if (cursor.isNull(index)) { + cache.elevation = null; + } else { + cache.elevation = (Double) cursor.getDouble(index); + } + cache.personalNote = (String) cursor.getString(cursor.getColumnIndex("personal_note")); + cache.shortdesc = (String) cursor.getString(cursor.getColumnIndex("shortdesc")); + cache.description = (String) cursor.getString(cursor.getColumnIndex("description")); + cache.favouriteCnt = (Integer) cursor.getInt(cursor.getColumnIndex("favourite_cnt")); + cache.rating = (Float) cursor.getFloat(cursor.getColumnIndex("rating")); + cache.votes = (Integer) cursor.getInt(cursor.getColumnIndex("votes")); + cache.myVote = (Float) cursor.getFloat(cursor.getColumnIndex("myvote")); + cache.disabled = cursor.getLong(cursor.getColumnIndex("disabled")) == 1l; + cache.archived = cursor.getLong(cursor.getColumnIndex("archived")) == 1l; + cache.members = cursor.getLong(cursor.getColumnIndex("members")) == 1l; + cache.found = cursor.getLong(cursor.getColumnIndex("found")) == 1l; + cache.favourite = cursor.getLong(cursor.getColumnIndex("favourite")) == 1l; + cache.inventoryItems = (Integer) cursor.getInt(cursor.getColumnIndex("inventoryunknown")); + cache.onWatchlist = cursor.getLong(cursor.getColumnIndex("onWatchlist")) == 1l; + cache.reliableLatLon = cursor.getInt(cursor.getColumnIndex("reliable_latlon")) > 0; + return cache; + } + + public List<String> loadAttributes(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + ArrayList<String> attributes = new ArrayList<String>(); + + Cursor cursor = databaseRO.query( + dbTableAttributes, + new String[] { "_id", "attribute" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "100"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("attribute"); - do { + do { attributes.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } + } while (cursor.moveToNext()); + } - if (cursor != null) { - cursor.close(); - } + if (cursor != null) { + cursor.close(); + } - return attributes; - } - - public cgWaypoint loadWaypoint(Integer id) { - if (id == null || id == 0) { - return null; - } - - init(); - - cgWaypoint waypoint = new cgWaypoint(); - - Cursor cursor = databaseRO.query( - dbTableWaypoints, - new String[]{"_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude_string", "longitude_string", "latitude", "longitude", "note"}, - "_id = " + id, - null, - null, - null, - null, - "1"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); - - waypoint = createWaypointFromDatabaseContent(cursor); - } - - if (cursor != null) { - cursor.close(); - } - - return waypoint; - } - - public List<cgWaypoint> loadWaypoints(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - List<cgWaypoint> waypoints = new ArrayList<cgWaypoint>(); - - Cursor cursor = databaseRO.query( - dbTableWaypoints, - new String[]{"_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude_string", "longitude_string", "latitude", "longitude", "note"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "100"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); - - do { - - cgWaypoint waypoint = createWaypointFromDatabaseContent(cursor); - - waypoints.add(waypoint); - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - return waypoints; - } - - private static cgWaypoint createWaypointFromDatabaseContent(Cursor cursor) { - cgWaypoint waypoint = new cgWaypoint(); - waypoint.id = (int) cursor.getInt(cursor.getColumnIndex("_id")); - waypoint.geocode = (String) cursor.getString(cursor.getColumnIndex("geocode")); - waypoint.type = (String) cursor.getString(cursor.getColumnIndex("type")); - waypoint.prefix = (String) cursor.getString(cursor.getColumnIndex("prefix")); - waypoint.lookup = (String) cursor.getString(cursor.getColumnIndex("lookup")); - waypoint.name = (String) cursor.getString(cursor.getColumnIndex("name")); - waypoint.latlon = (String) cursor.getString(cursor.getColumnIndex("latlon")); - waypoint.latitudeString = (String) cursor.getString(cursor.getColumnIndex("latitude_string")); - waypoint.longitudeString = (String) cursor.getString(cursor.getColumnIndex("longitude_string")); - waypoint.coords = getCoords(cursor); - waypoint.note = (String) cursor.getString(cursor.getColumnIndex("note")); - - return waypoint; - } - - public List<cgImage> loadSpoilers(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - List<cgImage> spoilers = new ArrayList<cgImage>(); - - Cursor cursor = databaseRO.query( - dbTableSpoilers, - new String[]{"_id", "url", "title", "description"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "100"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); + return attributes; + } + + public cgWaypoint loadWaypoint(Integer id) { + if (id == null || id == 0) { + return null; + } + + init(); + + cgWaypoint waypoint = new cgWaypoint(); + + Cursor cursor = databaseRO.query( + dbTableWaypoints, + new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude_string", "longitude_string", "latitude", "longitude", "note" }, + "_id = " + id, + null, + null, + null, + null, + "1"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); + + waypoint = createWaypointFromDatabaseContent(cursor); + } + + if (cursor != null) { + cursor.close(); + } + + return waypoint; + } + + public List<cgWaypoint> loadWaypoints(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + List<cgWaypoint> waypoints = new ArrayList<cgWaypoint>(); + + Cursor cursor = databaseRO.query( + dbTableWaypoints, + new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude_string", "longitude_string", "latitude", "longitude", "note" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "100"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); + + do { + + cgWaypoint waypoint = createWaypointFromDatabaseContent(cursor); + + waypoints.add(waypoint); + } while (cursor.moveToNext()); + } + + if (cursor != null) { + cursor.close(); + } + + return waypoints; + } + + private static cgWaypoint createWaypointFromDatabaseContent(Cursor cursor) { + cgWaypoint waypoint = new cgWaypoint(); + waypoint.id = (int) cursor.getInt(cursor.getColumnIndex("_id")); + waypoint.geocode = (String) cursor.getString(cursor.getColumnIndex("geocode")); + waypoint.type = (String) cursor.getString(cursor.getColumnIndex("type")); + waypoint.prefix = (String) cursor.getString(cursor.getColumnIndex("prefix")); + waypoint.lookup = (String) cursor.getString(cursor.getColumnIndex("lookup")); + waypoint.name = (String) cursor.getString(cursor.getColumnIndex("name")); + waypoint.latlon = (String) cursor.getString(cursor.getColumnIndex("latlon")); + waypoint.latitudeString = (String) cursor.getString(cursor.getColumnIndex("latitude_string")); + waypoint.longitudeString = (String) cursor.getString(cursor.getColumnIndex("longitude_string")); + waypoint.coords = getCoords(cursor); + waypoint.note = (String) cursor.getString(cursor.getColumnIndex("note")); + + return waypoint; + } + + public List<cgImage> loadSpoilers(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + List<cgImage> spoilers = new ArrayList<cgImage>(); + + Cursor cursor = databaseRO.query( + dbTableSpoilers, + new String[] { "_id", "url", "title", "description" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "100"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); int indexUrl = cursor.getColumnIndex("url"); int indexTitle = cursor.getColumnIndex("title"); int indexDescription = cursor.getColumnIndex("description"); - do { - cgImage spoiler = new cgImage(); + do { + cgImage spoiler = new cgImage(); spoiler.url = (String) cursor.getString(indexUrl); spoiler.title = (String) cursor.getString(indexTitle); spoiler.description = (String) cursor.getString(indexDescription); - spoilers.add(spoiler); - } while (cursor.moveToNext()); - } + spoilers.add(spoiler); + } while (cursor.moveToNext()); + } - if (cursor != null) { - cursor.close(); - } + if (cursor != null) { + cursor.close(); + } - return spoilers; - } + return spoilers; + } - /** - * Loads the history of previously entered destinations from - * the database. If no destinations exist, an {@link Collections#emptyList()} - * will be returned. - * @return A list of previously entered destinations or an empty list. - */ - public List<cgDestination> loadHistoryOfSearchedLocations() { - init(); + /** + * Loads the history of previously entered destinations from + * the database. If no destinations exist, an {@link Collections#emptyList()} will be returned. + * + * @return A list of previously entered destinations or an empty list. + */ + public List<cgDestination> loadHistoryOfSearchedLocations() { + init(); - Cursor cursor = databaseRO.query(dbTableSearchDestionationHistory, - new String[] { "_id", "date", "latitude", "longitude" }, null, - null, null, null, "date desc", "100"); + Cursor cursor = databaseRO.query(dbTableSearchDestionationHistory, + new String[] { "_id", "date", "latitude", "longitude" }, null, + null, null, null, "date desc", "100"); - final List<cgDestination> destinations = new LinkedList<cgDestination>(); + final List<cgDestination> destinations = new LinkedList<cgDestination>(); - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); int indexId = cursor.getColumnIndex("_id"); int indexDate = cursor.getColumnIndex("date"); int indexLatitude = cursor.getColumnIndex("latitude"); int indexLongitude = cursor.getColumnIndex("longitude"); - do { - cgDestination dest = new cgDestination(); + do { + cgDestination dest = new cgDestination(); dest.setId((long) cursor.getLong(indexId)); dest.setDate((long) cursor.getLong(indexDate)); dest.setCoords(new Geopoint((double) cursor.getDouble(indexLatitude), - (double) cursor.getDouble(indexLongitude))); - - destinations.add(dest); - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - return destinations; - } - - public boolean clearSearchedDestinations() { - boolean success = true; - init(); - databaseRW.beginTransaction(); - - try { - databaseRW.delete(dbTableSearchDestionationHistory, null, null); - databaseRW.setTransactionSuccessful(); - } catch (Exception e) { - success = false; - Log.e(cgSettings.tag, "Unable to clear searched destinations", e); - } - finally{ - databaseRW.endTransaction(); - } - - return success; - } - - public List<cgLog> loadLogs(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - List<cgLog> logs = new ArrayList<cgLog>(); - - Cursor cursor = databaseRO.rawQuery( - "SELECT cg_logs._id as cg_logs_id, type, author, log, date, found, " + dbTableLogImages + "._id as cg_logImages_id, log_id, title, url FROM " - + dbTableLogs + " LEFT OUTER JOIN " + dbTableLogImages - + " ON ( cg_logs._id = log_id ) WHERE geocode = ? ORDER BY date desc, cg_logs._id asc", new String[]{ geocode}); - - if (cursor != null && cursor.getCount() > 0) { - cgLog log = null; + (double) cursor.getDouble(indexLongitude))); + + destinations.add(dest); + } while (cursor.moveToNext()); + } + + if (cursor != null) { + cursor.close(); + } + + return destinations; + } + + public boolean clearSearchedDestinations() { + boolean success = true; + init(); + databaseRW.beginTransaction(); + + try { + databaseRW.delete(dbTableSearchDestionationHistory, null, null); + databaseRW.setTransactionSuccessful(); + } catch (Exception e) { + success = false; + Log.e(cgSettings.tag, "Unable to clear searched destinations", e); + } finally { + databaseRW.endTransaction(); + } + + return success; + } + + public List<cgLog> loadLogs(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + List<cgLog> logs = new ArrayList<cgLog>(); + + Cursor cursor = databaseRO.rawQuery( + "SELECT cg_logs._id as cg_logs_id, type, author, log, date, found, " + dbTableLogImages + "._id as cg_logImages_id, log_id, title, url FROM " + + dbTableLogs + " LEFT OUTER JOIN " + dbTableLogImages + + " ON ( cg_logs._id = log_id ) WHERE geocode = ? ORDER BY date desc, cg_logs._id asc", new String[] { geocode }); + + if (cursor != null && cursor.getCount() > 0) { + cgLog log = null; int indexLogsId = cursor.getColumnIndex("cg_logs_id"); int indexType = cursor.getColumnIndex("type"); int indexAuthor = cursor.getColumnIndex("author"); @@ -2274,63 +2280,63 @@ public class cgData { int indexLogImagesId = cursor.getColumnIndex("cg_logImages_id"); int indexTitle = cursor.getColumnIndex("title"); int indexUrl = cursor.getColumnIndex("url"); - while (cursor.moveToNext() && logs.size() < 100) { + while (cursor.moveToNext() && logs.size() < 100) { if (log == null || log.id != cursor.getInt(indexLogsId)) { - log = new cgLog(); - log.id = (int) cursor.getInt(indexLogsId); + log = new cgLog(); + log.id = (int) cursor.getInt(indexLogsId); log.type = (int) cursor.getInt(indexType); log.author = (String) cursor.getString(indexAuthor); log.log = (String) cursor.getString(indexLog); log.date = (long) cursor.getLong(indexDate); log.found = (int) cursor.getInt(indexFound); - logs.add(log); - } + logs.add(log); + } if (!cursor.isNull(indexLogImagesId)) { - final cgImage log_img = new cgImage(); + final cgImage log_img = new cgImage(); log_img.title = (String) cursor.getString(indexTitle); - if (log_img.title == null) { - log_img.title = ""; - } + if (log_img.title == null) { + log_img.title = ""; + } log_img.url = (String) cursor.getString(indexUrl); - if (log_img.url == null) { - log_img.url = ""; - } - if (log.logImages == null) { - log.logImages = new ArrayList<cgImage>(); - } - log.logImages.add(log_img); - } - } - } - - if (cursor != null) { - cursor.close(); - } - - return logs; - } - - public Map<Integer, Integer> loadLogCounts(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); - - Cursor cursor = databaseRO.query( - dbTableLogCount, - new String[]{"_id", "type", "count"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - null, - "100"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); + if (log_img.url == null) { + log_img.url = ""; + } + if (log.logImages == null) { + log.logImages = new ArrayList<cgImage>(); + } + log.logImages.add(log_img); + } + } + } + + if (cursor != null) { + cursor.close(); + } + + return logs; + } + + public Map<Integer, Integer> loadLogCounts(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); + + Cursor cursor = databaseRO.query( + dbTableLogCount, + new String[] { "_id", "type", "count" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + null, + "100"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); int indexType = cursor.getColumnIndex("type"); int indexCount = cursor.getColumnIndex("count"); @@ -2338,717 +2344,717 @@ public class cgData { Integer type = cursor.getInt(indexType); Integer count = cursor.getInt(indexCount); - logCounts.put(type, count); - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - return logCounts; - } - - public List<cgTrackable> loadInventory(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - List<cgTrackable> trackables = new ArrayList<cgTrackable>(); - - Cursor cursor = databaseRO.query( - dbTableTrackables, - new String[]{"_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - "title COLLATE NOCASE ASC", - "100"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); - - do { - cgTrackable trackable = createTrackableFromDatabaseContent(cursor); - - trackables.add(trackable); - } while (cursor.moveToNext()); - } - - if (cursor != null) { - cursor.close(); - } - - return trackables; - } - - public cgTrackable loadTrackable(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - cgTrackable trackable = new cgTrackable(); - - Cursor cursor = databaseRO.query( - dbTableTrackables, - new String[]{"_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, - "tbcode = \"" + geocode + "\"", - null, - null, - null, - null, - "1"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); - trackable = createTrackableFromDatabaseContent(cursor); - } - - if (cursor != null) { - cursor.close(); - } - - return trackable; - } - - private cgTrackable createTrackableFromDatabaseContent(Cursor cursor) { - cgTrackable trackable = new cgTrackable(); - trackable.geocode = (String) cursor.getString(cursor.getColumnIndex("tbcode")); - trackable.guid = (String) cursor.getString(cursor.getColumnIndex("guid")); - trackable.name = (String) cursor.getString(cursor.getColumnIndex("title")); - trackable.owner = (String) cursor.getString(cursor.getColumnIndex("owner")); - String releasedPre = cursor.getString(cursor.getColumnIndex("released")); - if (releasedPre != null && Long.getLong(releasedPre) != null) { - trackable.released = new Date(Long.getLong(releasedPre)); - } else { - trackable.released = null; - } - trackable.goal = (String) cursor.getString(cursor.getColumnIndex("goal")); - trackable.details = (String) cursor.getString(cursor.getColumnIndex("description")); - trackable.logs = loadLogs(trackable.geocode); - return trackable; - } - - public int getAllStoredCachesCount(boolean detailedOnly, String cachetype, Integer list) { - String listSql = null; - String listSqlW = null; - if (list == null) { - listSql = " where reason >= 1"; - listSqlW = " and reason >= 1"; - } else if (list >= 1) { - listSql = " where reason = " + list; - listSqlW = " and reason = " + list; - } else { - return 0; - } - - int count = 0; - try { - String sql = "select count(_id) from " + dbTableCaches; // this default is not used, but we like to have variables initialized - if (detailedOnly == false) { - if (cachetype == null) { - sql = "select count(_id) from " + dbTableCaches + listSql; - } else { - sql = "select count(_id) from " + dbTableCaches + " where type = \"" + cachetype + "\"" + listSqlW; - } - } else { - if (cachetype == null) { - sql = "select count(_id) from " + dbTableCaches + " where detailed = 1" + listSqlW; - } else { - sql = "select count(_id) from " + dbTableCaches + " where detailed = 1 and type = \"" + cachetype + "\"" + listSqlW; - } - } - SQLiteStatement compiledStmnt = databaseRO.compileStatement(sql); - count = (int) compiledStmnt.simpleQueryForLong(); - compiledStmnt.close(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.loadAllStoredCachesCount: " + e.toString()); - } - - return count; - } - - public int getAllHistoricCachesCount(boolean detailedOnly, String cachetype) { - init(); - - int count = 0; - - try { - SQLiteStatement sqlCount = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where visiteddate > 0"); - count = (int) sqlCount.simpleQueryForLong(); - sqlCount.close(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getAllHistoricCachesCount: " + e.toString()); - } - - return count; - } - - public List<String> loadBatchOfStoredGeocodes(boolean detailedOnly, final Geopoint coords, String cachetype, int list) { - init(); - - if (list < 1) { - list = 1; - } - - List<String> geocodes = new ArrayList<String>(); - - StringBuilder specifySql = new StringBuilder(); - - specifySql.append("reason = "); - specifySql.append(list); - - if (detailedOnly) { + logCounts.put(type, count); + } while (cursor.moveToNext()); + } + + if (cursor != null) { + cursor.close(); + } + + return logCounts; + } + + public List<cgTrackable> loadInventory(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + List<cgTrackable> trackables = new ArrayList<cgTrackable>(); + + Cursor cursor = databaseRO.query( + dbTableTrackables, + new String[] { "_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + "title COLLATE NOCASE ASC", + "100"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); + + do { + cgTrackable trackable = createTrackableFromDatabaseContent(cursor); + + trackables.add(trackable); + } while (cursor.moveToNext()); + } + + if (cursor != null) { + cursor.close(); + } + + return trackables; + } + + public cgTrackable loadTrackable(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + cgTrackable trackable = new cgTrackable(); + + Cursor cursor = databaseRO.query( + dbTableTrackables, + new String[] { "_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description" }, + "tbcode = \"" + geocode + "\"", + null, + null, + null, + null, + "1"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); + trackable = createTrackableFromDatabaseContent(cursor); + } + + if (cursor != null) { + cursor.close(); + } + + return trackable; + } + + private cgTrackable createTrackableFromDatabaseContent(Cursor cursor) { + cgTrackable trackable = new cgTrackable(); + trackable.geocode = (String) cursor.getString(cursor.getColumnIndex("tbcode")); + trackable.guid = (String) cursor.getString(cursor.getColumnIndex("guid")); + trackable.name = (String) cursor.getString(cursor.getColumnIndex("title")); + trackable.owner = (String) cursor.getString(cursor.getColumnIndex("owner")); + String releasedPre = cursor.getString(cursor.getColumnIndex("released")); + if (releasedPre != null && Long.getLong(releasedPre) != null) { + trackable.released = new Date(Long.getLong(releasedPre)); + } else { + trackable.released = null; + } + trackable.goal = (String) cursor.getString(cursor.getColumnIndex("goal")); + trackable.details = (String) cursor.getString(cursor.getColumnIndex("description")); + trackable.logs = loadLogs(trackable.geocode); + return trackable; + } + + public int getAllStoredCachesCount(boolean detailedOnly, String cachetype, Integer list) { + String listSql = null; + String listSqlW = null; + if (list == null) { + listSql = " where reason >= 1"; + listSqlW = " and reason >= 1"; + } else if (list >= 1) { + listSql = " where reason = " + list; + listSqlW = " and reason = " + list; + } else { + return 0; + } + + int count = 0; + try { + String sql = "select count(_id) from " + dbTableCaches; // this default is not used, but we like to have variables initialized + if (detailedOnly == false) { + if (cachetype == null) { + sql = "select count(_id) from " + dbTableCaches + listSql; + } else { + sql = "select count(_id) from " + dbTableCaches + " where type = \"" + cachetype + "\"" + listSqlW; + } + } else { + if (cachetype == null) { + sql = "select count(_id) from " + dbTableCaches + " where detailed = 1" + listSqlW; + } else { + sql = "select count(_id) from " + dbTableCaches + " where detailed = 1 and type = \"" + cachetype + "\"" + listSqlW; + } + } + SQLiteStatement compiledStmnt = databaseRO.compileStatement(sql); + count = (int) compiledStmnt.simpleQueryForLong(); + compiledStmnt.close(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.loadAllStoredCachesCount: " + e.toString()); + } + + return count; + } + + public int getAllHistoricCachesCount(boolean detailedOnly, String cachetype) { + init(); + + int count = 0; + + try { + SQLiteStatement sqlCount = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where visiteddate > 0"); + count = (int) sqlCount.simpleQueryForLong(); + sqlCount.close(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getAllHistoricCachesCount: " + e.toString()); + } + + return count; + } + + public List<String> loadBatchOfStoredGeocodes(boolean detailedOnly, final Geopoint coords, String cachetype, int list) { + init(); + + if (list < 1) { + list = 1; + } + + List<String> geocodes = new ArrayList<String>(); + + StringBuilder specifySql = new StringBuilder(); + + specifySql.append("reason = "); + specifySql.append(list); + + if (detailedOnly) { specifySql.append(" and detailed = 1 "); } - if (cachetype != null) { - specifySql.append(" and type = \""); - specifySql.append(cachetype); - specifySql.append('"'); - } - - try { - Cursor cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode", "(abs(latitude-" + String.format((Locale) null, "%.6f", coords.getLatitude()) + - ") + abs(longitude-" + String.format((Locale) null, "%.6f", coords.getLongitude()) + ")) as dif"}, - specifySql.toString(), - null, - null, - null, - "dif", - null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + if (cachetype != null) { + specifySql.append(" and type = \""); + specifySql.append(cachetype); + specifySql.append('"'); + } + + try { + Cursor cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode", "(abs(latitude-" + String.format((Locale) null, "%.6f", coords.getLatitude()) + + ") + abs(longitude-" + String.format((Locale) null, "%.6f", coords.getLongitude()) + ")) as dif" }, + specifySql.toString(), + null, + null, + null, + "dif", + null); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); - do { + do { geocodes.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } else { - cursor.close(); - return null; - } - - cursor.close(); - } - - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.loadBatchOfStoredGeocodes: " + e.toString()); - } - - return geocodes; - } - - public List<String> loadBatchOfHistoricGeocodes(boolean detailedOnly, String cachetype) { - init(); - - List<String> geocodes = new ArrayList<String>(); - - StringBuilder specifySql = new StringBuilder(); - specifySql.append("visiteddate > 0"); - - if (detailedOnly) { - specifySql.append(" and detailed = 1"); - } - if (cachetype != null) { - specifySql.append(" and type = \""); - specifySql.append(cachetype); - specifySql.append('"'); - } - - try { - Cursor cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - specifySql.toString(), - null, - null, - null, - "visiteddate", - null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + } while (cursor.moveToNext()); + } else { + cursor.close(); + return null; + } + + cursor.close(); + } + + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.loadBatchOfStoredGeocodes: " + e.toString()); + } + + return geocodes; + } + + public List<String> loadBatchOfHistoricGeocodes(boolean detailedOnly, String cachetype) { + init(); + + List<String> geocodes = new ArrayList<String>(); + + StringBuilder specifySql = new StringBuilder(); + specifySql.append("visiteddate > 0"); + + if (detailedOnly) { + specifySql.append(" and detailed = 1"); + } + if (cachetype != null) { + specifySql.append(" and type = \""); + specifySql.append(cachetype); + specifySql.append('"'); + } + + try { + Cursor cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + specifySql.toString(), + null, + null, + null, + "visiteddate", + null); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); - do { + do { geocodes.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } else { - cursor.close(); - return null; - } - - cursor.close(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.loadBatchOfHistoricGeocodes: " + e.toString()); - } - - return geocodes; - } - - public List<String> getCachedInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { - return getInViewport(false, centerLat, centerLon, spanLat, spanLon, cachetype); - } - - public List<String> getStoredInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { - return getInViewport(true, centerLat, centerLon, spanLat, spanLon, cachetype); - } - - public List<String> getInViewport(boolean stored, Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { - if (centerLat == null || centerLon == null || spanLat == null || spanLon == null) { - return null; - } - - init(); - - List<String> geocodes = new ArrayList<String>(); - - // viewport limitation - double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); - double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); - double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); - double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); - double llCache; - - if (latMin > latMax) { - llCache = latMax; - latMax = latMin; - latMin = llCache; - } - if (lonMin > lonMax) { - llCache = lonMax; - lonMax = lonMin; - lonMin = llCache; - } - - StringBuilder where = new StringBuilder(); - where.append("latitude >= "); - where.append(String.format((Locale) null, "%.6f", latMin)); - where.append(" and latitude <= "); - where.append(String.format((Locale) null, "%.6f", latMax)); - where.append(" and longitude >= "); - where.append(String.format((Locale) null, "%.6f", lonMin)); - where.append(" and longitude <= "); - where.append(String.format((Locale) null, "%.6f", lonMax)); - - // cachetype limitation - if (cachetype != null) { - where.append(" and type = \""); - where.append(cachetype); - where.append('"'); - } - - // offline caches only - if (stored) { - where.append(" and reason >= 1"); - } - - try { - Cursor cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - where.toString(), - null, - null, - null, - null, - "500"); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + } while (cursor.moveToNext()); + } else { + cursor.close(); + return null; + } + + cursor.close(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.loadBatchOfHistoricGeocodes: " + e.toString()); + } + + return geocodes; + } + + public List<String> getCachedInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { + return getInViewport(false, centerLat, centerLon, spanLat, spanLon, cachetype); + } + + public List<String> getStoredInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { + return getInViewport(true, centerLat, centerLon, spanLat, spanLon, cachetype); + } + + public List<String> getInViewport(boolean stored, Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { + if (centerLat == null || centerLon == null || spanLat == null || spanLon == null) { + return null; + } + + init(); + + List<String> geocodes = new ArrayList<String>(); + + // viewport limitation + double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); + double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); + double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); + double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); + double llCache; + + if (latMin > latMax) { + llCache = latMax; + latMax = latMin; + latMin = llCache; + } + if (lonMin > lonMax) { + llCache = lonMax; + lonMax = lonMin; + lonMin = llCache; + } + + StringBuilder where = new StringBuilder(); + where.append("latitude >= "); + where.append(String.format((Locale) null, "%.6f", latMin)); + where.append(" and latitude <= "); + where.append(String.format((Locale) null, "%.6f", latMax)); + where.append(" and longitude >= "); + where.append(String.format((Locale) null, "%.6f", lonMin)); + where.append(" and longitude <= "); + where.append(String.format((Locale) null, "%.6f", lonMax)); + + // cachetype limitation + if (cachetype != null) { + where.append(" and type = \""); + where.append(cachetype); + where.append('"'); + } + + // offline caches only + if (stored) { + where.append(" and reason >= 1"); + } + + try { + Cursor cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + where.toString(), + null, + null, + null, + null, + "500"); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); - do { + do { geocodes.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } else { - cursor.close(); - return null; - } - - cursor.close(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getOfflineInViewport: " + e.toString()); - } - - return geocodes; - } - - public List<String> getOfflineAll(String cachetype) { - init(); - - List<String> geocodes = new ArrayList<String>(); - - StringBuilder where = new StringBuilder(); - - // cachetype limitation - if (cachetype != null) { - where.append(cachetype); - where.append('"'); - } - - // offline caches only - if (where.length() > 0) { - where.append(" and "); - } - where.append("reason >= 1"); - - try { - Cursor cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - where.toString(), - null, - null, - null, - null, - "5000"); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + } while (cursor.moveToNext()); + } else { + cursor.close(); + return null; + } + + cursor.close(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getOfflineInViewport: " + e.toString()); + } + + return geocodes; + } + + public List<String> getOfflineAll(String cachetype) { + init(); + + List<String> geocodes = new ArrayList<String>(); + + StringBuilder where = new StringBuilder(); + + // cachetype limitation + if (cachetype != null) { + where.append(cachetype); + where.append('"'); + } + + // offline caches only + if (where.length() > 0) { + where.append(" and "); + } + where.append("reason >= 1"); + + try { + Cursor cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + where.toString(), + null, + null, + null, + null, + "5000"); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); - do { + do { geocodes.add((String) cursor.getString(index)); - } while (cursor.moveToNext()); - } else { - cursor.close(); - return null; - } - - cursor.close(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.getOfflineAll: " + e.toString()); - } - - return geocodes; - } - - public void markStored(String geocode, int listId) { - if (StringUtils.isBlank(geocode)) { - return; - } - - init(); - - if (listId <= 0) { - listId = 1; - } - - ContentValues values = new ContentValues(); - values.put("reason", listId); - databaseRW.update(dbTableCaches, values, "geocode = ? and reason < 1", new String[] {geocode}); - } - - public boolean markDropped(String geocode) { - if (StringUtils.isBlank(geocode)) { - return false; - } - - init(); - - try { - ContentValues values = new ContentValues(); - values.put("reason", 0); - int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {geocode}); - - if (rows > 0) { - return true; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.markDropped: " + e.toString()); - } - - return false; - } - - public boolean markFound(String geocode) { - if (StringUtils.isBlank(geocode)) { - return false; - } - - init(); - - try { - ContentValues values = new ContentValues(); - values.put("found", 1); - int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {geocode}); - - if (rows > 0) { - return true; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.markFound: " + e.toString()); - } - - return false; - } - - public void clean() { - clean(false); - } - - public void clean(boolean more) { - init(); - - Log.d(cgSettings.tag, "Database clean: started"); - - Cursor cursor = null; - List<String> geocodes = new ArrayList<String>(); - - try { - if (more) { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - "reason = 0", - null, - null, - null, - null, - null); - } else { - cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - "reason = 0 and detailed < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + " and detailedupdate < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + " and visiteddate < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)), - null, - null, - null, - null, - null); - } - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + } while (cursor.moveToNext()); + } else { + cursor.close(); + return null; + } + + cursor.close(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.getOfflineAll: " + e.toString()); + } + + return geocodes; + } + + public void markStored(String geocode, int listId) { + if (StringUtils.isBlank(geocode)) { + return; + } + + init(); + + if (listId <= 0) { + listId = 1; + } + + ContentValues values = new ContentValues(); + values.put("reason", listId); + databaseRW.update(dbTableCaches, values, "geocode = ? and reason < 1", new String[] { geocode }); + } + + public boolean markDropped(String geocode) { + if (StringUtils.isBlank(geocode)) { + return false; + } + + init(); + + try { + ContentValues values = new ContentValues(); + values.put("reason", 0); + int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); + + if (rows > 0) { + return true; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.markDropped: " + e.toString()); + } + + return false; + } + + public boolean markFound(String geocode) { + if (StringUtils.isBlank(geocode)) { + return false; + } + + init(); + + try { + ContentValues values = new ContentValues(); + values.put("found", 1); + int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); + + if (rows > 0) { + return true; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.markFound: " + e.toString()); + } + + return false; + } + + public void clean() { + clean(false); + } + + public void clean(boolean more) { + init(); + + Log.d(cgSettings.tag, "Database clean: started"); + + Cursor cursor = null; + List<String> geocodes = new ArrayList<String>(); + + try { + if (more) { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + "reason = 0", + null, + null, + null, + null, + null); + } else { + cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + "reason = 0 and detailed < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + " and detailedupdate < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)) + " and visiteddate < " + (System.currentTimeMillis() - (3 * 24 * 60 * 60 * 1000)), + null, + null, + null, + null, + null); + } + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); do { geocodes.add("\"" + (String) cursor.getString(index) + "\""); - } while (cursor.moveToNext()); - } - - cursor.close(); - } - - final int size = geocodes.size(); - if (size > 0) { - Log.d(cgSettings.tag, "Database clean: removing " + size + " geocaches"); - - String geocodeList = cgBase.implode(", ", geocodes.toArray()); - databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogs + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogCount + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogsOffline + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableWaypoints + " where geocode in (" + geocodeList + ") and type <> \"own\""); - databaseRW.execSQL("delete from " + dbTableTrackables + " where geocode in (" + geocodeList + ")"); - - geocodes.clear(); - } - - databaseRW.execSQL("delete from " + dbTableCaches + " where geocode = \"\""); - - if (Log.isLoggable(cgSettings.tag, Log.DEBUG)) { - final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where reason = 0"); - final int count = (int) countSql.simpleQueryForLong(); - countSql.close(); - Log.d(cgSettings.tag, "Database clean: " + count + " cached geocaches remaining"); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgData.clean: " + e.toString()); - } - - Log.d(cgSettings.tag, "Database clean: finished"); - } - - public void dropStored(int listId) { - init(); - - List<String> geocodes = new ArrayList<String>(); - - try { - Cursor cursor = databaseRO.query( - dbTableCaches, - new String[]{"_id", "geocode"}, - "reason = " + listId, - null, - null, - null, - null, - null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - cursor.moveToFirst(); + } while (cursor.moveToNext()); + } + + cursor.close(); + } + + final int size = geocodes.size(); + if (size > 0) { + Log.d(cgSettings.tag, "Database clean: removing " + size + " geocaches"); + + String geocodeList = cgBase.implode(", ", geocodes.toArray()); + databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogs + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogCount + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogsOffline + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableWaypoints + " where geocode in (" + geocodeList + ") and type <> \"own\""); + databaseRW.execSQL("delete from " + dbTableTrackables + " where geocode in (" + geocodeList + ")"); + + geocodes.clear(); + } + + databaseRW.execSQL("delete from " + dbTableCaches + " where geocode = \"\""); + + if (Log.isLoggable(cgSettings.tag, Log.DEBUG)) { + final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where reason = 0"); + final int count = (int) countSql.simpleQueryForLong(); + countSql.close(); + Log.d(cgSettings.tag, "Database clean: " + count + " cached geocaches remaining"); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgData.clean: " + e.toString()); + } + + Log.d(cgSettings.tag, "Database clean: finished"); + } + + public void dropStored(int listId) { + init(); + + List<String> geocodes = new ArrayList<String>(); + + try { + Cursor cursor = databaseRO.query( + dbTableCaches, + new String[] { "_id", "geocode" }, + "reason = " + listId, + null, + null, + null, + null, + null); + + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); int index = cursor.getColumnIndex("geocode"); - do { + do { geocodes.add("\"" + (String) cursor.getString(index) + "\""); - } while (cursor.moveToNext()); - } else { - cursor.close(); - return; - } - - cursor.close(); - } - - if (CollectionUtils.isNotEmpty(geocodes)) { - String geocodeList = cgBase.implode(", ", geocodes.toArray()); - databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogs + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogCount + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableLogsOffline + " where geocode in (" + geocodeList + ")"); - databaseRW.execSQL("delete from " + dbTableWaypoints + " where geocode in (" + geocodeList + ") and type <> \"own\""); - databaseRW.execSQL("delete from " + dbTableTrackables + " where geocode in (" + geocodeList + ")"); - - geocodes.clear(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.dropStored: " + e.toString()); - } - } - - public boolean saveLogOffline(String geocode, Date date, int type, String log) { - if (StringUtils.isBlank(geocode)) { - return false; - } - if (type <= 0 && StringUtils.isBlank(log)) { - return false; - } - - boolean status = false; - - ContentValues values = new ContentValues(); - values.put("geocode", geocode); - values.put("updated", System.currentTimeMillis()); - values.put("type", type); - values.put("log", log); - values.put("date", date.getTime()); - - try { - if (hasLogOffline(geocode)) { - final int rows = databaseRW.update(dbTableLogsOffline, values, "geocode = ?", new String[] {geocode}); - - if (rows > 0) { - status = true; - } - } else { - final long id = databaseRW.insert(dbTableLogsOffline, null, values); - - if (id > 0) { - status = true; - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.saveLogOffline: " + e.toString()); - } - - return status; - } - - public cgLog loadLogOffline(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - cgLog log = null; - - Cursor cursor = databaseRO.query( - dbTableLogsOffline, - new String[]{"_id", "type", "log", "date"}, - "geocode = \"" + geocode + "\"", - null, - null, - null, - "_id desc", - "1"); - - if (cursor != null && cursor.getCount() > 0) { - cursor.moveToFirst(); - - log = new cgLog(); - log.id = (int) cursor.getInt(cursor.getColumnIndex("_id")); - log.type = (int) cursor.getInt(cursor.getColumnIndex("type")); - log.log = (String) cursor.getString(cursor.getColumnIndex("log")); - log.date = (long) cursor.getLong(cursor.getColumnIndex("date")); - } - - if (cursor != null) { - cursor.close(); - } - - return log; - } - - public void clearLogOffline(String geocode) { - if (StringUtils.isBlank(geocode)) { - return; - } - - init(); - - databaseRW.delete(dbTableLogsOffline, "geocode = ?", new String[] {geocode}); - } - - public boolean hasLogOffline(String geocode) { - if (StringUtils.isBlank(geocode)) { - return false; - } - - int count = 0; - init(); - try { - final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableLogsOffline + " where geocode = \"" + geocode.toUpperCase() + "\""); - count = (int) countSql.simpleQueryForLong(); - - countSql.close(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.hasLogOffline: " + e.toString()); - } - - return count > 0; - } - - public void saveVisitDate(String geocode) { - if (StringUtils.isBlank(geocode)) { - return; - } - - ContentValues values = new ContentValues(); - values.put("visiteddate", System.currentTimeMillis()); - - try { - databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {geocode}); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgData.saveVisitDate: " + e.toString()); - } - } - - public void clearVisitDate(String geocode) { + } while (cursor.moveToNext()); + } else { + cursor.close(); + return; + } + + cursor.close(); + } + + if (CollectionUtils.isNotEmpty(geocodes)) { + String geocodeList = cgBase.implode(", ", geocodes.toArray()); + databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogs + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogCount + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableLogsOffline + " where geocode in (" + geocodeList + ")"); + databaseRW.execSQL("delete from " + dbTableWaypoints + " where geocode in (" + geocodeList + ") and type <> \"own\""); + databaseRW.execSQL("delete from " + dbTableTrackables + " where geocode in (" + geocodeList + ")"); + + geocodes.clear(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.dropStored: " + e.toString()); + } + } + + public boolean saveLogOffline(String geocode, Date date, int type, String log) { + if (StringUtils.isBlank(geocode)) { + return false; + } + if (type <= 0 && StringUtils.isBlank(log)) { + return false; + } + + boolean status = false; + + ContentValues values = new ContentValues(); + values.put("geocode", geocode); + values.put("updated", System.currentTimeMillis()); + values.put("type", type); + values.put("log", log); + values.put("date", date.getTime()); + + try { + if (hasLogOffline(geocode)) { + final int rows = databaseRW.update(dbTableLogsOffline, values, "geocode = ?", new String[] { geocode }); + + if (rows > 0) { + status = true; + } + } else { + final long id = databaseRW.insert(dbTableLogsOffline, null, values); + + if (id > 0) { + status = true; + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.saveLogOffline: " + e.toString()); + } + + return status; + } + + public cgLog loadLogOffline(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + cgLog log = null; + + Cursor cursor = databaseRO.query( + dbTableLogsOffline, + new String[] { "_id", "type", "log", "date" }, + "geocode = \"" + geocode + "\"", + null, + null, + null, + "_id desc", + "1"); + + if (cursor != null && cursor.getCount() > 0) { + cursor.moveToFirst(); + + log = new cgLog(); + log.id = (int) cursor.getInt(cursor.getColumnIndex("_id")); + log.type = (int) cursor.getInt(cursor.getColumnIndex("type")); + log.log = (String) cursor.getString(cursor.getColumnIndex("log")); + log.date = (long) cursor.getLong(cursor.getColumnIndex("date")); + } + + if (cursor != null) { + cursor.close(); + } + + return log; + } + + public void clearLogOffline(String geocode) { + if (StringUtils.isBlank(geocode)) { + return; + } + + init(); + + databaseRW.delete(dbTableLogsOffline, "geocode = ?", new String[] { geocode }); + } + + public boolean hasLogOffline(String geocode) { + if (StringUtils.isBlank(geocode)) { + return false; + } + + int count = 0; + init(); + try { + final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableLogsOffline + " where geocode = \"" + geocode.toUpperCase() + "\""); + count = (int) countSql.simpleQueryForLong(); + + countSql.close(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.hasLogOffline: " + e.toString()); + } + + return count > 0; + } + + public void saveVisitDate(String geocode) { + if (StringUtils.isBlank(geocode)) { + return; + } + + ContentValues values = new ContentValues(); + values.put("visiteddate", System.currentTimeMillis()); + + try { + databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgData.saveVisitDate: " + e.toString()); + } + } + + public void clearVisitDate(String geocode) { if (StringUtils.isBlank(geocode)) { return; } @@ -3057,32 +3063,32 @@ public class cgData { values.put("visiteddate", 0); try { - databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {geocode}); + databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); } catch (Exception e) { Log.e(cgSettings.tag, "cgData.clearVisitDate: " + e.toString()); } } - public List<cgList> getLists(Resources res) { - init(); + public List<cgList> getLists(Resources res) { + init(); - List<cgList> lists = new ArrayList<cgList>(); + List<cgList> lists = new ArrayList<cgList>(); - lists.add(new cgList(true, 1, res.getString(R.string.list_inbox))); - // lists.add(new cgList(true, 2, res.getString(R.string.list_wpt))); + lists.add(new cgList(true, 1, res.getString(R.string.list_inbox))); + // lists.add(new cgList(true, 2, res.getString(R.string.list_wpt))); - ArrayList<cgList> storedLists = readLists(null, "title COLLATE NOCASE ASC"); - lists.addAll(storedLists); + ArrayList<cgList> storedLists = readLists(null, "title COLLATE NOCASE ASC"); + lists.addAll(storedLists); - return lists; - } + return lists; + } - private ArrayList<cgList> readLists(String selection, String sorting) { - ArrayList<cgList> result = new ArrayList<cgList>(); + private ArrayList<cgList> readLists(String selection, String sorting) { + ArrayList<cgList> result = new ArrayList<cgList>(); try { Cursor cursor = databaseRO.query( dbTableLists, - new String[]{"_id", "title", "updated", "latitude", "longitude"}, + new String[] { "_id", "title", "updated", "latitude", "longitude" }, selection, null, null, @@ -3105,7 +3111,7 @@ public class cgData { list.title = (String) cursor.getString(indexTitle); list.updated = (Long) cursor.getLong(indexUpdated); list.coords = new Geopoint(cursor.getDouble(indexLatitude), - cursor.getDouble(indexLongitude)); + cursor.getDouble(indexLongitude)); result.add(list); } while (cursor.moveToNext()); @@ -3120,122 +3126,122 @@ public class cgData { } public cgList getList(int id, Resources res) { - if (id == 1) { - return new cgList(true, 1, res.getString(R.string.list_inbox)); - } else if (id == 2) { - return new cgList(true, 2, res.getString(R.string.list_wpt)); - } else if (id >= 10) { - init(); - - ArrayList<cgList> lists = readLists("_id = " + (id - 10), null); - if (!lists.isEmpty()) { - return lists.get(0); - } - } - - return null; - } - - public int createList(String name) { - int id = -1; - if (StringUtils.isBlank(name)) { - return id; - } - - init(); - - databaseRW.beginTransaction(); - try { - ContentValues values = new ContentValues(); - values.put("title", name); - values.put("updated", System.currentTimeMillis()); - - id = (int) databaseRW.insert(dbTableLists, null, values); - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - if (id < 0) { - return -1; - } else { - return (id + 10); - } - } - - public boolean removeList(int id) { - boolean status = false; - if (id < 10) { - return status; - } - - init(); - - databaseRW.beginTransaction(); - try { - int cnt = databaseRW.delete(dbTableLists, "_id = " + (id - 10), null); - - if (cnt > 0) { - ContentValues values = new ContentValues(); - values.put("reason", 1); - databaseRW.update(dbTableCaches, values, "reason = " + id, null); - - status = true; - } - - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - - return status; - } - - public void moveToList(String geocode, int listId) { - if (StringUtils.isBlank(geocode) || listId <= 0) { - return; - } - - databaseRW.beginTransaction(); - try { - ContentValues values = new ContentValues(); - values.put("reason", listId); - databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] {geocode}); - - databaseRW.setTransactionSuccessful(); - } finally { - databaseRW.endTransaction(); - } - } - - public synchronized boolean status() { - if (databaseRO == null || databaseRW == null || initialized == false) { - return false; - } - - return true; - } - - public boolean removeSearchedDestination(cgDestination destination) { - boolean success = true; - if (destination == null){ - success = false; - } else{ - init(); - - databaseRW.beginTransaction(); - - try { - databaseRW.delete(dbTableSearchDestionationHistory, "_id = " +destination.getId(), null); - databaseRW.setTransactionSuccessful(); - } catch (Exception e) { - Log.e(cgSettings.tag, "Unable to remove searched destination" ,e); - success = false; - } finally{ - databaseRW.endTransaction(); - } - } - - return success; - } + if (id == 1) { + return new cgList(true, 1, res.getString(R.string.list_inbox)); + } else if (id == 2) { + return new cgList(true, 2, res.getString(R.string.list_wpt)); + } else if (id >= 10) { + init(); + + ArrayList<cgList> lists = readLists("_id = " + (id - 10), null); + if (!lists.isEmpty()) { + return lists.get(0); + } + } + + return null; + } + + public int createList(String name) { + int id = -1; + if (StringUtils.isBlank(name)) { + return id; + } + + init(); + + databaseRW.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put("title", name); + values.put("updated", System.currentTimeMillis()); + + id = (int) databaseRW.insert(dbTableLists, null, values); + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + if (id < 0) { + return -1; + } else { + return (id + 10); + } + } + + public boolean removeList(int id) { + boolean status = false; + if (id < 10) { + return status; + } + + init(); + + databaseRW.beginTransaction(); + try { + int cnt = databaseRW.delete(dbTableLists, "_id = " + (id - 10), null); + + if (cnt > 0) { + ContentValues values = new ContentValues(); + values.put("reason", 1); + databaseRW.update(dbTableCaches, values, "reason = " + id, null); + + status = true; + } + + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + return status; + } + + public void moveToList(String geocode, int listId) { + if (StringUtils.isBlank(geocode) || listId <= 0) { + return; + } + + databaseRW.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put("reason", listId); + databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); + + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + } + + public synchronized boolean status() { + if (databaseRO == null || databaseRW == null || initialized == false) { + return false; + } + + return true; + } + + public boolean removeSearchedDestination(cgDestination destination) { + boolean success = true; + if (destination == null) { + success = false; + } else { + init(); + + databaseRW.beginTransaction(); + + try { + databaseRW.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null); + databaseRW.setTransactionSuccessful(); + } catch (Exception e) { + Log.e(cgSettings.tag, "Unable to remove searched destination", e); + success = false; + } finally { + databaseRW.endTransaction(); + } + } + + return success; + } } diff --git a/src/cgeo/geocaching/cgDestination.java b/src/cgeo/geocaching/cgDestination.java index d2b2428..96beec7 100644 --- a/src/cgeo/geocaching/cgDestination.java +++ b/src/cgeo/geocaching/cgDestination.java @@ -4,70 +4,69 @@ import cgeo.geocaching.geopoint.Geopoint; public class cgDestination { - private long id; - - private long date; - - private Geopoint coords; - - public cgDestination() { - } - - public cgDestination(long id, long date, final Geopoint coords) { - super(); - this.id = id; - this.date = date; - this.coords = coords; - } - - public long getDate() { - return date; - } - - public void setDate(long date) { - this.date = date; - } - - public Geopoint getCoords() { - return coords; - } - - public void setCoords(final Geopoint coords) { - this.coords = coords; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(coords.getLatitude()); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(coords.getLongitude()); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof cgDestination)) { - return false; - } - cgDestination other = (cgDestination) obj; - return coords.isEqualTo(other.coords); - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - + private long id; + + private long date; + + private Geopoint coords; + + public cgDestination() { + } + + public cgDestination(long id, long date, final Geopoint coords) { + super(); + this.id = id; + this.date = date; + this.coords = coords; + } + + public long getDate() { + return date; + } + + public void setDate(long date) { + this.date = date; + } + + public Geopoint getCoords() { + return coords; + } + + public void setCoords(final Geopoint coords) { + this.coords = coords; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(coords.getLatitude()); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(coords.getLongitude()); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof cgDestination)) { + return false; + } + cgDestination other = (cgDestination) obj; + return coords.isEqualTo(other.coords); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } } diff --git a/src/cgeo/geocaching/cgDirection.java b/src/cgeo/geocaching/cgDirection.java index abc4175..c1c1f68 100644 --- a/src/cgeo/geocaching/cgDirection.java +++ b/src/cgeo/geocaching/cgDirection.java @@ -1,73 +1,75 @@ package cgeo.geocaching;
+import cgeo.geocaching.compatibility.Compatibility;
+
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import cgeo.geocaching.compatibility.Compatibility;
public class cgDirection {
- private cgDirection dir = null;
- private Context context = null;
- private SensorManager sensorManager = null;
- private cgeoSensorListener sensorListener = null;
- private cgUpdateDir dirUpdate = null;
+ private cgDirection dir = null;
+ private Context context = null;
+ private SensorManager sensorManager = null;
+ private cgeoSensorListener sensorListener = null;
+ private cgUpdateDir dirUpdate = null;
- public Float directionNow = null;
+ public Float directionNow = null;
- public cgDirection(Context contextIn, cgUpdateDir dirUpdateIn) {
- context = contextIn;
- dirUpdate = dirUpdateIn;
- sensorListener = new cgeoSensorListener();
- }
+ public cgDirection(Context contextIn, cgUpdateDir dirUpdateIn) {
+ context = contextIn;
+ dirUpdate = dirUpdateIn;
+ sensorListener = new cgeoSensorListener();
+ }
- public void initDir() {
- dir = this;
+ public void initDir() {
+ dir = this;
- if (sensorManager == null) {
- sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
- }
- sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
- }
+ if (sensorManager == null) {
+ sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ }
+ sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
+ }
- public void closeDir() {
- if (sensorManager != null && sensorListener != null) {
- sensorManager.unregisterListener(sensorListener);
- }
- }
+ public void closeDir() {
+ if (sensorManager != null && sensorListener != null) {
+ sensorManager.unregisterListener(sensorListener);
+ }
+ }
- public void replaceUpdate(cgUpdateDir dirUpdateIn) {
- dirUpdate = dirUpdateIn;
+ public void replaceUpdate(cgUpdateDir dirUpdateIn) {
+ dirUpdate = dirUpdateIn;
- if (dirUpdate != null && directionNow != null) {
- dirUpdate.updateDir(dir);
- }
- }
+ if (dirUpdate != null && directionNow != null) {
+ dirUpdate.updateDir(dir);
+ }
+ }
- private class cgeoSensorListener implements SensorEventListener {
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- /* There is a bug in Android, which appearently causes this method to be called every
- * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging
- * this event leads to the log being flooded with multiple entries _per second_,
- * which I experienced when running cgeo in a building (with GPS and network being
- * unreliable).
- *
- * See for example https://code.google.com/p/android/issues/detail?id=14792
- */
+ private class cgeoSensorListener implements SensorEventListener {
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ /*
+ * There is a bug in Android, which appearently causes this method to be called every
+ * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging
+ * this event leads to the log being flooded with multiple entries _per second_,
+ * which I experienced when running cgeo in a building (with GPS and network being
+ * unreliable).
+ *
+ * See for example https://code.google.com/p/android/issues/detail?id=14792
+ */
- //Log.i(cgSettings.tag, "Compass' accuracy is low (" + accuracy + ")");
- }
+ //Log.i(cgSettings.tag, "Compass' accuracy is low (" + accuracy + ")");
+ }
- @Override
- public void onSensorChanged(SensorEvent event) {
- directionNow = Compatibility.getDirectionNow(event.values[0], (Activity)context);
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ directionNow = Compatibility.getDirectionNow(event.values[0], (Activity) context);
- if (dirUpdate != null && directionNow != null) {
- dirUpdate.updateDir(dir);
- }
- }
- }
+ if (dirUpdate != null && directionNow != null) {
+ dirUpdate.updateDir(dir);
+ }
+ }
+ }
}
diff --git a/src/cgeo/geocaching/cgDirectionImg.java b/src/cgeo/geocaching/cgDirectionImg.java index 1f513d3..1aa7795 100644 --- a/src/cgeo/geocaching/cgDirectionImg.java +++ b/src/cgeo/geocaching/cgDirectionImg.java @@ -1,10 +1,5 @@ package cgeo.geocaching; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -15,80 +10,86 @@ import org.apache.http.impl.client.DefaultHttpClient; import android.util.Log; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + public class cgDirectionImg { - public static void getDrawable(String geocode, String code) { - String dirName; - String fileName; - - if (StringUtils.isBlank(geocode) || StringUtils.isBlank(code)) { - return; - } - - if (StringUtils.isNotBlank(geocode)) { - dirName = cgSettings.getStorage() + geocode + "/"; - fileName = cgSettings.getStorage() + geocode + "/direction.png"; - } else { - return; - } - - File dir = null; - dir = new File(cgSettings.getStorage()); - if (dir.exists() == false) { - dir.mkdirs(); - } - dir = new File(dirName); - if (dir.exists() == false) { - dir.mkdirs(); - } - dir = null; - - HttpClient client = null; - HttpGet getMethod = null; - HttpResponse httpResponse = null; - HttpEntity entity = null; - BufferedHttpEntity bufferedEntity = null; - - boolean ok = false; - - for (int i = 0; i < 3; i ++) { - if (i > 0) Log.w(cgSettings.tag, "cgDirectionImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); - - try { - client = new DefaultHttpClient(); - getMethod = new HttpGet("http://www.geocaching.com/ImgGen/seek/CacheDir.ashx?k=" + code); - httpResponse = client.execute(getMethod); - entity = httpResponse.getEntity(); - bufferedEntity = new BufferedHttpEntity(entity); - - Log.i(cgSettings.tag, "[" + entity.getContentLength() + "B] Downloading direction image " + code); - - if (bufferedEntity != null) { - InputStream is = (InputStream)bufferedEntity.getContent(); - FileOutputStream fos = new FileOutputStream(fileName); - - try { - byte[] buffer = new byte[4096]; - int l; - while ((l = is.read(buffer)) != -1) { - fos.write(buffer, 0, l); - } - ok = true; - fos.flush(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgDirectionImg.getDrawable (saving to cache): " + e.toString()); - } finally { - is.close(); - fos.close(); - } - } - - if (ok) { - break; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgDirectionImg.getDrawable (downloading from web): " + e.toString()); - } - } - } + public static void getDrawable(String geocode, String code) { + String dirName; + String fileName; + + if (StringUtils.isBlank(geocode) || StringUtils.isBlank(code)) { + return; + } + + if (StringUtils.isNotBlank(geocode)) { + dirName = cgSettings.getStorage() + geocode + "/"; + fileName = cgSettings.getStorage() + geocode + "/direction.png"; + } else { + return; + } + + File dir = null; + dir = new File(cgSettings.getStorage()); + if (dir.exists() == false) { + dir.mkdirs(); + } + dir = new File(dirName); + if (dir.exists() == false) { + dir.mkdirs(); + } + dir = null; + + HttpClient client = null; + HttpGet getMethod = null; + HttpResponse httpResponse = null; + HttpEntity entity = null; + BufferedHttpEntity bufferedEntity = null; + + boolean ok = false; + + for (int i = 0; i < 3; i++) { + if (i > 0) + Log.w(cgSettings.tag, "cgDirectionImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); + + try { + client = new DefaultHttpClient(); + getMethod = new HttpGet("http://www.geocaching.com/ImgGen/seek/CacheDir.ashx?k=" + code); + httpResponse = client.execute(getMethod); + entity = httpResponse.getEntity(); + bufferedEntity = new BufferedHttpEntity(entity); + + Log.i(cgSettings.tag, "[" + entity.getContentLength() + "B] Downloading direction image " + code); + + if (bufferedEntity != null) { + InputStream is = (InputStream) bufferedEntity.getContent(); + FileOutputStream fos = new FileOutputStream(fileName); + + try { + byte[] buffer = new byte[4096]; + int l; + while ((l = is.read(buffer)) != -1) { + fos.write(buffer, 0, l); + } + ok = true; + fos.flush(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgDirectionImg.getDrawable (saving to cache): " + e.toString()); + } finally { + is.close(); + fos.close(); + } + } + + if (ok) { + break; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgDirectionImg.getDrawable (downloading from web): " + e.toString()); + } + } + } } diff --git a/src/cgeo/geocaching/cgDistanceView.java b/src/cgeo/geocaching/cgDistanceView.java index 9030bbb..ebdfe78 100644 --- a/src/cgeo/geocaching/cgDistanceView.java +++ b/src/cgeo/geocaching/cgDistanceView.java @@ -1,43 +1,44 @@ package cgeo.geocaching; +import cgeo.geocaching.geopoint.Geopoint; + import android.content.Context; import android.util.AttributeSet; import android.widget.TextView; -import cgeo.geocaching.geopoint.Geopoint; public class cgDistanceView extends TextView { - private cgBase base = null; - private Geopoint cacheCoords = null; - - public cgDistanceView(Context context) { - super(context); - } - - public cgDistanceView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public cgDistanceView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public void setContent(cgBase baseIn, final Geopoint cacheCoordsIn) { - base = baseIn; - cacheCoords = cacheCoordsIn; - } - - public void update(final Geopoint coords) { - if (cacheCoords == null || coords == null || base == null) { - return; - } - setText(base.getHumanDistance(coords.distanceTo(cacheCoords))); - } - - public void setDistance(Float distance) { - setText("~" + base.getHumanDistance(distance)); - } - - public void clear() { - setText(null); - } + private cgBase base = null; + private Geopoint cacheCoords = null; + + public cgDistanceView(Context context) { + super(context); + } + + public cgDistanceView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public cgDistanceView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setContent(cgBase baseIn, final Geopoint cacheCoordsIn) { + base = baseIn; + cacheCoords = cacheCoordsIn; + } + + public void update(final Geopoint coords) { + if (cacheCoords == null || coords == null || base == null) { + return; + } + setText(base.getHumanDistance(coords.distanceTo(cacheCoords))); + } + + public void setDistance(Float distance) { + setText("~" + base.getHumanDistance(distance)); + } + + public void clear() { + setText(null); + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgGPXListAdapter.java b/src/cgeo/geocaching/cgGPXListAdapter.java index 0c2b10d..df1933c 100644 --- a/src/cgeo/geocaching/cgGPXListAdapter.java +++ b/src/cgeo/geocaching/cgGPXListAdapter.java @@ -1,8 +1,5 @@ package cgeo.geocaching; -import java.io.File; -import java.util.List; - import android.app.Activity; import android.util.Log; import android.view.LayoutInflater; @@ -11,64 +8,68 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; +import java.io.File; +import java.util.List; + public class cgGPXListAdapter extends ArrayAdapter<File> { - private cgGPXView holder = null; - private cgeogpxes parent = null; - private LayoutInflater inflater = null; + private cgGPXView holder = null; + private cgeogpxes parent = null; + private LayoutInflater inflater = null; - public cgGPXListAdapter(cgeogpxes parentIn, cgSettings settingsIn, List<File> listIn) { - super(parentIn, 0, listIn); + public cgGPXListAdapter(cgeogpxes parentIn, cgSettings settingsIn, List<File> listIn) { + super(parentIn, 0, listIn); - parent = parentIn; - } + parent = parentIn; + } @Override public View getView(int position, View rowView, ViewGroup parent) { - if (inflater == null) inflater = ((Activity)getContext()).getLayoutInflater(); - - if (position > getCount()) { - Log.w(cgSettings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position); - return null; - } - - File file = getItem(position); + if (inflater == null) + inflater = ((Activity) getContext()).getLayoutInflater(); - if (rowView == null) { - rowView = (View)inflater.inflate(R.layout.gpx_item, null); + if (position > getCount()) { + Log.w(cgSettings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position); + return null; + } - holder = new cgGPXView(); - holder.filepath = (TextView)rowView.findViewById(R.id.filepath); - holder.filename = (TextView)rowView.findViewById(R.id.filename); + File file = getItem(position); - rowView.setTag(holder); - } else { - holder = (cgGPXView)rowView.getTag(); - } + if (rowView == null) { + rowView = (View) inflater.inflate(R.layout.gpx_item, null); - final touchListener touchLst = new touchListener(file); - rowView.setOnClickListener(touchLst); + holder = new cgGPXView(); + holder.filepath = (TextView) rowView.findViewById(R.id.filepath); + holder.filename = (TextView) rowView.findViewById(R.id.filename); - holder.filepath.setText(file.getParent()); - holder.filename.setText(file.getName()); + rowView.setTag(holder); + } else { + holder = (cgGPXView) rowView.getTag(); + } - return rowView; - } + final touchListener touchLst = new touchListener(file); + rowView.setOnClickListener(touchLst); - @Override - public void notifyDataSetChanged() { - super.notifyDataSetChanged(); - } + holder.filepath.setText(file.getParent()); + holder.filename.setText(file.getName()); - private class touchListener implements View.OnClickListener { - private File file = null; + return rowView; + } - public touchListener(File fileIn) { - file = fileIn; - } - - // tap on item - public void onClick(View view) { - parent.loadGPX(file); - } - } + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + } + + private class touchListener implements View.OnClickListener { + private File file = null; + + public touchListener(File fileIn) { + file = fileIn; + } + + // tap on item + public void onClick(View view) { + parent.loadGPX(file); + } + } } diff --git a/src/cgeo/geocaching/cgGPXView.java b/src/cgeo/geocaching/cgGPXView.java index f68b477..a731f70 100644 --- a/src/cgeo/geocaching/cgGPXView.java +++ b/src/cgeo/geocaching/cgGPXView.java @@ -3,7 +3,7 @@ package cgeo.geocaching; import android.widget.TextView; public class cgGPXView { - // layouts & views - public TextView filepath; - public TextView filename; + // layouts & views + public TextView filepath; + public TextView filename; } diff --git a/src/cgeo/geocaching/cgGeo.java b/src/cgeo/geocaching/cgGeo.java index bb9dffa..633ab2f 100644 --- a/src/cgeo/geocaching/cgGeo.java +++ b/src/cgeo/geocaching/cgGeo.java @@ -1,9 +1,6 @@ package cgeo.geocaching; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; @@ -16,424 +13,429 @@ import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; public class cgGeo { - private Context context = null; - private cgeoapplication app = null; - private LocationManager geoManager = null; - private cgUpdateLoc geoUpdate = null; - private cgBase base = null; - private cgSettings settings = null; - private SharedPreferences prefs = null; - private cgeoGeoListener geoNetListener = null; - private cgeoGeoListener geoGpsListener = null; - private cgeoGpsStatusListener geoGpsStatusListener = null; - private Integer time = 0; - private Integer distance = 0; - private Location locGps = null; - private Location locNet = null; - private long locGpsLast = 0L; - private boolean g4cRunning = false; - private Geopoint lastGo4cacheCoords = null; - public Location location = null; - public int gps = -1; - public Geopoint coordsNow = null; - public Geopoint coordsBefore = null; - public Double altitudeNow = null; - public Float bearingNow = null; - public Float speedNow = null; - public Float accuracyNow = null; - public Integer satellitesVisible = null; - public Integer satellitesFixed = null; - public double distanceNow = 0d; - - public cgGeo(Context contextIn, cgeoapplication appIn, cgUpdateLoc geoUpdateIn, cgBase baseIn, cgSettings settingsIn, int timeIn, int distanceIn) { - context = contextIn; - app = appIn; - geoUpdate = geoUpdateIn; - base = baseIn; - settings = settingsIn; - time = timeIn; - distance = distanceIn; - - if (prefs == null) { - prefs = context.getSharedPreferences(cgSettings.preferences, 0); - } - distanceNow = prefs.getFloat("dst", 0f); - if (Double.isNaN(distanceNow)) { - distanceNow = 0d; - } - if (distanceNow == 0f) { - final SharedPreferences.Editor prefsEdit = context.getSharedPreferences(cgSettings.preferences, 0).edit(); - if (prefsEdit != null) { - prefsEdit.putLong("dst-since", System.currentTimeMillis()); - prefsEdit.commit(); - } - } - - geoNetListener = new cgeoGeoListener(); - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); - - geoGpsListener = new cgeoGeoListener(); - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); - - geoGpsStatusListener = new cgeoGpsStatusListener(); - } - - public void initGeo() { - location = null; - gps = -1; - coordsNow = null; - altitudeNow = null; - bearingNow = null; - speedNow = null; - accuracyNow = null; - satellitesVisible = 0; - satellitesFixed = 0; - - if (geoManager == null) { - geoManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); - } - - lastLoc(); - - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); - geoManager.addGpsStatusListener(geoGpsStatusListener); - - try { - geoManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, distance, geoNetListener); - } catch (Exception e) { - Log.e(cgSettings.tag, "There is no NETWORK location provider"); - } - - try { - geoManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, distance, geoGpsListener); - } catch (Exception e) { - Log.e(cgSettings.tag, "There is no GPS location provider"); - } - } - - public void closeGeo() { - if (geoManager != null && geoNetListener != null) { - geoManager.removeUpdates(geoNetListener); - } - if (geoManager != null && geoGpsListener != null) { - geoManager.removeUpdates(geoGpsListener); - } - if (geoManager != null) { - geoManager.removeGpsStatusListener(geoGpsStatusListener); - } - - final SharedPreferences.Editor prefsEdit = context.getSharedPreferences(cgSettings.preferences, 0).edit(); - if (prefsEdit != null && Double.isNaN(distanceNow) == false) { - prefsEdit.putFloat("dst", (float) distanceNow); - prefsEdit.commit(); - } - } - - public void replaceUpdate(cgUpdateLoc geoUpdateIn) { - geoUpdate = geoUpdateIn; - - if (geoUpdate != null) { - geoUpdate.updateLoc(this); - } - } - - public class cgeoGeoListener implements LocationListener { - - public String active = null; - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - // nothing - } - - @Override - public void onLocationChanged(Location location) { - if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { - locGps = location; - locGpsLast = System.currentTimeMillis(); - } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { - locNet = location; - } - - selectBest(location.getProvider()); - } - - @Override - public void onProviderDisabled(String provider) { - if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoManager != null && geoNetListener != null) { - geoManager.removeUpdates(geoNetListener); - } - } else if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoManager != null && geoGpsListener != null) { - geoManager.removeUpdates(geoGpsListener); - } - } - } - - @Override - public void onProviderEnabled(String provider) { - if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoNetListener == null) { - geoNetListener = new cgeoGeoListener(); - } - geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); - } else if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoGpsListener == null) { - geoGpsListener = new cgeoGeoListener(); - } - geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); - } - } - - public void setProvider(String provider) { - if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (geoManager != null && geoManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - active = provider; - } else { - active = null; - } - } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - if (geoManager != null && geoManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - active = provider; - } else { - active = null; - } - } - } - } - - public class cgeoGpsStatusListener implements GpsStatus.Listener { - - @Override - public void onGpsStatusChanged(int event) { - if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { - GpsStatus status = geoManager.getGpsStatus(null); - Iterator<GpsSatellite> statusIterator = status.getSatellites().iterator(); - - int satellites = 0; - int fixed = 0; - - while (statusIterator.hasNext()) { - GpsSatellite sat = statusIterator.next(); - if (sat.usedInFix()) { - fixed++; - } - satellites++; - - /* satellite signal strength - if (sat.usedInFix()) { - Log.d(cgSettings.tag, "Sat #" + satellites + ": " + sat.getSnr() + " FIX"); - } else { - Log.d(cgSettings.tag, "Sat #" + satellites + ": " + sat.getSnr()); - } - */ - } - - boolean changed = false; - if (satellitesVisible == null || satellites != satellitesVisible) { - satellitesVisible = satellites; - changed = true; - } - if (satellitesFixed == null || fixed != satellitesFixed) { - satellitesFixed = fixed; - changed = true; - } - - if (changed) { - selectBest(null); - } - } - } - } - - private void selectBest(String initProvider) { - if (locNet == null && locGps != null) { // we have only GPS - assign(locGps); - return; - } - - if (locNet != null && locGps == null) { // we have only NET - assign(locNet); - return; - } - - if (satellitesFixed > 0) { // GPS seems to be fixed - assign(locGps); - return; - } - - if (initProvider != null && initProvider.equals(LocationManager.GPS_PROVIDER)) { // we have new location from GPS - assign(locGps); - return; - } - - if (locGpsLast > (System.currentTimeMillis() - 30 * 1000)) { // GPS was working in last 30 seconds - assign(locGps); - return; - } - - assign(locNet); // nothing else, using NET - } - - private void assign(final Geopoint coords) { - if (coords == null) { - return; - } - - gps = -1; - coordsNow = coords; - altitudeNow = null; - bearingNow = 0f; - speedNow = 0f; - accuracyNow = 999f; - - if (geoUpdate != null) { - geoUpdate.updateLoc(this); - } - } - - private void assign(Location loc) { - if (loc == null) { - gps = -1; - return; - } - - location = loc; - - String provider = location.getProvider(); - if (provider.equals(LocationManager.GPS_PROVIDER)) { - gps = 1; - } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { - gps = 0; - } else if (provider.equals("last")) { - gps = -1; - } - - coordsNow = new Geopoint(location.getLatitude(), location.getLongitude()); - app.setLastLoc(coordsNow); - - if (location.hasAltitude() && gps != -1) { - altitudeNow = location.getAltitude() + settings.altCorrection; - } else { - altitudeNow = null; - } - if (location.hasBearing() && gps != -1) { - bearingNow = location.getBearing(); - } else { - bearingNow = 0f; - } - if (location.hasSpeed() && gps != -1) { - speedNow = location.getSpeed(); - } else { - speedNow = 0f; - } - if (location.hasAccuracy() && gps != -1) { - accuracyNow = location.getAccuracy(); - } else { - accuracyNow = 999f; - } - - if (gps == 1) { - // save travelled distance only when location is from GPS - if (coordsBefore != null && coordsNow != null) { - final float dst = coordsBefore.distanceTo(coordsNow); - - if (dst > 0.005) { - distanceNow += dst; - - coordsBefore = coordsNow; - } - } else if (coordsBefore == null) { // values aren't initialized - coordsBefore = coordsNow; - } - } - - if (geoUpdate != null) { - geoUpdate.updateLoc(this); - } - - if (gps > -1) { - (new publishLoc()).start(); - } - } - - private class publishLoc extends Thread { - - private publishLoc() { - setPriority(Thread.MIN_PRIORITY); - } - - @Override - public void run() { - if (g4cRunning) { - return; - } - - if (settings.publicLoc == 1 && (lastGo4cacheCoords == null || coordsNow.distanceTo(lastGo4cacheCoords) > 0.75)) { - g4cRunning = true; - - final String host = "api.go4cache.com"; - final String path = "/"; - final String method = "POST"; - String action = null; - if (app != null) { - action = app.getAction(); - } else { - action = ""; - } - - final String username = settings.getUsername(); - if (username != null) { - final Map<String, String> params = new HashMap<String, String>(); - final String latStr = String.format((Locale) null, "%.6f", coordsNow.getLatitude()); - final String lonStr = String.format((Locale) null, "%.6f", coordsNow.getLongitude()); - params.put("u", username); - params.put("lt", latStr); - params.put("ln", lonStr); - params.put("a", action); - params.put("s", (cgBase.sha1(username + "|" + latStr + "|" + lonStr + "|" + action + "|" + cgBase.md5("carnero: developing your dreams"))).toLowerCase()); - if (base.version != null) { - params.put("v", base.version); - } - final String res = base.request(false, host, path, method, params, false, false, false).getData(); - - if (StringUtils.isNotBlank(res)) { - lastGo4cacheCoords = coordsNow; - } - } - } - - g4cRunning = false; - } - } - - public void lastLoc() { - assign(app.getLastCoords()); - - Location lastGps = geoManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); - - if (lastGps != null) { - lastGps.setProvider("last"); - assign(lastGps); - - Log.i(cgSettings.tag, "Using last location from GPS"); - return; - } - - Location lastGsm = geoManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - - if (lastGsm != null) { - lastGsm.setProvider("last"); - assign(lastGsm); - - Log.i(cgSettings.tag, "Using last location from NETWORK"); - return; - } - } + private Context context = null; + private cgeoapplication app = null; + private LocationManager geoManager = null; + private cgUpdateLoc geoUpdate = null; + private cgBase base = null; + private cgSettings settings = null; + private SharedPreferences prefs = null; + private cgeoGeoListener geoNetListener = null; + private cgeoGeoListener geoGpsListener = null; + private cgeoGpsStatusListener geoGpsStatusListener = null; + private Integer time = 0; + private Integer distance = 0; + private Location locGps = null; + private Location locNet = null; + private long locGpsLast = 0L; + private boolean g4cRunning = false; + private Geopoint lastGo4cacheCoords = null; + public Location location = null; + public int gps = -1; + public Geopoint coordsNow = null; + public Geopoint coordsBefore = null; + public Double altitudeNow = null; + public Float bearingNow = null; + public Float speedNow = null; + public Float accuracyNow = null; + public Integer satellitesVisible = null; + public Integer satellitesFixed = null; + public double distanceNow = 0d; + + public cgGeo(Context contextIn, cgeoapplication appIn, cgUpdateLoc geoUpdateIn, cgBase baseIn, cgSettings settingsIn, int timeIn, int distanceIn) { + context = contextIn; + app = appIn; + geoUpdate = geoUpdateIn; + base = baseIn; + settings = settingsIn; + time = timeIn; + distance = distanceIn; + + if (prefs == null) { + prefs = context.getSharedPreferences(cgSettings.preferences, 0); + } + distanceNow = prefs.getFloat("dst", 0f); + if (Double.isNaN(distanceNow)) { + distanceNow = 0d; + } + if (distanceNow == 0f) { + final SharedPreferences.Editor prefsEdit = context.getSharedPreferences(cgSettings.preferences, 0).edit(); + if (prefsEdit != null) { + prefsEdit.putLong("dst-since", System.currentTimeMillis()); + prefsEdit.commit(); + } + } + + geoNetListener = new cgeoGeoListener(); + geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); + + geoGpsListener = new cgeoGeoListener(); + geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); + + geoGpsStatusListener = new cgeoGpsStatusListener(); + } + + public void initGeo() { + location = null; + gps = -1; + coordsNow = null; + altitudeNow = null; + bearingNow = null; + speedNow = null; + accuracyNow = null; + satellitesVisible = 0; + satellitesFixed = 0; + + if (geoManager == null) { + geoManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + } + + lastLoc(); + + geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); + geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); + geoManager.addGpsStatusListener(geoGpsStatusListener); + + try { + geoManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, distance, geoNetListener); + } catch (Exception e) { + Log.e(cgSettings.tag, "There is no NETWORK location provider"); + } + + try { + geoManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, distance, geoGpsListener); + } catch (Exception e) { + Log.e(cgSettings.tag, "There is no GPS location provider"); + } + } + + public void closeGeo() { + if (geoManager != null && geoNetListener != null) { + geoManager.removeUpdates(geoNetListener); + } + if (geoManager != null && geoGpsListener != null) { + geoManager.removeUpdates(geoGpsListener); + } + if (geoManager != null) { + geoManager.removeGpsStatusListener(geoGpsStatusListener); + } + + final SharedPreferences.Editor prefsEdit = context.getSharedPreferences(cgSettings.preferences, 0).edit(); + if (prefsEdit != null && Double.isNaN(distanceNow) == false) { + prefsEdit.putFloat("dst", (float) distanceNow); + prefsEdit.commit(); + } + } + + public void replaceUpdate(cgUpdateLoc geoUpdateIn) { + geoUpdate = geoUpdateIn; + + if (geoUpdate != null) { + geoUpdate.updateLoc(this); + } + } + + public class cgeoGeoListener implements LocationListener { + + public String active = null; + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // nothing + } + + @Override + public void onLocationChanged(Location location) { + if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { + locGps = location; + locGpsLast = System.currentTimeMillis(); + } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { + locNet = location; + } + + selectBest(location.getProvider()); + } + + @Override + public void onProviderDisabled(String provider) { + if (provider.equals(LocationManager.NETWORK_PROVIDER)) { + if (geoManager != null && geoNetListener != null) { + geoManager.removeUpdates(geoNetListener); + } + } else if (provider.equals(LocationManager.GPS_PROVIDER)) { + if (geoManager != null && geoGpsListener != null) { + geoManager.removeUpdates(geoGpsListener); + } + } + } + + @Override + public void onProviderEnabled(String provider) { + if (provider.equals(LocationManager.NETWORK_PROVIDER)) { + if (geoNetListener == null) { + geoNetListener = new cgeoGeoListener(); + } + geoNetListener.setProvider(LocationManager.NETWORK_PROVIDER); + } else if (provider.equals(LocationManager.GPS_PROVIDER)) { + if (geoGpsListener == null) { + geoGpsListener = new cgeoGeoListener(); + } + geoGpsListener.setProvider(LocationManager.GPS_PROVIDER); + } + } + + public void setProvider(String provider) { + if (provider.equals(LocationManager.GPS_PROVIDER)) { + if (geoManager != null && geoManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + active = provider; + } else { + active = null; + } + } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { + if (geoManager != null && geoManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + active = provider; + } else { + active = null; + } + } + } + } + + public class cgeoGpsStatusListener implements GpsStatus.Listener { + + @Override + public void onGpsStatusChanged(int event) { + if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { + GpsStatus status = geoManager.getGpsStatus(null); + Iterator<GpsSatellite> statusIterator = status.getSatellites().iterator(); + + int satellites = 0; + int fixed = 0; + + while (statusIterator.hasNext()) { + GpsSatellite sat = statusIterator.next(); + if (sat.usedInFix()) { + fixed++; + } + satellites++; + + /* + * satellite signal strength + * if (sat.usedInFix()) { + * Log.d(cgSettings.tag, "Sat #" + satellites + ": " + sat.getSnr() + " FIX"); + * } else { + * Log.d(cgSettings.tag, "Sat #" + satellites + ": " + sat.getSnr()); + * } + */ + } + + boolean changed = false; + if (satellitesVisible == null || satellites != satellitesVisible) { + satellitesVisible = satellites; + changed = true; + } + if (satellitesFixed == null || fixed != satellitesFixed) { + satellitesFixed = fixed; + changed = true; + } + + if (changed) { + selectBest(null); + } + } + } + } + + private void selectBest(String initProvider) { + if (locNet == null && locGps != null) { // we have only GPS + assign(locGps); + return; + } + + if (locNet != null && locGps == null) { // we have only NET + assign(locNet); + return; + } + + if (satellitesFixed > 0) { // GPS seems to be fixed + assign(locGps); + return; + } + + if (initProvider != null && initProvider.equals(LocationManager.GPS_PROVIDER)) { // we have new location from GPS + assign(locGps); + return; + } + + if (locGpsLast > (System.currentTimeMillis() - 30 * 1000)) { // GPS was working in last 30 seconds + assign(locGps); + return; + } + + assign(locNet); // nothing else, using NET + } + + private void assign(final Geopoint coords) { + if (coords == null) { + return; + } + + gps = -1; + coordsNow = coords; + altitudeNow = null; + bearingNow = 0f; + speedNow = 0f; + accuracyNow = 999f; + + if (geoUpdate != null) { + geoUpdate.updateLoc(this); + } + } + + private void assign(Location loc) { + if (loc == null) { + gps = -1; + return; + } + + location = loc; + + String provider = location.getProvider(); + if (provider.equals(LocationManager.GPS_PROVIDER)) { + gps = 1; + } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) { + gps = 0; + } else if (provider.equals("last")) { + gps = -1; + } + + coordsNow = new Geopoint(location.getLatitude(), location.getLongitude()); + app.setLastLoc(coordsNow); + + if (location.hasAltitude() && gps != -1) { + altitudeNow = location.getAltitude() + settings.altCorrection; + } else { + altitudeNow = null; + } + if (location.hasBearing() && gps != -1) { + bearingNow = location.getBearing(); + } else { + bearingNow = 0f; + } + if (location.hasSpeed() && gps != -1) { + speedNow = location.getSpeed(); + } else { + speedNow = 0f; + } + if (location.hasAccuracy() && gps != -1) { + accuracyNow = location.getAccuracy(); + } else { + accuracyNow = 999f; + } + + if (gps == 1) { + // save travelled distance only when location is from GPS + if (coordsBefore != null && coordsNow != null) { + final float dst = coordsBefore.distanceTo(coordsNow); + + if (dst > 0.005) { + distanceNow += dst; + + coordsBefore = coordsNow; + } + } else if (coordsBefore == null) { // values aren't initialized + coordsBefore = coordsNow; + } + } + + if (geoUpdate != null) { + geoUpdate.updateLoc(this); + } + + if (gps > -1) { + (new publishLoc()).start(); + } + } + + private class publishLoc extends Thread { + + private publishLoc() { + setPriority(Thread.MIN_PRIORITY); + } + + @Override + public void run() { + if (g4cRunning) { + return; + } + + if (settings.publicLoc == 1 && (lastGo4cacheCoords == null || coordsNow.distanceTo(lastGo4cacheCoords) > 0.75)) { + g4cRunning = true; + + final String host = "api.go4cache.com"; + final String path = "/"; + final String method = "POST"; + String action = null; + if (app != null) { + action = app.getAction(); + } else { + action = ""; + } + + final String username = settings.getUsername(); + if (username != null) { + final Map<String, String> params = new HashMap<String, String>(); + final String latStr = String.format((Locale) null, "%.6f", coordsNow.getLatitude()); + final String lonStr = String.format((Locale) null, "%.6f", coordsNow.getLongitude()); + params.put("u", username); + params.put("lt", latStr); + params.put("ln", lonStr); + params.put("a", action); + params.put("s", (cgBase.sha1(username + "|" + latStr + "|" + lonStr + "|" + action + "|" + cgBase.md5("carnero: developing your dreams"))).toLowerCase()); + if (base.version != null) { + params.put("v", base.version); + } + final String res = base.request(false, host, path, method, params, false, false, false).getData(); + + if (StringUtils.isNotBlank(res)) { + lastGo4cacheCoords = coordsNow; + } + } + } + + g4cRunning = false; + } + } + + public void lastLoc() { + assign(app.getLastCoords()); + + Location lastGps = geoManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + + if (lastGps != null) { + lastGps.setProvider("last"); + assign(lastGps); + + Log.i(cgSettings.tag, "Using last location from GPS"); + return; + } + + Location lastGsm = geoManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + + if (lastGsm != null) { + lastGsm.setProvider("last"); + assign(lastGsm); + + Log.i(cgSettings.tag, "Using last location from NETWORK"); + return; + } + } } diff --git a/src/cgeo/geocaching/cgHtmlImg.java b/src/cgeo/geocaching/cgHtmlImg.java index cfb7cab..303fb0e 100644 --- a/src/cgeo/geocaching/cgHtmlImg.java +++ b/src/cgeo/geocaching/cgHtmlImg.java @@ -1,11 +1,5 @@ package cgeo.geocaching; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Date; - import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -26,270 +20,276 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; + public class cgHtmlImg implements Html.ImageGetter { - private Activity activity = null; - private String geocode = null; - private boolean placement = true; - private int reason = 0; - private boolean onlySave = false; - private boolean save = true; - private BitmapFactory.Options bfOptions = new BitmapFactory.Options(); - private Display display = null; - private int maxWidth = 0; - private int maxHeight = 0; - private double ratio = 1.0d; - private int width = 0; - private int height = 0; - - public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn) { - this(activityIn, geocodeIn, placementIn, reasonIn, onlySaveIn, true); - } - - public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn, boolean saveIn) { - activity = activityIn; - geocode = geocodeIn; - placement = placementIn; - reason = reasonIn; - onlySave = onlySaveIn; - save = saveIn; - - bfOptions.inTempStorage = new byte[16 * 1024]; - - display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - maxWidth = display.getWidth() - 25; - maxHeight = display.getHeight() - 25; - } - - @Override - public BitmapDrawable getDrawable(String url) { - Bitmap imagePre = null; - String dirName = null; - String fileName = null; - String fileNameSec = null; - - if (StringUtils.isBlank(url)) { - return null; - } - - final String[] urlParts = url.split("\\."); - String urlExt = null; - if (urlParts.length > 1) { - urlExt = "." + urlParts[(urlParts.length - 1)]; - if (urlExt.length() > 5) { - urlExt = ""; - } - } else { - urlExt = ""; - } - - if (StringUtils.isNotBlank(geocode)) { - dirName = cgSettings.getStorage() + geocode + "/"; - fileName = cgSettings.getStorage() + geocode + "/" + cgBase.md5(url) + urlExt; - fileNameSec = cgSettings.getStorageSec() + geocode + "/" + cgBase.md5(url) + urlExt; - } else { - dirName = cgSettings.getStorage() + "_others/"; - fileName = cgSettings.getStorage() + "_others/" + cgBase.md5(url) + urlExt; - fileNameSec = cgSettings.getStorageSec() + "_others/" + cgBase.md5(url) + urlExt; - } - - File dir = null; - dir = new File(cgSettings.getStorage()); - if (dir.exists() == false) { - dir.mkdirs(); - } - dir = new File(dirName); - if (dir.exists() == false) { - dir.mkdirs(); - } - dir = null; - - // load image from cache - if (onlySave == false) { - try { - final Date now = new Date(); - - final File file = new File(fileName); - if (file.exists()) { - final long imageSize = file.length(); - - // large images will be downscaled on input to save memory - if (imageSize > (6 * 1024 * 1024)) { - bfOptions.inSampleSize = 48; - } else if (imageSize > (4 * 1024 * 1024)) { - bfOptions.inSampleSize = 16; - } else if (imageSize > (2 * 1024 * 1024)) { - bfOptions.inSampleSize = 10; - } else if (imageSize > (1 * 1024 * 1024)) { - bfOptions.inSampleSize = 6; - } else if (imageSize > (0.5 * 1024 * 1024)) { - bfOptions.inSampleSize = 2; - } - - if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) { - imagePre = BitmapFactory.decodeFile(fileName, bfOptions); - } - } - - if (imagePre == null) { - final File fileSec = new File(fileNameSec); - if (fileSec.exists()) { - final long imageSize = fileSec.length(); - - // large images will be downscaled on input to save memory - if (imageSize > (6 * 1024 * 1024)) { - bfOptions.inSampleSize = 48; - } else if (imageSize > (4 * 1024 * 1024)) { - bfOptions.inSampleSize = 16; - } else if (imageSize > (2 * 1024 * 1024)) { - bfOptions.inSampleSize = 10; - } else if (imageSize > (1 * 1024 * 1024)) { - bfOptions.inSampleSize = 6; - } else if (imageSize > (0.5 * 1024 * 1024)) { - bfOptions.inSampleSize = 2; - } - - if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) { - imagePre = BitmapFactory.decodeFile(fileNameSec, bfOptions); - } - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgHtmlImg.getDrawable (reading cache): " + e.toString()); - } - } - - // download image and save it to the cache - if ((imagePre == null && reason == 0) || onlySave) { - Uri uri = null; - HttpClient client = null; - HttpGet getMethod = null; - HttpResponse httpResponse = null; - HttpEntity entity = null; - BufferedHttpEntity bufferedEntity = null; - - try { - // check if uri is absolute or not, if not attach geocaching.com hostname and scheme - uri = Uri.parse(url); - - if (uri.isAbsolute() == false) { - url = "http://www.geocaching.com" + url; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (parse URL): " + e.toString()); - } - - if (uri != null) { - for (int i = 0; i < 2; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); - } - - try { - client = new DefaultHttpClient(); - getMethod = new HttpGet(url); - httpResponse = client.execute(getMethod); - entity = httpResponse.getEntity(); - bufferedEntity = new BufferedHttpEntity(entity); - - final long imageSize = bufferedEntity.getContentLength(); - - // large images will be downscaled on input to save memory - if (imageSize > (6 * 1024 * 1024)) { - bfOptions.inSampleSize = 48; - } else if (imageSize > (4 * 1024 * 1024)) { - bfOptions.inSampleSize = 16; - } else if (imageSize > (2 * 1024 * 1024)) { - bfOptions.inSampleSize = 10; - } else if (imageSize > (1 * 1024 * 1024)) { - bfOptions.inSampleSize = 6; - } else if (imageSize > (0.5 * 1024 * 1024)) { - bfOptions.inSampleSize = 2; - } - - if (bufferedEntity != null) { - imagePre = BitmapFactory.decodeStream(bufferedEntity.getContent(), null, bfOptions); - } - if (imagePre != null) { - break; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (downloading from web): " + e.toString()); - } - } - } - - if (save) { - try { - // save to memory/SD cache - if (bufferedEntity != null) { - final InputStream is = (InputStream) bufferedEntity.getContent(); - final FileOutputStream fos = new FileOutputStream(fileName); - try { - final byte[] buffer = new byte[4096]; - int l; - while ((l = is.read(buffer)) != -1) { - fos.write(buffer, 0, l); - } - fos.flush(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString()); - } finally { - is.close(); - fos.close(); - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString()); - } - } - - entity = null; - bufferedEntity = null; - } - - if (onlySave) { - return null; - } - - // get image and return - if (imagePre == null) { - Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to obtain image"); - - if (placement == false) { - imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_no_placement); - } else { - imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_not_loaded); - } - } - - final int imgWidth = imagePre.getWidth(); - final int imgHeight = imagePre.getHeight(); - - if (imgWidth > maxWidth || imgHeight > maxHeight) { - if ((maxWidth / imgWidth) > (maxHeight / imgHeight)) { - ratio = (double) maxHeight / (double) imgHeight; - } else { - ratio = (double) maxWidth / (double) imgWidth; - } - - width = (int) Math.ceil(imgWidth * ratio); - height = (int) Math.ceil(imgHeight * ratio); - - try { - imagePre = Bitmap.createScaledBitmap(imagePre, width, height, true); - } catch (Exception e) { - Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to scale image"); - return null; - } - } else { - width = imgWidth; - height = imgHeight; - } - - final BitmapDrawable image = new BitmapDrawable(imagePre); - image.setBounds(new Rect(0, 0, width, height)); - - return image; - } + private Activity activity = null; + private String geocode = null; + private boolean placement = true; + private int reason = 0; + private boolean onlySave = false; + private boolean save = true; + private BitmapFactory.Options bfOptions = new BitmapFactory.Options(); + private Display display = null; + private int maxWidth = 0; + private int maxHeight = 0; + private double ratio = 1.0d; + private int width = 0; + private int height = 0; + + public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn) { + this(activityIn, geocodeIn, placementIn, reasonIn, onlySaveIn, true); + } + + public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn, boolean saveIn) { + activity = activityIn; + geocode = geocodeIn; + placement = placementIn; + reason = reasonIn; + onlySave = onlySaveIn; + save = saveIn; + + bfOptions.inTempStorage = new byte[16 * 1024]; + + display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + maxWidth = display.getWidth() - 25; + maxHeight = display.getHeight() - 25; + } + + @Override + public BitmapDrawable getDrawable(String url) { + Bitmap imagePre = null; + String dirName = null; + String fileName = null; + String fileNameSec = null; + + if (StringUtils.isBlank(url)) { + return null; + } + + final String[] urlParts = url.split("\\."); + String urlExt = null; + if (urlParts.length > 1) { + urlExt = "." + urlParts[(urlParts.length - 1)]; + if (urlExt.length() > 5) { + urlExt = ""; + } + } else { + urlExt = ""; + } + + if (StringUtils.isNotBlank(geocode)) { + dirName = cgSettings.getStorage() + geocode + "/"; + fileName = cgSettings.getStorage() + geocode + "/" + cgBase.md5(url) + urlExt; + fileNameSec = cgSettings.getStorageSec() + geocode + "/" + cgBase.md5(url) + urlExt; + } else { + dirName = cgSettings.getStorage() + "_others/"; + fileName = cgSettings.getStorage() + "_others/" + cgBase.md5(url) + urlExt; + fileNameSec = cgSettings.getStorageSec() + "_others/" + cgBase.md5(url) + urlExt; + } + + File dir = null; + dir = new File(cgSettings.getStorage()); + if (dir.exists() == false) { + dir.mkdirs(); + } + dir = new File(dirName); + if (dir.exists() == false) { + dir.mkdirs(); + } + dir = null; + + // load image from cache + if (onlySave == false) { + try { + final Date now = new Date(); + + final File file = new File(fileName); + if (file.exists()) { + final long imageSize = file.length(); + + // large images will be downscaled on input to save memory + if (imageSize > (6 * 1024 * 1024)) { + bfOptions.inSampleSize = 48; + } else if (imageSize > (4 * 1024 * 1024)) { + bfOptions.inSampleSize = 16; + } else if (imageSize > (2 * 1024 * 1024)) { + bfOptions.inSampleSize = 10; + } else if (imageSize > (1 * 1024 * 1024)) { + bfOptions.inSampleSize = 6; + } else if (imageSize > (0.5 * 1024 * 1024)) { + bfOptions.inSampleSize = 2; + } + + if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) { + imagePre = BitmapFactory.decodeFile(fileName, bfOptions); + } + } + + if (imagePre == null) { + final File fileSec = new File(fileNameSec); + if (fileSec.exists()) { + final long imageSize = fileSec.length(); + + // large images will be downscaled on input to save memory + if (imageSize > (6 * 1024 * 1024)) { + bfOptions.inSampleSize = 48; + } else if (imageSize > (4 * 1024 * 1024)) { + bfOptions.inSampleSize = 16; + } else if (imageSize > (2 * 1024 * 1024)) { + bfOptions.inSampleSize = 10; + } else if (imageSize > (1 * 1024 * 1024)) { + bfOptions.inSampleSize = 6; + } else if (imageSize > (0.5 * 1024 * 1024)) { + bfOptions.inSampleSize = 2; + } + + if (reason > 0 || file.lastModified() > (now.getTime() - (24 * 60 * 60 * 1000))) { + imagePre = BitmapFactory.decodeFile(fileNameSec, bfOptions); + } + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgHtmlImg.getDrawable (reading cache): " + e.toString()); + } + } + + // download image and save it to the cache + if ((imagePre == null && reason == 0) || onlySave) { + Uri uri = null; + HttpClient client = null; + HttpGet getMethod = null; + HttpResponse httpResponse = null; + HttpEntity entity = null; + BufferedHttpEntity bufferedEntity = null; + + try { + // check if uri is absolute or not, if not attach geocaching.com hostname and scheme + uri = Uri.parse(url); + + if (uri.isAbsolute() == false) { + url = "http://www.geocaching.com" + url; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (parse URL): " + e.toString()); + } + + if (uri != null) { + for (int i = 0; i < 2; i++) { + if (i > 0) { + Log.w(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1)); + } + + try { + client = new DefaultHttpClient(); + getMethod = new HttpGet(url); + httpResponse = client.execute(getMethod); + entity = httpResponse.getEntity(); + bufferedEntity = new BufferedHttpEntity(entity); + + final long imageSize = bufferedEntity.getContentLength(); + + // large images will be downscaled on input to save memory + if (imageSize > (6 * 1024 * 1024)) { + bfOptions.inSampleSize = 48; + } else if (imageSize > (4 * 1024 * 1024)) { + bfOptions.inSampleSize = 16; + } else if (imageSize > (2 * 1024 * 1024)) { + bfOptions.inSampleSize = 10; + } else if (imageSize > (1 * 1024 * 1024)) { + bfOptions.inSampleSize = 6; + } else if (imageSize > (0.5 * 1024 * 1024)) { + bfOptions.inSampleSize = 2; + } + + if (bufferedEntity != null) { + imagePre = BitmapFactory.decodeStream(bufferedEntity.getContent(), null, bfOptions); + } + if (imagePre != null) { + break; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (downloading from web): " + e.toString()); + } + } + } + + if (save) { + try { + // save to memory/SD cache + if (bufferedEntity != null) { + final InputStream is = (InputStream) bufferedEntity.getContent(); + final FileOutputStream fos = new FileOutputStream(fileName); + try { + final byte[] buffer = new byte[4096]; + int l; + while ((l = is.read(buffer)) != -1) { + fos.write(buffer, 0, l); + } + fos.flush(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString()); + } finally { + is.close(); + fos.close(); + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgHtmlImg.getDrawable (saving to cache): " + e.toString()); + } + } + + entity = null; + bufferedEntity = null; + } + + if (onlySave) { + return null; + } + + // get image and return + if (imagePre == null) { + Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to obtain image"); + + if (placement == false) { + imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_no_placement); + } else { + imagePre = BitmapFactory.decodeResource(activity.getResources(), R.drawable.image_not_loaded); + } + } + + final int imgWidth = imagePre.getWidth(); + final int imgHeight = imagePre.getHeight(); + + if (imgWidth > maxWidth || imgHeight > maxHeight) { + if ((maxWidth / imgWidth) > (maxHeight / imgHeight)) { + ratio = (double) maxHeight / (double) imgHeight; + } else { + ratio = (double) maxWidth / (double) imgWidth; + } + + width = (int) Math.ceil(imgWidth * ratio); + height = (int) Math.ceil(imgHeight * ratio); + + try { + imagePre = Bitmap.createScaledBitmap(imagePre, width, height, true); + } catch (Exception e) { + Log.d(cgSettings.tag, "cgHtmlImg.getDrawable: Failed to scale image"); + return null; + } + } else { + width = imgWidth; + height = imgHeight; + } + + final BitmapDrawable image = new BitmapDrawable(imagePre); + image.setBounds(new Rect(0, 0, width, height)); + + return image; + } } diff --git a/src/cgeo/geocaching/cgImage.java b/src/cgeo/geocaching/cgImage.java index 260bf15..b5874d6 100644 --- a/src/cgeo/geocaching/cgImage.java +++ b/src/cgeo/geocaching/cgImage.java @@ -1,7 +1,7 @@ package cgeo.geocaching; public class cgImage { - public String url = ""; - public String title = ""; - public String description = ""; + public String url = ""; + public String title = ""; + public String description = ""; } diff --git a/src/cgeo/geocaching/cgList.java b/src/cgeo/geocaching/cgList.java index 6c8ea54..162af76 100644 --- a/src/cgeo/geocaching/cgList.java +++ b/src/cgeo/geocaching/cgList.java @@ -3,19 +3,19 @@ package cgeo.geocaching; import cgeo.geocaching.geopoint.Geopoint; public class cgList { - public boolean def = false; - public int id = 0; - public String title = null; - public Long updated = null; - public Geopoint coords = null; - - public cgList(boolean defIn) { - def = defIn; - } - - public cgList(boolean defIn, int idIn, String titleIn) { - def = defIn; - id = idIn; - title = titleIn; - } + public boolean def = false; + public int id = 0; + public String title = null; + public Long updated = null; + public Geopoint coords = null; + + public cgList(boolean defIn) { + def = defIn; + } + + public cgList(boolean defIn, int idIn, String titleIn) { + def = defIn; + id = idIn; + title = titleIn; + } } diff --git a/src/cgeo/geocaching/cgLog.java b/src/cgeo/geocaching/cgLog.java index ebf5699..7e81897 100644 --- a/src/cgeo/geocaching/cgLog.java +++ b/src/cgeo/geocaching/cgLog.java @@ -3,13 +3,13 @@ package cgeo.geocaching; import java.util.List; public class cgLog { - public int id = 0; - public int type = 4; // note - public String author = ""; - public String log = ""; - public long date = 0; - public int found = -1; - public List<cgImage> logImages = null; - public String cacheName = ""; // used for trackables - public String cacheGuid = ""; // used for trackables + public int id = 0; + public int type = 4; // note + public String author = ""; + public String log = ""; + public long date = 0; + public int found = -1; + public List<cgImage> logImages = null; + public String cacheName = ""; // used for trackables + public String cacheGuid = ""; // used for trackables } diff --git a/src/cgeo/geocaching/cgLogForm.java b/src/cgeo/geocaching/cgLogForm.java index c2274f1..12f894e 100644 --- a/src/cgeo/geocaching/cgLogForm.java +++ b/src/cgeo/geocaching/cgLogForm.java @@ -1,15 +1,15 @@ package cgeo.geocaching; -import java.util.Calendar; - import cgeo.geocaching.activity.AbstractActivity; +import java.util.Calendar; + public class cgLogForm extends AbstractActivity { - public cgLogForm(String helpTopic) { - super(helpTopic); - } + public cgLogForm(String helpTopic) { + super(helpTopic); + } - public void setDate(Calendar dateIn) { - // to be overwritten - } + public void setDate(Calendar dateIn) { + // to be overwritten + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgMapfileListAdapter.java b/src/cgeo/geocaching/cgMapfileListAdapter.java index a7f54c8..c0f8f5b 100644 --- a/src/cgeo/geocaching/cgMapfileListAdapter.java +++ b/src/cgeo/geocaching/cgMapfileListAdapter.java @@ -1,8 +1,5 @@ package cgeo.geocaching; -import java.io.File; -import java.util.List; - import android.app.Activity; import android.graphics.Typeface; import android.util.Log; @@ -12,79 +9,83 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; +import java.io.File; +import java.util.List; + public class cgMapfileListAdapter extends ArrayAdapter<File> { - private cgSelectMapfile parentView; - private LayoutInflater inflater; - private MapfileView holder; + private cgSelectMapfile parentView; + private LayoutInflater inflater; + private MapfileView holder; + + public cgMapfileListAdapter(cgSelectMapfile parentIn, List<File> listIn) { + super(parentIn, 0, listIn); - public cgMapfileListAdapter(cgSelectMapfile parentIn, List<File> listIn) { - super(parentIn, 0, listIn); + parentView = parentIn; + } - parentView = parentIn; - } - @Override public View getView(int position, View rowView, ViewGroup parent) { - if (inflater == null) inflater = ((Activity)getContext()).getLayoutInflater(); - - if (position > getCount()) { - Log.w(cgSettings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position); - return null; - } - - File file = getItem(position); - - if (rowView == null) { - rowView = (View)inflater.inflate(R.layout.mapfile_item, null); - - holder = new MapfileView(); - holder.filepath = (TextView)rowView.findViewById(R.id.mapfilepath); - holder.filename = (TextView)rowView.findViewById(R.id.mapfilename); - - rowView.setTag(holder); - } else { - holder = (MapfileView)rowView.getTag(); - } - - File current = new File(parentView.getCurrentMapfile()); - - if (file.equals(current)) { - holder.filename.setTypeface(holder.filename.getTypeface(), Typeface.BOLD); - } else { - holder.filename.setTypeface(holder.filename.getTypeface(), Typeface.NORMAL); - } - - final touchListener touchLst = new touchListener(file); - rowView.setOnClickListener(touchLst); - - holder.filepath.setText(file.getParent()); - holder.filename.setText(file.getName()); - - return rowView; - } - - @Override - public void notifyDataSetChanged() { - super.notifyDataSetChanged(); - } - - private class touchListener implements View.OnClickListener { - private File file = null; - - public touchListener(File fileIn) { - file = fileIn; - } - - // tap on item - public void onClick(View view) { - parentView.setMapfile(file.toString()); - parentView.close(); - } - } - - private static class MapfileView { - public TextView filepath; - public TextView filename; - } + if (inflater == null) + inflater = ((Activity) getContext()).getLayoutInflater(); + + if (position > getCount()) { + Log.w(cgSettings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position); + return null; + } + + File file = getItem(position); + + if (rowView == null) { + rowView = (View) inflater.inflate(R.layout.mapfile_item, null); + + holder = new MapfileView(); + holder.filepath = (TextView) rowView.findViewById(R.id.mapfilepath); + holder.filename = (TextView) rowView.findViewById(R.id.mapfilename); + + rowView.setTag(holder); + } else { + holder = (MapfileView) rowView.getTag(); + } + + File current = new File(parentView.getCurrentMapfile()); + + if (file.equals(current)) { + holder.filename.setTypeface(holder.filename.getTypeface(), Typeface.BOLD); + } else { + holder.filename.setTypeface(holder.filename.getTypeface(), Typeface.NORMAL); + } + + final touchListener touchLst = new touchListener(file); + rowView.setOnClickListener(touchLst); + + holder.filepath.setText(file.getParent()); + holder.filename.setText(file.getName()); + + return rowView; + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + } + + private class touchListener implements View.OnClickListener { + private File file = null; + + public touchListener(File fileIn) { + file = fileIn; + } + + // tap on item + public void onClick(View view) { + parentView.setMapfile(file.toString()); + parentView.close(); + } + } + + private static class MapfileView { + public TextView filepath; + public TextView filename; + } } diff --git a/src/cgeo/geocaching/cgOAuth.java b/src/cgeo/geocaching/cgOAuth.java index 13a1eb2..29b82d3 100644 --- a/src/cgeo/geocaching/cgOAuth.java +++ b/src/cgeo/geocaching/cgOAuth.java @@ -7,48 +7,52 @@ import java.util.List; import java.util.Map; public class cgOAuth { - public static String signOAuth(String host, String path, String method, boolean https, Map<String, String> params, String token, String tokenSecret) { - String paramsDone = ""; - if (method.equalsIgnoreCase("GET") == false && method.equalsIgnoreCase("POST") == false) { - method = "POST"; - } else { - method = method.toUpperCase(); - } - - if (token == null) token = ""; - if (tokenSecret == null) tokenSecret = ""; - - long currentTime = new Date().getTime(); // miliseconds - currentTime = currentTime / 1000; // seconds - currentTime = (long)Math.floor(currentTime); - - params.put("oauth_consumer_key", cgSettings.keyConsumerPublic); - params.put("oauth_nonce", cgBase.md5(Long.toString(System.currentTimeMillis()))); - params.put("oauth_signature_method", "HMAC-SHA1"); - params.put("oauth_timestamp", Long.toString(currentTime)); - params.put("oauth_token", token); - params.put("oauth_version", "1.0"); - - String[] keys = new String[params.keySet().size()]; - params.keySet().toArray(keys); - Arrays.sort(keys); - - List<String> paramsEncoded = new ArrayList<String>(); - for (String key : keys) { - String value = params.get(key); - paramsEncoded.add(key + "=" + cgBase.urlencode_rfc3986(value)); - } - - String keysPacked; - String requestPacked; - - keysPacked = cgSettings.keyConsumerSecret + "&" + tokenSecret; // both even if empty some of them! - if (https) requestPacked = method + "&" + cgBase.urlencode_rfc3986("https://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); - else requestPacked = method + "&" + cgBase.urlencode_rfc3986("http://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); - paramsEncoded.add("oauth_signature=" + cgBase.urlencode_rfc3986(cgBase.base64Encode(cgBase.hashHmac(requestPacked, keysPacked)))); - - paramsDone = cgBase.implode("&", paramsEncoded.toArray()); - - return paramsDone; - } + public static String signOAuth(String host, String path, String method, boolean https, Map<String, String> params, String token, String tokenSecret) { + String paramsDone = ""; + if (method.equalsIgnoreCase("GET") == false && method.equalsIgnoreCase("POST") == false) { + method = "POST"; + } else { + method = method.toUpperCase(); + } + + if (token == null) + token = ""; + if (tokenSecret == null) + tokenSecret = ""; + + long currentTime = new Date().getTime(); // miliseconds + currentTime = currentTime / 1000; // seconds + currentTime = (long) Math.floor(currentTime); + + params.put("oauth_consumer_key", cgSettings.keyConsumerPublic); + params.put("oauth_nonce", cgBase.md5(Long.toString(System.currentTimeMillis()))); + params.put("oauth_signature_method", "HMAC-SHA1"); + params.put("oauth_timestamp", Long.toString(currentTime)); + params.put("oauth_token", token); + params.put("oauth_version", "1.0"); + + String[] keys = new String[params.keySet().size()]; + params.keySet().toArray(keys); + Arrays.sort(keys); + + List<String> paramsEncoded = new ArrayList<String>(); + for (String key : keys) { + String value = params.get(key); + paramsEncoded.add(key + "=" + cgBase.urlencode_rfc3986(value)); + } + + String keysPacked; + String requestPacked; + + keysPacked = cgSettings.keyConsumerSecret + "&" + tokenSecret; // both even if empty some of them! + if (https) + requestPacked = method + "&" + cgBase.urlencode_rfc3986("https://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); + else + requestPacked = method + "&" + cgBase.urlencode_rfc3986("http://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); + paramsEncoded.add("oauth_signature=" + cgBase.urlencode_rfc3986(cgBase.base64Encode(cgBase.hashHmac(requestPacked, keysPacked)))); + + paramsDone = cgBase.implode("&", paramsEncoded.toArray()); + + return paramsDone; + } } diff --git a/src/cgeo/geocaching/cgRating.java b/src/cgeo/geocaching/cgRating.java index 374ae7c..f0c7a76 100644 --- a/src/cgeo/geocaching/cgRating.java +++ b/src/cgeo/geocaching/cgRating.java @@ -1,7 +1,7 @@ package cgeo.geocaching; public class cgRating { - public Float rating = null; - public Integer votes = null; - public Float myVote = null; + public Float rating = null; + public Integer votes = null; + public Float myVote = null; } diff --git a/src/cgeo/geocaching/cgResponse.java b/src/cgeo/geocaching/cgResponse.java index 6735d85..3ac7770 100644 --- a/src/cgeo/geocaching/cgResponse.java +++ b/src/cgeo/geocaching/cgResponse.java @@ -1,40 +1,40 @@ package cgeo.geocaching; public class cgResponse { - private String url; - private int statusCode; - private String statusMessage; - private String data; - - public void setUrl(String url) { - this.url = url; - } - - public String getUrl() { - return url; - } - - public void setStatusCode(int code) { - statusCode = code; - } - - public int getStatusCode() { - return statusCode; - } - - public void setStatusMessage(String message) { - statusMessage = message; - } - - public String getStatusMessage() { - return statusMessage; - } - - public void setData(String data) { - this.data = data; - } - - public String getData() { - return data; - } + private String url; + private int statusCode; + private String statusMessage; + private String data; + + public void setUrl(String url) { + this.url = url; + } + + public String getUrl() { + return url; + } + + public void setStatusCode(int code) { + statusCode = code; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusMessage(String message) { + statusMessage = message; + } + + public String getStatusMessage() { + return statusMessage; + } + + public void setData(String data) { + this.data = data; + } + + public String getData() { + return data; + } } diff --git a/src/cgeo/geocaching/cgSearch.java b/src/cgeo/geocaching/cgSearch.java index 76599b2..75c5572 100644 --- a/src/cgeo/geocaching/cgSearch.java +++ b/src/cgeo/geocaching/cgSearch.java @@ -5,35 +5,35 @@ import java.util.List; import java.util.UUID; public class cgSearch { - private UUID id; - private List<String> geocodes = new ArrayList<String>(); + private UUID id; + private List<String> geocodes = new ArrayList<String>(); - public String error = null; - public String url = ""; - public String[] viewstates = null; - public int totalCnt = 0; + public String error = null; + public String url = ""; + public String[] viewstates = null; + public int totalCnt = 0; - public cgSearch() { - id = UUID.randomUUID(); - } + public cgSearch() { + id = UUID.randomUUID(); + } - public UUID getCurrentId() { - return id; - } + public UUID getCurrentId() { + return id; + } - public List<String> getGeocodes() { - return geocodes; - } + public List<String> getGeocodes() { + return geocodes; + } - public int getCount() { - return geocodes.size(); - } + public int getCount() { + return geocodes.size(); + } - public void addGeocode(String geocode) { - if (geocodes == null) { - geocodes = new ArrayList<String>(); - } + public void addGeocode(String geocode) { + if (geocodes == null) { + geocodes = new ArrayList<String>(); + } - geocodes.add(geocode); - } + geocodes.add(geocode); + } } diff --git a/src/cgeo/geocaching/cgSearchHandler.java b/src/cgeo/geocaching/cgSearchHandler.java index 3563c6d..4fc6200 100644 --- a/src/cgeo/geocaching/cgSearchHandler.java +++ b/src/cgeo/geocaching/cgSearchHandler.java @@ -13,92 +13,93 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; import android.widget.ImageView; + import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class cgSearchHandler extends Handler { - private Activity activity = null; - private Resources res = null; - private cgSearchThread recaptchaThread = null; - private ImageView imageView = null; - private Bitmap img = null; - - private Handler imgHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - try { - if (img != null && imageView != null) { - imageView.setImageBitmap(img); - } - } catch (Exception e) { - // nothing - } - } - }; - - public cgSearchHandler(Activity activityIn, Resources resIn, cgSearchThread recaptchaThreadIn) { - activity = activityIn; - res = resIn; - recaptchaThread = recaptchaThreadIn; - } - - @Override - public void handleMessage(Message msg) { - try { - if (msg.what == 1) { - final AlertDialog.Builder dlg = new AlertDialog.Builder(activity); - final LayoutInflater inflater = activity.getLayoutInflater(); - final View view = inflater.inflate(R.layout.recaptcha_dialog, null); - - imageView = (ImageView) view.findViewById(R.id.image); - - (new getCaptcha(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start(); - - dlg.setTitle(res.getString(R.string.caches_recaptcha_title)); - dlg.setView(view); - dlg.setNeutralButton(res.getString(R.string.caches_recaptcha_continue), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - final String text = ((EditText) view.findViewById(R.id.text)).getText().toString(); - - recaptchaThread.setText(text); - - dialog.cancel(); - } - }); - - dlg.create().show(); - } - } catch (Exception e) { - // nothing - } - } - - private class getCaptcha extends Thread { - private URL uri = null; - - public getCaptcha(URL uriIn) { - uri = uriIn; - } - - @Override - public void run() { - try { - HttpURLConnection connection = (HttpURLConnection)uri.openConnection(); - connection.setDoInput(true); - connection.connect(); - - InputStream is = connection.getInputStream(); - - img = BitmapFactory.decodeStream(is); - - is.close(); - - imgHandler.sendEmptyMessage(0); - } catch (IOException e) { - Log.e(cgSettings.tag, "Failed to download reCAPTCHA image"); - } - } - } + private Activity activity = null; + private Resources res = null; + private cgSearchThread recaptchaThread = null; + private ImageView imageView = null; + private Bitmap img = null; + + private Handler imgHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + try { + if (img != null && imageView != null) { + imageView.setImageBitmap(img); + } + } catch (Exception e) { + // nothing + } + } + }; + + public cgSearchHandler(Activity activityIn, Resources resIn, cgSearchThread recaptchaThreadIn) { + activity = activityIn; + res = resIn; + recaptchaThread = recaptchaThreadIn; + } + + @Override + public void handleMessage(Message msg) { + try { + if (msg.what == 1) { + final AlertDialog.Builder dlg = new AlertDialog.Builder(activity); + final LayoutInflater inflater = activity.getLayoutInflater(); + final View view = inflater.inflate(R.layout.recaptcha_dialog, null); + + imageView = (ImageView) view.findViewById(R.id.image); + + (new getCaptcha(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start(); + + dlg.setTitle(res.getString(R.string.caches_recaptcha_title)); + dlg.setView(view); + dlg.setNeutralButton(res.getString(R.string.caches_recaptcha_continue), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + final String text = ((EditText) view.findViewById(R.id.text)).getText().toString(); + + recaptchaThread.setText(text); + + dialog.cancel(); + } + }); + + dlg.create().show(); + } + } catch (Exception e) { + // nothing + } + } + + private class getCaptcha extends Thread { + private URL uri = null; + + public getCaptcha(URL uriIn) { + uri = uriIn; + } + + @Override + public void run() { + try { + HttpURLConnection connection = (HttpURLConnection) uri.openConnection(); + connection.setDoInput(true); + connection.connect(); + + InputStream is = connection.getInputStream(); + + img = BitmapFactory.decodeStream(is); + + is.close(); + + imgHandler.sendEmptyMessage(0); + } catch (IOException e) { + Log.e(cgSettings.tag, "Failed to download reCAPTCHA image"); + } + } + } } diff --git a/src/cgeo/geocaching/cgSearchThread.java b/src/cgeo/geocaching/cgSearchThread.java index b3c21ed..732275c 100644 --- a/src/cgeo/geocaching/cgSearchThread.java +++ b/src/cgeo/geocaching/cgSearchThread.java @@ -4,43 +4,43 @@ import android.os.Handler; import android.util.Log; public class cgSearchThread extends Thread { - private Handler recaptchaHandler = null; - private String recaptchaChallenge = null; - private String recaptchaText = null; - - public void setRecaptchaHandler(Handler recaptchaHandlerIn) { - recaptchaHandler = recaptchaHandlerIn; - } - - public void notifyNeed() { - if (recaptchaHandler != null) { - recaptchaHandler.sendEmptyMessage(1); - } - } - - public synchronized void waitForUser() { - try { - wait(); - } catch (InterruptedException e) { - Log.w(cgSettings.tag, "searchThread is not waiting for user..."); - } - } - - public void setChallenge(String challenge) { - recaptchaChallenge = challenge; - } - - public String getChallenge() { - return recaptchaChallenge; - } - - public synchronized void setText(String text) { - recaptchaText = text; - - notify(); - } - - public synchronized String getText() { - return recaptchaText; - } + private Handler recaptchaHandler = null; + private String recaptchaChallenge = null; + private String recaptchaText = null; + + public void setRecaptchaHandler(Handler recaptchaHandlerIn) { + recaptchaHandler = recaptchaHandlerIn; + } + + public void notifyNeed() { + if (recaptchaHandler != null) { + recaptchaHandler.sendEmptyMessage(1); + } + } + + public synchronized void waitForUser() { + try { + wait(); + } catch (InterruptedException e) { + Log.w(cgSettings.tag, "searchThread is not waiting for user..."); + } + } + + public void setChallenge(String challenge) { + recaptchaChallenge = challenge; + } + + public String getChallenge() { + return recaptchaChallenge; + } + + public synchronized void setText(String text) { + recaptchaText = text; + + notify(); + } + + public synchronized String getText() { + return recaptchaText; + } } diff --git a/src/cgeo/geocaching/cgSelectMapfile.java b/src/cgeo/geocaching/cgSelectMapfile.java index 9ce9dd2..921987c 100644 --- a/src/cgeo/geocaching/cgSelectMapfile.java +++ b/src/cgeo/geocaching/cgSelectMapfile.java @@ -1,60 +1,61 @@ package cgeo.geocaching; -import java.io.File; -import java.util.List; +import cgeo.geocaching.files.FileList; import android.content.Intent; import android.os.Bundle; import android.os.Environment; -import cgeo.geocaching.files.FileList; + +import java.io.File; +import java.util.List; public class cgSelectMapfile extends FileList<cgMapfileListAdapter> { - public cgSelectMapfile() { - super("map"); - } - - String mapFile; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mapFile = getSettings().getMapFile(); - } - - public void close() { - - Intent intent = new Intent(); - intent.putExtra("mapfile", mapFile); - - setResult(RESULT_OK, intent); - - finish(); - } - - @Override - protected cgMapfileListAdapter getAdapter(List<File> files) { - return new cgMapfileListAdapter(this, files); - } - - @Override - protected String[] getBaseFolders() { - String base = Environment.getExternalStorageDirectory().toString(); - return new String[]{base + "/mfmaps", base + "/Locus/mapsVector"}; - } - - @Override - protected void setTitle() { - setTitle(res.getString(R.string.map_file_select_title)); - } - - public String getCurrentMapfile() { - return mapFile; - } - - public void setMapfile(String newMapfile) { - mapFile = newMapfile; - } + public cgSelectMapfile() { + super("map"); + } + + String mapFile; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mapFile = getSettings().getMapFile(); + } + + public void close() { + + Intent intent = new Intent(); + intent.putExtra("mapfile", mapFile); + + setResult(RESULT_OK, intent); + + finish(); + } + + @Override + protected cgMapfileListAdapter getAdapter(List<File> files) { + return new cgMapfileListAdapter(this, files); + } + + @Override + protected String[] getBaseFolders() { + String base = Environment.getExternalStorageDirectory().toString(); + return new String[] { base + "/mfmaps", base + "/Locus/mapsVector" }; + } + + @Override + protected void setTitle() { + setTitle(res.getString(R.string.map_file_select_title)); + } + + public String getCurrentMapfile() { + return mapFile; + } + + public void setMapfile(String newMapfile) { + mapFile = newMapfile; + } } diff --git a/src/cgeo/geocaching/cgSettings.java b/src/cgeo/geocaching/cgSettings.java index a1d2a59..72dc362 100644 --- a/src/cgeo/geocaching/cgSettings.java +++ b/src/cgeo/geocaching/cgSettings.java @@ -1,8 +1,9 @@ package cgeo.geocaching; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; +import cgeo.geocaching.googlemaps.googleMapFactory; +import cgeo.geocaching.mapinterfaces.MapFactory; +import cgeo.geocaching.mapsforge.mfMapFactory; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.mapsforge.android.maps.MapDatabase; @@ -14,594 +15,595 @@ import android.content.SharedPreferences.Editor; import android.content.res.Configuration; import android.os.Environment; import android.util.Log; -import cgeo.geocaching.googlemaps.googleMapFactory; -import cgeo.geocaching.mapinterfaces.MapFactory; -import cgeo.geocaching.mapsforge.mfMapFactory; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; /** * General c:geo preferences/settings set by the user */ public class cgSettings { - 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"; - private static final String KEY_MAP_SOURCE = "mapsource"; - private static final String KEY_USE_TWITTER = "twitter"; - private static final String KEY_SHOW_ADDRESS = "showaddress"; - private static final String KEY_SHOW_CAPTCHA = "showcaptcha"; - private static final String KEY_MAP_TRAIL = "maptrail"; - private static final String KEY_LAST_MAP_ZOOM = "mapzoom"; - private static final String KEY_LIVE_LIST = "livelist"; - private static final String KEY_METRIC_UNITS = "units"; - private static final String KEY_SKIN = "skin"; - private static final String KEY_LAST_USED_LIST = "lastlist"; - private static final String KEY_CACHE_TYPE = "cachetype"; - private static final String KEY_INITIALIZED = "initialized"; - private static final String KEY_TWITTER_TOKEN_SECRET = "tokensecret"; - private static final String KEY_TWITTER_TOKEN_PUBLIC = "tokenpublic"; - private static final String KEY_VERSION = "version"; - private static final String KEY_LOAD_DESCRIPTION = "autoloaddesc"; - private static final String KEY_USE_ENGLISH = "useenglish"; - private static final String KEY_AS_BROWSER = "asbrowser"; - private static final String KEY_USE_COMPASS = "usecompass"; - private static final String KEY_AUTO_VISIT_TRACKABLES = "trackautovisit"; - private static final String KEY_AUTO_INSERT_SIGNATURE = "sigautoinsert"; - private static final String KEY_ALTITUDE_CORRECTION = "altcorrection"; - private static final String KEY_USE_GOOGLE_NAVIGATION = "usegnav"; - private static final String KEY_STORE_LOG_IMAGES = "logimages"; - private static final String KEY_EXCLUDE_DISABLED = "excludedisabled"; - private static final String KEY_EXCLUDE_OWN = "excludemine"; - private static final String KEY_MAPFILE = "mfmapfile"; - private static final String KEY_SIGNATURE = "signature"; - private static final String KEY_GCVOTE_PASSWORD = "pass-vote"; - private static final String KEY_PASSWORD = "password"; - private static final String KEY_USERNAME = "username"; - private static final String KEY_COORD_INPUT_FORMAT = "coordinputformat"; - private static final String KEY_LOG_OFFLINE = "log_offline"; - private static final String KEY_LOAD_DIRECTION_IMG = "loaddirectionimg"; - private static final String KEY_GC_CUSTOM_DATE = "gccustomdate"; - - private interface PrefRunnable { - void edit(final Editor edit); - } - - public enum mapSourceEnum { - googleMap, - googleSat, - mapsforgeMapnik, - mapsforgeOsmarender, - mapsforgeCycle, - mapsforgeOffline; - - static mapSourceEnum fromInt(int id) { - mapSourceEnum[] values = mapSourceEnum.values(); - if (id >= 0 && id < values.length) { - return values[id]; - } else { - return googleMap; - } - } - - public boolean isGoogleMapSource() { - if (googleMap == this || googleSat == this) { - return true; - } - - return false; - } - } - - public enum coordInputFormatEnum { - Plain, - Deg, - Min, - Sec; - - static coordInputFormatEnum fromInt(int id) { - coordInputFormatEnum[] values = coordInputFormatEnum.values(); - if (id >= 0 && id < values.length) { - return values[id]; - } else { - return Min; - } - } - } - - // constants - public final static int unitsMetric = 1; - public final static int unitsImperial = 2; - public final static String cache = ".cgeo"; - - // twitter api keys - public final static String keyConsumerPublic = "RFafPiNi3xRhcS1TPE3wTw"; - public final static String keyConsumerSecret = "7iDJprNPI9hzRwWhpzycSr9SPZMFrdVdsxD2OauI9k"; - - // version - public int version = 0; - - // skin - public int skin = 0; - - // settings - public int helper = 0; - public int initialized = 0; - public int autoLoadDesc = 0; - public int units = unitsMetric; - public int livelist = 1; - public int mapzoom = 14; - public int maplive = 1; - public int maptrail = 1; - public boolean useEnglish = false; - public boolean showCaptcha = false; - public int excludeMine = 0; - public int excludeDisabled = 0; - public int storeOfflineMaps = 0; - public boolean storelogimages = false; - public int asBrowser = 1; - public int useCompass = 1; - public int useGNavigation = 1; - public int showAddress = 1; - public int publicLoc = 0; - public int twitter = 0; - public int altCorrection = 0; - public String cacheType = null; - public String tokenPublic = null; - public String tokenSecret = null; + 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"; + private static final String KEY_MAP_SOURCE = "mapsource"; + private static final String KEY_USE_TWITTER = "twitter"; + private static final String KEY_SHOW_ADDRESS = "showaddress"; + private static final String KEY_SHOW_CAPTCHA = "showcaptcha"; + private static final String KEY_MAP_TRAIL = "maptrail"; + private static final String KEY_LAST_MAP_ZOOM = "mapzoom"; + private static final String KEY_LIVE_LIST = "livelist"; + private static final String KEY_METRIC_UNITS = "units"; + private static final String KEY_SKIN = "skin"; + private static final String KEY_LAST_USED_LIST = "lastlist"; + private static final String KEY_CACHE_TYPE = "cachetype"; + private static final String KEY_INITIALIZED = "initialized"; + private static final String KEY_TWITTER_TOKEN_SECRET = "tokensecret"; + private static final String KEY_TWITTER_TOKEN_PUBLIC = "tokenpublic"; + private static final String KEY_VERSION = "version"; + private static final String KEY_LOAD_DESCRIPTION = "autoloaddesc"; + private static final String KEY_USE_ENGLISH = "useenglish"; + private static final String KEY_AS_BROWSER = "asbrowser"; + private static final String KEY_USE_COMPASS = "usecompass"; + private static final String KEY_AUTO_VISIT_TRACKABLES = "trackautovisit"; + private static final String KEY_AUTO_INSERT_SIGNATURE = "sigautoinsert"; + private static final String KEY_ALTITUDE_CORRECTION = "altcorrection"; + private static final String KEY_USE_GOOGLE_NAVIGATION = "usegnav"; + private static final String KEY_STORE_LOG_IMAGES = "logimages"; + private static final String KEY_EXCLUDE_DISABLED = "excludedisabled"; + private static final String KEY_EXCLUDE_OWN = "excludemine"; + private static final String KEY_MAPFILE = "mfmapfile"; + private static final String KEY_SIGNATURE = "signature"; + private static final String KEY_GCVOTE_PASSWORD = "pass-vote"; + private static final String KEY_PASSWORD = "password"; + private static final String KEY_USERNAME = "username"; + private static final String KEY_COORD_INPUT_FORMAT = "coordinputformat"; + private static final String KEY_LOG_OFFLINE = "log_offline"; + private static final String KEY_LOAD_DIRECTION_IMG = "loaddirectionimg"; + private static final String KEY_GC_CUSTOM_DATE = "gccustomdate"; + + private interface PrefRunnable { + void edit(final Editor edit); + } + + public enum mapSourceEnum { + googleMap, + googleSat, + mapsforgeMapnik, + mapsforgeOsmarender, + mapsforgeCycle, + mapsforgeOffline; + + static mapSourceEnum fromInt(int id) { + mapSourceEnum[] values = mapSourceEnum.values(); + if (id >= 0 && id < values.length) { + return values[id]; + } else { + return googleMap; + } + } + + public boolean isGoogleMapSource() { + if (googleMap == this || googleSat == this) { + return true; + } + + return false; + } + } + + public enum coordInputFormatEnum { + Plain, + Deg, + Min, + Sec; + + static coordInputFormatEnum fromInt(int id) { + coordInputFormatEnum[] values = coordInputFormatEnum.values(); + if (id >= 0 && id < values.length) { + return values[id]; + } else { + return Min; + } + } + } + + // constants + public final static int unitsMetric = 1; + public final static int unitsImperial = 2; + public final static String cache = ".cgeo"; + + // twitter api keys + public final static String keyConsumerPublic = "RFafPiNi3xRhcS1TPE3wTw"; + public final static String keyConsumerSecret = "7iDJprNPI9hzRwWhpzycSr9SPZMFrdVdsxD2OauI9k"; + + // version + public int version = 0; + + // skin + public int skin = 0; + + // settings + public int helper = 0; + public int initialized = 0; + public int autoLoadDesc = 0; + public int units = unitsMetric; + public int livelist = 1; + public int mapzoom = 14; + public int maplive = 1; + public int maptrail = 1; + public boolean useEnglish = false; + public boolean showCaptcha = false; + public int excludeMine = 0; + public int excludeDisabled = 0; + public int storeOfflineMaps = 0; + public boolean storelogimages = false; + public int asBrowser = 1; + public int useCompass = 1; + public int useGNavigation = 1; + public int showAddress = 1; + public int publicLoc = 0; + public int twitter = 0; + public int altCorrection = 0; + public String cacheType = null; + public String tokenPublic = null; + public String tokenSecret = null; public String webDeviceName = null; public String webDeviceCode = null; public boolean trackableAutovisit = false; public boolean signatureAutoinsert = false; - // usable values - public static final String tag = "cgeo"; - - /** Name of the preferences file */ - public static final String preferences = "cgeo.pref"; - - // private variables - private Context context = null; - private SharedPreferences prefs = null; - private String username = null; - private String password = null; - private coordInputFormatEnum coordInput = coordInputFormatEnum.Plain; - - // maps - public MapFactory mapFactory = null; - public mapSourceEnum mapSourceUsed = mapSourceEnum.googleMap; - public mapSourceEnum mapSource = mapSourceEnum.googleMap; - private String mapFile = null; - private boolean mapFileValid = false; - - public cgSettings(Context contextIn, SharedPreferences prefsIn) { - context = contextIn; - prefs = prefsIn; - - load(); - } - - public void load() { - version = prefs.getInt(KEY_VERSION, 0); - - initialized = prefs.getInt(KEY_INITIALIZED, 0); - helper = prefs.getInt("helper", 0); - - skin = prefs.getInt(KEY_SKIN, 0); - - autoLoadDesc = prefs.getInt(KEY_LOAD_DESCRIPTION, 0); - units = prefs.getInt(KEY_METRIC_UNITS, 1); - livelist = prefs.getInt(KEY_LIVE_LIST, 1); - maplive = prefs.getInt(KEY_MAP_LIVE, 1); - mapzoom = prefs.getInt(KEY_LAST_MAP_ZOOM, 14); - maptrail = prefs.getInt(KEY_MAP_TRAIL, 1); - useEnglish = prefs.getBoolean(KEY_USE_ENGLISH, false); - showCaptcha = prefs.getBoolean(KEY_SHOW_CAPTCHA, false); - excludeMine = prefs.getInt(KEY_EXCLUDE_OWN, 0); - excludeDisabled = prefs.getInt(KEY_EXCLUDE_DISABLED, 0); - storeOfflineMaps = prefs.getInt("offlinemaps", 1); - storelogimages = prefs.getBoolean(KEY_STORE_LOG_IMAGES, false); - asBrowser = prefs.getInt(KEY_AS_BROWSER, 1); - useCompass = prefs.getInt(KEY_USE_COMPASS, 1); - useGNavigation = prefs.getInt(KEY_USE_GOOGLE_NAVIGATION, 1); - showAddress = prefs.getInt(KEY_SHOW_ADDRESS, 1); - publicLoc = prefs.getInt("publicloc", 0); - twitter = prefs.getInt(KEY_USE_TWITTER, 0); - altCorrection = prefs.getInt(KEY_ALTITUDE_CORRECTION, 0); - cacheType = prefs.getString(KEY_CACHE_TYPE, null); - tokenPublic = prefs.getString(KEY_TWITTER_TOKEN_PUBLIC, null); - tokenSecret = prefs.getString(KEY_TWITTER_TOKEN_SECRET, null); - mapFile = prefs.getString(KEY_MAPFILE, null); - mapFileValid = checkMapfile(mapFile); - mapSource = mapSourceEnum.fromInt(prefs.getInt(KEY_MAP_SOURCE, 0)); - webDeviceName = prefs.getString(KEY_WEBDEVICE_NAME, null); - webDeviceCode = prefs.getString(KEY_WEB_DEVICE_CODE, null); - trackableAutovisit = prefs.getBoolean(KEY_AUTO_VISIT_TRACKABLES, false); - signatureAutoinsert = prefs.getBoolean(KEY_AUTO_INSERT_SIGNATURE, false); - coordInput = coordInputFormatEnum.fromInt(prefs.getInt(KEY_COORD_INPUT_FORMAT, 0)); - - setLanguage(useEnglish); - } - - public void setSkin(int skinIn) { - if (skin == 1) { - skin = 1; - } else { - skin = 0; - } - } - - public void setLanguage(boolean useEnglish) { - Locale locale = Locale.getDefault(); - if (useEnglish) { - locale = new Locale("en"); - } - Configuration config = new Configuration(); - config.locale = locale; - context.getResources().updateConfiguration(config, - context.getResources().getDisplayMetrics()); - } - - public void reloadTwitterTokens() { - tokenPublic = prefs.getString(KEY_TWITTER_TOKEN_PUBLIC, null); - tokenSecret = prefs.getString(KEY_TWITTER_TOKEN_SECRET, null); - } - - public void reloadCacheType() { - cacheType = prefs.getString(KEY_CACHE_TYPE, null); - } - - public static String getStorage() { - return getStorageSpecific(null)[0]; - } - - public static String getStorageSec() { - return getStorageSpecific(null)[1]; - } - - public static String[] getStorageSpecific(Boolean hidden) { - String external = Environment.getExternalStorageDirectory() + "/" + cache + "/"; - String data = Environment.getDataDirectory() + "/data/cgeo.geocaching/" + cache + "/"; - - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - return new String[] {external, data}; - } else { - return new String[] {data, external}; - } - } - - public boolean isLogin() { - final String preUsername = prefs.getString(KEY_USERNAME, null); - final String prePassword = prefs.getString(KEY_PASSWORD, null); - - if (StringUtils.isBlank(preUsername) || StringUtils.isBlank(prePassword)) { - return false; - } else { - return true; - } - } - - public Map<String, String> getLogin() { - final Map<String, String> login = new HashMap<String, String>(); - - if (username == null || password == null) { - final String preUsername = prefs.getString(KEY_USERNAME, null); - final String prePassword = prefs.getString(KEY_PASSWORD, null); - - if (initialized == 0 && (preUsername == null || prePassword == null)) { - Intent initIntent = new Intent(context, cgeoinit.class); - context.startActivity(initIntent); - - final SharedPreferences.Editor prefsEdit = prefs.edit(); - prefsEdit.putInt(KEY_INITIALIZED, 1); - prefsEdit.commit(); - - initialized = 1; - - return null; - } else if (initialized == 1 && (preUsername == null || prePassword == null)) { - return null; - } - - login.put(KEY_USERNAME, preUsername); - login.put(KEY_PASSWORD, prePassword); - - username = preUsername; - password = prePassword; - } else { - login.put(KEY_USERNAME, username); - login.put(KEY_PASSWORD, password); - } - - return login; - } - - public String getUsername() { - if (username == null) { - return prefs.getString(KEY_USERNAME, null); - } else { - return username; - } - } - - public boolean setLogin(final String username, final String password) { - this.username = username; - this.password = password; - return editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { - // erase username and password - edit.remove(KEY_USERNAME); - edit.remove(KEY_PASSWORD); - } else { - // save username and password - edit.putString(KEY_USERNAME, username); - edit.putString(KEY_PASSWORD, password); - } - } - }); - } - - public boolean isGCvoteLogin() { - final String preUsername = prefs.getString(KEY_USERNAME, null); - final String prePassword = prefs.getString(KEY_GCVOTE_PASSWORD, null); - - if (StringUtils.isBlank(preUsername) || StringUtils.isBlank(prePassword)) { - return false; - } else { - return true; - } - } - - public boolean setGCvoteLogin(final String password) { - return editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - if (StringUtils.isBlank(password)) { - // erase password - edit.remove(KEY_GCVOTE_PASSWORD); - } else { - // save password - edit.putString(KEY_GCVOTE_PASSWORD, password); - } - } - }); - } - - public Map<String, String> getGCvoteLogin() { - final Map<String, String> login = new HashMap<String, String>(); - - if (username == null || password == null) { - final String preUsername = prefs.getString(KEY_USERNAME, null); - final String prePassword = prefs.getString(KEY_GCVOTE_PASSWORD, null); - - if (preUsername == null || prePassword == null) { - return null; - } - - login.put(KEY_USERNAME, preUsername); - login.put(KEY_PASSWORD, prePassword); - - username = preUsername; - } else { - login.put(KEY_USERNAME, username); - login.put(KEY_PASSWORD, password); - } - - return login; - } - - public boolean setSignature(final String signature) { - return editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - if (StringUtils.isBlank(signature)) { - // erase signature - edit.remove(KEY_SIGNATURE); - } else { - // save signature - edit.putString(KEY_SIGNATURE, signature); - } - } - }); - } - - public String getSignature() { - return prefs.getString(KEY_SIGNATURE, null); - } - - public boolean setAltCorrection(final int altitude) { - altCorrection = altitude; - return editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putInt(KEY_ALTITUDE_CORRECTION, altitude); - } - }); - } - - public void deleteCookies() { - editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - // delete cookies - Map<String, ?> prefsValues = prefs.getAll(); - - if (CollectionUtils.isNotEmpty(prefsValues)) { - Log.i(cgSettings.tag, "Removing cookies"); - - for (String key : prefsValues.keySet()) { - if (key.length() > 7 && key.substring(0, 7).equals("cookie_")) { - edit.remove(key); - } - } - } - } - }); - } - - public String setCacheType(final String cacheTypeIn) { - editSettings(new PrefRunnable() { - @Override - public void edit(Editor edit) { - edit.putString(KEY_CACHE_TYPE, cacheTypeIn); - } - }); - - cacheType = cacheTypeIn; - - return cacheType; - } - - public void liveMapEnable() { - if (editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putInt(KEY_MAP_LIVE, 1); - } - })) { - maplive = 1; - } - } - - public void liveMapDisable() { - if (editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putInt(KEY_MAP_LIVE, 0); - } - })) { - maplive = 0; - } - } - - public int getLastList() { - int listId = prefs.getInt(KEY_LAST_USED_LIST, -1); - - return listId; - } - - public void saveLastList(final int listId) { - editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putInt(KEY_LAST_USED_LIST, listId); - } - }); - } - - public void setWebNameCode(final String name, final String code) { - if (editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - - edit.putString(KEY_WEBDEVICE_NAME, name); - edit.putString(KEY_WEB_DEVICE_CODE, code); - } - })) { - webDeviceCode=code; - webDeviceName=name; - } - } - - public MapFactory getMapFactory() { - if (mapSource.isGoogleMapSource()) { - if (!mapSourceUsed.isGoogleMapSource() || mapFactory == null) { - mapFactory = new googleMapFactory(); - mapSourceUsed = mapSource; - } - } else if (!mapSource.isGoogleMapSource()) { - if (mapSourceUsed.isGoogleMapSource() || mapFactory == null) { - mapFactory = new mfMapFactory(); - mapSourceUsed = mapSource; - } - } - - return mapFactory; - } - - public String getMapFile() { - return mapFile; - } - - public boolean setMapFile(final String mapFileIn) { - boolean commitResult = editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putString(KEY_MAPFILE, mapFileIn); - } - }); - - mapFile = mapFileIn; - mapFileValid = checkMapfile(mapFile); - - return commitResult; - } - - public boolean hasValidMapFile() { - return mapFileValid; - } - - private static boolean checkMapfile(String mapFileIn) { - if (null == mapFileIn) { - return false; - } - return MapDatabase.isValidMapFile(mapFileIn); - } - - public coordInputFormatEnum getCoordInputFormat() { - return coordInput; - } - - public boolean setCoordInputFormat (coordInputFormatEnum format) { - coordInput = format; - boolean commitResult = editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putInt(KEY_COORD_INPUT_FORMAT, coordInput.ordinal()); - } - }); - return commitResult; - } - - /** - * edit some settings without knowing how to get the settings editor or how to commit - * @param runnable - * @return commit result - */ - private boolean editSettings(final PrefRunnable runnable) { - final SharedPreferences.Editor prefsEdit = prefs.edit(); - runnable.edit(prefsEdit); - return prefsEdit.commit(); - } - - void setLogOffline(final boolean offline) { - editSettings(new PrefRunnable() { - - @Override - public void edit(Editor edit) { - edit.putBoolean(KEY_LOG_OFFLINE, offline); - } - }); - } - - public boolean getLogOffline() { - return prefs.getBoolean(KEY_LOG_OFFLINE, false); - } - - void setLoadDirImg(final boolean value) { + // usable values + public static final String tag = "cgeo"; + + /** Name of the preferences file */ + public static final String preferences = "cgeo.pref"; + + // private variables + private Context context = null; + private SharedPreferences prefs = null; + private String username = null; + private String password = null; + private coordInputFormatEnum coordInput = coordInputFormatEnum.Plain; + + // maps + public MapFactory mapFactory = null; + public mapSourceEnum mapSourceUsed = mapSourceEnum.googleMap; + public mapSourceEnum mapSource = mapSourceEnum.googleMap; + private String mapFile = null; + private boolean mapFileValid = false; + + public cgSettings(Context contextIn, SharedPreferences prefsIn) { + context = contextIn; + prefs = prefsIn; + + load(); + } + + public void load() { + version = prefs.getInt(KEY_VERSION, 0); + + initialized = prefs.getInt(KEY_INITIALIZED, 0); + helper = prefs.getInt("helper", 0); + + skin = prefs.getInt(KEY_SKIN, 0); + + autoLoadDesc = prefs.getInt(KEY_LOAD_DESCRIPTION, 0); + units = prefs.getInt(KEY_METRIC_UNITS, 1); + livelist = prefs.getInt(KEY_LIVE_LIST, 1); + maplive = prefs.getInt(KEY_MAP_LIVE, 1); + mapzoom = prefs.getInt(KEY_LAST_MAP_ZOOM, 14); + maptrail = prefs.getInt(KEY_MAP_TRAIL, 1); + useEnglish = prefs.getBoolean(KEY_USE_ENGLISH, false); + showCaptcha = prefs.getBoolean(KEY_SHOW_CAPTCHA, false); + excludeMine = prefs.getInt(KEY_EXCLUDE_OWN, 0); + excludeDisabled = prefs.getInt(KEY_EXCLUDE_DISABLED, 0); + storeOfflineMaps = prefs.getInt("offlinemaps", 1); + storelogimages = prefs.getBoolean(KEY_STORE_LOG_IMAGES, false); + asBrowser = prefs.getInt(KEY_AS_BROWSER, 1); + useCompass = prefs.getInt(KEY_USE_COMPASS, 1); + useGNavigation = prefs.getInt(KEY_USE_GOOGLE_NAVIGATION, 1); + showAddress = prefs.getInt(KEY_SHOW_ADDRESS, 1); + publicLoc = prefs.getInt("publicloc", 0); + twitter = prefs.getInt(KEY_USE_TWITTER, 0); + altCorrection = prefs.getInt(KEY_ALTITUDE_CORRECTION, 0); + cacheType = prefs.getString(KEY_CACHE_TYPE, null); + tokenPublic = prefs.getString(KEY_TWITTER_TOKEN_PUBLIC, null); + tokenSecret = prefs.getString(KEY_TWITTER_TOKEN_SECRET, null); + mapFile = prefs.getString(KEY_MAPFILE, null); + mapFileValid = checkMapfile(mapFile); + mapSource = mapSourceEnum.fromInt(prefs.getInt(KEY_MAP_SOURCE, 0)); + webDeviceName = prefs.getString(KEY_WEBDEVICE_NAME, null); + webDeviceCode = prefs.getString(KEY_WEB_DEVICE_CODE, null); + trackableAutovisit = prefs.getBoolean(KEY_AUTO_VISIT_TRACKABLES, false); + signatureAutoinsert = prefs.getBoolean(KEY_AUTO_INSERT_SIGNATURE, false); + coordInput = coordInputFormatEnum.fromInt(prefs.getInt(KEY_COORD_INPUT_FORMAT, 0)); + + setLanguage(useEnglish); + } + + public void setSkin(int skinIn) { + if (skin == 1) { + skin = 1; + } else { + skin = 0; + } + } + + public void setLanguage(boolean useEnglish) { + Locale locale = Locale.getDefault(); + if (useEnglish) { + locale = new Locale("en"); + } + Configuration config = new Configuration(); + config.locale = locale; + context.getResources().updateConfiguration(config, + context.getResources().getDisplayMetrics()); + } + + public void reloadTwitterTokens() { + tokenPublic = prefs.getString(KEY_TWITTER_TOKEN_PUBLIC, null); + tokenSecret = prefs.getString(KEY_TWITTER_TOKEN_SECRET, null); + } + + public void reloadCacheType() { + cacheType = prefs.getString(KEY_CACHE_TYPE, null); + } + + public static String getStorage() { + return getStorageSpecific(null)[0]; + } + + public static String getStorageSec() { + return getStorageSpecific(null)[1]; + } + + public static String[] getStorageSpecific(Boolean hidden) { + String external = Environment.getExternalStorageDirectory() + "/" + cache + "/"; + String data = Environment.getDataDirectory() + "/data/cgeo.geocaching/" + cache + "/"; + + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + return new String[] { external, data }; + } else { + return new String[] { data, external }; + } + } + + public boolean isLogin() { + final String preUsername = prefs.getString(KEY_USERNAME, null); + final String prePassword = prefs.getString(KEY_PASSWORD, null); + + if (StringUtils.isBlank(preUsername) || StringUtils.isBlank(prePassword)) { + return false; + } else { + return true; + } + } + + public Map<String, String> getLogin() { + final Map<String, String> login = new HashMap<String, String>(); + + if (username == null || password == null) { + final String preUsername = prefs.getString(KEY_USERNAME, null); + final String prePassword = prefs.getString(KEY_PASSWORD, null); + + if (initialized == 0 && (preUsername == null || prePassword == null)) { + Intent initIntent = new Intent(context, cgeoinit.class); + context.startActivity(initIntent); + + final SharedPreferences.Editor prefsEdit = prefs.edit(); + prefsEdit.putInt(KEY_INITIALIZED, 1); + prefsEdit.commit(); + + initialized = 1; + + return null; + } else if (initialized == 1 && (preUsername == null || prePassword == null)) { + return null; + } + + login.put(KEY_USERNAME, preUsername); + login.put(KEY_PASSWORD, prePassword); + + username = preUsername; + password = prePassword; + } else { + login.put(KEY_USERNAME, username); + login.put(KEY_PASSWORD, password); + } + + return login; + } + + public String getUsername() { + if (username == null) { + return prefs.getString(KEY_USERNAME, null); + } else { + return username; + } + } + + public boolean setLogin(final String username, final String password) { + this.username = username; + this.password = password; + return editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { + // erase username and password + edit.remove(KEY_USERNAME); + edit.remove(KEY_PASSWORD); + } else { + // save username and password + edit.putString(KEY_USERNAME, username); + edit.putString(KEY_PASSWORD, password); + } + } + }); + } + + public boolean isGCvoteLogin() { + final String preUsername = prefs.getString(KEY_USERNAME, null); + final String prePassword = prefs.getString(KEY_GCVOTE_PASSWORD, null); + + if (StringUtils.isBlank(preUsername) || StringUtils.isBlank(prePassword)) { + return false; + } else { + return true; + } + } + + public boolean setGCvoteLogin(final String password) { + return editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + if (StringUtils.isBlank(password)) { + // erase password + edit.remove(KEY_GCVOTE_PASSWORD); + } else { + // save password + edit.putString(KEY_GCVOTE_PASSWORD, password); + } + } + }); + } + + public Map<String, String> getGCvoteLogin() { + final Map<String, String> login = new HashMap<String, String>(); + + if (username == null || password == null) { + final String preUsername = prefs.getString(KEY_USERNAME, null); + final String prePassword = prefs.getString(KEY_GCVOTE_PASSWORD, null); + + if (preUsername == null || prePassword == null) { + return null; + } + + login.put(KEY_USERNAME, preUsername); + login.put(KEY_PASSWORD, prePassword); + + username = preUsername; + } else { + login.put(KEY_USERNAME, username); + login.put(KEY_PASSWORD, password); + } + + return login; + } + + public boolean setSignature(final String signature) { + return editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + if (StringUtils.isBlank(signature)) { + // erase signature + edit.remove(KEY_SIGNATURE); + } else { + // save signature + edit.putString(KEY_SIGNATURE, signature); + } + } + }); + } + + public String getSignature() { + return prefs.getString(KEY_SIGNATURE, null); + } + + public boolean setAltCorrection(final int altitude) { + altCorrection = altitude; + return editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_ALTITUDE_CORRECTION, altitude); + } + }); + } + + public void deleteCookies() { + editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + // delete cookies + Map<String, ?> prefsValues = prefs.getAll(); + + if (CollectionUtils.isNotEmpty(prefsValues)) { + Log.i(cgSettings.tag, "Removing cookies"); + + for (String key : prefsValues.keySet()) { + if (key.length() > 7 && key.substring(0, 7).equals("cookie_")) { + edit.remove(key); + } + } + } + } + }); + } + + public String setCacheType(final String cacheTypeIn) { + editSettings(new PrefRunnable() { + @Override + public void edit(Editor edit) { + edit.putString(KEY_CACHE_TYPE, cacheTypeIn); + } + }); + + cacheType = cacheTypeIn; + + return cacheType; + } + + public void liveMapEnable() { + if (editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_MAP_LIVE, 1); + } + })) { + maplive = 1; + } + } + + public void liveMapDisable() { + if (editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_MAP_LIVE, 0); + } + })) { + maplive = 0; + } + } + + public int getLastList() { + int listId = prefs.getInt(KEY_LAST_USED_LIST, -1); + + return listId; + } + + public void saveLastList(final int listId) { + editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_LAST_USED_LIST, listId); + } + }); + } + + public void setWebNameCode(final String name, final String code) { + if (editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + + edit.putString(KEY_WEBDEVICE_NAME, name); + edit.putString(KEY_WEB_DEVICE_CODE, code); + } + })) { + webDeviceCode = code; + webDeviceName = name; + } + } + + public MapFactory getMapFactory() { + if (mapSource.isGoogleMapSource()) { + if (!mapSourceUsed.isGoogleMapSource() || mapFactory == null) { + mapFactory = new googleMapFactory(); + mapSourceUsed = mapSource; + } + } else if (!mapSource.isGoogleMapSource()) { + if (mapSourceUsed.isGoogleMapSource() || mapFactory == null) { + mapFactory = new mfMapFactory(); + mapSourceUsed = mapSource; + } + } + + return mapFactory; + } + + public String getMapFile() { + return mapFile; + } + + public boolean setMapFile(final String mapFileIn) { + boolean commitResult = editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putString(KEY_MAPFILE, mapFileIn); + } + }); + + mapFile = mapFileIn; + mapFileValid = checkMapfile(mapFile); + + return commitResult; + } + + public boolean hasValidMapFile() { + return mapFileValid; + } + + private static boolean checkMapfile(String mapFileIn) { + if (null == mapFileIn) { + return false; + } + return MapDatabase.isValidMapFile(mapFileIn); + } + + public coordInputFormatEnum getCoordInputFormat() { + return coordInput; + } + + public boolean setCoordInputFormat(coordInputFormatEnum format) { + coordInput = format; + boolean commitResult = editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_COORD_INPUT_FORMAT, coordInput.ordinal()); + } + }); + return commitResult; + } + + /** + * edit some settings without knowing how to get the settings editor or how to commit + * + * @param runnable + * @return commit result + */ + private boolean editSettings(final PrefRunnable runnable) { + final SharedPreferences.Editor prefsEdit = prefs.edit(); + runnable.edit(prefsEdit); + return prefsEdit.commit(); + } + + void setLogOffline(final boolean offline) { + editSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putBoolean(KEY_LOG_OFFLINE, offline); + } + }); + } + + public boolean getLogOffline() { + return prefs.getBoolean(KEY_LOG_OFFLINE, false); + } + + void setLoadDirImg(final boolean value) { editSettings(new PrefRunnable() { @Override @@ -610,11 +612,11 @@ public class cgSettings { } }); } - + public boolean getLoadDirImg() { return prefs.getBoolean(KEY_LOAD_DIRECTION_IMG, true); } - + void setGcCustomDate(final String format) { editSettings(new PrefRunnable() { @@ -624,7 +626,7 @@ public class cgSettings { } }); } - + public String getGcCustomDate() { return prefs.getString(KEY_GC_CUSTOM_DATE, null); } diff --git a/src/cgeo/geocaching/cgTrackable.java b/src/cgeo/geocaching/cgTrackable.java index fb877ad..a8e4621 100644 --- a/src/cgeo/geocaching/cgTrackable.java +++ b/src/cgeo/geocaching/cgTrackable.java @@ -1,37 +1,37 @@ package cgeo.geocaching; +import android.text.Spannable; + import java.util.ArrayList; import java.util.Date; import java.util.List; -import android.text.Spannable; - public class cgTrackable { - static final public int SPOTTED_UNSET = 0; - static final public int SPOTTED_CACHE = 1; - static final public int SPOTTED_USER = 2; - static final public int SPOTTED_UNKNOWN = 3; - static final public int SPOTTED_OWNER = 4; - - public int errorRetrieve = 0; - public String error = ""; - public String guid = ""; - public String geocode = ""; - public String iconUrl = ""; - public String name = ""; - public String nameString = null; - public Spannable nameSp = null; - public String type = null; - public Date released = null; - public Float distance = null; - public String origin = null; - public String owner = null; - public String ownerGuid = null; - public String spottedName = null; - public int spottedType = SPOTTED_UNSET; - public String spottedGuid = null; - public String goal = null; - public String details = null; - public String image = null; - public List<cgLog> logs = new ArrayList<cgLog>(); + static final public int SPOTTED_UNSET = 0; + static final public int SPOTTED_CACHE = 1; + static final public int SPOTTED_USER = 2; + static final public int SPOTTED_UNKNOWN = 3; + static final public int SPOTTED_OWNER = 4; + + public int errorRetrieve = 0; + public String error = ""; + public String guid = ""; + public String geocode = ""; + public String iconUrl = ""; + public String name = ""; + public String nameString = null; + public Spannable nameSp = null; + public String type = null; + public Date released = null; + public Float distance = null; + public String origin = null; + public String owner = null; + public String ownerGuid = null; + public String spottedName = null; + public int spottedType = SPOTTED_UNSET; + public String spottedGuid = null; + public String goal = null; + public String details = null; + public String image = null; + public List<cgLog> logs = new ArrayList<cgLog>(); } diff --git a/src/cgeo/geocaching/cgTrackableLog.java b/src/cgeo/geocaching/cgTrackableLog.java index 7522d8d..a5bae6d 100644 --- a/src/cgeo/geocaching/cgTrackableLog.java +++ b/src/cgeo/geocaching/cgTrackableLog.java @@ -1,9 +1,9 @@ package cgeo.geocaching; public class cgTrackableLog { - public int ctl = -1; - public int id = -1; - public String trackCode = null; - public String name = null; - public int action = 0; // base.logTrackablesAction - no action + public int ctl = -1; + public int id = -1; + public String trackCode = null; + public String name = null; + public int action = 0; // base.logTrackablesAction - no action } diff --git a/src/cgeo/geocaching/cgUpdateDir.java b/src/cgeo/geocaching/cgUpdateDir.java index 01346ec..dd09a55 100644 --- a/src/cgeo/geocaching/cgUpdateDir.java +++ b/src/cgeo/geocaching/cgUpdateDir.java @@ -1,7 +1,7 @@ package cgeo.geocaching; public class cgUpdateDir { - public void updateDir(cgDirection dir) { - // to be overriden - } + public void updateDir(cgDirection dir) { + // to be overriden + } } diff --git a/src/cgeo/geocaching/cgUpdateLoc.java b/src/cgeo/geocaching/cgUpdateLoc.java index 3c063f2..a341081 100644 --- a/src/cgeo/geocaching/cgUpdateLoc.java +++ b/src/cgeo/geocaching/cgUpdateLoc.java @@ -1,7 +1,7 @@ package cgeo.geocaching; public class cgUpdateLoc { - public void updateLoc(cgGeo geo) { - // to be overriden - } + public void updateLoc(cgGeo geo) { + // to be overriden + } } diff --git a/src/cgeo/geocaching/cgUser.java b/src/cgeo/geocaching/cgUser.java index 017caa7..2249133 100644 --- a/src/cgeo/geocaching/cgUser.java +++ b/src/cgeo/geocaching/cgUser.java @@ -1,13 +1,13 @@ package cgeo.geocaching; -import java.util.Date; - import cgeo.geocaching.geopoint.Geopoint; +import java.util.Date; + public class cgUser { - public Date located = null; - public String username = null; - public Geopoint coords = null; - public String action = null; - public String client = null; + public Date located = null; + public String username = null; + public Geopoint coords = null; + public String action = null; + public String client = null; } diff --git a/src/cgeo/geocaching/cgWaypoint.java b/src/cgeo/geocaching/cgWaypoint.java index a11a2c5..c0dd719 100644 --- a/src/cgeo/geocaching/cgWaypoint.java +++ b/src/cgeo/geocaching/cgWaypoint.java @@ -1,96 +1,97 @@ package cgeo.geocaching; -import java.util.List; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.widget.TextView; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.List; public class cgWaypoint { public Integer id = 0; - public String geocode = "geocode"; - public String type = "waypoint"; - public String prefix = ""; - public String lookup = ""; - public String name = ""; - public String latlon = ""; - public String latitudeString = ""; - public String longitudeString = ""; - public Geopoint coords = null; - public String note = ""; + public String geocode = "geocode"; + public String type = "waypoint"; + public String prefix = ""; + public String lookup = ""; + public String name = ""; + public String latlon = ""; + public String latitudeString = ""; + public String longitudeString = ""; + public Geopoint coords = null; + public String note = ""; - public void setIcon(Resources res, cgBase base, TextView nameView) { - int iconId = R.drawable.waypoint_waypoint; - if (type != null) { - int specialId = res.getIdentifier("waypoint_" + type, "drawable", base.context.getPackageName()); - if (specialId > 0) { - iconId = specialId; - } - } - nameView.setCompoundDrawablesWithIntrinsicBounds((Drawable) res.getDrawable(iconId), null, null, null); - } + public void setIcon(Resources res, cgBase base, TextView nameView) { + int iconId = R.drawable.waypoint_waypoint; + if (type != null) { + int specialId = res.getIdentifier("waypoint_" + type, "drawable", base.context.getPackageName()); + if (specialId > 0) { + iconId = specialId; + } + } + nameView.setCompoundDrawablesWithIntrinsicBounds((Drawable) res.getDrawable(iconId), null, null, null); + } - public void merge(final cgWaypoint old) { - if (StringUtils.isBlank(prefix)) { - prefix = old.prefix; - } - if (StringUtils.isBlank(lookup)) { - lookup = old.lookup; - } - if (StringUtils.isBlank(name)) { - name = old.name; - } - if (StringUtils.isBlank(latlon)) { - latlon = old.latlon; - } - if (StringUtils.isBlank(latitudeString)) { - latitudeString = old.latitudeString; - } - if (StringUtils.isBlank(longitudeString)) { - longitudeString = old.longitudeString; - } - if (coords == null) { - coords = old.coords; - } - if (StringUtils.isBlank(note)) { - note = old.note; - } - if (note != null && old.note != null) { - if (old.note.length() > note.length()) { - note = old.note; - } - } - } + public void merge(final cgWaypoint old) { + if (StringUtils.isBlank(prefix)) { + prefix = old.prefix; + } + if (StringUtils.isBlank(lookup)) { + lookup = old.lookup; + } + if (StringUtils.isBlank(name)) { + name = old.name; + } + if (StringUtils.isBlank(latlon)) { + latlon = old.latlon; + } + if (StringUtils.isBlank(latitudeString)) { + latitudeString = old.latitudeString; + } + if (StringUtils.isBlank(longitudeString)) { + longitudeString = old.longitudeString; + } + if (coords == null) { + coords = old.coords; + } + if (StringUtils.isBlank(note)) { + note = old.note; + } + if (note != null && old.note != null) { + if (old.note.length() > note.length()) { + note = old.note; + } + } + } - public static void mergeWayPoints(List<cgWaypoint> newPoints, - List<cgWaypoint> oldPoints) { - // copy user modified details of the waypoints - if (newPoints != null && oldPoints != null) { - for (cgWaypoint old : oldPoints) { - boolean merged = false; - if (old != null && old.name != null && old.name.length() > 0) { - for (cgWaypoint waypoint : newPoints) { - if (waypoint != null && waypoint.name != null) { - if (old.name.equalsIgnoreCase(waypoint.name)) { - waypoint.merge(old); - merged = true; - break; - } - } - } - } - // user added waypoints should also be in the new list - if (!merged) { - newPoints.add(old); - } - } - } - } + public static void mergeWayPoints(List<cgWaypoint> newPoints, + List<cgWaypoint> oldPoints) { + // copy user modified details of the waypoints + if (newPoints != null && oldPoints != null) { + for (cgWaypoint old : oldPoints) { + boolean merged = false; + if (old != null && old.name != null && old.name.length() > 0) { + for (cgWaypoint waypoint : newPoints) { + if (waypoint != null && waypoint.name != null) { + if (old.name.equalsIgnoreCase(waypoint.name)) { + waypoint.merge(old); + merged = true; + break; + } + } + } + } + // user added waypoints should also be in the new list + if (!merged) { + newPoints.add(old); + } + } + } + } - public boolean isUserDefined() { - return type != null && type.equalsIgnoreCase("own"); - } + public boolean isUserDefined() { + return type != null && type.equalsIgnoreCase("own"); + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgeo.java b/src/cgeo/geocaching/cgeo.java index 1f6260f..9782b18 100644 --- a/src/cgeo/geocaching/cgeo.java +++ b/src/cgeo/geocaching/cgeo.java @@ -1,12 +1,9 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -30,699 +27,702 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.RelativeLayout; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; public class cgeo extends AbstractActivity { - private static final String SCAN_INTENT = "com.google.zxing.client.android.SCAN"; - private static final int MENU_ABOUT = 0; - private static final int MENU_HELPERS = 1; - private static final int MENU_SETTINGS = 2; - private static final int MENU_HISTORY = 3; - private static final int MENU_SCAN = 4; - private static final int SCAN_REQUEST_CODE = 1; - private static final int MENU_OPEN_LIST = 100; - - private Context context = null; - private Integer version = null; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private TextView navType = null; - private TextView navAccuracy = null; - private TextView navSatellites = null; - private TextView navLocation = null; - private TextView filterTitle = null; - private TextView countBubble = null; - private boolean cleanupRunning = false; - private int countBubbleCnt = 0; - private Geopoint addCoords = null; - private List<Address> addresses = null; - private boolean addressObtaining = false; - private boolean initialized = false; - private Handler countBubbleHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (countBubble == null) { - countBubble = (TextView) findViewById(R.id.offline_count); - } - - if (countBubbleCnt == 0) { - countBubble.setVisibility(View.GONE); - } else { - countBubble.setText(Integer.toString(countBubbleCnt)); - countBubble.bringToFront(); - countBubble.setVisibility(View.VISIBLE); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeo.countBubbleHander: " + e.toString()); - } - } - }; - private Handler obtainAddressHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (CollectionUtils.isNotEmpty(addresses)) { - final Address address = addresses.get(0); - final StringBuilder addText = new StringBuilder(); - - if (address.getCountryName() != null) { - addText.append(address.getCountryName()); - } - if (address.getLocality() != null) { - if (addText.length() > 0) { - addText.append(", "); - } - addText.append(address.getLocality()); - } else if (address.getAdminArea() != null) { - if (addText.length() > 0) { - addText.append(", "); - } - addText.append(address.getAdminArea()); - } - - addCoords = geo.coordsNow; - - if (navLocation == null) { - navLocation = (TextView) findViewById(R.id.nav_location); - } - - navLocation.setText(addText.toString()); - } - } catch (Exception e) { - // nothing - } - - addresses = null; - } - }; - - public cgeo() { - super("c:geo-main-screen"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - context = this; - app.setAction(null); - - app.cleanGeo(); - app.cleanDir(); - - setContentView(R.layout.main); - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); // type to search - - try { - PackageManager manager = this.getPackageManager(); - PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); - - version = info.versionCode; - - Log.i(cgSettings.tag, "Starting " + info.packageName + " " + info.versionCode + " a.k.a " + info.versionName + "..."); - - info = null; - manager = null; - } catch (Exception e) { - Log.i(cgSettings.tag, "No info."); - } - - try { - if (settings.helper == 0) { - RelativeLayout helper = (RelativeLayout) findViewById(R.id.helper); - if (helper != null) { - helper.setVisibility(View.VISIBLE); - helper.setClickable(true); - helper.setOnClickListener(new View.OnClickListener() { - - public void onClick(View view) { - ActivityMixin.goManual(context, "c:geo-intro"); - view.setVisibility(View.GONE); - } - }); - - final SharedPreferences.Editor edit = getSharedPreferences(cgSettings.preferences, 0).edit(); - edit.putInt("helper", 1); - edit.commit(); - } - } - } catch (Exception e) { - // nothing - } - - init(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - init(); - } - - @Override - public void onDestroy() { - initialized = false; - - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - initialized = false; - - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - initialized = false; - - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, MENU_SETTINGS, 0, res.getString(R.string.menu_settings)).setIcon(android.R.drawable.ic_menu_preferences); - menu.add(0, MENU_HISTORY, 0, res.getString(R.string.menu_history)).setIcon(android.R.drawable.ic_menu_recent_history); - menu.add(0, MENU_HELPERS, 0, res.getString(R.string.menu_helpers)).setIcon(android.R.drawable.ic_menu_add); - menu.add(0, MENU_SCAN, 0, res.getString(R.string.menu_scan)).setIcon(android.R.drawable.ic_menu_camera); - menu.add(0, MENU_ABOUT, 0, res.getString(R.string.menu_about)).setIcon(android.R.drawable.ic_menu_help); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - MenuItem item = menu.findItem(MENU_SCAN); - if (item != null) { - item.setEnabled(isIntentAvailable(this, SCAN_INTENT)); - } - return true; - } - - private static boolean isIntentAvailable(Context context, String intent) { - final PackageManager packageManager = context.getPackageManager(); - final List<ResolveInfo> list = packageManager.queryIntentActivities( - new Intent(intent), PackageManager.MATCH_DEFAULT_ONLY); - - return list.size() > 0; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int id = item.getItemId(); - switch (id) { - case MENU_ABOUT: - showAbout(null); - return true; - case MENU_HELPERS: - context.startActivity(new Intent(context, cgeohelpers.class)); - return true; - case MENU_SETTINGS: - context.startActivity(new Intent(context, cgeoinit.class)); - return true; - case MENU_HISTORY: - final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra("type", "history"); - context.startActivity(cachesIntent); - return true; - case MENU_SCAN: - Intent intent = new Intent(SCAN_INTENT); - intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); - startActivityForResult(intent, SCAN_REQUEST_CODE); - return true; - default: - break; - } - - return false; - } - - public void onActivityResult(int requestCode, int resultCode, Intent intent) { - if (requestCode == SCAN_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - String scan = intent.getStringExtra("SCAN_RESULT"); - if (StringUtils.isBlank(scan)) { - return; - } - String host = "http://coord.info/"; - if (scan.toLowerCase().startsWith(host)) { - String geocode = scan.substring(host.length()).trim(); - cgeodetail.startActivity(this, geocode); - } - else { - showToast(res.getString(R.string.unknown_scan)); - } - } else if (resultCode == RESULT_CANCELED) { - // do nothing - } - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - - // context menu for offline button - if (v.getId() == R.id.search_offline) { - List<cgList> cacheLists = app.getLists(); - int listCount = cacheLists.size(); - menu.setHeaderTitle(res.getString(R.string.list_title)); - for (int i = 0; i < listCount; i++) { - cgList list = cacheLists.get(i); - menu.add(Menu.NONE, MENU_OPEN_LIST + list.id, Menu.NONE, list.title); - } - return; - } - - // standard context menu - menu.setHeaderTitle(res.getString(R.string.menu_filter)); - - //first add the most used types - menu.add(1, 0, 0, res.getString(R.string.all_types)); - menu.add(1, 1, 0, res.getString(R.string.traditional)); - menu.add(1, 2, 0, res.getString(R.string.multi)); - menu.add(1, 3, 0, res.getString(R.string.mystery)); - - // then add all other cache types sorted alphabetically - Map<String, String> allTypes = new HashMap<String, String>(cgBase.cacheTypesInv); - allTypes.remove("traditional"); - allTypes.remove("multi"); - allTypes.remove("mystery"); - List<String> sorted = new ArrayList<String>(allTypes.values()); - Collections.sort(sorted); - for (String choice : sorted) { - menu.add(1, menu.size(), 0, choice); - } - - // mark current filter as checked - menu.setGroupCheckable(1, true, true); - boolean foundItem = false; - int itemCount = menu.size(); - if (settings.cacheType != null) { - String typeTitle = cgBase.cacheTypesInv.get(settings.cacheType); - if (typeTitle != null) { - for (int i = 0; i < itemCount; i++) { - if (menu.getItem(i).getTitle().equals(typeTitle)) { - menu.getItem(i).setChecked(true); - foundItem = true; - break; - } - } - } - } - if (!foundItem) { - menu.getItem(0).setChecked(true); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int id = item.getItemId(); - - if (id == 0) { - settings.setCacheType(null); - setFilterTitle(); - - return true; - } else if (id > MENU_OPEN_LIST) { - int listId = id - MENU_OPEN_LIST; - settings.saveLastList(listId); - cgeocaches.startActivityOffline(context); - return true; - } else if (id > 0) { - String itemTitle = item.getTitle().toString(); - String choice = null; - for (Entry<String, String> entry : cgBase.cacheTypesInv.entrySet()) { - if (entry.getValue().equalsIgnoreCase(itemTitle)) { - choice = entry.getKey(); - break; - } - } - if (choice == null) { - settings.setCacheType(null); - } else { - settings.setCacheType(choice); - } - setFilterTitle(); - - return true; - } - - return false; - } - - private void setFilterTitle() { - if (filterTitle == null) { - filterTitle = (TextView) findViewById(R.id.filter_button_title); - } - if (settings.cacheType != null) { - filterTitle.setText(cgBase.cacheTypesInv.get(settings.cacheType)); - } else { - filterTitle.setText(res.getString(R.string.all)); - } - } - - private void init() { - if (initialized) { - return; - } - - initialized = true; - - settings.getLogin(); - settings.reloadCacheType(); - - if (app.firstRun) { - new Thread() { - - @Override - public void run() { - int status = base.login(); - - if (status == 1) { - app.firstRun = false; - } - } - }.start(); - } - - (new countBubbleUpdate()).start(); - (new cleanDatabase()).start(); - - if (settings.cacheType != null && cgBase.cacheTypesInv.containsKey(settings.cacheType) == false) { - settings.setCacheType(null); - } - - if (geo == null) { - geo = app.startGeo(context, geoUpdate, base, settings, 0, 0); - } - - navType = (TextView) findViewById(R.id.nav_type); - navAccuracy = (TextView) findViewById(R.id.nav_accuracy); - navLocation = (TextView) findViewById(R.id.nav_location); - - final View findOnMap = findViewById(R.id.map); - findOnMap.setClickable(true); - findOnMap.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - cgeoFindOnMap(v); - } - }); - - final View findByOffline = findViewById(R.id.search_offline); - findByOffline.setClickable(true); - findByOffline.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - cgeoFindByOffline(v); - } - }); - registerForContextMenu(findByOffline); - - (new countBubbleUpdate()).start(); - - final View advanced = findViewById(R.id.advanced_button); - advanced.setClickable(true); - advanced.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - cgeoSearch(v); - } - }); - - final View any = findViewById(R.id.any_button); - any.setClickable(true); - any.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - cgeoPoint(v); - } - }); - - final View filter = findViewById(R.id.filter_button); - filter.setClickable(true); - registerForContextMenu(filter); - filter.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - openContextMenu(v); - } - }); - - setFilterTitle(); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - if (navType == null || navLocation == null || navAccuracy == null) { - navType = (TextView) findViewById(R.id.nav_type); - navAccuracy = (TextView) findViewById(R.id.nav_accuracy); - navSatellites = (TextView) findViewById(R.id.nav_satellites); - navLocation = (TextView) findViewById(R.id.nav_location); - } - - if (geo.coordsNow != null) { - View findNearest = findViewById(R.id.nearest); - findNearest.setClickable(true); - findNearest.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - cgeoFindNearest(v); - } - }); - findNearest.setBackgroundResource(R.drawable.main_nearby); - - String satellites = null; - if (geo.satellitesVisible != null && geo.satellitesFixed != null && geo.satellitesFixed > 0) { - satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible; - } else if (geo.satellitesVisible != null) { - satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible; - } else { - satellites = ""; - } - navSatellites.setText(satellites); - - if (geo.gps == -1) { - navType.setText(res.getString(R.string.loc_last)); - } else if (geo.gps == 0) { - navType.setText(res.getString(R.string.loc_net)); - } else { - navType.setText(res.getString(R.string.loc_gps)); - } - - if (geo.accuracyNow != null) { - if (settings.units == cgSettings.unitsImperial) { - navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", (geo.accuracyNow * 3.2808399)) + " ft"); - } else { - navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", geo.accuracyNow) + " m"); - } - } else { - navAccuracy.setText(null); - } - - if (settings.showAddress == 1) { - if (addCoords == null) { - navLocation.setText(res.getString(R.string.loc_no_addr)); - } - if (addCoords == null || (geo.coordsNow.distanceTo(addCoords) > 0.5 && addressObtaining == false)) { - (new obtainAddress()).start(); - } - } else { - if (geo.altitudeNow != null) { - String humanAlt; - if (settings.units == cgSettings.unitsImperial) { - humanAlt = String.format("%.0f", (geo.altitudeNow * 3.2808399)) + " ft"; - } else { - humanAlt = String.format("%.0f", geo.altitudeNow) + " m"; - } - navLocation.setText(cgBase.formatCoords(geo.coordsNow, true) + " | " + humanAlt); - } else { - navLocation.setText(cgBase.formatCoords(geo.coordsNow, true)); - } - } - } else { - View findNearest = findViewById(R.id.nearest); - findNearest.setFocusable(false); - findNearest.setClickable(false); - findNearest.setOnClickListener(null); - findNearest.setBackgroundResource(R.drawable.main_nearby_disabled); - - navType.setText(null); - navAccuracy.setText(null); - navLocation.setText(res.getString(R.string.loc_trying)); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - public void cgeoFindOnMap(View v) { - findViewById(R.id.map).setPressed(true); - context.startActivity(new Intent(context, settings.getMapFactory().getMapClass())); - } - - public void cgeoFindNearest(View v) { - if (geo == null) { - return; - } - - findViewById(R.id.nearest).setPressed(true); - final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra("type", "nearest"); - cachesIntent.putExtra("latitude", geo.coordsNow.getLatitude()); - cachesIntent.putExtra("longitude", geo.coordsNow.getLongitude()); - cachesIntent.putExtra("cachetype", settings.cacheType); - context.startActivity(cachesIntent); - } - - public void cgeoFindByOffline(View v) { - findViewById(R.id.search_offline).setPressed(true); - final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra("type", "offline"); - context.startActivity(cachesIntent); - } - - public void cgeoSearch(View v) { - findViewById(R.id.advanced_button).setPressed(true); - context.startActivity(new Intent(context, cgeoadvsearch.class)); - } - - public void cgeoPoint(View v) { - findViewById(R.id.any_button).setPressed(true); - context.startActivity(new Intent(context, cgeopoint.class)); - } - - public void cgeoFilter(View v) { - findViewById(R.id.filter_button).setPressed(true); - findViewById(R.id.filter_button).performClick(); - } - - private class countBubbleUpdate extends Thread { - - @Override - public void run() { - if (app == null) { - return; - } - - int checks = 0; - while (app.storageStatus() == false) { - try { - wait(500); - checks++; - } catch (Exception e) { - // nothing; - } - - if (checks > 10) { - return; - } - } - - - countBubbleCnt = app.getAllStoredCachesCount(true, null, null); - - countBubbleHandler.sendEmptyMessage(0); - } - } - - private class cleanDatabase extends Thread { - - @Override - public void run() { - if (app == null) { - return; - } - if (cleanupRunning) { - return; - } - - boolean more = false; - if (version != settings.version) { - Log.i(cgSettings.tag, "Initializing hard cleanup - version changed from " + settings.version + " to " + version + "."); - - more = true; - } - - cleanupRunning = true; - app.cleanDatabase(more); - cleanupRunning = false; - - if (version != null && version > 0) { - SharedPreferences.Editor edit = prefs.edit(); - edit.putInt("version", version); - edit.commit(); - } - } - } - - private class obtainAddress extends Thread { - - public obtainAddress() { - setPriority(Thread.MIN_PRIORITY); - } - - @Override - public void run() { - if (geo == null) { - return; - } - if (addressObtaining) { - return; - } - addressObtaining = true; - - try { - Geocoder geocoder = new Geocoder(context, Locale.getDefault()); - - addresses = geocoder.getFromLocation(geo.coordsNow.getLatitude(), geo.coordsNow.getLongitude(), 1); - } catch (Exception e) { - Log.i(cgSettings.tag, "Failed to obtain address"); - } - - obtainAddressHandler.sendEmptyMessage(0); - - addressObtaining = false; - } - } - - public void showAbout(View view) { - context.startActivity(new Intent(context, cgeoabout.class)); - } - - public void goSearch(View view) { - onSearchRequested(); - } + private static final String SCAN_INTENT = "com.google.zxing.client.android.SCAN"; + private static final int MENU_ABOUT = 0; + private static final int MENU_HELPERS = 1; + private static final int MENU_SETTINGS = 2; + private static final int MENU_HISTORY = 3; + private static final int MENU_SCAN = 4; + private static final int SCAN_REQUEST_CODE = 1; + private static final int MENU_OPEN_LIST = 100; + + private Context context = null; + private Integer version = null; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private TextView navType = null; + private TextView navAccuracy = null; + private TextView navSatellites = null; + private TextView navLocation = null; + private TextView filterTitle = null; + private TextView countBubble = null; + private boolean cleanupRunning = false; + private int countBubbleCnt = 0; + private Geopoint addCoords = null; + private List<Address> addresses = null; + private boolean addressObtaining = false; + private boolean initialized = false; + private Handler countBubbleHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (countBubble == null) { + countBubble = (TextView) findViewById(R.id.offline_count); + } + + if (countBubbleCnt == 0) { + countBubble.setVisibility(View.GONE); + } else { + countBubble.setText(Integer.toString(countBubbleCnt)); + countBubble.bringToFront(); + countBubble.setVisibility(View.VISIBLE); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeo.countBubbleHander: " + e.toString()); + } + } + }; + private Handler obtainAddressHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (CollectionUtils.isNotEmpty(addresses)) { + final Address address = addresses.get(0); + final StringBuilder addText = new StringBuilder(); + + if (address.getCountryName() != null) { + addText.append(address.getCountryName()); + } + if (address.getLocality() != null) { + if (addText.length() > 0) { + addText.append(", "); + } + addText.append(address.getLocality()); + } else if (address.getAdminArea() != null) { + if (addText.length() > 0) { + addText.append(", "); + } + addText.append(address.getAdminArea()); + } + + addCoords = geo.coordsNow; + + if (navLocation == null) { + navLocation = (TextView) findViewById(R.id.nav_location); + } + + navLocation.setText(addText.toString()); + } + } catch (Exception e) { + // nothing + } + + addresses = null; + } + }; + + public cgeo() { + super("c:geo-main-screen"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + context = this; + app.setAction(null); + + app.cleanGeo(); + app.cleanDir(); + + setContentView(R.layout.main); + setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); // type to search + + try { + PackageManager manager = this.getPackageManager(); + PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); + + version = info.versionCode; + + Log.i(cgSettings.tag, "Starting " + info.packageName + " " + info.versionCode + " a.k.a " + info.versionName + "..."); + + info = null; + manager = null; + } catch (Exception e) { + Log.i(cgSettings.tag, "No info."); + } + + try { + if (settings.helper == 0) { + RelativeLayout helper = (RelativeLayout) findViewById(R.id.helper); + if (helper != null) { + helper.setVisibility(View.VISIBLE); + helper.setClickable(true); + helper.setOnClickListener(new View.OnClickListener() { + + public void onClick(View view) { + ActivityMixin.goManual(context, "c:geo-intro"); + view.setVisibility(View.GONE); + } + }); + + final SharedPreferences.Editor edit = getSharedPreferences(cgSettings.preferences, 0).edit(); + edit.putInt("helper", 1); + edit.commit(); + } + } + } catch (Exception e) { + // nothing + } + + init(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + init(); + } + + @Override + public void onDestroy() { + initialized = false; + + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + initialized = false; + + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + initialized = false; + + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, MENU_SETTINGS, 0, res.getString(R.string.menu_settings)).setIcon(android.R.drawable.ic_menu_preferences); + menu.add(0, MENU_HISTORY, 0, res.getString(R.string.menu_history)).setIcon(android.R.drawable.ic_menu_recent_history); + menu.add(0, MENU_HELPERS, 0, res.getString(R.string.menu_helpers)).setIcon(android.R.drawable.ic_menu_add); + menu.add(0, MENU_SCAN, 0, res.getString(R.string.menu_scan)).setIcon(android.R.drawable.ic_menu_camera); + menu.add(0, MENU_ABOUT, 0, res.getString(R.string.menu_about)).setIcon(android.R.drawable.ic_menu_help); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.findItem(MENU_SCAN); + if (item != null) { + item.setEnabled(isIntentAvailable(this, SCAN_INTENT)); + } + return true; + } + + private static boolean isIntentAvailable(Context context, String intent) { + final PackageManager packageManager = context.getPackageManager(); + final List<ResolveInfo> list = packageManager.queryIntentActivities( + new Intent(intent), PackageManager.MATCH_DEFAULT_ONLY); + + return list.size() > 0; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int id = item.getItemId(); + switch (id) { + case MENU_ABOUT: + showAbout(null); + return true; + case MENU_HELPERS: + context.startActivity(new Intent(context, cgeohelpers.class)); + return true; + case MENU_SETTINGS: + context.startActivity(new Intent(context, cgeoinit.class)); + return true; + case MENU_HISTORY: + final Intent cachesIntent = new Intent(context, cgeocaches.class); + cachesIntent.putExtra("type", "history"); + context.startActivity(cachesIntent); + return true; + case MENU_SCAN: + Intent intent = new Intent(SCAN_INTENT); + intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); + startActivityForResult(intent, SCAN_REQUEST_CODE); + return true; + default: + break; + } + + return false; + } + + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + if (requestCode == SCAN_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + String scan = intent.getStringExtra("SCAN_RESULT"); + if (StringUtils.isBlank(scan)) { + return; + } + String host = "http://coord.info/"; + if (scan.toLowerCase().startsWith(host)) { + String geocode = scan.substring(host.length()).trim(); + cgeodetail.startActivity(this, geocode); + } + else { + showToast(res.getString(R.string.unknown_scan)); + } + } else if (resultCode == RESULT_CANCELED) { + // do nothing + } + } + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + + // context menu for offline button + if (v.getId() == R.id.search_offline) { + List<cgList> cacheLists = app.getLists(); + int listCount = cacheLists.size(); + menu.setHeaderTitle(res.getString(R.string.list_title)); + for (int i = 0; i < listCount; i++) { + cgList list = cacheLists.get(i); + menu.add(Menu.NONE, MENU_OPEN_LIST + list.id, Menu.NONE, list.title); + } + return; + } + + // standard context menu + menu.setHeaderTitle(res.getString(R.string.menu_filter)); + + //first add the most used types + menu.add(1, 0, 0, res.getString(R.string.all_types)); + menu.add(1, 1, 0, res.getString(R.string.traditional)); + menu.add(1, 2, 0, res.getString(R.string.multi)); + menu.add(1, 3, 0, res.getString(R.string.mystery)); + + // then add all other cache types sorted alphabetically + Map<String, String> allTypes = new HashMap<String, String>(cgBase.cacheTypesInv); + allTypes.remove("traditional"); + allTypes.remove("multi"); + allTypes.remove("mystery"); + List<String> sorted = new ArrayList<String>(allTypes.values()); + Collections.sort(sorted); + for (String choice : sorted) { + menu.add(1, menu.size(), 0, choice); + } + + // mark current filter as checked + menu.setGroupCheckable(1, true, true); + boolean foundItem = false; + int itemCount = menu.size(); + if (settings.cacheType != null) { + String typeTitle = cgBase.cacheTypesInv.get(settings.cacheType); + if (typeTitle != null) { + for (int i = 0; i < itemCount; i++) { + if (menu.getItem(i).getTitle().equals(typeTitle)) { + menu.getItem(i).setChecked(true); + foundItem = true; + break; + } + } + } + } + if (!foundItem) { + menu.getItem(0).setChecked(true); + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + final int id = item.getItemId(); + + if (id == 0) { + settings.setCacheType(null); + setFilterTitle(); + + return true; + } else if (id > MENU_OPEN_LIST) { + int listId = id - MENU_OPEN_LIST; + settings.saveLastList(listId); + cgeocaches.startActivityOffline(context); + return true; + } else if (id > 0) { + String itemTitle = item.getTitle().toString(); + String choice = null; + for (Entry<String, String> entry : cgBase.cacheTypesInv.entrySet()) { + if (entry.getValue().equalsIgnoreCase(itemTitle)) { + choice = entry.getKey(); + break; + } + } + if (choice == null) { + settings.setCacheType(null); + } else { + settings.setCacheType(choice); + } + setFilterTitle(); + + return true; + } + + return false; + } + + private void setFilterTitle() { + if (filterTitle == null) { + filterTitle = (TextView) findViewById(R.id.filter_button_title); + } + if (settings.cacheType != null) { + filterTitle.setText(cgBase.cacheTypesInv.get(settings.cacheType)); + } else { + filterTitle.setText(res.getString(R.string.all)); + } + } + + private void init() { + if (initialized) { + return; + } + + initialized = true; + + settings.getLogin(); + settings.reloadCacheType(); + + if (app.firstRun) { + new Thread() { + + @Override + public void run() { + int status = base.login(); + + if (status == 1) { + app.firstRun = false; + } + } + }.start(); + } + + (new countBubbleUpdate()).start(); + (new cleanDatabase()).start(); + + if (settings.cacheType != null && cgBase.cacheTypesInv.containsKey(settings.cacheType) == false) { + settings.setCacheType(null); + } + + if (geo == null) { + geo = app.startGeo(context, geoUpdate, base, settings, 0, 0); + } + + navType = (TextView) findViewById(R.id.nav_type); + navAccuracy = (TextView) findViewById(R.id.nav_accuracy); + navLocation = (TextView) findViewById(R.id.nav_location); + + final View findOnMap = findViewById(R.id.map); + findOnMap.setClickable(true); + findOnMap.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + cgeoFindOnMap(v); + } + }); + + final View findByOffline = findViewById(R.id.search_offline); + findByOffline.setClickable(true); + findByOffline.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + cgeoFindByOffline(v); + } + }); + registerForContextMenu(findByOffline); + + (new countBubbleUpdate()).start(); + + final View advanced = findViewById(R.id.advanced_button); + advanced.setClickable(true); + advanced.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + cgeoSearch(v); + } + }); + + final View any = findViewById(R.id.any_button); + any.setClickable(true); + any.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + cgeoPoint(v); + } + }); + + final View filter = findViewById(R.id.filter_button); + filter.setClickable(true); + registerForContextMenu(filter); + filter.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + openContextMenu(v); + } + }); + + setFilterTitle(); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + if (navType == null || navLocation == null || navAccuracy == null) { + navType = (TextView) findViewById(R.id.nav_type); + navAccuracy = (TextView) findViewById(R.id.nav_accuracy); + navSatellites = (TextView) findViewById(R.id.nav_satellites); + navLocation = (TextView) findViewById(R.id.nav_location); + } + + if (geo.coordsNow != null) { + View findNearest = findViewById(R.id.nearest); + findNearest.setClickable(true); + findNearest.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + cgeoFindNearest(v); + } + }); + findNearest.setBackgroundResource(R.drawable.main_nearby); + + String satellites = null; + if (geo.satellitesVisible != null && geo.satellitesFixed != null && geo.satellitesFixed > 0) { + satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible; + } else if (geo.satellitesVisible != null) { + satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible; + } else { + satellites = ""; + } + navSatellites.setText(satellites); + + if (geo.gps == -1) { + navType.setText(res.getString(R.string.loc_last)); + } else if (geo.gps == 0) { + navType.setText(res.getString(R.string.loc_net)); + } else { + navType.setText(res.getString(R.string.loc_gps)); + } + + if (geo.accuracyNow != null) { + if (settings.units == cgSettings.unitsImperial) { + navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", (geo.accuracyNow * 3.2808399)) + " ft"); + } else { + navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", geo.accuracyNow) + " m"); + } + } else { + navAccuracy.setText(null); + } + + if (settings.showAddress == 1) { + if (addCoords == null) { + navLocation.setText(res.getString(R.string.loc_no_addr)); + } + if (addCoords == null || (geo.coordsNow.distanceTo(addCoords) > 0.5 && addressObtaining == false)) { + (new obtainAddress()).start(); + } + } else { + if (geo.altitudeNow != null) { + String humanAlt; + if (settings.units == cgSettings.unitsImperial) { + humanAlt = String.format("%.0f", (geo.altitudeNow * 3.2808399)) + " ft"; + } else { + humanAlt = String.format("%.0f", geo.altitudeNow) + " m"; + } + navLocation.setText(cgBase.formatCoords(geo.coordsNow, true) + " | " + humanAlt); + } else { + navLocation.setText(cgBase.formatCoords(geo.coordsNow, true)); + } + } + } else { + View findNearest = findViewById(R.id.nearest); + findNearest.setFocusable(false); + findNearest.setClickable(false); + findNearest.setOnClickListener(null); + findNearest.setBackgroundResource(R.drawable.main_nearby_disabled); + + navType.setText(null); + navAccuracy.setText(null); + navLocation.setText(res.getString(R.string.loc_trying)); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + public void cgeoFindOnMap(View v) { + findViewById(R.id.map).setPressed(true); + context.startActivity(new Intent(context, settings.getMapFactory().getMapClass())); + } + + public void cgeoFindNearest(View v) { + if (geo == null) { + return; + } + + findViewById(R.id.nearest).setPressed(true); + final Intent cachesIntent = new Intent(context, cgeocaches.class); + cachesIntent.putExtra("type", "nearest"); + cachesIntent.putExtra("latitude", geo.coordsNow.getLatitude()); + cachesIntent.putExtra("longitude", geo.coordsNow.getLongitude()); + cachesIntent.putExtra("cachetype", settings.cacheType); + context.startActivity(cachesIntent); + } + + public void cgeoFindByOffline(View v) { + findViewById(R.id.search_offline).setPressed(true); + final Intent cachesIntent = new Intent(context, cgeocaches.class); + cachesIntent.putExtra("type", "offline"); + context.startActivity(cachesIntent); + } + + public void cgeoSearch(View v) { + findViewById(R.id.advanced_button).setPressed(true); + context.startActivity(new Intent(context, cgeoadvsearch.class)); + } + + public void cgeoPoint(View v) { + findViewById(R.id.any_button).setPressed(true); + context.startActivity(new Intent(context, cgeopoint.class)); + } + + public void cgeoFilter(View v) { + findViewById(R.id.filter_button).setPressed(true); + findViewById(R.id.filter_button).performClick(); + } + + private class countBubbleUpdate extends Thread { + + @Override + public void run() { + if (app == null) { + return; + } + + int checks = 0; + while (app.storageStatus() == false) { + try { + wait(500); + checks++; + } catch (Exception e) { + // nothing; + } + + if (checks > 10) { + return; + } + } + + countBubbleCnt = app.getAllStoredCachesCount(true, null, null); + + countBubbleHandler.sendEmptyMessage(0); + } + } + + private class cleanDatabase extends Thread { + + @Override + public void run() { + if (app == null) { + return; + } + if (cleanupRunning) { + return; + } + + boolean more = false; + if (version != settings.version) { + Log.i(cgSettings.tag, "Initializing hard cleanup - version changed from " + settings.version + " to " + version + "."); + + more = true; + } + + cleanupRunning = true; + app.cleanDatabase(more); + cleanupRunning = false; + + if (version != null && version > 0) { + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("version", version); + edit.commit(); + } + } + } + + private class obtainAddress extends Thread { + + public obtainAddress() { + setPriority(Thread.MIN_PRIORITY); + } + + @Override + public void run() { + if (geo == null) { + return; + } + if (addressObtaining) { + return; + } + addressObtaining = true; + + try { + Geocoder geocoder = new Geocoder(context, Locale.getDefault()); + + addresses = geocoder.getFromLocation(geo.coordsNow.getLatitude(), geo.coordsNow.getLongitude(), 1); + } catch (Exception e) { + Log.i(cgSettings.tag, "Failed to obtain address"); + } + + obtainAddressHandler.sendEmptyMessage(0); + + addressObtaining = false; + } + } + + public void showAbout(View view) { + context.startActivity(new Intent(context, cgeoabout.class)); + } + + public void goSearch(View view) { + onSearchRequested(); + } } diff --git a/src/cgeo/geocaching/cgeoabout.java b/src/cgeo/geocaching/cgeoabout.java index 5241a13..1c09614 100644 --- a/src/cgeo/geocaching/cgeoabout.java +++ b/src/cgeo/geocaching/cgeoabout.java @@ -1,5 +1,7 @@ package cgeo.geocaching; +import cgeo.geocaching.activity.AbstractActivity; + import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -9,81 +11,80 @@ import android.text.method.LinkMovementMethod; import android.util.Log; import android.view.View; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; public class cgeoabout extends AbstractActivity { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - setTheme(); - setContentView(R.layout.about); - setTitle(res.getString(R.string.about)); + setTheme(); + setContentView(R.layout.about); + setTitle(res.getString(R.string.about)); - init(); - } + init(); + } - @Override - public void onResume() { - super.onResume(); + @Override + public void onResume() { + super.onResume(); - settings.load(); - } + settings.load(); + } - @Override - public void onDestroy() { - super.onDestroy(); - } + @Override + public void onDestroy() { + super.onDestroy(); + } - private void init() { - try { - PackageManager manager = this.getPackageManager(); - PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); + private void init() { + try { + PackageManager manager = this.getPackageManager(); + PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); - setTitle(res.getString(R.string.about) + " (ver. " + info.versionName + ")"); + setTitle(res.getString(R.string.about) + " (ver. " + info.versionName + ")"); - manager = null; + manager = null; - ((TextView)findViewById(R.id.contributors)).setMovementMethod(LinkMovementMethod.getInstance()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoabout.init: Failed to obtain package version."); - } - } + ((TextView) findViewById(R.id.contributors)).setMovementMethod(LinkMovementMethod.getInstance()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoabout.init: Failed to obtain package version."); + } + } - public void donateMore(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FMLNN8GXZKJEE"))); - //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N2FKGNCPPRUVE"))); - //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2Z69QWLRCBE9N&lc=US&item_name=c%3ageo¤cy_code=EUR&amount=15&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"))); - } + public void donateMore(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FMLNN8GXZKJEE"))); + //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N2FKGNCPPRUVE"))); + //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2Z69QWLRCBE9N&lc=US&item_name=c%3ageo¤cy_code=EUR&amount=15&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"))); + } - public void donateLess(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FMLNN8GXZKJEE"))); - //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4PRD9CX4Y8XR6"))); - //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2Z69QWLRCBE9N&lc=US&item_name=c%3ageo¤cy_code=EUR&amount=7&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"))); - } + public void donateLess(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FMLNN8GXZKJEE"))); + //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4PRD9CX4Y8XR6"))); + //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2Z69QWLRCBE9N&lc=US&item_name=c%3ageo¤cy_code=EUR&amount=7&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"))); + } - public void author(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://carnero.cc/"))); - } + public void author(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://carnero.cc/"))); + } - public void support(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:support@cgeo.org"))); - } + public void support(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:support@cgeo.org"))); + } - public void website(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.cgeo.org/"))); - } + public void website(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.cgeo.org/"))); + } - public void facebook(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/pages/cgeo/297269860090"))); - } + public void facebook(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/pages/cgeo/297269860090"))); + } - public void twitter(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://twitter.com/android_gc"))); - } + public void twitter(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://twitter.com/android_gc"))); + } - public void nutshellmanual(View view) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.cgeo.org/"))); - } + public void nutshellmanual(View view) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.cgeo.org/"))); + } } diff --git a/src/cgeo/geocaching/cgeoaddresses.java b/src/cgeo/geocaching/cgeoaddresses.java index 2320cb9..0261349 100644 --- a/src/cgeo/geocaching/cgeoaddresses.java +++ b/src/cgeo/geocaching/cgeoaddresses.java @@ -1,8 +1,6 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import cgeo.geocaching.activity.AbstractActivity; import android.app.ProgressDialog; import android.content.Intent; @@ -16,162 +14,165 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; -import cgeo.geocaching.activity.AbstractActivity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; public class cgeoaddresses extends AbstractActivity { - private final List<Address> addresses = new ArrayList<Address>(); - private String keyword = null; - private LayoutInflater inflater = null; - private LinearLayout addList = null; - private ProgressDialog waitDialog = null; - private Handler loadPlacesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (addList == null) { - addList = (LinearLayout) findViewById(R.id.address_list); - } - - if (addresses.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - showToast(res.getString(R.string.err_search_address_no_match)); - - finish(); - return; - } else { - LinearLayout oneAddPre = null; - for (Address address : addresses) { - oneAddPre = (LinearLayout) inflater.inflate(R.layout.address_button, null); - - Button oneAdd = (Button) oneAddPre.findViewById(R.id.button); - int index = 0; - StringBuilder allAdd = new StringBuilder(); - StringBuilder allAddLine = new StringBuilder(); - - while (address.getAddressLine(index) != null) { - if (allAdd.length() > 0) { - allAdd.append('\n'); - } - if (allAddLine.length() > 0) { - allAddLine.append("; "); - } - - allAdd.append(address.getAddressLine(index)); - allAddLine.append(address.getAddressLine(index)); - - index++; - } - - oneAdd.setText(allAdd.toString()); - oneAdd.setLines(allAdd.toString().split("\n").length); - oneAdd.setClickable(true); - oneAdd.setOnClickListener(new buttonListener(address.getLatitude(), address.getLongitude(), allAddLine.toString())); - addList.addView(oneAddPre); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgeoaddresses.loadCachesHandler: " + e.toString()); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - inflater = getLayoutInflater(); - - setTheme(); - setContentView(R.layout.addresses); - setTitle(res.getString(R.string.search_address_result)); - - // get parameters - Bundle extras = getIntent().getExtras(); - - // try to get data from extras - if (extras != null) { - keyword = extras.getString("keyword"); - } - - if (keyword == null) { - showToast(res.getString(R.string.err_search_address_forgot)); - finish(); - return; - } - - waitDialog = ProgressDialog.show(this, res.getString(R.string.search_address_started), keyword, true); - waitDialog.setCancelable(true); - - (new loadPlaces()).start(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - private class loadPlaces extends Thread { - - @Override - public void run() { - Geocoder geocoder = new Geocoder(cgeoaddresses.this, Locale.getDefault()); - try { - List<Address> knownLocations = geocoder.getFromLocationName(keyword, 20); - - addresses.clear(); - for (Address address : knownLocations) { - addresses.add(address); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoaddresses.loadPlaces.run: " + e.toString()); - } - - loadPlacesHandler.sendMessage(new Message()); - } - } - - private class buttonListener implements View.OnClickListener { - - private Double latitude = null; - private Double longitude = null; - private String address = null; - - public buttonListener(Double latitudeIn, Double longitudeIn, String addressIn) { - latitude = latitudeIn; - longitude = longitudeIn; - address = addressIn; - } - - public void onClick(View arg0) { - Intent addressIntent = new Intent(cgeoaddresses.this, cgeocaches.class); - addressIntent.putExtra("type", "address"); - addressIntent.putExtra("latitude", (Double) latitude); - addressIntent.putExtra("longitude", (Double) longitude); - addressIntent.putExtra("address", (String) address); - addressIntent.putExtra("cachetype", settings.cacheType); - startActivity(addressIntent); - - finish(); - return; - } - } + private final List<Address> addresses = new ArrayList<Address>(); + private String keyword = null; + private LayoutInflater inflater = null; + private LinearLayout addList = null; + private ProgressDialog waitDialog = null; + private Handler loadPlacesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (addList == null) { + addList = (LinearLayout) findViewById(R.id.address_list); + } + + if (addresses.isEmpty()) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + showToast(res.getString(R.string.err_search_address_no_match)); + + finish(); + return; + } else { + LinearLayout oneAddPre = null; + for (Address address : addresses) { + oneAddPre = (LinearLayout) inflater.inflate(R.layout.address_button, null); + + Button oneAdd = (Button) oneAddPre.findViewById(R.id.button); + int index = 0; + StringBuilder allAdd = new StringBuilder(); + StringBuilder allAddLine = new StringBuilder(); + + while (address.getAddressLine(index) != null) { + if (allAdd.length() > 0) { + allAdd.append('\n'); + } + if (allAddLine.length() > 0) { + allAddLine.append("; "); + } + + allAdd.append(address.getAddressLine(index)); + allAddLine.append(address.getAddressLine(index)); + + index++; + } + + oneAdd.setText(allAdd.toString()); + oneAdd.setLines(allAdd.toString().split("\n").length); + oneAdd.setClickable(true); + oneAdd.setOnClickListener(new buttonListener(address.getLatitude(), address.getLongitude(), allAddLine.toString())); + addList.addView(oneAddPre); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgeoaddresses.loadCachesHandler: " + e.toString()); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + inflater = getLayoutInflater(); + + setTheme(); + setContentView(R.layout.addresses); + setTitle(res.getString(R.string.search_address_result)); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + if (extras != null) { + keyword = extras.getString("keyword"); + } + + if (keyword == null) { + showToast(res.getString(R.string.err_search_address_forgot)); + finish(); + return; + } + + waitDialog = ProgressDialog.show(this, res.getString(R.string.search_address_started), keyword, true); + waitDialog.setCancelable(true); + + (new loadPlaces()).start(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + private class loadPlaces extends Thread { + + @Override + public void run() { + Geocoder geocoder = new Geocoder(cgeoaddresses.this, Locale.getDefault()); + try { + List<Address> knownLocations = geocoder.getFromLocationName(keyword, 20); + + addresses.clear(); + for (Address address : knownLocations) { + addresses.add(address); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoaddresses.loadPlaces.run: " + e.toString()); + } + + loadPlacesHandler.sendMessage(new Message()); + } + } + + private class buttonListener implements View.OnClickListener { + + private Double latitude = null; + private Double longitude = null; + private String address = null; + + public buttonListener(Double latitudeIn, Double longitudeIn, String addressIn) { + latitude = latitudeIn; + longitude = longitudeIn; + address = addressIn; + } + + public void onClick(View arg0) { + Intent addressIntent = new Intent(cgeoaddresses.this, cgeocaches.class); + addressIntent.putExtra("type", "address"); + addressIntent.putExtra("latitude", (Double) latitude); + addressIntent.putExtra("longitude", (Double) longitude); + addressIntent.putExtra("address", (String) address); + addressIntent.putExtra("cachetype", settings.cacheType); + startActivity(addressIntent); + + finish(); + return; + } + } } diff --git a/src/cgeo/geocaching/cgeoadvsearch.java b/src/cgeo/geocaching/cgeoadvsearch.java index 70db229..e70e331 100644 --- a/src/cgeo/geocaching/cgeoadvsearch.java +++ b/src/cgeo/geocaching/cgeoadvsearch.java @@ -1,8 +1,7 @@ package cgeo.geocaching; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; @@ -22,484 +21,486 @@ import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class cgeoadvsearch extends AbstractActivity { - private static final int MENU_SEARCH_OWN_CACHES = 1; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private EditText latEdit = null; - private EditText lonEdit = null; - private String[] geocodesInCache = null; - - public cgeoadvsearch() { - super("c:geo-search"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - app.setAction(null); - - // search query - Intent intent = getIntent(); - if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - final String query = intent.getStringExtra(SearchManager.QUERY); - final boolean found = instantSearch(query); - - if (found) { - finish(); - - return; - } - } - - setTheme(); - setContentView(R.layout.search); - setTitle(res.getString(R.string.search)); - - init(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - init(); - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } + private static final int MENU_SEARCH_OWN_CACHES = 1; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private EditText latEdit = null; + private EditText lonEdit = null; + private String[] geocodesInCache = null; + + public cgeoadvsearch() { + super("c:geo-search"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + app.setAction(null); + + // search query + Intent intent = getIntent(); + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + final String query = intent.getStringExtra(SearchManager.QUERY); + final boolean found = instantSearch(query); + + if (found) { + finish(); + + return; + } + } + + setTheme(); + setContentView(R.layout.search); + setTitle(res.getString(R.string.search)); + + init(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + init(); + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + private boolean instantSearch(String query) { + boolean found = false; + + final Pattern gcCode = Pattern.compile("^GC[0-9A-Z]+$", Pattern.CASE_INSENSITIVE); + final Pattern tbCode = Pattern.compile("^TB[0-9A-Z]+$", Pattern.CASE_INSENSITIVE); + final Matcher gcCodeM = gcCode.matcher(query); + final Matcher tbCodeM = tbCode.matcher(query); - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - private boolean instantSearch(String query) { - boolean found = false; - - final Pattern gcCode = Pattern.compile("^GC[0-9A-Z]+$", Pattern.CASE_INSENSITIVE); - final Pattern tbCode = Pattern.compile("^TB[0-9A-Z]+$", Pattern.CASE_INSENSITIVE); - final Matcher gcCodeM = gcCode.matcher(query); - final Matcher tbCodeM = tbCode.matcher(query); - - try { - if (gcCodeM.find()) { // GC-code - final Intent cachesIntent = new Intent(this, cgeodetail.class); - cachesIntent.putExtra("geocode", query.trim().toUpperCase()); - startActivity(cachesIntent); - - found = true; - } else if (tbCodeM.find()) { // TB-code - final Intent trackablesIntent = new Intent(this, cgeotrackable.class); - trackablesIntent.putExtra("geocode", query.trim().toUpperCase()); - startActivity(trackablesIntent); - - found = true; - } else { // keyword (fallback) - final Intent cachesIntent = new Intent(this, cgeocaches.class); - cachesIntent.putExtra("type", "keyword"); - cachesIntent.putExtra("keyword", query); - cachesIntent.putExtra("cachetype", settings.cacheType); - startActivity(cachesIntent); - - found = true; - } - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeoadvsearch.instantSearch: " + e.toString()); - } - - return found; - } - - private void init() { - settings.getLogin(); - settings.reloadCacheType(); - - if (settings.cacheType != null && cgBase.cacheTypesInv.containsKey(settings.cacheType) == false) { - settings.setCacheType(null); - } - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - ((Button) findViewById(R.id.buttonLatitude)).setOnClickListener(new findByCoordsAction()); - ((Button) findViewById(R.id.buttonLongitude)).setOnClickListener(new findByCoordsAction()); - - final Button findByCoords = (Button) findViewById(R.id.search_coordinates); - findByCoords.setOnClickListener(new findByCoordsListener()); - - ((EditText) findViewById(R.id.address)).setOnEditorActionListener(new findByAddressAction()); - - final Button findByAddress = (Button) findViewById(R.id.search_address); - findByAddress.setOnClickListener(new findByAddressListener()); - - final AutoCompleteTextView geocodeEdit = (AutoCompleteTextView) findViewById(R.id.geocode); - geocodeEdit.setOnEditorActionListener(new findByGeocodeAction()); - geocodesInCache = app.geocodesInCache(); - if (geocodesInCache != null) { - final ArrayAdapter<String> geocodesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, geocodesInCache); - geocodeEdit.setAdapter(geocodesAdapter); - } - - final Button displayByGeocode = (Button) findViewById(R.id.display_geocode); - displayByGeocode.setOnClickListener(new findByGeocodeListener()); - - ((EditText) findViewById(R.id.keyword)).setOnEditorActionListener(new findByKeywordAction()); - - final Button findByKeyword = (Button) findViewById(R.id.search_keyword); - findByKeyword.setOnClickListener(new findByKeywordListener()); - - ((EditText) findViewById(R.id.username)).setOnEditorActionListener(new findByUsernameAction()); - - final Button findByUserName = (Button) findViewById(R.id.search_username); - findByUserName.setOnClickListener(new findByUsernameListener()); - - ((EditText) findViewById(R.id.owner)).setOnEditorActionListener(new findByOwnerAction()); - - final Button findByOwner = (Button) findViewById(R.id.search_owner); - findByOwner.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View arg0) { - findByOwnerFn(); - } - }); - - EditText trackable = (EditText) findViewById(R.id.trackable); - trackable.setOnEditorActionListener(new findTrackableAction()); - - final Button displayTrackable = (Button) findViewById(R.id.display_trackable); - displayTrackable.setOnClickListener(new findTrackableListener()); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - if (latEdit == null) { - latEdit = (EditText) findViewById(R.id.latitude); - } - if (lonEdit == null) { - lonEdit = (EditText) findViewById(R.id.longitude); - } - - if (geo.coordsNow != null) { - latEdit.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); - lonEdit.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class findByCoordsAction implements OnClickListener { - - @Override - public void onClick(View arg0) { - cgeocoords coordsDialog = new cgeocoords(cgeoadvsearch.this, settings, null, geo); - coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { - @Override - public void update(Geopoint gp) { - ((Button) findViewById(R.id.buttonLatitude)).setText(cgBase.formatLatitude(gp.getLatitude(), true)); - ((Button) findViewById(R.id.buttonLongitude)).setText(cgBase.formatLongitude(gp.getLongitude(), true)); - } - }); - coordsDialog.show(); - } - } - - private class findByCoordsListener implements View.OnClickListener { - - public void onClick(View arg0) { - findByCoordsFn(); - } - } - - private void findByCoordsFn() { - final Button latView = (Button) findViewById(R.id.buttonLatitude); - final Button lonView = (Button) findViewById(R.id.buttonLongitude); - final String latText = latView.getText().toString(); - final String lonText = lonView.getText().toString(); - - if (StringUtils.isEmpty(latText) || StringUtils.isEmpty(lonText)) { // TODO: now coordinates - latView.setText(cgBase.formatLatitude(geo.coordsNow.getLatitude(), true)); - lonView.setText(cgBase.formatLongitude(geo.coordsNow.getLongitude(), true)); - } else { - Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); - Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lat"); - - if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lat)); - return; - } - - if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lon)); - return; - } - - final Intent cachesIntent = new Intent(this, cgeocaches.class); - cachesIntent.putExtra("type", "coordinate"); - cachesIntent.putExtra("latitude", (Double) latParsed.get("coordinate")); - cachesIntent.putExtra("longitude", (Double) lonParsed.get("coordinate")); - cachesIntent.putExtra("cachetype", settings.cacheType); - startActivity(cachesIntent); - } - } - - private class findByKeywordAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findByKeywordFn(); - return true; - } - - return false; - } - } - - private class findByKeywordListener implements View.OnClickListener { - - public void onClick(View arg0) { - findByKeywordFn(); - } - } - - private void findByKeywordFn() { - // find caches by coordinates - String keyText = ((EditText) findViewById(R.id.keyword)).getText().toString(); - - if (StringUtils.isBlank(keyText)) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_keyword)); - return; - } - - final Intent cachesIntent = new Intent(this, cgeocaches.class); - cachesIntent.putExtra("type", "keyword"); - cachesIntent.putExtra("keyword", keyText); - cachesIntent.putExtra("cachetype", settings.cacheType); - startActivity(cachesIntent); - } - - private class findByAddressAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findByAddressFn(); - return true; - } - - return false; - } - } - - private class findByAddressListener implements View.OnClickListener { - - public void onClick(View arg0) { - findByAddressFn(); - } - } - - private void findByAddressFn() { - final String addText = ((EditText) findViewById(R.id.address)).getText().toString(); - - if (StringUtils.isBlank(addText)) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_address)); - return; - } - - final Intent addressesIntent = new Intent(this, cgeoaddresses.class); - addressesIntent.putExtra("keyword", addText); - startActivity(addressesIntent); - } - - private class findByUsernameAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findByUsernameFn(); - return true; - } - - return false; - } - } - - private class findByUsernameListener implements View.OnClickListener { - - public void onClick(View arg0) { - findByUsernameFn(); - } - } - - public void findByUsernameFn() { - final String usernameText = ((EditText) findViewById(R.id.username)).getText().toString(); - - if (StringUtils.isBlank(usernameText)) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_user)); - return; - } - - final Intent cachesIntent = new Intent(this, cgeocaches.class); - cachesIntent.putExtra("type", "username"); - cachesIntent.putExtra("username", usernameText); - cachesIntent.putExtra("cachetype", settings.cacheType); - startActivity(cachesIntent); - } - - private class findByOwnerAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findByOwnerFn(); - return true; - } - - return false; - } - } - - private void findByOwnerFn() { - findByOwnerFn(((EditText) findViewById(R.id.owner)).getText().toString()); - } - - private void findByOwnerFn(String userName) { - final String usernameText = StringUtils.trimToEmpty(userName); - - if (StringUtils.isBlank(usernameText)) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_user)); - return; - } - - final Intent cachesIntent = new Intent(this, cgeocaches.class); - cachesIntent.putExtra("type", "owner"); - cachesIntent.putExtra("username", usernameText); - cachesIntent.putExtra("cachetype", settings.cacheType); - startActivity(cachesIntent); - } - - private class findByGeocodeAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findByGeocodeFn(); - return true; - } - - return false; - } - } - - private class findByGeocodeListener implements View.OnClickListener { - - public void onClick(View arg0) { - findByGeocodeFn(); - } - } - - private void findByGeocodeFn() { - final String geocodeText = ((EditText) findViewById(R.id.geocode)).getText().toString(); - - if (StringUtils.isBlank(geocodeText) || geocodeText.equalsIgnoreCase("GC")) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_gccode)); - return; - } - - cgeodetail.startActivity(this, geocodeText); - } - - private class findTrackableAction implements TextView.OnEditorActionListener { - - @Override - public boolean onEditorAction(TextView view, int action, KeyEvent event) { - if (action == EditorInfo.IME_ACTION_GO) { - findTrackableFn(); - return true; - } - - return false; - } - } - - private class findTrackableListener implements View.OnClickListener { - - public void onClick(View arg0) { - findTrackableFn(); - } - } - - private void findTrackableFn() { - final String trackableText = ((EditText) findViewById(R.id.trackable)).getText().toString(); - - if (StringUtils.isBlank(trackableText)|| trackableText.equalsIgnoreCase("TB")) { - helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_tb)); - return; - } - - final Intent trackablesIntent = new Intent(this, cgeotrackable.class); - trackablesIntent.putExtra("geocode", trackableText.toUpperCase()); - startActivity(trackablesIntent); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, MENU_SEARCH_OWN_CACHES, 0, res.getString(R.string.search_own_caches)); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == MENU_SEARCH_OWN_CACHES) { - findByOwnerFn(settings.getUsername()); - return true; - } - return super.onOptionsItemSelected(item); - } + try { + if (gcCodeM.find()) { // GC-code + final Intent cachesIntent = new Intent(this, cgeodetail.class); + cachesIntent.putExtra("geocode", query.trim().toUpperCase()); + startActivity(cachesIntent); + + found = true; + } else if (tbCodeM.find()) { // TB-code + final Intent trackablesIntent = new Intent(this, cgeotrackable.class); + trackablesIntent.putExtra("geocode", query.trim().toUpperCase()); + startActivity(trackablesIntent); + + found = true; + } else { // keyword (fallback) + final Intent cachesIntent = new Intent(this, cgeocaches.class); + cachesIntent.putExtra("type", "keyword"); + cachesIntent.putExtra("keyword", query); + cachesIntent.putExtra("cachetype", settings.cacheType); + startActivity(cachesIntent); + + found = true; + } + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeoadvsearch.instantSearch: " + e.toString()); + } + + return found; + } + + private void init() { + settings.getLogin(); + settings.reloadCacheType(); + + if (settings.cacheType != null && cgBase.cacheTypesInv.containsKey(settings.cacheType) == false) { + settings.setCacheType(null); + } + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + ((Button) findViewById(R.id.buttonLatitude)).setOnClickListener(new findByCoordsAction()); + ((Button) findViewById(R.id.buttonLongitude)).setOnClickListener(new findByCoordsAction()); + + final Button findByCoords = (Button) findViewById(R.id.search_coordinates); + findByCoords.setOnClickListener(new findByCoordsListener()); + + ((EditText) findViewById(R.id.address)).setOnEditorActionListener(new findByAddressAction()); + + final Button findByAddress = (Button) findViewById(R.id.search_address); + findByAddress.setOnClickListener(new findByAddressListener()); + + final AutoCompleteTextView geocodeEdit = (AutoCompleteTextView) findViewById(R.id.geocode); + geocodeEdit.setOnEditorActionListener(new findByGeocodeAction()); + geocodesInCache = app.geocodesInCache(); + if (geocodesInCache != null) { + final ArrayAdapter<String> geocodesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, geocodesInCache); + geocodeEdit.setAdapter(geocodesAdapter); + } + + final Button displayByGeocode = (Button) findViewById(R.id.display_geocode); + displayByGeocode.setOnClickListener(new findByGeocodeListener()); + + ((EditText) findViewById(R.id.keyword)).setOnEditorActionListener(new findByKeywordAction()); + + final Button findByKeyword = (Button) findViewById(R.id.search_keyword); + findByKeyword.setOnClickListener(new findByKeywordListener()); + + ((EditText) findViewById(R.id.username)).setOnEditorActionListener(new findByUsernameAction()); + + final Button findByUserName = (Button) findViewById(R.id.search_username); + findByUserName.setOnClickListener(new findByUsernameListener()); + + ((EditText) findViewById(R.id.owner)).setOnEditorActionListener(new findByOwnerAction()); + + final Button findByOwner = (Button) findViewById(R.id.search_owner); + findByOwner.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + findByOwnerFn(); + } + }); + + EditText trackable = (EditText) findViewById(R.id.trackable); + trackable.setOnEditorActionListener(new findTrackableAction()); + + final Button displayTrackable = (Button) findViewById(R.id.display_trackable); + displayTrackable.setOnClickListener(new findTrackableListener()); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + if (latEdit == null) { + latEdit = (EditText) findViewById(R.id.latitude); + } + if (lonEdit == null) { + lonEdit = (EditText) findViewById(R.id.longitude); + } + + if (geo.coordsNow != null) { + latEdit.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); + lonEdit.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class findByCoordsAction implements OnClickListener { + + @Override + public void onClick(View arg0) { + cgeocoords coordsDialog = new cgeocoords(cgeoadvsearch.this, settings, null, geo); + coordsDialog.setCancelable(true); + coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + @Override + public void update(Geopoint gp) { + ((Button) findViewById(R.id.buttonLatitude)).setText(cgBase.formatLatitude(gp.getLatitude(), true)); + ((Button) findViewById(R.id.buttonLongitude)).setText(cgBase.formatLongitude(gp.getLongitude(), true)); + } + }); + coordsDialog.show(); + } + } + + private class findByCoordsListener implements View.OnClickListener { + + public void onClick(View arg0) { + findByCoordsFn(); + } + } + + private void findByCoordsFn() { + final Button latView = (Button) findViewById(R.id.buttonLatitude); + final Button lonView = (Button) findViewById(R.id.buttonLongitude); + final String latText = latView.getText().toString(); + final String lonText = lonView.getText().toString(); + + if (StringUtils.isEmpty(latText) || StringUtils.isEmpty(lonText)) { // TODO: now coordinates + latView.setText(cgBase.formatLatitude(geo.coordsNow.getLatitude(), true)); + lonView.setText(cgBase.formatLongitude(geo.coordsNow.getLongitude(), true)); + } else { + Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); + Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lat"); + + if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lat)); + return; + } + + if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lon)); + return; + } + + final Intent cachesIntent = new Intent(this, cgeocaches.class); + cachesIntent.putExtra("type", "coordinate"); + cachesIntent.putExtra("latitude", (Double) latParsed.get("coordinate")); + cachesIntent.putExtra("longitude", (Double) lonParsed.get("coordinate")); + cachesIntent.putExtra("cachetype", settings.cacheType); + startActivity(cachesIntent); + } + } + + private class findByKeywordAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findByKeywordFn(); + return true; + } + + return false; + } + } + + private class findByKeywordListener implements View.OnClickListener { + + public void onClick(View arg0) { + findByKeywordFn(); + } + } + + private void findByKeywordFn() { + // find caches by coordinates + String keyText = ((EditText) findViewById(R.id.keyword)).getText().toString(); + + if (StringUtils.isBlank(keyText)) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_keyword)); + return; + } + + final Intent cachesIntent = new Intent(this, cgeocaches.class); + cachesIntent.putExtra("type", "keyword"); + cachesIntent.putExtra("keyword", keyText); + cachesIntent.putExtra("cachetype", settings.cacheType); + startActivity(cachesIntent); + } + + private class findByAddressAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findByAddressFn(); + return true; + } + + return false; + } + } + + private class findByAddressListener implements View.OnClickListener { + + public void onClick(View arg0) { + findByAddressFn(); + } + } + + private void findByAddressFn() { + final String addText = ((EditText) findViewById(R.id.address)).getText().toString(); + + if (StringUtils.isBlank(addText)) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_address)); + return; + } + + final Intent addressesIntent = new Intent(this, cgeoaddresses.class); + addressesIntent.putExtra("keyword", addText); + startActivity(addressesIntent); + } + + private class findByUsernameAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findByUsernameFn(); + return true; + } + + return false; + } + } + + private class findByUsernameListener implements View.OnClickListener { + + public void onClick(View arg0) { + findByUsernameFn(); + } + } + + public void findByUsernameFn() { + final String usernameText = ((EditText) findViewById(R.id.username)).getText().toString(); + + if (StringUtils.isBlank(usernameText)) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_user)); + return; + } + + final Intent cachesIntent = new Intent(this, cgeocaches.class); + cachesIntent.putExtra("type", "username"); + cachesIntent.putExtra("username", usernameText); + cachesIntent.putExtra("cachetype", settings.cacheType); + startActivity(cachesIntent); + } + + private class findByOwnerAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findByOwnerFn(); + return true; + } + + return false; + } + } + + private void findByOwnerFn() { + findByOwnerFn(((EditText) findViewById(R.id.owner)).getText().toString()); + } + + private void findByOwnerFn(String userName) { + final String usernameText = StringUtils.trimToEmpty(userName); + + if (StringUtils.isBlank(usernameText)) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_user)); + return; + } + + final Intent cachesIntent = new Intent(this, cgeocaches.class); + cachesIntent.putExtra("type", "owner"); + cachesIntent.putExtra("username", usernameText); + cachesIntent.putExtra("cachetype", settings.cacheType); + startActivity(cachesIntent); + } + + private class findByGeocodeAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findByGeocodeFn(); + return true; + } + + return false; + } + } + + private class findByGeocodeListener implements View.OnClickListener { + + public void onClick(View arg0) { + findByGeocodeFn(); + } + } + + private void findByGeocodeFn() { + final String geocodeText = ((EditText) findViewById(R.id.geocode)).getText().toString(); + + if (StringUtils.isBlank(geocodeText) || geocodeText.equalsIgnoreCase("GC")) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_gccode)); + return; + } + + cgeodetail.startActivity(this, geocodeText); + } + + private class findTrackableAction implements TextView.OnEditorActionListener { + + @Override + public boolean onEditorAction(TextView view, int action, KeyEvent event) { + if (action == EditorInfo.IME_ACTION_GO) { + findTrackableFn(); + return true; + } + + return false; + } + } + + private class findTrackableListener implements View.OnClickListener { + + public void onClick(View arg0) { + findTrackableFn(); + } + } + + private void findTrackableFn() { + final String trackableText = ((EditText) findViewById(R.id.trackable)).getText().toString(); + + if (StringUtils.isBlank(trackableText) || trackableText.equalsIgnoreCase("TB")) { + helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_tb)); + return; + } + + final Intent trackablesIntent = new Intent(this, cgeotrackable.class); + trackablesIntent.putExtra("geocode", trackableText.toUpperCase()); + startActivity(trackablesIntent); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, MENU_SEARCH_OWN_CACHES, 0, res.getString(R.string.search_own_caches)); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == MENU_SEARCH_OWN_CACHES) { + findByOwnerFn(settings.getUsername()); + return true; + } + return super.onOptionsItemSelected(item); + } } diff --git a/src/cgeo/geocaching/cgeoapplication.java b/src/cgeo/geocaching/cgeoapplication.java index 0244112..b892fa5 100644 --- a/src/cgeo/geocaching/cgeoapplication.java +++ b/src/cgeo/geocaching/cgeoapplication.java @@ -1,5 +1,14 @@ package cgeo.geocaching; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.utils.CollectionUtils; + +import org.apache.commons.lang3.StringUtils; + +import android.app.Application; +import android.content.Context; +import android.util.Log; + import java.io.File; import java.util.ArrayList; import java.util.Date; @@ -8,831 +17,826 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import org.apache.commons.lang3.StringUtils; +public class cgeoapplication extends Application { -import android.app.Application; -import android.content.Context; -import android.util.Log; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.utils.CollectionUtils; + private cgData storage = null; + private String action = null; + private Geopoint lastCoords = null; + private cgGeo geo = null; + private boolean geoInUse = false; + private cgDirection dir = null; + private boolean dirInUse = false; + final private Map<UUID, cgSearch> searches = new HashMap<UUID, cgSearch>(); // information about searches + final private Map<String, cgCache> cachesCache = new HashMap<String, cgCache>(); // caching caches into memory + public boolean firstRun = true; // c:geo is just launched + public boolean warnedLanguage = false; // user was warned about different language settings on geocaching.com + private boolean databaseCleaned = false; // database was cleaned + + public cgeoapplication() { + if (storage == null) { + storage = new cgData(this); + } + } -public class cgeoapplication extends Application { + @Override + public void onLowMemory() { + Log.i(cgSettings.tag, "Cleaning applications cache."); + + cachesCache.clear(); + } + + @Override + public void onTerminate() { + Log.d(cgSettings.tag, "Terminating c:geo..."); + + if (geo != null) { + geo.closeGeo(); + geo = null; + } + + if (dir != null) { + dir.closeDir(); + dir = null; + } + + if (storage != null) { + storage.clean(); + storage.closeDb(); + storage = null; + } + + super.onTerminate(); + } + + public String backupDatabase() { + return storage.backupDatabase(); + } + + public static File isRestoreFile() { + return cgData.isRestoreFile(); + } + + public boolean restoreDatabase() { + return storage.restoreDatabase(); + } + + public void cleanGeo() { + if (geo != null) { + geo.closeGeo(); + geo = null; + } + } + + public void cleanDir() { + if (dir != null) { + dir.closeDir(); + dir = null; + } + } + + public boolean storageStatus() { + return storage.status(); + } + + public cgGeo startGeo(Context context, cgUpdateLoc geoUpdate, cgBase base, cgSettings settings, int time, int distance) { + if (geo == null) { + geo = new cgGeo(context, this, geoUpdate, base, settings, time, distance); + geo.initGeo(); + + Log.i(cgSettings.tag, "Location service started"); + } + + geo.replaceUpdate(geoUpdate); + geoInUse = true; + + return geo; + } + + public cgGeo removeGeo() { + if (geo != null) { + geo.replaceUpdate(null); + } + geoInUse = false; + + (new removeGeoThread()).start(); + + return null; + } + + private class removeGeoThread extends Thread { + + @Override + public void run() { + try { + sleep(2500); + } catch (Exception e) { + // nothing + } + + if (geoInUse == false && geo != null) { + geo.closeGeo(); + geo = null; + + Log.i(cgSettings.tag, "Location service stopped"); + } + } + } + + public cgDirection startDir(Context context, cgUpdateDir dirUpdate) { + if (dir == null) { + dir = new cgDirection(context, dirUpdate); + dir.initDir(); + + Log.i(cgSettings.tag, "Direction service started"); + } + + dir.replaceUpdate(dirUpdate); + dirInUse = true; + + return dir; + } + + public cgDirection removeDir() { + if (dir != null) { + dir.replaceUpdate(null); + } + dirInUse = false; + + (new removeDirThread()).start(); + + return null; + } + + private class removeDirThread extends Thread { + + @Override + public void run() { + try { + sleep(2500); + } catch (Exception e) { + // nothing + } + + if (dirInUse == false && dir != null) { + dir.closeDir(); + dir = null; + + Log.i(cgSettings.tag, "Direction service stopped"); + } + } + } + + public void cleanDatabase(boolean more) { + if (databaseCleaned) { + return; + } + + if (storage == null) { + storage = new cgData(this); + } + storage.clean(more); + databaseCleaned = true; + } + + public Boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { + if (storage == null) { + storage = new cgData(this); + } + return storage.isThere(geocode, guid, detailed, checkTime); + } + + public Boolean isOffline(String geocode, String guid) { + if (storage == null) { + storage = new cgData(this); + } + return storage.isOffline(geocode, guid); + } + + public String getGeocode(String guid) { + if (storage == null) { + storage = new cgData(this); + } + return storage.getGeocodeForGuid(guid); + } + + public String getCacheid(String geocode) { + if (storage == null) { + storage = new cgData(this); + } + return storage.getCacheidForGeocode(geocode); + } + + public String getError(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + return searches.get(searchId).error; + } + + public boolean setError(final UUID searchId, String error) { + if (searchId == null || searches.containsKey(searchId) == false) { + return false; + } + + searches.get(searchId).error = error; + + return true; + } + + public String getUrl(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + return searches.get(searchId).url; + } + + public boolean setUrl(final UUID searchId, String url) { + if (searchId == null || searches.containsKey(searchId) == false) { + return false; + } + + searches.get(searchId).url = url; + + return true; + } + + public String[] getViewstates(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + return searches.get(searchId).viewstates; + } + + public boolean setViewstates(final UUID searchId, String[] viewstates) { + if (cgBase.isEmpty(viewstates)) { + return false; + } + if (searchId == null || searches.containsKey(searchId) == false) { + return false; + } + + searches.get(searchId).viewstates = viewstates; + + return true; + } + + public Integer getTotal(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + return searches.get(searchId).totalCnt; + } + + public Integer getCount(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return 0; + } + + return searches.get(searchId).getCount(); + } + + public Integer getNotOfflineCount(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return 0; + } + + int count = 0; + List<String> geocodes = searches.get(searchId).getGeocodes(); + if (geocodes != null) { + for (String geocode : geocodes) { + if (isOffline(geocode, null) == false) { + count++; + } + } + } + + return count; + } + + public cgCache getCacheByGeocode(String geocode) { + return getCacheByGeocode(geocode, false, true, false, false, false, false); + } + + public cgCache getCacheByGeocode(String geocode, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + cgCache cache = null; + if (cachesCache.containsKey(geocode)) { + cache = cachesCache.get(geocode); + } else { + if (storage == null) { + storage = new cgData(this); + } + cache = storage.loadCache(geocode, null, loadA, loadW, loadS, loadL, loadI, loadO); + + if (cache != null && cache.detailed && loadA && loadW && loadS && loadL && loadI) { + putCacheInCache(cache); + } + } + + return cache; + } + + public cgTrackable getTrackableByGeocode(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + cgTrackable trackable = null; + trackable = storage.loadTrackable(geocode); + + return trackable; + } + + public void removeCacheFromCache(String geocode) { + if (geocode != null && cachesCache.containsKey(geocode)) { + cachesCache.remove(geocode); + } + } + + public void putCacheInCache(cgCache cache) { + if (cache == null || cache.geocode == null) { + return; + } + + if (cachesCache.containsKey(cache.geocode)) { + cachesCache.remove(cache.geocode); + } + + cachesCache.put(cache.geocode, cache); + } + + public String[] geocodesInCache() { + if (storage == null) { + storage = new cgData(this); + } + + return storage.allDetailedThere(); + } + + public cgWaypoint getWaypointById(Integer id) { + if (id == null || id == 0) { + return null; + } + + if (storage == null) { + storage = new cgData(this); + } + return storage.loadWaypoint(id); + } + + public List<Object> getBounds(String geocode) { + if (geocode == null) { + return null; + } - private cgData storage = null; - private String action = null; - private Geopoint lastCoords = null; - private cgGeo geo = null; - private boolean geoInUse = false; - private cgDirection dir = null; - private boolean dirInUse = false; - final private Map<UUID, cgSearch> searches = new HashMap<UUID, cgSearch>(); // information about searches - final private Map<String, cgCache> cachesCache = new HashMap<String, cgCache>(); // caching caches into memory - public boolean firstRun = true; // c:geo is just launched - public boolean warnedLanguage = false; // user was warned about different language settings on geocaching.com - private boolean databaseCleaned = false; // database was cleaned - - public cgeoapplication() { - if (storage == null) { - storage = new cgData(this); - } - } - - @Override - public void onLowMemory() { - Log.i(cgSettings.tag, "Cleaning applications cache."); - - cachesCache.clear(); - } - - @Override - public void onTerminate() { - Log.d(cgSettings.tag, "Terminating c:geo..."); - - if (geo != null) { - geo.closeGeo(); - geo = null; - } - - if (dir != null) { - dir.closeDir(); - dir = null; - } - - if (storage != null) { - storage.clean(); - storage.closeDb(); - storage = null; - } - - super.onTerminate(); - } - - public String backupDatabase() { - return storage.backupDatabase(); - } - - public static File isRestoreFile() { - return cgData.isRestoreFile(); - } - - public boolean restoreDatabase() { - return storage.restoreDatabase(); - } - - public void cleanGeo() { - if (geo != null) { - geo.closeGeo(); - geo = null; - } - } - - public void cleanDir() { - if (dir != null) { - dir.closeDir(); - dir = null; - } - } - - public boolean storageStatus() { - return storage.status(); - } - - public cgGeo startGeo(Context context, cgUpdateLoc geoUpdate, cgBase base, cgSettings settings, int time, int distance) { - if (geo == null) { - geo = new cgGeo(context, this, geoUpdate, base, settings, time, distance); - geo.initGeo(); - - Log.i(cgSettings.tag, "Location service started"); - } - - geo.replaceUpdate(geoUpdate); - geoInUse = true; - - return geo; - } - - public cgGeo removeGeo() { - if (geo != null) { - geo.replaceUpdate(null); - } - geoInUse = false; - - (new removeGeoThread()).start(); - - return null; - } - - private class removeGeoThread extends Thread { - - @Override - public void run() { - try { - sleep(2500); - } catch (Exception e) { - // nothing - } - - if (geoInUse == false && geo != null) { - geo.closeGeo(); - geo = null; - - Log.i(cgSettings.tag, "Location service stopped"); - } - } - } - - public cgDirection startDir(Context context, cgUpdateDir dirUpdate) { - if (dir == null) { - dir = new cgDirection(context, dirUpdate); - dir.initDir(); - - Log.i(cgSettings.tag, "Direction service started"); - } - - dir.replaceUpdate(dirUpdate); - dirInUse = true; - - return dir; - } - - public cgDirection removeDir() { - if (dir != null) { - dir.replaceUpdate(null); - } - dirInUse = false; - - (new removeDirThread()).start(); - - return null; - } - - private class removeDirThread extends Thread { - - @Override - public void run() { - try { - sleep(2500); - } catch (Exception e) { - // nothing - } - - if (dirInUse == false && dir != null) { - dir.closeDir(); - dir = null; - - Log.i(cgSettings.tag, "Direction service stopped"); - } - } - } - - public void cleanDatabase(boolean more) { - if (databaseCleaned) { - return; - } - - if (storage == null) { - storage = new cgData(this); - } - storage.clean(more); - databaseCleaned = true; - } - - public Boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { - if (storage == null) { - storage = new cgData(this); - } - return storage.isThere(geocode, guid, detailed, checkTime); - } - - public Boolean isOffline(String geocode, String guid) { - if (storage == null) { - storage = new cgData(this); - } - return storage.isOffline(geocode, guid); - } - - public String getGeocode(String guid) { - if (storage == null) { - storage = new cgData(this); - } - return storage.getGeocodeForGuid(guid); - } - - public String getCacheid(String geocode) { - if (storage == null) { - storage = new cgData(this); - } - return storage.getCacheidForGeocode(geocode); - } - - public String getError(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - return searches.get(searchId).error; - } - - public boolean setError(final UUID searchId, String error) { - if (searchId == null || searches.containsKey(searchId) == false) { - return false; - } - - searches.get(searchId).error = error; - - return true; - } - - public String getUrl(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - return searches.get(searchId).url; - } - - public boolean setUrl(final UUID searchId, String url) { - if (searchId == null || searches.containsKey(searchId) == false) { - return false; - } - - searches.get(searchId).url = url; - - return true; - } - - public String[] getViewstates(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - return searches.get(searchId).viewstates; - } - - public boolean setViewstates(final UUID searchId, String[] viewstates) { - if (cgBase.isEmpty(viewstates)) { - return false; - } - if (searchId == null || searches.containsKey(searchId) == false) { - return false; - } - - searches.get(searchId).viewstates = viewstates; - - return true; - } - - public Integer getTotal(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - return searches.get(searchId).totalCnt; - } - - public Integer getCount(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return 0; - } - - return searches.get(searchId).getCount(); - } - - public Integer getNotOfflineCount(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return 0; - } - - int count = 0; - List<String> geocodes = searches.get(searchId).getGeocodes(); - if (geocodes != null) { - for (String geocode : geocodes) { - if (isOffline(geocode, null) == false) { - count++; - } - } - } - - return count; - } - - public cgCache getCacheByGeocode(String geocode) { - return getCacheByGeocode(geocode, false, true, false, false, false, false); - } - - public cgCache getCacheByGeocode(String geocode, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - cgCache cache = null; - if (cachesCache.containsKey(geocode)) { - cache = cachesCache.get(geocode); - } else { - if (storage == null) { - storage = new cgData(this); - } - cache = storage.loadCache(geocode, null, loadA, loadW, loadS, loadL, loadI, loadO); - - if (cache != null && cache.detailed && loadA && loadW && loadS && loadL && loadI) { - putCacheInCache(cache); - } - } - - return cache; - } - - public cgTrackable getTrackableByGeocode(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - cgTrackable trackable = null; - trackable = storage.loadTrackable(geocode); - - return trackable; - } - - public void removeCacheFromCache(String geocode) { - if (geocode != null && cachesCache.containsKey(geocode)) { - cachesCache.remove(geocode); - } - } - - public void putCacheInCache(cgCache cache) { - if (cache == null || cache.geocode == null) { - return; - } - - if (cachesCache.containsKey(cache.geocode)) { - cachesCache.remove(cache.geocode); - } - - cachesCache.put(cache.geocode, cache); - } - - public String[] geocodesInCache() { - if (storage == null) { - storage = new cgData(this); - } - - return storage.allDetailedThere(); - } - - public cgWaypoint getWaypointById(Integer id) { - if (id == null || id == 0) { - return null; - } - - if (storage == null) { - storage = new cgData(this); - } - return storage.loadWaypoint(id); - } - - public List<Object> getBounds(String geocode) { - if (geocode == null) { - return null; - } - - List<String> geocodeList = new ArrayList<String>(); - geocodeList.add(geocode); - - return getBounds(geocodeList); - } - - public List<Object> getBounds(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - if (storage == null) { - storage = new cgData(this); - } - - final cgSearch search = searches.get(searchId); - final List<String> geocodeList = search.getGeocodes(); - - return getBounds(geocodeList); - } - - public List<Object> getBounds(List<String> geocodes) { - if (geocodes == null || geocodes.isEmpty()) { - return null; - } - - if (storage == null) { - storage = new cgData(this); - } - - return storage.getBounds(geocodes.toArray()); - } - - public cgCache getCache(final UUID searchId) { - if (searchId == null || searches.containsKey(searchId) == false) { - return null; - } - - cgSearch search = searches.get(searchId); - List<String> geocodeList = search.getGeocodes(); - - return getCacheByGeocode(geocodeList.get(0), true, true, true, true, true, true); - } - - public List<cgCache> getCaches(final UUID searchId) { - return getCaches(searchId, null, null, null, null, false, true, false, false, false, true); - } - - public List<cgCache> getCaches(final UUID searchId, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { - return getCaches(searchId, null, null, null, null, loadA, loadW, loadS, loadL, loadI, loadO); - } - - public List<cgCache> getCaches(final UUID searchId, Long centerLat, Long centerLon, Long spanLat, Long spanLon) { - return getCaches(searchId, centerLat, centerLon, spanLat, spanLon, false, true, false, false, false, true); - } - - public List<cgCache> getCaches(final UUID searchId, Long centerLat, Long centerLon, Long spanLat, Long spanLon, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { - if (searchId == null || searches.containsKey(searchId) == false) { - List<cgCache> cachesOut = new ArrayList<cgCache>(); - - final List<cgCache> cachesPre = storage.loadCaches(null , null, centerLat, centerLon, spanLat, spanLon, loadA, loadW, loadS, loadL, loadI, loadO); - - if (cachesPre != null) { - cachesOut.addAll(cachesPre); - } - - return cachesOut; - } - - List<cgCache> cachesOut = new ArrayList<cgCache>(); - - cgSearch search = searches.get(searchId); - List<String> geocodeList = search.getGeocodes(); - - if (storage == null) { - storage = new cgData(this); - } - - // 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, null, loadA, loadW, loadS, loadL, loadI, loadO); - if (cachesPre != null) { - cachesOut.addAll(cachesPre); - } - - return cachesOut; - } - - public cgSearch getBatchOfStoredCaches(boolean detailedOnly, final Geopoint coords, String cachetype, int list) { - if (storage == null) { - storage = new cgData(this); - } - cgSearch search = new cgSearch(); - - List<String> geocodes = storage.loadBatchOfStoredGeocodes(detailedOnly, coords, cachetype, list); - if (geocodes != null && geocodes.isEmpty() == false) { - for (String gccode : geocodes) { - search.addGeocode(gccode); - } - } - searches.put(search.getCurrentId(), search); - - return search; - } - - public List<cgDestination> getHistoryOfSearchedLocations() { - if (storage == null) { - storage = new cgData(this); - } - - return storage.loadHistoryOfSearchedLocations(); - } - - public cgSearch getHistoryOfCaches(boolean detailedOnly, String cachetype) { - if (storage == null) { - storage = new cgData(this); - } - cgSearch search = new cgSearch(); - - List<String> geocodes = storage.loadBatchOfHistoricGeocodes(detailedOnly, cachetype); - if (geocodes != null && geocodes.isEmpty() == false) { - for (String gccode : geocodes) { - search.addGeocode(gccode); - } - } - searches.put(search.getCurrentId(), search); - - return search; - } - - public UUID getCachedInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { - if (storage == null) { - storage = new cgData(this); - } - cgSearch search = new cgSearch(); - - List<String> geocodes = storage.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, cachetype); - if (geocodes != null && geocodes.isEmpty() == false) { - for (String gccode : geocodes) { - search.addGeocode(gccode); - } - } - searches.put(search.getCurrentId(), search); - - return search.getCurrentId(); - } - - public UUID getStoredInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { - if (storage == null) { - storage = new cgData(this); - } - cgSearch search = new cgSearch(); - - List<String> geocodes = storage.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, cachetype); - if (geocodes != null && geocodes.isEmpty() == false) { - for (String gccode : geocodes) { - search.addGeocode(gccode); - } - } - searches.put(search.getCurrentId(), search); - - return search.getCurrentId(); - } - - public UUID getOfflineAll(String cachetype) { - if (storage == null) { - storage = new cgData(this); - } - cgSearch search = new cgSearch(); - - List<String> geocodes = storage.getOfflineAll(cachetype); - if (geocodes != null && geocodes.isEmpty() == false) { - for (String gccode : geocodes) { - search.addGeocode(gccode); - } - } - searches.put(search.getCurrentId(), search); - - return search.getCurrentId(); - } - - public int getAllStoredCachesCount(boolean detailedOnly, String cachetype, Integer list) { - if (storage == null) { - storage = new cgData(this); - } - - return storage.getAllStoredCachesCount(detailedOnly, cachetype, list); - } - - public int getAllHistoricCachesCount(boolean detailedOnly, String cachetype) { - if (storage == null) { - storage = new cgData(this); - } - - return storage.getAllHistoricCachesCount(detailedOnly, cachetype); - } - - public void markStored(String geocode, int listId) { - if (storage == null) { - storage = new cgData(this); - } - storage.markStored(geocode, listId); - } - - public boolean markDropped(String geocode) { - if (storage == null) { - storage = new cgData(this); - } - return storage.markDropped(geocode); - } - - public boolean markFound(String geocode) { - if (storage == null) { - storage = new cgData(this); - } - return storage.markFound(geocode); - } - - public boolean clearSearchedDestinations() { - if (storage == null) { - storage = new cgData(this); - } - - return storage.clearSearchedDestinations(); - } - - public boolean saveSearchedDestination(cgDestination destination) { - if (storage == null) { - storage = new cgData(this); - } - - return storage.saveSearchedDestination(destination); - } - - public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) { - if (storage == null) { - storage = new cgData(this); - } - return storage.saveWaypoints(geocode, waypoints, drop); - } - - public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { - if (storage == null) { - storage = new cgData(this); - } - return storage.saveOwnWaypoint(id, geocode, waypoint); - } - - public boolean deleteWaypoint(int id) { - if (storage == null) { - storage = new cgData(this); - } - return storage.deleteWaypoint(id); - } - - public boolean saveTrackable(cgTrackable trackable) { - if (storage == null) { - storage = new cgData(this); - } - - final List<cgTrackable> list = new ArrayList<cgTrackable>(); - list.add(trackable); - - return storage.saveInventory("---", list); - } - - public void addGeocode(final UUID searchId, String geocode) { - if (this.searches.containsKey(searchId) == false || StringUtils.isBlank(geocode)) { - return; - } - - this.searches.get(searchId).addGeocode(geocode); - } - - public UUID addSearch(final UUID searchId, List<cgCache> cacheList, Boolean newItem, int reason) { - if (this.searches.containsKey(searchId) == false) { - return null; - } - - cgSearch search = this.searches.get(searchId); - - return addSearch(search, cacheList, newItem, reason); - } - - public UUID addSearch(final cgSearch search, final List<cgCache> cacheList, final boolean newItem, final int reason) { - if (CollectionUtils.isEmpty(cacheList)) { - return null; - } - - final UUID searchId = search.getCurrentId(); - searches.put(searchId, search); - - if (storage == null) { - storage = new cgData(this); - } - if (newItem) { - // save only newly downloaded data - for (cgCache cache : cacheList) { - cache.reason = reason; - storeWithMerge(cache, false); - } - } - - return searchId; - } - - public boolean addCacheToSearch(cgSearch search, cgCache cache) { - if (search == null || cache == null) { - return false; - } - - final UUID searchId = search.getCurrentId(); - - if (searches.containsKey(searchId) == false) { - searches.put(searchId, search); - } - - final boolean status = storeWithMerge(cache, cache.reason >= 1); - - if (status) { - search.addGeocode(cache.geocode); - } - - return status; - } - - /** - * Checks if Cache is already in Database and if so does a merge. - * @param cache the cache to be saved - * @param override override the check and persist the new state. - * @return true if the cache has been saved correctly - */ - - private boolean storeWithMerge(final cgCache cache, final boolean override) { - if (!override) { - final cgCache oldCache = storage.loadCache(cache.geocode, cache.guid, - true, true, true, true, true, true); - cache.gatherMissingFrom(oldCache); - } - return storage.saveCache(cache); - } - - public void dropStored(int listId) { - if (storage == null) { - storage = new cgData(this); - } - storage.dropStored(listId); - } - - public List<cgTrackable> loadInventory(String geocode) { - return storage.loadInventory(geocode); - } - - public Map<Integer,Integer> loadLogCounts(String geocode) { - return storage.loadLogCounts(geocode); - } - - public List<cgImage> loadSpoilers(String geocode) { - return storage.loadSpoilers(geocode); - } - - public cgWaypoint loadWaypoint(int id) { - return storage.loadWaypoint(id); - } - - public void setAction(String act) { - action = act; - } - - public String getAction() { - if (action == null) { - return ""; - } - return action; - } - - public boolean addLog(String geocode, cgLog log) { - if (StringUtils.isBlank(geocode)) { - return false; - } - if (log == null) { - return false; - } - - List<cgLog> list = new ArrayList<cgLog>(); - list.add(log); - - return storage.saveLogs(geocode, list, false); - } - - public void setLastLoc(final Geopoint coords) { - lastCoords = coords; - } - - public Geopoint getLastCoords() { - return lastCoords; - } - - public boolean saveLogOffline(String geocode, Date date, int logtype, String log) { - return storage.saveLogOffline(geocode, date, logtype, log); - } - - public cgLog loadLogOffline(String geocode) { - return storage.loadLogOffline(geocode); - } - - public void clearLogOffline(String geocode) { - storage.clearLogOffline(geocode); - } - - public void saveVisitDate(String geocode) { - storage.saveVisitDate(geocode); - } - - public void clearVisitDate(String geocode) { + List<String> geocodeList = new ArrayList<String>(); + geocodeList.add(geocode); + + return getBounds(geocodeList); + } + + public List<Object> getBounds(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + if (storage == null) { + storage = new cgData(this); + } + + final cgSearch search = searches.get(searchId); + final List<String> geocodeList = search.getGeocodes(); + + return getBounds(geocodeList); + } + + public List<Object> getBounds(List<String> geocodes) { + if (geocodes == null || geocodes.isEmpty()) { + return null; + } + + if (storage == null) { + storage = new cgData(this); + } + + return storage.getBounds(geocodes.toArray()); + } + + public cgCache getCache(final UUID searchId) { + if (searchId == null || searches.containsKey(searchId) == false) { + return null; + } + + cgSearch search = searches.get(searchId); + List<String> geocodeList = search.getGeocodes(); + + return getCacheByGeocode(geocodeList.get(0), true, true, true, true, true, true); + } + + public List<cgCache> getCaches(final UUID searchId) { + return getCaches(searchId, null, null, null, null, false, true, false, false, false, true); + } + + public List<cgCache> getCaches(final UUID searchId, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { + return getCaches(searchId, null, null, null, null, loadA, loadW, loadS, loadL, loadI, loadO); + } + + public List<cgCache> getCaches(final UUID searchId, Long centerLat, Long centerLon, Long spanLat, Long spanLon) { + return getCaches(searchId, centerLat, centerLon, spanLat, spanLon, false, true, false, false, false, true); + } + + public List<cgCache> getCaches(final UUID searchId, Long centerLat, Long centerLon, Long spanLat, Long spanLon, boolean loadA, boolean loadW, boolean loadS, boolean loadL, boolean loadI, boolean loadO) { + if (searchId == null || searches.containsKey(searchId) == false) { + List<cgCache> cachesOut = new ArrayList<cgCache>(); + + final List<cgCache> cachesPre = storage.loadCaches(null, null, centerLat, centerLon, spanLat, spanLon, loadA, loadW, loadS, loadL, loadI, loadO); + + if (cachesPre != null) { + cachesOut.addAll(cachesPre); + } + + return cachesOut; + } + + List<cgCache> cachesOut = new ArrayList<cgCache>(); + + cgSearch search = searches.get(searchId); + List<String> geocodeList = search.getGeocodes(); + + if (storage == null) { + storage = new cgData(this); + } + + // 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, null, loadA, loadW, loadS, loadL, loadI, loadO); + if (cachesPre != null) { + cachesOut.addAll(cachesPre); + } + + return cachesOut; + } + + public cgSearch getBatchOfStoredCaches(boolean detailedOnly, final Geopoint coords, String cachetype, int list) { + if (storage == null) { + storage = new cgData(this); + } + cgSearch search = new cgSearch(); + + List<String> geocodes = storage.loadBatchOfStoredGeocodes(detailedOnly, coords, cachetype, list); + if (geocodes != null && geocodes.isEmpty() == false) { + for (String gccode : geocodes) { + search.addGeocode(gccode); + } + } + searches.put(search.getCurrentId(), search); + + return search; + } + + public List<cgDestination> getHistoryOfSearchedLocations() { + if (storage == null) { + storage = new cgData(this); + } + + return storage.loadHistoryOfSearchedLocations(); + } + + public cgSearch getHistoryOfCaches(boolean detailedOnly, String cachetype) { + if (storage == null) { + storage = new cgData(this); + } + cgSearch search = new cgSearch(); + + List<String> geocodes = storage.loadBatchOfHistoricGeocodes(detailedOnly, cachetype); + if (geocodes != null && geocodes.isEmpty() == false) { + for (String gccode : geocodes) { + search.addGeocode(gccode); + } + } + searches.put(search.getCurrentId(), search); + + return search; + } + + public UUID getCachedInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { + if (storage == null) { + storage = new cgData(this); + } + cgSearch search = new cgSearch(); + + List<String> geocodes = storage.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, cachetype); + if (geocodes != null && geocodes.isEmpty() == false) { + for (String gccode : geocodes) { + search.addGeocode(gccode); + } + } + searches.put(search.getCurrentId(), search); + + return search.getCurrentId(); + } + + public UUID getStoredInViewport(Long centerLat, Long centerLon, Long spanLat, Long spanLon, String cachetype) { + if (storage == null) { + storage = new cgData(this); + } + cgSearch search = new cgSearch(); + + List<String> geocodes = storage.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, cachetype); + if (geocodes != null && geocodes.isEmpty() == false) { + for (String gccode : geocodes) { + search.addGeocode(gccode); + } + } + searches.put(search.getCurrentId(), search); + + return search.getCurrentId(); + } + + public UUID getOfflineAll(String cachetype) { + if (storage == null) { + storage = new cgData(this); + } + cgSearch search = new cgSearch(); + + List<String> geocodes = storage.getOfflineAll(cachetype); + if (geocodes != null && geocodes.isEmpty() == false) { + for (String gccode : geocodes) { + search.addGeocode(gccode); + } + } + searches.put(search.getCurrentId(), search); + + return search.getCurrentId(); + } + + public int getAllStoredCachesCount(boolean detailedOnly, String cachetype, Integer list) { + if (storage == null) { + storage = new cgData(this); + } + + return storage.getAllStoredCachesCount(detailedOnly, cachetype, list); + } + + public int getAllHistoricCachesCount(boolean detailedOnly, String cachetype) { + if (storage == null) { + storage = new cgData(this); + } + + return storage.getAllHistoricCachesCount(detailedOnly, cachetype); + } + + public void markStored(String geocode, int listId) { + if (storage == null) { + storage = new cgData(this); + } + storage.markStored(geocode, listId); + } + + public boolean markDropped(String geocode) { + if (storage == null) { + storage = new cgData(this); + } + return storage.markDropped(geocode); + } + + public boolean markFound(String geocode) { + if (storage == null) { + storage = new cgData(this); + } + return storage.markFound(geocode); + } + + public boolean clearSearchedDestinations() { + if (storage == null) { + storage = new cgData(this); + } + + return storage.clearSearchedDestinations(); + } + + public boolean saveSearchedDestination(cgDestination destination) { + if (storage == null) { + storage = new cgData(this); + } + + return storage.saveSearchedDestination(destination); + } + + public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) { + if (storage == null) { + storage = new cgData(this); + } + return storage.saveWaypoints(geocode, waypoints, drop); + } + + public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { + if (storage == null) { + storage = new cgData(this); + } + return storage.saveOwnWaypoint(id, geocode, waypoint); + } + + public boolean deleteWaypoint(int id) { + if (storage == null) { + storage = new cgData(this); + } + return storage.deleteWaypoint(id); + } + + public boolean saveTrackable(cgTrackable trackable) { + if (storage == null) { + storage = new cgData(this); + } + + final List<cgTrackable> list = new ArrayList<cgTrackable>(); + list.add(trackable); + + return storage.saveInventory("---", list); + } + + public void addGeocode(final UUID searchId, String geocode) { + if (this.searches.containsKey(searchId) == false || StringUtils.isBlank(geocode)) { + return; + } + + this.searches.get(searchId).addGeocode(geocode); + } + + public UUID addSearch(final UUID searchId, List<cgCache> cacheList, Boolean newItem, int reason) { + if (this.searches.containsKey(searchId) == false) { + return null; + } + + cgSearch search = this.searches.get(searchId); + + return addSearch(search, cacheList, newItem, reason); + } + + public UUID addSearch(final cgSearch search, final List<cgCache> cacheList, final boolean newItem, final int reason) { + if (CollectionUtils.isEmpty(cacheList)) { + return null; + } + + final UUID searchId = search.getCurrentId(); + searches.put(searchId, search); + + if (storage == null) { + storage = new cgData(this); + } + if (newItem) { + // save only newly downloaded data + for (cgCache cache : cacheList) { + cache.reason = reason; + storeWithMerge(cache, false); + } + } + + return searchId; + } + + public boolean addCacheToSearch(cgSearch search, cgCache cache) { + if (search == null || cache == null) { + return false; + } + + final UUID searchId = search.getCurrentId(); + + if (searches.containsKey(searchId) == false) { + searches.put(searchId, search); + } + + final boolean status = storeWithMerge(cache, cache.reason >= 1); + + if (status) { + search.addGeocode(cache.geocode); + } + + return status; + } + + /** + * Checks if Cache is already in Database and if so does a merge. + * + * @param cache + * the cache to be saved + * @param override + * override the check and persist the new state. + * @return true if the cache has been saved correctly + */ + + private boolean storeWithMerge(final cgCache cache, final boolean override) { + if (!override) { + final cgCache oldCache = storage.loadCache(cache.geocode, cache.guid, + true, true, true, true, true, true); + cache.gatherMissingFrom(oldCache); + } + return storage.saveCache(cache); + } + + public void dropStored(int listId) { + if (storage == null) { + storage = new cgData(this); + } + storage.dropStored(listId); + } + + public List<cgTrackable> loadInventory(String geocode) { + return storage.loadInventory(geocode); + } + + public Map<Integer, Integer> loadLogCounts(String geocode) { + return storage.loadLogCounts(geocode); + } + + public List<cgImage> loadSpoilers(String geocode) { + return storage.loadSpoilers(geocode); + } + + public cgWaypoint loadWaypoint(int id) { + return storage.loadWaypoint(id); + } + + public void setAction(String act) { + action = act; + } + + public String getAction() { + if (action == null) { + return ""; + } + return action; + } + + public boolean addLog(String geocode, cgLog log) { + if (StringUtils.isBlank(geocode)) { + return false; + } + if (log == null) { + return false; + } + + List<cgLog> list = new ArrayList<cgLog>(); + list.add(log); + + return storage.saveLogs(geocode, list, false); + } + + public void setLastLoc(final Geopoint coords) { + lastCoords = coords; + } + + public Geopoint getLastCoords() { + return lastCoords; + } + + public boolean saveLogOffline(String geocode, Date date, int logtype, String log) { + return storage.saveLogOffline(geocode, date, logtype, log); + } + + public cgLog loadLogOffline(String geocode) { + return storage.loadLogOffline(geocode); + } + + public void clearLogOffline(String geocode) { + storage.clearLogOffline(geocode); + } + + public void saveVisitDate(String geocode) { + storage.saveVisitDate(geocode); + } + + public void clearVisitDate(String geocode) { storage.clearVisitDate(geocode); } - public List<cgList> getLists() { - return storage.getLists(getResources()); - } + public List<cgList> getLists() { + return storage.getLists(getResources()); + } - public cgList getList(int id) { - return storage.getList(id, getResources()); - } + public cgList getList(int id) { + return storage.getList(id, getResources()); + } - public int createList(String title) { - return storage.createList(title); - } + public int createList(String title) { + return storage.createList(title); + } - public boolean removeList(int id) { - return storage.removeList(id); - } + public boolean removeList(int id) { + return storage.removeList(id); + } - public boolean removeSearchedDestinations(cgDestination destination) { - return storage.removeSearchedDestination(destination); - } + public boolean removeSearchedDestinations(cgDestination destination) { + return storage.removeSearchedDestination(destination); + } - public void moveToList(String geocode, int listId) { - storage.moveToList(geocode, listId); - } + public void moveToList(String geocode, int listId) { + storage.moveToList(geocode, listId); + } } diff --git a/src/cgeo/geocaching/cgeoauth.java b/src/cgeo/geocaching/cgeoauth.java index c20c13c..124ff7c 100644 --- a/src/cgeo/geocaching/cgeoauth.java +++ b/src/cgeo/geocaching/cgeoauth.java @@ -1,19 +1,6 @@ package cgeo.geocaching; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.URL; -import java.net.URLConnection; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.HttpsURLConnection; +import cgeo.geocaching.activity.AbstractActivity; import org.apache.commons.lang3.StringUtils; @@ -28,364 +15,378 @@ import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; -import cgeo.geocaching.activity.AbstractActivity; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.HttpsURLConnection; public class cgeoauth extends AbstractActivity { - private String OAtoken = null; - private String OAtokenSecret = null; - private final Pattern paramsPattern1 = Pattern.compile("oauth_token=([a-zA-Z0-9\\-\\_\\.]+)"); - private final Pattern paramsPattern2 = Pattern.compile("oauth_token_secret=([a-zA-Z0-9\\-\\_\\.]+)"); - private Button startButton = null; - private EditText pinEntry = null; - private Button pinEntryButton = null; - private ProgressDialog requestTokenDialog = null; - private ProgressDialog changeTokensDialog = null; - private Handler requestTokenHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (requestTokenDialog != null && requestTokenDialog.isShowing()) { - requestTokenDialog.dismiss(); - } - - startButton.setOnClickListener(new startListener()); - startButton.setEnabled(true); - - if (msg.what == 1) { - startButton.setText(res.getString(R.string.auth_again)); - - pinEntry.setVisibility(View.VISIBLE); - pinEntryButton.setVisibility(View.VISIBLE); - pinEntryButton.setOnClickListener(new confirmPINListener()); - } else { - showToast(res.getString(R.string.err_auth_initialize)); - startButton.setText(res.getString(R.string.auth_start)); - } - } - }; - private Handler changeTokensHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (changeTokensDialog != null && changeTokensDialog.isShowing()) { - changeTokensDialog.dismiss(); - } - - pinEntryButton.setOnClickListener(new confirmPINListener()); - pinEntryButton.setEnabled(true); - - if (msg.what == 1) { - showToast(res.getString(R.string.auth_dialog_completed)); - - pinEntryButton.setVisibility(View.GONE); - - finish(); - } else { - showToast(res.getString(R.string.err_auth_process)); - - pinEntry.setVisibility(View.GONE); - pinEntryButton.setVisibility(View.GONE); - startButton.setText(res.getString(R.string.auth_start)); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - app.setAction("setting up"); - - setTheme(); - setContentView(R.layout.auth); - setTitle(res.getString(R.string.auth_twitter)); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - private void init() { - startButton = (Button) findViewById(R.id.start); - pinEntry = (EditText) findViewById(R.id.pin); - pinEntryButton = (Button) findViewById(R.id.pin_button); - - OAtoken = prefs.getString("temp-token-public", null); - OAtokenSecret = prefs.getString("temp-token-secret", null); - - startButton.setEnabled(true); - startButton.setOnClickListener(new startListener()); - - if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { - // start authorization process - startButton.setText(res.getString(R.string.auth_start)); - } else { - // already have temporary tokens, continue from pin - startButton.setText(res.getString(R.string.auth_again)); - - pinEntry.setVisibility(View.VISIBLE); - pinEntryButton.setVisibility(View.VISIBLE); - pinEntryButton.setOnClickListener(new confirmPINListener()); - } - } - - private void requestToken() { - final String host = "twitter.com"; - final String pathRequest = "/oauth/request_token"; - final String pathAuthorize = "/oauth/authorize"; - final String method = "GET"; - - int status = 0; - try { - String lineOne = null; - HttpsURLConnection connection = null; - - try { - final StringBuilder sb = new StringBuilder(); - final String params = cgOAuth.signOAuth(host, pathRequest, method, true, new HashMap<String, String>(), null, null); - - int code = -1; - int retries = 0; - - do { - // base.trustAllHosts(); - Log.d(cgSettings.tag, "https://" + host + pathRequest + "?" + params); - final URL u = new URL("https://" + host + pathRequest + "?" + params); - final URLConnection uc = u.openConnection(); - connection = (HttpsURLConnection) uc; - - // connection.setHostnameVerifier(base.doNotVerify); - connection.setReadTimeout(30000); - connection.setRequestMethod(method); - HttpsURLConnection.setFollowRedirects(true); - connection.setDoInput(true); - connection.setDoOutput(false); - - final InputStream in = connection.getInputStream(); - final InputStreamReader ins = new InputStreamReader(in); - final BufferedReader br = new BufferedReader(ins, 16 * 1024); - - while ((lineOne = br.readLine()) != null) { - sb.append(lineOne); - sb.append('\n'); - } - - code = connection.getResponseCode(); - retries++; - - Log.i(cgSettings.tag, host + ": " + connection.getResponseCode() + " " + connection.getResponseMessage()); - - br.close(); - in.close(); - ins.close(); - } while (code == -1 && retries < 5); - - final String line = sb.toString(); - - if (StringUtils.isNotBlank(line)) { - final Matcher paramsMatcher1 = paramsPattern1.matcher(line); - if (paramsMatcher1.find() && paramsMatcher1.groupCount() > 0) { - OAtoken = paramsMatcher1.group(1); - } - final Matcher paramsMatcher2 = paramsPattern2.matcher(line); - if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) { - OAtokenSecret = paramsMatcher2.group(1); - } - - if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) { - final SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefsEdit.putString("temp-token-public", OAtoken); - prefsEdit.putString("temp-token-secret", OAtokenSecret); - prefsEdit.commit(); - - try { - final Map<String, String> paramsPre = new HashMap<String, String>(); - paramsPre.put("oauth_callback", "oob"); - - final String paramsBrowser = cgOAuth.signOAuth(host, pathAuthorize, "GET", true, paramsPre, OAtoken, OAtokenSecret); - - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + host + pathAuthorize + "?" + paramsBrowser))); - - status = 1; - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoauth.requestToken(2): " + e.toString()); - } - } - } - } catch (IOException eio) { - Log.e(cgSettings.tag, "cgeoauth.requestToken(IO): " + eio.toString() + " ~ " + connection.getResponseCode() + ": " + connection.getResponseMessage()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoauth.requestToken(1): " + e.toString()); - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } catch (Exception e2) { - Log.e(cgSettings.tag, "cgeoauth.requestToken(3): " + e2.toString()); - } - - requestTokenHandler.sendEmptyMessage(status); - } - - private void changeToken() { - final String host = "twitter.com"; - final String path = "/oauth/access_token"; - final String method = "POST"; - - int status = 0; - String lineOne = null; - - try { - final Map<String, String> paramsPre = new HashMap<String, String>(); - paramsPre.put("oauth_verifier", pinEntry.getText().toString()); - - int code = -1; - int retries = 0; - - final String params = cgOAuth.signOAuth(host, path, method, true, paramsPre, OAtoken, OAtokenSecret); - final StringBuilder sb = new StringBuilder(); - do { - // base.trustAllHosts(); - final URL u = new URL("https://" + host + path); - final URLConnection uc = u.openConnection(); - final HttpsURLConnection connection = (HttpsURLConnection) uc; - - // connection.setHostnameVerifier(base.doNotVerify); - connection.setReadTimeout(30000); - connection.setRequestMethod(method); - HttpsURLConnection.setFollowRedirects(true); - connection.setDoOutput(true); - connection.setDoInput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - - wr.write(params); - wr.flush(); - wr.close(); - out.close(); - - final InputStream in = connection.getInputStream(); - final InputStreamReader ins = new InputStreamReader(in); - final BufferedReader br = new BufferedReader(ins, 16 * 1024); - - while ((lineOne = br.readLine()) != null) { - sb.append(lineOne); - sb.append('\n'); - } - - code = connection.getResponseCode(); - retries++; - - Log.i(cgSettings.tag, host + ": " + connection.getResponseCode() + " " + connection.getResponseMessage()); - - br.close(); - ins.close(); - in.close(); - connection.disconnect(); - } while (code == -1 && retries < 5); - - final String line = sb.toString(); - - OAtoken = ""; - OAtokenSecret = ""; - - final Matcher paramsMatcher1 = paramsPattern1.matcher(line); - if (paramsMatcher1.find() && paramsMatcher1.groupCount() > 0) { - OAtoken = paramsMatcher1.group(1); - } - final Matcher paramsMatcher2 = paramsPattern2.matcher(line); - if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) { - OAtokenSecret = paramsMatcher2.group(1); - } - - if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { - OAtoken = ""; - OAtokenSecret = ""; - - final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefs.putString("tokenpublic", null); - prefs.putString("tokensecret", null); - prefs.putInt("twitter", 0); - prefs.commit(); - } else { - final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefs.remove("temp-token-public"); - prefs.remove("temp-token-secret"); - prefs.putString("tokenpublic", OAtoken); - prefs.putString("tokensecret", OAtokenSecret); - prefs.putInt("twitter", 1); - prefs.commit(); - - status = 1; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoauth.changeToken: " + e.toString()); - } - - changeTokensHandler.sendEmptyMessage(status); - } - - private class startListener implements View.OnClickListener { - - public void onClick(View arg0) { - if (requestTokenDialog == null) { - requestTokenDialog = new ProgressDialog(cgeoauth.this); - requestTokenDialog.setCancelable(false); - requestTokenDialog.setMessage(res.getString(R.string.auth_dialog_wait)); - } - requestTokenDialog.show(); - startButton.setEnabled(false); - startButton.setOnTouchListener(null); - startButton.setOnClickListener(null); - - final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefs.putString("temp-token-public", null); - prefs.putString("temp-token-secret", null); - prefs.commit(); - - (new Thread() { - - @Override - public void run() { - requestToken(); - } - }).start(); - } - } - - private class confirmPINListener implements View.OnClickListener { - - public void onClick(View arg0) { - if (((EditText) findViewById(R.id.pin)).getText().toString().length() == 0) { - helpDialog(res.getString(R.string.auth_dialog_pin_title), res.getString(R.string.auth_dialog_pin_message)); - return; - } - - if (changeTokensDialog == null) { - changeTokensDialog = new ProgressDialog(cgeoauth.this); - changeTokensDialog.setCancelable(false); - changeTokensDialog.setMessage(res.getString(R.string.auth_dialog_wait)); - } - changeTokensDialog.show(); - pinEntryButton.setEnabled(false); - pinEntryButton.setOnTouchListener(null); - pinEntryButton.setOnClickListener(null); - - (new Thread() { - - @Override - public void run() { - changeToken(); - } - }).start(); - } - } + private String OAtoken = null; + private String OAtokenSecret = null; + private final Pattern paramsPattern1 = Pattern.compile("oauth_token=([a-zA-Z0-9\\-\\_\\.]+)"); + private final Pattern paramsPattern2 = Pattern.compile("oauth_token_secret=([a-zA-Z0-9\\-\\_\\.]+)"); + private Button startButton = null; + private EditText pinEntry = null; + private Button pinEntryButton = null; + private ProgressDialog requestTokenDialog = null; + private ProgressDialog changeTokensDialog = null; + private Handler requestTokenHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (requestTokenDialog != null && requestTokenDialog.isShowing()) { + requestTokenDialog.dismiss(); + } + + startButton.setOnClickListener(new startListener()); + startButton.setEnabled(true); + + if (msg.what == 1) { + startButton.setText(res.getString(R.string.auth_again)); + + pinEntry.setVisibility(View.VISIBLE); + pinEntryButton.setVisibility(View.VISIBLE); + pinEntryButton.setOnClickListener(new confirmPINListener()); + } else { + showToast(res.getString(R.string.err_auth_initialize)); + startButton.setText(res.getString(R.string.auth_start)); + } + } + }; + private Handler changeTokensHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (changeTokensDialog != null && changeTokensDialog.isShowing()) { + changeTokensDialog.dismiss(); + } + + pinEntryButton.setOnClickListener(new confirmPINListener()); + pinEntryButton.setEnabled(true); + + if (msg.what == 1) { + showToast(res.getString(R.string.auth_dialog_completed)); + + pinEntryButton.setVisibility(View.GONE); + + finish(); + } else { + showToast(res.getString(R.string.err_auth_process)); + + pinEntry.setVisibility(View.GONE); + pinEntryButton.setVisibility(View.GONE); + startButton.setText(res.getString(R.string.auth_start)); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + app.setAction("setting up"); + + setTheme(); + setContentView(R.layout.auth); + setTitle(res.getString(R.string.auth_twitter)); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + private void init() { + startButton = (Button) findViewById(R.id.start); + pinEntry = (EditText) findViewById(R.id.pin); + pinEntryButton = (Button) findViewById(R.id.pin_button); + + OAtoken = prefs.getString("temp-token-public", null); + OAtokenSecret = prefs.getString("temp-token-secret", null); + + startButton.setEnabled(true); + startButton.setOnClickListener(new startListener()); + + if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { + // start authorization process + startButton.setText(res.getString(R.string.auth_start)); + } else { + // already have temporary tokens, continue from pin + startButton.setText(res.getString(R.string.auth_again)); + + pinEntry.setVisibility(View.VISIBLE); + pinEntryButton.setVisibility(View.VISIBLE); + pinEntryButton.setOnClickListener(new confirmPINListener()); + } + } + + private void requestToken() { + final String host = "twitter.com"; + final String pathRequest = "/oauth/request_token"; + final String pathAuthorize = "/oauth/authorize"; + final String method = "GET"; + + int status = 0; + try { + String lineOne = null; + HttpsURLConnection connection = null; + + try { + final StringBuilder sb = new StringBuilder(); + final String params = cgOAuth.signOAuth(host, pathRequest, method, true, new HashMap<String, String>(), null, null); + + int code = -1; + int retries = 0; + + do { + // base.trustAllHosts(); + Log.d(cgSettings.tag, "https://" + host + pathRequest + "?" + params); + final URL u = new URL("https://" + host + pathRequest + "?" + params); + final URLConnection uc = u.openConnection(); + connection = (HttpsURLConnection) uc; + + // connection.setHostnameVerifier(base.doNotVerify); + connection.setReadTimeout(30000); + connection.setRequestMethod(method); + HttpsURLConnection.setFollowRedirects(true); + connection.setDoInput(true); + connection.setDoOutput(false); + + final InputStream in = connection.getInputStream(); + final InputStreamReader ins = new InputStreamReader(in); + final BufferedReader br = new BufferedReader(ins, 16 * 1024); + + while ((lineOne = br.readLine()) != null) { + sb.append(lineOne); + sb.append('\n'); + } + + code = connection.getResponseCode(); + retries++; + + Log.i(cgSettings.tag, host + ": " + connection.getResponseCode() + " " + connection.getResponseMessage()); + + br.close(); + in.close(); + ins.close(); + } while (code == -1 && retries < 5); + + final String line = sb.toString(); + + if (StringUtils.isNotBlank(line)) { + final Matcher paramsMatcher1 = paramsPattern1.matcher(line); + if (paramsMatcher1.find() && paramsMatcher1.groupCount() > 0) { + OAtoken = paramsMatcher1.group(1); + } + final Matcher paramsMatcher2 = paramsPattern2.matcher(line); + if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) { + OAtokenSecret = paramsMatcher2.group(1); + } + + if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) { + final SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefsEdit.putString("temp-token-public", OAtoken); + prefsEdit.putString("temp-token-secret", OAtokenSecret); + prefsEdit.commit(); + + try { + final Map<String, String> paramsPre = new HashMap<String, String>(); + paramsPre.put("oauth_callback", "oob"); + + final String paramsBrowser = cgOAuth.signOAuth(host, pathAuthorize, "GET", true, paramsPre, OAtoken, OAtokenSecret); + + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + host + pathAuthorize + "?" + paramsBrowser))); + + status = 1; + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoauth.requestToken(2): " + e.toString()); + } + } + } + } catch (IOException eio) { + Log.e(cgSettings.tag, "cgeoauth.requestToken(IO): " + eio.toString() + " ~ " + connection.getResponseCode() + ": " + connection.getResponseMessage()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoauth.requestToken(1): " + e.toString()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } catch (Exception e2) { + Log.e(cgSettings.tag, "cgeoauth.requestToken(3): " + e2.toString()); + } + + requestTokenHandler.sendEmptyMessage(status); + } + + private void changeToken() { + final String host = "twitter.com"; + final String path = "/oauth/access_token"; + final String method = "POST"; + + int status = 0; + String lineOne = null; + + try { + final Map<String, String> paramsPre = new HashMap<String, String>(); + paramsPre.put("oauth_verifier", pinEntry.getText().toString()); + + int code = -1; + int retries = 0; + + final String params = cgOAuth.signOAuth(host, path, method, true, paramsPre, OAtoken, OAtokenSecret); + final StringBuilder sb = new StringBuilder(); + do { + // base.trustAllHosts(); + final URL u = new URL("https://" + host + path); + final URLConnection uc = u.openConnection(); + final HttpsURLConnection connection = (HttpsURLConnection) uc; + + // connection.setHostnameVerifier(base.doNotVerify); + connection.setReadTimeout(30000); + connection.setRequestMethod(method); + HttpsURLConnection.setFollowRedirects(true); + connection.setDoOutput(true); + connection.setDoInput(true); + + final OutputStream out = connection.getOutputStream(); + final OutputStreamWriter wr = new OutputStreamWriter(out); + + wr.write(params); + wr.flush(); + wr.close(); + out.close(); + + final InputStream in = connection.getInputStream(); + final InputStreamReader ins = new InputStreamReader(in); + final BufferedReader br = new BufferedReader(ins, 16 * 1024); + + while ((lineOne = br.readLine()) != null) { + sb.append(lineOne); + sb.append('\n'); + } + + code = connection.getResponseCode(); + retries++; + + Log.i(cgSettings.tag, host + ": " + connection.getResponseCode() + " " + connection.getResponseMessage()); + + br.close(); + ins.close(); + in.close(); + connection.disconnect(); + } while (code == -1 && retries < 5); + + final String line = sb.toString(); + + OAtoken = ""; + OAtokenSecret = ""; + + final Matcher paramsMatcher1 = paramsPattern1.matcher(line); + if (paramsMatcher1.find() && paramsMatcher1.groupCount() > 0) { + OAtoken = paramsMatcher1.group(1); + } + final Matcher paramsMatcher2 = paramsPattern2.matcher(line); + if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) { + OAtokenSecret = paramsMatcher2.group(1); + } + + if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { + OAtoken = ""; + OAtokenSecret = ""; + + final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefs.putString("tokenpublic", null); + prefs.putString("tokensecret", null); + prefs.putInt("twitter", 0); + prefs.commit(); + } else { + final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefs.remove("temp-token-public"); + prefs.remove("temp-token-secret"); + prefs.putString("tokenpublic", OAtoken); + prefs.putString("tokensecret", OAtokenSecret); + prefs.putInt("twitter", 1); + prefs.commit(); + + status = 1; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoauth.changeToken: " + e.toString()); + } + + changeTokensHandler.sendEmptyMessage(status); + } + + private class startListener implements View.OnClickListener { + + public void onClick(View arg0) { + if (requestTokenDialog == null) { + requestTokenDialog = new ProgressDialog(cgeoauth.this); + requestTokenDialog.setCancelable(false); + requestTokenDialog.setMessage(res.getString(R.string.auth_dialog_wait)); + } + requestTokenDialog.show(); + startButton.setEnabled(false); + startButton.setOnTouchListener(null); + startButton.setOnClickListener(null); + + final SharedPreferences.Editor prefs = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefs.putString("temp-token-public", null); + prefs.putString("temp-token-secret", null); + prefs.commit(); + + (new Thread() { + + @Override + public void run() { + requestToken(); + } + }).start(); + } + } + + private class confirmPINListener implements View.OnClickListener { + + public void onClick(View arg0) { + if (((EditText) findViewById(R.id.pin)).getText().toString().length() == 0) { + helpDialog(res.getString(R.string.auth_dialog_pin_title), res.getString(R.string.auth_dialog_pin_message)); + return; + } + + if (changeTokensDialog == null) { + changeTokensDialog = new ProgressDialog(cgeoauth.this); + changeTokensDialog.setCancelable(false); + changeTokensDialog.setMessage(res.getString(R.string.auth_dialog_wait)); + } + changeTokensDialog.show(); + pinEntryButton.setEnabled(false); + pinEntryButton.setOnTouchListener(null); + pinEntryButton.setOnClickListener(null); + + (new Thread() { + + @Override + public void run() { + changeToken(); + } + }).start(); + } + } } diff --git a/src/cgeo/geocaching/cgeocaches.java b/src/cgeo/geocaching/cgeocaches.java index 926a72d..d196ec1 100644 --- a/src/cgeo/geocaching/cgeocaches.java +++ b/src/cgeo/geocaching/cgeocaches.java @@ -1,20 +1,29 @@ package cgeo.geocaching; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractListActivity; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.apps.cachelist.CacheListAppFactory; +import cgeo.geocaching.filter.cgFilter; +import cgeo.geocaching.filter.cgFilterBySize; +import cgeo.geocaching.filter.cgFilterByTrackables; +import cgeo.geocaching.filter.cgFilterByType; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.sorting.CacheComparator; +import cgeo.geocaching.sorting.DateComparator; +import cgeo.geocaching.sorting.DifficultyComparator; +import cgeo.geocaching.sorting.FindsComparator; +import cgeo.geocaching.sorting.GeocodeComparator; +import cgeo.geocaching.sorting.InventoryComparator; +import cgeo.geocaching.sorting.NameComparator; +import cgeo.geocaching.sorting.PopularityComparator; +import cgeo.geocaching.sorting.RatingComparator; +import cgeo.geocaching.sorting.SizeComparator; +import cgeo.geocaching.sorting.StateComparator; +import cgeo.geocaching.sorting.TerrainComparator; +import cgeo.geocaching.sorting.VoteComparator; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -31,6 +40,7 @@ import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; @@ -38,446 +48,437 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.WindowManager; -import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.EditText; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.activity.AbstractListActivity; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; -import cgeo.geocaching.apps.cachelist.CacheListAppFactory; -import cgeo.geocaching.filter.cgFilter; -import cgeo.geocaching.filter.cgFilterBySize; -import cgeo.geocaching.filter.cgFilterByTrackables; -import cgeo.geocaching.filter.cgFilterByType; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.sorting.CacheComparator; -import cgeo.geocaching.sorting.DateComparator; -import cgeo.geocaching.sorting.DifficultyComparator; -import cgeo.geocaching.sorting.FindsComparator; -import cgeo.geocaching.sorting.GeocodeComparator; -import cgeo.geocaching.sorting.InventoryComparator; -import cgeo.geocaching.sorting.NameComparator; -import cgeo.geocaching.sorting.PopularityComparator; -import cgeo.geocaching.sorting.RatingComparator; -import cgeo.geocaching.sorting.SizeComparator; -import cgeo.geocaching.sorting.StateComparator; -import cgeo.geocaching.sorting.TerrainComparator; -import cgeo.geocaching.sorting.VoteComparator; -import cgeo.geocaching.utils.CollectionUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; public class cgeocaches extends AbstractListActivity { - private static final int MAX_LIST_ITEMS = 1000; - private static final String EXTRAS_LIST_TYPE = "type"; - private static final int MENU_COMPASS = 1; - private static final int MENU_REFRESH_STORED = 2; - private static final int MENU_CACHE_DETAILS = 4; - private static final int MENU_DROP_CACHES = 5; - private static final int MENU_IMPORT_GPX = 6; - private static final int MENU_CREATE_LIST = 7; - private static final int MENU_DROP_LIST = 8; - private static final int MENU_INVERT_SELECTION = 9; - private static final int MENU_SORT_DISTANCE = 10; - private static final int MENU_SORT_DIFFICULTY = 11; - private static final int MENU_SORT_TERRAIN = 12; - private static final int MENU_SORT_SIZE = 13; - private static final int MENU_SORT_FAVORITES = 14; - private static final int MENU_SORT_NAME = 15; - private static final int MENU_SORT_GEOCODE = 16; - private static final int MENU_SWITCH_LIST = 17; - private static final int MENU_SORT_RATING = 18; - private static final int MENU_SORT_VOTE = 19; - private static final int MENU_SORT_INVENTORY = 20; - private static final int MENU_IMPORT_WEB = 21; - private static final int MENU_EXPORT_NOTES = 22; - private static final int MENU_REMOVE_FROM_HISTORY = 23; - private static final int MENU_DROP_CACHE = 24; - private static final int MENU_MOVE_TO_LIST = 25; - private static final int MENU_FILTER_CLEAR = 26; - private static final int MENU_FILTER_TRACKABLES = 27; - private static final int SUBMENU_FILTER_SIZE = 28; - private static final int SUBMENU_FILTER_TYPE = 29; - private static final int MENU_FILTER_TYPE_GPS = 30; - private static final int MENU_FILTER_TYPE_GCHQ = 31; - private static final int MENU_FILTER_TYPE_APE = 32; - private static final int MENU_FILTER_TYPE_LOSTFOUND = 33; - private static final int MENU_FILTER_TYPE_WHERIGO = 34; - private static final int MENU_FILTER_TYPE_VIRTUAL = 35; - private static final int MENU_FILTER_TYPE_WEBCAM = 36; - private static final int MENU_FILTER_TYPE_CITO = 37; - private static final int MENU_FILTER_TYPE_EARTH = 38; - private static final int MENU_FILTER_TYPE_MEGA = 39; - private static final int MENU_FILTER_TYPE_EVENT = 40; - private static final int MENU_FILTER_TYPE_LETTERBOX = 41; - private static final int MENU_FILTER_TYPE_MYSTERY = 42; - private static final int MENU_FILTER_TYPE_MULTI = 43; - private static final int MENU_FILTER_TYPE_TRADITIONAL = 44; - private static final int MENU_FILTER_SIZE_NOT_CHOSEN = 45; - private static final int MENU_FILTER_SIZE_VIRTUAL = 46; - private static final int MENU_FILTER_SIZE_OTHER = 47; - private static final int MENU_FILTER_SIZE_LARGE = 48; - private static final int MENU_FILTER_SIZE_REGULAR = 49; - private static final int MENU_FILTER_SIZE_SMALL = 50; - private static final int MENU_FILTER_SIZE_MICRO = 51; - private static final int MENU_SWITCH_SELECT_MODE = 52; - private static final int SUBMENU_SHOW_MAP = 54; - private static final int SUBMENU_MANAGE_LISTS = 55; - private static final int SUBMENU_MANAGE_OFFLINE = 56; + private static final int MAX_LIST_ITEMS = 1000; + private static final String EXTRAS_LIST_TYPE = "type"; + private static final int MENU_COMPASS = 1; + private static final int MENU_REFRESH_STORED = 2; + private static final int MENU_CACHE_DETAILS = 4; + private static final int MENU_DROP_CACHES = 5; + private static final int MENU_IMPORT_GPX = 6; + private static final int MENU_CREATE_LIST = 7; + private static final int MENU_DROP_LIST = 8; + private static final int MENU_INVERT_SELECTION = 9; + private static final int MENU_SORT_DISTANCE = 10; + private static final int MENU_SORT_DIFFICULTY = 11; + private static final int MENU_SORT_TERRAIN = 12; + private static final int MENU_SORT_SIZE = 13; + private static final int MENU_SORT_FAVORITES = 14; + private static final int MENU_SORT_NAME = 15; + private static final int MENU_SORT_GEOCODE = 16; + private static final int MENU_SWITCH_LIST = 17; + private static final int MENU_SORT_RATING = 18; + private static final int MENU_SORT_VOTE = 19; + private static final int MENU_SORT_INVENTORY = 20; + private static final int MENU_IMPORT_WEB = 21; + private static final int MENU_EXPORT_NOTES = 22; + private static final int MENU_REMOVE_FROM_HISTORY = 23; + private static final int MENU_DROP_CACHE = 24; + private static final int MENU_MOVE_TO_LIST = 25; + private static final int MENU_FILTER_CLEAR = 26; + private static final int MENU_FILTER_TRACKABLES = 27; + private static final int SUBMENU_FILTER_SIZE = 28; + private static final int SUBMENU_FILTER_TYPE = 29; + private static final int MENU_FILTER_TYPE_GPS = 30; + private static final int MENU_FILTER_TYPE_GCHQ = 31; + private static final int MENU_FILTER_TYPE_APE = 32; + private static final int MENU_FILTER_TYPE_LOSTFOUND = 33; + private static final int MENU_FILTER_TYPE_WHERIGO = 34; + private static final int MENU_FILTER_TYPE_VIRTUAL = 35; + private static final int MENU_FILTER_TYPE_WEBCAM = 36; + private static final int MENU_FILTER_TYPE_CITO = 37; + private static final int MENU_FILTER_TYPE_EARTH = 38; + private static final int MENU_FILTER_TYPE_MEGA = 39; + private static final int MENU_FILTER_TYPE_EVENT = 40; + private static final int MENU_FILTER_TYPE_LETTERBOX = 41; + private static final int MENU_FILTER_TYPE_MYSTERY = 42; + private static final int MENU_FILTER_TYPE_MULTI = 43; + private static final int MENU_FILTER_TYPE_TRADITIONAL = 44; + private static final int MENU_FILTER_SIZE_NOT_CHOSEN = 45; + private static final int MENU_FILTER_SIZE_VIRTUAL = 46; + private static final int MENU_FILTER_SIZE_OTHER = 47; + private static final int MENU_FILTER_SIZE_LARGE = 48; + private static final int MENU_FILTER_SIZE_REGULAR = 49; + private static final int MENU_FILTER_SIZE_SMALL = 50; + private static final int MENU_FILTER_SIZE_MICRO = 51; + private static final int MENU_SWITCH_SELECT_MODE = 52; + private static final int SUBMENU_SHOW_MAP = 54; + private static final int SUBMENU_MANAGE_LISTS = 55; + private static final int SUBMENU_MANAGE_OFFLINE = 56; private static final int SUBMENU_SORT = 57; - private static final int SUBMENU_FILTER = 58; - private static final int SUBMENU_IMPORT = 59; - private static final int SUBMENU_MANAGE_HISTORY = 60; - private static final int MENU_SORT_DATE = 61; - private static final int MENU_SORT_FINDS = 62; - private static final int MENU_SORT_STATE = 63; - - private static final int CONTEXT_MENU_MOVE_TO_LIST = 1000; - private static final int MENU_MOVE_SELECTED_OR_ALL_TO_LIST = 1200; - - private String action = null; - private String type = null; - private Geopoint coords = null; - private String cachetype = null; - private String keyword = null; - private String address = null; - private String username = null; - private UUID searchId = null; - private List<cgCache> cacheList = new ArrayList<cgCache>(); - private cgCacheListAdapter adapter = null; - private LayoutInflater inflater = null; - private View listFooter = null; - private TextView listFooterText = null; - private ProgressDialog waitDialog = null; - private Float northHeading = 0f; - private cgGeo geo = null; - private cgDirection dir = null; - private cgUpdateLoc geoUpdate = new update(); - private cgUpdateDir dirUpdate = new UpdateDirection(); - private String title = ""; - private int detailTotal = 0; - private int detailProgress = 0; - private long detailProgressTime = 0L; - private geocachesLoadDetails threadD = null; - private geocachesLoadFromWeb threadW = null; - private geocachesDropDetails threadR = null; - private geocachesExportFieldNotes threadF = null; - private geocachesRemoveFromHistory threadH = null; - private int listId = 0; - private List<cgList> lists = null; - private String selectedFilter = null; - private GeocodeComparator gcComparator = new GeocodeComparator(); - private Handler loadCachesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (searchId != null) { - setTitle(title + " [" + app.getCount(searchId) + "]"); - cacheList.clear(); - - final List<cgCache> cacheListTmp = app.getCaches(searchId); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - - Collections.sort((List<cgCache>)cacheList, gcComparator); - } - } else { - setTitle(title); - } - - setAdapter(); - - if (cacheList == null) { - showToast(res.getString(R.string.err_list_load_fail)); - setMoreCaches(false); - } else { - final Integer count = app.getTotal(searchId); - - if (count != null && count > 0) { - if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { - setMoreCaches(true); - } else { - setMoreCaches(false); - } - } else { - setMoreCaches(false); - } - } - - if (cacheList != null && app.getError(searchId) != null && app.getError(searchId).equalsIgnoreCase(cgBase.errorRetrieve.get(-7))) { - AlertDialog.Builder dialog = new AlertDialog.Builder(cgeocaches.this); - dialog.setTitle(res.getString(R.string.license)); - dialog.setMessage(res.getString(R.string.err_license)); - dialog.setCancelable(true); - dialog.setNegativeButton(res.getString(R.string.license_dismiss), new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - settings.deleteCookies(); - dialog.cancel(); - } - }); - dialog.setPositiveButton(res.getString(R.string.license_show), new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - settings.deleteCookies(); - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/software/agreement.aspx?ID=0"))); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - } else if (app != null && StringUtils.isNotBlank(app.getError(searchId))) { - showToast(res.getString(R.string.err_download_fail) + app.getError(searchId) + "."); - - hideLoading(); - showProgress(false); - - finish(); - return; - } - - if (geo != null && geo.coordsNow != null) { - adapter.setActualCoordinates(geo.coordsNow); - adapter.setActualHeading(northHeading); - } - } catch (Exception e) { - showToast(res.getString(R.string.err_detail_cache_find_any)); - Log.e(cgSettings.tag, "cgeocaches.loadCachesHandler: " + e.toString()); - - hideLoading(); - showProgress(false); - - finish(); - return; - } - - try { - hideLoading(); - showProgress(false); - } catch (Exception e2) { - Log.e(cgSettings.tag, "cgeocaches.loadCachesHandler.2: " + e2.toString()); - } - - if (adapter != null) { - adapter.setSelectMode(false, true); - } - } - }; - private Handler loadNextPageHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (searchId != null) { - setTitle(title + " [" + app.getCount(searchId) + "]"); - cacheList.clear(); - - final List<cgCache> cacheListTmp = app.getCaches(searchId); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - Collections.sort((List<cgCache>)cacheList, gcComparator); - } - if(adapter != null){ - adapter.reFilter(); - } - } else { - setTitle(title); - } - - setAdapter(); - - if (cacheList == null) { - showToast(res.getString(R.string.err_list_load_fail)); - setMoreCaches(false); - } else { - final Integer count = app.getTotal(searchId); - if (count != null && count > 0) { - if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { - setMoreCaches(true); - } else { - setMoreCaches(false); - } - } else { - setMoreCaches(false); - } - } - - if (StringUtils.isNotBlank(app.getError(searchId))) { - showToast(res.getString(R.string.err_download_fail) + app.getError(searchId) + "."); - - listFooter.setOnClickListener(new moreCachesListener()); - hideLoading(); - showProgress(false); - - finish(); - return; - } - - if (geo != null && geo.coordsNow != null) { - adapter.setActualCoordinates(geo.coordsNow); - adapter.setActualHeading(northHeading); - } - } catch (Exception e) { - showToast(res.getString(R.string.err_detail_cache_find_next)); - Log.e(cgSettings.tag, "cgeocaches.loadNextPageHandler: " + e.toString()); - } - - listFooter.setOnClickListener(new moreCachesListener()); - - hideLoading(); - showProgress(false); - - if (adapter != null) { - adapter.setSelectMode(false, true); - } - } - }; - private Handler loadDetailsHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - setAdapter(); - - if (msg.what > -1) { - if (waitDialog != null) { - cacheList.get(msg.what).statusChecked = false; - - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - - int secondsElapsed = (int)((System.currentTimeMillis() - detailProgressTime) / 1000); - int minutesRemaining = (int) ((detailTotal - detailProgress) * secondsElapsed / ((detailProgress > 0) ? detailProgress : 1) / 60); - - waitDialog.setProgress(detailProgress); - if (minutesRemaining < 1) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); - } else if (minutesRemaining == 1) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + minutesRemaining + " " + res.getString(R.string.caches_eta_min)); - } else { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + minutesRemaining + " " + res.getString(R.string.caches_eta_mins)); - } - } - } else { - if (cacheList != null && searchId != null) { - final List<cgCache> cacheListTmp = app.getCaches(searchId); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.clear(); - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - Collections.sort((List<cgCache>)cacheList, gcComparator); - } - } - - if (geo != null && geo.coordsNow != null) { - adapter.setActualCoordinates(geo.coordsNow); - adapter.setActualHeading(northHeading); - } - - showProgress(false); - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } - - if (geo == null) { - geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); - } - if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { - dir = app.startDir(cgeocaches.this, dirUpdate); - } - } - } - }; - private Handler downloadFromWebHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - setAdapter(); - - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - - if (msg.what == 0) { //no caches - waitDialog.setMessage(res.getString(R.string.web_import_waiting)); - } else if (msg.what == 1) { //cache downloading - waitDialog.setMessage(res.getString(R.string.web_downloading)+" "+(String)msg.obj+"..."); - } else if (msg.what == 2) { //Cache downloaded - waitDialog.setMessage(res.getString(R.string.web_downloaded)+" "+(String)msg.obj+"."); - refreshCurrentList(); + private static final int SUBMENU_FILTER = 58; + private static final int SUBMENU_IMPORT = 59; + private static final int SUBMENU_MANAGE_HISTORY = 60; + private static final int MENU_SORT_DATE = 61; + private static final int MENU_SORT_FINDS = 62; + private static final int MENU_SORT_STATE = 63; + + private static final int CONTEXT_MENU_MOVE_TO_LIST = 1000; + private static final int MENU_MOVE_SELECTED_OR_ALL_TO_LIST = 1200; + + private String action = null; + private String type = null; + private Geopoint coords = null; + private String cachetype = null; + private String keyword = null; + private String address = null; + private String username = null; + private UUID searchId = null; + private List<cgCache> cacheList = new ArrayList<cgCache>(); + private cgCacheListAdapter adapter = null; + private LayoutInflater inflater = null; + private View listFooter = null; + private TextView listFooterText = null; + private ProgressDialog waitDialog = null; + private Float northHeading = 0f; + private cgGeo geo = null; + private cgDirection dir = null; + private cgUpdateLoc geoUpdate = new update(); + private cgUpdateDir dirUpdate = new UpdateDirection(); + private String title = ""; + private int detailTotal = 0; + private int detailProgress = 0; + private long detailProgressTime = 0L; + private geocachesLoadDetails threadD = null; + private geocachesLoadFromWeb threadW = null; + private geocachesDropDetails threadR = null; + private geocachesExportFieldNotes threadF = null; + private geocachesRemoveFromHistory threadH = null; + private int listId = 0; + private List<cgList> lists = null; + private String selectedFilter = null; + private GeocodeComparator gcComparator = new GeocodeComparator(); + private Handler loadCachesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (searchId != null) { + setTitle(title + " [" + app.getCount(searchId) + "]"); + cacheList.clear(); + + final List<cgCache> cacheListTmp = app.getCaches(searchId); + if (CollectionUtils.isNotEmpty(cacheListTmp)) { + cacheList.addAll(cacheListTmp); + cacheListTmp.clear(); + + Collections.sort((List<cgCache>) cacheList, gcComparator); + } + } else { + setTitle(title); + } + + setAdapter(); + + if (cacheList == null) { + showToast(res.getString(R.string.err_list_load_fail)); + setMoreCaches(false); + } else { + final Integer count = app.getTotal(searchId); + + if (count != null && count > 0) { + if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { + setMoreCaches(true); + } else { + setMoreCaches(false); + } + } else { + setMoreCaches(false); + } + } + + if (cacheList != null && app.getError(searchId) != null && app.getError(searchId).equalsIgnoreCase(cgBase.errorRetrieve.get(-7))) { + AlertDialog.Builder dialog = new AlertDialog.Builder(cgeocaches.this); + dialog.setTitle(res.getString(R.string.license)); + dialog.setMessage(res.getString(R.string.err_license)); + dialog.setCancelable(true); + dialog.setNegativeButton(res.getString(R.string.license_dismiss), new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + settings.deleteCookies(); + dialog.cancel(); + } + }); + dialog.setPositiveButton(res.getString(R.string.license_show), new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + settings.deleteCookies(); + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/software/agreement.aspx?ID=0"))); + } + }); + + AlertDialog alert = dialog.create(); + alert.show(); + } else if (app != null && StringUtils.isNotBlank(app.getError(searchId))) { + showToast(res.getString(R.string.err_download_fail) + app.getError(searchId) + "."); + + hideLoading(); + showProgress(false); + + finish(); + return; + } + + if (geo != null && geo.coordsNow != null) { + adapter.setActualCoordinates(geo.coordsNow); + adapter.setActualHeading(northHeading); + } + } catch (Exception e) { + showToast(res.getString(R.string.err_detail_cache_find_any)); + Log.e(cgSettings.tag, "cgeocaches.loadCachesHandler: " + e.toString()); + + hideLoading(); + showProgress(false); + + finish(); + return; + } + + try { + hideLoading(); + showProgress(false); + } catch (Exception e2) { + Log.e(cgSettings.tag, "cgeocaches.loadCachesHandler.2: " + e2.toString()); + } + + if (adapter != null) { + adapter.setSelectMode(false, true); + } + } + }; + private Handler loadNextPageHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (searchId != null) { + setTitle(title + " [" + app.getCount(searchId) + "]"); + cacheList.clear(); + + final List<cgCache> cacheListTmp = app.getCaches(searchId); + if (CollectionUtils.isNotEmpty(cacheListTmp)) { + cacheList.addAll(cacheListTmp); + cacheListTmp.clear(); + Collections.sort((List<cgCache>) cacheList, gcComparator); + } + if (adapter != null) { + adapter.reFilter(); + } + } else { + setTitle(title); + } + + setAdapter(); + + if (cacheList == null) { + showToast(res.getString(R.string.err_list_load_fail)); + setMoreCaches(false); + } else { + final Integer count = app.getTotal(searchId); + if (count != null && count > 0) { + if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { + setMoreCaches(true); + } else { + setMoreCaches(false); + } + } else { + setMoreCaches(false); + } + } + + if (StringUtils.isNotBlank(app.getError(searchId))) { + showToast(res.getString(R.string.err_download_fail) + app.getError(searchId) + "."); + + listFooter.setOnClickListener(new moreCachesListener()); + hideLoading(); + showProgress(false); + + finish(); + return; + } + + if (geo != null && geo.coordsNow != null) { + adapter.setActualCoordinates(geo.coordsNow); + adapter.setActualHeading(northHeading); + } + } catch (Exception e) { + showToast(res.getString(R.string.err_detail_cache_find_next)); + Log.e(cgSettings.tag, "cgeocaches.loadNextPageHandler: " + e.toString()); + } + + listFooter.setOnClickListener(new moreCachesListener()); + + hideLoading(); + showProgress(false); + + if (adapter != null) { + adapter.setSelectMode(false, true); + } + } + }; + private Handler loadDetailsHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + setAdapter(); + + if (msg.what > -1) { + if (waitDialog != null) { + cacheList.get(msg.what).statusChecked = false; + + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + + int secondsElapsed = (int) ((System.currentTimeMillis() - detailProgressTime) / 1000); + int minutesRemaining = (int) ((detailTotal - detailProgress) * secondsElapsed / ((detailProgress > 0) ? detailProgress : 1) / 60); + + waitDialog.setProgress(detailProgress); + if (minutesRemaining < 1) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); + } else if (minutesRemaining == 1) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + minutesRemaining + " " + res.getString(R.string.caches_eta_min)); + } else { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + minutesRemaining + " " + res.getString(R.string.caches_eta_mins)); + } + } + } else { + if (cacheList != null && searchId != null) { + final List<cgCache> cacheListTmp = app.getCaches(searchId); + if (CollectionUtils.isNotEmpty(cacheListTmp)) { + cacheList.clear(); + cacheList.addAll(cacheListTmp); + cacheListTmp.clear(); + Collections.sort((List<cgCache>) cacheList, gcComparator); + } + } + + if (geo != null && geo.coordsNow != null) { + adapter.setActualCoordinates(geo.coordsNow); + adapter.setActualHeading(northHeading); + } + + showProgress(false); + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } + + if (geo == null) { + geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); + } + if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { + dir = app.startDir(cgeocaches.this, dirUpdate); + } + } + } + }; + private Handler downloadFromWebHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + setAdapter(); + + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + + if (msg.what == 0) { //no caches + waitDialog.setMessage(res.getString(R.string.web_import_waiting)); + } else if (msg.what == 1) { //cache downloading + waitDialog.setMessage(res.getString(R.string.web_downloading) + " " + (String) msg.obj + "..."); + } else if (msg.what == 2) { //Cache downloaded + waitDialog.setMessage(res.getString(R.string.web_downloaded) + " " + (String) msg.obj + "."); + refreshCurrentList(); } else if (msg.what == -2) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); showToast(res.getString(R.string.sendToCgeo_download_fail)); - finish(); - return; + finish(); + return; } else if (msg.what == -3) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); showToast(res.getString(R.string.sendToCgeo_no_registration)); - finish(); - return; - } else { - if (adapter != null) { - adapter.setSelectMode(false, true); - } - - cacheList.clear(); - - final List<cgCache> cacheListTmp = app.getCaches(searchId); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - - Collections.sort((List<cgCache>)cacheList, gcComparator); - } - - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - } - }; - private Handler dropDetailsHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (adapter != null) { - adapter.setSelectMode(false, true); - } - - refreshCurrentList(); - - cacheList.clear(); - - final List<cgCache> cacheListTmp = app.getCaches(searchId); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - - Collections.sort((List<cgCache>)cacheList, gcComparator); - } - - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } - } - }; + finish(); + return; + } else { + if (adapter != null) { + adapter.setSelectMode(false, true); + } + + cacheList.clear(); + + final List<cgCache> cacheListTmp = app.getCaches(searchId); + if (CollectionUtils.isNotEmpty(cacheListTmp)) { + cacheList.addAll(cacheListTmp); + cacheListTmp.clear(); + + Collections.sort((List<cgCache>) cacheList, gcComparator); + } + + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + }; + private Handler dropDetailsHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (adapter != null) { + adapter.setSelectMode(false, true); + } + + refreshCurrentList(); + + cacheList.clear(); + + final List<cgCache> cacheListTmp = app.getCaches(searchId); + if (CollectionUtils.isNotEmpty(cacheListTmp)) { + cacheList.addAll(cacheListTmp); + cacheListTmp.clear(); + + Collections.sort((List<cgCache>) cacheList, gcComparator); + } + + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } + } + }; private Handler removeFromHistoryHandler = new Handler() { @Override @@ -500,7 +501,7 @@ public class cgeocaches extends AbstractListActivity { } } }; - private Handler exportFieldNotesHandler = new Handler() { + private Handler exportFieldNotesHandler = new Handler() { @Override public void handleMessage(Message msg) @@ -535,371 +536,371 @@ public class cgeocaches extends AbstractListActivity { } } }; - private ContextMenuInfo lastMenuInfo; - /** - * the navigation menu item for the cache list (not the context menu!), or <code>null</code> - */ - private MenuItem navigationMenu; - /** - * flag indicating whether we shall show the move to list context menu - */ - private boolean contextMenuMoveToList = false; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - app.setAction(action); - - setTheme(); - setContentView(R.layout.caches); - setTitle("caches"); - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - type = extras.getString(EXTRAS_LIST_TYPE); - coords = new Geopoint(extras.getDouble("latitude"), extras.getDouble("longitude")); - cachetype = extras.getString("cachetype"); - keyword = extras.getString("keyword"); - address = extras.getString("address"); - username = extras.getString("username"); - } - - init(); - - Thread threadPure; - cgSearchThread thread; - - if (type.equals("offline")) { - listId = settings.getLastList(); - if (listId <= 0) { - listId = 1; - title = res.getString(R.string.caches_stored); - } else { - final cgList list = app.getList(listId); - title = list.title; - } - - setTitle(title); - showProgress(true); - setLoadingCaches(); - - threadPure = new geocachesLoadByOffline(loadCachesHandler, coords, listId); - threadPure.start(); - } else if (type.equals("history")) { - if (adapter != null) { - adapter.setHistoric(true); - } - - title = res.getString(R.string.caches_history); - setTitle(title); - showProgress(true); - setLoadingCaches(); - - threadPure = new geocachesLoadByHistory(loadCachesHandler); - threadPure.start(); - } else if (type.equals("nearest")) { - action = "pending"; - title = res.getString(R.string.caches_nearby); - setTitle(title); - showProgress(true); - setLoadingCaches(); - - thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else if (type.equals("coordinate")) { - action = "planning"; - title = cgBase.formatCoords(coords, true); - setTitle(title); - showProgress(true); - setLoadingCaches(); - - thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else if (type.equals("keyword")) { - title = keyword; - setTitle(title); - showProgress(true); - setLoadingCaches(); - - thread = new geocachesLoadByKeyword(loadCachesHandler, keyword, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else if (type.equals("address")) { - action = "planning"; - if (StringUtils.isNotBlank(address)) { - title = address; - setTitle(title); - showProgress(true); - setLoadingCaches(); - } else { - title = cgBase.formatCoords(coords, true); - setTitle(title); - showProgress(true); - setLoadingCaches(); - } - - thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else if (type.equals("username")) { - title = username; - setTitle(title); - showProgress(true); - setLoadingCaches(); - - thread = new geocachesLoadByUserName(loadCachesHandler, username, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else if (type.equals("owner")) { - title = username; - setTitle(title); - showProgress(true); - setLoadingCaches(); - - thread = new geocachesLoadByOwner(loadCachesHandler, username, cachetype); - thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); - thread.start(); - } else { - title = "caches"; - setTitle(title); - Log.e(cgSettings.tag, "cgeocaches.onCreate: No action or unknown action specified"); - } - - prepareFilterBar(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - init(); - - if (adapter != null && geo != null && geo.coordsNow != null) { - adapter.setActualCoordinates(geo.coordsNow); - adapter.setActualHeading(northHeading); - } - - if (adapter != null) { - adapter.setSelectMode(false, true); - if (geo != null && geo.coordsNow != null) { - adapter.forceSort(geo.coordsNow); - } - } - - if (loadCachesHandler != null && searchId != null) { - loadCachesHandler.sendEmptyMessage(0); - } - } - - @Override - public void onDestroy() { - if (adapter != null) { - adapter = null; - } - - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - SubMenu subMenuFilter = menu.addSubMenu(0, SUBMENU_FILTER, 0, res.getString(R.string.caches_filter)).setIcon(android.R.drawable.ic_menu_search); - subMenuFilter.setHeaderTitle(res.getString(R.string.caches_filter_title)); - if (settings.cacheType == null) { - 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, 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)); - - SubMenu subMenuSort = menu.addSubMenu(0, SUBMENU_SORT, 0, res.getString(R.string.caches_sort)).setIcon(android.R.drawable.ic_menu_sort_alphabetically); - subMenuSort.setHeaderTitle(res.getString(R.string.caches_sort_title)); - - // sort the context menu labels alphabetically for easier reading - Map<String, Integer> comparators = new HashMap<String, Integer>(); - comparators.put(res.getString(R.string.caches_sort_distance), MENU_SORT_DISTANCE); - comparators.put(res.getString(R.string.caches_sort_difficulty), MENU_SORT_DIFFICULTY); - comparators.put(res.getString(R.string.caches_sort_terrain), MENU_SORT_TERRAIN); - comparators.put(res.getString(R.string.caches_sort_size), MENU_SORT_SIZE); - comparators.put(res.getString(R.string.caches_sort_favorites), MENU_SORT_FAVORITES); - comparators.put(res.getString(R.string.caches_sort_name), MENU_SORT_NAME); - comparators.put(res.getString(R.string.caches_sort_gccode), MENU_SORT_GEOCODE); - comparators.put(res.getString(R.string.caches_sort_rating), MENU_SORT_RATING); - comparators.put(res.getString(R.string.caches_sort_vote), MENU_SORT_VOTE); - comparators.put(res.getString(R.string.caches_sort_inventory), MENU_SORT_INVENTORY); - comparators.put(res.getString(R.string.caches_sort_date), MENU_SORT_DATE); - comparators.put(res.getString(R.string.caches_sort_finds), MENU_SORT_FINDS); - comparators.put(res.getString(R.string.caches_sort_state), MENU_SORT_STATE); - - List<String> sortedLabels = new ArrayList<String>(comparators.keySet()); - Collections.sort(sortedLabels); - for (String label : sortedLabels) { - Integer id = comparators.get(label); - subMenuSort.add(1, id, 0, label).setCheckable(true).setChecked(id == MENU_SORT_DISTANCE); - } - - subMenuSort.setGroupCheckable(1, true, true); - - menu.add(0, MENU_SWITCH_SELECT_MODE, 0, res.getString(R.string.caches_select_mode)).setIcon(android.R.drawable.ic_menu_agenda); - menu.add(0, MENU_INVERT_SELECTION, 0, res.getString(R.string.caches_select_invert)).setIcon(android.R.drawable.ic_menu_agenda); - if (type.equals("offline")) { - SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_OFFLINE, 0, res.getString(R.string.caches_manage)).setIcon(android.R.drawable.ic_menu_save); - subMenu.add(0, MENU_DROP_CACHES, 0, res.getString(R.string.caches_drop_all)); // delete saved caches - subMenu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.cache_offline_refresh)); // download details for all caches - subMenu.add(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list)); - subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes - if (settings.webDeviceCode == null) - { - menu.add(0, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setIcon(android.R.drawable.ic_menu_upload); // import gpx file - } else { - SubMenu subMenuImport = menu.addSubMenu(0, SUBMENU_IMPORT, 0, res.getString(R.string.import_title)).setIcon(android.R.drawable.ic_menu_upload); // import - subMenuImport.add(1, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setCheckable(false).setChecked(false); - subMenuImport.add(1, MENU_IMPORT_WEB, 0, res.getString(R.string.web_import_title)).setCheckable(false).setChecked(false); - } - } else { - if (type.equals("history")) - { - SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_HISTORY, 0, res.getString(R.string.caches_manage)).setIcon(android.R.drawable.ic_menu_save); - subMenu.add(0, MENU_REMOVE_FROM_HISTORY, 0, res.getString(R.string.cache_clear_history)); // remove from history - subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes - } - menu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.caches_store_offline)).setIcon(android.R.drawable.ic_menu_set_as); // download details for all caches - } - - navigationMenu = CacheListAppFactory.addMenuItems(menu, this, res); - - if (type.equals("offline")) { - SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_LISTS, 0, res.getString(R.string.list_menu)).setIcon(android.R.drawable.ic_menu_more); - subMenu.add(0, MENU_CREATE_LIST, 0, res.getString(R.string.list_menu_create)); - subMenu.add(0, MENU_DROP_LIST, 0, res.getString(R.string.list_menu_drop)); - subMenu.add(0, MENU_SWITCH_LIST, 0, res.getString(R.string.list_menu_change)); - } - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - try { - if (adapter != null && adapter.getSelectMode()) { - menu.findItem(MENU_SWITCH_SELECT_MODE).setTitle(res.getString(R.string.caches_select_mode_exit)); - menu.findItem(MENU_INVERT_SELECTION).setVisible(true); - } else { - menu.findItem(MENU_SWITCH_SELECT_MODE).setTitle(res.getString(R.string.caches_select_mode)); - menu.findItem(MENU_INVERT_SELECTION).setVisible(false); - } - - boolean hasSelection = adapter != null && adapter.getChecked() > 0; - if (type != null && type.equals("offline")) { // only offline list - if (hasSelection) { - menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_selected) + " (" + adapter.getChecked() + ")"); - } else { - menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_all)); - } - - if (hasSelection) { - menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_selected) + " (" + adapter.getChecked() + ")"); - } else { - menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_all)); - } - - if (hasSelection) { - menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_selected) + " (" + adapter.getChecked() + ")"); - } else { - menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_all)); - } - } else { // search and history list (all other than offline) - if (hasSelection) { - menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_selected) + " (" + adapter.getChecked() + ")"); - } else { - menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_offline)); - } - } - - // Hide menus if cache-list is empty - int[] hideIfEmptyList = new int[] {MENU_SWITCH_SELECT_MODE, - SUBMENU_MANAGE_OFFLINE, - SUBMENU_MANAGE_HISTORY, - SUBMENU_SHOW_MAP, - SUBMENU_SORT, - MENU_REFRESH_STORED}; - - boolean menuEnabled = cacheList.size() > 0; - for (int itemId : hideIfEmptyList) - { - MenuItem item = menu.findItem(itemId); - if (null != item) - { - item.setEnabled(menuEnabled); - } - } - - if (navigationMenu != null) { - navigationMenu.setEnabled(menuEnabled); - } - - MenuItem item = menu.findItem(MENU_DROP_LIST); - if (item != null) { - item.setVisible(listId != 1); - } - - boolean multipleLists = app.getLists().size() >= 2; - item = menu.findItem(MENU_SWITCH_LIST); - if (item != null) { - item.setVisible(multipleLists); - } - item = menu.findItem(MENU_MOVE_TO_LIST); - if (item != null) { - item.setVisible(multipleLists); - } - - item = menu.findItem(MENU_REMOVE_FROM_HISTORY); - if (null != item) { + private ContextMenuInfo lastMenuInfo; + /** + * the navigation menu item for the cache list (not the context menu!), or <code>null</code> + */ + private MenuItem navigationMenu; + /** + * flag indicating whether we shall show the move to list context menu + */ + private boolean contextMenuMoveToList = false; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + app.setAction(action); + + setTheme(); + setContentView(R.layout.caches); + setTitle("caches"); + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + type = extras.getString(EXTRAS_LIST_TYPE); + coords = new Geopoint(extras.getDouble("latitude"), extras.getDouble("longitude")); + cachetype = extras.getString("cachetype"); + keyword = extras.getString("keyword"); + address = extras.getString("address"); + username = extras.getString("username"); + } + + init(); + + Thread threadPure; + cgSearchThread thread; + + if (type.equals("offline")) { + listId = settings.getLastList(); + if (listId <= 0) { + listId = 1; + title = res.getString(R.string.caches_stored); + } else { + final cgList list = app.getList(listId); + title = list.title; + } + + setTitle(title); + showProgress(true); + setLoadingCaches(); + + threadPure = new geocachesLoadByOffline(loadCachesHandler, coords, listId); + threadPure.start(); + } else if (type.equals("history")) { + if (adapter != null) { + adapter.setHistoric(true); + } + + title = res.getString(R.string.caches_history); + setTitle(title); + showProgress(true); + setLoadingCaches(); + + threadPure = new geocachesLoadByHistory(loadCachesHandler); + threadPure.start(); + } else if (type.equals("nearest")) { + action = "pending"; + title = res.getString(R.string.caches_nearby); + setTitle(title); + showProgress(true); + setLoadingCaches(); + + thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else if (type.equals("coordinate")) { + action = "planning"; + title = cgBase.formatCoords(coords, true); + setTitle(title); + showProgress(true); + setLoadingCaches(); + + thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else if (type.equals("keyword")) { + title = keyword; + setTitle(title); + showProgress(true); + setLoadingCaches(); + + thread = new geocachesLoadByKeyword(loadCachesHandler, keyword, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else if (type.equals("address")) { + action = "planning"; + if (StringUtils.isNotBlank(address)) { + title = address; + setTitle(title); + showProgress(true); + setLoadingCaches(); + } else { + title = cgBase.formatCoords(coords, true); + setTitle(title); + showProgress(true); + setLoadingCaches(); + } + + thread = new geocachesLoadByCoords(loadCachesHandler, coords, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else if (type.equals("username")) { + title = username; + setTitle(title); + showProgress(true); + setLoadingCaches(); + + thread = new geocachesLoadByUserName(loadCachesHandler, username, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else if (type.equals("owner")) { + title = username; + setTitle(title); + showProgress(true); + setLoadingCaches(); + + thread = new geocachesLoadByOwner(loadCachesHandler, username, cachetype); + thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread)); + thread.start(); + } else { + title = "caches"; + setTitle(title); + Log.e(cgSettings.tag, "cgeocaches.onCreate: No action or unknown action specified"); + } + + prepareFilterBar(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + init(); + + if (adapter != null && geo != null && geo.coordsNow != null) { + adapter.setActualCoordinates(geo.coordsNow); + adapter.setActualHeading(northHeading); + } + + if (adapter != null) { + adapter.setSelectMode(false, true); + if (geo != null && geo.coordsNow != null) { + adapter.forceSort(geo.coordsNow); + } + } + + if (loadCachesHandler != null && searchId != null) { + loadCachesHandler.sendEmptyMessage(0); + } + } + + @Override + public void onDestroy() { + if (adapter != null) { + adapter = null; + } + + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + SubMenu subMenuFilter = menu.addSubMenu(0, SUBMENU_FILTER, 0, res.getString(R.string.caches_filter)).setIcon(android.R.drawable.ic_menu_search); + subMenuFilter.setHeaderTitle(res.getString(R.string.caches_filter_title)); + if (settings.cacheType == null) { + 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, 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)); + + SubMenu subMenuSort = menu.addSubMenu(0, SUBMENU_SORT, 0, res.getString(R.string.caches_sort)).setIcon(android.R.drawable.ic_menu_sort_alphabetically); + subMenuSort.setHeaderTitle(res.getString(R.string.caches_sort_title)); + + // sort the context menu labels alphabetically for easier reading + Map<String, Integer> comparators = new HashMap<String, Integer>(); + comparators.put(res.getString(R.string.caches_sort_distance), MENU_SORT_DISTANCE); + comparators.put(res.getString(R.string.caches_sort_difficulty), MENU_SORT_DIFFICULTY); + comparators.put(res.getString(R.string.caches_sort_terrain), MENU_SORT_TERRAIN); + comparators.put(res.getString(R.string.caches_sort_size), MENU_SORT_SIZE); + comparators.put(res.getString(R.string.caches_sort_favorites), MENU_SORT_FAVORITES); + comparators.put(res.getString(R.string.caches_sort_name), MENU_SORT_NAME); + comparators.put(res.getString(R.string.caches_sort_gccode), MENU_SORT_GEOCODE); + comparators.put(res.getString(R.string.caches_sort_rating), MENU_SORT_RATING); + comparators.put(res.getString(R.string.caches_sort_vote), MENU_SORT_VOTE); + comparators.put(res.getString(R.string.caches_sort_inventory), MENU_SORT_INVENTORY); + comparators.put(res.getString(R.string.caches_sort_date), MENU_SORT_DATE); + comparators.put(res.getString(R.string.caches_sort_finds), MENU_SORT_FINDS); + comparators.put(res.getString(R.string.caches_sort_state), MENU_SORT_STATE); + + List<String> sortedLabels = new ArrayList<String>(comparators.keySet()); + Collections.sort(sortedLabels); + for (String label : sortedLabels) { + Integer id = comparators.get(label); + subMenuSort.add(1, id, 0, label).setCheckable(true).setChecked(id == MENU_SORT_DISTANCE); + } + + subMenuSort.setGroupCheckable(1, true, true); + + menu.add(0, MENU_SWITCH_SELECT_MODE, 0, res.getString(R.string.caches_select_mode)).setIcon(android.R.drawable.ic_menu_agenda); + menu.add(0, MENU_INVERT_SELECTION, 0, res.getString(R.string.caches_select_invert)).setIcon(android.R.drawable.ic_menu_agenda); + if (type.equals("offline")) { + SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_OFFLINE, 0, res.getString(R.string.caches_manage)).setIcon(android.R.drawable.ic_menu_save); + subMenu.add(0, MENU_DROP_CACHES, 0, res.getString(R.string.caches_drop_all)); // delete saved caches + subMenu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.cache_offline_refresh)); // download details for all caches + subMenu.add(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list)); + subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes + if (settings.webDeviceCode == null) + { + menu.add(0, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setIcon(android.R.drawable.ic_menu_upload); // import gpx file + } else { + SubMenu subMenuImport = menu.addSubMenu(0, SUBMENU_IMPORT, 0, res.getString(R.string.import_title)).setIcon(android.R.drawable.ic_menu_upload); // import + subMenuImport.add(1, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setCheckable(false).setChecked(false); + subMenuImport.add(1, MENU_IMPORT_WEB, 0, res.getString(R.string.web_import_title)).setCheckable(false).setChecked(false); + } + } else { + if (type.equals("history")) + { + SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_HISTORY, 0, res.getString(R.string.caches_manage)).setIcon(android.R.drawable.ic_menu_save); + subMenu.add(0, MENU_REMOVE_FROM_HISTORY, 0, res.getString(R.string.cache_clear_history)); // remove from history + subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes + } + menu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.caches_store_offline)).setIcon(android.R.drawable.ic_menu_set_as); // download details for all caches + } + + navigationMenu = CacheListAppFactory.addMenuItems(menu, this, res); + + if (type.equals("offline")) { + SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_LISTS, 0, res.getString(R.string.list_menu)).setIcon(android.R.drawable.ic_menu_more); + subMenu.add(0, MENU_CREATE_LIST, 0, res.getString(R.string.list_menu_create)); + subMenu.add(0, MENU_DROP_LIST, 0, res.getString(R.string.list_menu_drop)); + subMenu.add(0, MENU_SWITCH_LIST, 0, res.getString(R.string.list_menu_change)); + } + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + try { + if (adapter != null && adapter.getSelectMode()) { + menu.findItem(MENU_SWITCH_SELECT_MODE).setTitle(res.getString(R.string.caches_select_mode_exit)); + menu.findItem(MENU_INVERT_SELECTION).setVisible(true); + } else { + menu.findItem(MENU_SWITCH_SELECT_MODE).setTitle(res.getString(R.string.caches_select_mode)); + menu.findItem(MENU_INVERT_SELECTION).setVisible(false); + } + + boolean hasSelection = adapter != null && adapter.getChecked() > 0; + if (type != null && type.equals("offline")) { // only offline list + if (hasSelection) { + menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_selected) + " (" + adapter.getChecked() + ")"); + } else { + menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_all)); + } + + if (hasSelection) { + menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_selected) + " (" + adapter.getChecked() + ")"); + } else { + menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_all)); + } + + if (hasSelection) { + menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_selected) + " (" + adapter.getChecked() + ")"); + } else { + menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_all)); + } + } else { // search and history list (all other than offline) + if (hasSelection) { + menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_selected) + " (" + adapter.getChecked() + ")"); + } else { + menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_offline)); + } + } + + // Hide menus if cache-list is empty + int[] hideIfEmptyList = new int[] { MENU_SWITCH_SELECT_MODE, + SUBMENU_MANAGE_OFFLINE, + SUBMENU_MANAGE_HISTORY, + SUBMENU_SHOW_MAP, + SUBMENU_SORT, + MENU_REFRESH_STORED }; + + boolean menuEnabled = cacheList.size() > 0; + for (int itemId : hideIfEmptyList) + { + MenuItem item = menu.findItem(itemId); + if (null != item) + { + item.setEnabled(menuEnabled); + } + } + + if (navigationMenu != null) { + navigationMenu.setEnabled(menuEnabled); + } + + MenuItem item = menu.findItem(MENU_DROP_LIST); + if (item != null) { + item.setVisible(listId != 1); + } + + boolean multipleLists = app.getLists().size() >= 2; + item = menu.findItem(MENU_SWITCH_LIST); + if (item != null) { + item.setVisible(multipleLists); + } + item = menu.findItem(MENU_MOVE_TO_LIST); + if (item != null) { + item.setVisible(multipleLists); + } + + item = menu.findItem(MENU_REMOVE_FROM_HISTORY); + if (null != item) { if (hasSelection) { item.setTitle(res.getString(R.string.cache_remove_from_history) + " (" + adapter.getChecked() + ")"); } else { @@ -907,8 +908,8 @@ public class cgeocaches extends AbstractListActivity { } } - item = menu.findItem(MENU_EXPORT_NOTES); - if (null != item) { + item = menu.findItem(MENU_EXPORT_NOTES); + if (null != item) { if (hasSelection) { item.setTitle(res.getString(R.string.cache_export_fieldnote) + " (" + adapter.getChecked() + ")"); } else { @@ -916,7 +917,7 @@ public class cgeocaches extends AbstractListActivity { } } - // Hide Field Notes export if there are no caches with logs + // Hide Field Notes export if there are no caches with logs item = menu.findItem(MENU_EXPORT_NOTES); if (null != item) { item.setEnabled(false); @@ -929,582 +930,581 @@ public class cgeocaches extends AbstractListActivity { } } } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.onPrepareOptionsMenu: " + e.toString()); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - switch (itemId) { - case MENU_SWITCH_SELECT_MODE: - if (adapter != null) { - adapter.switchSelectMode(); - } - return true; - case MENU_REFRESH_STORED: - refreshStored(); - return true; - case MENU_DROP_CACHES: - dropStored(); - return false; - case MENU_IMPORT_GPX: - importGpx(); - return false; - case MENU_CREATE_LIST: - createList(); - return false; - case MENU_DROP_LIST: - removeList(); - return false; - case MENU_INVERT_SELECTION: - if (adapter != null) { - adapter.invertSelection(); - } - return false; - case MENU_SORT_DISTANCE: - setComparator(item, null); - return false; - case MENU_SORT_DIFFICULTY: - setComparator(item, new DifficultyComparator()); - return false; - case MENU_SORT_TERRAIN: - setComparator(item, new TerrainComparator()); - return false; - case MENU_SORT_SIZE: - setComparator(item, new SizeComparator()); - return false; - case MENU_SORT_FAVORITES: - setComparator(item, new PopularityComparator()); - return false; - case MENU_SORT_NAME: - setComparator(item, new NameComparator()); - return false; - case MENU_SORT_GEOCODE: - setComparator(item, new GeocodeComparator()); - return false; - case MENU_SWITCH_LIST: - selectList(null); - return false; - case MENU_SORT_RATING: - setComparator(item, new RatingComparator()); - return false; - case MENU_SORT_VOTE: - setComparator(item, new VoteComparator()); - return false; - case MENU_SORT_INVENTORY: - setComparator(item, new InventoryComparator()); - return false; - case MENU_SORT_DATE: - setComparator(item, new DateComparator()); - return true; - case MENU_SORT_FINDS: - setComparator(item, new FindsComparator(app)); - return true; - case MENU_SORT_STATE: - setComparator(item, new StateComparator()); - return true; - case SUBMENU_FILTER_TYPE: - selectedFilter = res.getString(R.string.caches_filter_type); - openContextMenu(getListView()); - return false; - case SUBMENU_FILTER_SIZE: - selectedFilter = res.getString(R.string.caches_filter_size); - openContextMenu(getListView()); - return false; - case MENU_FILTER_TRACKABLES: - setFilter(new cgFilterByTrackables(res.getString(R.string.caches_filter_track))); - return false; - case MENU_FILTER_CLEAR: - if (adapter != null) { - setFilter(null); - } - return false; - case MENU_IMPORT_WEB: - importWeb(); - return false; - case MENU_EXPORT_NOTES: + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.onPrepareOptionsMenu: " + e.toString()); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int itemId = item.getItemId(); + switch (itemId) { + case MENU_SWITCH_SELECT_MODE: + if (adapter != null) { + adapter.switchSelectMode(); + } + return true; + case MENU_REFRESH_STORED: + refreshStored(); + return true; + case MENU_DROP_CACHES: + dropStored(); + return false; + case MENU_IMPORT_GPX: + importGpx(); + return false; + case MENU_CREATE_LIST: + createList(); + return false; + case MENU_DROP_LIST: + removeList(); + return false; + case MENU_INVERT_SELECTION: + if (adapter != null) { + adapter.invertSelection(); + } + return false; + case MENU_SORT_DISTANCE: + setComparator(item, null); + return false; + case MENU_SORT_DIFFICULTY: + setComparator(item, new DifficultyComparator()); + return false; + case MENU_SORT_TERRAIN: + setComparator(item, new TerrainComparator()); + return false; + case MENU_SORT_SIZE: + setComparator(item, new SizeComparator()); + return false; + case MENU_SORT_FAVORITES: + setComparator(item, new PopularityComparator()); + return false; + case MENU_SORT_NAME: + setComparator(item, new NameComparator()); + return false; + case MENU_SORT_GEOCODE: + setComparator(item, new GeocodeComparator()); + return false; + case MENU_SWITCH_LIST: + selectList(null); + return false; + case MENU_SORT_RATING: + setComparator(item, new RatingComparator()); + return false; + case MENU_SORT_VOTE: + setComparator(item, new VoteComparator()); + return false; + case MENU_SORT_INVENTORY: + setComparator(item, new InventoryComparator()); + return false; + case MENU_SORT_DATE: + setComparator(item, new DateComparator()); + return true; + case MENU_SORT_FINDS: + setComparator(item, new FindsComparator(app)); + return true; + case MENU_SORT_STATE: + setComparator(item, new StateComparator()); + return true; + case SUBMENU_FILTER_TYPE: + selectedFilter = res.getString(R.string.caches_filter_type); + openContextMenu(getListView()); + return false; + case SUBMENU_FILTER_SIZE: + selectedFilter = res.getString(R.string.caches_filter_size); + openContextMenu(getListView()); + return false; + case MENU_FILTER_TRACKABLES: + setFilter(new cgFilterByTrackables(res.getString(R.string.caches_filter_track))); + return false; + case MENU_FILTER_CLEAR: + if (adapter != null) { + setFilter(null); + } + return false; + case MENU_IMPORT_WEB: + importWeb(); + return false; + case MENU_EXPORT_NOTES: exportFieldNotes(); return false; - case MENU_REMOVE_FROM_HISTORY: + case MENU_REMOVE_FROM_HISTORY: removeFromHistoryCheck(); return false; - case MENU_MOVE_TO_LIST: - contextMenuMoveToList = true; - openContextMenu(getListView()); - contextMenuMoveToList = false; - return false; - } - - return CacheListAppFactory.onMenuItemSelected(item, geo, cacheList, this, res, searchId); - } - - private void setComparator(MenuItem item, - CacheComparator comparator) { - if (adapter != null) { - adapter.setComparator(comparator); - } - item.setChecked(true); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - - if (adapter == null) { - return; - } - - if (contextMenuMoveToList) { - createFakeContextMenuMoveToList(menu); - return; - } - - AdapterContextMenuInfo adapterInfo = null; - try { - adapterInfo = (AdapterContextMenuInfo) info; - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeocaches.onCreateContextMenu: " + e.toString()); - } - - if ((adapterInfo == null || adapterInfo.position < 0) && selectedFilter != null){ - // Context menu opened by selecting an option on the filter submenu - - if (selectedFilter.equals(res.getString(R.string.caches_filter_size))) { - menu.setHeaderTitle(res.getString(R.string.caches_filter_size_title)); - menu.add(0, MENU_FILTER_SIZE_MICRO, 0, res.getString(R.string.caches_filter_size_micro)); - menu.add(0, MENU_FILTER_SIZE_SMALL, 0, res.getString(R.string.caches_filter_size_small)); - menu.add(0, MENU_FILTER_SIZE_REGULAR, 0, res.getString(R.string.caches_filter_size_regular)); - menu.add(0, MENU_FILTER_SIZE_LARGE, 0, res.getString(R.string.caches_filter_size_large)); - menu.add(0, MENU_FILTER_SIZE_OTHER, 0, res.getString(R.string.caches_filter_size_other)); - menu.add(0, MENU_FILTER_SIZE_VIRTUAL, 0, res.getString(R.string.caches_filter_size_virtual)); - menu.add(0, MENU_FILTER_SIZE_NOT_CHOSEN, 0, res.getString(R.string.caches_filter_size_notchosen)); - } else if (selectedFilter.equals(res.getString(R.string.caches_filter_type))) { - menu.setHeaderTitle(res.getString(R.string.caches_filter_type_title)); - menu.add(0, MENU_FILTER_TYPE_TRADITIONAL, 0, res.getString(R.string.caches_filter_type_traditional)); - menu.add(0, MENU_FILTER_TYPE_MULTI, 0, res.getString(R.string.caches_filter_type_multi)); - menu.add(0, MENU_FILTER_TYPE_MYSTERY, 0, res.getString(R.string.caches_filter_type_mystery)); - menu.add(0, MENU_FILTER_TYPE_LETTERBOX, 0, res.getString(R.string.caches_filter_type_letterbox)); - menu.add(0, MENU_FILTER_TYPE_EVENT, 0, res.getString(R.string.caches_filter_type_event)); - menu.add(0, MENU_FILTER_TYPE_MEGA, 0, res.getString(R.string.caches_filter_type_mega)); - menu.add(0, MENU_FILTER_TYPE_EARTH, 0, res.getString(R.string.caches_filter_type_earth)); - menu.add(0, MENU_FILTER_TYPE_CITO, 0, res.getString(R.string.caches_filter_type_cito)); - menu.add(0, MENU_FILTER_TYPE_WEBCAM, 0, res.getString(R.string.caches_filter_type_webcam)); - menu.add(0, MENU_FILTER_TYPE_VIRTUAL, 0, res.getString(R.string.caches_filter_type_virtual)); - menu.add(0, MENU_FILTER_TYPE_WHERIGO, 0, res.getString(R.string.caches_filter_type_wherigo)); - menu.add(0, MENU_FILTER_TYPE_LOSTFOUND, 0, res.getString(R.string.caches_filter_type_lostfound)); - menu.add(0, MENU_FILTER_TYPE_APE, 0, res.getString(R.string.caches_filter_type_ape)); - menu.add(0, MENU_FILTER_TYPE_GCHQ, 0, res.getString(R.string.caches_filter_type_gchq)); - menu.add(0, MENU_FILTER_TYPE_GPS, 0, res.getString(R.string.caches_filter_type_gps)); - } - } else{ - if (adapterInfo.position >= adapter.getCount()) { - return; - } - final cgCache cache = adapter.getItem(adapterInfo.position); - - if (StringUtils.isNotBlank(cache.name)) { - menu.setHeaderTitle(cache.name); - } else { - menu.setHeaderTitle(cache.geocode); - } - - if (cache.coords != null) { - menu.add(0, MENU_COMPASS, 0, res.getString(R.string.cache_menu_compass)); - SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); - NavigationAppFactory.addMenuItems(subMenu, this, res); - addVisitMenu(menu, cache); -// String label = settings.getLogOffline()? res.getString(R.string.cache_menu_visit_offline) : res.getString(R.string.cache_menu_visit); -// menu.add(0, MENU_LOG_VISIT, 0, label); - menu.add(0, MENU_CACHE_DETAILS, 0, res.getString(R.string.cache_menu_details)); - } - if (cache.reason >= 1) { - menu.add(0, MENU_DROP_CACHE, 0, res.getString(R.string.cache_offline_drop)); - List<cgList> cacheLists = app.getLists(); - int listCount = cacheLists.size(); - if (listCount > 1) { - SubMenu submenu = menu.addSubMenu(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list)); - for (int i = 0; i < listCount; i++) { - cgList list = cacheLists.get(i); - submenu.add(Menu.NONE, CONTEXT_MENU_MOVE_TO_LIST + list.id, Menu.NONE, list.title); - } - } - } - } - } - - private void createFakeContextMenuMoveToList(ContextMenu menu) { - List<cgList> cacheLists = app.getLists(); - int listCount = cacheLists.size(); - menu.setHeaderTitle(res.getString(R.string.cache_menu_move_list)); - for (int i = 0; i < listCount; i++) { - cgList list = cacheLists.get(i); - menu.add(Menu.NONE, MENU_MOVE_SELECTED_OR_ALL_TO_LIST + list.id, Menu.NONE, list.title); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int id = item.getItemId(); - ContextMenu.ContextMenuInfo info = item.getMenuInfo(); - - // restore menu info for sub menu items, see - // https://code.google.com/p/android/issues/detail?id=7139 - if (info == null) { - info = lastMenuInfo; - lastMenuInfo = null; - } - - AdapterContextMenuInfo adapterInfo = null; - try { - adapterInfo = (AdapterContextMenuInfo) info; - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeocaches.onContextItemSelected: " + e.toString()); - } - - // the context menu may be invoked for the cache or for the filter list - int touchedPos = -1; - cgCache cache = null; - if (adapterInfo != null) { - touchedPos = adapterInfo.position; - if (touchedPos < adapter.getCount()) { - cache = adapter.getItem(touchedPos); - } - } - - if (id == MENU_COMPASS) { - Intent navigateIntent = new Intent(this, cgeonavigate.class); - navigateIntent.putExtra("latitude", cache.coords.getLatitude()); - navigateIntent.putExtra("longitude", cache.coords.getLongitude()); - navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); - navigateIntent.putExtra("name", cache.name); - - startActivity(navigateIntent); - - return true; - } else if (id == MENU_LOG_VISIT) { - return cache.logVisit(this); - } else if (id == MENU_CACHE_DETAILS) { - Intent cachesIntent = new Intent(this, cgeodetail.class); - cachesIntent.putExtra("geocode", cache.geocode.toUpperCase()); - cachesIntent.putExtra("name", cache.name); - startActivity(cachesIntent); - - return true; - } - else if (id == MENU_FILTER_SIZE_MICRO) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_micro))); - } else if (id == MENU_FILTER_SIZE_SMALL) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_small))); - } else if (id == MENU_FILTER_SIZE_REGULAR) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_regular))); - } else if (id == MENU_FILTER_SIZE_LARGE) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_large))); - } else if (id == MENU_FILTER_SIZE_OTHER) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_other))); - } else if (id == MENU_FILTER_SIZE_VIRTUAL) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_virtual))); - } else if (id == MENU_FILTER_SIZE_NOT_CHOSEN) { - return setFilter(new cgFilterBySize( - res.getString(R.string.caches_filter_size_notchosen))); - } else if (id == MENU_FILTER_TYPE_TRADITIONAL) { - return setFilter(new cgFilterByType("traditional")); - } else if (id == MENU_FILTER_TYPE_MULTI) { - return setFilter(new cgFilterByType("multi")); - } else if (id == MENU_FILTER_TYPE_MYSTERY) { - return setFilter(new cgFilterByType("mystery")); - } else if (id == MENU_FILTER_TYPE_LETTERBOX) { - return setFilter(new cgFilterByType("letterbox")); - } else if (id == MENU_FILTER_TYPE_EVENT) { - return setFilter(new cgFilterByType("event")); - } else if (id == MENU_FILTER_TYPE_MEGA) { - return setFilter(new cgFilterByType("mega")); - } else if (id == MENU_FILTER_TYPE_EARTH) { - return setFilter(new cgFilterByType("earth")); - } else if (id == MENU_FILTER_TYPE_CITO) { - return setFilter(new cgFilterByType("cito")); - } else if (id == MENU_FILTER_TYPE_WEBCAM) { - return setFilter(new cgFilterByType("webcam")); - } else if (id == MENU_FILTER_TYPE_VIRTUAL) { - return setFilter(new cgFilterByType("virtual")); - } else if (id == MENU_FILTER_TYPE_WHERIGO) { - return setFilter(new cgFilterByType("wherigo")); - } else if (id == MENU_FILTER_TYPE_LOSTFOUND) { - return setFilter(new cgFilterByType("lostfound")); - } else if (id == MENU_FILTER_TYPE_APE) { - return setFilter(new cgFilterByType("ape")); - } else if (id == MENU_FILTER_TYPE_GCHQ) { - return setFilter(new cgFilterByType("gchq")); - } else if (id == MENU_FILTER_TYPE_GPS) { - return setFilter(new cgFilterByType("gps")); - } else if (id == MENU_DROP_CACHE) { - cgBase.dropCache(app, this, cache, new Handler() { - @Override - public void handleMessage(Message msg) { - refreshCurrentList(); - } - }); - return true; - } else if (id >= CONTEXT_MENU_MOVE_TO_LIST && id < CONTEXT_MENU_MOVE_TO_LIST + 100) { - int newListId = id - CONTEXT_MENU_MOVE_TO_LIST; - if (cache != null) { - app.moveToList(cache.geocode, newListId); - } - adapter.resetChecks(); - - refreshCurrentList(); - return true; - } else if (id >= MENU_MOVE_SELECTED_OR_ALL_TO_LIST && id < MENU_MOVE_SELECTED_OR_ALL_TO_LIST + 100) { - int newListId = id - MENU_MOVE_SELECTED_OR_ALL_TO_LIST; - boolean moveAll = adapter.getChecked() == 0; - final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); - for (cgCache c : cacheListTemp) { - if (moveAll || c.statusChecked) { - app.moveToList(c.geocode, newListId); - } - } - adapter.resetChecks(); - - refreshCurrentList(); - return true; - } - - // we must remember the menu info for the sub menu, there is a bug - // in Android: - // https://code.google.com/p/android/issues/detail?id=7139 - lastMenuInfo = info; - - if (cache != null) { - // create a searchId for a single cache (as if in details view) - Map<String, String> params = new HashMap<String, String>(); - params.put("geocode", cache.geocode); - final UUID singleSearchId = base.searchByGeocode(params, 0, false); - - if (NavigationAppFactory.onMenuItemSelected(item, geo, this, - res, cache, singleSearchId, null, null)) { - return true; - } - - int logType = id - MENU_LOG_VISIT_OFFLINE; - cache.logOffline(this, logType, settings, base); - } - return true; - } - - private boolean setFilter(cgFilter filter) { - if (adapter != null) { - adapter.setFilter(filter); - prepareFilterBar(); - return true; - } - return false; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - if (adapter != null) { - if (adapter.resetChecks()) { - return true; - } else if (adapter.getSelectMode()) { - adapter.setSelectMode(false, true); - return true; - } - } - } - return super.onKeyDown(keyCode, event); - } - - - private void setAdapter() { - if (listFooter == null) { - if (inflater == null) { - inflater = getLayoutInflater(); - } - listFooter = inflater.inflate(R.layout.caches_footer, null); - - listFooter.setClickable(true); - listFooter.setOnClickListener(new moreCachesListener()); - } - if (listFooterText == null) { - listFooterText = (TextView) listFooter.findViewById(R.id.more_caches); - } - - if (adapter == null) { - final ListView list = getListView(); - - registerForContextMenu(list); - list.setLongClickable(true); - list.addFooterView(listFooter); - - adapter = new cgCacheListAdapter(this, settings, cacheList, base); - setListAdapter(adapter); - } else { - adapter.notifyDataSetChanged(); - } - adapter.reFilter(); - - if (geo != null) { - adapter.setActualCoordinates(geo.coordsNow); - } - if (dir != null) { - adapter.setActualHeading(dir.directionNow); - } - } - - private void setLoadingCaches() { - if (listFooter == null) { - return; - } - if (listFooterText == null) { - return; - } - - listFooterText.setText(res.getString(R.string.caches_more_caches_loading)); - listFooter.setClickable(false); - listFooter.setOnClickListener(null); - } - - private void setMoreCaches(boolean more) { - if (listFooter == null) { - return; - } - if (listFooterText == null) { - return; - } - - if (more == false) { - if (CollectionUtils.isEmpty(cacheList)) { - listFooterText.setText(res.getString(R.string.caches_no_cache)); - } else { - listFooterText.setText(res.getString(R.string.caches_more_caches_no)); - } - listFooter.setClickable(false); - listFooter.setOnClickListener(null); - } else { - listFooterText.setText(res.getString(R.string.caches_more_caches)); - listFooter.setClickable(true); - listFooter.setOnClickListener(new moreCachesListener()); - } - } - - private void init() { - // sensor & geolocation manager - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { - dir = app.startDir(this, dirUpdate); - } - - if (cacheList != null) { - setTitle(title); - } - - if (CollectionUtils.isNotEmpty(cacheList)) { - final Integer count = app.getTotal(searchId); - if (count != null && count > 0) { - setTitle(title); - if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { - setMoreCaches(true); - } else { - setMoreCaches(false); - } - } else { - setTitle(title); - setMoreCaches(false); - } - } else { - setTitle(title); - } - - setAdapter(); - - if (geo != null) { - geoUpdate.updateLoc(geo); - } - if (dir != null) { - dirUpdate.updateDir(dir); - } - } - - private void importGpx() { - cgeogpxes.startSubActivity(this, listId); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - refreshCurrentList(); - } - - public void refreshStored() { - if (adapter != null && adapter.getChecked() > 0) { - // there are some checked caches - detailTotal = adapter.getChecked(); - } else { - // no checked caches, download everything (when already stored - refresh them) - detailTotal = cacheList.size(); - } - detailProgress = 0; - - showProgress(false); - waitDialog = new ProgressDialog(this); - waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - public void onCancel(DialogInterface arg0) { - try { - if (threadD != null) { - threadD.kill(); - } - - if (geo == null) { - geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); - } - if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { - dir = app.startDir(cgeocaches.this, dirUpdate); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.onOptionsItemSelected.onCancel: " + e.toString()); - } - } - }); - - waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - int etaTime = (int) ((detailTotal * 25) / 60); - if (etaTime < 1) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); - } else if (etaTime == 1) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + etaTime + " " + res.getString(R.string.caches_eta_min)); - } else { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + etaTime + " " + res.getString(R.string.caches_eta_mins)); - } - waitDialog.setCancelable(true); - waitDialog.setMax(detailTotal); - waitDialog.show(); - - detailProgressTime = System.currentTimeMillis(); - - threadD = new geocachesLoadDetails(loadDetailsHandler, listId); - threadD.start(); - } - - public void removeFromHistoryCheck() + case MENU_MOVE_TO_LIST: + contextMenuMoveToList = true; + openContextMenu(getListView()); + contextMenuMoveToList = false; + return false; + } + + return CacheListAppFactory.onMenuItemSelected(item, geo, cacheList, this, res, searchId); + } + + private void setComparator(MenuItem item, + CacheComparator comparator) { + if (adapter != null) { + adapter.setComparator(comparator); + } + item.setChecked(true); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + super.onCreateContextMenu(menu, view, info); + + if (adapter == null) { + return; + } + + if (contextMenuMoveToList) { + createFakeContextMenuMoveToList(menu); + return; + } + + AdapterContextMenuInfo adapterInfo = null; + try { + adapterInfo = (AdapterContextMenuInfo) info; + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeocaches.onCreateContextMenu: " + e.toString()); + } + + if ((adapterInfo == null || adapterInfo.position < 0) && selectedFilter != null) { + // Context menu opened by selecting an option on the filter submenu + + if (selectedFilter.equals(res.getString(R.string.caches_filter_size))) { + menu.setHeaderTitle(res.getString(R.string.caches_filter_size_title)); + menu.add(0, MENU_FILTER_SIZE_MICRO, 0, res.getString(R.string.caches_filter_size_micro)); + menu.add(0, MENU_FILTER_SIZE_SMALL, 0, res.getString(R.string.caches_filter_size_small)); + menu.add(0, MENU_FILTER_SIZE_REGULAR, 0, res.getString(R.string.caches_filter_size_regular)); + menu.add(0, MENU_FILTER_SIZE_LARGE, 0, res.getString(R.string.caches_filter_size_large)); + menu.add(0, MENU_FILTER_SIZE_OTHER, 0, res.getString(R.string.caches_filter_size_other)); + menu.add(0, MENU_FILTER_SIZE_VIRTUAL, 0, res.getString(R.string.caches_filter_size_virtual)); + menu.add(0, MENU_FILTER_SIZE_NOT_CHOSEN, 0, res.getString(R.string.caches_filter_size_notchosen)); + } else if (selectedFilter.equals(res.getString(R.string.caches_filter_type))) { + menu.setHeaderTitle(res.getString(R.string.caches_filter_type_title)); + menu.add(0, MENU_FILTER_TYPE_TRADITIONAL, 0, res.getString(R.string.caches_filter_type_traditional)); + menu.add(0, MENU_FILTER_TYPE_MULTI, 0, res.getString(R.string.caches_filter_type_multi)); + menu.add(0, MENU_FILTER_TYPE_MYSTERY, 0, res.getString(R.string.caches_filter_type_mystery)); + menu.add(0, MENU_FILTER_TYPE_LETTERBOX, 0, res.getString(R.string.caches_filter_type_letterbox)); + menu.add(0, MENU_FILTER_TYPE_EVENT, 0, res.getString(R.string.caches_filter_type_event)); + menu.add(0, MENU_FILTER_TYPE_MEGA, 0, res.getString(R.string.caches_filter_type_mega)); + menu.add(0, MENU_FILTER_TYPE_EARTH, 0, res.getString(R.string.caches_filter_type_earth)); + menu.add(0, MENU_FILTER_TYPE_CITO, 0, res.getString(R.string.caches_filter_type_cito)); + menu.add(0, MENU_FILTER_TYPE_WEBCAM, 0, res.getString(R.string.caches_filter_type_webcam)); + menu.add(0, MENU_FILTER_TYPE_VIRTUAL, 0, res.getString(R.string.caches_filter_type_virtual)); + menu.add(0, MENU_FILTER_TYPE_WHERIGO, 0, res.getString(R.string.caches_filter_type_wherigo)); + menu.add(0, MENU_FILTER_TYPE_LOSTFOUND, 0, res.getString(R.string.caches_filter_type_lostfound)); + menu.add(0, MENU_FILTER_TYPE_APE, 0, res.getString(R.string.caches_filter_type_ape)); + menu.add(0, MENU_FILTER_TYPE_GCHQ, 0, res.getString(R.string.caches_filter_type_gchq)); + menu.add(0, MENU_FILTER_TYPE_GPS, 0, res.getString(R.string.caches_filter_type_gps)); + } + } else { + if (adapterInfo.position >= adapter.getCount()) { + return; + } + final cgCache cache = adapter.getItem(adapterInfo.position); + + if (StringUtils.isNotBlank(cache.name)) { + menu.setHeaderTitle(cache.name); + } else { + menu.setHeaderTitle(cache.geocode); + } + + if (cache.coords != null) { + menu.add(0, MENU_COMPASS, 0, res.getString(R.string.cache_menu_compass)); + SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); + NavigationAppFactory.addMenuItems(subMenu, this, res); + addVisitMenu(menu, cache); + // String label = settings.getLogOffline()? res.getString(R.string.cache_menu_visit_offline) : res.getString(R.string.cache_menu_visit); + // menu.add(0, MENU_LOG_VISIT, 0, label); + menu.add(0, MENU_CACHE_DETAILS, 0, res.getString(R.string.cache_menu_details)); + } + if (cache.reason >= 1) { + menu.add(0, MENU_DROP_CACHE, 0, res.getString(R.string.cache_offline_drop)); + List<cgList> cacheLists = app.getLists(); + int listCount = cacheLists.size(); + if (listCount > 1) { + SubMenu submenu = menu.addSubMenu(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list)); + for (int i = 0; i < listCount; i++) { + cgList list = cacheLists.get(i); + submenu.add(Menu.NONE, CONTEXT_MENU_MOVE_TO_LIST + list.id, Menu.NONE, list.title); + } + } + } + } + } + + private void createFakeContextMenuMoveToList(ContextMenu menu) { + List<cgList> cacheLists = app.getLists(); + int listCount = cacheLists.size(); + menu.setHeaderTitle(res.getString(R.string.cache_menu_move_list)); + for (int i = 0; i < listCount; i++) { + cgList list = cacheLists.get(i); + menu.add(Menu.NONE, MENU_MOVE_SELECTED_OR_ALL_TO_LIST + list.id, Menu.NONE, list.title); + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + final int id = item.getItemId(); + ContextMenu.ContextMenuInfo info = item.getMenuInfo(); + + // restore menu info for sub menu items, see + // https://code.google.com/p/android/issues/detail?id=7139 + if (info == null) { + info = lastMenuInfo; + lastMenuInfo = null; + } + + AdapterContextMenuInfo adapterInfo = null; + try { + adapterInfo = (AdapterContextMenuInfo) info; + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeocaches.onContextItemSelected: " + e.toString()); + } + + // the context menu may be invoked for the cache or for the filter list + int touchedPos = -1; + cgCache cache = null; + if (adapterInfo != null) { + touchedPos = adapterInfo.position; + if (touchedPos < adapter.getCount()) { + cache = adapter.getItem(touchedPos); + } + } + + if (id == MENU_COMPASS) { + Intent navigateIntent = new Intent(this, cgeonavigate.class); + navigateIntent.putExtra("latitude", cache.coords.getLatitude()); + navigateIntent.putExtra("longitude", cache.coords.getLongitude()); + navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); + navigateIntent.putExtra("name", cache.name); + + startActivity(navigateIntent); + + return true; + } else if (id == MENU_LOG_VISIT) { + return cache.logVisit(this); + } else if (id == MENU_CACHE_DETAILS) { + Intent cachesIntent = new Intent(this, cgeodetail.class); + cachesIntent.putExtra("geocode", cache.geocode.toUpperCase()); + cachesIntent.putExtra("name", cache.name); + startActivity(cachesIntent); + + return true; + } + else if (id == MENU_FILTER_SIZE_MICRO) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_micro))); + } else if (id == MENU_FILTER_SIZE_SMALL) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_small))); + } else if (id == MENU_FILTER_SIZE_REGULAR) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_regular))); + } else if (id == MENU_FILTER_SIZE_LARGE) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_large))); + } else if (id == MENU_FILTER_SIZE_OTHER) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_other))); + } else if (id == MENU_FILTER_SIZE_VIRTUAL) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_virtual))); + } else if (id == MENU_FILTER_SIZE_NOT_CHOSEN) { + return setFilter(new cgFilterBySize( + res.getString(R.string.caches_filter_size_notchosen))); + } else if (id == MENU_FILTER_TYPE_TRADITIONAL) { + return setFilter(new cgFilterByType("traditional")); + } else if (id == MENU_FILTER_TYPE_MULTI) { + return setFilter(new cgFilterByType("multi")); + } else if (id == MENU_FILTER_TYPE_MYSTERY) { + return setFilter(new cgFilterByType("mystery")); + } else if (id == MENU_FILTER_TYPE_LETTERBOX) { + return setFilter(new cgFilterByType("letterbox")); + } else if (id == MENU_FILTER_TYPE_EVENT) { + return setFilter(new cgFilterByType("event")); + } else if (id == MENU_FILTER_TYPE_MEGA) { + return setFilter(new cgFilterByType("mega")); + } else if (id == MENU_FILTER_TYPE_EARTH) { + return setFilter(new cgFilterByType("earth")); + } else if (id == MENU_FILTER_TYPE_CITO) { + return setFilter(new cgFilterByType("cito")); + } else if (id == MENU_FILTER_TYPE_WEBCAM) { + return setFilter(new cgFilterByType("webcam")); + } else if (id == MENU_FILTER_TYPE_VIRTUAL) { + return setFilter(new cgFilterByType("virtual")); + } else if (id == MENU_FILTER_TYPE_WHERIGO) { + return setFilter(new cgFilterByType("wherigo")); + } else if (id == MENU_FILTER_TYPE_LOSTFOUND) { + return setFilter(new cgFilterByType("lostfound")); + } else if (id == MENU_FILTER_TYPE_APE) { + return setFilter(new cgFilterByType("ape")); + } else if (id == MENU_FILTER_TYPE_GCHQ) { + return setFilter(new cgFilterByType("gchq")); + } else if (id == MENU_FILTER_TYPE_GPS) { + return setFilter(new cgFilterByType("gps")); + } else if (id == MENU_DROP_CACHE) { + cgBase.dropCache(app, this, cache, new Handler() { + @Override + public void handleMessage(Message msg) { + refreshCurrentList(); + } + }); + return true; + } else if (id >= CONTEXT_MENU_MOVE_TO_LIST && id < CONTEXT_MENU_MOVE_TO_LIST + 100) { + int newListId = id - CONTEXT_MENU_MOVE_TO_LIST; + if (cache != null) { + app.moveToList(cache.geocode, newListId); + } + adapter.resetChecks(); + + refreshCurrentList(); + return true; + } else if (id >= MENU_MOVE_SELECTED_OR_ALL_TO_LIST && id < MENU_MOVE_SELECTED_OR_ALL_TO_LIST + 100) { + int newListId = id - MENU_MOVE_SELECTED_OR_ALL_TO_LIST; + boolean moveAll = adapter.getChecked() == 0; + final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); + for (cgCache c : cacheListTemp) { + if (moveAll || c.statusChecked) { + app.moveToList(c.geocode, newListId); + } + } + adapter.resetChecks(); + + refreshCurrentList(); + return true; + } + + // we must remember the menu info for the sub menu, there is a bug + // in Android: + // https://code.google.com/p/android/issues/detail?id=7139 + lastMenuInfo = info; + + if (cache != null) { + // create a searchId for a single cache (as if in details view) + Map<String, String> params = new HashMap<String, String>(); + params.put("geocode", cache.geocode); + final UUID singleSearchId = base.searchByGeocode(params, 0, false); + + if (NavigationAppFactory.onMenuItemSelected(item, geo, this, + res, cache, singleSearchId, null, null)) { + return true; + } + + int logType = id - MENU_LOG_VISIT_OFFLINE; + cache.logOffline(this, logType, settings, base); + } + return true; + } + + private boolean setFilter(cgFilter filter) { + if (adapter != null) { + adapter.setFilter(filter); + prepareFilterBar(); + return true; + } + return false; + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (adapter != null) { + if (adapter.resetChecks()) { + return true; + } else if (adapter.getSelectMode()) { + adapter.setSelectMode(false, true); + return true; + } + } + } + return super.onKeyDown(keyCode, event); + } + + private void setAdapter() { + if (listFooter == null) { + if (inflater == null) { + inflater = getLayoutInflater(); + } + listFooter = inflater.inflate(R.layout.caches_footer, null); + + listFooter.setClickable(true); + listFooter.setOnClickListener(new moreCachesListener()); + } + if (listFooterText == null) { + listFooterText = (TextView) listFooter.findViewById(R.id.more_caches); + } + + if (adapter == null) { + final ListView list = getListView(); + + registerForContextMenu(list); + list.setLongClickable(true); + list.addFooterView(listFooter); + + adapter = new cgCacheListAdapter(this, settings, cacheList, base); + setListAdapter(adapter); + } else { + adapter.notifyDataSetChanged(); + } + adapter.reFilter(); + + if (geo != null) { + adapter.setActualCoordinates(geo.coordsNow); + } + if (dir != null) { + adapter.setActualHeading(dir.directionNow); + } + } + + private void setLoadingCaches() { + if (listFooter == null) { + return; + } + if (listFooterText == null) { + return; + } + + listFooterText.setText(res.getString(R.string.caches_more_caches_loading)); + listFooter.setClickable(false); + listFooter.setOnClickListener(null); + } + + private void setMoreCaches(boolean more) { + if (listFooter == null) { + return; + } + if (listFooterText == null) { + return; + } + + if (more == false) { + if (CollectionUtils.isEmpty(cacheList)) { + listFooterText.setText(res.getString(R.string.caches_no_cache)); + } else { + listFooterText.setText(res.getString(R.string.caches_more_caches_no)); + } + listFooter.setClickable(false); + listFooter.setOnClickListener(null); + } else { + listFooterText.setText(res.getString(R.string.caches_more_caches)); + listFooter.setClickable(true); + listFooter.setOnClickListener(new moreCachesListener()); + } + } + + private void init() { + // sensor & geolocation manager + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { + dir = app.startDir(this, dirUpdate); + } + + if (cacheList != null) { + setTitle(title); + } + + if (CollectionUtils.isNotEmpty(cacheList)) { + final Integer count = app.getTotal(searchId); + if (count != null && count > 0) { + setTitle(title); + if (cacheList.size() < app.getTotal(searchId) && cacheList.size() < MAX_LIST_ITEMS) { + setMoreCaches(true); + } else { + setMoreCaches(false); + } + } else { + setTitle(title); + setMoreCaches(false); + } + } else { + setTitle(title); + } + + setAdapter(); + + if (geo != null) { + geoUpdate.updateLoc(geo); + } + if (dir != null) { + dirUpdate.updateDir(dir); + } + } + + private void importGpx() { + cgeogpxes.startSubActivity(this, listId); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + refreshCurrentList(); + } + + public void refreshStored() { + if (adapter != null && adapter.getChecked() > 0) { + // there are some checked caches + detailTotal = adapter.getChecked(); + } else { + // no checked caches, download everything (when already stored - refresh them) + detailTotal = cacheList.size(); + } + detailProgress = 0; + + showProgress(false); + waitDialog = new ProgressDialog(this); + waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + public void onCancel(DialogInterface arg0) { + try { + if (threadD != null) { + threadD.kill(); + } + + if (geo == null) { + geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); + } + if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { + dir = app.startDir(cgeocaches.this, dirUpdate); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.onOptionsItemSelected.onCancel: " + e.toString()); + } + } + }); + + waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + int etaTime = (int) ((detailTotal * 25) / 60); + if (etaTime < 1) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); + } else if (etaTime == 1) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + etaTime + " " + res.getString(R.string.caches_eta_min)); + } else { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + etaTime + " " + res.getString(R.string.caches_eta_mins)); + } + waitDialog.setCancelable(true); + waitDialog.setMax(detailTotal); + waitDialog.show(); + + detailProgressTime = System.currentTimeMillis(); + + threadD = new geocachesLoadDetails(loadDetailsHandler, listId); + threadD.start(); + } + + public void removeFromHistoryCheck() { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); + AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setCancelable(true); dialog.setTitle(res.getString(R.string.caches_removing_from_history)); dialog.setMessage((adapter != null && adapter.getChecked() > 0) ? res.getString(R.string.cache_remove_from_history) - : res.getString(R.string.cache_clear_history)); + : res.getString(R.string.cache_clear_history)); dialog.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { removeFromHistory(); @@ -1565,8 +1565,8 @@ public class cgeocaches extends AbstractListActivity { threadH.start(); } - public void exportFieldNotes() - { + public void exportFieldNotes() + { if (adapter != null && adapter.getChecked() > 0) { // there are some checked caches @@ -1609,586 +1609,586 @@ public class cgeocaches extends AbstractListActivity { threadF.start(); } - public void importWeb() { - detailProgress = 0; - - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - showProgress(false); - waitDialog = new ProgressDialog(this); - waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - public void onCancel(DialogInterface arg0) { - try { - if (threadW != null) { - threadW.kill(); - } - - if (geo == null) { - geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); - } - if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { - dir = app.startDir(cgeocaches.this, dirUpdate); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.importWeb.onCancel: " + e.toString()); - } - } - }); - - waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - waitDialog.setMessage(res.getString(R.string.web_import_waiting)); - waitDialog.setCancelable(true); - waitDialog.show(); - - threadW = new geocachesLoadFromWeb(downloadFromWebHandler, listId); - threadW.start(); - } - - public void dropStored() { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setCancelable(true); - dialog.setTitle(res.getString(R.string.caches_drop_stored)); - - if (adapter != null && adapter.getChecked() > 0) { - dialog.setMessage(res.getString(R.string.caches_drop_selected_ask)); - dialog.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - dropSelected(); - dialog.cancel(); - } - }); - } else { - dialog.setMessage(res.getString(R.string.caches_drop_all_ask)); - dialog.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - dropSelected(); - dialog.cancel(); - } - }); - } - dialog.setNegativeButton(getString(android.R.string.no), new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - } - - public void dropSelected() { - waitDialog = new ProgressDialog(this); - waitDialog.setMessage(res.getString(R.string.caches_drop_progress)); - waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - public void onCancel(DialogInterface arg0) { - try { - if (threadR != null) { - threadR.kill(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.onOptionsItemSelected.onCancel: " + e.toString()); - } - } - }); - - waitDialog.setCancelable(true); - waitDialog.show(); - - threadR = new geocachesDropDetails(dropDetailsHandler); - threadR.start(); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - if (adapter == null) { - return; - } - - try { - if (cacheList != null && geo.coordsNow != null) { - adapter.setActualCoordinates(geo.coordsNow); - } - - if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h - if (settings.useCompass == 0) { - if (geo.bearingNow != null) { - adapter.setActualHeading(geo.bearingNow); - } else { - adapter.setActualHeading(0f); - } - } - if (northHeading != null) { - adapter.setActualHeading(northHeading); - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class UpdateDirection extends cgUpdateDir { - - @Override - public void updateDir(cgDirection dir) { - if (settings.livelist == 0) { - return; - } - if (dir == null || dir.directionNow == null) { - return; - } - - northHeading = dir.directionNow; - if (northHeading != null && adapter != null && (geo == null || geo.speedNow == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h) { - adapter.setActualHeading(northHeading); - } - } - } - - private class geocachesLoadByOffline extends Thread { - - private Handler handler = null; - private Geopoint coords = null; - private int listId = 1; - - public geocachesLoadByOffline(Handler handlerIn, final Geopoint coordsIn, int listIdIn) { - handler = handlerIn; - coords = coordsIn; - listId = listIdIn; - } - - @Override - public void run() { - Map<String, Object> params = new HashMap<String, Object>(); - if (coords != null) { - params.put("latitude", coords.getLatitude()); - params.put("longitude", coords.getLongitude()); - params.put("cachetype", settings.cacheType); - params.put("list", listId); - } - - searchId = base.searchByOffline(params); - - handler.sendMessage(new Message()); - } - } - - private class geocachesLoadByHistory extends Thread { - - private Handler handler = null; - - public geocachesLoadByHistory(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - Map<String, Object> params = new HashMap<String, Object>(); - if (coords != null) { - params.put("cachetype", settings.cacheType); - } - - searchId = base.searchByHistory(params); - - handler.sendMessage(new Message()); - } - } - - private class geocachesLoadNextPage extends cgSearchThread { - - private Handler handler = null; - - public geocachesLoadNextPage(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - searchId = base.searchByNextPage(this, searchId, 0, settings.showCaptcha); - - handler.sendMessage(new Message()); - } - } - - private class geocachesLoadByCoords extends cgSearchThread { - - private Handler handler = null; - private Geopoint coords = null; - private String cachetype = null; + public void importWeb() { + detailProgress = 0; + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + showProgress(false); + waitDialog = new ProgressDialog(this); + waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + public void onCancel(DialogInterface arg0) { + try { + if (threadW != null) { + threadW.kill(); + } + + if (geo == null) { + geo = app.startGeo(cgeocaches.this, geoUpdate, base, settings, 0, 0); + } + if (settings.livelist == 1 && settings.useCompass == 1 && dir == null) { + dir = app.startDir(cgeocaches.this, dirUpdate); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.importWeb.onCancel: " + e.toString()); + } + } + }); + + waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + waitDialog.setMessage(res.getString(R.string.web_import_waiting)); + waitDialog.setCancelable(true); + waitDialog.show(); + + threadW = new geocachesLoadFromWeb(downloadFromWebHandler, listId); + threadW.start(); + } + + public void dropStored() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setCancelable(true); + dialog.setTitle(res.getString(R.string.caches_drop_stored)); + + if (adapter != null && adapter.getChecked() > 0) { + dialog.setMessage(res.getString(R.string.caches_drop_selected_ask)); + dialog.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + dropSelected(); + dialog.cancel(); + } + }); + } else { + dialog.setMessage(res.getString(R.string.caches_drop_all_ask)); + dialog.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + dropSelected(); + dialog.cancel(); + } + }); + } + dialog.setNegativeButton(getString(android.R.string.no), new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + AlertDialog alert = dialog.create(); + alert.show(); + } + + public void dropSelected() { + waitDialog = new ProgressDialog(this); + waitDialog.setMessage(res.getString(R.string.caches_drop_progress)); + waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + public void onCancel(DialogInterface arg0) { + try { + if (threadR != null) { + threadR.kill(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.onOptionsItemSelected.onCancel: " + e.toString()); + } + } + }); + + waitDialog.setCancelable(true); + waitDialog.show(); + + threadR = new geocachesDropDetails(dropDetailsHandler); + threadR.start(); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + if (adapter == null) { + return; + } + + try { + if (cacheList != null && geo.coordsNow != null) { + adapter.setActualCoordinates(geo.coordsNow); + } + + if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h + if (settings.useCompass == 0) { + if (geo.bearingNow != null) { + adapter.setActualHeading(geo.bearingNow); + } else { + adapter.setActualHeading(0f); + } + } + if (northHeading != null) { + adapter.setActualHeading(northHeading); + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class UpdateDirection extends cgUpdateDir { + + @Override + public void updateDir(cgDirection dir) { + if (settings.livelist == 0) { + return; + } + if (dir == null || dir.directionNow == null) { + return; + } + + northHeading = dir.directionNow; + if (northHeading != null && adapter != null && (geo == null || geo.speedNow == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h) { + adapter.setActualHeading(northHeading); + } + } + } + + private class geocachesLoadByOffline extends Thread { - public geocachesLoadByCoords(Handler handlerIn, final Geopoint coordsIn, String cachetypeIn) { - setPriority(Thread.MIN_PRIORITY); + private Handler handler = null; + private Geopoint coords = null; + private int listId = 1; - handler = handlerIn; - coords = coordsIn; - cachetype = cachetypeIn; + public geocachesLoadByOffline(Handler handlerIn, final Geopoint coordsIn, int listIdIn) { + handler = handlerIn; + coords = coordsIn; + listId = listIdIn; + } - if (coords == null) { - showToast(res.getString(R.string.warn_no_coordinates)); + @Override + public void run() { + Map<String, Object> params = new HashMap<String, Object>(); + if (coords != null) { + params.put("latitude", coords.getLatitude()); + params.put("longitude", coords.getLongitude()); + params.put("cachetype", settings.cacheType); + params.put("list", listId); + } - finish(); - return; - } - } + searchId = base.searchByOffline(params); - @Override - public void run() { - Map<String, String> params = new HashMap<String, String>(); - params.put("latitude", String.format((Locale) null, "%.6f", coords.getLatitude())); - params.put("longitude", String.format((Locale) null, "%.6f", coords.getLongitude())); - params.put("cachetype", cachetype); + handler.sendMessage(new Message()); + } + } - searchId = base.searchByCoords(this, params, 0, settings.showCaptcha); + private class geocachesLoadByHistory extends Thread { - handler.sendMessage(new Message()); - } - } + private Handler handler = null; - private class geocachesLoadByKeyword extends cgSearchThread { + public geocachesLoadByHistory(Handler handlerIn) { + handler = handlerIn; + } - private Handler handler = null; - private String keyword = null; - private String cachetype = null; + @Override + public void run() { + Map<String, Object> params = new HashMap<String, Object>(); + if (coords != null) { + params.put("cachetype", settings.cacheType); + } - public geocachesLoadByKeyword(Handler handlerIn, String keywordIn, String cachetypeIn) { - setPriority(Thread.MIN_PRIORITY); + searchId = base.searchByHistory(params); - handler = handlerIn; - keyword = keywordIn; - cachetype = cachetypeIn; + handler.sendMessage(new Message()); + } + } - if (keyword == null) { - showToast(res.getString(R.string.warn_no_keyword)); + private class geocachesLoadNextPage extends cgSearchThread { - finish(); - return; - } - } + private Handler handler = null; - @Override - public void run() { - Map<String, String> params = new HashMap<String, String>(); - params.put("keyword", keyword); - params.put("cachetype", cachetype); + public geocachesLoadNextPage(Handler handlerIn) { + handler = handlerIn; + } - searchId = base.searchByKeyword(this, params, 0, settings.showCaptcha); + @Override + public void run() { + searchId = base.searchByNextPage(this, searchId, 0, settings.showCaptcha); - handler.sendMessage(new Message()); - } - } + handler.sendMessage(new Message()); + } + } - private class geocachesLoadByUserName extends cgSearchThread { + private class geocachesLoadByCoords extends cgSearchThread { - private Handler handler = null; - private String username = null; - private String cachetype = null; + private Handler handler = null; + private Geopoint coords = null; + private String cachetype = null; - public geocachesLoadByUserName(Handler handlerIn, String usernameIn, String cachetypeIn) { - setPriority(Thread.MIN_PRIORITY); + public geocachesLoadByCoords(Handler handlerIn, final Geopoint coordsIn, String cachetypeIn) { + setPriority(Thread.MIN_PRIORITY); - handler = handlerIn; - username = usernameIn; - cachetype = cachetypeIn; + handler = handlerIn; + coords = coordsIn; + cachetype = cachetypeIn; - if (StringUtils.isBlank(username)) { - showToast(res.getString(R.string.warn_no_username)); + if (coords == null) { + showToast(res.getString(R.string.warn_no_coordinates)); - finish(); - return; - } - } + finish(); + return; + } + } - @Override - public void run() { - Map<String, String> params = new HashMap<String, String>(); - params.put("username", username); - params.put("cachetype", cachetype); + @Override + public void run() { + Map<String, String> params = new HashMap<String, String>(); + params.put("latitude", String.format((Locale) null, "%.6f", coords.getLatitude())); + params.put("longitude", String.format((Locale) null, "%.6f", coords.getLongitude())); + params.put("cachetype", cachetype); - searchId = base.searchByUsername(this, params, 0, settings.showCaptcha); + searchId = base.searchByCoords(this, params, 0, settings.showCaptcha); - handler.sendMessage(new Message()); - } - } + handler.sendMessage(new Message()); + } + } - private class geocachesLoadByOwner extends cgSearchThread { + private class geocachesLoadByKeyword extends cgSearchThread { - private Handler handler = null; - private String username = null; - private String cachetype = null; + private Handler handler = null; + private String keyword = null; + private String cachetype = null; - public geocachesLoadByOwner(Handler handlerIn, String usernameIn, String cachetypeIn) { - setPriority(Thread.MIN_PRIORITY); + public geocachesLoadByKeyword(Handler handlerIn, String keywordIn, String cachetypeIn) { + setPriority(Thread.MIN_PRIORITY); - handler = handlerIn; - username = usernameIn; - cachetype = cachetypeIn; + handler = handlerIn; + keyword = keywordIn; + cachetype = cachetypeIn; - if (StringUtils.isBlank(username)) { - showToast(res.getString(R.string.warn_no_username)); - - finish(); - return; - } - } + if (keyword == null) { + showToast(res.getString(R.string.warn_no_keyword)); - @Override - public void run() { - Map<String, String> params = new HashMap<String, String>(); - params.put("username", username); - params.put("cachetype", cachetype); + finish(); + return; + } + } - searchId = base.searchByOwner(this, params, 0, settings.showCaptcha); + @Override + public void run() { + Map<String, String> params = new HashMap<String, String>(); + params.put("keyword", keyword); + params.put("cachetype", cachetype); - handler.sendMessage(new Message()); - } - } + searchId = base.searchByKeyword(this, params, 0, settings.showCaptcha); - private class geocachesLoadDetails extends Thread { + handler.sendMessage(new Message()); + } + } - private Handler handler = null; - private int reason = 1; - private volatile boolean needToStop = false; - private int checked = 0; - private long last = 0L; - - public geocachesLoadDetails(Handler handlerIn, int reasonIn) { - setPriority(Thread.MIN_PRIORITY); - - handler = handlerIn; - reason = reasonIn; - - if (adapter != null) { - checked = adapter.getChecked(); - } - } - - public void kill() { - needToStop = true; - } - - @Override - public void run() { - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); - for (cgCache cache : cacheListTemp) { - if (checked > 0 && cache.statusChecked == false) { - handler.sendEmptyMessage(0); - - yield(); - continue; - } - - try { - if (needToStop) { - Log.i(cgSettings.tag, "Stopped storing process."); - break; - } - - if ((System.currentTimeMillis() - last) < 1500) { - try { - int delay = 1000 + ((Double) (Math.random() * 1000)).intValue() - (int) (System.currentTimeMillis() - last); - if (delay < 0) { - delay = 500; - } - - Log.i(cgSettings.tag, "Waiting for next cache " + delay + " ms"); - sleep(delay); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.geocachesLoadDetails.sleep: " + e.toString()); - } - } - - if (needToStop) { - Log.i(cgSettings.tag, "Stopped storing process."); - break; - } - - detailProgress++; - base.storeCache(app, cgeocaches.this, cache, null, reason, null); - - handler.sendEmptyMessage(cacheList.indexOf(cache)); - - yield(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.geocachesLoadDetails: " + e.toString()); - } - - last = System.currentTimeMillis(); - } - cacheListTemp.clear(); - - handler.sendEmptyMessage(-1); - } - } - - private class geocachesLoadFromWeb extends Thread { - - private Handler handler = null; - private int reason = 1; - private volatile boolean needToStop = false; - - public geocachesLoadFromWeb(Handler handlerIn, int reasonIn) { - setPriority(Thread.MIN_PRIORITY); - - handler = handlerIn; - reason = reasonIn; - } - - public void kill() { - needToStop = true; - } - - @Override - public void run() { - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - int delay=-1; - int times=0; - - while (times < 3 * 60 / 5) // maximum: 3 minutes, every 5 seconds - { - if (needToStop) - { - handler.sendEmptyMessage(-1); - break; - } - - //download new code - String deviceCode = settings.webDeviceCode; - if (deviceCode == null) { - deviceCode = ""; - } - cgResponse responseFromWeb = base.request(false, "send2.cgeo.org", "/read.html", "GET", "code=" + cgBase.urlencode_rfc3986(deviceCode), 0, true); - - if (responseFromWeb.getStatusCode() == 200) { - if (responseFromWeb.getData().length() > 2) { - - String GCcode = responseFromWeb.getData(); - - delay = 1; - Message mes = new Message(); - mes.what = 1; - mes.obj = GCcode; - handler.sendMessage(mes); - yield(); - - base.storeCache(app, cgeocaches.this, null, GCcode, - reason, null); - - Message mes1 = new Message(); - mes1.what = 2; - mes1.obj = GCcode; - handler.sendMessage(mes1); - yield(); - } else if ("RG".equals(responseFromWeb.getData())) { - //Server returned RG (registration) and this device no longer registered. - settings.setWebNameCode(null, null); - needToStop = true; - handler.sendEmptyMessage(-3); - return; - } else { - delay = 0; - handler.sendEmptyMessage(0); - yield(); - } - } - if (responseFromWeb.getStatusCode() != 200) { - needToStop = true; - handler.sendEmptyMessage(-2); - return; - } - - try { - yield(); - if (delay==0) - { - sleep(5000); //No caches 5s - times++; - } else { - sleep(500); //Cache was loaded 0.5s - times=0; - } - } catch (InterruptedException e) { - Log.e(cgSettings.tag, "cgeocaches.geocachesLoadFromWeb.sleep: " + e.toString()); - } - } - handler.sendEmptyMessage(-1); - } - } - - private class geocachesDropDetails extends Thread { - - private Handler handler = null; - private volatile boolean needToStop = false; - private int checked = 0; - - public geocachesDropDetails(Handler handlerIn) { - setPriority(Thread.MIN_PRIORITY); - - handler = handlerIn; - - if (adapter != null) { - checked = adapter.getChecked(); - } - } - - public void kill() { - needToStop = true; - } - - @Override - public void run() { - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); - for (cgCache cache : cacheListTemp) { - if (checked > 0 && cache.statusChecked == false) { - continue; - } - - try { - if (needToStop) { - Log.i(cgSettings.tag, "Stopped dropping process."); - break; - } - - app.markDropped(cache.geocode); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.geocachesDropDetails: " + e.toString()); - } - } - cacheListTemp.clear(); - - handler.sendEmptyMessage(-1); - } - } - - private class geocachesRemoveFromHistory extends Thread { + private class geocachesLoadByUserName extends cgSearchThread { + + private Handler handler = null; + private String username = null; + private String cachetype = null; + + public geocachesLoadByUserName(Handler handlerIn, String usernameIn, String cachetypeIn) { + setPriority(Thread.MIN_PRIORITY); + + handler = handlerIn; + username = usernameIn; + cachetype = cachetypeIn; + + if (StringUtils.isBlank(username)) { + showToast(res.getString(R.string.warn_no_username)); + + finish(); + return; + } + } + + @Override + public void run() { + Map<String, String> params = new HashMap<String, String>(); + params.put("username", username); + params.put("cachetype", cachetype); + + searchId = base.searchByUsername(this, params, 0, settings.showCaptcha); + + handler.sendMessage(new Message()); + } + } + + private class geocachesLoadByOwner extends cgSearchThread { + + private Handler handler = null; + private String username = null; + private String cachetype = null; + + public geocachesLoadByOwner(Handler handlerIn, String usernameIn, String cachetypeIn) { + setPriority(Thread.MIN_PRIORITY); + + handler = handlerIn; + username = usernameIn; + cachetype = cachetypeIn; + + if (StringUtils.isBlank(username)) { + showToast(res.getString(R.string.warn_no_username)); + + finish(); + return; + } + } + + @Override + public void run() { + Map<String, String> params = new HashMap<String, String>(); + params.put("username", username); + params.put("cachetype", cachetype); + + searchId = base.searchByOwner(this, params, 0, settings.showCaptcha); + + handler.sendMessage(new Message()); + } + } + + private class geocachesLoadDetails extends Thread { + + private Handler handler = null; + private int reason = 1; + private volatile boolean needToStop = false; + private int checked = 0; + private long last = 0L; + + public geocachesLoadDetails(Handler handlerIn, int reasonIn) { + setPriority(Thread.MIN_PRIORITY); + + handler = handlerIn; + reason = reasonIn; + + if (adapter != null) { + checked = adapter.getChecked(); + } + } + + public void kill() { + needToStop = true; + } + + @Override + public void run() { + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); + for (cgCache cache : cacheListTemp) { + if (checked > 0 && cache.statusChecked == false) { + handler.sendEmptyMessage(0); + + yield(); + continue; + } + + try { + if (needToStop) { + Log.i(cgSettings.tag, "Stopped storing process."); + break; + } + + if ((System.currentTimeMillis() - last) < 1500) { + try { + int delay = 1000 + ((Double) (Math.random() * 1000)).intValue() - (int) (System.currentTimeMillis() - last); + if (delay < 0) { + delay = 500; + } + + Log.i(cgSettings.tag, "Waiting for next cache " + delay + " ms"); + sleep(delay); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.geocachesLoadDetails.sleep: " + e.toString()); + } + } + + if (needToStop) { + Log.i(cgSettings.tag, "Stopped storing process."); + break; + } + + detailProgress++; + base.storeCache(app, cgeocaches.this, cache, null, reason, null); + + handler.sendEmptyMessage(cacheList.indexOf(cache)); + + yield(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.geocachesLoadDetails: " + e.toString()); + } + + last = System.currentTimeMillis(); + } + cacheListTemp.clear(); + + handler.sendEmptyMessage(-1); + } + } + + private class geocachesLoadFromWeb extends Thread { + + private Handler handler = null; + private int reason = 1; + private volatile boolean needToStop = false; + + public geocachesLoadFromWeb(Handler handlerIn, int reasonIn) { + setPriority(Thread.MIN_PRIORITY); + + handler = handlerIn; + reason = reasonIn; + } + + public void kill() { + needToStop = true; + } + + @Override + public void run() { + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + int delay = -1; + int times = 0; + + while (times < 3 * 60 / 5) // maximum: 3 minutes, every 5 seconds + { + if (needToStop) + { + handler.sendEmptyMessage(-1); + break; + } + + //download new code + String deviceCode = settings.webDeviceCode; + if (deviceCode == null) { + deviceCode = ""; + } + cgResponse responseFromWeb = base.request(false, "send2.cgeo.org", "/read.html", "GET", "code=" + cgBase.urlencode_rfc3986(deviceCode), 0, true); + + if (responseFromWeb.getStatusCode() == 200) { + if (responseFromWeb.getData().length() > 2) { + + String GCcode = responseFromWeb.getData(); + + delay = 1; + Message mes = new Message(); + mes.what = 1; + mes.obj = GCcode; + handler.sendMessage(mes); + yield(); + + base.storeCache(app, cgeocaches.this, null, GCcode, + reason, null); + + Message mes1 = new Message(); + mes1.what = 2; + mes1.obj = GCcode; + handler.sendMessage(mes1); + yield(); + } else if ("RG".equals(responseFromWeb.getData())) { + //Server returned RG (registration) and this device no longer registered. + settings.setWebNameCode(null, null); + needToStop = true; + handler.sendEmptyMessage(-3); + return; + } else { + delay = 0; + handler.sendEmptyMessage(0); + yield(); + } + } + if (responseFromWeb.getStatusCode() != 200) { + needToStop = true; + handler.sendEmptyMessage(-2); + return; + } + + try { + yield(); + if (delay == 0) + { + sleep(5000); //No caches 5s + times++; + } else { + sleep(500); //Cache was loaded 0.5s + times = 0; + } + } catch (InterruptedException e) { + Log.e(cgSettings.tag, "cgeocaches.geocachesLoadFromWeb.sleep: " + e.toString()); + } + } + handler.sendEmptyMessage(-1); + } + } + + private class geocachesDropDetails extends Thread { + + private Handler handler = null; + private volatile boolean needToStop = false; + private int checked = 0; + + public geocachesDropDetails(Handler handlerIn) { + setPriority(Thread.MIN_PRIORITY); + + handler = handlerIn; + + if (adapter != null) { + checked = adapter.getChecked(); + } + } + + public void kill() { + needToStop = true; + } + + @Override + public void run() { + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); + for (cgCache cache : cacheListTemp) { + if (checked > 0 && cache.statusChecked == false) { + continue; + } + + try { + if (needToStop) { + Log.i(cgSettings.tag, "Stopped dropping process."); + break; + } + + app.markDropped(cache.geocode); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.geocachesDropDetails: " + e.toString()); + } + } + cacheListTemp.clear(); + + handler.sendEmptyMessage(-1); + } + } + + private class geocachesRemoveFromHistory extends Thread { private Handler handler = null; private volatile boolean needToStop = false; @@ -2238,8 +2238,8 @@ public class cgeocaches extends AbstractListActivity { } } - private class geocachesExportFieldNotes extends Thread - { + private class geocachesExportFieldNotes extends Thread + { private Handler handler = null; private volatile boolean needToStop = false; private int checked = 0; @@ -2302,13 +2302,13 @@ public class cgeocaches extends AbstractListActivity { if (null != logTypes.get(log.type)) { fieldNoteBuffer.append(cache.geocode) - .append(',') - .append(fieldNoteDateFormat.format(new Date(log.date))) - .append(',') - .append(logTypes.get(log.type)) - .append(",\"") - .append(log.log.replaceAll("\"", "'")) - .append("\"\n"); + .append(',') + .append(fieldNoteDateFormat.format(new Date(log.date))) + .append(',') + .append(logTypes.get(log.type)) + .append(",\"") + .append(log.log.replaceAll("\"", "'")) + .append("\"\n"); } } @@ -2331,7 +2331,7 @@ public class cgeocaches extends AbstractListActivity { File exportFile = new File(exportLocation + "/" + fileNameDateFormat.format(new Date()) + ".txt"); OutputStream os = null; - Writer fw = null; + Writer fw = null; try { os = new FileOutputStream(exportFile); @@ -2339,16 +2339,18 @@ public class cgeocaches extends AbstractListActivity { fw.write(fieldNoteBuffer.toString()); Message.obtain(handler, -2, exportFile).sendToTarget(); - } - catch (IOException e) { + } catch (IOException e) { Log.e(cgSettings.tag, "cgeocaches.geocachesExportFieldNotes: " + e.toString()); handler.sendEmptyMessage(-3); - } - finally + } finally { - if ( fw != null ) + if (fw != null) { - try { fw.close(); } catch (IOException e) { Log.e(cgSettings.tag, "cgeocaches.geocachesExportFieldNotes: " + e.toString()); } + try { + fw.close(); + } catch (IOException e) { + Log.e(cgSettings.tag, "cgeocaches.geocachesExportFieldNotes: " + e.toString()); + } } } } @@ -2357,256 +2359,256 @@ public class cgeocaches extends AbstractListActivity { } } - private class moreCachesListener implements View.OnClickListener { - - @Override - public void onClick(View arg0) { - showProgress(true); - setLoadingCaches(); - listFooter.setOnClickListener(null); - - geocachesLoadNextPage thread; - thread = new geocachesLoadNextPage(loadNextPageHandler); - thread.setRecaptchaHandler(new cgSearchHandler(cgeocaches.this, res, thread)); - thread.start(); - } - } - - private void hideLoading() { - final ListView list = getListView(); - final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading); - - if (list.getVisibility() == View.GONE) { - list.setVisibility(View.VISIBLE); - loading.setVisibility(View.GONE); - } - } - - public void selectList(View view) { - if (type.equals("offline") == false) { - return; - } - - lists = app.getLists(); - - if (lists == null) { - return; - } - - final List<CharSequence> listsTitle = new ArrayList<CharSequence>(); - for (cgList list : lists) { - listsTitle.add(list.title); - } - - final CharSequence[] items = new CharSequence[listsTitle.size()]; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(res.getString(R.string.list_title)); - builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialogInterface, int item) { - switchListById(lists.get(item).id); - - return; - } - }); - builder.create().show(); - } - - public void switchListById(int id) { - cgList list = null; - - if (id >= 0) { - list = app.getList(id); - } else { - return; - } - - if (list == null) { - return; - } - - listId = list.id; - title = list.title; - - settings.saveLastList(listId); - - showProgress(true); - setLoadingCaches(); - - (new moveCachesToList(listId, new MoveHandler())).start(); - } - - private class MoveHandler extends Handler { - @Override - public void handleMessage(Message msg) { - Thread threadPure = new geocachesLoadByOffline(loadCachesHandler, coords, msg.what); - threadPure.start(); - } - } - - private class moveCachesToList extends Thread { - int listId = -1; - Handler handler = null; - - public moveCachesToList(int listIdIn, Handler handlerIn) { - listId = listIdIn; - handler = handlerIn; - } - - @Override - public void run() { - int checked = adapter.getChecked(); - if (checked > 0) { - final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); - for (cgCache cache : cacheListTemp) { - if (cache.statusChecked) { - app.moveToList(cache.geocode, listId); - } - } - } - - handler.sendEmptyMessage(listId); - } - } - - private void createList() { - final AlertDialog.Builder alert = new AlertDialog.Builder(this); - final View view = inflater.inflate(R.layout.list_create_dialog, null); - final EditText input = (EditText) view.findViewById(R.id.text); - - alert.setTitle(R.string.list_dialog_create_title); - alert.setView(view); - alert.setPositiveButton(R.string.list_dialog_create, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - String value = input.getText().toString(); - // remove whitespaces added by autocompletion of Android keyboard - if (value != null) { - value = value.trim(); - } - - if (StringUtils.isNotBlank(value)) { - int newId = app.createList(value); - - if (newId >= 10) { - showToast(res.getString(R.string.list_dialog_create_ok)); - } else { - showToast(res.getString(R.string.list_dialog_create_err)); - } - } - } - }); - alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dialog.dismiss(); - } - }); - - alert.show(); - } - - private void removeListInternal() { - boolean status = app.removeList(listId); - - if (status) { - showToast(res.getString(R.string.list_dialog_remove_ok)); - switchListById(1); - } else { - showToast(res.getString(R.string.list_dialog_remove_err)); - } - } - - private void removeList() { - // if there are no caches on this list, don't bother the user with questions. - // there is no harm in deleting the list, he could recreate it easily - if (cacheList != null && cacheList.isEmpty()) { - removeListInternal(); - return; - } - - // ask him, if there are caches on the list - final AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setTitle(R.string.list_dialog_remove_title); - alert.setMessage(R.string.list_dialog_remove_description); - alert.setPositiveButton(R.string.list_dialog_remove, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - removeListInternal(); - } - }); - alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dialog.dismiss(); - } - }); - - alert.show(); - } - - public void goMap(View view) { - if (searchId == null || CollectionUtils.isEmpty(cacheList)) { - showToast(res.getString(R.string.warn_no_cache_coord)); - - return; - } - - Intent mapIntent = new Intent(this, settings.getMapFactory().getMapClass()); - mapIntent.putExtra("detail", false); - mapIntent.putExtra("searchid", searchId.toString()); - - startActivity(mapIntent); - } - - public void goManual(View view) { - if (type != null && type.equals("offline")) { - ActivityMixin.goManual(this, "c:geo-stored"); - } else if (type != null && type.equals("history")) { - ActivityMixin.goManual(this, "c:geo-history"); - } else { - ActivityMixin.goManual(this, "c:geo-nearby"); - } - } - - private void refreshCurrentList() { - switchListById(listId); - } - - public static void startActivityOffline(final Context context) { - final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, "offline"); - context.startActivity(cachesIntent); - } - - public static void startActivityCachesAround(final AbstractActivity context, final Geopoint coords) { - cgeocaches cachesActivity = new cgeocaches(); - - Intent cachesIntent = new Intent(context, cachesActivity.getClass()); - cachesIntent.putExtra("type", "coordinate"); - cachesIntent.putExtra("latitude", coords.getLatitude()); - cachesIntent.putExtra("longitude", coords.getLongitude()); - cachesIntent.putExtra("cachetype", context.getSettings().cacheType); - - context.startActivity(cachesIntent); - } - - public static void startActivityCacheOwner(final AbstractActivity context, final String userName) { - final Intent cachesIntent = new Intent(context, cgeocaches.class); - - cachesIntent.putExtra("type", "owner"); - cachesIntent.putExtra("username", userName); - cachesIntent.putExtra("cachetype", context.getSettings().cacheType); - - context.startActivity(cachesIntent); - } - - public static void startActivityCacheUser(final AbstractActivity context, final String userName) { - final Intent cachesIntent = new Intent(context, cgeocaches.class); - - cachesIntent.putExtra("type", "username"); - cachesIntent.putExtra("username", userName); - cachesIntent.putExtra("cachetype", context.getSettings().cacheType); - - context.startActivity(cachesIntent); - } + private class moreCachesListener implements View.OnClickListener { + + @Override + public void onClick(View arg0) { + showProgress(true); + setLoadingCaches(); + listFooter.setOnClickListener(null); + + geocachesLoadNextPage thread; + thread = new geocachesLoadNextPage(loadNextPageHandler); + thread.setRecaptchaHandler(new cgSearchHandler(cgeocaches.this, res, thread)); + thread.start(); + } + } + + private void hideLoading() { + final ListView list = getListView(); + final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading); + + if (list.getVisibility() == View.GONE) { + list.setVisibility(View.VISIBLE); + loading.setVisibility(View.GONE); + } + } + + public void selectList(View view) { + if (type.equals("offline") == false) { + return; + } + + lists = app.getLists(); + + if (lists == null) { + return; + } + + final List<CharSequence> listsTitle = new ArrayList<CharSequence>(); + for (cgList list : lists) { + listsTitle.add(list.title); + } + + final CharSequence[] items = new CharSequence[listsTitle.size()]; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(res.getString(R.string.list_title)); + builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialogInterface, int item) { + switchListById(lists.get(item).id); + + return; + } + }); + builder.create().show(); + } + + public void switchListById(int id) { + cgList list = null; + + if (id >= 0) { + list = app.getList(id); + } else { + return; + } + + if (list == null) { + return; + } + + listId = list.id; + title = list.title; + + settings.saveLastList(listId); + + showProgress(true); + setLoadingCaches(); + + (new moveCachesToList(listId, new MoveHandler())).start(); + } + + private class MoveHandler extends Handler { + @Override + public void handleMessage(Message msg) { + Thread threadPure = new geocachesLoadByOffline(loadCachesHandler, coords, msg.what); + threadPure.start(); + } + } + + private class moveCachesToList extends Thread { + int listId = -1; + Handler handler = null; + + public moveCachesToList(int listIdIn, Handler handlerIn) { + listId = listIdIn; + handler = handlerIn; + } + + @Override + public void run() { + int checked = adapter.getChecked(); + if (checked > 0) { + final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList); + for (cgCache cache : cacheListTemp) { + if (cache.statusChecked) { + app.moveToList(cache.geocode, listId); + } + } + } + + handler.sendEmptyMessage(listId); + } + } + + private void createList() { + final AlertDialog.Builder alert = new AlertDialog.Builder(this); + final View view = inflater.inflate(R.layout.list_create_dialog, null); + final EditText input = (EditText) view.findViewById(R.id.text); + + alert.setTitle(R.string.list_dialog_create_title); + alert.setView(view); + alert.setPositiveButton(R.string.list_dialog_create, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String value = input.getText().toString(); + // remove whitespaces added by autocompletion of Android keyboard + if (value != null) { + value = value.trim(); + } + + if (StringUtils.isNotBlank(value)) { + int newId = app.createList(value); + + if (newId >= 10) { + showToast(res.getString(R.string.list_dialog_create_ok)); + } else { + showToast(res.getString(R.string.list_dialog_create_err)); + } + } + } + }); + alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + dialog.dismiss(); + } + }); + + alert.show(); + } + + private void removeListInternal() { + boolean status = app.removeList(listId); + + if (status) { + showToast(res.getString(R.string.list_dialog_remove_ok)); + switchListById(1); + } else { + showToast(res.getString(R.string.list_dialog_remove_err)); + } + } + + private void removeList() { + // if there are no caches on this list, don't bother the user with questions. + // there is no harm in deleting the list, he could recreate it easily + if (cacheList != null && cacheList.isEmpty()) { + removeListInternal(); + return; + } + + // ask him, if there are caches on the list + final AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setTitle(R.string.list_dialog_remove_title); + alert.setMessage(R.string.list_dialog_remove_description); + alert.setPositiveButton(R.string.list_dialog_remove, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + removeListInternal(); + } + }); + alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + dialog.dismiss(); + } + }); + + alert.show(); + } + + public void goMap(View view) { + if (searchId == null || CollectionUtils.isEmpty(cacheList)) { + showToast(res.getString(R.string.warn_no_cache_coord)); + + return; + } + + Intent mapIntent = new Intent(this, settings.getMapFactory().getMapClass()); + mapIntent.putExtra("detail", false); + mapIntent.putExtra("searchid", searchId.toString()); + + startActivity(mapIntent); + } + + public void goManual(View view) { + if (type != null && type.equals("offline")) { + ActivityMixin.goManual(this, "c:geo-stored"); + } else if (type != null && type.equals("history")) { + ActivityMixin.goManual(this, "c:geo-history"); + } else { + ActivityMixin.goManual(this, "c:geo-nearby"); + } + } + + private void refreshCurrentList() { + switchListById(listId); + } + + public static void startActivityOffline(final Context context) { + final Intent cachesIntent = new Intent(context, cgeocaches.class); + cachesIntent.putExtra(EXTRAS_LIST_TYPE, "offline"); + context.startActivity(cachesIntent); + } + + public static void startActivityCachesAround(final AbstractActivity context, final Geopoint coords) { + cgeocaches cachesActivity = new cgeocaches(); + + Intent cachesIntent = new Intent(context, cachesActivity.getClass()); + cachesIntent.putExtra("type", "coordinate"); + cachesIntent.putExtra("latitude", coords.getLatitude()); + cachesIntent.putExtra("longitude", coords.getLongitude()); + cachesIntent.putExtra("cachetype", context.getSettings().cacheType); + + context.startActivity(cachesIntent); + } + + public static void startActivityCacheOwner(final AbstractActivity context, final String userName) { + final Intent cachesIntent = new Intent(context, cgeocaches.class); + + cachesIntent.putExtra("type", "owner"); + cachesIntent.putExtra("username", userName); + cachesIntent.putExtra("cachetype", context.getSettings().cacheType); + + context.startActivity(cachesIntent); + } + + public static void startActivityCacheUser(final AbstractActivity context, final String userName) { + final Intent cachesIntent = new Intent(context, cgeocaches.class); + + cachesIntent.putExtra("type", "username"); + cachesIntent.putExtra("username", userName); + cachesIntent.putExtra("cachetype", context.getSettings().cacheType); + + context.startActivity(cachesIntent); + } private void prepareFilterBar() { TextView filterTextView = (TextView) findViewById(R.id.filter_text); @@ -2620,11 +2622,11 @@ public class cgeocaches extends AbstractListActivity { if (adapter.isFilter()) { filter = adapter.getFilterName(); } - + if (settings.cacheType != null && adapter.isFilter()) { filter = ", " + filter; } - + filterTextView.setText(cacheType + filter); filterBar.setVisibility(View.VISIBLE); } diff --git a/src/cgeo/geocaching/cgeocoords.java b/src/cgeo/geocaching/cgeocoords.java index 43d24f7..3758ea9 100644 --- a/src/cgeo/geocaching/cgeocoords.java +++ b/src/cgeo/geocaching/cgeocoords.java @@ -1,5 +1,12 @@ package cgeo.geocaching; +import cgeo.geocaching.cgSettings.coordInputFormatEnum; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.Geopoint.MalformedCoordinateException; +import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.geopoint.GeopointParser.ParseException; + import org.apache.commons.lang3.StringUtils; import android.app.Dialog; @@ -16,469 +23,459 @@ import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -import cgeo.geocaching.cgSettings.coordInputFormatEnum; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.Geopoint.MalformedCoordinateException; -import cgeo.geocaching.geopoint.GeopointFormatter; -import cgeo.geocaching.geopoint.GeopointParser.ParseException; public class cgeocoords extends Dialog { - private AbstractActivity context = null; - private cgSettings settings = null; - private cgGeo geo = null; - private Geopoint gp = null; - - private EditText eLat, eLon; - private Button bLat, bLon; - private EditText eLatDeg, eLatMin, eLatSec, eLatSub; - private EditText eLonDeg, eLonMin, eLonSec, eLonSub; - private TextView tLatSep1, tLatSep2, tLatSep3; - private TextView tLonSep1, tLonSep2, tLonSep3; - - private Spinner spinner; - - CoordinateUpdate cuListener; - - coordInputFormatEnum currentFormat = null; - - public cgeocoords(final AbstractActivity contextIn, cgSettings settingsIn, final Geopoint gpIn, final cgGeo geoIn) { - super(contextIn); - context = contextIn; - settings = settingsIn; - geo = geoIn; - - if (gpIn != null) { - gp = gpIn; - } else if (geo != null && geo.coordsNow != null) { - gp = geo.coordsNow; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - try { - requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); - } catch (Exception e) { - // nothing - } - - setContentView(R.layout.coords); - - spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats); - ArrayAdapter<CharSequence> adapter = - ArrayAdapter.createFromResource(context, - R.array.waypoint_coordinate_formats, - android.R.layout.simple_spinner_item); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - spinner.setSelection(settings.getCoordInputFormat().ordinal()); - spinner.setOnItemSelectedListener(new CoordinateFormatListener()); - - bLat = (Button) findViewById(R.id.ButtonLat); - eLat = (EditText) findViewById(R.id.latitude); - eLatDeg = (EditText) findViewById(R.id.EditTextLatDeg); - eLatMin = (EditText) findViewById(R.id.EditTextLatMin); - eLatSec = (EditText) findViewById(R.id.EditTextLatSec); - eLatSub = (EditText) findViewById(R.id.EditTextLatSecFrac); - tLatSep1 = (TextView) findViewById(R.id.LatSeparator1); - tLatSep2 = (TextView) findViewById(R.id.LatSeparator2); - tLatSep3 = (TextView) findViewById(R.id.LatSeparator3); - - bLon = (Button) findViewById(R.id.ButtonLon); - eLon = (EditText) findViewById(R.id.longitude); - eLonDeg = (EditText) findViewById(R.id.EditTextLonDeg); - eLonMin = (EditText) findViewById(R.id.EditTextLonMin); - eLonSec = (EditText) findViewById(R.id.EditTextLonSec); - eLonSub = (EditText) findViewById(R.id.EditTextLonSecFrac); - tLonSep1 = (TextView) findViewById(R.id.LonSeparator1); - tLonSep2 = (TextView) findViewById(R.id.LonSeparator2); - tLonSep3 = (TextView) findViewById(R.id.LonSeparator3); - - eLatDeg.addTextChangedListener(new TextChanged(eLatDeg)); - eLatMin.addTextChangedListener(new TextChanged(eLatMin)); - eLatSec.addTextChangedListener(new TextChanged(eLatSec)); - eLatSub.addTextChangedListener(new TextChanged(eLatSub)); - eLonDeg.addTextChangedListener(new TextChanged(eLonDeg)); - eLonMin.addTextChangedListener(new TextChanged(eLonMin)); - eLonSec.addTextChangedListener(new TextChanged(eLonSec)); - eLonSub.addTextChangedListener(new TextChanged(eLonSub)); - - bLat.setOnClickListener(new ButtonClickListener()); - bLon.setOnClickListener(new ButtonClickListener()); - - Button buttonCurrent = (Button) findViewById(R.id.current); - buttonCurrent.setOnClickListener(new CurrentListener()); - Button buttonDone = (Button) findViewById(R.id.done); - buttonDone.setOnClickListener(new InputDoneListener()); - } - - private void updateGUI() { - if (gp == null) - return; - Double lat = 0.0; - if (gp.getLatitude() < 0) { - bLat.setText("S"); - } else { - bLat.setText("N"); - } - - lat = Math.abs(gp.getLatitude()); - - Double lon = 0.0; - if (gp.getLongitude() < 0) { - bLon.setText("W"); - } else { - bLon.setText("E"); - } - - lon = Math.abs(gp.getLongitude()); - - int latDeg = (int) Math.floor(lat); - int latDegFrac = (int) Math.round((lat - latDeg) * 100000); - - int latMin = (int) Math.floor((lat - latDeg) * 60); - int latMinFrac = (int) Math.round(((lat - latDeg) * 60 - latMin) * 1000); - - int latSec = (int) Math.floor(((lat - latDeg) * 60 - latMin) * 60); - int latSecFrac = (int) Math.round((((lat - latDeg) * 60 - latMin) * 60 - latSec) * 1000); - - int lonDeg = (int) Math.floor(lon); - int lonDegFrac = (int) Math.round((lon - lonDeg) * 100000); - - int lonMin = (int) Math.floor((lon - lonDeg) * 60); - int lonMinFrac = (int) Math.round(((lon - lonDeg) * 60 - lonMin) * 1000); - - int lonSec = (int) Math.floor(((lon - lonDeg) * 60 - lonMin) * 60); - int lonSecFrac = (int) Math.round((((lon - lonDeg) * 60 - lonMin) * 60 - lonSec) * 1000); - - switch (currentFormat) { - case Plain: - findViewById(R.id.coordTable).setVisibility(View.GONE); - eLat.setVisibility(View.VISIBLE); - eLon.setVisibility(View.VISIBLE); - eLat.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); - eLon.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); - break; - case Deg: // DDD.DDDDD° - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); - eLat.setVisibility(View.GONE); - eLon.setVisibility(View.GONE); - eLatSec.setVisibility(View.GONE); - eLonSec.setVisibility(View.GONE); - tLatSep3.setVisibility(View.GONE); - tLonSep3.setVisibility(View.GONE); - eLatSub.setVisibility(View.GONE); - eLonSub.setVisibility(View.GONE); - - tLatSep1.setText("."); - tLonSep1.setText("."); - tLatSep2.setText("°"); - tLonSep2.setText("°"); - - eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); - eLatMin.setText(addZeros(latDegFrac, 5) + Integer.toString(latDegFrac)); - eLonDeg.setText(addZeros(latDeg, 3) + Integer.toString(lonDeg)); - eLonMin.setText(addZeros(lonDegFrac, 5) + Integer.toString(lonDegFrac)); - break; - case Min: // DDD° MM.MMM - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); - eLat.setVisibility(View.GONE); - eLon.setVisibility(View.GONE); - eLatSec.setVisibility(View.VISIBLE); - eLonSec.setVisibility(View.VISIBLE); - tLatSep3.setVisibility(View.VISIBLE); - tLonSep3.setVisibility(View.VISIBLE); - eLatSub.setVisibility(View.GONE); - eLonSub.setVisibility(View.GONE); - - tLatSep1.setText("°"); - tLonSep1.setText("°"); - tLatSep2.setText("."); - tLonSep2.setText("."); - tLatSep3.setText("'"); - tLonSep3.setText("'"); - - eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); - eLatMin.setText(addZeros(latMin, 2) + Integer.toString(latMin)); - eLatSec.setText(addZeros(latMinFrac, 3) + Integer.toString(latMinFrac)); - eLonDeg.setText(addZeros(lonDeg, 3) + Integer.toString(lonDeg)); - eLonMin.setText(addZeros(lonMin, 2) + Integer.toString(lonMin)); - eLonSec.setText(addZeros(lonMinFrac, 3) + Integer.toString(lonMinFrac)); - break; - case Sec: // DDD° MM SS.SSS - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); - eLat.setVisibility(View.GONE); - eLon.setVisibility(View.GONE); - eLatSec.setVisibility(View.VISIBLE); - eLonSec.setVisibility(View.VISIBLE); - tLatSep3.setVisibility(View.VISIBLE); - tLonSep3.setVisibility(View.VISIBLE); - eLatSub.setVisibility(View.VISIBLE); - eLonSub.setVisibility(View.VISIBLE); - - tLatSep1.setText("°"); - tLonSep1.setText("°"); - tLatSep2.setText("'"); - tLonSep2.setText("'"); - tLatSep3.setText("."); - tLonSep3.setText("."); - - eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); - eLatMin.setText(addZeros(latMin, 2) + Integer.toString(latMin)); - eLatSec.setText(addZeros(latSec, 2) + Integer.toString(latSec)); - eLatSub.setText(addZeros(latSecFrac, 3) + Integer.toString(latSecFrac)); - eLonDeg.setText(addZeros(lonDeg, 3) + Integer.toString(lonDeg)); - eLonMin.setText(addZeros(lonMin, 2) + Integer.toString(lonMin)); - eLonSec.setText(addZeros(lonSec, 2) + Integer.toString(lonSec)); - eLonSub.setText(addZeros(lonSecFrac, 3) + Integer.toString(lonSecFrac)); - break; - } - } - - private static String addZeros(int value, int len) { - StringBuilder zeros = new StringBuilder(); - if (value == 0) { - value = 1; - } - double wantedLength = Math.pow(10, len-1); - while (value < wantedLength) { - zeros.append('0'); - value *= 10; - } - return zeros.toString(); - } - - private class ButtonClickListener implements View.OnClickListener { - - @Override - public void onClick(View v) { - Button e = (Button) v; - CharSequence text = e.getText(); - if (StringUtils.isBlank(text)) { - return; - } - switch (text.charAt(0)) { - case 'N': - e.setText("S"); - break; - case 'S': - e.setText("N"); - break; - case 'E': - e.setText("W"); - break; - case 'W': - e.setText("E"); - break; - } - calc(); - } - } - - private class TextChanged implements TextWatcher { - - private EditText editText; - - public TextChanged(EditText editText) { - this.editText = editText; - } - - @Override - public void afterTextChanged(Editable s) { - /* - * Max lengths, depending on currentFormat - * - * formatPlain = disabled - * DEG MIN SEC SUB - * formatDeg 2/3 5 - - - * formatMin 2/3 2 3 - - * formatSec 2/3 2 2 3 - */ - - if (currentFormat == coordInputFormatEnum.Plain) - return; - - int maxLength = 2; - if (editText == eLonDeg || editText == eLatSub || editText == eLonSub) { - maxLength = 3; - } - if ((editText == eLatMin || editText == eLonMin) && currentFormat == coordInputFormatEnum.Deg) { - maxLength = 5; - } - if ((editText == eLatSec || editText == eLonSec) && currentFormat == coordInputFormatEnum.Min) { - maxLength = 3; - } - - if (s.length() == maxLength) { - if (editText == eLatDeg) - eLatMin.requestFocus(); - else - if (editText == eLatMin) - if (eLatSec.getVisibility() == View.GONE) - eLonDeg.requestFocus(); - else - eLatSec.requestFocus(); - else - if (editText == eLatSec) - if (eLatSub.getVisibility() == View.GONE) - eLonDeg.requestFocus(); - else - eLatSub.requestFocus(); - else - if (editText == eLatSub) - eLonDeg.requestFocus(); - else - if (editText == eLonDeg) - eLonMin.requestFocus(); - else - if (editText == eLonMin) - if (eLonSec.getVisibility() == View.GONE) - eLatDeg.requestFocus(); - else - eLonSec.requestFocus(); - else - if (editText == eLonSec) - if (eLonSub.getVisibility() == View.GONE) - eLatDeg.requestFocus(); - else - eLonSub.requestFocus(); - else - if (editText == eLonSub) - eLatDeg.requestFocus(); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - } - - private boolean calc() { - if (currentFormat == coordInputFormatEnum.Plain) { - try { - gp = new Geopoint(eLat.getText().toString() + " " + eLon.getText().toString()); - } catch (ParseException e) { - context.showToast(context.getResources().getString(R.string.err_parse_lat_lon)); - return false; - } catch (MalformedCoordinateException e) { - context.showToast(context.getResources().getString(R.string.err_invalid_lat_lon)); - return false; - } - return true; - } - - int latDeg = 0, latMin = 0, latSec = 0; - int lonDeg = 0, lonMin = 0, lonSec = 0; - Double latDegFrac = 0.0, latMinFrac = 0.0, latSecFrac = 0.0; - Double lonDegFrac = 0.0, lonMinFrac = 0.0, lonSecFrac = 0.0; - - try { - latDeg = Integer.parseInt(eLatDeg.getText().toString()); - lonDeg = Integer.parseInt(eLonDeg.getText().toString()); - latDegFrac = Double.parseDouble("0."+eLatMin.getText().toString()); - lonDegFrac = Double.parseDouble("0."+eLonMin.getText().toString()); - latMin = Integer.parseInt(eLatMin.getText().toString()); - lonMin = Integer.parseInt(eLonMin.getText().toString()); - latMinFrac = Double.parseDouble("0."+eLatSec.getText().toString()); - lonMinFrac = Double.parseDouble("0."+eLonSec.getText().toString()); - latSec = Integer.parseInt(eLatSec.getText().toString()); - lonSec = Integer.parseInt(eLonSec.getText().toString()); - latSecFrac = Double.parseDouble("0."+eLatSub.getText().toString()); - lonSecFrac = Double.parseDouble("0."+eLonSub.getText().toString()); - - } catch (NumberFormatException e) {} - - double latitude = 0.0; - double longitude = 0.0; - - switch (currentFormat) { - case Deg: - latitude = latDeg + latDegFrac; - longitude = lonDeg + lonDegFrac; - break; - case Min: - latitude = latDeg + latMin/60.0 + latMinFrac/60.0; - longitude = lonDeg + lonMin/60.0 + lonMinFrac/60.0; - break; - case Sec: - latitude = latDeg + latMin/60.0 + latSec/60.0/60.0 + latSecFrac/60.0/60.0; - longitude = lonDeg + lonMin/60.0 + lonSec/60.0/60.0 + lonSecFrac/60.0/60.0; - break; - } - latitude *= (bLat.getText().toString().equalsIgnoreCase("S") ? -1 : 1); - longitude *= (bLon.getText().toString().equalsIgnoreCase("W") ? -1 : 1); - - try { - gp = new Geopoint(latitude, longitude); - } catch (MalformedCoordinateException e) { - context.showToast(context.getResources().getString(R.string.err_invalid_lat_lon)); - return false; - } - return true; - } - - private class CoordinateFormatListener implements OnItemSelectedListener { - - @Override - public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { - // Ignore first call, which comes from onCreate() - if (currentFormat != null && !calc()) { - // An error occurred, reset spinner to current format - spinner.setSelection(currentFormat.ordinal()); - return; - } - - currentFormat = coordInputFormatEnum.fromInt(pos); - settings.setCoordInputFormat(currentFormat); - updateGUI(); - } - - @Override - public void onNothingSelected(AdapterView<?> arg0) {} - - } - - private class CurrentListener implements View.OnClickListener { - - @Override - public void onClick(View v) { - if (geo == null || geo.coordsNow == null) { - context.showToast(context.getResources().getString(R.string.err_point_unknown_position)); - return; - } - - gp = geo.coordsNow; - updateGUI(); - } - } - - private class InputDoneListener implements View.OnClickListener { - - @Override - public void onClick(View v) { - if (calc() == false) - return; - if (gp != null) - cuListener.update(gp); - dismiss(); - } - } - - public void setOnCoordinateUpdate(CoordinateUpdate cu) { - cuListener = cu; - } - - public interface CoordinateUpdate { - public void update(final Geopoint gp); - } + private AbstractActivity context = null; + private cgSettings settings = null; + private cgGeo geo = null; + private Geopoint gp = null; + + private EditText eLat, eLon; + private Button bLat, bLon; + private EditText eLatDeg, eLatMin, eLatSec, eLatSub; + private EditText eLonDeg, eLonMin, eLonSec, eLonSub; + private TextView tLatSep1, tLatSep2, tLatSep3; + private TextView tLonSep1, tLonSep2, tLonSep3; + + private Spinner spinner; + + CoordinateUpdate cuListener; + + coordInputFormatEnum currentFormat = null; + + public cgeocoords(final AbstractActivity contextIn, cgSettings settingsIn, final Geopoint gpIn, final cgGeo geoIn) { + super(contextIn); + context = contextIn; + settings = settingsIn; + geo = geoIn; + + if (gpIn != null) { + gp = gpIn; + } else if (geo != null && geo.coordsNow != null) { + gp = geo.coordsNow; + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + try { + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); + } catch (Exception e) { + // nothing + } + + setContentView(R.layout.coords); + + spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats); + ArrayAdapter<CharSequence> adapter = + ArrayAdapter.createFromResource(context, + R.array.waypoint_coordinate_formats, + android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setSelection(settings.getCoordInputFormat().ordinal()); + spinner.setOnItemSelectedListener(new CoordinateFormatListener()); + + bLat = (Button) findViewById(R.id.ButtonLat); + eLat = (EditText) findViewById(R.id.latitude); + eLatDeg = (EditText) findViewById(R.id.EditTextLatDeg); + eLatMin = (EditText) findViewById(R.id.EditTextLatMin); + eLatSec = (EditText) findViewById(R.id.EditTextLatSec); + eLatSub = (EditText) findViewById(R.id.EditTextLatSecFrac); + tLatSep1 = (TextView) findViewById(R.id.LatSeparator1); + tLatSep2 = (TextView) findViewById(R.id.LatSeparator2); + tLatSep3 = (TextView) findViewById(R.id.LatSeparator3); + + bLon = (Button) findViewById(R.id.ButtonLon); + eLon = (EditText) findViewById(R.id.longitude); + eLonDeg = (EditText) findViewById(R.id.EditTextLonDeg); + eLonMin = (EditText) findViewById(R.id.EditTextLonMin); + eLonSec = (EditText) findViewById(R.id.EditTextLonSec); + eLonSub = (EditText) findViewById(R.id.EditTextLonSecFrac); + tLonSep1 = (TextView) findViewById(R.id.LonSeparator1); + tLonSep2 = (TextView) findViewById(R.id.LonSeparator2); + tLonSep3 = (TextView) findViewById(R.id.LonSeparator3); + + eLatDeg.addTextChangedListener(new TextChanged(eLatDeg)); + eLatMin.addTextChangedListener(new TextChanged(eLatMin)); + eLatSec.addTextChangedListener(new TextChanged(eLatSec)); + eLatSub.addTextChangedListener(new TextChanged(eLatSub)); + eLonDeg.addTextChangedListener(new TextChanged(eLonDeg)); + eLonMin.addTextChangedListener(new TextChanged(eLonMin)); + eLonSec.addTextChangedListener(new TextChanged(eLonSec)); + eLonSub.addTextChangedListener(new TextChanged(eLonSub)); + + bLat.setOnClickListener(new ButtonClickListener()); + bLon.setOnClickListener(new ButtonClickListener()); + + Button buttonCurrent = (Button) findViewById(R.id.current); + buttonCurrent.setOnClickListener(new CurrentListener()); + Button buttonDone = (Button) findViewById(R.id.done); + buttonDone.setOnClickListener(new InputDoneListener()); + } + + private void updateGUI() { + if (gp == null) + return; + Double lat = 0.0; + if (gp.getLatitude() < 0) { + bLat.setText("S"); + } else { + bLat.setText("N"); + } + + lat = Math.abs(gp.getLatitude()); + + Double lon = 0.0; + if (gp.getLongitude() < 0) { + bLon.setText("W"); + } else { + bLon.setText("E"); + } + + lon = Math.abs(gp.getLongitude()); + + int latDeg = (int) Math.floor(lat); + int latDegFrac = (int) Math.round((lat - latDeg) * 100000); + + int latMin = (int) Math.floor((lat - latDeg) * 60); + int latMinFrac = (int) Math.round(((lat - latDeg) * 60 - latMin) * 1000); + + int latSec = (int) Math.floor(((lat - latDeg) * 60 - latMin) * 60); + int latSecFrac = (int) Math.round((((lat - latDeg) * 60 - latMin) * 60 - latSec) * 1000); + + int lonDeg = (int) Math.floor(lon); + int lonDegFrac = (int) Math.round((lon - lonDeg) * 100000); + + int lonMin = (int) Math.floor((lon - lonDeg) * 60); + int lonMinFrac = (int) Math.round(((lon - lonDeg) * 60 - lonMin) * 1000); + + int lonSec = (int) Math.floor(((lon - lonDeg) * 60 - lonMin) * 60); + int lonSecFrac = (int) Math.round((((lon - lonDeg) * 60 - lonMin) * 60 - lonSec) * 1000); + + switch (currentFormat) { + case Plain: + findViewById(R.id.coordTable).setVisibility(View.GONE); + eLat.setVisibility(View.VISIBLE); + eLon.setVisibility(View.VISIBLE); + eLat.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); + eLon.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); + break; + case Deg: // DDD.DDDDD° + findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + eLat.setVisibility(View.GONE); + eLon.setVisibility(View.GONE); + eLatSec.setVisibility(View.GONE); + eLonSec.setVisibility(View.GONE); + tLatSep3.setVisibility(View.GONE); + tLonSep3.setVisibility(View.GONE); + eLatSub.setVisibility(View.GONE); + eLonSub.setVisibility(View.GONE); + + tLatSep1.setText("."); + tLonSep1.setText("."); + tLatSep2.setText("°"); + tLonSep2.setText("°"); + + eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); + eLatMin.setText(addZeros(latDegFrac, 5) + Integer.toString(latDegFrac)); + eLonDeg.setText(addZeros(latDeg, 3) + Integer.toString(lonDeg)); + eLonMin.setText(addZeros(lonDegFrac, 5) + Integer.toString(lonDegFrac)); + break; + case Min: // DDD° MM.MMM + findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + eLat.setVisibility(View.GONE); + eLon.setVisibility(View.GONE); + eLatSec.setVisibility(View.VISIBLE); + eLonSec.setVisibility(View.VISIBLE); + tLatSep3.setVisibility(View.VISIBLE); + tLonSep3.setVisibility(View.VISIBLE); + eLatSub.setVisibility(View.GONE); + eLonSub.setVisibility(View.GONE); + + tLatSep1.setText("°"); + tLonSep1.setText("°"); + tLatSep2.setText("."); + tLonSep2.setText("."); + tLatSep3.setText("'"); + tLonSep3.setText("'"); + + eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); + eLatMin.setText(addZeros(latMin, 2) + Integer.toString(latMin)); + eLatSec.setText(addZeros(latMinFrac, 3) + Integer.toString(latMinFrac)); + eLonDeg.setText(addZeros(lonDeg, 3) + Integer.toString(lonDeg)); + eLonMin.setText(addZeros(lonMin, 2) + Integer.toString(lonMin)); + eLonSec.setText(addZeros(lonMinFrac, 3) + Integer.toString(lonMinFrac)); + break; + case Sec: // DDD° MM SS.SSS + findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + eLat.setVisibility(View.GONE); + eLon.setVisibility(View.GONE); + eLatSec.setVisibility(View.VISIBLE); + eLonSec.setVisibility(View.VISIBLE); + tLatSep3.setVisibility(View.VISIBLE); + tLonSep3.setVisibility(View.VISIBLE); + eLatSub.setVisibility(View.VISIBLE); + eLonSub.setVisibility(View.VISIBLE); + + tLatSep1.setText("°"); + tLonSep1.setText("°"); + tLatSep2.setText("'"); + tLonSep2.setText("'"); + tLatSep3.setText("."); + tLonSep3.setText("."); + + eLatDeg.setText(addZeros(latDeg, 2) + Integer.toString(latDeg)); + eLatMin.setText(addZeros(latMin, 2) + Integer.toString(latMin)); + eLatSec.setText(addZeros(latSec, 2) + Integer.toString(latSec)); + eLatSub.setText(addZeros(latSecFrac, 3) + Integer.toString(latSecFrac)); + eLonDeg.setText(addZeros(lonDeg, 3) + Integer.toString(lonDeg)); + eLonMin.setText(addZeros(lonMin, 2) + Integer.toString(lonMin)); + eLonSec.setText(addZeros(lonSec, 2) + Integer.toString(lonSec)); + eLonSub.setText(addZeros(lonSecFrac, 3) + Integer.toString(lonSecFrac)); + break; + } + } + + private static String addZeros(int value, int len) { + StringBuilder zeros = new StringBuilder(); + if (value == 0) { + value = 1; + } + double wantedLength = Math.pow(10, len - 1); + while (value < wantedLength) { + zeros.append('0'); + value *= 10; + } + return zeros.toString(); + } + + private class ButtonClickListener implements View.OnClickListener { + + @Override + public void onClick(View v) { + Button e = (Button) v; + CharSequence text = e.getText(); + if (StringUtils.isBlank(text)) { + return; + } + switch (text.charAt(0)) { + case 'N': + e.setText("S"); + break; + case 'S': + e.setText("N"); + break; + case 'E': + e.setText("W"); + break; + case 'W': + e.setText("E"); + break; + } + calc(); + } + } + + private class TextChanged implements TextWatcher { + + private EditText editText; + + public TextChanged(EditText editText) { + this.editText = editText; + } + + @Override + public void afterTextChanged(Editable s) { + /* + * Max lengths, depending on currentFormat + * + * formatPlain = disabled + * DEG MIN SEC SUB + * formatDeg 2/3 5 - - + * formatMin 2/3 2 3 - + * formatSec 2/3 2 2 3 + */ + + if (currentFormat == coordInputFormatEnum.Plain) + return; + + int maxLength = 2; + if (editText == eLonDeg || editText == eLatSub || editText == eLonSub) { + maxLength = 3; + } + if ((editText == eLatMin || editText == eLonMin) && currentFormat == coordInputFormatEnum.Deg) { + maxLength = 5; + } + if ((editText == eLatSec || editText == eLonSec) && currentFormat == coordInputFormatEnum.Min) { + maxLength = 3; + } + + if (s.length() == maxLength) { + if (editText == eLatDeg) + eLatMin.requestFocus(); + else if (editText == eLatMin) + if (eLatSec.getVisibility() == View.GONE) + eLonDeg.requestFocus(); + else + eLatSec.requestFocus(); + else if (editText == eLatSec) + if (eLatSub.getVisibility() == View.GONE) + eLonDeg.requestFocus(); + else + eLatSub.requestFocus(); + else if (editText == eLatSub) + eLonDeg.requestFocus(); + else if (editText == eLonDeg) + eLonMin.requestFocus(); + else if (editText == eLonMin) + if (eLonSec.getVisibility() == View.GONE) + eLatDeg.requestFocus(); + else + eLonSec.requestFocus(); + else if (editText == eLonSec) + if (eLonSub.getVisibility() == View.GONE) + eLatDeg.requestFocus(); + else + eLonSub.requestFocus(); + else if (editText == eLonSub) + eLatDeg.requestFocus(); + } + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + } + + private boolean calc() { + if (currentFormat == coordInputFormatEnum.Plain) { + try { + gp = new Geopoint(eLat.getText().toString() + " " + eLon.getText().toString()); + } catch (ParseException e) { + context.showToast(context.getResources().getString(R.string.err_parse_lat_lon)); + return false; + } catch (MalformedCoordinateException e) { + context.showToast(context.getResources().getString(R.string.err_invalid_lat_lon)); + return false; + } + return true; + } + + int latDeg = 0, latMin = 0, latSec = 0; + int lonDeg = 0, lonMin = 0, lonSec = 0; + Double latDegFrac = 0.0, latMinFrac = 0.0, latSecFrac = 0.0; + Double lonDegFrac = 0.0, lonMinFrac = 0.0, lonSecFrac = 0.0; + + try { + latDeg = Integer.parseInt(eLatDeg.getText().toString()); + lonDeg = Integer.parseInt(eLonDeg.getText().toString()); + latDegFrac = Double.parseDouble("0." + eLatMin.getText().toString()); + lonDegFrac = Double.parseDouble("0." + eLonMin.getText().toString()); + latMin = Integer.parseInt(eLatMin.getText().toString()); + lonMin = Integer.parseInt(eLonMin.getText().toString()); + latMinFrac = Double.parseDouble("0." + eLatSec.getText().toString()); + lonMinFrac = Double.parseDouble("0." + eLonSec.getText().toString()); + latSec = Integer.parseInt(eLatSec.getText().toString()); + lonSec = Integer.parseInt(eLonSec.getText().toString()); + latSecFrac = Double.parseDouble("0." + eLatSub.getText().toString()); + lonSecFrac = Double.parseDouble("0." + eLonSub.getText().toString()); + + } catch (NumberFormatException e) { + } + + double latitude = 0.0; + double longitude = 0.0; + + switch (currentFormat) { + case Deg: + latitude = latDeg + latDegFrac; + longitude = lonDeg + lonDegFrac; + break; + case Min: + latitude = latDeg + latMin / 60.0 + latMinFrac / 60.0; + longitude = lonDeg + lonMin / 60.0 + lonMinFrac / 60.0; + break; + case Sec: + latitude = latDeg + latMin / 60.0 + latSec / 60.0 / 60.0 + latSecFrac / 60.0 / 60.0; + longitude = lonDeg + lonMin / 60.0 + lonSec / 60.0 / 60.0 + lonSecFrac / 60.0 / 60.0; + break; + } + latitude *= (bLat.getText().toString().equalsIgnoreCase("S") ? -1 : 1); + longitude *= (bLon.getText().toString().equalsIgnoreCase("W") ? -1 : 1); + + try { + gp = new Geopoint(latitude, longitude); + } catch (MalformedCoordinateException e) { + context.showToast(context.getResources().getString(R.string.err_invalid_lat_lon)); + return false; + } + return true; + } + + private class CoordinateFormatListener implements OnItemSelectedListener { + + @Override + public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { + // Ignore first call, which comes from onCreate() + if (currentFormat != null && !calc()) { + // An error occurred, reset spinner to current format + spinner.setSelection(currentFormat.ordinal()); + return; + } + + currentFormat = coordInputFormatEnum.fromInt(pos); + settings.setCoordInputFormat(currentFormat); + updateGUI(); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) { + } + + } + + private class CurrentListener implements View.OnClickListener { + + @Override + public void onClick(View v) { + if (geo == null || geo.coordsNow == null) { + context.showToast(context.getResources().getString(R.string.err_point_unknown_position)); + return; + } + + gp = geo.coordsNow; + updateGUI(); + } + } + + private class InputDoneListener implements View.OnClickListener { + + @Override + public void onClick(View v) { + if (calc() == false) + return; + if (gp != null) + cuListener.update(gp); + dismiss(); + } + } + + public void setOnCoordinateUpdate(CoordinateUpdate cu) { + cuListener = cu; + } + + public interface CoordinateUpdate { + public void update(final Geopoint gp); + } } - diff --git a/src/cgeo/geocaching/cgeodate.java b/src/cgeo/geocaching/cgeodate.java index ce75e76..85ddeac 100644 --- a/src/cgeo/geocaching/cgeodate.java +++ b/src/cgeo/geocaching/cgeodate.java @@ -1,7 +1,5 @@ package cgeo.geocaching; -import java.util.Calendar; - import android.app.Activity; import android.app.Dialog; import android.os.Bundle; @@ -9,45 +7,47 @@ import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.DatePicker; +import java.util.Calendar; + public class cgeodate extends Dialog { - private cgLogForm parent = null; - private Calendar date = Calendar.getInstance(); + private cgLogForm parent = null; + private Calendar date = Calendar.getInstance(); - public cgeodate(Activity contextIn, cgLogForm parentIn, Calendar dateIn) { - super(contextIn); + public cgeodate(Activity contextIn, cgLogForm parentIn, Calendar dateIn) { + super(contextIn); - // init - date = dateIn; - parent = parentIn; - } + // init + date = dateIn; + parent = parentIn; + } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - try { - requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); - } catch (Exception e) { - // nothing - } + try { + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); + } catch (Exception e) { + // nothing + } - setContentView(R.layout.date); + setContentView(R.layout.date); - DatePicker picker = (DatePicker) findViewById(R.id.picker); - picker.init(date.get(Calendar.YEAR), date.get(Calendar.MONTH), date.get(Calendar.DATE), new pickerListener()); - } + DatePicker picker = (DatePicker) findViewById(R.id.picker); + picker.init(date.get(Calendar.YEAR), date.get(Calendar.MONTH), date.get(Calendar.DATE), new pickerListener()); + } - public class pickerListener implements DatePicker.OnDateChangedListener { + public class pickerListener implements DatePicker.OnDateChangedListener { - @Override - public void onDateChanged(DatePicker picker, int year, int month, int day) { - if (parent != null) { - date.set(year, month, day); + @Override + public void onDateChanged(DatePicker picker, int year, int month, int day) { + if (parent != null) { + date.set(year, month, day); - parent.setDate(date); - } - } - } + parent.setDate(date); + } + } + } } diff --git a/src/cgeo/geocaching/cgeodetail.java b/src/cgeo/geocaching/cgeodetail.java index 340e8ee..bf52fa9 100644 --- a/src/cgeo/geocaching/cgeodetail.java +++ b/src/cgeo/geocaching/cgeodetail.java @@ -1,16 +1,10 @@ package cgeo.geocaching; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.apps.cache.GeneralAppsFactory; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.compatibility.Compatibility; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -55,1753 +49,1773 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.apps.cache.GeneralAppsFactory; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; -import cgeo.geocaching.compatibility.Compatibility; -import cgeo.geocaching.utils.CollectionUtils; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; /** * Activity to display all details of a cache like owner, difficulty, description etc. - * + * */ public class cgeodetail extends AbstractActivity { - public cgeodetail() { - super("c:geo-cache-details"); - } - - public UUID searchId = null; - public cgCache cache = null; - public String geocode = null; - public String name = null; - public String guid = null; - private LayoutInflater inflater = null; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private float pixelRatio = 1; - private TextView cacheDistance = null; - private String contextMenuUser = null; - private ProgressDialog waitDialog = null; - private ProgressDialog descDialog = null; - private Spanned longDesc = null; - private Boolean longDescDisplayed = false; - private loadCache threadCache = null; - private loadLongDesc threadLongDesc = null; - private Thread storeThread = null; - private Thread refreshThread = null; - private ProgressDialog storeDialog = null; - private ProgressDialog refreshDialog = null; - private ProgressDialog dropDialog = null; - private ProgressDialog watchlistDialog = null; // progress dialog for watchlist add/remove - private Thread watchlistThread = null; // thread for watchlist add/remove - private Map<Integer, String> calendars = new HashMap<Integer, String>(); - - private ViewGroup attributeIconsLayout; // layout for attribute icons - private ViewGroup attributeDescriptionsLayout; // layout for attribute descriptions - private boolean attributesShowAsIcons = true; // default: show icons - /** <code>noAttributeImagesFound</code> - * This will be the case if the cache was imported with an older version of c:geo. - * These older versions parsed the attribute description from the tooltip in the web - * page and put them into the DB. No icons can be matched for these. */ - private boolean noAttributeIconsFound = false; - private int attributeBoxMaxWidth; - /** - * differentiate between whether we are starting the activity for a cache or if we return to the activity from - * another activity that we started in front - */ - private boolean disableResumeSetView = false; - - private Handler storeCacheHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - storeThread = null; - - try { - cache = app.getCache(searchId); // reload cache details - } catch (Exception e) { - showToast(res.getString(R.string.err_store_failed)); - - Log.e(cgSettings.tag, "cgeodetail.storeCacheHandler: " + e.toString()); - } - - setView(); - } - }; - - private Handler refreshCacheHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - refreshThread = null; - - try { - cache = app.getCache(searchId); // reload cache details - } catch (Exception e) { - showToast(res.getString(R.string.err_refresh_failed)); - - Log.e(cgSettings.tag, "cgeodetail.refreshCacheHandler: " + e.toString()); - } - - setView(); - } - }; - - private Handler dropCacheHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - try { - cache = app.getCache(searchId); // reload cache details - } catch (Exception e) { - showToast(res.getString(R.string.err_drop_failed)); - - Log.e(cgSettings.tag, "cgeodetail.dropCacheHandler: " + e.toString()); - } - - setView(); - } - }; - - private Handler loadCacheHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (searchId == null) { - showToast(res.getString(R.string.err_dwld_details_failed)); - - finish(); - return; - } - - if (app.getError(searchId) != null) { - showToast(res.getString(R.string.err_dwld_details_failed_reason) + " " + app.getError(searchId) + "."); - - finish(); - return; - } - - setView(); - - if (settings.autoLoadDesc == 1) { - try { - loadLongDesc(); - } catch (Exception e) { - // activity is not visible - } - } - - (new loadMapPreview(loadMapPreviewHandler)).start(); - } - }; - - final Handler loadMapPreviewHandler = new Handler() { - @Override - public void handleMessage(Message message) { - BitmapDrawable image = (BitmapDrawable) message.obj; - if (image == null) { - return; - } - ScrollView scroll = (ScrollView) findViewById(R.id.details_list_box); - final ImageView view = (ImageView) findViewById(R.id.map_preview); - if (view == null) { - return; - } - Bitmap bitmap = image.getBitmap(); - if (bitmap == null || bitmap.getWidth() <= 10) { - return; - } - view.setImageDrawable(image); - - if (scroll.getScrollY() == 0) { - scroll.scrollTo(0, (int) (80 * pixelRatio)); - } - view.setVisibility(View.VISIBLE); - view.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - try { - registerForContextMenu(view); - openContextMenu(view); - } catch (Exception e) { - // nothing - } - } - }); - } - }; - - private Handler loadDescriptionHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - parseLongDescription(); - - if (longDesc != null) { - ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); - TextView descView = (TextView) findViewById(R.id.description); - if (cache.description.length() > 0) { - descView.setVisibility(View.VISIBLE); - descView.setText(longDesc, TextView.BufferType.SPANNABLE); - descView.setMovementMethod(LinkMovementMethod.getInstance()); - } - else { - descView.setVisibility(View.GONE); - } - - Button showDesc = (Button) findViewById(R.id.show_description); - showDesc.setVisibility(View.GONE); - showDesc.setOnTouchListener(null); - showDesc.setOnClickListener(null); - } else { - showToast(res.getString(R.string.err_load_descr_failed)); - } - - if (descDialog != null && descDialog.isShowing()) { - descDialog.dismiss(); - } - - longDescDisplayed = true; - } - }; - - /** - * shows/hides buttons, sets text in watchlist box - */ - private void updateWatchlistBox() { - LinearLayout layout = (LinearLayout)findViewById(R.id.watchlist_box); - boolean supportsWatchList = cache.supportsWatchList(); - layout.setVisibility(supportsWatchList ? View.VISIBLE : View.GONE); - if (!supportsWatchList) { - return; - } - Button buttonAdd = (Button) findViewById(R.id.add_to_watchlist); - Button buttonRemove = (Button) findViewById(R.id.remove_from_watchlist); - TextView text = (TextView) findViewById(R.id.watchlist_text); - - if (cache.onWatchlist) { - buttonAdd.setVisibility(View.GONE); - buttonRemove.setVisibility(View.VISIBLE); - text.setText(R.string.cache_watchlist_on); - } else { - buttonAdd.setVisibility(View.VISIBLE); - buttonRemove.setVisibility(View.GONE); - text.setText(R.string.cache_watchlist_not_on); - } - } - - /** - * Handler, called when watchlist add or remove is done - */ - private Handler WatchlistHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - watchlistThread = null; - if (watchlistDialog != null) - watchlistDialog.dismiss(); - if (msg.what == -1) { - showToast(res.getString(R.string.err_watchlist_failed)); - } else { - updateWatchlistBox(); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.detail); - setTitle(res.getString(R.string.cache)); - - init(); - - // get parameters - final Bundle extras = getIntent().getExtras(); - final Uri uri = getIntent().getData(); - - // try to get data from extras - if (geocode == null && extras != null) { - geocode = extras.getString("geocode"); - name = extras.getString("name"); - guid = extras.getString("guid"); - } - - // try to get data from URI - if (geocode == null && guid == null && uri != null) { - String uriHost = uri.getHost().toLowerCase(); - String uriPath = uri.getPath().toLowerCase(); - String uriQuery = uri.getQuery(); - - if (uriQuery != null) { - Log.i(cgSettings.tag, "Opening URI: " + uriHost + uriPath + "?" + uriQuery); - } else { - Log.i(cgSettings.tag, "Opening URI: " + uriHost + uriPath); - } - - if (uriHost.contains("geocaching.com")) { - geocode = uri.getQueryParameter("wp"); - guid = uri.getQueryParameter("guid"); - - if (StringUtils.isNotBlank(geocode)) { - geocode = geocode.toUpperCase(); - guid = null; - } else if (StringUtils.isNotBlank(guid)) { - geocode = null; - guid = guid.toLowerCase(); - } else { - showToast(res.getString(R.string.err_detail_open)); - finish(); - return; - } - } else if (uriHost.contains("coord.info")) { - if (uriPath != null && uriPath.startsWith("/gc")) { - geocode = uriPath.substring(1).toUpperCase(); - } else { - showToast(res.getString(R.string.err_detail_open)); - finish(); - return; - } - } - } - - // no given data - if (geocode == null && guid == null) { - showToast(res.getString(R.string.err_detail_cache)); - finish(); - return; - } - - app.setAction(geocode); - - try { - if (StringUtils.isNotBlank(name)) { - waitDialog = ProgressDialog.show(this, name, res.getString(R.string.cache_dialog_loading_details), true); - } else if (StringUtils.isNotBlank(geocode)) { - waitDialog = ProgressDialog.show(this, geocode.toUpperCase(), res.getString(R.string.cache_dialog_loading_details), true); - } else { - waitDialog = ProgressDialog.show(this, res.getString(R.string.cache), res.getString(R.string.cache_dialog_loading_details), true); - } - waitDialog.setCancelable(true); - } catch (Exception e) { - // nothing, we lost the window - } - - disableResumeSetView = true; - threadCache = new loadCache(loadCacheHandler); - threadCache.start(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - setView(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - if (!disableResumeSetView) { - setView(); - } - disableResumeSetView = false; - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - - if (viewId == R.id.author || viewId == R.id.value) { - if (viewId == R.id.author) { // Author of a log entry - contextMenuUser = ((TextView)view).getText().toString(); - } else if (viewId == R.id.value) { // The owner of the cache - if (StringUtils.isNotBlank(cache.ownerReal)) { - contextMenuUser = cache.ownerReal; - } else { - contextMenuUser = cache.owner; - } - } - - menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser); - menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden)); - menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found)); - menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser)); - } - if (viewId == R.id.map_preview) { - menu.setHeaderTitle(res.getString(R.string.cache_menu_navigate)); - addNavigationMenuItems(menu); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int group = item.getGroupId(); - - if (group == R.id.author || group == R.id.value) { - final int id = item.getItemId(); - - if (id == 1) { - cgeocaches.startActivityCacheOwner(this, contextMenuUser); - return true; - } else if (id == 2) { - cgeocaches.startActivityCacheUser(this, contextMenuUser); - return true; - } else if (id == 3) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser)))); - - return true; - } - } - else { - return onOptionsItemSelected(item); - } - return false; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (cache != null && cache.coords != null) { - menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass - SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); - addNavigationMenuItems(subMenu); - } - - if (cache != null && cache.canBeAddedToCalendar()) { - menu.add(1, 11, 0, res.getString(R.string.cache_menu_event)).setIcon(android.R.drawable.ic_menu_agenda); // add event to calendar - } - addVisitMenu(menu, cache); - - if (cache != null && CollectionUtils.isNotEmpty(cache.spoilers)) { - menu.add(1, 5, 0, res.getString(R.string.cache_menu_spoilers)).setIcon(android.R.drawable.ic_menu_gallery); // spoiler images - } - - if (cache != null && cache.coords != null) { - menu.add(0, 10, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around - } - - if (cache != null && cache.canOpenInBrowser()) { - menu.add(1, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(android.R.drawable.ic_menu_info_details); // browser - } - menu.add(0, 12, 0, res.getString(R.string.cache_menu_share)).setIcon(android.R.drawable.ic_menu_share); // share cache - - return true; - } - - private void addNavigationMenuItems(final Menu menu) { - NavigationAppFactory.addMenuItems(menu, this, res); - GeneralAppsFactory.addMenuItems(menu, this, res, cache); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int menuItem = item.getItemId(); - - if (menuItem == 2) { - navigateTo(); - return true; - } else if (menuItem == MENU_LOG_VISIT) { - logVisit(); - return true; - } else if (menuItem == 5) { - showSpoilers(); - return true; - } else if (menuItem == 7) { - cache.openInBrowser(this); - return true; - } else if (menuItem == 10) { - cachesAround(); - return true; - } else if (menuItem == 11) { - addToCalendar(); - return true; - } else if (menuItem == 12) { - shareCache(); - return true; - } - if (NavigationAppFactory.onMenuItemSelected(item, geo, this, res, cache, searchId, null, null)) { - return true; - } - if (GeneralAppsFactory.onMenuItemSelected(item, this, cache)) { - return true; - } - - int logType = menuItem - MENU_LOG_VISIT_OFFLINE; - cache.logOffline(this, logType, settings, base); - return true; - } - - private void init() { - final DisplayMetrics dm = getResources().getDisplayMetrics(); - pixelRatio = dm.density; - - if (inflater == null) { - inflater = getLayoutInflater(); - } - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - if (searchId != null) { - cache = app.getCache(searchId); - if (cache != null && cache.geocode != null) { - geocode = cache.geocode; - } - } - - if (StringUtils.isNotBlank(geocode)) { - app.setAction(geocode); - } - } - - private void setView() { - RelativeLayout itemLayout; - TextView itemName; - TextView itemValue; - - if (searchId == null) { - return; - } - - cache = app.getCache(searchId); - - if (cache == null) { - if (waitDialog != null && waitDialog.isShowing()) waitDialog.dismiss(); - - if (StringUtils.isNotBlank(geocode)) { - showToast(res.getString(R.string.err_detail_cache_find) + " " + geocode + "."); - } else { - geocode = null; - showToast(res.getString(R.string.err_detail_cache_find_some)); - } - - finish(); - return; - } - - try { - - if (geocode == null && StringUtils.isNotBlank(cache.geocode)) { - geocode = cache.geocode; - } - - if (guid == null && StringUtils.isNotBlank(cache.guid)) { + public cgeodetail() { + super("c:geo-cache-details"); + } + + public UUID searchId = null; + public cgCache cache = null; + public String geocode = null; + public String name = null; + public String guid = null; + private LayoutInflater inflater = null; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private float pixelRatio = 1; + private TextView cacheDistance = null; + private String contextMenuUser = null; + private ProgressDialog waitDialog = null; + private ProgressDialog descDialog = null; + private Spanned longDesc = null; + private Boolean longDescDisplayed = false; + private loadCache threadCache = null; + private loadLongDesc threadLongDesc = null; + private Thread storeThread = null; + private Thread refreshThread = null; + private ProgressDialog storeDialog = null; + private ProgressDialog refreshDialog = null; + private ProgressDialog dropDialog = null; + private ProgressDialog watchlistDialog = null; // progress dialog for watchlist add/remove + private Thread watchlistThread = null; // thread for watchlist add/remove + private Map<Integer, String> calendars = new HashMap<Integer, String>(); + + private ViewGroup attributeIconsLayout; // layout for attribute icons + private ViewGroup attributeDescriptionsLayout; // layout for attribute descriptions + private boolean attributesShowAsIcons = true; // default: show icons + /** + * <code>noAttributeImagesFound</code> This will be the case if the cache was imported with an older version of + * c:geo. + * These older versions parsed the attribute description from the tooltip in the web + * page and put them into the DB. No icons can be matched for these. + */ + private boolean noAttributeIconsFound = false; + private int attributeBoxMaxWidth; + /** + * differentiate between whether we are starting the activity for a cache or if we return to the activity from + * another activity that we started in front + */ + private boolean disableResumeSetView = false; + + private Handler storeCacheHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + storeThread = null; + + try { + cache = app.getCache(searchId); // reload cache details + } catch (Exception e) { + showToast(res.getString(R.string.err_store_failed)); + + Log.e(cgSettings.tag, "cgeodetail.storeCacheHandler: " + e.toString()); + } + + setView(); + } + }; + + private Handler refreshCacheHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + refreshThread = null; + + try { + cache = app.getCache(searchId); // reload cache details + } catch (Exception e) { + showToast(res.getString(R.string.err_refresh_failed)); + + Log.e(cgSettings.tag, "cgeodetail.refreshCacheHandler: " + e.toString()); + } + + setView(); + } + }; + + private Handler dropCacheHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + try { + cache = app.getCache(searchId); // reload cache details + } catch (Exception e) { + showToast(res.getString(R.string.err_drop_failed)); + + Log.e(cgSettings.tag, "cgeodetail.dropCacheHandler: " + e.toString()); + } + + setView(); + } + }; + + private Handler loadCacheHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (searchId == null) { + showToast(res.getString(R.string.err_dwld_details_failed)); + + finish(); + return; + } + + if (app.getError(searchId) != null) { + showToast(res.getString(R.string.err_dwld_details_failed_reason) + " " + app.getError(searchId) + "."); + + finish(); + return; + } + + setView(); + + if (settings.autoLoadDesc == 1) { + try { + loadLongDesc(); + } catch (Exception e) { + // activity is not visible + } + } + + (new loadMapPreview(loadMapPreviewHandler)).start(); + } + }; + + final Handler loadMapPreviewHandler = new Handler() { + @Override + public void handleMessage(Message message) { + BitmapDrawable image = (BitmapDrawable) message.obj; + if (image == null) { + return; + } + ScrollView scroll = (ScrollView) findViewById(R.id.details_list_box); + final ImageView view = (ImageView) findViewById(R.id.map_preview); + if (view == null) { + return; + } + Bitmap bitmap = image.getBitmap(); + if (bitmap == null || bitmap.getWidth() <= 10) { + return; + } + view.setImageDrawable(image); + + if (scroll.getScrollY() == 0) { + scroll.scrollTo(0, (int) (80 * pixelRatio)); + } + view.setVisibility(View.VISIBLE); + view.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + try { + registerForContextMenu(view); + openContextMenu(view); + } catch (Exception e) { + // nothing + } + } + }); + } + }; + + private Handler loadDescriptionHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + parseLongDescription(); + + if (longDesc != null) { + ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); + TextView descView = (TextView) findViewById(R.id.description); + if (cache.description.length() > 0) { + descView.setVisibility(View.VISIBLE); + descView.setText(longDesc, TextView.BufferType.SPANNABLE); + descView.setMovementMethod(LinkMovementMethod.getInstance()); + } + else { + descView.setVisibility(View.GONE); + } + + Button showDesc = (Button) findViewById(R.id.show_description); + showDesc.setVisibility(View.GONE); + showDesc.setOnTouchListener(null); + showDesc.setOnClickListener(null); + } else { + showToast(res.getString(R.string.err_load_descr_failed)); + } + + if (descDialog != null && descDialog.isShowing()) { + descDialog.dismiss(); + } + + longDescDisplayed = true; + } + }; + + /** + * shows/hides buttons, sets text in watchlist box + */ + private void updateWatchlistBox() { + LinearLayout layout = (LinearLayout) findViewById(R.id.watchlist_box); + boolean supportsWatchList = cache.supportsWatchList(); + layout.setVisibility(supportsWatchList ? View.VISIBLE : View.GONE); + if (!supportsWatchList) { + return; + } + Button buttonAdd = (Button) findViewById(R.id.add_to_watchlist); + Button buttonRemove = (Button) findViewById(R.id.remove_from_watchlist); + TextView text = (TextView) findViewById(R.id.watchlist_text); + + if (cache.onWatchlist) { + buttonAdd.setVisibility(View.GONE); + buttonRemove.setVisibility(View.VISIBLE); + text.setText(R.string.cache_watchlist_on); + } else { + buttonAdd.setVisibility(View.VISIBLE); + buttonRemove.setVisibility(View.GONE); + text.setText(R.string.cache_watchlist_not_on); + } + } + + /** + * Handler, called when watchlist add or remove is done + */ + private Handler WatchlistHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + watchlistThread = null; + if (watchlistDialog != null) + watchlistDialog.dismiss(); + if (msg.what == -1) { + showToast(res.getString(R.string.err_watchlist_failed)); + } else { + updateWatchlistBox(); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.detail); + setTitle(res.getString(R.string.cache)); + + init(); + + // get parameters + final Bundle extras = getIntent().getExtras(); + final Uri uri = getIntent().getData(); + + // try to get data from extras + if (geocode == null && extras != null) { + geocode = extras.getString("geocode"); + name = extras.getString("name"); + guid = extras.getString("guid"); + } + + // try to get data from URI + if (geocode == null && guid == null && uri != null) { + String uriHost = uri.getHost().toLowerCase(); + String uriPath = uri.getPath().toLowerCase(); + String uriQuery = uri.getQuery(); + + if (uriQuery != null) { + Log.i(cgSettings.tag, "Opening URI: " + uriHost + uriPath + "?" + uriQuery); + } else { + Log.i(cgSettings.tag, "Opening URI: " + uriHost + uriPath); + } + + if (uriHost.contains("geocaching.com")) { + geocode = uri.getQueryParameter("wp"); + guid = uri.getQueryParameter("guid"); + + if (StringUtils.isNotBlank(geocode)) { + geocode = geocode.toUpperCase(); + guid = null; + } else if (StringUtils.isNotBlank(guid)) { + geocode = null; + guid = guid.toLowerCase(); + } else { + showToast(res.getString(R.string.err_detail_open)); + finish(); + return; + } + } else if (uriHost.contains("coord.info")) { + if (uriPath != null && uriPath.startsWith("/gc")) { + geocode = uriPath.substring(1).toUpperCase(); + } else { + showToast(res.getString(R.string.err_detail_open)); + finish(); + return; + } + } + } + + // no given data + if (geocode == null && guid == null) { + showToast(res.getString(R.string.err_detail_cache)); + finish(); + return; + } + + app.setAction(geocode); + + try { + if (StringUtils.isNotBlank(name)) { + waitDialog = ProgressDialog.show(this, name, res.getString(R.string.cache_dialog_loading_details), true); + } else if (StringUtils.isNotBlank(geocode)) { + waitDialog = ProgressDialog.show(this, geocode.toUpperCase(), res.getString(R.string.cache_dialog_loading_details), true); + } else { + waitDialog = ProgressDialog.show(this, res.getString(R.string.cache), res.getString(R.string.cache_dialog_loading_details), true); + } + waitDialog.setCancelable(true); + } catch (Exception e) { + // nothing, we lost the window + } + + disableResumeSetView = true; + threadCache = new loadCache(loadCacheHandler); + threadCache.start(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + setView(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + if (!disableResumeSetView) { + setView(); + } + disableResumeSetView = false; + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + super.onCreateContextMenu(menu, view, info); + final int viewId = view.getId(); + + if (viewId == R.id.author || viewId == R.id.value) { + if (viewId == R.id.author) { // Author of a log entry + contextMenuUser = ((TextView) view).getText().toString(); + } else if (viewId == R.id.value) { // The owner of the cache + if (StringUtils.isNotBlank(cache.ownerReal)) { + contextMenuUser = cache.ownerReal; + } else { + contextMenuUser = cache.owner; + } + } + + menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser); + menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden)); + menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found)); + menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser)); + } + if (viewId == R.id.map_preview) { + menu.setHeaderTitle(res.getString(R.string.cache_menu_navigate)); + addNavigationMenuItems(menu); + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + final int group = item.getGroupId(); + + if (group == R.id.author || group == R.id.value) { + final int id = item.getItemId(); + + if (id == 1) { + cgeocaches.startActivityCacheOwner(this, contextMenuUser); + return true; + } else if (id == 2) { + cgeocaches.startActivityCacheUser(this, contextMenuUser); + return true; + } else if (id == 3) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser)))); + + return true; + } + } + else { + return onOptionsItemSelected(item); + } + return false; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + if (cache != null && cache.coords != null) { + menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass + SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); + addNavigationMenuItems(subMenu); + } + + if (cache != null && cache.canBeAddedToCalendar()) { + menu.add(1, 11, 0, res.getString(R.string.cache_menu_event)).setIcon(android.R.drawable.ic_menu_agenda); // add event to calendar + } + addVisitMenu(menu, cache); + + if (cache != null && CollectionUtils.isNotEmpty(cache.spoilers)) { + menu.add(1, 5, 0, res.getString(R.string.cache_menu_spoilers)).setIcon(android.R.drawable.ic_menu_gallery); // spoiler images + } + + if (cache != null && cache.coords != null) { + menu.add(0, 10, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around + } + + if (cache != null && cache.canOpenInBrowser()) { + menu.add(1, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(android.R.drawable.ic_menu_info_details); // browser + } + menu.add(0, 12, 0, res.getString(R.string.cache_menu_share)).setIcon(android.R.drawable.ic_menu_share); // share cache + + return true; + } + + private void addNavigationMenuItems(final Menu menu) { + NavigationAppFactory.addMenuItems(menu, this, res); + GeneralAppsFactory.addMenuItems(menu, this, res, cache); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int menuItem = item.getItemId(); + + if (menuItem == 2) { + navigateTo(); + return true; + } else if (menuItem == MENU_LOG_VISIT) { + logVisit(); + return true; + } else if (menuItem == 5) { + showSpoilers(); + return true; + } else if (menuItem == 7) { + cache.openInBrowser(this); + return true; + } else if (menuItem == 10) { + cachesAround(); + return true; + } else if (menuItem == 11) { + addToCalendar(); + return true; + } else if (menuItem == 12) { + shareCache(); + return true; + } + if (NavigationAppFactory.onMenuItemSelected(item, geo, this, res, cache, searchId, null, null)) { + return true; + } + if (GeneralAppsFactory.onMenuItemSelected(item, this, cache)) { + return true; + } + + int logType = menuItem - MENU_LOG_VISIT_OFFLINE; + cache.logOffline(this, logType, settings, base); + return true; + } + + private void init() { + final DisplayMetrics dm = getResources().getDisplayMetrics(); + pixelRatio = dm.density; + + if (inflater == null) { + inflater = getLayoutInflater(); + } + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + if (searchId != null) { + cache = app.getCache(searchId); + if (cache != null && cache.geocode != null) { + geocode = cache.geocode; + } + } + + if (StringUtils.isNotBlank(geocode)) { + app.setAction(geocode); + } + } + + private void setView() { + RelativeLayout itemLayout; + TextView itemName; + TextView itemValue; + + if (searchId == null) { + return; + } + + cache = app.getCache(searchId); + + if (cache == null) { + if (waitDialog != null && waitDialog.isShowing()) + waitDialog.dismiss(); + + if (StringUtils.isNotBlank(geocode)) { + showToast(res.getString(R.string.err_detail_cache_find) + " " + geocode + "."); + } else { + geocode = null; + showToast(res.getString(R.string.err_detail_cache_find_some)); + } + + finish(); + return; + } + + try { + + if (geocode == null && StringUtils.isNotBlank(cache.geocode)) { + geocode = cache.geocode; + } + + if (guid == null && StringUtils.isNotBlank(cache.guid)) { guid = cache.guid; } - setTitle(cache.geocode.toUpperCase()); - - inflater = getLayoutInflater(); - - ScrollView scroll = (ScrollView) findViewById(R.id.details_list_box); - scroll.setVisibility(View.VISIBLE); - - LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); - detailsList.removeAllViews(); - - // actionbar icon, default myster< - ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) getResources().getDrawable(cgBase.getCacheIcon(cache.type)), null, null, null); - - // cache name (full name) - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_name)); - Spannable span = (new Spannable.Factory()).newSpannable(Html.fromHtml(cache.name).toString()); - if (cache.disabled || cache.archived) { // strike - span.setSpan(new StrikethroughSpan(), 0, span.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - itemValue.setText(span); - detailsList.addView(itemLayout); - - // cache type - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_type)); - - String size = ""; - if (StringUtils.isNotBlank(cache.size)) { - // don't show "not chosen" for events, that should be the normal case - if (!(cache.isEventCache() && cache.size.equals("not chosen"))) { - size = " (" + cache.size + ")"; - } - } - - if (cgBase.cacheTypesInv.containsKey(cache.type)) { // cache icon - itemValue.setText(cgBase.cacheTypesInv.get(cache.type) + size); - } else { - itemValue.setText(cgBase.cacheTypesInv.get("mystery") + size); - } - detailsList.addView(itemLayout); - - // gc-code - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_geocode)); - itemValue.setText(cache.geocode.toUpperCase()); - detailsList.addView(itemLayout); - - // cache state - if (cache.logOffline || cache.archived || cache.disabled || cache.members || cache.found) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_status)); - - StringBuilder state = new StringBuilder(); - if (cache.logOffline) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_offline_log)); - } - if (cache.found) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_found)); - } - if (cache.archived) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_archived)); - } - if (cache.disabled) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_disabled)); - } - if (cache.members) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_premium)); - } - - itemValue.setText(state.toString()); - detailsList.addView(itemLayout); - - state = null; - } - - // distance - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_distance)); - if (cache.distance != null) { - itemValue.setText("~" + base.getHumanDistance(cache.distance)); - } else { - itemValue.setText("--"); - } - detailsList.addView(itemLayout); - cacheDistance = itemValue; - - // difficulty - if (cache.difficulty != null && cache.difficulty > 0) { - addStarRating(detailsList, res.getString(R.string.cache_difficulty), cache.difficulty); - } - - // terrain - if (cache.terrain != null && cache.terrain > 0) { - addStarRating(detailsList, res.getString(R.string.cache_terrain), cache.terrain); - } - - // rating - if (cache.rating != null && cache.rating > 0) { - itemLayout = addStarRating(detailsList, res.getString(R.string.cache_rating), cache.rating); - if (cache.votes != null) { - final TextView itemAddition = (TextView)itemLayout.findViewById(R.id.addition); - itemAddition.setText("(" + cache.votes + ")"); - itemAddition.setVisibility(View.VISIBLE); - } - } - - // favourite count - if (cache.favouriteCnt != null) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_favourite)); - itemValue.setText(String.format("%d", cache.favouriteCnt) + "×"); - detailsList.addView(itemLayout); - } - - // cache author - if (StringUtils.isNotBlank(cache.owner) || StringUtils.isNotBlank(cache.ownerReal)) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_owner)); - if (StringUtils.isNotBlank(cache.owner)) { - itemValue.setText(Html.fromHtml(cache.owner), TextView.BufferType.SPANNABLE); - } else if (StringUtils.isNotBlank(cache.ownerReal)) { - itemValue.setText(Html.fromHtml(cache.ownerReal), TextView.BufferType.SPANNABLE); - } - itemValue.setOnClickListener(new userActions()); - detailsList.addView(itemLayout); - } - - // cache hidden - if (cache.hidden != null && cache.hidden.getTime() > 0) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - if (cache.type != null && (cache.type.equalsIgnoreCase("event") || cache.type.equalsIgnoreCase("mega") || cache.type.equalsIgnoreCase("cito"))) { - itemName.setText(res.getString(R.string.cache_event)); - } else { - itemName.setText(res.getString(R.string.cache_hidden)); - } - itemValue.setText(base.formatFullDate(cache.hidden.getTime())); - detailsList.addView(itemLayout); - } - - // cache location - if (StringUtils.isNotBlank(cache.location)) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_location)); - itemValue.setText(cache.location); - detailsList.addView(itemLayout); - } - - // cache coordinates - if (cache.coords != null) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_coordinates)); - itemValue.setText(cache.latitudeString + " | " + cache.longitudeString); - detailsList.addView(itemLayout); - } - - // cache attributes - if (CollectionUtils.isNotEmpty(cache.attributes)) { - - final LinearLayout attribBox = (LinearLayout) findViewById( - R.id.attributes_innerbox); - - // maximum width for attribute icons is screen width - paddings of parents - attributeBoxMaxWidth = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay().getWidth(); - ViewParent child = attribBox; - do { - if (child instanceof View) - attributeBoxMaxWidth = attributeBoxMaxWidth - ((View) child).getPaddingLeft() - - ((View) child).getPaddingRight(); - child = child.getParent(); - } while (child != null); - - // delete views holding description / icons - attributeDescriptionsLayout = null; - attributeIconsLayout = null; - - attribBox.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // toggle between attribute icons and descriptions - toggleAttributeDisplay(attribBox, attributeBoxMaxWidth); - } - } ); - - // icons or text? - // - // also show icons when noAttributeImagesFound == true. Explanation: - // 1. no icons could be found in the first invocation of this method - // 2. user refreshes cache from web - // 3. now this method is called again - // 4. attributeShowAsIcons is false but noAttributeImagesFound is true - // => try to show them now - if (attributesShowAsIcons || noAttributeIconsFound) { - showAttributeIcons(attribBox, attributeBoxMaxWidth); - } else { - showAttributeDescriptions(attribBox); - } - - findViewById(R.id.attributes_box).setVisibility(View.VISIBLE); - } - - // cache inventory - if (CollectionUtils.isNotEmpty(cache.inventory)) { - final LinearLayout inventBox = (LinearLayout) findViewById(R.id.inventory_box); - final TextView inventView = (TextView) findViewById(R.id.inventory); - - StringBuilder inventoryString = new StringBuilder(); - for (cgTrackable inventoryItem : cache.inventory) { - if (inventoryString.length() > 0) { - inventoryString.append('\n'); - } - // avoid HTML parsing where possible - if (inventoryItem.name.indexOf('<') >= 0 || inventoryItem.name.indexOf('&') >= 0 ) { - inventoryString.append(Html.fromHtml(inventoryItem.name).toString()); - } - else { - inventoryString.append(inventoryItem.name); - } - } - inventView.setText(inventoryString); - inventBox.setClickable(true); - inventBox.setOnClickListener(new selectTrackable()); - inventBox.setVisibility(View.VISIBLE); - } - - // offline use - final TextView offlineText = (TextView) findViewById(R.id.offline_text); - final Button offlineRefresh = (Button) findViewById(R.id.offline_refresh); - final Button offlineStore = (Button) findViewById(R.id.offline_store); - - if (cache.reason >= 1) { - Long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.detailedUpdate / (60 * 1000)); // minutes - - String ago = ""; - if (diff < 15) { - ago = res.getString(R.string.cache_offline_time_mins_few); - } else if (diff < 50) { - ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); - } else if (diff < 90) { - ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); - } else if (diff < (48 * 60)) { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); - } else { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); - } - - offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); - offlineRefresh.setOnClickListener(new storeCache()); - - offlineStore.setText(res.getString(R.string.cache_offline_drop)); - offlineStore.setClickable(true); - offlineStore.setOnClickListener(new dropCache()); - } else { - offlineText.setText(res.getString(R.string.cache_offline_not_ready)); - offlineRefresh.setOnClickListener(new refreshCache()); - - offlineStore.setText(res.getString(R.string.cache_offline_store)); - offlineStore.setClickable(true); - offlineStore.setOnClickListener(new storeCache()); - } - offlineRefresh.setVisibility(cache.supportsRefresh() ? View.VISIBLE : View.GONE); - offlineRefresh.setClickable(true); - - // cache personal note - if (StringUtils.isNotBlank(cache.personalNote)) { - ((LinearLayout) findViewById(R.id.personalnote_box)).setVisibility(View.VISIBLE); - - TextView personalNoteText = (TextView) findViewById(R.id.personalnote); - personalNoteText.setVisibility(View.VISIBLE); - personalNoteText.setText(cache.personalNote, TextView.BufferType.SPANNABLE); - personalNoteText.setMovementMethod(LinkMovementMethod.getInstance()); - } - - // cache short desc - if (StringUtils.isNotBlank(cache.shortdesc)) { - ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); - - TextView descView = (TextView) findViewById(R.id.shortdesc); - descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(cache.shortdesc.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), null), TextView.BufferType.SPANNABLE); - descView.setMovementMethod(LinkMovementMethod.getInstance()); - } - - // cache long desc - if (longDescDisplayed) { - parseLongDescription(); - - if (StringUtils.isNotBlank(longDesc)) { - ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); - - TextView descView = (TextView) findViewById(R.id.description); - descView.setVisibility(View.VISIBLE); - descView.setText(longDesc, TextView.BufferType.SPANNABLE); - descView.setMovementMethod(LinkMovementMethod.getInstance()); - - Button showDesc = (Button) findViewById(R.id.show_description); - showDesc.setVisibility(View.GONE); - showDesc.setOnTouchListener(null); - showDesc.setOnClickListener(null); - } - } else if (longDescDisplayed == false && StringUtils.isNotBlank(cache.description)) { - ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); - - Button showDesc = (Button) findViewById(R.id.show_description); - showDesc.setVisibility(View.VISIBLE); - showDesc.setOnClickListener(new View.OnClickListener() { - public void onClick(View arg0) { - loadLongDesc(); - } - }); - } - - // watchlist - Button buttonWatchlistAdd = (Button) findViewById(R.id.add_to_watchlist); - Button buttonWatchlistRemove = (Button) findViewById(R.id.remove_from_watchlist); - buttonWatchlistAdd.setOnClickListener(new AddToWatchlistClickListener()); - buttonWatchlistRemove.setOnClickListener(new RemoveFromWatchlistClickListener()); - updateWatchlistBox(); - - // waypoints - LinearLayout waypoints = (LinearLayout) findViewById(R.id.waypoints); - waypoints.removeAllViews(); - - if (CollectionUtils.isNotEmpty(cache.waypoints)) { - LinearLayout waypointView; - - // sort waypoints: PP, Sx, FI, OWN - List<cgWaypoint> sortedWaypoints = new ArrayList<cgWaypoint>(cache.waypoints); - Collections.sort(sortedWaypoints, new Comparator<cgWaypoint>() { - - @Override - public int compare(cgWaypoint wayPoint1, cgWaypoint wayPoint2) { - - return order(wayPoint1) - order(wayPoint2); - } - - private int order(cgWaypoint waypoint) { - if (StringUtils.isEmpty(waypoint.prefix)) { - return 0; - } - // check only the first character. sometimes there are inconsistencies like FI or FN for the FINAL - char firstLetter = Character.toUpperCase(waypoint.prefix.charAt(0)); - switch (firstLetter) { - case 'P' : return -100; // parking - case 'S' : { // stage N - try { - Integer stageNumber = Integer.valueOf(waypoint.prefix.substring(1)); - return stageNumber; - } catch (NumberFormatException e) { - // nothing - } - return 0; - } - case 'F' : return 1000; // final - case 'O' : return 10000; // own - } - return 0; - }}); - - for (cgWaypoint wpt : sortedWaypoints) { - waypointView = (LinearLayout) inflater.inflate(R.layout.waypoint_item, null); - final TextView identification = (TextView) waypointView.findViewById(R.id.identification); - - ((TextView) waypointView.findViewById(R.id.type)).setText(cgBase.waypointTypes.get(wpt.type)); - if (wpt.prefix.equalsIgnoreCase("OWN") == false) { - identification.setText(wpt.prefix.trim() + "/" + wpt.lookup.trim()); - } else { - identification.setText(res.getString(R.string.waypoint_custom)); - } - - TextView nameView = (TextView) waypointView.findViewById(R.id.name); - if (StringUtils.isBlank(wpt.name)) { - nameView.setText(cgBase.formatCoords(wpt.coords, true)); - } else { - // avoid HTML parsing - if (wpt.name.indexOf('<') >= 0 || wpt.name.indexOf('&') >= 0) { - nameView.setText(Html.fromHtml(wpt.name.trim()), TextView.BufferType.SPANNABLE); - } - else { - nameView.setText(wpt.name.trim()); - } - } - wpt.setIcon(res, base, nameView); - - // avoid HTML parsing - if (wpt.note.indexOf('<') >= 0 || wpt.note.indexOf('&') >= 0) { - ((TextView) waypointView.findViewById(R.id.note)).setText(Html.fromHtml(wpt.note.trim()), TextView.BufferType.SPANNABLE); - } - else { - ((TextView) waypointView.findViewById(R.id.note)).setText(wpt.note.trim()); - } - - waypointView.setOnClickListener(new waypointInfo(wpt.id)); - - waypoints.addView(waypointView); - } - } - - Button addWaypoint = (Button) findViewById(R.id.add_waypoint); - addWaypoint.setClickable(true); - addWaypoint.setOnClickListener(new addWaypoint()); - - // cache hint - if (StringUtils.isNotBlank(cache.hint)) { - ((LinearLayout) findViewById(R.id.hint_box)).setVisibility(View.VISIBLE); - TextView hintView = ((TextView) findViewById(R.id.hint)); - hintView.setText(cgBase.rot13(cache.hint.trim())); - hintView.setClickable(true); - hintView.setOnClickListener(new codeHint()); - } else { - ((LinearLayout) findViewById(R.id.hint_box)).setVisibility(View.GONE); - TextView hintView = ((TextView) findViewById(R.id.hint)); - hintView.setClickable(false); - hintView.setOnClickListener(null); - } - - if (geo != null && geo.coordsNow != null && cache != null && cache.coords != null) { - cacheDistance.setText(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); - cacheDistance.bringToFront(); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeodetail.setView: " + e.toString()); - } - - if (waitDialog != null && waitDialog.isShowing()) waitDialog.dismiss(); - if (storeDialog != null && storeDialog.isShowing()) storeDialog.dismiss(); - if (dropDialog != null && dropDialog.isShowing()) dropDialog.dismiss(); - if (refreshDialog != null && refreshDialog.isShowing()) refreshDialog.dismiss(); - - displayLogs(); - - if (geo != null) geoUpdate.updateLoc(geo); - } - - private void parseLongDescription() { - if (longDesc == null && cache != null && cache.description != null) { - longDesc = Html.fromHtml(cache.description.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), new UnknownTagsHandler()); - } - } - - private RelativeLayout addStarRating(final LinearLayout detailsList, final String name, final float value) { - RelativeLayout itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); - TextView itemName = (TextView) itemLayout.findViewById(R.id.name); - TextView itemValue = (TextView) itemLayout.findViewById(R.id.value); - LinearLayout itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); - - itemName.setText(name); - itemValue.setText(String.format(Locale.getDefault(), "%.1f", value) + ' ' + res.getString(R.string.cache_rating_of) + " 5"); - for (int i = 0; i <= 4; i++) { - ImageView star = (ImageView) inflater.inflate(R.layout.star, null); - if ((value - i) >= 1.0) { - star.setImageResource(R.drawable.star_on); - } else if ((value - i) > 0.0) { - star.setImageResource(R.drawable.star_half); - } else { - star.setImageResource(R.drawable.star_off); - } - itemStars.addView(star, (1 + i)); - } - detailsList.addView(itemLayout); - return itemLayout; - } - - private void displayLogs() { - // cache logs - TextView textView = (TextView) findViewById(R.id.logcount); - int logCounter = 0; - if (cache != null && cache.logCounts != null) { - final StringBuffer buff = new StringBuffer(); - buff.append(res.getString(R.string.cache_log_types)); - buff.append(": "); - - // sort the log counts by type id ascending. that way the FOUND, DNF log types are the first and most visible ones - List<Entry<Integer, Integer>> sortedLogCounts = new ArrayList<Entry<Integer,Integer>>(); - sortedLogCounts.addAll(cache.logCounts.entrySet()); - Collections.sort(sortedLogCounts, new Comparator<Entry<Integer, Integer>>() { - - @Override - public int compare(Entry<Integer, Integer> logCountItem1, - Entry<Integer, Integer> logCountItem2) { - return logCountItem1.getKey().compareTo(logCountItem2.getKey()); - }}); - for (Entry<Integer, Integer> pair : sortedLogCounts) { - int logTypeId = pair.getKey().intValue(); - String logTypeLabel = cgBase.logTypes1.get(logTypeId); - // it may happen that the label is unknown -> then avoid any output for this type - if (logTypeLabel != null) { - if (logCounter > 0) { - buff.append(", "); - } - buff.append(pair.getValue().intValue()); - buff.append("× "); - buff.append(logTypeLabel); - } - logCounter ++; - } - textView.setText(buff.toString()); - } - // it may happen, that the logCounts map is available, but every log type has zero counts, - // therefore check again for the number of counted logs - if (logCounter > 0) { - textView.setVisibility(View.VISIBLE); - } else { - textView.setVisibility(View.GONE); - } - - // cache logs - LinearLayout listView = (LinearLayout) findViewById(R.id.log_list); - listView.removeAllViews(); - - RelativeLayout rowView; - - if (cache != null && cache.logs != null) { - for (cgLog log : cache.logs) { - rowView = (RelativeLayout) inflater.inflate(R.layout.log_item, null); - - if (log.date > 0) { - ((TextView) rowView.findViewById(R.id.added)).setText(base.formatShortDate(log.date)); - } else { - ((TextView) rowView.findViewById(R.id.added)).setVisibility(View.GONE); - } - - if (cgBase.logTypes1.containsKey(log.type)) { - ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(log.type)); - } else { - ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(4)); // note if type is unknown - } - // avoid parsing HTML if not necessary - if (log.author.indexOf('<') >= 0 || log.author.indexOf('&') >= 0) { - ((TextView) rowView.findViewById(R.id.author)).setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE); - } - else { - ((TextView) rowView.findViewById(R.id.author)).setText(log.author); - } - - if (log.found == -1) { - ((TextView) rowView.findViewById(R.id.count)).setVisibility(View.GONE); - } else if (log.found == 0) { - ((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_no)); - } else if (log.found == 1) { - ((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_one)); - } else { - ((TextView) rowView.findViewById(R.id.count)).setText(log.found + " " + res.getString(R.string.cache_count_more)); - } - // avoid parsing HTML if not necessary - if (log.log.indexOf('<') >= 0 || log.log.indexOf('&') >= 0) { - ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(this, null, false, cache.reason, false), null), TextView.BufferType.SPANNABLE); - } - else { - ((TextView) rowView.findViewById(R.id.log)).setText(log.log); - } - // add LogImages - LinearLayout logLayout = (LinearLayout) rowView.findViewById(R.id.log_layout); - - if ((log.logImages != null) && (!log.logImages.isEmpty())) { - for (int i_img_cnt = 0; i_img_cnt < log.logImages.size(); i_img_cnt++) { - String img_title = log.logImages.get(i_img_cnt).title; - if (img_title.equals("")) { - img_title = res.getString(R.string.cache_log_image_default_title); - } - final String title = img_title; - final String url = log.logImages.get(i_img_cnt).url; - LinearLayout log_imgView = (LinearLayout) inflater.inflate(R.layout.log_img, null); - TextView log_img_title = (TextView)log_imgView.findViewById(R.id.title); - log_img_title.setText(title); - log_img_title.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent logImgIntent = new Intent(cgeodetail.this, cgeoimages.class); - logImgIntent.putExtra("geocode", geocode.toUpperCase()); - logImgIntent.putExtra("type", cgeoimages.LOG_IMAGE); - logImgIntent.putExtra("title", title); - logImgIntent.putExtra("url", url); - startActivity(logImgIntent); - } - }); - logLayout.addView(log_imgView); - } - } - - // Add colored mark - final ImageView logMark = (ImageView) rowView.findViewById(R.id.log_mark); - if (log.type == cgBase.LOG_FOUND_IT - || log.type == cgBase.LOG_WEBCAM_PHOTO_TAKEN - || log.type == cgBase.LOG_ATTENDED) - { - logMark.setImageResource(R.drawable.mark_green); - } - else if (log.type == cgBase.LOG_PUBLISH_LISTING + setTitle(cache.geocode.toUpperCase()); + + inflater = getLayoutInflater(); + + ScrollView scroll = (ScrollView) findViewById(R.id.details_list_box); + scroll.setVisibility(View.VISIBLE); + + LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); + detailsList.removeAllViews(); + + // actionbar icon, default myster< + ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) getResources().getDrawable(cgBase.getCacheIcon(cache.type)), null, null, null); + + // cache name (full name) + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_name)); + Spannable span = (new Spannable.Factory()).newSpannable(Html.fromHtml(cache.name).toString()); + if (cache.disabled || cache.archived) { // strike + span.setSpan(new StrikethroughSpan(), 0, span.toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + itemValue.setText(span); + detailsList.addView(itemLayout); + + // cache type + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_type)); + + String size = ""; + if (StringUtils.isNotBlank(cache.size)) { + // don't show "not chosen" for events, that should be the normal case + if (!(cache.isEventCache() && cache.size.equals("not chosen"))) { + size = " (" + cache.size + ")"; + } + } + + if (cgBase.cacheTypesInv.containsKey(cache.type)) { // cache icon + itemValue.setText(cgBase.cacheTypesInv.get(cache.type) + size); + } else { + itemValue.setText(cgBase.cacheTypesInv.get("mystery") + size); + } + detailsList.addView(itemLayout); + + // gc-code + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_geocode)); + itemValue.setText(cache.geocode.toUpperCase()); + detailsList.addView(itemLayout); + + // cache state + if (cache.logOffline || cache.archived || cache.disabled || cache.members || cache.found) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_status)); + + StringBuilder state = new StringBuilder(); + if (cache.logOffline) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_offline_log)); + } + if (cache.found) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_found)); + } + if (cache.archived) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_archived)); + } + if (cache.disabled) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_disabled)); + } + if (cache.members) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_premium)); + } + + itemValue.setText(state.toString()); + detailsList.addView(itemLayout); + + state = null; + } + + // distance + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_distance)); + if (cache.distance != null) { + itemValue.setText("~" + base.getHumanDistance(cache.distance)); + } else { + itemValue.setText("--"); + } + detailsList.addView(itemLayout); + cacheDistance = itemValue; + + // difficulty + if (cache.difficulty != null && cache.difficulty > 0) { + addStarRating(detailsList, res.getString(R.string.cache_difficulty), cache.difficulty); + } + + // terrain + if (cache.terrain != null && cache.terrain > 0) { + addStarRating(detailsList, res.getString(R.string.cache_terrain), cache.terrain); + } + + // rating + if (cache.rating != null && cache.rating > 0) { + itemLayout = addStarRating(detailsList, res.getString(R.string.cache_rating), cache.rating); + if (cache.votes != null) { + final TextView itemAddition = (TextView) itemLayout.findViewById(R.id.addition); + itemAddition.setText("(" + cache.votes + ")"); + itemAddition.setVisibility(View.VISIBLE); + } + } + + // favourite count + if (cache.favouriteCnt != null) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_favourite)); + itemValue.setText(String.format("%d", cache.favouriteCnt) + "×"); + detailsList.addView(itemLayout); + } + + // cache author + if (StringUtils.isNotBlank(cache.owner) || StringUtils.isNotBlank(cache.ownerReal)) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_owner)); + if (StringUtils.isNotBlank(cache.owner)) { + itemValue.setText(Html.fromHtml(cache.owner), TextView.BufferType.SPANNABLE); + } else if (StringUtils.isNotBlank(cache.ownerReal)) { + itemValue.setText(Html.fromHtml(cache.ownerReal), TextView.BufferType.SPANNABLE); + } + itemValue.setOnClickListener(new userActions()); + detailsList.addView(itemLayout); + } + + // cache hidden + if (cache.hidden != null && cache.hidden.getTime() > 0) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + if (cache.type != null && (cache.type.equalsIgnoreCase("event") || cache.type.equalsIgnoreCase("mega") || cache.type.equalsIgnoreCase("cito"))) { + itemName.setText(res.getString(R.string.cache_event)); + } else { + itemName.setText(res.getString(R.string.cache_hidden)); + } + itemValue.setText(base.formatFullDate(cache.hidden.getTime())); + detailsList.addView(itemLayout); + } + + // cache location + if (StringUtils.isNotBlank(cache.location)) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_location)); + itemValue.setText(cache.location); + detailsList.addView(itemLayout); + } + + // cache coordinates + if (cache.coords != null) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_coordinates)); + itemValue.setText(cache.latitudeString + " | " + cache.longitudeString); + detailsList.addView(itemLayout); + } + + // cache attributes + if (CollectionUtils.isNotEmpty(cache.attributes)) { + + final LinearLayout attribBox = (LinearLayout) findViewById( + R.id.attributes_innerbox); + + // maximum width for attribute icons is screen width - paddings of parents + attributeBoxMaxWidth = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay().getWidth(); + ViewParent child = attribBox; + do { + if (child instanceof View) + attributeBoxMaxWidth = attributeBoxMaxWidth - ((View) child).getPaddingLeft() + - ((View) child).getPaddingRight(); + child = child.getParent(); + } while (child != null); + + // delete views holding description / icons + attributeDescriptionsLayout = null; + attributeIconsLayout = null; + + attribBox.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // toggle between attribute icons and descriptions + toggleAttributeDisplay(attribBox, attributeBoxMaxWidth); + } + }); + + // icons or text? + // + // also show icons when noAttributeImagesFound == true. Explanation: + // 1. no icons could be found in the first invocation of this method + // 2. user refreshes cache from web + // 3. now this method is called again + // 4. attributeShowAsIcons is false but noAttributeImagesFound is true + // => try to show them now + if (attributesShowAsIcons || noAttributeIconsFound) { + showAttributeIcons(attribBox, attributeBoxMaxWidth); + } else { + showAttributeDescriptions(attribBox); + } + + findViewById(R.id.attributes_box).setVisibility(View.VISIBLE); + } + + // cache inventory + if (CollectionUtils.isNotEmpty(cache.inventory)) { + final LinearLayout inventBox = (LinearLayout) findViewById(R.id.inventory_box); + final TextView inventView = (TextView) findViewById(R.id.inventory); + + StringBuilder inventoryString = new StringBuilder(); + for (cgTrackable inventoryItem : cache.inventory) { + if (inventoryString.length() > 0) { + inventoryString.append('\n'); + } + // avoid HTML parsing where possible + if (inventoryItem.name.indexOf('<') >= 0 || inventoryItem.name.indexOf('&') >= 0) { + inventoryString.append(Html.fromHtml(inventoryItem.name).toString()); + } + else { + inventoryString.append(inventoryItem.name); + } + } + inventView.setText(inventoryString); + inventBox.setClickable(true); + inventBox.setOnClickListener(new selectTrackable()); + inventBox.setVisibility(View.VISIBLE); + } + + // offline use + final TextView offlineText = (TextView) findViewById(R.id.offline_text); + final Button offlineRefresh = (Button) findViewById(R.id.offline_refresh); + final Button offlineStore = (Button) findViewById(R.id.offline_store); + + if (cache.reason >= 1) { + Long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.detailedUpdate / (60 * 1000)); // minutes + + String ago = ""; + if (diff < 15) { + ago = res.getString(R.string.cache_offline_time_mins_few); + } else if (diff < 50) { + ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); + } else if (diff < 90) { + ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); + } else if (diff < (48 * 60)) { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); + } else { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); + } + + offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); + offlineRefresh.setOnClickListener(new storeCache()); + + offlineStore.setText(res.getString(R.string.cache_offline_drop)); + offlineStore.setClickable(true); + offlineStore.setOnClickListener(new dropCache()); + } else { + offlineText.setText(res.getString(R.string.cache_offline_not_ready)); + offlineRefresh.setOnClickListener(new refreshCache()); + + offlineStore.setText(res.getString(R.string.cache_offline_store)); + offlineStore.setClickable(true); + offlineStore.setOnClickListener(new storeCache()); + } + offlineRefresh.setVisibility(cache.supportsRefresh() ? View.VISIBLE : View.GONE); + offlineRefresh.setClickable(true); + + // cache personal note + if (StringUtils.isNotBlank(cache.personalNote)) { + ((LinearLayout) findViewById(R.id.personalnote_box)).setVisibility(View.VISIBLE); + + TextView personalNoteText = (TextView) findViewById(R.id.personalnote); + personalNoteText.setVisibility(View.VISIBLE); + personalNoteText.setText(cache.personalNote, TextView.BufferType.SPANNABLE); + personalNoteText.setMovementMethod(LinkMovementMethod.getInstance()); + } + + // cache short desc + if (StringUtils.isNotBlank(cache.shortdesc)) { + ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); + + TextView descView = (TextView) findViewById(R.id.shortdesc); + descView.setVisibility(View.VISIBLE); + descView.setText(Html.fromHtml(cache.shortdesc.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), null), TextView.BufferType.SPANNABLE); + descView.setMovementMethod(LinkMovementMethod.getInstance()); + } + + // cache long desc + if (longDescDisplayed) { + parseLongDescription(); + + if (StringUtils.isNotBlank(longDesc)) { + ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); + + TextView descView = (TextView) findViewById(R.id.description); + descView.setVisibility(View.VISIBLE); + descView.setText(longDesc, TextView.BufferType.SPANNABLE); + descView.setMovementMethod(LinkMovementMethod.getInstance()); + + Button showDesc = (Button) findViewById(R.id.show_description); + showDesc.setVisibility(View.GONE); + showDesc.setOnTouchListener(null); + showDesc.setOnClickListener(null); + } + } else if (longDescDisplayed == false && StringUtils.isNotBlank(cache.description)) { + ((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE); + + Button showDesc = (Button) findViewById(R.id.show_description); + showDesc.setVisibility(View.VISIBLE); + showDesc.setOnClickListener(new View.OnClickListener() { + public void onClick(View arg0) { + loadLongDesc(); + } + }); + } + + // watchlist + Button buttonWatchlistAdd = (Button) findViewById(R.id.add_to_watchlist); + Button buttonWatchlistRemove = (Button) findViewById(R.id.remove_from_watchlist); + buttonWatchlistAdd.setOnClickListener(new AddToWatchlistClickListener()); + buttonWatchlistRemove.setOnClickListener(new RemoveFromWatchlistClickListener()); + updateWatchlistBox(); + + // waypoints + LinearLayout waypoints = (LinearLayout) findViewById(R.id.waypoints); + waypoints.removeAllViews(); + + if (CollectionUtils.isNotEmpty(cache.waypoints)) { + LinearLayout waypointView; + + // sort waypoints: PP, Sx, FI, OWN + List<cgWaypoint> sortedWaypoints = new ArrayList<cgWaypoint>(cache.waypoints); + Collections.sort(sortedWaypoints, new Comparator<cgWaypoint>() { + + @Override + public int compare(cgWaypoint wayPoint1, cgWaypoint wayPoint2) { + + return order(wayPoint1) - order(wayPoint2); + } + + private int order(cgWaypoint waypoint) { + if (StringUtils.isEmpty(waypoint.prefix)) { + return 0; + } + // check only the first character. sometimes there are inconsistencies like FI or FN for the FINAL + char firstLetter = Character.toUpperCase(waypoint.prefix.charAt(0)); + switch (firstLetter) { + case 'P': + return -100; // parking + case 'S': { // stage N + try { + Integer stageNumber = Integer.valueOf(waypoint.prefix.substring(1)); + return stageNumber; + } catch (NumberFormatException e) { + // nothing + } + return 0; + } + case 'F': + return 1000; // final + case 'O': + return 10000; // own + } + return 0; + } + }); + + for (cgWaypoint wpt : sortedWaypoints) { + waypointView = (LinearLayout) inflater.inflate(R.layout.waypoint_item, null); + final TextView identification = (TextView) waypointView.findViewById(R.id.identification); + + ((TextView) waypointView.findViewById(R.id.type)).setText(cgBase.waypointTypes.get(wpt.type)); + if (wpt.prefix.equalsIgnoreCase("OWN") == false) { + identification.setText(wpt.prefix.trim() + "/" + wpt.lookup.trim()); + } else { + identification.setText(res.getString(R.string.waypoint_custom)); + } + + TextView nameView = (TextView) waypointView.findViewById(R.id.name); + if (StringUtils.isBlank(wpt.name)) { + nameView.setText(cgBase.formatCoords(wpt.coords, true)); + } else { + // avoid HTML parsing + if (wpt.name.indexOf('<') >= 0 || wpt.name.indexOf('&') >= 0) { + nameView.setText(Html.fromHtml(wpt.name.trim()), TextView.BufferType.SPANNABLE); + } + else { + nameView.setText(wpt.name.trim()); + } + } + wpt.setIcon(res, base, nameView); + + // avoid HTML parsing + if (wpt.note.indexOf('<') >= 0 || wpt.note.indexOf('&') >= 0) { + ((TextView) waypointView.findViewById(R.id.note)).setText(Html.fromHtml(wpt.note.trim()), TextView.BufferType.SPANNABLE); + } + else { + ((TextView) waypointView.findViewById(R.id.note)).setText(wpt.note.trim()); + } + + waypointView.setOnClickListener(new waypointInfo(wpt.id)); + + waypoints.addView(waypointView); + } + } + + Button addWaypoint = (Button) findViewById(R.id.add_waypoint); + addWaypoint.setClickable(true); + addWaypoint.setOnClickListener(new addWaypoint()); + + // cache hint + if (StringUtils.isNotBlank(cache.hint)) { + ((LinearLayout) findViewById(R.id.hint_box)).setVisibility(View.VISIBLE); + TextView hintView = ((TextView) findViewById(R.id.hint)); + hintView.setText(cgBase.rot13(cache.hint.trim())); + hintView.setClickable(true); + hintView.setOnClickListener(new codeHint()); + } else { + ((LinearLayout) findViewById(R.id.hint_box)).setVisibility(View.GONE); + TextView hintView = ((TextView) findViewById(R.id.hint)); + hintView.setClickable(false); + hintView.setOnClickListener(null); + } + + if (geo != null && geo.coordsNow != null && cache != null && cache.coords != null) { + cacheDistance.setText(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); + cacheDistance.bringToFront(); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeodetail.setView: " + e.toString()); + } + + if (waitDialog != null && waitDialog.isShowing()) + waitDialog.dismiss(); + if (storeDialog != null && storeDialog.isShowing()) + storeDialog.dismiss(); + if (dropDialog != null && dropDialog.isShowing()) + dropDialog.dismiss(); + if (refreshDialog != null && refreshDialog.isShowing()) + refreshDialog.dismiss(); + + displayLogs(); + + if (geo != null) + geoUpdate.updateLoc(geo); + } + + private void parseLongDescription() { + if (longDesc == null && cache != null && cache.description != null) { + longDesc = Html.fromHtml(cache.description.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), new UnknownTagsHandler()); + } + } + + private RelativeLayout addStarRating(final LinearLayout detailsList, final String name, final float value) { + RelativeLayout itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); + TextView itemName = (TextView) itemLayout.findViewById(R.id.name); + TextView itemValue = (TextView) itemLayout.findViewById(R.id.value); + LinearLayout itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); + + itemName.setText(name); + itemValue.setText(String.format(Locale.getDefault(), "%.1f", value) + ' ' + res.getString(R.string.cache_rating_of) + " 5"); + for (int i = 0; i <= 4; i++) { + ImageView star = (ImageView) inflater.inflate(R.layout.star, null); + if ((value - i) >= 1.0) { + star.setImageResource(R.drawable.star_on); + } else if ((value - i) > 0.0) { + star.setImageResource(R.drawable.star_half); + } else { + star.setImageResource(R.drawable.star_off); + } + itemStars.addView(star, (1 + i)); + } + detailsList.addView(itemLayout); + return itemLayout; + } + + private void displayLogs() { + // cache logs + TextView textView = (TextView) findViewById(R.id.logcount); + int logCounter = 0; + if (cache != null && cache.logCounts != null) { + final StringBuffer buff = new StringBuffer(); + buff.append(res.getString(R.string.cache_log_types)); + buff.append(": "); + + // sort the log counts by type id ascending. that way the FOUND, DNF log types are the first and most visible ones + List<Entry<Integer, Integer>> sortedLogCounts = new ArrayList<Entry<Integer, Integer>>(); + sortedLogCounts.addAll(cache.logCounts.entrySet()); + Collections.sort(sortedLogCounts, new Comparator<Entry<Integer, Integer>>() { + + @Override + public int compare(Entry<Integer, Integer> logCountItem1, + Entry<Integer, Integer> logCountItem2) { + return logCountItem1.getKey().compareTo(logCountItem2.getKey()); + } + }); + for (Entry<Integer, Integer> pair : sortedLogCounts) { + int logTypeId = pair.getKey().intValue(); + String logTypeLabel = cgBase.logTypes1.get(logTypeId); + // it may happen that the label is unknown -> then avoid any output for this type + if (logTypeLabel != null) { + if (logCounter > 0) { + buff.append(", "); + } + buff.append(pair.getValue().intValue()); + buff.append("× "); + buff.append(logTypeLabel); + } + logCounter++; + } + textView.setText(buff.toString()); + } + // it may happen, that the logCounts map is available, but every log type has zero counts, + // therefore check again for the number of counted logs + if (logCounter > 0) { + textView.setVisibility(View.VISIBLE); + } else { + textView.setVisibility(View.GONE); + } + + // cache logs + LinearLayout listView = (LinearLayout) findViewById(R.id.log_list); + listView.removeAllViews(); + + RelativeLayout rowView; + + if (cache != null && cache.logs != null) { + for (cgLog log : cache.logs) { + rowView = (RelativeLayout) inflater.inflate(R.layout.log_item, null); + + if (log.date > 0) { + ((TextView) rowView.findViewById(R.id.added)).setText(base.formatShortDate(log.date)); + } else { + ((TextView) rowView.findViewById(R.id.added)).setVisibility(View.GONE); + } + + if (cgBase.logTypes1.containsKey(log.type)) { + ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(log.type)); + } else { + ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(4)); // note if type is unknown + } + // avoid parsing HTML if not necessary + if (log.author.indexOf('<') >= 0 || log.author.indexOf('&') >= 0) { + ((TextView) rowView.findViewById(R.id.author)).setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE); + } + else { + ((TextView) rowView.findViewById(R.id.author)).setText(log.author); + } + + if (log.found == -1) { + ((TextView) rowView.findViewById(R.id.count)).setVisibility(View.GONE); + } else if (log.found == 0) { + ((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_no)); + } else if (log.found == 1) { + ((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_one)); + } else { + ((TextView) rowView.findViewById(R.id.count)).setText(log.found + " " + res.getString(R.string.cache_count_more)); + } + // avoid parsing HTML if not necessary + if (log.log.indexOf('<') >= 0 || log.log.indexOf('&') >= 0) { + ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(this, null, false, cache.reason, false), null), TextView.BufferType.SPANNABLE); + } + else { + ((TextView) rowView.findViewById(R.id.log)).setText(log.log); + } + // add LogImages + LinearLayout logLayout = (LinearLayout) rowView.findViewById(R.id.log_layout); + + if ((log.logImages != null) && (!log.logImages.isEmpty())) { + for (int i_img_cnt = 0; i_img_cnt < log.logImages.size(); i_img_cnt++) { + String img_title = log.logImages.get(i_img_cnt).title; + if (img_title.equals("")) { + img_title = res.getString(R.string.cache_log_image_default_title); + } + final String title = img_title; + final String url = log.logImages.get(i_img_cnt).url; + LinearLayout log_imgView = (LinearLayout) inflater.inflate(R.layout.log_img, null); + TextView log_img_title = (TextView) log_imgView.findViewById(R.id.title); + log_img_title.setText(title); + log_img_title.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent logImgIntent = new Intent(cgeodetail.this, cgeoimages.class); + logImgIntent.putExtra("geocode", geocode.toUpperCase()); + logImgIntent.putExtra("type", cgeoimages.LOG_IMAGE); + logImgIntent.putExtra("title", title); + logImgIntent.putExtra("url", url); + startActivity(logImgIntent); + } + }); + logLayout.addView(log_imgView); + } + } + + // Add colored mark + final ImageView logMark = (ImageView) rowView.findViewById(R.id.log_mark); + if (log.type == cgBase.LOG_FOUND_IT + || log.type == cgBase.LOG_WEBCAM_PHOTO_TAKEN + || log.type == cgBase.LOG_ATTENDED) + { + logMark.setImageResource(R.drawable.mark_green); + } + else if (log.type == cgBase.LOG_PUBLISH_LISTING || log.type == cgBase.LOG_ENABLE_LISTING || log.type == cgBase.LOG_OWNER_MAINTENANCE) { logMark.setImageResource(R.drawable.mark_green_more); } - else if (log.type == cgBase.LOG_DIDNT_FIND_IT - || log.type == cgBase.LOG_NEEDS_MAINTENANCE - || log.type == cgBase.LOG_NEEDS_ARCHIVE) - { - logMark.setImageResource(R.drawable.mark_red); - } - else if (log.type == cgBase.LOG_TEMP_DISABLE_LISTING - || log.type == cgBase.LOG_ARCHIVE) - { - logMark.setImageResource(R.drawable.mark_red_more); - } - else - { - logMark.setVisibility(View.GONE); - } - - ((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions()); - ((TextView) logLayout.findViewById(R.id.log)).setOnClickListener(new decryptLog()); - - listView.addView(rowView); - } - - if (cache.logs.size() > 0) { - ((LinearLayout) findViewById(R.id.log_box)).setVisibility(View.VISIBLE); - } - } - } - - private class loadCache extends Thread { - - private Handler handler = null; - - public loadCache(Handler handlerIn) { - handler = handlerIn; - - if (geocode == null && guid == null) { - showToast(res.getString(R.string.err_detail_cache_forgot)); - - finish(); - return; - } - } - - @Override - public void run() { - Map<String, String> params = new HashMap<String, String>(); - if (StringUtils.isNotBlank(geocode)) { - params.put("geocode", geocode); - } else if (StringUtils.isNotBlank(guid)) { - params.put("guid", guid); - } else { - return; - } - - searchId = base.searchByGeocode(params, 0, false); - - handler.sendMessage(new Message()); - } - } - - private class loadMapPreview extends Thread { - private Handler handler = null; - - public loadMapPreview(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - if (cache == null || cache.coords == null) { - return; - } - - BitmapDrawable image = null; - - try { - final String latlonMap = String.format((Locale) null, "%.6f", cache.coords.getLatitude()) + "," + - String.format((Locale) null, "%.6f", cache.coords.getLongitude()); - final Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - - int width = display.getWidth(); - int height = (int) (90 * pixelRatio); - - String markerUrl = cgBase.urlencode_rfc3986("http://cgeo.carnero.cc/_markers/my_location_mdpi.png"); - - cgHtmlImg mapGetter = new cgHtmlImg(cgeodetail.this, cache.geocode, false, 0, false); - image = mapGetter.getDrawable("http://maps.google.com/maps/api/staticmap?center=" + latlonMap + "&zoom=15&size=" + width + "x" + height + "&maptype=terrain&markers=icon%3A" + markerUrl + "%7C" + latlonMap + "&sensor=false"); - Message message = handler.obtainMessage(0, image); - handler.sendMessage(message); - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeodetail.loadMapPreview.run: " + e.toString()); - } - } - } - - public void loadLongDesc() { - if (waitDialog == null || waitDialog.isShowing() == false) { - descDialog = ProgressDialog.show(this, null, res.getString(R.string.cache_dialog_loading_description), true); - descDialog.setCancelable(true); - } - - threadLongDesc = new loadLongDesc(loadDescriptionHandler); - threadLongDesc.start(); - } - - private class loadLongDesc extends Thread { - private Handler handler = null; - - public loadLongDesc(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - if (cache == null || cache.description == null || handler == null) { - return; - } - parseLongDescription(); - handler.sendMessage(new Message()); - } - } - - public List<cgCoord> getCoordinates() { - cgCoord coords = null; - List<cgCoord> coordinates = new ArrayList<cgCoord>(); - - try { - // cache - coords = new cgCoord(); - coords.type = "cache"; - if (StringUtils.isNotBlank(name)) { - coords.name = name; - } else { - coords.name = geocode.toUpperCase(); - } - coords.coords = cache.coords; - coordinates.add(coords); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeodetail.getCoordinates (cache): " + e.toString()); - } - - try { - // waypoints - for (cgWaypoint waypoint : cache.waypoints) { - if (waypoint.coords == null) { - continue; - } - - coords = new cgCoord(); - coords.type = "waypoint"; - coords.name = waypoint.name; - coords.coords = waypoint.coords; - coordinates.add(coords); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeodetail.getCoordinates (waypoint): " + e.toString()); - } - - return coordinates; - } - - private void cachesAround() { - cgeocaches.startActivityCachesAround(this, cache.coords); - - finish(); - } - - private void addToCalendar() { - String[] projection = new String[] { "_id", "displayName" }; - Uri calendarProvider = Compatibility.getCalendarProviderURI(); - - Cursor cursor = managedQuery(calendarProvider, projection, "selected=1", null, null); - - calendars.clear(); - int cnt = 0; - if (cursor != null) { - cnt = cursor.getCount(); - - if (cnt > 0) { - cursor.moveToFirst(); - - int calId = 0; - String calIdPre = null; - String calName = null; - int calIdIn = cursor.getColumnIndex("_id"); - int calNameIn = cursor.getColumnIndex("displayName"); - - do { - calIdPre = cursor.getString(calIdIn); - if (calIdPre != null) { - calId = new Integer(calIdPre); - } - calName = cursor.getString(calNameIn); - - if (calId > 0 && calName != null) { - calendars.put(calId, calName); - } - } while (cursor.moveToNext()); - } - } - - final CharSequence[] items = calendars.values().toArray(new CharSequence[calendars.size()]); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.cache_calendars); - builder.setItems(items, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - addToCalendarFn(item); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - } - - private void addToCalendarFn(int index) { - if (calendars == null || calendars.isEmpty()) { - return; - } - - try { - Uri calendarProvider = Compatibility.getCalenderEventsProviderURI(); - - final Integer[] keys = calendars.keySet().toArray(new Integer[calendars.size()]); - final Integer calId = keys[index]; - - final Date eventDate = cache.hidden; - eventDate.setHours(0); - eventDate.setMinutes(0); - eventDate.setSeconds(0); - - StringBuilder description = new StringBuilder(); - description.append("http://coord.info/"); - description.append(cache.geocode.toUpperCase()); - description.append("\n\n"); - if (StringUtils.isNotBlank(cache.shortdesc)) { - description.append(Html.fromHtml(cache.shortdesc).toString()); - } - - if (StringUtils.isNotBlank(cache.personalNote)) { - description.append("\n\n"+Html.fromHtml(cache.personalNote).toString()); - } - - ContentValues event = new ContentValues(); - event.put("calendar_id", calId); - event.put("dtstart", eventDate.getTime() + 43200000); // noon - event.put("dtend", eventDate.getTime() + 43200000 + 3600000); // + one hour - event.put("eventTimezone", "UTC"); - event.put("title", Html.fromHtml(cache.name).toString()); - event.put("description", description.toString()); - String location = ""; - if (StringUtils.isNotBlank(cache.latitudeString) && StringUtils.isNotBlank(cache.longitudeString)) { - location += cache.latitudeString + " " + cache.longitudeString; - } - if (StringUtils.isNotBlank(cache.location)) { - boolean addParenteses = false; - if (location.length() > 0) { - addParenteses = true; - location += " ("; - } - - location += Html.fromHtml(cache.location).toString(); - if (addParenteses) { - location += ")"; - } - } - if (location.length() > 0) { - event.put("eventLocation", location); - } - event.put("allDay", 1); - event.put("hasAlarm", 0); - - getContentResolver().insert(calendarProvider, event); - - showToast(res.getString(R.string.event_success)); - } catch (Exception e) { - showToast(res.getString(R.string.event_fail)); - - Log.e(cgSettings.tag, "cgeodetail.addToCalendarFn: " + e.toString()); - } - } - - private void navigateTo() { - if (cache == null || cache.coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - } - - cgeonavigate navigateActivity = new cgeonavigate(); - - Intent navigateIntent = new Intent(this, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", cache.coords.getLatitude()); - navigateIntent.putExtra("longitude", cache.coords.getLongitude()); - navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); - navigateIntent.putExtra("name", cache.name); - - cgeonavigate.coordinates.clear(); - cgeonavigate.coordinates.addAll(getCoordinates()); - startActivity(navigateIntent); - } - - public void shareCache() { - if (geocode == null && cache == null) { - return; - } - - final Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - - if (cache != null && cache.geocode != null) { - String subject = cache.geocode.toUpperCase(); - if (StringUtils.isNotBlank(cache.name)){ - subject = subject + " - " + cache.name; - } - intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + subject); - intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + cache.geocode.toUpperCase()); - } else if (geocode != null) { - intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + geocode.toUpperCase()); - intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + geocode.toUpperCase()); - } - - startActivity(Intent.createChooser(intent, res.getText(R.string.action_bar_share_title))); - } - - private class waypointInfo implements View.OnClickListener { - private int id = -1; - - public waypointInfo(int idIn) { - id = idIn; - } - - public void onClick(View arg0) { - Intent waypointIntent = new Intent(cgeodetail.this, cgeowaypoint.class); - waypointIntent.putExtra("waypoint", id); - waypointIntent.putExtra("geocode", cache.geocode); - startActivity(waypointIntent); - } - } - - private void logVisit() { - cache.logVisit(this); - } - - private void showSpoilers() { - if (cache == null || cache.spoilers == null || cache.spoilers.isEmpty()) { - showToast(res.getString(R.string.err_detail_no_spoiler)); - } - - Intent spoilersIntent = new Intent(this, cgeoimages.class); - spoilersIntent.putExtra("geocode", geocode.toUpperCase()); - spoilersIntent.putExtra("type", cgeoimages.SPOILER_IMAGE); - startActivity(spoilersIntent); - } - - public class codeHint implements View.OnClickListener { - public void onClick(View arg0) { - // code hint - TextView hintView = ((TextView) findViewById(R.id.hint)); - hintView.setText(cgBase.rot13(hintView.getText().toString())); - - } - } - - private class update extends cgUpdateLoc { - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - if (cacheDistance == null) { - return; - } - - try { - StringBuilder dist = new StringBuilder(); - - if (geo.coordsNow != null && cache != null && cache.coords != null) { - dist.append(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); - } - - if (cache != null && cache.elevation != null) { - if (geo.altitudeNow != null) { - Double diff = (cache.elevation - geo.altitudeNow); - if (diff >= 0) { - dist.append(" ↗"); - } else if (diff < 0) { - dist.append(" ↘"); - } - if (settings.units == cgSettings.unitsImperial) { - dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff) * 3.2808399))); - dist.append(" ft"); - } else { - dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff)))); - dist.append(" m"); - } - } - } - - cacheDistance.setText(dist.toString()); - cacheDistance.bringToFront(); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class selectTrackable implements View.OnClickListener { - public void onClick(View arg0) { - // show list of trackables - try { - // jump directly into details if there is only one trackable - if (cache != null && cache.inventory != null && cache.inventory.size() == 1) { - cgTrackable trackable = cache.inventory.get(0); - cgeotrackable.startActivity(cgeodetail.this, trackable.guid, trackable.geocode, trackable.name); - } - else { - Intent trackablesIntent = new Intent(cgeodetail.this, cgeotrackables.class); - trackablesIntent.putExtra("geocode", geocode.toUpperCase()); - startActivity(trackablesIntent); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeodetail.selectTrackable: " + e.toString()); - } - } - } - - private class storeCache implements View.OnClickListener { - public void onClick(View arg0) { - if (dropDialog != null && dropDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_removing)); - return; - } - if (refreshDialog != null && refreshDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_refreshing)); - return; - } - - storeDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true); - storeDialog.setCancelable(true); - - if (storeThread != null) { - storeThread.interrupt(); - } - - storeThread = new storeCacheThread(storeCacheHandler); - storeThread.start(); - } - } - - private class refreshCache implements View.OnClickListener { - public void onClick(View arg0) { - if (dropDialog != null && dropDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_removing)); - return; - } - if (storeDialog != null && storeDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_saving)); - return; - } - - refreshDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true); - refreshDialog.setCancelable(true); - - if (refreshThread != null) { - refreshThread.interrupt(); - } - - refreshThread = new refreshCacheThread(refreshCacheHandler); - refreshThread.start(); - } - } - - private class storeCacheThread extends Thread { - private Handler handler = null; - - public storeCacheThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - int reason = (cache.reason > 1) ? cache.reason : 1; - base.storeCache(app, cgeodetail.this, cache, null, reason, handler); - } - } - - private class refreshCacheThread extends Thread { - private Handler handler = null; - - public refreshCacheThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - app.removeCacheFromCache(geocode); - - final Map<String, String> params = new HashMap<String, String>(); - params.put("geocode", cache.geocode); - searchId = base.searchByGeocode(params, 0, true); - - handler.sendEmptyMessage(0); - } - } - - private class dropCache implements View.OnClickListener { - public void onClick(View arg0) { - if (storeDialog != null && storeDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_saving)); - return; - } - if (refreshDialog != null && refreshDialog.isShowing()) { - showToast(res.getString(R.string.err_detail_still_refreshing)); - return; - } - - dropDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true); - dropDialog.setCancelable(false); - Thread thread = new dropCacheThread(dropCacheHandler); - thread.start(); - } - } - - private class dropCacheThread extends Thread { - - private Handler handler = null; - - public dropCacheThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - cgBase.dropCache(app, cgeodetail.this, cache, handler); - } - } - - /** - * Abstract Listener for add / remove buttons for watchlist - */ + else if (log.type == cgBase.LOG_DIDNT_FIND_IT + || log.type == cgBase.LOG_NEEDS_MAINTENANCE + || log.type == cgBase.LOG_NEEDS_ARCHIVE) + { + logMark.setImageResource(R.drawable.mark_red); + } + else if (log.type == cgBase.LOG_TEMP_DISABLE_LISTING + || log.type == cgBase.LOG_ARCHIVE) + { + logMark.setImageResource(R.drawable.mark_red_more); + } + else + { + logMark.setVisibility(View.GONE); + } + + ((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions()); + ((TextView) logLayout.findViewById(R.id.log)).setOnClickListener(new decryptLog()); + + listView.addView(rowView); + } + + if (cache.logs.size() > 0) { + ((LinearLayout) findViewById(R.id.log_box)).setVisibility(View.VISIBLE); + } + } + } + + private class loadCache extends Thread { + + private Handler handler = null; + + public loadCache(Handler handlerIn) { + handler = handlerIn; + + if (geocode == null && guid == null) { + showToast(res.getString(R.string.err_detail_cache_forgot)); + + finish(); + return; + } + } + + @Override + public void run() { + Map<String, String> params = new HashMap<String, String>(); + if (StringUtils.isNotBlank(geocode)) { + params.put("geocode", geocode); + } else if (StringUtils.isNotBlank(guid)) { + params.put("guid", guid); + } else { + return; + } + + searchId = base.searchByGeocode(params, 0, false); + + handler.sendMessage(new Message()); + } + } + + private class loadMapPreview extends Thread { + private Handler handler = null; + + public loadMapPreview(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + if (cache == null || cache.coords == null) { + return; + } + + BitmapDrawable image = null; + + try { + final String latlonMap = String.format((Locale) null, "%.6f", cache.coords.getLatitude()) + "," + + String.format((Locale) null, "%.6f", cache.coords.getLongitude()); + final Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + + int width = display.getWidth(); + int height = (int) (90 * pixelRatio); + + String markerUrl = cgBase.urlencode_rfc3986("http://cgeo.carnero.cc/_markers/my_location_mdpi.png"); + + cgHtmlImg mapGetter = new cgHtmlImg(cgeodetail.this, cache.geocode, false, 0, false); + image = mapGetter.getDrawable("http://maps.google.com/maps/api/staticmap?center=" + latlonMap + "&zoom=15&size=" + width + "x" + height + "&maptype=terrain&markers=icon%3A" + markerUrl + "%7C" + latlonMap + "&sensor=false"); + Message message = handler.obtainMessage(0, image); + handler.sendMessage(message); + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeodetail.loadMapPreview.run: " + e.toString()); + } + } + } + + public void loadLongDesc() { + if (waitDialog == null || waitDialog.isShowing() == false) { + descDialog = ProgressDialog.show(this, null, res.getString(R.string.cache_dialog_loading_description), true); + descDialog.setCancelable(true); + } + + threadLongDesc = new loadLongDesc(loadDescriptionHandler); + threadLongDesc.start(); + } + + private class loadLongDesc extends Thread { + private Handler handler = null; + + public loadLongDesc(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + if (cache == null || cache.description == null || handler == null) { + return; + } + parseLongDescription(); + handler.sendMessage(new Message()); + } + } + + public List<cgCoord> getCoordinates() { + cgCoord coords = null; + List<cgCoord> coordinates = new ArrayList<cgCoord>(); + + try { + // cache + coords = new cgCoord(); + coords.type = "cache"; + if (StringUtils.isNotBlank(name)) { + coords.name = name; + } else { + coords.name = geocode.toUpperCase(); + } + coords.coords = cache.coords; + coordinates.add(coords); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeodetail.getCoordinates (cache): " + e.toString()); + } + + try { + // waypoints + for (cgWaypoint waypoint : cache.waypoints) { + if (waypoint.coords == null) { + continue; + } + + coords = new cgCoord(); + coords.type = "waypoint"; + coords.name = waypoint.name; + coords.coords = waypoint.coords; + coordinates.add(coords); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeodetail.getCoordinates (waypoint): " + e.toString()); + } + + return coordinates; + } + + private void cachesAround() { + cgeocaches.startActivityCachesAround(this, cache.coords); + + finish(); + } + + private void addToCalendar() { + String[] projection = new String[] { "_id", "displayName" }; + Uri calendarProvider = Compatibility.getCalendarProviderURI(); + + Cursor cursor = managedQuery(calendarProvider, projection, "selected=1", null, null); + + calendars.clear(); + int cnt = 0; + if (cursor != null) { + cnt = cursor.getCount(); + + if (cnt > 0) { + cursor.moveToFirst(); + + int calId = 0; + String calIdPre = null; + String calName = null; + int calIdIn = cursor.getColumnIndex("_id"); + int calNameIn = cursor.getColumnIndex("displayName"); + + do { + calIdPre = cursor.getString(calIdIn); + if (calIdPre != null) { + calId = new Integer(calIdPre); + } + calName = cursor.getString(calNameIn); + + if (calId > 0 && calName != null) { + calendars.put(calId, calName); + } + } while (cursor.moveToNext()); + } + } + + final CharSequence[] items = calendars.values().toArray(new CharSequence[calendars.size()]); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.cache_calendars); + builder.setItems(items, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + addToCalendarFn(item); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + } + + private void addToCalendarFn(int index) { + if (calendars == null || calendars.isEmpty()) { + return; + } + + try { + Uri calendarProvider = Compatibility.getCalenderEventsProviderURI(); + + final Integer[] keys = calendars.keySet().toArray(new Integer[calendars.size()]); + final Integer calId = keys[index]; + + final Date eventDate = cache.hidden; + eventDate.setHours(0); + eventDate.setMinutes(0); + eventDate.setSeconds(0); + + StringBuilder description = new StringBuilder(); + description.append("http://coord.info/"); + description.append(cache.geocode.toUpperCase()); + description.append("\n\n"); + if (StringUtils.isNotBlank(cache.shortdesc)) { + description.append(Html.fromHtml(cache.shortdesc).toString()); + } + + if (StringUtils.isNotBlank(cache.personalNote)) { + description.append("\n\n" + Html.fromHtml(cache.personalNote).toString()); + } + + ContentValues event = new ContentValues(); + event.put("calendar_id", calId); + event.put("dtstart", eventDate.getTime() + 43200000); // noon + event.put("dtend", eventDate.getTime() + 43200000 + 3600000); // + one hour + event.put("eventTimezone", "UTC"); + event.put("title", Html.fromHtml(cache.name).toString()); + event.put("description", description.toString()); + String location = ""; + if (StringUtils.isNotBlank(cache.latitudeString) && StringUtils.isNotBlank(cache.longitudeString)) { + location += cache.latitudeString + " " + cache.longitudeString; + } + if (StringUtils.isNotBlank(cache.location)) { + boolean addParenteses = false; + if (location.length() > 0) { + addParenteses = true; + location += " ("; + } + + location += Html.fromHtml(cache.location).toString(); + if (addParenteses) { + location += ")"; + } + } + if (location.length() > 0) { + event.put("eventLocation", location); + } + event.put("allDay", 1); + event.put("hasAlarm", 0); + + getContentResolver().insert(calendarProvider, event); + + showToast(res.getString(R.string.event_success)); + } catch (Exception e) { + showToast(res.getString(R.string.event_fail)); + + Log.e(cgSettings.tag, "cgeodetail.addToCalendarFn: " + e.toString()); + } + } + + private void navigateTo() { + if (cache == null || cache.coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + } + + cgeonavigate navigateActivity = new cgeonavigate(); + + Intent navigateIntent = new Intent(this, navigateActivity.getClass()); + navigateIntent.putExtra("latitude", cache.coords.getLatitude()); + navigateIntent.putExtra("longitude", cache.coords.getLongitude()); + navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); + navigateIntent.putExtra("name", cache.name); + + cgeonavigate.coordinates.clear(); + cgeonavigate.coordinates.addAll(getCoordinates()); + startActivity(navigateIntent); + } + + public void shareCache() { + if (geocode == null && cache == null) { + return; + } + + final Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + + if (cache != null && cache.geocode != null) { + String subject = cache.geocode.toUpperCase(); + if (StringUtils.isNotBlank(cache.name)) { + subject = subject + " - " + cache.name; + } + intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + subject); + intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + cache.geocode.toUpperCase()); + } else if (geocode != null) { + intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + geocode.toUpperCase()); + intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + geocode.toUpperCase()); + } + + startActivity(Intent.createChooser(intent, res.getText(R.string.action_bar_share_title))); + } + + private class waypointInfo implements View.OnClickListener { + private int id = -1; + + public waypointInfo(int idIn) { + id = idIn; + } + + public void onClick(View arg0) { + Intent waypointIntent = new Intent(cgeodetail.this, cgeowaypoint.class); + waypointIntent.putExtra("waypoint", id); + waypointIntent.putExtra("geocode", cache.geocode); + startActivity(waypointIntent); + } + } + + private void logVisit() { + cache.logVisit(this); + } + + private void showSpoilers() { + if (cache == null || cache.spoilers == null || cache.spoilers.isEmpty()) { + showToast(res.getString(R.string.err_detail_no_spoiler)); + } + + Intent spoilersIntent = new Intent(this, cgeoimages.class); + spoilersIntent.putExtra("geocode", geocode.toUpperCase()); + spoilersIntent.putExtra("type", cgeoimages.SPOILER_IMAGE); + startActivity(spoilersIntent); + } + + public class codeHint implements View.OnClickListener { + public void onClick(View arg0) { + // code hint + TextView hintView = ((TextView) findViewById(R.id.hint)); + hintView.setText(cgBase.rot13(hintView.getText().toString())); + + } + } + + private class update extends cgUpdateLoc { + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + if (cacheDistance == null) { + return; + } + + try { + StringBuilder dist = new StringBuilder(); + + if (geo.coordsNow != null && cache != null && cache.coords != null) { + dist.append(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); + } + + if (cache != null && cache.elevation != null) { + if (geo.altitudeNow != null) { + Double diff = (cache.elevation - geo.altitudeNow); + if (diff >= 0) { + dist.append(" ↗"); + } else if (diff < 0) { + dist.append(" ↘"); + } + if (settings.units == cgSettings.unitsImperial) { + dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff) * 3.2808399))); + dist.append(" ft"); + } else { + dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff)))); + dist.append(" m"); + } + } + } + + cacheDistance.setText(dist.toString()); + cacheDistance.bringToFront(); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class selectTrackable implements View.OnClickListener { + public void onClick(View arg0) { + // show list of trackables + try { + // jump directly into details if there is only one trackable + if (cache != null && cache.inventory != null && cache.inventory.size() == 1) { + cgTrackable trackable = cache.inventory.get(0); + cgeotrackable.startActivity(cgeodetail.this, trackable.guid, trackable.geocode, trackable.name); + } + else { + Intent trackablesIntent = new Intent(cgeodetail.this, cgeotrackables.class); + trackablesIntent.putExtra("geocode", geocode.toUpperCase()); + startActivity(trackablesIntent); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeodetail.selectTrackable: " + e.toString()); + } + } + } + + private class storeCache implements View.OnClickListener { + public void onClick(View arg0) { + if (dropDialog != null && dropDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_removing)); + return; + } + if (refreshDialog != null && refreshDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_refreshing)); + return; + } + + storeDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true); + storeDialog.setCancelable(true); + + if (storeThread != null) { + storeThread.interrupt(); + } + + storeThread = new storeCacheThread(storeCacheHandler); + storeThread.start(); + } + } + + private class refreshCache implements View.OnClickListener { + public void onClick(View arg0) { + if (dropDialog != null && dropDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_removing)); + return; + } + if (storeDialog != null && storeDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_saving)); + return; + } + + refreshDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true); + refreshDialog.setCancelable(true); + + if (refreshThread != null) { + refreshThread.interrupt(); + } + + refreshThread = new refreshCacheThread(refreshCacheHandler); + refreshThread.start(); + } + } + + private class storeCacheThread extends Thread { + private Handler handler = null; + + public storeCacheThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + int reason = (cache.reason > 1) ? cache.reason : 1; + base.storeCache(app, cgeodetail.this, cache, null, reason, handler); + } + } + + private class refreshCacheThread extends Thread { + private Handler handler = null; + + public refreshCacheThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + app.removeCacheFromCache(geocode); + + final Map<String, String> params = new HashMap<String, String>(); + params.put("geocode", cache.geocode); + searchId = base.searchByGeocode(params, 0, true); + + handler.sendEmptyMessage(0); + } + } + + private class dropCache implements View.OnClickListener { + public void onClick(View arg0) { + if (storeDialog != null && storeDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_saving)); + return; + } + if (refreshDialog != null && refreshDialog.isShowing()) { + showToast(res.getString(R.string.err_detail_still_refreshing)); + return; + } + + dropDialog = ProgressDialog.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true); + dropDialog.setCancelable(false); + Thread thread = new dropCacheThread(dropCacheHandler); + thread.start(); + } + } + + private class dropCacheThread extends Thread { + + private Handler handler = null; + + public dropCacheThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + cgBase.dropCache(app, cgeodetail.this, cache, handler); + } + } + + /** + * Abstract Listener for add / remove buttons for watchlist + */ private abstract class AbstractWatchlistClickListener implements View.OnClickListener { public void doExecute(int titleId, int messageId, Thread thread) { - if (watchlistDialog != null && watchlistDialog.isShowing()) { + if (watchlistDialog != null && watchlistDialog.isShowing()) { showToast(res.getString(R.string.err_watchlist_still_managing)); return; } @@ -1818,286 +1832,291 @@ public class cgeodetail extends AbstractActivity { } } - /** - * Listener for "add to watchlist" button - */ - private class AddToWatchlistClickListener extends AbstractWatchlistClickListener { - public void onClick(View arg0) { - doExecute(R.string.cache_dialog_watchlist_add_title, - R.string.cache_dialog_watchlist_add_message, - new WatchlistAddThread(WatchlistHandler) ); - } - } - - /** - * Listener for "remove from watchlist" button - */ - private class RemoveFromWatchlistClickListener extends AbstractWatchlistClickListener { + /** + * Listener for "add to watchlist" button + */ + private class AddToWatchlistClickListener extends AbstractWatchlistClickListener { + public void onClick(View arg0) { + doExecute(R.string.cache_dialog_watchlist_add_title, + R.string.cache_dialog_watchlist_add_message, + new WatchlistAddThread(WatchlistHandler)); + } + } + + /** + * Listener for "remove from watchlist" button + */ + private class RemoveFromWatchlistClickListener extends AbstractWatchlistClickListener { public void onClick(View arg0) { doExecute(R.string.cache_dialog_watchlist_remove_title, R.string.cache_dialog_watchlist_remove_message, - new WatchlistRemoveThread(WatchlistHandler) ); + new WatchlistRemoveThread(WatchlistHandler)); } - } + } + + /** Thread to add this cache to the watchlist of the user */ + private class WatchlistAddThread extends Thread { + private final Handler handler; - /** Thread to add this cache to the watchlist of the user */ - private class WatchlistAddThread extends Thread { - private final Handler handler; public WatchlistAddThread(Handler handler) { this.handler = handler; } + @Override public void run() { handler.sendEmptyMessage(base.addToWatchlist(cache)); } - } + } /** Thread to remove this cache from the watchlist of the user */ private class WatchlistRemoveThread extends Thread { private final Handler handler; + public WatchlistRemoveThread(Handler handler) { this.handler = handler; } + @Override public void run() { handler.sendEmptyMessage(base.removeFromWatchlist(cache)); } } - private class addWaypoint implements View.OnClickListener { - - public void onClick(View view) { - Intent addWptIntent = new Intent(cgeodetail.this, cgeowaypointadd.class); - - addWptIntent.putExtra("geocode", geocode); - int wpCount = 0; - if (cache.waypoints != null) { - wpCount = cache.waypoints.size(); - } - addWptIntent.putExtra("count", wpCount); - - startActivity(addWptIntent); - } - } - - private static class decryptLog implements View.OnClickListener { - - public void onClick(View view) { - if (view == null) { - return; - } - - try { - final TextView logView = (TextView)view; - Spannable span = (Spannable) logView.getText(); - - // I needed to re-implement the base.rot13() encryption here because we must work on - // a SpannableStringBuilder instead of the pure text and we must replace each character inline. - // Otherwise we loose all the images, colors and so on... - SpannableStringBuilder buffer = new SpannableStringBuilder(span); - boolean plaintext = false; - - int length = span.length(); - for (int index = 0; index < length; index++) { - int c = span.charAt(index); - if (c == '[') { - plaintext = true; - } else if (c == ']') { - plaintext = false; - } else if (!plaintext) { - int capitalized = c & 32; - c &= ~capitalized; - c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) - | capitalized; - } - buffer.replace(index, index + 1, String.valueOf((char) c)); - } - logView.setText(buffer); - } catch (Exception e) { - // nothing - } - } - } - - private class userActions implements View.OnClickListener { - - public void onClick(View view) { - if (view == null) { - return; - } - - try { - registerForContextMenu(view); - openContextMenu(view); - } catch (Exception e) { - // nothing - } - } - } - - public void goCompass(View view) { - if (cache == null || cache.coords == null) { - showToast(res.getString(R.string.cache_coordinates_no)); - - return; - } - - Intent navigateIntent = new Intent(this, cgeonavigate.class); - navigateIntent.putExtra("latitude", cache.coords.getLatitude()); - navigateIntent.putExtra("longitude", cache.coords.getLongitude()); - navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); - navigateIntent.putExtra("name", cache.name); - - cgeonavigate.coordinates.clear(); - cgeonavigate.coordinates.addAll(getCoordinates()); - startActivity(navigateIntent); - } - - /** - * lazy-creates the layout holding the icons of the chaches attributes - * and makes it visible - */ - private void showAttributeIcons(LinearLayout attribBox, int parentWidth) { - if (attributeIconsLayout == null) { - attributeIconsLayout = createAttributeIconsLayout(parentWidth); - // no matching icons found? show text - if (noAttributeIconsFound) { - showAttributeDescriptions(attribBox); - return; - } - } - attribBox.removeAllViews(); - attribBox.addView(attributeIconsLayout); - attributesShowAsIcons = true; - } - - /** - * lazy-creates the layout holding the discriptions of the chaches attributes - * and makes it visible - */ - private void showAttributeDescriptions(LinearLayout attribBox) { - if (attributeDescriptionsLayout == null) { - attributeDescriptionsLayout = createAttributeDescriptionsLayout(); - } - attribBox.removeAllViews(); - attribBox.addView(attributeDescriptionsLayout); - attributesShowAsIcons = false; - } - - /** - * toggle attribute descriptions and icons - */ - private void toggleAttributeDisplay(LinearLayout attribBox, int parentWidth) { - // Don't toggle when there are no icons to show. - if (noAttributeIconsFound) { - return; - } - - // toggle - if (attributesShowAsIcons) { - showAttributeDescriptions(attribBox); - } else { - showAttributeIcons(attribBox, parentWidth); - } - } - - private ViewGroup createAttributeIconsLayout(int parentWidth) { - LinearLayout rows = new LinearLayout(this); - rows.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); - rows.setOrientation(LinearLayout.VERTICAL); - - LinearLayout attributeRow = newAttributeIconsRow(); + private class addWaypoint implements View.OnClickListener { + + public void onClick(View view) { + Intent addWptIntent = new Intent(cgeodetail.this, cgeowaypointadd.class); + + addWptIntent.putExtra("geocode", geocode); + int wpCount = 0; + if (cache.waypoints != null) { + wpCount = cache.waypoints.size(); + } + addWptIntent.putExtra("count", wpCount); + + startActivity(addWptIntent); + } + } + + private static class decryptLog implements View.OnClickListener { + + public void onClick(View view) { + if (view == null) { + return; + } + + try { + final TextView logView = (TextView) view; + Spannable span = (Spannable) logView.getText(); + + // I needed to re-implement the base.rot13() encryption here because we must work on + // a SpannableStringBuilder instead of the pure text and we must replace each character inline. + // Otherwise we loose all the images, colors and so on... + SpannableStringBuilder buffer = new SpannableStringBuilder(span); + boolean plaintext = false; + + int length = span.length(); + for (int index = 0; index < length; index++) { + int c = span.charAt(index); + if (c == '[') { + plaintext = true; + } else if (c == ']') { + plaintext = false; + } else if (!plaintext) { + int capitalized = c & 32; + c &= ~capitalized; + c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) + | capitalized; + } + buffer.replace(index, index + 1, String.valueOf((char) c)); + } + logView.setText(buffer); + } catch (Exception e) { + // nothing + } + } + } + + private class userActions implements View.OnClickListener { + + public void onClick(View view) { + if (view == null) { + return; + } + + try { + registerForContextMenu(view); + openContextMenu(view); + } catch (Exception e) { + // nothing + } + } + } + + public void goCompass(View view) { + if (cache == null || cache.coords == null) { + showToast(res.getString(R.string.cache_coordinates_no)); + + return; + } + + Intent navigateIntent = new Intent(this, cgeonavigate.class); + navigateIntent.putExtra("latitude", cache.coords.getLatitude()); + navigateIntent.putExtra("longitude", cache.coords.getLongitude()); + navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); + navigateIntent.putExtra("name", cache.name); + + cgeonavigate.coordinates.clear(); + cgeonavigate.coordinates.addAll(getCoordinates()); + startActivity(navigateIntent); + } + + /** + * lazy-creates the layout holding the icons of the chaches attributes + * and makes it visible + */ + private void showAttributeIcons(LinearLayout attribBox, int parentWidth) { + if (attributeIconsLayout == null) { + attributeIconsLayout = createAttributeIconsLayout(parentWidth); + // no matching icons found? show text + if (noAttributeIconsFound) { + showAttributeDescriptions(attribBox); + return; + } + } + attribBox.removeAllViews(); + attribBox.addView(attributeIconsLayout); + attributesShowAsIcons = true; + } + + /** + * lazy-creates the layout holding the discriptions of the chaches attributes + * and makes it visible + */ + private void showAttributeDescriptions(LinearLayout attribBox) { + if (attributeDescriptionsLayout == null) { + attributeDescriptionsLayout = createAttributeDescriptionsLayout(); + } + attribBox.removeAllViews(); + attribBox.addView(attributeDescriptionsLayout); + attributesShowAsIcons = false; + } + + /** + * toggle attribute descriptions and icons + */ + private void toggleAttributeDisplay(LinearLayout attribBox, int parentWidth) { + // Don't toggle when there are no icons to show. + if (noAttributeIconsFound) { + return; + } + + // toggle + if (attributesShowAsIcons) { + showAttributeDescriptions(attribBox); + } else { + showAttributeIcons(attribBox, parentWidth); + } + } + + private ViewGroup createAttributeIconsLayout(int parentWidth) { + LinearLayout rows = new LinearLayout(this); + rows.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + rows.setOrientation(LinearLayout.VERTICAL); + + LinearLayout attributeRow = newAttributeIconsRow(); rows.addView(attributeRow); noAttributeIconsFound = true; - for(String attributeName : cache.attributes) { - boolean strikethru = attributeName.endsWith("_no"); - // cut off _yes / _no - if (attributeName.endsWith("_no") || attributeName.endsWith("_yes")) { - attributeName = attributeName.substring(0, attributeName.lastIndexOf("_")); - } - // check if another attribute icon fits in this row - attributeRow.measure(0, 0); - int rowWidth = attributeRow.getMeasuredWidth(); - FrameLayout fl = (FrameLayout) inflater.inflate(R.layout.attribute_image, null); - ImageView iv = (ImageView) fl.getChildAt(0); - if ((parentWidth - rowWidth) < iv.getLayoutParams().width) { - // make a new row - attributeRow = newAttributeIconsRow(); - rows.addView(attributeRow); - } - - // dynamically search icon of the attribute - Drawable d = null; - int id = res.getIdentifier("attribute_" + attributeName, "drawable", - base.context.getPackageName()); - if (id > 0) { - noAttributeIconsFound = false; - d = res.getDrawable(id); - iv.setImageDrawable(d); - // strike through? - if (strikethru) { - // generate strikethru image with same properties as attribute image - ImageView strikethruImage = new ImageView(this); - strikethruImage.setLayoutParams(iv.getLayoutParams()); - d = res.getDrawable(R.drawable.attribute__strikethru); - strikethruImage.setImageDrawable(d); - fl.addView(strikethruImage); - } - } else { - d = res.getDrawable(R.drawable.attribute_icon_not_found); - iv.setImageDrawable(d); - } - - attributeRow.addView(fl); - } - - return rows; + for (String attributeName : cache.attributes) { + boolean strikethru = attributeName.endsWith("_no"); + // cut off _yes / _no + if (attributeName.endsWith("_no") || attributeName.endsWith("_yes")) { + attributeName = attributeName.substring(0, attributeName.lastIndexOf("_")); + } + // check if another attribute icon fits in this row + attributeRow.measure(0, 0); + int rowWidth = attributeRow.getMeasuredWidth(); + FrameLayout fl = (FrameLayout) inflater.inflate(R.layout.attribute_image, null); + ImageView iv = (ImageView) fl.getChildAt(0); + if ((parentWidth - rowWidth) < iv.getLayoutParams().width) { + // make a new row + attributeRow = newAttributeIconsRow(); + rows.addView(attributeRow); + } + + // dynamically search icon of the attribute + Drawable d = null; + int id = res.getIdentifier("attribute_" + attributeName, "drawable", + base.context.getPackageName()); + if (id > 0) { + noAttributeIconsFound = false; + d = res.getDrawable(id); + iv.setImageDrawable(d); + // strike through? + if (strikethru) { + // generate strikethru image with same properties as attribute image + ImageView strikethruImage = new ImageView(this); + strikethruImage.setLayoutParams(iv.getLayoutParams()); + d = res.getDrawable(R.drawable.attribute__strikethru); + strikethruImage.setImageDrawable(d); + fl.addView(strikethruImage); + } + } else { + d = res.getDrawable(R.drawable.attribute_icon_not_found); + iv.setImageDrawable(d); + } + + attributeRow.addView(fl); + } + + return rows; } private LinearLayout newAttributeIconsRow() { - LinearLayout rowLayout = new LinearLayout(this); - rowLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, - LayoutParams.WRAP_CONTENT)); - rowLayout.setOrientation(LinearLayout.HORIZONTAL); - return rowLayout; + LinearLayout rowLayout = new LinearLayout(this); + rowLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.WRAP_CONTENT)); + rowLayout.setOrientation(LinearLayout.HORIZONTAL); + return rowLayout; } private ViewGroup createAttributeDescriptionsLayout() { - final LinearLayout descriptions = (LinearLayout) inflater.inflate( - R.layout.attribute_descriptions, null); - TextView attribView = (TextView) descriptions.getChildAt(0); - - StringBuilder buffer = new StringBuilder(); - String attribute; - for (int i = 0; i < cache.attributes.size(); i++) { - attribute = cache.attributes.get(i); - - // dynamically search for a translation of the attribute - int id = res.getIdentifier("attribute_" + attribute, "string", - base.context.getPackageName()); - if (id > 0) { - String translated = res.getString(id); - if (StringUtils.isNotBlank(translated)) { - attribute = translated; - } - } - if (buffer.length() > 0) buffer.append('\n'); - buffer.append(attribute); - } - - if (noAttributeIconsFound) - buffer.append("\n\n").append(res.getString(R.string.cache_attributes_no_icons)); - - attribView.setText(buffer); + final LinearLayout descriptions = (LinearLayout) inflater.inflate( + R.layout.attribute_descriptions, null); + TextView attribView = (TextView) descriptions.getChildAt(0); + + StringBuilder buffer = new StringBuilder(); + String attribute; + for (int i = 0; i < cache.attributes.size(); i++) { + attribute = cache.attributes.get(i); + + // dynamically search for a translation of the attribute + int id = res.getIdentifier("attribute_" + attribute, "string", + base.context.getPackageName()); + if (id > 0) { + String translated = res.getString(id); + if (StringUtils.isNotBlank(translated)) { + attribute = translated; + } + } + if (buffer.length() > 0) + buffer.append('\n'); + buffer.append(attribute); + } + + if (noAttributeIconsFound) + buffer.append("\n\n").append(res.getString(R.string.cache_attributes_no_icons)); + + attribView.setText(buffer); return descriptions; } - public static void startActivity(final Context context, final String geocode) { - final Intent detailIntent = new Intent(context, cgeodetail.class); - detailIntent.putExtra("geocode", geocode.toUpperCase()); - context.startActivity(detailIntent); - } + public static void startActivity(final Context context, final String geocode) { + final Intent detailIntent = new Intent(context, cgeodetail.class); + detailIntent.putExtra("geocode", geocode.toUpperCase()); + context.startActivity(detailIntent); + } } diff --git a/src/cgeo/geocaching/cgeogpxes.java b/src/cgeo/geocaching/cgeogpxes.java index 92d0d48..e3e9ba6 100644 --- a/src/cgeo/geocaching/cgeogpxes.java +++ b/src/cgeo/geocaching/cgeogpxes.java @@ -1,8 +1,8 @@ package cgeo.geocaching; -import java.io.File; -import java.util.List; -import java.util.UUID; +import cgeo.geocaching.files.FileList; +import cgeo.geocaching.files.GPXParser; +import cgeo.geocaching.files.LocParser; import android.app.Activity; import android.app.ProgressDialog; @@ -11,121 +11,122 @@ import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; -import cgeo.geocaching.files.FileList; -import cgeo.geocaching.files.GPXParser; -import cgeo.geocaching.files.LocParser; + +import java.io.File; +import java.util.List; +import java.util.UUID; public class cgeogpxes extends FileList<cgGPXListAdapter> { - private static final String EXTRAS_LIST_ID = "list"; - - public cgeogpxes() { - super(new String[] {"gpx" - // TODO , "loc" - }); - } - - private ProgressDialog parseDialog = null; - private int listId = 1; - private int imported = 0; - - final private Handler changeParseDialogHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (msg.obj != null && parseDialog != null) { - parseDialog.setMessage(res.getString(R.string.gpx_import_loading_stored) + " " + (Integer) msg.obj); - } - } - }; - final private Handler loadCachesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (parseDialog != null) { - parseDialog.dismiss(); - } - - helpDialog(res.getString(R.string.gpx_import_title_caches_imported), imported + " " + res.getString(R.string.gpx_import_caches_imported)); - imported = 0; - } catch (Exception e) { - if (parseDialog != null) { - parseDialog.dismiss(); - } - } - } - }; - - @Override - protected cgGPXListAdapter getAdapter(List<File> files) { - return new cgGPXListAdapter(this, getSettings(), files); - } - - @Override - protected String[] getBaseFolders() { - String base = Environment.getExternalStorageDirectory().toString(); - return new String[]{base + "/gpx"}; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Bundle extras = getIntent().getExtras(); - if (extras != null) { - listId = extras.getInt(EXTRAS_LIST_ID); - } - if (listId <= 0) { - listId = 1; - } - - } - - @Override - protected void setTitle() { - setTitle(res.getString(R.string.gpx_import_title)); - } - - public void loadGPX(File file) { - - parseDialog = ProgressDialog.show( - this, - res.getString(R.string.gpx_import_title_reading_file), - res.getString(R.string.gpx_import_loading), - true, - false); - - new loadCaches(file).start(); - } - - private class loadCaches extends Thread { - - File file = null; - - public loadCaches(File fileIn) { - file = fileIn; - } - - @Override - public void run() { - final UUID searchId; - String name = file.getName().toLowerCase(); - if (name.endsWith("gpx")) { - searchId = GPXParser.parseGPX(app, file, listId, changeParseDialogHandler); - } - else { - searchId = LocParser.parseLoc(app, file, listId, changeParseDialogHandler); - } - imported = app.getCount(searchId); - - loadCachesHandler.sendMessage(new Message()); - } - } - - 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); - } + private static final String EXTRAS_LIST_ID = "list"; + + public cgeogpxes() { + super(new String[] { "gpx" + // TODO , "loc" + }); + } + + private ProgressDialog parseDialog = null; + private int listId = 1; + private int imported = 0; + + final private Handler changeParseDialogHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (msg.obj != null && parseDialog != null) { + parseDialog.setMessage(res.getString(R.string.gpx_import_loading_stored) + " " + (Integer) msg.obj); + } + } + }; + final private Handler loadCachesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (parseDialog != null) { + parseDialog.dismiss(); + } + + helpDialog(res.getString(R.string.gpx_import_title_caches_imported), imported + " " + res.getString(R.string.gpx_import_caches_imported)); + imported = 0; + } catch (Exception e) { + if (parseDialog != null) { + parseDialog.dismiss(); + } + } + } + }; + + @Override + protected cgGPXListAdapter getAdapter(List<File> files) { + return new cgGPXListAdapter(this, getSettings(), files); + } + + @Override + protected String[] getBaseFolders() { + String base = Environment.getExternalStorageDirectory().toString(); + return new String[] { base + "/gpx" }; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle extras = getIntent().getExtras(); + if (extras != null) { + listId = extras.getInt(EXTRAS_LIST_ID); + } + if (listId <= 0) { + listId = 1; + } + + } + + @Override + protected void setTitle() { + setTitle(res.getString(R.string.gpx_import_title)); + } + + public void loadGPX(File file) { + + parseDialog = ProgressDialog.show( + this, + res.getString(R.string.gpx_import_title_reading_file), + res.getString(R.string.gpx_import_loading), + true, + false); + + new loadCaches(file).start(); + } + + private class loadCaches extends Thread { + + File file = null; + + public loadCaches(File fileIn) { + file = fileIn; + } + + @Override + public void run() { + final UUID searchId; + String name = file.getName().toLowerCase(); + if (name.endsWith("gpx")) { + searchId = GPXParser.parseGPX(app, file, listId, changeParseDialogHandler); + } + else { + searchId = LocParser.parseLoc(app, file, listId, changeParseDialogHandler); + } + imported = app.getCount(searchId); + + loadCachesHandler.sendMessage(new Message()); + } + } + + 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); + } } diff --git a/src/cgeo/geocaching/cgeohelpers.java b/src/cgeo/geocaching/cgeohelpers.java index 85cf422..cc288b1 100644 --- a/src/cgeo/geocaching/cgeohelpers.java +++ b/src/cgeo/geocaching/cgeohelpers.java @@ -1,63 +1,64 @@ package cgeo.geocaching; -import java.util.Locale; +import cgeo.geocaching.activity.AbstractActivity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; -import cgeo.geocaching.activity.AbstractActivity; + +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(); - - settings.load(); - } - - 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(); - } - - 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"); - } - } - - public void installLocus(View view) { - installFromMarket("menion.android.locus"); - } - - public void installGpsStatus(View view) { - installFromMarket("com.eclipsim.gpsstatus2"); - } - - public void installBluetoothGps(View view) { - installFromMarket("googoo.android.btgps"); - } + @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(); + + settings.load(); + } + + 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(); + } + + 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"); + } + } + + public void installLocus(View view) { + installFromMarket("menion.android.locus"); + } + + public void installGpsStatus(View view) { + installFromMarket("com.eclipsim.gpsstatus2"); + } + + public void installBluetoothGps(View view) { + installFromMarket("googoo.android.btgps"); + } } diff --git a/src/cgeo/geocaching/cgeoimages.java b/src/cgeo/geocaching/cgeoimages.java index 4dd3d55..c1a6bee 100644 --- a/src/cgeo/geocaching/cgeoimages.java +++ b/src/cgeo/geocaching/cgeoimages.java @@ -1,9 +1,6 @@ package cgeo.geocaching; -import java.io.File; -import java.io.FileOutputStream; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.activity.AbstractActivity; import org.apache.commons.lang3.StringUtils; @@ -25,278 +22,282 @@ import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.List; public class cgeoimages extends AbstractActivity { - public static final int LOG_IMAGE = 1; - public static final int SPOILER_IMAGE = 2; - - private int img_type; - private List<cgImage> images = new ArrayList<cgImage>(); - private String geocode = null; - private String title = null; - private String url = null; - private LayoutInflater inflater = null; - private ProgressDialog progressDialog = null; - private ProgressDialog waitDialog = null; - private LinearLayout imagesView = null; - private int offline = 0; - private boolean save = true; - private int count = 0; - private int countDone = 0; - private String load_process_string; - - private Handler loadImagesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (images.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - switch (img_type) { - case LOG_IMAGE: - showToast(res.getString(R.string.warn_load_log_image)); - break; - case SPOILER_IMAGE: - showToast(res.getString(R.string.warn_load_spoiler_image)); - break; - } - - finish(); - return; - } else { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - if (app.isOffline(geocode, null)) { - offline = 1; - if ((img_type == LOG_IMAGE) && (settings.storelogimages == false)) { - offline = 0; - } - } else { - offline = 0; - } - - count = images.size(); - progressDialog = new ProgressDialog(cgeoimages.this); - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - progressDialog.setMessage(load_process_string); - progressDialog.setCancelable(true); - progressDialog.setMax(count); - progressDialog.show(); - - LinearLayout rowView = null; - 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.title)); - - if (StringUtils.isNotBlank(img.description)) { - final TextView descView = (TextView) rowView.findViewById(R.id.description); - descView.setText(Html.fromHtml(img.description), TextView.BufferType.SPANNABLE); - descView.setVisibility(View.VISIBLE); - } - - final Handler handler = new onLoadHandler(rowView, img); - - new Thread() { - - @Override - public void run() { - BitmapDrawable image = null; - try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeoimages.this, geocode, true, offline, false, save); - - image = imgGetter.getDrawable(img.url); - Message message = handler.obtainMessage(0, image); - handler.sendMessage(message); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.onCreate.onClick.run: " + e.toString()); - } - - } - }.start(); - - imagesView.addView(rowView); - } - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler: " + e.toString()); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - setTheme(); - setContentView(R.layout.spoilers); - - // get parameters - Bundle extras = getIntent().getExtras(); - - // try to get data from extras - if (extras != null) { - geocode = extras.getString("geocode"); - img_type = extras.getInt("type", 0); - } - - // google analytics - if (img_type == SPOILER_IMAGE) - { - setTitle(res.getString(R.string.cache_spoiler_images_title)); - } else if (img_type == LOG_IMAGE) { - setTitle(res.getString(R.string.cache_log_images_title)); - } - - if (geocode == null) { - showToast("Sorry, c:geo forgot for what cache you want to load spoiler images."); - finish(); - return; - } - switch (img_type) { - case LOG_IMAGE: - title = extras.getString("title"); - url = extras.getString("url"); - if ((title == null) || (url == null)) { - showToast("Sorry, c:geo forgot which logimage you wanted to load."); - finish(); - return; - } - break; - } - - inflater = getLayoutInflater(); - if (imagesView == null) { - imagesView = (LinearLayout) findViewById(R.id.spoiler_list); - } - - switch (img_type) { - case SPOILER_IMAGE: - load_process_string = res.getString(R.string.cache_spoiler_images_loading); - save = true; - break; - case LOG_IMAGE: - load_process_string = res.getString(R.string.cache_log_images_loading); - if (settings.storelogimages) { - save = true; - } else { - save = false; - } - break; - default: - load_process_string = "Loading..."; - } - waitDialog = ProgressDialog.show(this, null, load_process_string, true); - waitDialog.setCancelable(true); - - switch (img_type) { - case LOG_IMAGE: - cgImage logimage = new cgImage(); - logimage.title = title; - logimage.url = url; - logimage.description = ""; - images.add(logimage); - try { - loadImagesHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler.sendMessage: " + e.toString()); - } - break; - case SPOILER_IMAGE: - (new loadSpoilers()).start(); - break; - default: - showToast("Sorry, can't load unknown image type."); - finish(); - } - - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - private class loadSpoilers extends Thread { - - @Override - public void run() { - try { - images = app.loadSpoilers(geocode); - - loadImagesHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.loadSpoilers.run: " + e.toString()); - } - } - } - - private class onLoadHandler extends Handler { - - LinearLayout view = null; - - public onLoadHandler(LinearLayout view, cgImage image) { - this.view = view; - } - - @Override - public void handleMessage(Message message) { - final BitmapDrawable image = (BitmapDrawable) message.obj; - if (image != null) { - ImageView image_view = null; - image_view = (ImageView) inflater.inflate(R.layout.image_item, null); - - Rect bounds = image.getBounds(); - - image_view.setImageResource(R.drawable.image_not_loaded); - image_view.setClickable(true); - image_view.setOnClickListener(new View.OnClickListener() { - - public void onClick(View arg0) { - final String directoryTarget = Environment.getExternalStorageDirectory() + "/" + cgSettings.cache + "/" + "temp.jpg"; - final File file = new File(directoryTarget); - try { - final FileOutputStream fos = new FileOutputStream(file); - image.getBitmap().compress(CompressFormat.JPEG, 100, fos); - fos.close(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.handleMessage.onClick: " + e.toString()); - return; - } - - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(file), "image/jpg"); - startActivity(intent); - - if (file.exists()) - file.deleteOnExit(); - } - }); - image_view.setImageDrawable(image); - image_view.setScaleType(ImageView.ScaleType.CENTER_CROP); - image_view.setLayoutParams(new LayoutParams(bounds.width(), bounds.height())); - - view.addView(image_view); - } - - countDone++; - progressDialog.setProgress(countDone); - if (progressDialog.getProgress() >= count) { - progressDialog.dismiss(); - } - } - } + public static final int LOG_IMAGE = 1; + public static final int SPOILER_IMAGE = 2; + + private int img_type; + private List<cgImage> images = new ArrayList<cgImage>(); + private String geocode = null; + private String title = null; + private String url = null; + private LayoutInflater inflater = null; + private ProgressDialog progressDialog = null; + private ProgressDialog waitDialog = null; + private LinearLayout imagesView = null; + private int offline = 0; + private boolean save = true; + private int count = 0; + private int countDone = 0; + private String load_process_string; + + private Handler loadImagesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (images.isEmpty()) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + switch (img_type) { + case LOG_IMAGE: + showToast(res.getString(R.string.warn_load_log_image)); + break; + case SPOILER_IMAGE: + showToast(res.getString(R.string.warn_load_spoiler_image)); + break; + } + + finish(); + return; + } else { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + if (app.isOffline(geocode, null)) { + offline = 1; + if ((img_type == LOG_IMAGE) && (settings.storelogimages == false)) { + offline = 0; + } + } else { + offline = 0; + } + + count = images.size(); + progressDialog = new ProgressDialog(cgeoimages.this); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setMessage(load_process_string); + progressDialog.setCancelable(true); + progressDialog.setMax(count); + progressDialog.show(); + + LinearLayout rowView = null; + 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.title)); + + if (StringUtils.isNotBlank(img.description)) { + final TextView descView = (TextView) rowView.findViewById(R.id.description); + descView.setText(Html.fromHtml(img.description), TextView.BufferType.SPANNABLE); + descView.setVisibility(View.VISIBLE); + } + + final Handler handler = new onLoadHandler(rowView, img); + + new Thread() { + + @Override + public void run() { + BitmapDrawable image = null; + try { + cgHtmlImg imgGetter = new cgHtmlImg(cgeoimages.this, geocode, true, offline, false, save); + + image = imgGetter.getDrawable(img.url); + Message message = handler.obtainMessage(0, image); + handler.sendMessage(message); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoimages.onCreate.onClick.run: " + e.toString()); + } + + } + }.start(); + + imagesView.addView(rowView); + } + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler: " + e.toString()); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + setTheme(); + setContentView(R.layout.spoilers); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + if (extras != null) { + geocode = extras.getString("geocode"); + img_type = extras.getInt("type", 0); + } + + // google analytics + if (img_type == SPOILER_IMAGE) + { + setTitle(res.getString(R.string.cache_spoiler_images_title)); + } else if (img_type == LOG_IMAGE) { + setTitle(res.getString(R.string.cache_log_images_title)); + } + + if (geocode == null) { + showToast("Sorry, c:geo forgot for what cache you want to load spoiler images."); + finish(); + return; + } + switch (img_type) { + case LOG_IMAGE: + title = extras.getString("title"); + url = extras.getString("url"); + if ((title == null) || (url == null)) { + showToast("Sorry, c:geo forgot which logimage you wanted to load."); + finish(); + return; + } + break; + } + + inflater = getLayoutInflater(); + if (imagesView == null) { + imagesView = (LinearLayout) findViewById(R.id.spoiler_list); + } + + switch (img_type) { + case SPOILER_IMAGE: + load_process_string = res.getString(R.string.cache_spoiler_images_loading); + save = true; + break; + case LOG_IMAGE: + load_process_string = res.getString(R.string.cache_log_images_loading); + if (settings.storelogimages) { + save = true; + } else { + save = false; + } + break; + default: + load_process_string = "Loading..."; + } + waitDialog = ProgressDialog.show(this, null, load_process_string, true); + waitDialog.setCancelable(true); + + switch (img_type) { + case LOG_IMAGE: + cgImage logimage = new cgImage(); + logimage.title = title; + logimage.url = url; + logimage.description = ""; + images.add(logimage); + try { + loadImagesHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler.sendMessage: " + e.toString()); + } + break; + case SPOILER_IMAGE: + (new loadSpoilers()).start(); + break; + default: + showToast("Sorry, can't load unknown image type."); + finish(); + } + + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + private class loadSpoilers extends Thread { + + @Override + public void run() { + try { + images = app.loadSpoilers(geocode); + + loadImagesHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoimages.loadSpoilers.run: " + e.toString()); + } + } + } + + private class onLoadHandler extends Handler { + + LinearLayout view = null; + + public onLoadHandler(LinearLayout view, cgImage image) { + this.view = view; + } + + @Override + public void handleMessage(Message message) { + final BitmapDrawable image = (BitmapDrawable) message.obj; + if (image != null) { + ImageView image_view = null; + image_view = (ImageView) inflater.inflate(R.layout.image_item, null); + + Rect bounds = image.getBounds(); + + image_view.setImageResource(R.drawable.image_not_loaded); + image_view.setClickable(true); + image_view.setOnClickListener(new View.OnClickListener() { + + public void onClick(View arg0) { + final String directoryTarget = Environment.getExternalStorageDirectory() + "/" + cgSettings.cache + "/" + "temp.jpg"; + final File file = new File(directoryTarget); + try { + final FileOutputStream fos = new FileOutputStream(file); + image.getBitmap().compress(CompressFormat.JPEG, 100, fos); + fos.close(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeoimages.handleMessage.onClick: " + e.toString()); + return; + } + + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(Uri.fromFile(file), "image/jpg"); + startActivity(intent); + + if (file.exists()) + file.deleteOnExit(); + } + }); + image_view.setImageDrawable(image); + image_view.setScaleType(ImageView.ScaleType.CENTER_CROP); + image_view.setLayoutParams(new LayoutParams(bounds.width(), bounds.height())); + + view.addView(image_view); + } + + countDone++; + progressDialog.setProgress(countDone); + if (progressDialog.getProgress() >= count) { + progressDialog.dismiss(); + } + } + } } diff --git a/src/cgeo/geocaching/cgeoinit.java b/src/cgeo/geocaching/cgeoinit.java index c755fa7..ce74985 100644 --- a/src/cgeo/geocaching/cgeoinit.java +++ b/src/cgeo/geocaching/cgeoinit.java @@ -1,6 +1,8 @@ package cgeo.geocaching; -import java.io.File; +import cgeo.geocaching.LogTemplateProvider.LogTemplate; +import cgeo.geocaching.cgSettings.mapSourceEnum; +import cgeo.geocaching.activity.AbstractActivity; import org.apache.commons.lang3.StringUtils; @@ -26,302 +28,301 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -import cgeo.geocaching.LogTemplateProvider.LogTemplate; -import cgeo.geocaching.cgSettings.mapSourceEnum; -import cgeo.geocaching.activity.AbstractActivity; + +import java.io.File; public class cgeoinit extends AbstractActivity { - private final int SELECT_MAPFILE_REQUEST=1; - - private ProgressDialog loginDialog = null; - private ProgressDialog webDialog = null; - private Handler logInHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (loginDialog != null && loginDialog.isShowing()) { - loginDialog.dismiss(); - } - - if (msg.what == 1) { - helpDialog(res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_ok)); - } else { - if (cgBase.errorRetrieve.containsKey(msg.what)) { - helpDialog(res.getString(R.string.init_login_popup), - res.getString(R.string.init_login_popup_failed_reason) + " " + cgBase.errorRetrieve.get(msg.what) + "."); - } else { - helpDialog(res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_failed)); - } - } - } catch (Exception e) { - showToast(res.getString(R.string.err_login_failed)); - - Log.e(cgSettings.tag, "cgeoinit.logInHandler: " + e.toString()); - } - - if (loginDialog != null && loginDialog.isShowing()) { - loginDialog.dismiss(); - } - - init(); - } - }; - - private Handler webAuthHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (webDialog != null && webDialog.isShowing()) { - webDialog.dismiss(); - } - - if (msg.what > 0) { - helpDialog(res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_register_ok).replace("####", ""+msg.what)); - } else { - helpDialog(res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_register_fail)); - } - } catch (Exception e) { - showToast(res.getString(R.string.init_sendToCgeo_register_fail)); - - Log.e(cgSettings.tag, "cgeoinit.webHandler: " + e.toString()); - } - - if (webDialog != null && webDialog.isShowing()) { - webDialog.dismiss(); - } - - init(); - } - }; - protected boolean enableTemplatesMenu = false; - - public cgeoinit() { - super("c:geo-configuration"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - - setTheme(); - setContentView(R.layout.init); - setTitle(res.getString(R.string.settings)); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onPause() { - saveValues(); - super.onPause(); - } - - @Override - public void onStop() { - saveValues(); - super.onStop(); - } - - @Override - public void onDestroy() { - saveValues(); - - super.onDestroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, 0, 0, res.getString(R.string.init_clear)).setIcon(android.R.drawable.ic_menu_delete); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == 0) { - boolean status = false; - - ((EditText) findViewById(R.id.username)).setText(""); - ((EditText) findViewById(R.id.password)).setText(""); - ((EditText) findViewById(R.id.passvote)).setText(""); - - status = saveValues(); - if (status) { - showToast(res.getString(R.string.init_cleared)); - } else { - showToast(res.getString(R.string.err_init_cleared)); - } - - finish(); - } - - return false; - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - if (enableTemplatesMenu) { - menu.setHeaderTitle(R.string.init_signature_template_button); - for (LogTemplate template : LogTemplateProvider.getTemplates()) { - menu.add(0, template.getItemId(), 0, template.getResourceId()); - } - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - LogTemplate template = LogTemplateProvider.getTemplate(item.getItemId()); - if (template != null) { - return insertSignatureTemplate(template); - } - return super.onContextItemSelected(item); - } - - private boolean insertSignatureTemplate(final LogTemplate template) { - EditText sig = (EditText) findViewById(R.id.signature); - String insertText = "[" + template.getTemplateString() + "]"; - cgBase.insertAtPosition(sig, insertText, true); - return true; - } - - public void init() { - - // geocaching.com settings - String usernameNow = prefs.getString("username", null); - if (usernameNow != null) { - ((EditText) findViewById(R.id.username)).setText(usernameNow); - } - String passwordNow = prefs.getString("password", null); - if (usernameNow != null) { - ((EditText) findViewById(R.id.password)).setText(passwordNow); - } - - Button logMeIn = (Button) findViewById(R.id.log_me_in); - logMeIn.setOnClickListener(new logIn()); - - TextView legalNote = (TextView) findViewById(R.id.legal_note); - legalNote.setClickable(true); - legalNote.setOnClickListener(new View.OnClickListener() { - - public void onClick(View arg0) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/about/termsofuse.aspx"))); - } - }); - - // gcvote settings - String passvoteNow = prefs.getString("pass-vote", null); - if (passvoteNow != null) { - ((EditText) findViewById(R.id.passvote)).setText(passvoteNow); - } - - // go4cache settings - TextView go4cache = (TextView) findViewById(R.id.about_go4cache); - go4cache.setClickable(true); - go4cache.setOnClickListener(new View.OnClickListener() { - - public void onClick(View arg0) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://go4cache.com/"))); - } - }); - - CheckBox publicButton = (CheckBox) findViewById(R.id.publicloc); - if (prefs.getInt("publicloc", 0) == 0) { - publicButton.setChecked(false); - } else { - publicButton.setChecked(true); - } - publicButton.setOnClickListener(new cgeoChangePublic()); - - // Twitter settings - Button authorizeTwitter = (Button) findViewById(R.id.authorize_twitter); - authorizeTwitter.setOnClickListener(new View.OnClickListener() { - - public void onClick(View arg0) { - Intent authIntent = new Intent(cgeoinit.this, cgeoauth.class); - startActivity(authIntent); - } - }); - - CheckBox twitterButton = (CheckBox) findViewById(R.id.twitter_option); - if (prefs.getInt("twitter", 0) == 0 || StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret)) { - twitterButton.setChecked(false); - } else { - twitterButton.setChecked(true); - } - twitterButton.setOnClickListener(new cgeoChangeTwitter()); - - // Signature settings - EditText sigEdit = (EditText) findViewById(R.id.signature); - if (sigEdit.getText().length() == 0) { - sigEdit.setText(settings.getSignature()); - } - Button sigBtn = (Button) findViewById(R.id.signature_help); - sigBtn.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - helpDialog(res.getString(R.string.init_signature_help_title), res.getString(R.string.init_signature_help_text)); - } - }); - Button templates = (Button) findViewById(R.id.signature_template); - registerForContextMenu(templates); - templates.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - enableTemplatesMenu = true; - openContextMenu(v); - enableTemplatesMenu = false; - } - }); - CheckBox autoinsertButton = (CheckBox) findViewById(R.id.sigautoinsert); + private final int SELECT_MAPFILE_REQUEST = 1; + + private ProgressDialog loginDialog = null; + private ProgressDialog webDialog = null; + private Handler logInHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (loginDialog != null && loginDialog.isShowing()) { + loginDialog.dismiss(); + } + + if (msg.what == 1) { + helpDialog(res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_ok)); + } else { + if (cgBase.errorRetrieve.containsKey(msg.what)) { + helpDialog(res.getString(R.string.init_login_popup), + res.getString(R.string.init_login_popup_failed_reason) + " " + cgBase.errorRetrieve.get(msg.what) + "."); + } else { + helpDialog(res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_failed)); + } + } + } catch (Exception e) { + showToast(res.getString(R.string.err_login_failed)); + + Log.e(cgSettings.tag, "cgeoinit.logInHandler: " + e.toString()); + } + + if (loginDialog != null && loginDialog.isShowing()) { + loginDialog.dismiss(); + } + + init(); + } + }; + + private Handler webAuthHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (webDialog != null && webDialog.isShowing()) { + webDialog.dismiss(); + } + + if (msg.what > 0) { + helpDialog(res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_register_ok).replace("####", "" + msg.what)); + } else { + helpDialog(res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_register_fail)); + } + } catch (Exception e) { + showToast(res.getString(R.string.init_sendToCgeo_register_fail)); + + Log.e(cgSettings.tag, "cgeoinit.webHandler: " + e.toString()); + } + + if (webDialog != null && webDialog.isShowing()) { + webDialog.dismiss(); + } + + init(); + } + }; + protected boolean enableTemplatesMenu = false; + + public cgeoinit() { + super("c:geo-configuration"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // init + + setTheme(); + setContentView(R.layout.init); + setTitle(res.getString(R.string.settings)); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onPause() { + saveValues(); + super.onPause(); + } + + @Override + public void onStop() { + saveValues(); + super.onStop(); + } + + @Override + public void onDestroy() { + saveValues(); + + super.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, 0, 0, res.getString(R.string.init_clear)).setIcon(android.R.drawable.ic_menu_delete); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == 0) { + boolean status = false; + + ((EditText) findViewById(R.id.username)).setText(""); + ((EditText) findViewById(R.id.password)).setText(""); + ((EditText) findViewById(R.id.passvote)).setText(""); + + status = saveValues(); + if (status) { + showToast(res.getString(R.string.init_cleared)); + } else { + showToast(res.getString(R.string.err_init_cleared)); + } + + finish(); + } + + return false; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + if (enableTemplatesMenu) { + menu.setHeaderTitle(R.string.init_signature_template_button); + for (LogTemplate template : LogTemplateProvider.getTemplates()) { + menu.add(0, template.getItemId(), 0, template.getResourceId()); + } + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + LogTemplate template = LogTemplateProvider.getTemplate(item.getItemId()); + if (template != null) { + return insertSignatureTemplate(template); + } + return super.onContextItemSelected(item); + } + + private boolean insertSignatureTemplate(final LogTemplate template) { + EditText sig = (EditText) findViewById(R.id.signature); + String insertText = "[" + template.getTemplateString() + "]"; + cgBase.insertAtPosition(sig, insertText, true); + return true; + } + + public void init() { + + // geocaching.com settings + String usernameNow = prefs.getString("username", null); + if (usernameNow != null) { + ((EditText) findViewById(R.id.username)).setText(usernameNow); + } + String passwordNow = prefs.getString("password", null); + if (usernameNow != null) { + ((EditText) findViewById(R.id.password)).setText(passwordNow); + } + + Button logMeIn = (Button) findViewById(R.id.log_me_in); + logMeIn.setOnClickListener(new logIn()); + + TextView legalNote = (TextView) findViewById(R.id.legal_note); + legalNote.setClickable(true); + legalNote.setOnClickListener(new View.OnClickListener() { + + public void onClick(View arg0) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/about/termsofuse.aspx"))); + } + }); + + // gcvote settings + String passvoteNow = prefs.getString("pass-vote", null); + if (passvoteNow != null) { + ((EditText) findViewById(R.id.passvote)).setText(passvoteNow); + } + + // go4cache settings + TextView go4cache = (TextView) findViewById(R.id.about_go4cache); + go4cache.setClickable(true); + go4cache.setOnClickListener(new View.OnClickListener() { + + public void onClick(View arg0) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://go4cache.com/"))); + } + }); + + CheckBox publicButton = (CheckBox) findViewById(R.id.publicloc); + if (prefs.getInt("publicloc", 0) == 0) { + publicButton.setChecked(false); + } else { + publicButton.setChecked(true); + } + publicButton.setOnClickListener(new cgeoChangePublic()); + + // Twitter settings + Button authorizeTwitter = (Button) findViewById(R.id.authorize_twitter); + authorizeTwitter.setOnClickListener(new View.OnClickListener() { + + public void onClick(View arg0) { + Intent authIntent = new Intent(cgeoinit.this, cgeoauth.class); + startActivity(authIntent); + } + }); + + CheckBox twitterButton = (CheckBox) findViewById(R.id.twitter_option); + if (prefs.getInt("twitter", 0) == 0 || StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret)) { + twitterButton.setChecked(false); + } else { + twitterButton.setChecked(true); + } + twitterButton.setOnClickListener(new cgeoChangeTwitter()); + + // Signature settings + EditText sigEdit = (EditText) findViewById(R.id.signature); + if (sigEdit.getText().length() == 0) { + sigEdit.setText(settings.getSignature()); + } + Button sigBtn = (Button) findViewById(R.id.signature_help); + sigBtn.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + helpDialog(res.getString(R.string.init_signature_help_title), res.getString(R.string.init_signature_help_text)); + } + }); + Button templates = (Button) findViewById(R.id.signature_template); + registerForContextMenu(templates); + templates.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + enableTemplatesMenu = true; + openContextMenu(v); + enableTemplatesMenu = false; + } + }); + CheckBox autoinsertButton = (CheckBox) findViewById(R.id.sigautoinsert); autoinsertButton.setChecked(prefs.getBoolean("sigautoinsert", false)); autoinsertButton.setOnClickListener(new cgeoChangeSignatureAutoinsert()); - // Other settings - CheckBox skinButton = (CheckBox) findViewById(R.id.skin); - if (prefs.getInt("skin", 0) == 0) { - skinButton.setChecked(false); - } else { - skinButton.setChecked(true); - } - skinButton.setOnClickListener(new cgeoChangeSkin()); - - CheckBox addressButton = (CheckBox) findViewById(R.id.address); - if (prefs.getInt("showaddress", 1) == 0) { - addressButton.setChecked(false); - } else { - addressButton.setChecked(true); - } - addressButton.setOnClickListener(new cgeoChangeAddress()); - - CheckBox captchaButton = (CheckBox) findViewById(R.id.captcha); - if (prefs.getBoolean("showcaptcha", false) == false) { - captchaButton.setChecked(false); - } else { - captchaButton.setChecked(true); - } - captchaButton.setOnClickListener(new cgeoChangeCaptcha()); - - final CheckBox dirImgButton = (CheckBox) findViewById(R.id.loaddirectionimg); - dirImgButton.setChecked(settings.getLoadDirImg()); - dirImgButton.setOnClickListener(new View.OnClickListener() { + // Other settings + CheckBox skinButton = (CheckBox) findViewById(R.id.skin); + if (prefs.getInt("skin", 0) == 0) { + skinButton.setChecked(false); + } else { + skinButton.setChecked(true); + } + skinButton.setOnClickListener(new cgeoChangeSkin()); + + CheckBox addressButton = (CheckBox) findViewById(R.id.address); + if (prefs.getInt("showaddress", 1) == 0) { + addressButton.setChecked(false); + } else { + addressButton.setChecked(true); + } + addressButton.setOnClickListener(new cgeoChangeAddress()); + + CheckBox captchaButton = (CheckBox) findViewById(R.id.captcha); + if (prefs.getBoolean("showcaptcha", false) == false) { + captchaButton.setChecked(false); + } else { + captchaButton.setChecked(true); + } + captchaButton.setOnClickListener(new cgeoChangeCaptcha()); + + final CheckBox dirImgButton = (CheckBox) findViewById(R.id.loaddirectionimg); + dirImgButton.setChecked(settings.getLoadDirImg()); + dirImgButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -330,31 +331,31 @@ public class cgeoinit extends AbstractActivity { } }); - CheckBox useEnglishButton = (CheckBox) findViewById(R.id.useenglish); - if (prefs.getBoolean("useenglish", false) == false) { - useEnglishButton.setChecked(false); - } else { - useEnglishButton.setChecked(true); - } - useEnglishButton.setOnClickListener(new cgeoChangeUseEnglish()); - - CheckBox excludeButton = (CheckBox) findViewById(R.id.exclude); - if (prefs.getInt("excludemine", 0) == 0) { - excludeButton.setChecked(false); - } else { - excludeButton.setChecked(true); - } - excludeButton.setOnClickListener(new cgeoChangeExclude()); - - CheckBox disabledButton = (CheckBox) findViewById(R.id.disabled); - if (prefs.getInt("excludedisabled", 0) == 0) { - disabledButton.setChecked(false); - } else { - disabledButton.setChecked(true); - } - disabledButton.setOnClickListener(new cgeoChangeDisabled()); - - CheckBox autovisitButton = (CheckBox) findViewById(R.id.trackautovisit); + CheckBox useEnglishButton = (CheckBox) findViewById(R.id.useenglish); + if (prefs.getBoolean("useenglish", false) == false) { + useEnglishButton.setChecked(false); + } else { + useEnglishButton.setChecked(true); + } + useEnglishButton.setOnClickListener(new cgeoChangeUseEnglish()); + + CheckBox excludeButton = (CheckBox) findViewById(R.id.exclude); + if (prefs.getInt("excludemine", 0) == 0) { + excludeButton.setChecked(false); + } else { + excludeButton.setChecked(true); + } + excludeButton.setOnClickListener(new cgeoChangeExclude()); + + CheckBox disabledButton = (CheckBox) findViewById(R.id.disabled); + if (prefs.getInt("excludedisabled", 0) == 0) { + disabledButton.setChecked(false); + } else { + disabledButton.setChecked(true); + } + disabledButton.setOnClickListener(new cgeoChangeDisabled()); + + CheckBox autovisitButton = (CheckBox) findViewById(R.id.trackautovisit); if (prefs.getBoolean("trackautovisit", false)) { autovisitButton.setChecked(true); } else { @@ -362,375 +363,374 @@ public class cgeoinit extends AbstractActivity { } autovisitButton.setOnClickListener(new cgeoChangeAutovisit()); - CheckBox offlineButton = (CheckBox) findViewById(R.id.offline); - if (prefs.getInt("offlinemaps", 1) == 0) { - offlineButton.setChecked(false); - } else { - offlineButton.setChecked(true); - } - offlineButton.setOnClickListener(new cgeoChangeOffline()); - - CheckBox saveLogImgButton = (CheckBox) findViewById(R.id.save_log_img); - if (prefs.getBoolean("logimages", false) == false) { - saveLogImgButton.setChecked(false); - } else { - saveLogImgButton.setChecked(true); - } - saveLogImgButton.setOnClickListener(new cgeoChangeSaveLogImg()); - - - CheckBox autoloadButton = (CheckBox) findViewById(R.id.autoload); - if (prefs.getInt("autoloaddesc", 0) == 0) { - autoloadButton.setChecked(false); - } else { - autoloadButton.setChecked(true); - } - autoloadButton.setOnClickListener(new cgeoChangeAutoload()); - - CheckBox livelistButton = (CheckBox) findViewById(R.id.livelist); - if (prefs.getInt("livelist", 1) == 0) { - livelistButton.setChecked(false); - } else { - livelistButton.setChecked(true); - } - livelistButton.setOnClickListener(new cgeoChangeLivelist()); - - CheckBox unitsButton = (CheckBox) findViewById(R.id.units); - if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { - unitsButton.setChecked(false); - } else { - unitsButton.setChecked(true); - } - unitsButton.setOnClickListener(new cgeoChangeUnits()); - - CheckBox gnavButton = (CheckBox) findViewById(R.id.gnav); - if (prefs.getInt("usegnav", 1) == 1) { - gnavButton.setChecked(true); - } else { - gnavButton.setChecked(false); - } - gnavButton.setOnClickListener(new cgeoChangeGNav()); - - final CheckBox logOffline = (CheckBox) findViewById(R.id.log_offline); - logOffline.setChecked(settings.getLogOffline()); - logOffline.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - settings.setLogOffline(!settings.getLogOffline()); - logOffline.setChecked(settings.getLogOffline()); - } - }); - - CheckBox browserButton = (CheckBox) findViewById(R.id.browser); - if (prefs.getInt("asbrowser", 1) == 0) { - browserButton.setChecked(false); - } else { - browserButton.setChecked(true); - } - browserButton.setOnClickListener(new cgeoChangeBrowser()); - - // Altitude settings - EditText altitudeEdit = (EditText) findViewById(R.id.altitude); - altitudeEdit.setText("" + prefs.getInt("altcorrection", 0)); - - //Send2cgeo settings - String webDeviceName = prefs.getString("webDeviceName", null); - - if (StringUtils.isNotBlank(webDeviceName)) { - ((EditText) findViewById(R.id.webDeviceName)).setText(webDeviceName); - } else { - String s = android.os.Build.MODEL; - ((EditText) findViewById(R.id.webDeviceName)).setText(s); + CheckBox offlineButton = (CheckBox) findViewById(R.id.offline); + if (prefs.getInt("offlinemaps", 1) == 0) { + offlineButton.setChecked(false); + } else { + offlineButton.setChecked(true); + } + offlineButton.setOnClickListener(new cgeoChangeOffline()); + + CheckBox saveLogImgButton = (CheckBox) findViewById(R.id.save_log_img); + if (prefs.getBoolean("logimages", false) == false) { + saveLogImgButton.setChecked(false); + } else { + saveLogImgButton.setChecked(true); + } + saveLogImgButton.setOnClickListener(new cgeoChangeSaveLogImg()); + + CheckBox autoloadButton = (CheckBox) findViewById(R.id.autoload); + if (prefs.getInt("autoloaddesc", 0) == 0) { + autoloadButton.setChecked(false); + } else { + autoloadButton.setChecked(true); + } + autoloadButton.setOnClickListener(new cgeoChangeAutoload()); + + CheckBox livelistButton = (CheckBox) findViewById(R.id.livelist); + if (prefs.getInt("livelist", 1) == 0) { + livelistButton.setChecked(false); + } else { + livelistButton.setChecked(true); + } + livelistButton.setOnClickListener(new cgeoChangeLivelist()); + + CheckBox unitsButton = (CheckBox) findViewById(R.id.units); + if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { + unitsButton.setChecked(false); + } else { + unitsButton.setChecked(true); + } + unitsButton.setOnClickListener(new cgeoChangeUnits()); + + CheckBox gnavButton = (CheckBox) findViewById(R.id.gnav); + if (prefs.getInt("usegnav", 1) == 1) { + gnavButton.setChecked(true); + } else { + gnavButton.setChecked(false); + } + gnavButton.setOnClickListener(new cgeoChangeGNav()); + + final CheckBox logOffline = (CheckBox) findViewById(R.id.log_offline); + logOffline.setChecked(settings.getLogOffline()); + logOffline.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + settings.setLogOffline(!settings.getLogOffline()); + logOffline.setChecked(settings.getLogOffline()); + } + }); + + CheckBox browserButton = (CheckBox) findViewById(R.id.browser); + if (prefs.getInt("asbrowser", 1) == 0) { + browserButton.setChecked(false); + } else { + browserButton.setChecked(true); + } + browserButton.setOnClickListener(new cgeoChangeBrowser()); + + // Altitude settings + EditText altitudeEdit = (EditText) findViewById(R.id.altitude); + altitudeEdit.setText("" + prefs.getInt("altcorrection", 0)); + + //Send2cgeo settings + String webDeviceName = prefs.getString("webDeviceName", null); + + if (StringUtils.isNotBlank(webDeviceName)) { + ((EditText) findViewById(R.id.webDeviceName)).setText(webDeviceName); + } else { + String s = android.os.Build.MODEL; + ((EditText) findViewById(R.id.webDeviceName)).setText(s); + } + + Button webAuth = (Button) findViewById(R.id.sendToCgeo_register); + webAuth.setOnClickListener(new webAuth()); + + // Map source settings + Spinner mapSourceSelector = (Spinner) findViewById(R.id.mapsource); + ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( + this, R.array.map_sources, android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mapSourceSelector.setAdapter(adapter); + int mapsource = prefs.getInt("mapsource", 0); + mapSourceSelector.setSelection(mapsource); + mapSourceSelector.setOnItemSelectedListener(new cgeoChangeMapSource()); + + initMapfileEdittext(false); + + Button selectMapfile = (Button) findViewById(R.id.select_mapfile); + selectMapfile.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + Intent selectIntent = new Intent(cgeoinit.this, cgSelectMapfile.class); + startActivityForResult(selectIntent, SELECT_MAPFILE_REQUEST); + } + }); + + showBackupDate(); + + } + + private void initMapfileEdittext(boolean setFocus) { + EditText mfmapFileEdit = (EditText) findViewById(R.id.mapfile); + mfmapFileEdit.setText(prefs.getString("mfmapfile", "")); + if (setFocus) { + mfmapFileEdit.requestFocus(); + } + } + + public void backup(View view) { + // avoid overwriting an existing backup with an empty database (can happen directly after reinstalling the app) + if (app.getAllStoredCachesCount(true, null, null) == 0) { + return; + } + + final String file = app.backupDatabase(); + + if (file != null) { + helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_success) + "\n" + file); + } else { + helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_failed)); + } + + showBackupDate(); + } + + private void showBackupDate() { + TextView lastBackup = (TextView) findViewById(R.id.backup_last); + File lastBackupFile = cgeoapplication.isRestoreFile(); + if (lastBackupFile != null) { + lastBackup.setText(res.getString(R.string.init_backup_last) + " " + base.formatTime(lastBackupFile.lastModified()) + ", " + base.formatDate(lastBackupFile.lastModified())); + } else { + lastBackup.setText(res.getString(R.string.init_backup_last_no)); + } + } + + public void restore(View view) { + final boolean status = app.restoreDatabase(); + + if (status) { + helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_success)); + } else { + helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_failed)); + } + } + + public boolean saveValues() { + String usernameNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.username)).getText().toString()); + String passwordNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.password)).getText().toString()); + String passvoteNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.passvote)).getText().toString()); + // don't trim signature, user may want to have whitespace at the beginning + String signatureNew = ((EditText) findViewById(R.id.signature)).getText().toString(); + String altitudeNew = StringUtils.trimToNull(((EditText) findViewById(R.id.altitude)).getText().toString()); + String mfmapFileNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.mapfile)).getText().toString()); + + int altitudeNewInt = 0; + if (altitudeNew != null) { + try { + altitudeNewInt = Integer.parseInt(altitudeNew); + } catch (NumberFormatException e) { + altitudeNewInt = 0; + } + } + + final boolean status1 = settings.setLogin(usernameNew, passwordNew); + final boolean status2 = settings.setGCvoteLogin(passvoteNew); + final boolean status3 = settings.setSignature(signatureNew); + final boolean status4 = settings.setAltCorrection(altitudeNewInt); + final boolean status5 = settings.setMapFile(mfmapFileNew); + + return status1 && status2 && status3 && status4 && status5; + } + + private class cgeoChangeTwitter implements View.OnClickListener { + + public void onClick(View arg0) { + CheckBox twitterButton = (CheckBox) findViewById(R.id.twitter_option); + + if (twitterButton.isChecked()) { + settings.reloadTwitterTokens(); + + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("twitter", 0) == 0) { + edit.putInt("twitter", 1); + settings.twitter = 1; + } else { + edit.putInt("twitter", 0); + settings.twitter = 0; + } + edit.commit(); + + if (settings.twitter == 1 && (StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret))) { + Intent authIntent = new Intent(cgeoinit.this, cgeoauth.class); + startActivity(authIntent); } - Button webAuth = (Button) findViewById(R.id.sendToCgeo_register); - webAuth.setOnClickListener(new webAuth()); - - // Map source settings - Spinner mapSourceSelector = (Spinner) findViewById(R.id.mapsource); - ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( - this, R.array.map_sources, android.R.layout.simple_spinner_item); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mapSourceSelector.setAdapter(adapter); - int mapsource = prefs.getInt("mapsource", 0); - mapSourceSelector.setSelection(mapsource); - mapSourceSelector.setOnItemSelectedListener(new cgeoChangeMapSource()); - - initMapfileEdittext(false); - - Button selectMapfile = (Button) findViewById(R.id.select_mapfile); - selectMapfile.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - Intent selectIntent = new Intent(cgeoinit.this, cgSelectMapfile.class); - startActivityForResult(selectIntent, SELECT_MAPFILE_REQUEST); - } - }); - - showBackupDate(); - - } - - private void initMapfileEdittext(boolean setFocus) { - EditText mfmapFileEdit = (EditText) findViewById(R.id.mapfile); - mfmapFileEdit.setText(prefs.getString("mfmapfile", "")); - if (setFocus) { - mfmapFileEdit.requestFocus(); - } - } - - public void backup(View view) { - // avoid overwriting an existing backup with an empty database (can happen directly after reinstalling the app) - if (app.getAllStoredCachesCount(true, null, null) == 0) { - return; - } - - final String file = app.backupDatabase(); - - if (file != null) { - helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_success) + "\n" + file); - } else { - helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_failed)); - } - - showBackupDate(); - } - - private void showBackupDate() { - TextView lastBackup = (TextView) findViewById(R.id.backup_last); - File lastBackupFile = cgeoapplication.isRestoreFile(); - if (lastBackupFile != null) { - lastBackup.setText(res.getString(R.string.init_backup_last) + " " + base.formatTime(lastBackupFile.lastModified()) + ", " + base.formatDate(lastBackupFile.lastModified())); - } else { - lastBackup.setText(res.getString(R.string.init_backup_last_no)); - } - } - - public void restore(View view) { - final boolean status = app.restoreDatabase(); - - if (status) { - helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_success)); - } else { - helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_failed)); - } - } - - public boolean saveValues() { - String usernameNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.username)).getText().toString()); - String passwordNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.password)).getText().toString()); - String passvoteNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.passvote)).getText().toString()); - // don't trim signature, user may want to have whitespace at the beginning - String signatureNew = ((EditText) findViewById(R.id.signature)).getText().toString(); - String altitudeNew = StringUtils.trimToNull(((EditText) findViewById(R.id.altitude)).getText().toString()); - String mfmapFileNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.mapfile)).getText().toString()); - - int altitudeNewInt = 0; - if (altitudeNew != null) { - try { - altitudeNewInt = Integer.parseInt(altitudeNew); - } catch (NumberFormatException e) { - altitudeNewInt = 0; - } - } - - final boolean status1 = settings.setLogin(usernameNew, passwordNew); - final boolean status2 = settings.setGCvoteLogin(passvoteNew); - final boolean status3 = settings.setSignature(signatureNew); - final boolean status4 = settings.setAltCorrection(altitudeNewInt); - final boolean status5 = settings.setMapFile(mfmapFileNew); - - return status1 && status2 && status3 && status4 && status5; - } - - private class cgeoChangeTwitter implements View.OnClickListener { - - public void onClick(View arg0) { - CheckBox twitterButton = (CheckBox) findViewById(R.id.twitter_option); - - if (twitterButton.isChecked()) { - settings.reloadTwitterTokens(); - - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("twitter", 0) == 0) { - edit.putInt("twitter", 1); - settings.twitter = 1; - } else { - edit.putInt("twitter", 0); - settings.twitter = 0; - } - edit.commit(); - - if (settings.twitter == 1 && (StringUtils.isBlank(settings.tokenPublic) || StringUtils.isBlank(settings.tokenSecret))) { - Intent authIntent = new Intent(cgeoinit.this, cgeoauth.class); - startActivity(authIntent); - } - - if (prefs.getInt("twitter", 0) == 0) { - twitterButton.setChecked(false); - } else { - twitterButton.setChecked(true); - } - } else { - SharedPreferences.Editor edit = prefs.edit(); - edit.putInt("twitter", 0); - settings.twitter = 0; - edit.commit(); - - twitterButton.setChecked(false); - } - - return; - } - } - - private class cgeoChangeSkin implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("skin", 0) == 0) { - edit.putInt("skin", 1); - settings.setSkin(1); - } else { - edit.putInt("skin", 0); - settings.setSkin(0); - } - edit.commit(); - - CheckBox skinButton = (CheckBox) findViewById(R.id.skin); - if (prefs.getInt("skin", 0) == 0) { - skinButton.setChecked(false); - } else { - skinButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeAddress implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("showaddress", 1) == 0) { - edit.putInt("showaddress", 1); - } else { - edit.putInt("showaddress", 0); - } - edit.commit(); - - CheckBox transparentButton = (CheckBox) findViewById(R.id.address); - if (prefs.getInt("showaddress", 1) == 0) { - transparentButton.setChecked(false); - } else { - transparentButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangePublic implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("publicloc", 0) == 0) { - edit.putInt("publicloc", 1); - settings.publicLoc = 1; - } else { - edit.putInt("publicloc", 0); - settings.publicLoc = 0; - } - edit.commit(); - - CheckBox publicloc = (CheckBox) findViewById(R.id.publicloc); - if (prefs.getInt("publicloc", 0) == 0) { - publicloc.setChecked(false); - } else { - publicloc.setChecked(true); - } - - return; - } - } - - private class cgeoChangeCaptcha implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getBoolean("showcaptcha", false) == false) { - edit.putBoolean("showcaptcha", true); - settings.showCaptcha = true; - } else { - edit.putBoolean("showcaptcha", false); - settings.showCaptcha = false; - } - edit.commit(); - - CheckBox captchaButton = (CheckBox) findViewById(R.id.captcha); - if (prefs.getBoolean("showcaptcha", false) == false) { - captchaButton.setChecked(false); - } else { - captchaButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeUseEnglish implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getBoolean("useenglish", false) == false) { - edit.putBoolean("useenglish", true); - settings.useEnglish = true; - settings.setLanguage(true); - } else { - edit.putBoolean("useenglish", false); - settings.useEnglish = false; - settings.setLanguage(false); - } - edit.commit(); - - CheckBox useEnglishButton = (CheckBox) findViewById(R.id.useenglish); - if (prefs.getBoolean("useenglish", false) == false) { - useEnglishButton.setChecked(false); - } else { - useEnglishButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeExclude implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("excludemine", 0) == 0) { - edit.putInt("excludemine", 1); - settings.excludeMine = 1; - } else { - edit.putInt("excludemine", 0); - settings.excludeMine = 0; - } - edit.commit(); - - CheckBox excludeButton = (CheckBox) findViewById(R.id.exclude); - if (prefs.getInt("excludemine", 0) == 0) { - excludeButton.setChecked(false); - } else { - excludeButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeAutovisit implements View.OnClickListener { + if (prefs.getInt("twitter", 0) == 0) { + twitterButton.setChecked(false); + } else { + twitterButton.setChecked(true); + } + } else { + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("twitter", 0); + settings.twitter = 0; + edit.commit(); + + twitterButton.setChecked(false); + } + + return; + } + } + + private class cgeoChangeSkin implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("skin", 0) == 0) { + edit.putInt("skin", 1); + settings.setSkin(1); + } else { + edit.putInt("skin", 0); + settings.setSkin(0); + } + edit.commit(); + + CheckBox skinButton = (CheckBox) findViewById(R.id.skin); + if (prefs.getInt("skin", 0) == 0) { + skinButton.setChecked(false); + } else { + skinButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeAddress implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("showaddress", 1) == 0) { + edit.putInt("showaddress", 1); + } else { + edit.putInt("showaddress", 0); + } + edit.commit(); + + CheckBox transparentButton = (CheckBox) findViewById(R.id.address); + if (prefs.getInt("showaddress", 1) == 0) { + transparentButton.setChecked(false); + } else { + transparentButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangePublic implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("publicloc", 0) == 0) { + edit.putInt("publicloc", 1); + settings.publicLoc = 1; + } else { + edit.putInt("publicloc", 0); + settings.publicLoc = 0; + } + edit.commit(); + + CheckBox publicloc = (CheckBox) findViewById(R.id.publicloc); + if (prefs.getInt("publicloc", 0) == 0) { + publicloc.setChecked(false); + } else { + publicloc.setChecked(true); + } + + return; + } + } + + private class cgeoChangeCaptcha implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getBoolean("showcaptcha", false) == false) { + edit.putBoolean("showcaptcha", true); + settings.showCaptcha = true; + } else { + edit.putBoolean("showcaptcha", false); + settings.showCaptcha = false; + } + edit.commit(); + + CheckBox captchaButton = (CheckBox) findViewById(R.id.captcha); + if (prefs.getBoolean("showcaptcha", false) == false) { + captchaButton.setChecked(false); + } else { + captchaButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeUseEnglish implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getBoolean("useenglish", false) == false) { + edit.putBoolean("useenglish", true); + settings.useEnglish = true; + settings.setLanguage(true); + } else { + edit.putBoolean("useenglish", false); + settings.useEnglish = false; + settings.setLanguage(false); + } + edit.commit(); + + CheckBox useEnglishButton = (CheckBox) findViewById(R.id.useenglish); + if (prefs.getBoolean("useenglish", false) == false) { + useEnglishButton.setChecked(false); + } else { + useEnglishButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeExclude implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("excludemine", 0) == 0) { + edit.putInt("excludemine", 1); + settings.excludeMine = 1; + } else { + edit.putInt("excludemine", 0); + settings.excludeMine = 0; + } + edit.commit(); + + CheckBox excludeButton = (CheckBox) findViewById(R.id.exclude); + if (prefs.getInt("excludemine", 0) == 0) { + excludeButton.setChecked(false); + } else { + excludeButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeAutovisit implements View.OnClickListener { public void onClick(View arg0) { SharedPreferences.Editor edit = prefs.edit(); @@ -754,7 +754,7 @@ public class cgeoinit extends AbstractActivity { } } - private class cgeoChangeSignatureAutoinsert implements View.OnClickListener { + private class cgeoChangeSignatureAutoinsert implements View.OnClickListener { public void onClick(View arg0) { SharedPreferences.Editor edit = prefs.edit(); @@ -778,305 +778,304 @@ public class cgeoinit extends AbstractActivity { } } - private class cgeoChangeDisabled implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("excludedisabled", 0) == 0) { - edit.putInt("excludedisabled", 1); - settings.excludeDisabled = 1; - } else { - edit.putInt("excludedisabled", 0); - settings.excludeDisabled = 0; - } - edit.commit(); - - CheckBox disabledButton = (CheckBox) findViewById(R.id.disabled); - if (prefs.getInt("excludedisabled", 0) == 0) { - disabledButton.setChecked(false); - } else { - disabledButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeOffline implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("offlinemaps", 1) == 0) { - edit.putInt("offlinemaps", 1); - settings.excludeDisabled = 1; - } else { - edit.putInt("offlinemaps", 0); - settings.excludeDisabled = 0; - } - edit.commit(); - - CheckBox offlineButton = (CheckBox) findViewById(R.id.offline); - if (prefs.getInt("offlinemaps", 0) == 0) { - offlineButton.setChecked(false); - } else { - offlineButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeSaveLogImg implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getBoolean("logimages", true) == false) { - edit.putBoolean("logimages", true); - settings.storelogimages = true; - } else { - edit.putBoolean("logimages", false); - settings.storelogimages = false; - } - edit.commit(); - - CheckBox saveLogImgButton = (CheckBox) findViewById(R.id.save_log_img); - if (prefs.getBoolean("logimages", true) == false) { - saveLogImgButton.setChecked(false); - } else { - saveLogImgButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeLivelist implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("livelist", 1) == 0) { - edit.putInt("livelist", 1); - settings.livelist = 1; - } else { - edit.putInt("livelist", 0); - settings.livelist = 0; - } - edit.commit(); - - CheckBox livelistButton = (CheckBox) findViewById(R.id.livelist); - if (prefs.getInt("livelist", 1) == 0) { - livelistButton.setChecked(false); - } else { - livelistButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeAutoload implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("autoloaddesc", 0) == 0) { - edit.putInt("autoloaddesc", 1); - settings.autoLoadDesc = 1; - } else { - edit.putInt("autoloaddesc", 0); - settings.autoLoadDesc = 0; - } - edit.commit(); - - CheckBox autoloadButton = (CheckBox) findViewById(R.id.autoload); - if (prefs.getInt("autoloaddesc", 0) == 0) { - autoloadButton.setChecked(false); - } else { - autoloadButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeUnits implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { - edit.putInt("units", cgSettings.unitsImperial); - settings.units = cgSettings.unitsImperial; - } else { - edit.putInt("units", cgSettings.unitsMetric); - settings.units = cgSettings.unitsMetric; - } - edit.commit(); - - CheckBox unitsButton = (CheckBox) findViewById(R.id.units); - if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { - unitsButton.setChecked(false); - } else { - unitsButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeGNav implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("usegnav", 1) == 1) { - edit.putInt("usegnav", 0); - settings.useGNavigation = 0; - } else { - edit.putInt("usegnav", 1); - settings.useGNavigation = 1; - } - edit.commit(); - - CheckBox gnavButton = (CheckBox) findViewById(R.id.gnav); - if (prefs.getInt("usegnav", 1) == 1) { - gnavButton.setChecked(true); - } else { - gnavButton.setChecked(false); - } - - return; - } - } - - private class cgeoChangeBrowser implements View.OnClickListener { - - public void onClick(View arg0) { - SharedPreferences.Editor edit = prefs.edit(); - if (prefs.getInt("asbrowser", 1) == 0) { - edit.putInt("asbrowser", 1); - settings.asBrowser = 1; - } else { - edit.putInt("asbrowser", 0); - settings.asBrowser = 0; - } - edit.commit(); - - CheckBox browserButton = (CheckBox) findViewById(R.id.browser); - if (prefs.getInt("asbrowser", 1) == 0) { - browserButton.setChecked(false); - } else { - browserButton.setChecked(true); - } - - return; - } - } - - private class cgeoChangeMapSource implements OnItemSelectedListener { - - @Override - public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, - long arg3) { - settings.mapSource = mapSourceEnum.fromInt(arg2); - SharedPreferences.Editor edit = prefs.edit(); - edit.putInt("mapsource", arg2); - edit.commit(); - } - - @Override - public void onNothingSelected(AdapterView<?> arg0) { - arg0.setSelection(settings.mapSource.ordinal()); - } - } - - private class logIn implements View.OnClickListener { - - public void onClick(View arg0) { - final String username = ((EditText) findViewById(R.id.username)).getText().toString(); - final String password = ((EditText) findViewById(R.id.password)).getText().toString(); - - if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { - showToast(res.getString(R.string.err_missing_auth)); - return; - } - - loginDialog = ProgressDialog.show(cgeoinit.this, res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_working), true); - loginDialog.setCancelable(false); - - settings.setLogin(username, password); - settings.deleteCookies(); - - (new Thread() { - - @Override - public void run() { - final int loginResult = base.login(); - if (1 == loginResult) - { - base.detectGcCustomDate(); - } - logInHandler.sendEmptyMessage(loginResult); - } - }).start(); - } - } - - private class webAuth implements View.OnClickListener { - - public void onClick(View arg0) { - final String deviceName = ((EditText) findViewById(R.id.webDeviceName)).getText().toString(); - final String deviceCode = prefs.getString("webDeviceCode", null); - - - if (StringUtils.isBlank(deviceName)) { - showToast(res.getString(R.string.err_missing_device_name)); - return; - } - - webDialog = ProgressDialog.show(cgeoinit.this, res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_registering), true); - webDialog.setCancelable(false); - - (new Thread() { - - @Override - public void run() { - int pin = 0; - - String nam = deviceName==null?"":deviceName; - String cod = deviceCode==null?"":deviceCode; - - String params = "name="+cgBase.urlencode_rfc3986(nam)+"&code="+cgBase.urlencode_rfc3986(cod); - - cgResponse response = base.request(false, "send2.cgeo.org", "/auth.html", "GET", params, 0, true); - - if (response.getStatusCode() == 200) - { - //response was OK - String[] strings = response.getData().split(","); - try { - pin=Integer.parseInt(strings[1].trim()); - } catch (Exception e) { - Log.e(cgSettings.tag, "webDialog: " + e.toString()); - } - String code = strings[0]; - settings.setWebNameCode(nam, code); - } - - webAuthHandler.sendEmptyMessage(pin); - } - }).start(); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == SELECT_MAPFILE_REQUEST) { - if (resultCode == RESULT_OK) { - if (data.hasExtra("mapfile")) { - settings.setMapFile(data.getStringExtra("mapfile")); - } - } - initMapfileEdittext(true); - } - } + private class cgeoChangeDisabled implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("excludedisabled", 0) == 0) { + edit.putInt("excludedisabled", 1); + settings.excludeDisabled = 1; + } else { + edit.putInt("excludedisabled", 0); + settings.excludeDisabled = 0; + } + edit.commit(); + + CheckBox disabledButton = (CheckBox) findViewById(R.id.disabled); + if (prefs.getInt("excludedisabled", 0) == 0) { + disabledButton.setChecked(false); + } else { + disabledButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeOffline implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("offlinemaps", 1) == 0) { + edit.putInt("offlinemaps", 1); + settings.excludeDisabled = 1; + } else { + edit.putInt("offlinemaps", 0); + settings.excludeDisabled = 0; + } + edit.commit(); + + CheckBox offlineButton = (CheckBox) findViewById(R.id.offline); + if (prefs.getInt("offlinemaps", 0) == 0) { + offlineButton.setChecked(false); + } else { + offlineButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeSaveLogImg implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getBoolean("logimages", true) == false) { + edit.putBoolean("logimages", true); + settings.storelogimages = true; + } else { + edit.putBoolean("logimages", false); + settings.storelogimages = false; + } + edit.commit(); + + CheckBox saveLogImgButton = (CheckBox) findViewById(R.id.save_log_img); + if (prefs.getBoolean("logimages", true) == false) { + saveLogImgButton.setChecked(false); + } else { + saveLogImgButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeLivelist implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("livelist", 1) == 0) { + edit.putInt("livelist", 1); + settings.livelist = 1; + } else { + edit.putInt("livelist", 0); + settings.livelist = 0; + } + edit.commit(); + + CheckBox livelistButton = (CheckBox) findViewById(R.id.livelist); + if (prefs.getInt("livelist", 1) == 0) { + livelistButton.setChecked(false); + } else { + livelistButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeAutoload implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("autoloaddesc", 0) == 0) { + edit.putInt("autoloaddesc", 1); + settings.autoLoadDesc = 1; + } else { + edit.putInt("autoloaddesc", 0); + settings.autoLoadDesc = 0; + } + edit.commit(); + + CheckBox autoloadButton = (CheckBox) findViewById(R.id.autoload); + if (prefs.getInt("autoloaddesc", 0) == 0) { + autoloadButton.setChecked(false); + } else { + autoloadButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeUnits implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { + edit.putInt("units", cgSettings.unitsImperial); + settings.units = cgSettings.unitsImperial; + } else { + edit.putInt("units", cgSettings.unitsMetric); + settings.units = cgSettings.unitsMetric; + } + edit.commit(); + + CheckBox unitsButton = (CheckBox) findViewById(R.id.units); + if (prefs.getInt("units", cgSettings.unitsMetric) == cgSettings.unitsMetric) { + unitsButton.setChecked(false); + } else { + unitsButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeGNav implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("usegnav", 1) == 1) { + edit.putInt("usegnav", 0); + settings.useGNavigation = 0; + } else { + edit.putInt("usegnav", 1); + settings.useGNavigation = 1; + } + edit.commit(); + + CheckBox gnavButton = (CheckBox) findViewById(R.id.gnav); + if (prefs.getInt("usegnav", 1) == 1) { + gnavButton.setChecked(true); + } else { + gnavButton.setChecked(false); + } + + return; + } + } + + private class cgeoChangeBrowser implements View.OnClickListener { + + public void onClick(View arg0) { + SharedPreferences.Editor edit = prefs.edit(); + if (prefs.getInt("asbrowser", 1) == 0) { + edit.putInt("asbrowser", 1); + settings.asBrowser = 1; + } else { + edit.putInt("asbrowser", 0); + settings.asBrowser = 0; + } + edit.commit(); + + CheckBox browserButton = (CheckBox) findViewById(R.id.browser); + if (prefs.getInt("asbrowser", 1) == 0) { + browserButton.setChecked(false); + } else { + browserButton.setChecked(true); + } + + return; + } + } + + private class cgeoChangeMapSource implements OnItemSelectedListener { + + @Override + public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, + long arg3) { + settings.mapSource = mapSourceEnum.fromInt(arg2); + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("mapsource", arg2); + edit.commit(); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) { + arg0.setSelection(settings.mapSource.ordinal()); + } + } + + private class logIn implements View.OnClickListener { + + public void onClick(View arg0) { + final String username = ((EditText) findViewById(R.id.username)).getText().toString(); + final String password = ((EditText) findViewById(R.id.password)).getText().toString(); + + if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { + showToast(res.getString(R.string.err_missing_auth)); + return; + } + + loginDialog = ProgressDialog.show(cgeoinit.this, res.getString(R.string.init_login_popup), res.getString(R.string.init_login_popup_working), true); + loginDialog.setCancelable(false); + + settings.setLogin(username, password); + settings.deleteCookies(); + + (new Thread() { + + @Override + public void run() { + final int loginResult = base.login(); + if (1 == loginResult) + { + base.detectGcCustomDate(); + } + logInHandler.sendEmptyMessage(loginResult); + } + }).start(); + } + } + + private class webAuth implements View.OnClickListener { + + public void onClick(View arg0) { + final String deviceName = ((EditText) findViewById(R.id.webDeviceName)).getText().toString(); + final String deviceCode = prefs.getString("webDeviceCode", null); + + if (StringUtils.isBlank(deviceName)) { + showToast(res.getString(R.string.err_missing_device_name)); + return; + } + + webDialog = ProgressDialog.show(cgeoinit.this, res.getString(R.string.init_sendToCgeo), res.getString(R.string.init_sendToCgeo_registering), true); + webDialog.setCancelable(false); + + (new Thread() { + + @Override + public void run() { + int pin = 0; + + String nam = deviceName == null ? "" : deviceName; + String cod = deviceCode == null ? "" : deviceCode; + + String params = "name=" + cgBase.urlencode_rfc3986(nam) + "&code=" + cgBase.urlencode_rfc3986(cod); + + cgResponse response = base.request(false, "send2.cgeo.org", "/auth.html", "GET", params, 0, true); + + if (response.getStatusCode() == 200) + { + //response was OK + String[] strings = response.getData().split(","); + try { + pin = Integer.parseInt(strings[1].trim()); + } catch (Exception e) { + Log.e(cgSettings.tag, "webDialog: " + e.toString()); + } + String code = strings[0]; + settings.setWebNameCode(nam, code); + } + + webAuthHandler.sendEmptyMessage(pin); + } + }).start(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == SELECT_MAPFILE_REQUEST) { + if (resultCode == RESULT_OK) { + if (data.hasExtra("mapfile")) { + settings.setMapFile(data.getStringExtra("mapfile")); + } + } + initMapfileEdittext(true); + } + } } diff --git a/src/cgeo/geocaching/cgeonavigate.java b/src/cgeo/geocaching/cgeonavigate.java index 4e0cd34..f4f8393 100644 --- a/src/cgeo/geocaching/cgeonavigate.java +++ b/src/cgeo/geocaching/cgeonavigate.java @@ -1,8 +1,7 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; @@ -19,445 +18,446 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.WindowManager; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.geopoint.Geopoint; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; public class cgeonavigate extends AbstractActivity { - public final static List<cgCoord> coordinates = new ArrayList<cgCoord>(); - private PowerManager pm = null; - private cgGeo geo = null; - private cgDirection dir = null; - private cgUpdateLoc geoUpdate = new update(); - private cgUpdateDir dirUpdate = new UpdateDirection(); - private Geopoint dstCoords = null; - private float cacheHeading = 0; - private float northHeading = 0; - private String title = null; - private String name = null; - private TextView navType = null; - private TextView navAccuracy = null; - private TextView navSatellites = null; - private TextView navLocation = null; - private TextView distanceView = null; - private TextView headingView = null; - private cgCompass compassView = null; - private updaterThread updater = null; - private Handler updaterHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (compassView != null) { - compassView.updateNorth(northHeading, cacheHeading); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeonavigate.updaterHandler: " + e.toString()); - } - } - }; - - public cgeonavigate() { - super("c:geo-compass"); - } - - @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)); - - // sensor & geolocation manager - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(this, dirUpdate); - } - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - title = extras.getString("geocode"); - name = extras.getString("name"); - dstCoords = new Geopoint(extras.getDouble("latitude"), extras.getDouble("longitude")); - - if (StringUtils.isNotBlank(name)) { - if (StringUtils.isNotBlank(title)) { - title = title + ": " + name; - } else { - title = name; - } - } - } else { - Intent pointIntent = new Intent(this, cgeopoint.class); - startActivity(pointIntent); - - finish(); - return; - } - - if (StringUtils.isNotBlank(title)) { - app.setAction(title); - } else if (StringUtils.isNotBlank(name)) { - app.setAction(name); - } - - // set header - setTitle(); - setDestCoords(); - - // get textviews once - compassView = (cgCompass) findViewById(R.id.rose); - - // start updater thread - updater = new updaterThread(updaterHandler); - updater.start(); - - if (geo != null) { - geoUpdate.updateLoc(geo); - } - if (dir != null) { - dirUpdate.updateDir(dir); - } - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - - if (StringUtils.isNotBlank(title)) { - app.setAction(title); - } else if (StringUtils.isNotBlank(name)) { - app.setAction(name); - } - - // sensor & geolocation manager - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(this, dirUpdate); - } - - // keep backlight on - if (pm == null) { - pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - } - - // updater thread - if (updater == null) { - updater = new updaterThread(updaterHandler); - updater.start(); - } - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - if (dir != null) { - dir = app.removeDir(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - if (dir != null) { - dir = app.removeDir(); - } - - super.onPause(); - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - if (dir != null) { - dir = app.removeDir(); - } - - compassView.destroyDrawingCache(); - compassView = null; - - super.onDestroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (settings.useCompass == 1) { - menu.add(0, 1, 0, res.getString(R.string.use_gps)).setIcon(android.R.drawable.ic_menu_compass); - } else { - menu.add(0, 1, 0, res.getString(R.string.use_compass)).setIcon(android.R.drawable.ic_menu_compass); - } - menu.add(0, 0, 0, res.getString(R.string.caches_on_map)).setIcon(android.R.drawable.ic_menu_mapmode); - menu.add(0, 2, 0, res.getString(R.string.destination_set)).setIcon(android.R.drawable.ic_menu_edit); - if (coordinates.size() > 1) { - SubMenu subMenu = menu.addSubMenu(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces); - - int cnt = 4; - for (cgCoord coordinate : coordinates) { - subMenu.add(0, cnt, 0, coordinate.name + " (" + coordinate.type + ")"); - cnt++; - } - - return true; - } else { - menu.add(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces).setEnabled(false); - - return true; - } - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - MenuItem item; - item = menu.findItem(1); - if (settings.useCompass == 1) { - item.setTitle(res.getString(R.string.use_gps)); - } else { - item.setTitle(res.getString(R.string.use_compass)); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - - if (id == 0) { - Intent mapIntent = new Intent(this, settings.getMapFactory().getMapClass()); - mapIntent.putExtra("detail", false); - mapIntent.putExtra("latitude", dstCoords.getLatitude()); - mapIntent.putExtra("longitude", dstCoords.getLongitude()); - - startActivity(mapIntent); - } else if (id == 1) { - if (settings.useCompass == 1) { - settings.useCompass = 0; - - if (dir != null) { - dir = app.removeDir(); - } - - SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefsEdit.putInt("usecompass", settings.useCompass); - prefsEdit.commit(); - } else { - settings.useCompass = 1; - - if (dir == null) { - dir = app.startDir(this, dirUpdate); - } - - SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); - prefsEdit.putInt("usecompass", settings.useCompass); - prefsEdit.commit(); - } - } else if (id == 2) { - Intent pointIntent = new Intent(this, cgeopoint.class); - startActivity(pointIntent); - - finish(); - return true; - } else if (id > 3 && coordinates.get(id - 4) != null) { - cgCoord coordinate = coordinates.get(id - 4); - - title = coordinate.name; - dstCoords = coordinate.coords; - setTitle(); - setDestCoords(); - updateDistanceInfo(); - - Log.d(cgSettings.tag, "destination set: " + title + " (" + - String.format(Locale.getDefault(), "%.8f", dstCoords.getLatitude()) + " | " + - String.format(Locale.getDefault(), "%.8f", dstCoords.getLongitude()) + ")"); - return true; - } - - return false; - } - - private void setTitle() { - if (StringUtils.isNotBlank(title)) { - setTitle(title); - } else { - setTitle(res.getString(R.string.navigation)); - } - } - - private void setDestCoords() { - if (dstCoords == null) { - return; - } - - ((TextView) findViewById(R.id.destination)).setText(cgBase.formatCoords(dstCoords, true)); - } - - public void setDest(final Geopoint coords) { - if (coords == null) { - return; - } - - title = "some place"; - setTitle(); - setDestCoords(); - - dstCoords = coords; - updateDistanceInfo(); - } - - public Geopoint getCoordinatesNow() { - return geo.coordsNow; - } - - private void updateDistanceInfo() { - if (geo == null || geo.coordsNow == null || dstCoords == null) { - return; - } - - if (distanceView == null) { - distanceView = (TextView) findViewById(R.id.distance); - } - if (headingView == null) { - headingView = (TextView) findViewById(R.id.heading); - } - - cacheHeading = geo.coordsNow.bearingTo(dstCoords); - distanceView.setText(base.getHumanDistance(geo.coordsNow.distanceTo(dstCoords))); - headingView.setText(String.format(Locale.getDefault(), "%.0f", cacheHeading) + "°"); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - if (navType == null || navLocation == null || navAccuracy == null) { - navType = (TextView) findViewById(R.id.nav_type); - navAccuracy = (TextView) findViewById(R.id.nav_accuracy); - navSatellites = (TextView) findViewById(R.id.nav_satellites); - navLocation = (TextView) findViewById(R.id.nav_location); - } - - if (geo.coordsNow != null) { - String satellites = null; - if (geo.satellitesVisible != null && geo.satellitesFixed != null && geo.satellitesFixed > 0) { - satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible; - } else if (geo.satellitesVisible != null) { - satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible; - } else { - satellites = ""; - } - navSatellites.setText(satellites); - - if (geo.gps == -1) { - navType.setText(res.getString(R.string.loc_last)); - } else if (geo.gps == 0) { - navType.setText(res.getString(R.string.loc_net)); - } else { - navType.setText(res.getString(R.string.loc_gps)); - } - - if (geo.accuracyNow != null) { - if (settings.units == cgSettings.unitsImperial) { - navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", (geo.accuracyNow * 3.2808399)) + " ft"); - } else { - navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", geo.accuracyNow) + " m"); - } - } else { - navAccuracy.setText(null); - } - - if (geo.altitudeNow != null) { - String humanAlt; - if (settings.units == cgSettings.unitsImperial) { - humanAlt = String.format("%.0f", (geo.altitudeNow * 3.2808399)) + " ft"; - } else { - humanAlt = String.format("%.0f", geo.altitudeNow) + " m"; - } - navLocation.setText(cgBase.formatCoords(geo.coordsNow, true) + " | " + humanAlt); - } else { - navLocation.setText(cgBase.formatCoords(geo.coordsNow, true)); - } - - updateDistanceInfo(); - } else { - navType.setText(null); - navAccuracy.setText(null); - navLocation.setText(res.getString(R.string.loc_trying)); - } - - if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h - if (geo != null && geo.bearingNow != null) { - northHeading = geo.bearingNow; - } else { - northHeading = 0; - } - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class UpdateDirection extends cgUpdateDir { - - @Override - public void updateDir(cgDirection dir) { - if (dir == null || dir.directionNow == null) { - return; - } - - if (geo == null || geo.speedNow == null || geo.speedNow <= 5) { // use compass when speed is lower than 18 km/h - northHeading = dir.directionNow; - } - } - } - - private static class updaterThread extends Thread { - - private Handler handler = null; - - public updaterThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - while (!Thread.currentThread().isInterrupted()) { - if (handler != null) { - handler.sendMessage(new Message()); - } - - try { - Thread.sleep(20); - } catch (Exception e) { - Thread.currentThread().interrupt(); - } - } - } - } + public final static List<cgCoord> coordinates = new ArrayList<cgCoord>(); + private PowerManager pm = null; + private cgGeo geo = null; + private cgDirection dir = null; + private cgUpdateLoc geoUpdate = new update(); + private cgUpdateDir dirUpdate = new UpdateDirection(); + private Geopoint dstCoords = null; + private float cacheHeading = 0; + private float northHeading = 0; + private String title = null; + private String name = null; + private TextView navType = null; + private TextView navAccuracy = null; + private TextView navSatellites = null; + private TextView navLocation = null; + private TextView distanceView = null; + private TextView headingView = null; + private cgCompass compassView = null; + private updaterThread updater = null; + private Handler updaterHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (compassView != null) { + compassView.updateNorth(northHeading, cacheHeading); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeonavigate.updaterHandler: " + e.toString()); + } + } + }; + + public cgeonavigate() { + super("c:geo-compass"); + } + + @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)); + + // sensor & geolocation manager + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(this, dirUpdate); + } + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + title = extras.getString("geocode"); + name = extras.getString("name"); + dstCoords = new Geopoint(extras.getDouble("latitude"), extras.getDouble("longitude")); + + if (StringUtils.isNotBlank(name)) { + if (StringUtils.isNotBlank(title)) { + title = title + ": " + name; + } else { + title = name; + } + } + } else { + Intent pointIntent = new Intent(this, cgeopoint.class); + startActivity(pointIntent); + + finish(); + return; + } + + if (StringUtils.isNotBlank(title)) { + app.setAction(title); + } else if (StringUtils.isNotBlank(name)) { + app.setAction(name); + } + + // set header + setTitle(); + setDestCoords(); + + // get textviews once + compassView = (cgCompass) findViewById(R.id.rose); + + // start updater thread + updater = new updaterThread(updaterHandler); + updater.start(); + + if (geo != null) { + geoUpdate.updateLoc(geo); + } + if (dir != null) { + dirUpdate.updateDir(dir); + } + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + + if (StringUtils.isNotBlank(title)) { + app.setAction(title); + } else if (StringUtils.isNotBlank(name)) { + app.setAction(name); + } + + // sensor & geolocation manager + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(this, dirUpdate); + } + + // keep backlight on + if (pm == null) { + pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + } + + // updater thread + if (updater == null) { + updater = new updaterThread(updaterHandler); + updater.start(); + } + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + if (dir != null) { + dir = app.removeDir(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + if (dir != null) { + dir = app.removeDir(); + } + + super.onPause(); + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + if (dir != null) { + dir = app.removeDir(); + } + + compassView.destroyDrawingCache(); + compassView = null; + + super.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + if (settings.useCompass == 1) { + menu.add(0, 1, 0, res.getString(R.string.use_gps)).setIcon(android.R.drawable.ic_menu_compass); + } else { + menu.add(0, 1, 0, res.getString(R.string.use_compass)).setIcon(android.R.drawable.ic_menu_compass); + } + menu.add(0, 0, 0, res.getString(R.string.caches_on_map)).setIcon(android.R.drawable.ic_menu_mapmode); + menu.add(0, 2, 0, res.getString(R.string.destination_set)).setIcon(android.R.drawable.ic_menu_edit); + if (coordinates.size() > 1) { + SubMenu subMenu = menu.addSubMenu(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces); + + int cnt = 4; + for (cgCoord coordinate : coordinates) { + subMenu.add(0, cnt, 0, coordinate.name + " (" + coordinate.type + ")"); + cnt++; + } + + return true; + } else { + menu.add(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces).setEnabled(false); + + return true; + } + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + MenuItem item; + item = menu.findItem(1); + if (settings.useCompass == 1) { + item.setTitle(res.getString(R.string.use_gps)); + } else { + item.setTitle(res.getString(R.string.use_compass)); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id == 0) { + Intent mapIntent = new Intent(this, settings.getMapFactory().getMapClass()); + mapIntent.putExtra("detail", false); + mapIntent.putExtra("latitude", dstCoords.getLatitude()); + mapIntent.putExtra("longitude", dstCoords.getLongitude()); + + startActivity(mapIntent); + } else if (id == 1) { + if (settings.useCompass == 1) { + settings.useCompass = 0; + + if (dir != null) { + dir = app.removeDir(); + } + + SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefsEdit.putInt("usecompass", settings.useCompass); + prefsEdit.commit(); + } else { + settings.useCompass = 1; + + if (dir == null) { + dir = app.startDir(this, dirUpdate); + } + + SharedPreferences.Editor prefsEdit = getSharedPreferences(cgSettings.preferences, 0).edit(); + prefsEdit.putInt("usecompass", settings.useCompass); + prefsEdit.commit(); + } + } else if (id == 2) { + Intent pointIntent = new Intent(this, cgeopoint.class); + startActivity(pointIntent); + + finish(); + return true; + } else if (id > 3 && coordinates.get(id - 4) != null) { + cgCoord coordinate = coordinates.get(id - 4); + + title = coordinate.name; + dstCoords = coordinate.coords; + setTitle(); + setDestCoords(); + updateDistanceInfo(); + + Log.d(cgSettings.tag, "destination set: " + title + " (" + + String.format(Locale.getDefault(), "%.8f", dstCoords.getLatitude()) + " | " + + String.format(Locale.getDefault(), "%.8f", dstCoords.getLongitude()) + ")"); + return true; + } + + return false; + } + + private void setTitle() { + if (StringUtils.isNotBlank(title)) { + setTitle(title); + } else { + setTitle(res.getString(R.string.navigation)); + } + } + + private void setDestCoords() { + if (dstCoords == null) { + return; + } + + ((TextView) findViewById(R.id.destination)).setText(cgBase.formatCoords(dstCoords, true)); + } + + public void setDest(final Geopoint coords) { + if (coords == null) { + return; + } + + title = "some place"; + setTitle(); + setDestCoords(); + + dstCoords = coords; + updateDistanceInfo(); + } + + public Geopoint getCoordinatesNow() { + return geo.coordsNow; + } + + private void updateDistanceInfo() { + if (geo == null || geo.coordsNow == null || dstCoords == null) { + return; + } + + if (distanceView == null) { + distanceView = (TextView) findViewById(R.id.distance); + } + if (headingView == null) { + headingView = (TextView) findViewById(R.id.heading); + } + + cacheHeading = geo.coordsNow.bearingTo(dstCoords); + distanceView.setText(base.getHumanDistance(geo.coordsNow.distanceTo(dstCoords))); + headingView.setText(String.format(Locale.getDefault(), "%.0f", cacheHeading) + "°"); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + if (navType == null || navLocation == null || navAccuracy == null) { + navType = (TextView) findViewById(R.id.nav_type); + navAccuracy = (TextView) findViewById(R.id.nav_accuracy); + navSatellites = (TextView) findViewById(R.id.nav_satellites); + navLocation = (TextView) findViewById(R.id.nav_location); + } + + if (geo.coordsNow != null) { + String satellites = null; + if (geo.satellitesVisible != null && geo.satellitesFixed != null && geo.satellitesFixed > 0) { + satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible; + } else if (geo.satellitesVisible != null) { + satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible; + } else { + satellites = ""; + } + navSatellites.setText(satellites); + + if (geo.gps == -1) { + navType.setText(res.getString(R.string.loc_last)); + } else if (geo.gps == 0) { + navType.setText(res.getString(R.string.loc_net)); + } else { + navType.setText(res.getString(R.string.loc_gps)); + } + + if (geo.accuracyNow != null) { + if (settings.units == cgSettings.unitsImperial) { + navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", (geo.accuracyNow * 3.2808399)) + " ft"); + } else { + navAccuracy.setText("±" + String.format(Locale.getDefault(), "%.0f", geo.accuracyNow) + " m"); + } + } else { + navAccuracy.setText(null); + } + + if (geo.altitudeNow != null) { + String humanAlt; + if (settings.units == cgSettings.unitsImperial) { + humanAlt = String.format("%.0f", (geo.altitudeNow * 3.2808399)) + " ft"; + } else { + humanAlt = String.format("%.0f", geo.altitudeNow) + " m"; + } + navLocation.setText(cgBase.formatCoords(geo.coordsNow, true) + " | " + humanAlt); + } else { + navLocation.setText(cgBase.formatCoords(geo.coordsNow, true)); + } + + updateDistanceInfo(); + } else { + navType.setText(null); + navAccuracy.setText(null); + navLocation.setText(res.getString(R.string.loc_trying)); + } + + if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h + if (geo != null && geo.bearingNow != null) { + northHeading = geo.bearingNow; + } else { + northHeading = 0; + } + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class UpdateDirection extends cgUpdateDir { + + @Override + public void updateDir(cgDirection dir) { + if (dir == null || dir.directionNow == null) { + return; + } + + if (geo == null || geo.speedNow == null || geo.speedNow <= 5) { // use compass when speed is lower than 18 km/h + northHeading = dir.directionNow; + } + } + } + + private static class updaterThread extends Thread { + + private Handler handler = null; + + public updaterThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + if (handler != null) { + handler.sendMessage(new Message()); + } + + try { + Thread.sleep(20); + } catch (Exception e) { + Thread.currentThread().interrupt(); + } + } + } + } } diff --git a/src/cgeo/geocaching/cgeopoint.java b/src/cgeo/geocaching/cgeopoint.java index e6483a0..ff4216c 100644 --- a/src/cgeo/geocaching/cgeopoint.java +++ b/src/cgeo/geocaching/cgeopoint.java @@ -1,7 +1,9 @@ package cgeo.geocaching; -import java.util.List; -import java.util.Map; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.geopoint.DistanceParser; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; @@ -28,538 +30,537 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; -import cgeo.geocaching.geopoint.DistanceParser; -import cgeo.geocaching.geopoint.Geopoint; + +import java.util.List; +import java.util.Map; public class cgeopoint extends AbstractActivity { - private static class DestinationHistoryAdapter extends ArrayAdapter<cgDestination> { - private LayoutInflater inflater = null; - - public DestinationHistoryAdapter(Context context, - List<cgDestination> objects) { - super(context, 0, objects); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - - cgDestination loc = getItem(position); - - if (convertView == null) { - convertView = getInflater().inflate(R.layout.simple_way_point, - null); - } - TextView longitude = (TextView) convertView - .findViewById(R.id.simple_way_point_longitude); - TextView latitude = (TextView) convertView - .findViewById(R.id.simple_way_point_latitude); - TextView date = (TextView) convertView.findViewById(R.id.date); - - String lonString = cgBase.formatLongitude(loc.getCoords().getLongitude(), true); - String latString = cgBase.formatLatitude(loc.getCoords().getLatitude(), true); - - longitude.setText(lonString); - latitude.setText(latString); - date.setText(cgBase.formatShortDateTime(getContext(), loc.getDate())); - - return convertView; - } - - private LayoutInflater getInflater() { - if (inflater == null) { - inflater = ((Activity) getContext()).getLayoutInflater(); - } - - return inflater; - } - } - - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private Button latButton = null; - private Button lonButton = null; - private boolean changed = false; - private List<cgDestination> historyOfSearchedLocations; - private DestinationHistoryAdapter destionationHistoryAdapter; - private ListView historyListView; - private TextView historyFooter; - - private static final int CONTEXT_MENU_DELETE_WAYPOINT = Menu.FIRST; - - public cgeopoint() { - super("c:geo-navigate-any"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.point); - setTitle(res.getString(R.string.search_destination)); - - createHistoryView(); - - init(); - } - - private void createHistoryView() { - historyListView = (ListView) findViewById(R.id.historyList); - - View pointControls = getLayoutInflater().inflate( - R.layout.point_controls, null); - historyListView.addHeaderView(pointControls); - - if (getHistoryOfSearchedLocations().isEmpty()) { - historyListView.addFooterView(getEmptyHistoryFooter(), null, false); - } - - historyListView.setAdapter(getDestionationHistoryAdapter()); - historyListView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, - long arg3) { - Object selection = arg0.getItemAtPosition(arg2); - if (selection instanceof cgDestination) { - navigateTo(((cgDestination) selection).getCoords()); - } - } - }); - historyListView - .setOnCreateContextMenuListener(new OnCreateContextMenuListener() { - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - menu.add(Menu.NONE, CONTEXT_MENU_DELETE_WAYPOINT, - Menu.NONE, R.string.waypoint_delete); - } - }); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - switch (item.getItemId()) { - case CONTEXT_MENU_DELETE_WAYPOINT: - AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item - .getMenuInfo(); - Object destination = historyListView - .getItemAtPosition(menuInfo.position); - if (destination instanceof cgDestination) { - removeFromHistory((cgDestination) destination); - } - return true; - default: - return super.onContextItemSelected(item); - } - } - - private TextView getEmptyHistoryFooter() { - if (historyFooter == null) { - historyFooter = (TextView) getLayoutInflater().inflate( - R.layout.caches_footer, null); - historyFooter.setText(R.string.search_history_empty); - } - return historyFooter; - } - - private DestinationHistoryAdapter getDestionationHistoryAdapter() { - if (destionationHistoryAdapter == null) { - destionationHistoryAdapter = new DestinationHistoryAdapter(this, - getHistoryOfSearchedLocations()); - } - return destionationHistoryAdapter; - } - - private List<cgDestination> getHistoryOfSearchedLocations() { - if (historyOfSearchedLocations == null) { - // Load from database - historyOfSearchedLocations = app.getHistoryOfSearchedLocations(); - } - - return historyOfSearchedLocations; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - init(); - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - private void init() { - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - latButton = (Button) findViewById(R.id.buttonLatitude); - lonButton = (Button) findViewById(R.id.buttonLongitude); - - latButton.setOnClickListener(new coordDialogListener()); - lonButton.setOnClickListener(new coordDialogListener()); - - if (prefs.contains("anylatitude") && prefs.contains("anylongitude")) { - latButton.setText(cgBase.formatLatitude(Double.valueOf(prefs.getFloat("anylatitude", 0f)), true)); - lonButton.setText(cgBase.formatLongitude(Double.valueOf(prefs.getFloat("anylongitude", 0f)), true)); - } - - Button buttonCurrent = (Button) findViewById(R.id.current); - buttonCurrent.setOnClickListener(new currentListener()); - - getDestionationHistoryAdapter().notifyDataSetChanged(); - } - - private class coordDialogListener implements View.OnClickListener { - - public void onClick(View arg0) { - Geopoint gp = null; - if (latButton.getText().length() > 0 && lonButton.getText().length() > 0) { - gp = new Geopoint(latButton.getText().toString() + " " + lonButton.getText().toString()); - } - cgeocoords coordsDialog = new cgeocoords(cgeopoint.this, settings, gp, geo); - coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { - @Override - public void update(Geopoint gp) { - latButton.setText(cgBase.formatLatitude(gp.getLatitude(), true)); - lonButton.setText(cgBase.formatLongitude(gp.getLongitude(), true)); - changed = true; - } - }); - coordsDialog.show(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass - - SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); - NavigationAppFactory.addMenuItems(subMenu, this, res); - - menu.add(0, 5, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around - - // clear history - MenuItem clearHistoryItem = menu.add(0, 6, 0, res.getString(R.string.search_clear_history)); - clearHistoryItem.setIcon(android.R.drawable.ic_menu_delete); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - try { - final Geopoint coords = getDestination(); - - if (coords != null) { - menu.findItem(0).setVisible(true); - menu.findItem(2).setVisible(true); - menu.findItem(5).setVisible(true); - } else { - menu.findItem(0).setVisible(false); - menu.findItem(2).setVisible(false); - menu.findItem(5).setVisible(false); - } - - menu.findItem(6).setEnabled(!getHistoryOfSearchedLocations().isEmpty()); - } catch (Exception e) { - // nothing - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int menuItem = item.getItemId(); - - final Geopoint coords = getDestination(); - - if(coords != null) - { - addToHistory(coords); - } - - if (menuItem == 2) { - navigateTo(); - return true; - } else if (menuItem == 5) { - cachesAround(); - return true; - } - else if (menuItem == 6) { - clearHistory(); - return true; - } - - return NavigationAppFactory.onMenuItemSelected(item, geo, this, res, null, null, null, coords); - } - - private void addToHistory(final Geopoint coords) { - // Add locations to history - cgDestination loc = new cgDestination(); - loc.setCoords(coords); - - if(!getHistoryOfSearchedLocations().contains(loc)) - { - loc.setDate(System.currentTimeMillis()); - getHistoryOfSearchedLocations().add(0,loc); - - // Save location - app.saveSearchedDestination(loc); - - // Ensure to remove the footer - historyListView.removeFooterView(getEmptyHistoryFooter()); - } - } - - private void removeFromHistory(cgDestination destination) { - if (getHistoryOfSearchedLocations().contains(destination)) { - getHistoryOfSearchedLocations().remove(destination); - - // Save - app.removeSearchedDestinations(destination); - - if (getHistoryOfSearchedLocations().isEmpty()) { - if (historyListView.getFooterViewsCount() == 0) { - historyListView.addFooterView(getEmptyHistoryFooter()); - } - } - - getDestionationHistoryAdapter().notifyDataSetChanged(); + private static class DestinationHistoryAdapter extends ArrayAdapter<cgDestination> { + private LayoutInflater inflater = null; + + public DestinationHistoryAdapter(Context context, + List<cgDestination> objects) { + super(context, 0, objects); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + + cgDestination loc = getItem(position); + + if (convertView == null) { + convertView = getInflater().inflate(R.layout.simple_way_point, + null); + } + TextView longitude = (TextView) convertView + .findViewById(R.id.simple_way_point_longitude); + TextView latitude = (TextView) convertView + .findViewById(R.id.simple_way_point_latitude); + TextView date = (TextView) convertView.findViewById(R.id.date); + + String lonString = cgBase.formatLongitude(loc.getCoords().getLongitude(), true); + String latString = cgBase.formatLatitude(loc.getCoords().getLatitude(), true); + + longitude.setText(lonString); + latitude.setText(latString); + date.setText(cgBase.formatShortDateTime(getContext(), loc.getDate())); + + return convertView; + } + + private LayoutInflater getInflater() { + if (inflater == null) { + inflater = ((Activity) getContext()).getLayoutInflater(); + } + + return inflater; + } + } + + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private Button latButton = null; + private Button lonButton = null; + private boolean changed = false; + private List<cgDestination> historyOfSearchedLocations; + private DestinationHistoryAdapter destionationHistoryAdapter; + private ListView historyListView; + private TextView historyFooter; + + private static final int CONTEXT_MENU_DELETE_WAYPOINT = Menu.FIRST; + + public cgeopoint() { + super("c:geo-navigate-any"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.point); + setTitle(res.getString(R.string.search_destination)); + + createHistoryView(); + + init(); + } + + private void createHistoryView() { + historyListView = (ListView) findViewById(R.id.historyList); + + View pointControls = getLayoutInflater().inflate( + R.layout.point_controls, null); + historyListView.addHeaderView(pointControls); + + if (getHistoryOfSearchedLocations().isEmpty()) { + historyListView.addFooterView(getEmptyHistoryFooter(), null, false); + } + + historyListView.setAdapter(getDestionationHistoryAdapter()); + historyListView.setOnItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, + long arg3) { + Object selection = arg0.getItemAtPosition(arg2); + if (selection instanceof cgDestination) { + navigateTo(((cgDestination) selection).getCoords()); + } + } + }); + historyListView + .setOnCreateContextMenuListener(new OnCreateContextMenuListener() { + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + menu.add(Menu.NONE, CONTEXT_MENU_DELETE_WAYPOINT, + Menu.NONE, R.string.waypoint_delete); + } + }); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + switch (item.getItemId()) { + case CONTEXT_MENU_DELETE_WAYPOINT: + AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item + .getMenuInfo(); + Object destination = historyListView + .getItemAtPosition(menuInfo.position); + if (destination instanceof cgDestination) { + removeFromHistory((cgDestination) destination); + } + return true; + default: + return super.onContextItemSelected(item); + } + } + + private TextView getEmptyHistoryFooter() { + if (historyFooter == null) { + historyFooter = (TextView) getLayoutInflater().inflate( + R.layout.caches_footer, null); + historyFooter.setText(R.string.search_history_empty); + } + return historyFooter; + } + + private DestinationHistoryAdapter getDestionationHistoryAdapter() { + if (destionationHistoryAdapter == null) { + destionationHistoryAdapter = new DestinationHistoryAdapter(this, + getHistoryOfSearchedLocations()); + } + return destionationHistoryAdapter; + } + + private List<cgDestination> getHistoryOfSearchedLocations() { + if (historyOfSearchedLocations == null) { + // Load from database + historyOfSearchedLocations = app.getHistoryOfSearchedLocations(); + } + + return historyOfSearchedLocations; + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + init(); + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + private void init() { + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + latButton = (Button) findViewById(R.id.buttonLatitude); + lonButton = (Button) findViewById(R.id.buttonLongitude); + + latButton.setOnClickListener(new coordDialogListener()); + lonButton.setOnClickListener(new coordDialogListener()); + + if (prefs.contains("anylatitude") && prefs.contains("anylongitude")) { + latButton.setText(cgBase.formatLatitude(Double.valueOf(prefs.getFloat("anylatitude", 0f)), true)); + lonButton.setText(cgBase.formatLongitude(Double.valueOf(prefs.getFloat("anylongitude", 0f)), true)); + } + + Button buttonCurrent = (Button) findViewById(R.id.current); + buttonCurrent.setOnClickListener(new currentListener()); + + getDestionationHistoryAdapter().notifyDataSetChanged(); + } + + private class coordDialogListener implements View.OnClickListener { + + public void onClick(View arg0) { + Geopoint gp = null; + if (latButton.getText().length() > 0 && lonButton.getText().length() > 0) { + gp = new Geopoint(latButton.getText().toString() + " " + lonButton.getText().toString()); + } + cgeocoords coordsDialog = new cgeocoords(cgeopoint.this, settings, gp, geo); + coordsDialog.setCancelable(true); + coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + @Override + public void update(Geopoint gp) { + latButton.setText(cgBase.formatLatitude(gp.getLatitude(), true)); + lonButton.setText(cgBase.formatLongitude(gp.getLongitude(), true)); + changed = true; + } + }); + coordsDialog.show(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass + + SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); + NavigationAppFactory.addMenuItems(subMenu, this, res); + + menu.add(0, 5, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around + + // clear history + MenuItem clearHistoryItem = menu.add(0, 6, 0, res.getString(R.string.search_clear_history)); + clearHistoryItem.setIcon(android.R.drawable.ic_menu_delete); + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + try { + final Geopoint coords = getDestination(); + + if (coords != null) { + menu.findItem(0).setVisible(true); + menu.findItem(2).setVisible(true); + menu.findItem(5).setVisible(true); + } else { + menu.findItem(0).setVisible(false); + menu.findItem(2).setVisible(false); + menu.findItem(5).setVisible(false); + } + + menu.findItem(6).setEnabled(!getHistoryOfSearchedLocations().isEmpty()); + } catch (Exception e) { + // nothing + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int menuItem = item.getItemId(); + + final Geopoint coords = getDestination(); + + if (coords != null) + { + addToHistory(coords); + } + + if (menuItem == 2) { + navigateTo(); + return true; + } else if (menuItem == 5) { + cachesAround(); + return true; + } + else if (menuItem == 6) { + clearHistory(); + return true; + } + + return NavigationAppFactory.onMenuItemSelected(item, geo, this, res, null, null, null, coords); + } + + private void addToHistory(final Geopoint coords) { + // Add locations to history + cgDestination loc = new cgDestination(); + loc.setCoords(coords); + + if (!getHistoryOfSearchedLocations().contains(loc)) + { + loc.setDate(System.currentTimeMillis()); + getHistoryOfSearchedLocations().add(0, loc); + + // Save location + app.saveSearchedDestination(loc); + + // Ensure to remove the footer + historyListView.removeFooterView(getEmptyHistoryFooter()); + } + } + + private void removeFromHistory(cgDestination destination) { + if (getHistoryOfSearchedLocations().contains(destination)) { + getHistoryOfSearchedLocations().remove(destination); + + // Save + app.removeSearchedDestinations(destination); + + if (getHistoryOfSearchedLocations().isEmpty()) { + if (historyListView.getFooterViewsCount() == 0) { + historyListView.addFooterView(getEmptyHistoryFooter()); + } + } + + getDestionationHistoryAdapter().notifyDataSetChanged(); - showToast(res.getString(R.string.search_remove_destination)); - } - } - - private void clearHistory() { - if (!getHistoryOfSearchedLocations().isEmpty()) { - getHistoryOfSearchedLocations().clear(); - - // Save - app.clearSearchedDestinations(); - - if (historyListView.getFooterViewsCount() == 0) { - historyListView.addFooterView(getEmptyHistoryFooter()); - } - - getDestionationHistoryAdapter().notifyDataSetChanged(); - - showToast(res.getString(R.string.search_history_cleared)); - } - } - - private void navigateTo() { - navigateTo(getDestination()); - } - - private void navigateTo(Geopoint geopoint) { - if (geopoint == null) { - showToast(res.getString(R.string.err_location_unknown)); - return; - } - - cgeonavigate navigateActivity = new cgeonavigate(); - - Intent navigateIntent = new Intent(this, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", geopoint.getLatitude()); - navigateIntent.putExtra("longitude", geopoint.getLongitude()); - navigateIntent.putExtra("geocode", ""); - navigateIntent.putExtra("name", "Some destination"); - - startActivity(navigateIntent); - } - - private void cachesAround() { - final Geopoint coords = getDestination(); - - if (coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - return; - } - - cgeocaches cachesActivity = new cgeocaches(); - - Intent cachesIntent = new Intent(this, cachesActivity.getClass()); - - cachesIntent.putExtra("type", "coordinate"); - cachesIntent.putExtra("latitude", coords.getLatitude()); - cachesIntent.putExtra("longitude", coords.getLongitude()); - cachesIntent.putExtra("cachetype", settings.cacheType); - - startActivity(cachesIntent); - - finish(); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - latButton.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); - lonButton.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class currentListener implements View.OnClickListener { - - public void onClick(View arg0) { - if (geo == null || geo.coordsNow == null) { - showToast(res.getString(R.string.err_point_unknown_position)); - return; - } - - latButton.setText(cgBase.formatLatitude(geo.coordsNow.getLatitude(), true)); - lonButton.setText(cgBase.formatLongitude(geo.coordsNow.getLongitude(), true)); - - changed = false; - } - } - - private Geopoint getDestination() { - Geopoint result = null; - Geopoint coords = null; - - String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString(); - String distanceText = ((EditText) findViewById(R.id.distance)).getText().toString(); - String latText = latButton.getText().toString(); - String lonText = lonButton.getText().toString(); - - if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText) - && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) { - showToast(res.getString(R.string.err_point_no_position_given)); - return null; - } - - if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) { - // latitude & longitude - Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); - Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lon"); - - if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lat)); - return null; - } - - if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lon)); - return null; - } - - coords = new Geopoint((Double) latParsed.get("coordinate"), (Double) lonParsed.get("coordinate")); - } else { - if (geo == null || geo.coordsNow == null) { - showToast(res.getString(R.string.err_point_curr_position_unavailable)); - return null; - } - - coords = geo.coordsNow; - } - - if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) { - // bearing & distance - Double bearing = null; - try { - bearing = new Double(bearingText); - } catch (Exception e) { - // probably not a number - } - if (bearing == null) { - helpDialog(res.getString(R.string.err_point_bear_and_dist_title), res.getString(R.string.err_point_bear_and_dist)); - return null; - } - - double distance; - try { - distance = DistanceParser.parseDistance(distanceText, settings.units); - } catch (NumberFormatException e) { - showToast(res.getString(R.string.err_parse_dist)); - return null; - } - - final Geopoint coordsDst = coords.project(bearing, distance); - - if (coordsDst == null) { - showToast(res.getString(R.string.err_point_location_error)); - return null; - } - - result = coordsDst; - } else if (coords != null) { - result = coords; - } else { - return null; - } - - saveCoords(result); - - return result; - } - - private void saveCoords(final Geopoint coords) { - if (changed && coords != null) { - SharedPreferences.Editor edit = prefs.edit(); - - edit.putFloat("anylatitude", (float) coords.getLatitude()); - edit.putFloat("anylongitude", (float) coords.getLongitude()); - - edit.commit(); - } else { - SharedPreferences.Editor edit = prefs.edit(); - - edit.remove("anylatitude"); - edit.remove("anylongitude"); - - edit.commit(); - } - } + showToast(res.getString(R.string.search_remove_destination)); + } + } + + private void clearHistory() { + if (!getHistoryOfSearchedLocations().isEmpty()) { + getHistoryOfSearchedLocations().clear(); + + // Save + app.clearSearchedDestinations(); + + if (historyListView.getFooterViewsCount() == 0) { + historyListView.addFooterView(getEmptyHistoryFooter()); + } + + getDestionationHistoryAdapter().notifyDataSetChanged(); + + showToast(res.getString(R.string.search_history_cleared)); + } + } + + private void navigateTo() { + navigateTo(getDestination()); + } + + private void navigateTo(Geopoint geopoint) { + if (geopoint == null) { + showToast(res.getString(R.string.err_location_unknown)); + return; + } + + cgeonavigate navigateActivity = new cgeonavigate(); + + Intent navigateIntent = new Intent(this, navigateActivity.getClass()); + navigateIntent.putExtra("latitude", geopoint.getLatitude()); + navigateIntent.putExtra("longitude", geopoint.getLongitude()); + navigateIntent.putExtra("geocode", ""); + navigateIntent.putExtra("name", "Some destination"); + + startActivity(navigateIntent); + } + + private void cachesAround() { + final Geopoint coords = getDestination(); + + if (coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + return; + } + + cgeocaches cachesActivity = new cgeocaches(); + + Intent cachesIntent = new Intent(this, cachesActivity.getClass()); + + cachesIntent.putExtra("type", "coordinate"); + cachesIntent.putExtra("latitude", coords.getLatitude()); + cachesIntent.putExtra("longitude", coords.getLongitude()); + cachesIntent.putExtra("cachetype", settings.cacheType); + + startActivity(cachesIntent); + + finish(); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + latButton.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); + lonButton.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class currentListener implements View.OnClickListener { + + public void onClick(View arg0) { + if (geo == null || geo.coordsNow == null) { + showToast(res.getString(R.string.err_point_unknown_position)); + return; + } + + latButton.setText(cgBase.formatLatitude(geo.coordsNow.getLatitude(), true)); + lonButton.setText(cgBase.formatLongitude(geo.coordsNow.getLongitude(), true)); + + changed = false; + } + } + + private Geopoint getDestination() { + Geopoint result = null; + Geopoint coords = null; + + String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString(); + String distanceText = ((EditText) findViewById(R.id.distance)).getText().toString(); + String latText = latButton.getText().toString(); + String lonText = lonButton.getText().toString(); + + if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText) + && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) { + showToast(res.getString(R.string.err_point_no_position_given)); + return null; + } + + if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) { + // latitude & longitude + Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); + Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lon"); + + if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lat)); + return null; + } + + if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lon)); + return null; + } + + coords = new Geopoint((Double) latParsed.get("coordinate"), (Double) lonParsed.get("coordinate")); + } else { + if (geo == null || geo.coordsNow == null) { + showToast(res.getString(R.string.err_point_curr_position_unavailable)); + return null; + } + + coords = geo.coordsNow; + } + + if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) { + // bearing & distance + Double bearing = null; + try { + bearing = new Double(bearingText); + } catch (Exception e) { + // probably not a number + } + if (bearing == null) { + helpDialog(res.getString(R.string.err_point_bear_and_dist_title), res.getString(R.string.err_point_bear_and_dist)); + return null; + } + + double distance; + try { + distance = DistanceParser.parseDistance(distanceText, settings.units); + } catch (NumberFormatException e) { + showToast(res.getString(R.string.err_parse_dist)); + return null; + } + + final Geopoint coordsDst = coords.project(bearing, distance); + + if (coordsDst == null) { + showToast(res.getString(R.string.err_point_location_error)); + return null; + } + + result = coordsDst; + } else if (coords != null) { + result = coords; + } else { + return null; + } + + saveCoords(result); + + return result; + } + + private void saveCoords(final Geopoint coords) { + if (changed && coords != null) { + SharedPreferences.Editor edit = prefs.edit(); + + edit.putFloat("anylatitude", (float) coords.getLatitude()); + edit.putFloat("anylongitude", (float) coords.getLongitude()); + + edit.commit(); + } else { + SharedPreferences.Editor edit = prefs.edit(); + + edit.remove("anylatitude"); + edit.remove("anylongitude"); + + edit.commit(); + } + } } diff --git a/src/cgeo/geocaching/cgeopopup.java b/src/cgeo/geocaching/cgeopopup.java index 029e8d7..49c59b0 100644 --- a/src/cgeo/geocaching/cgeopopup.java +++ b/src/cgeo/geocaching/cgeopopup.java @@ -1,6 +1,7 @@ package cgeo.geocaching; -import java.util.Locale; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import org.apache.commons.lang3.StringUtils; @@ -25,643 +26,643 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; + +import java.util.Locale; public class cgeopopup extends AbstractActivity { - private Boolean fromDetail = false; - private LayoutInflater inflater = null; - private String geocode = null; - private cgCache cache = null; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private ProgressDialog storeDialog = null; - private ProgressDialog dropDialog = null; - private TextView cacheDistance = null; - private Handler ratingHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - final Bundle data = msg.getData(); - - setRating(data.getFloat("rating"), data.getInt("votes")); - } catch (Exception e) { - // nothing - } - } - }; - private Handler storeCacheHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (storeDialog != null) { - storeDialog.dismiss(); - } - - finish(); - return; - } catch (Exception e) { - showToast(res.getString(R.string.err_store)); - - Log.e(cgSettings.tag, "cgeopopup.storeCacheHandler: " + e.toString()); - } - - if (storeDialog != null) { - storeDialog.dismiss(); - } - init(); - } - }; - private Handler dropCacheHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (dropDialog != null) { - dropDialog.dismiss(); - } - - finish(); - return; - } catch (Exception e) { - showToast(res.getString(R.string.err_drop)); - - Log.e(cgSettings.tag, "cgeopopup.dropCacheHandler: " + e.toString()); - } - - if (dropDialog != null) { - dropDialog.dismiss(); - } - init(); - } - }; - - public cgeopopup() { - super("c:geo-cache-info"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // set layout - setTheme(R.style.transparent); - setContentView(R.layout.popup); - setTitle(res.getString(R.string.detail)); - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - fromDetail = extras.getBoolean("fromdetail"); - geocode = extras.getString("geocode"); - } - - if (StringUtils.isBlank(geocode)) { - showToast(res.getString(R.string.err_detail_cache_find)); - - finish(); - return; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass - - SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); - NavigationAppFactory.addMenuItems(subMenu, this, res); - addVisitMenu(menu, cache); - menu.add(0, 5, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around - menu.add(0, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(android.R.drawable.ic_menu_info_details); // browser - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - try { - if (cache != null && cache.coords != null) { - menu.findItem(0).setVisible(true); - menu.findItem(2).setVisible(true); - menu.findItem(5).setVisible(true); - } else { - menu.findItem(0).setVisible(false); - menu.findItem(2).setVisible(false); - menu.findItem(5).setVisible(false); - } - - boolean visitPossible = fromDetail == false && settings.isLogin(); - menu.findItem(MENU_LOG_VISIT).setEnabled(visitPossible); - } catch (Exception e) { - // nothing - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int menuItem = item.getItemId(); - - if (menuItem == 2) { - navigateTo(); - return true; - } else if (menuItem == 5) { - cachesAround(); - return true; - } else if (menuItem == MENU_LOG_VISIT) { - cache.logVisit(this); - finish(); - return true; - } else if (menuItem == 7) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.geocode))); - return true; - } - - if (NavigationAppFactory.onMenuItemSelected(item, geo, this, res, cache, null, null, null)) { - return true; - } - - int logType = menuItem - MENU_LOG_VISIT_OFFLINE; - cache.logOffline(this, logType, settings, base); - return true; - } - - private void init() { - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - app.setAction(geocode); - - cache = app.getCacheByGeocode(geocode); - - if (cache == null) { - showToast(res.getString(R.string.err_detail_cache_find)); - - finish(); - return; - } - - try { - RelativeLayout itemLayout; - TextView itemName; - TextView itemValue; - LinearLayout itemStars; - - if (StringUtils.isNotBlank(cache.name)) { - setTitle(cache.name); - } else { - setTitle(geocode.toUpperCase()); - } - - inflater = getLayoutInflater(); - geocode = cache.geocode.toUpperCase(); - - ((ScrollView) findViewById(R.id.details_list_box)).setVisibility(View.VISIBLE); - LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); - detailsList.removeAllViews(); - - // actionbar icon - ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) getResources().getDrawable(cgBase.getCacheIcon(cache.type)), null, null, null); - - // cache type - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_type)); - if (cgBase.cacheTypesInv.containsKey(cache.type)) { // cache icon - if (StringUtils.isNotBlank(cache.size)) { - itemValue.setText(cgBase.cacheTypesInv.get(cache.type) + " (" + cache.size + ")"); - } else { - itemValue.setText(cgBase.cacheTypesInv.get(cache.type)); - } - } else { - if (StringUtils.isNotBlank(cache.size)) { - itemValue.setText(cgBase.cacheTypesInv.get("mystery") + " (" + cache.size + ")"); - } else { - itemValue.setText(cgBase.cacheTypesInv.get("mystery")); - } - } - detailsList.addView(itemLayout); - - // gc-code - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_geocode)); - itemValue.setText(cache.geocode.toUpperCase()); - detailsList.addView(itemLayout); - - // cache state - if (cache.archived || cache.disabled || cache.members || cache.found) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_status)); - - StringBuilder state = new StringBuilder(); - if (cache.found) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_found)); - } - if (cache.archived) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_archived)); - } - if (cache.disabled) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_disabled)); - } - if (cache.members) { - if (state.length() > 0) { - state.append(", "); - } - state.append(res.getString(R.string.cache_status_premium)); - } - - itemValue.setText(state.toString()); - detailsList.addView(itemLayout); - - state = null; - } - - // distance - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.cache_distance)); - itemValue.setText("--"); - detailsList.addView(itemLayout); - cacheDistance = itemValue; - - // difficulty - if (cache.difficulty > 0f) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); - - itemName.setText(res.getString(R.string.cache_difficulty)); - itemValue.setText(String.format(Locale.getDefault(), "%.1f", cache.difficulty) + " of 5"); - for (int i = 0; i <= 4; i++) { - ImageView star = (ImageView) inflater.inflate(R.layout.star, null); - if ((cache.difficulty - i) >= 1.0) { - star.setImageResource(R.drawable.star_on); - } else if ((cache.difficulty - i) > 0.0) { - star.setImageResource(R.drawable.star_half); - } else { - star.setImageResource(R.drawable.star_off); - } - itemStars.addView(star); - } - detailsList.addView(itemLayout); - } - - // terrain - if (cache.terrain > 0f) { - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); - - itemName.setText(res.getString(R.string.cache_terrain)); - itemValue.setText(String.format(Locale.getDefault(), "%.1f", cache.terrain) + " of 5"); - for (int i = 0; i <= 4; i++) { - ImageView star = (ImageView) inflater.inflate(R.layout.star, null); - if ((cache.terrain - i) >= 1.0) { - star.setImageResource(R.drawable.star_on); - } else if ((cache.terrain - i) > 0.0) { - star.setImageResource(R.drawable.star_half); - } else { - star.setImageResource(R.drawable.star_off); - } - itemStars.addView(star); - } - detailsList.addView(itemLayout); - } - - // rating - if (cache.rating != null && cache.rating > 0) { - setRating(cache.rating, cache.votes); - } else { - (new Thread() { - - public void run() { - cgRating rating = base.getRating(cache.guid, geocode); - - Message msg = new Message(); - Bundle bundle = new Bundle(); - - if (rating == null || rating.rating == null) { - return; - } - - bundle.putFloat("rating", rating.rating); - bundle.putInt("votes", rating.votes); - msg.setData(bundle); - - ratingHandler.sendMessage(msg); - } - }).start(); - } - - // more details - if (fromDetail == false) { - ((LinearLayout) findViewById(R.id.more_details_box)).setVisibility(View.VISIBLE); - - Button buttonMore = (Button) findViewById(R.id.more_details); - buttonMore.setOnClickListener(new OnClickListener() { - - public void onClick(View arg0) { - Intent cachesIntent = new Intent(cgeopopup.this, cgeodetail.class); - cachesIntent.putExtra("geocode", geocode.toUpperCase()); - startActivity(cachesIntent); - - finish(); - return; - } - }); - } else { - ((LinearLayout) findViewById(R.id.more_details_box)).setVisibility(View.GONE); - } - - if (fromDetail == false) { - ((LinearLayout) findViewById(R.id.offline_box)).setVisibility(View.VISIBLE); - - // offline use - final TextView offlineText = (TextView) findViewById(R.id.offline_text); - final Button offlineRefresh = (Button) findViewById(R.id.offline_refresh); - final Button offlineStore = (Button) findViewById(R.id.offline_store); - - if (cache.reason > 0) { - Long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.detailedUpdate / (60 * 1000)); // minutes - - String ago = ""; - if (diff < 15) { - ago = res.getString(R.string.cache_offline_time_mins_few); - } else if (diff < 50) { - ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); - } else if (diff < 90) { - ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); - } else if (diff < (48 * 60)) { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); - } else { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); - } - - offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); - - offlineRefresh.setVisibility(View.VISIBLE); - offlineRefresh.setEnabled(true); - offlineRefresh.setOnClickListener(new storeCache()); - - offlineStore.setText(res.getString(R.string.cache_offline_drop)); - offlineStore.setEnabled(true); - offlineStore.setOnClickListener(new dropCache()); - } else { - offlineText.setText(res.getString(R.string.cache_offline_not_ready)); - - offlineRefresh.setVisibility(View.GONE); - offlineRefresh.setEnabled(false); - offlineRefresh.setOnTouchListener(null); - offlineRefresh.setOnClickListener(null); - - offlineStore.setText(res.getString(R.string.cache_offline_store)); - offlineStore.setEnabled(true); - offlineStore.setOnClickListener(new storeCache()); - } - } else { - ((LinearLayout) findViewById(R.id.offline_box)).setVisibility(View.GONE); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeopopup.init: " + e.toString()); - } - - if (geo != null) { - geoUpdate.updateLoc(geo); - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - init(); - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - if (geo.coordsNow != null && cache != null && cache.coords != null) { - cacheDistance.setText(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); - cacheDistance.bringToFront(); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private void navigateTo() { - if (cache == null || cache.coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - } - - cgeonavigate navigateActivity = new cgeonavigate(); - - Intent navigateIntent = new Intent(this, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", cache.coords.getLatitude()); - navigateIntent.putExtra("longitude", cache.coords.getLongitude()); - navigateIntent.putExtra("geocode", ""); - navigateIntent.putExtra("name", "Some destination"); - - startActivity(navigateIntent); - } - - private void cachesAround() { - if (cache == null || cache.coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - } - - cgeocaches.startActivityCachesAround(this, cache.coords); - - finish(); - } - - private class storeCache implements View.OnClickListener { - - public void onClick(View arg0) { - if (dropDialog != null && dropDialog.isShowing()) { - showToast("Still removing this cache."); - return; - } - - storeDialog = ProgressDialog.show(cgeopopup.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true); - storeDialog.setCancelable(false); - Thread thread = new storeCacheThread(storeCacheHandler); - thread.start(); - } - } - - private class storeCacheThread extends Thread { - - private Handler handler = null; - - public storeCacheThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - base.storeCache(app, cgeopopup.this, cache, null, 1, handler); - } - } - - private class dropCache implements View.OnClickListener { - - public void onClick(View arg0) { - if (storeDialog != null && storeDialog.isShowing()) { - showToast("Still saving this cache."); - return; - } - - dropDialog = ProgressDialog.show(cgeopopup.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true); - dropDialog.setCancelable(false); - Thread thread = new dropCacheThread(dropCacheHandler); - thread.start(); - } - } - - private class dropCacheThread extends Thread { - - private Handler handler = null; - - public dropCacheThread(Handler handlerIn) { - handler = handlerIn; - } - - @Override - public void run() { - cgBase.dropCache(app, cgeopopup.this, cache, handler); - } - } - - private void setRating(Float rating, Integer votes) { - if (rating == null || rating <= 0) { - return; - } - - RelativeLayout itemLayout; - TextView itemName; - TextView itemValue; - LinearLayout itemStars; - LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); - - itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); - - itemName.setText(res.getString(R.string.cache_rating)); - itemValue.setText(String.format(Locale.getDefault(), "%.1f", rating) + " of 5"); - for (int i = 0; i <= 4; i++) { - ImageView star = (ImageView) inflater.inflate(R.layout.star, null); - if ((rating - i) >= 1.0) { - star.setImageResource(R.drawable.star_on); - } else if ((rating - i) > 0.0) { - star.setImageResource(R.drawable.star_half); - } else { - star.setImageResource(R.drawable.star_off); - } - itemStars.addView(star, (1 + i)); - } - if (votes != null) { - final TextView itemAddition = (TextView) itemLayout.findViewById(R.id.addition); - itemAddition.setText("(" + votes + ")"); - itemAddition.setVisibility(View.VISIBLE); - } - detailsList.addView(itemLayout); - } - - public void goCompass(View view) { - if (cache == null || cache.coords == 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.coords.getLatitude()); - navigateIntent.putExtra("longitude", cache.coords.getLongitude()); - navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); - navigateIntent.putExtra("name", cache.name); - - startActivity(navigateIntent); - - finish(); - } - - public void goManual(View view) { - super.goManual(view); - finish(); - } + private Boolean fromDetail = false; + private LayoutInflater inflater = null; + private String geocode = null; + private cgCache cache = null; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private ProgressDialog storeDialog = null; + private ProgressDialog dropDialog = null; + private TextView cacheDistance = null; + private Handler ratingHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + final Bundle data = msg.getData(); + + setRating(data.getFloat("rating"), data.getInt("votes")); + } catch (Exception e) { + // nothing + } + } + }; + private Handler storeCacheHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (storeDialog != null) { + storeDialog.dismiss(); + } + + finish(); + return; + } catch (Exception e) { + showToast(res.getString(R.string.err_store)); + + Log.e(cgSettings.tag, "cgeopopup.storeCacheHandler: " + e.toString()); + } + + if (storeDialog != null) { + storeDialog.dismiss(); + } + init(); + } + }; + private Handler dropCacheHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (dropDialog != null) { + dropDialog.dismiss(); + } + + finish(); + return; + } catch (Exception e) { + showToast(res.getString(R.string.err_drop)); + + Log.e(cgSettings.tag, "cgeopopup.dropCacheHandler: " + e.toString()); + } + + if (dropDialog != null) { + dropDialog.dismiss(); + } + init(); + } + }; + + public cgeopopup() { + super("c:geo-cache-info"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // set layout + setTheme(R.style.transparent); + setContentView(R.layout.popup); + setTitle(res.getString(R.string.detail)); + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + fromDetail = extras.getBoolean("fromdetail"); + geocode = extras.getString("geocode"); + } + + if (StringUtils.isBlank(geocode)) { + showToast(res.getString(R.string.err_detail_cache_find)); + + finish(); + return; + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass + + SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); + NavigationAppFactory.addMenuItems(subMenu, this, res); + addVisitMenu(menu, cache); + menu.add(0, 5, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around + menu.add(0, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(android.R.drawable.ic_menu_info_details); // browser + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + try { + if (cache != null && cache.coords != null) { + menu.findItem(0).setVisible(true); + menu.findItem(2).setVisible(true); + menu.findItem(5).setVisible(true); + } else { + menu.findItem(0).setVisible(false); + menu.findItem(2).setVisible(false); + menu.findItem(5).setVisible(false); + } + + boolean visitPossible = fromDetail == false && settings.isLogin(); + menu.findItem(MENU_LOG_VISIT).setEnabled(visitPossible); + } catch (Exception e) { + // nothing + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int menuItem = item.getItemId(); + + if (menuItem == 2) { + navigateTo(); + return true; + } else if (menuItem == 5) { + cachesAround(); + return true; + } else if (menuItem == MENU_LOG_VISIT) { + cache.logVisit(this); + finish(); + return true; + } else if (menuItem == 7) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.geocode))); + return true; + } + + if (NavigationAppFactory.onMenuItemSelected(item, geo, this, res, cache, null, null, null)) { + return true; + } + + int logType = menuItem - MENU_LOG_VISIT_OFFLINE; + cache.logOffline(this, logType, settings, base); + return true; + } + + private void init() { + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + app.setAction(geocode); + + cache = app.getCacheByGeocode(geocode); + + if (cache == null) { + showToast(res.getString(R.string.err_detail_cache_find)); + + finish(); + return; + } + + try { + RelativeLayout itemLayout; + TextView itemName; + TextView itemValue; + LinearLayout itemStars; + + if (StringUtils.isNotBlank(cache.name)) { + setTitle(cache.name); + } else { + setTitle(geocode.toUpperCase()); + } + + inflater = getLayoutInflater(); + geocode = cache.geocode.toUpperCase(); + + ((ScrollView) findViewById(R.id.details_list_box)).setVisibility(View.VISIBLE); + LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); + detailsList.removeAllViews(); + + // actionbar icon + ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) getResources().getDrawable(cgBase.getCacheIcon(cache.type)), null, null, null); + + // cache type + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_type)); + if (cgBase.cacheTypesInv.containsKey(cache.type)) { // cache icon + if (StringUtils.isNotBlank(cache.size)) { + itemValue.setText(cgBase.cacheTypesInv.get(cache.type) + " (" + cache.size + ")"); + } else { + itemValue.setText(cgBase.cacheTypesInv.get(cache.type)); + } + } else { + if (StringUtils.isNotBlank(cache.size)) { + itemValue.setText(cgBase.cacheTypesInv.get("mystery") + " (" + cache.size + ")"); + } else { + itemValue.setText(cgBase.cacheTypesInv.get("mystery")); + } + } + detailsList.addView(itemLayout); + + // gc-code + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_geocode)); + itemValue.setText(cache.geocode.toUpperCase()); + detailsList.addView(itemLayout); + + // cache state + if (cache.archived || cache.disabled || cache.members || cache.found) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_status)); + + StringBuilder state = new StringBuilder(); + if (cache.found) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_found)); + } + if (cache.archived) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_archived)); + } + if (cache.disabled) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_disabled)); + } + if (cache.members) { + if (state.length() > 0) { + state.append(", "); + } + state.append(res.getString(R.string.cache_status_premium)); + } + + itemValue.setText(state.toString()); + detailsList.addView(itemLayout); + + state = null; + } + + // distance + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.cache_distance)); + itemValue.setText("--"); + detailsList.addView(itemLayout); + cacheDistance = itemValue; + + // difficulty + if (cache.difficulty > 0f) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); + + itemName.setText(res.getString(R.string.cache_difficulty)); + itemValue.setText(String.format(Locale.getDefault(), "%.1f", cache.difficulty) + " of 5"); + for (int i = 0; i <= 4; i++) { + ImageView star = (ImageView) inflater.inflate(R.layout.star, null); + if ((cache.difficulty - i) >= 1.0) { + star.setImageResource(R.drawable.star_on); + } else if ((cache.difficulty - i) > 0.0) { + star.setImageResource(R.drawable.star_half); + } else { + star.setImageResource(R.drawable.star_off); + } + itemStars.addView(star); + } + detailsList.addView(itemLayout); + } + + // terrain + if (cache.terrain > 0f) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); + + itemName.setText(res.getString(R.string.cache_terrain)); + itemValue.setText(String.format(Locale.getDefault(), "%.1f", cache.terrain) + " of 5"); + for (int i = 0; i <= 4; i++) { + ImageView star = (ImageView) inflater.inflate(R.layout.star, null); + if ((cache.terrain - i) >= 1.0) { + star.setImageResource(R.drawable.star_on); + } else if ((cache.terrain - i) > 0.0) { + star.setImageResource(R.drawable.star_half); + } else { + star.setImageResource(R.drawable.star_off); + } + itemStars.addView(star); + } + detailsList.addView(itemLayout); + } + + // rating + if (cache.rating != null && cache.rating > 0) { + setRating(cache.rating, cache.votes); + } else { + (new Thread() { + + public void run() { + cgRating rating = base.getRating(cache.guid, geocode); + + Message msg = new Message(); + Bundle bundle = new Bundle(); + + if (rating == null || rating.rating == null) { + return; + } + + bundle.putFloat("rating", rating.rating); + bundle.putInt("votes", rating.votes); + msg.setData(bundle); + + ratingHandler.sendMessage(msg); + } + }).start(); + } + + // more details + if (fromDetail == false) { + ((LinearLayout) findViewById(R.id.more_details_box)).setVisibility(View.VISIBLE); + + Button buttonMore = (Button) findViewById(R.id.more_details); + buttonMore.setOnClickListener(new OnClickListener() { + + public void onClick(View arg0) { + Intent cachesIntent = new Intent(cgeopopup.this, cgeodetail.class); + cachesIntent.putExtra("geocode", geocode.toUpperCase()); + startActivity(cachesIntent); + + finish(); + return; + } + }); + } else { + ((LinearLayout) findViewById(R.id.more_details_box)).setVisibility(View.GONE); + } + + if (fromDetail == false) { + ((LinearLayout) findViewById(R.id.offline_box)).setVisibility(View.VISIBLE); + + // offline use + final TextView offlineText = (TextView) findViewById(R.id.offline_text); + final Button offlineRefresh = (Button) findViewById(R.id.offline_refresh); + final Button offlineStore = (Button) findViewById(R.id.offline_store); + + if (cache.reason > 0) { + Long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.detailedUpdate / (60 * 1000)); // minutes + + String ago = ""; + if (diff < 15) { + ago = res.getString(R.string.cache_offline_time_mins_few); + } else if (diff < 50) { + ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); + } else if (diff < 90) { + ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); + } else if (diff < (48 * 60)) { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); + } else { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); + } + + offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); + + offlineRefresh.setVisibility(View.VISIBLE); + offlineRefresh.setEnabled(true); + offlineRefresh.setOnClickListener(new storeCache()); + + offlineStore.setText(res.getString(R.string.cache_offline_drop)); + offlineStore.setEnabled(true); + offlineStore.setOnClickListener(new dropCache()); + } else { + offlineText.setText(res.getString(R.string.cache_offline_not_ready)); + + offlineRefresh.setVisibility(View.GONE); + offlineRefresh.setEnabled(false); + offlineRefresh.setOnTouchListener(null); + offlineRefresh.setOnClickListener(null); + + offlineStore.setText(res.getString(R.string.cache_offline_store)); + offlineStore.setEnabled(true); + offlineStore.setOnClickListener(new storeCache()); + } + } else { + ((LinearLayout) findViewById(R.id.offline_box)).setVisibility(View.GONE); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeopopup.init: " + e.toString()); + } + + if (geo != null) { + geoUpdate.updateLoc(geo); + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + init(); + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + if (geo.coordsNow != null && cache != null && cache.coords != null) { + cacheDistance.setText(base.getHumanDistance(geo.coordsNow.distanceTo(cache.coords))); + cacheDistance.bringToFront(); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private void navigateTo() { + if (cache == null || cache.coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + } + + cgeonavigate navigateActivity = new cgeonavigate(); + + Intent navigateIntent = new Intent(this, navigateActivity.getClass()); + navigateIntent.putExtra("latitude", cache.coords.getLatitude()); + navigateIntent.putExtra("longitude", cache.coords.getLongitude()); + navigateIntent.putExtra("geocode", ""); + navigateIntent.putExtra("name", "Some destination"); + + startActivity(navigateIntent); + } + + private void cachesAround() { + if (cache == null || cache.coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + } + + cgeocaches.startActivityCachesAround(this, cache.coords); + + finish(); + } + + private class storeCache implements View.OnClickListener { + + public void onClick(View arg0) { + if (dropDialog != null && dropDialog.isShowing()) { + showToast("Still removing this cache."); + return; + } + + storeDialog = ProgressDialog.show(cgeopopup.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true); + storeDialog.setCancelable(false); + Thread thread = new storeCacheThread(storeCacheHandler); + thread.start(); + } + } + + private class storeCacheThread extends Thread { + + private Handler handler = null; + + public storeCacheThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + base.storeCache(app, cgeopopup.this, cache, null, 1, handler); + } + } + + private class dropCache implements View.OnClickListener { + + public void onClick(View arg0) { + if (storeDialog != null && storeDialog.isShowing()) { + showToast("Still saving this cache."); + return; + } + + dropDialog = ProgressDialog.show(cgeopopup.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true); + dropDialog.setCancelable(false); + Thread thread = new dropCacheThread(dropCacheHandler); + thread.start(); + } + } + + private class dropCacheThread extends Thread { + + private Handler handler = null; + + public dropCacheThread(Handler handlerIn) { + handler = handlerIn; + } + + @Override + public void run() { + cgBase.dropCache(app, cgeopopup.this, cache, handler); + } + } + + private void setRating(Float rating, Integer votes) { + if (rating == null || rating <= 0) { + return; + } + + RelativeLayout itemLayout; + TextView itemName; + TextView itemValue; + LinearLayout itemStars; + LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); + + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars); + + itemName.setText(res.getString(R.string.cache_rating)); + itemValue.setText(String.format(Locale.getDefault(), "%.1f", rating) + " of 5"); + for (int i = 0; i <= 4; i++) { + ImageView star = (ImageView) inflater.inflate(R.layout.star, null); + if ((rating - i) >= 1.0) { + star.setImageResource(R.drawable.star_on); + } else if ((rating - i) > 0.0) { + star.setImageResource(R.drawable.star_half); + } else { + star.setImageResource(R.drawable.star_off); + } + itemStars.addView(star, (1 + i)); + } + if (votes != null) { + final TextView itemAddition = (TextView) itemLayout.findViewById(R.id.addition); + itemAddition.setText("(" + votes + ")"); + itemAddition.setVisibility(View.VISIBLE); + } + detailsList.addView(itemLayout); + } + + public void goCompass(View view) { + if (cache == null || cache.coords == 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.coords.getLatitude()); + navigateIntent.putExtra("longitude", cache.coords.getLongitude()); + navigateIntent.putExtra("geocode", cache.geocode.toUpperCase()); + navigateIntent.putExtra("name", cache.name); + + startActivity(navigateIntent); + + finish(); + } + + public void goManual(View view) { + super.goManual(view); + finish(); + } } diff --git a/src/cgeo/geocaching/cgeosmaps.java b/src/cgeo/geocaching/cgeosmaps.java index 540d50c..96c9e0d 100644 --- a/src/cgeo/geocaching/cgeosmaps.java +++ b/src/cgeo/geocaching/cgeosmaps.java @@ -1,7 +1,7 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.utils.CollectionUtils; import android.app.ProgressDialog; import android.graphics.Bitmap; @@ -13,134 +13,135 @@ import android.util.Log; import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.LinearLayout; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; public class cgeosmaps extends AbstractActivity { - private List<Bitmap> maps = new ArrayList<Bitmap>(); - private String geocode = null; - private LayoutInflater inflater = null; - private ProgressDialog waitDialog = null; - private LinearLayout smapsView = null; - private BitmapFactory factory = null; - private Handler loadMapsHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (CollectionUtils.isEmpty(maps)) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - showToast(res.getString(R.string.err_detail_not_load_map_static)); - - finish(); - return; - } else { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - if (inflater == null) { - inflater = getLayoutInflater(); - } - - if (smapsView == null) { - smapsView = (LinearLayout) findViewById(R.id.maps_list); - } - smapsView.removeAllViews(); - - for (Bitmap image : maps) { - if (image != null) { - final ImageView map = (ImageView) inflater.inflate(R.layout.map_static_item, null); - map.setImageBitmap(image); - smapsView.addView(map); - } - } - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgeosmaps.loadMapsHandler: " + e.toString()); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.map_static); - setTitle(res.getString(R.string.map_static_title)); - - // get parameters - Bundle extras = getIntent().getExtras(); - - // try to get data from extras - if (extras != null) { - geocode = extras.getString("geocode"); - } - - if (geocode == null) { - showToast("Sorry, c:geo forgot for what cache you want to load static maps."); - finish(); - return; - } - - waitDialog = ProgressDialog.show(this, null, res.getString(R.string.map_static_loading), true); - waitDialog.setCancelable(true); - - (new loadMaps()).start(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - private class loadMaps extends Thread { - - @Override - public void run() { - try { - if (factory == null) { - factory = new BitmapFactory(); - } - - for (int level = 1; level <= 5; level++) { - try { - Bitmap image = BitmapFactory.decodeFile(cgSettings.getStorage() + geocode + "/map_" + level); - if (image != null) { - maps.add(image); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run.1: " + e.toString()); - } - } - - if (maps.isEmpty()) { - for (int level = 1; level <= 5; level++) { - try { - Bitmap image = BitmapFactory.decodeFile(cgSettings.getStorageSec() + geocode + "/map_" + level); - if (image != null) { - maps.add(image); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run.2: " + e.toString()); - } - } - } - - loadMapsHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run: " + e.toString()); - } - } - } + private List<Bitmap> maps = new ArrayList<Bitmap>(); + private String geocode = null; + private LayoutInflater inflater = null; + private ProgressDialog waitDialog = null; + private LinearLayout smapsView = null; + private BitmapFactory factory = null; + private Handler loadMapsHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (CollectionUtils.isEmpty(maps)) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + showToast(res.getString(R.string.err_detail_not_load_map_static)); + + finish(); + return; + } else { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + if (inflater == null) { + inflater = getLayoutInflater(); + } + + if (smapsView == null) { + smapsView = (LinearLayout) findViewById(R.id.maps_list); + } + smapsView.removeAllViews(); + + for (Bitmap image : maps) { + if (image != null) { + final ImageView map = (ImageView) inflater.inflate(R.layout.map_static_item, null); + map.setImageBitmap(image); + smapsView.addView(map); + } + } + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgeosmaps.loadMapsHandler: " + e.toString()); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.map_static); + setTitle(res.getString(R.string.map_static_title)); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + if (extras != null) { + geocode = extras.getString("geocode"); + } + + if (geocode == null) { + showToast("Sorry, c:geo forgot for what cache you want to load static maps."); + finish(); + return; + } + + waitDialog = ProgressDialog.show(this, null, res.getString(R.string.map_static_loading), true); + waitDialog.setCancelable(true); + + (new loadMaps()).start(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + private class loadMaps extends Thread { + + @Override + public void run() { + try { + if (factory == null) { + factory = new BitmapFactory(); + } + + for (int level = 1; level <= 5; level++) { + try { + Bitmap image = BitmapFactory.decodeFile(cgSettings.getStorage() + geocode + "/map_" + level); + if (image != null) { + maps.add(image); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run.1: " + e.toString()); + } + } + + if (maps.isEmpty()) { + for (int level = 1; level <= 5; level++) { + try { + Bitmap image = BitmapFactory.decodeFile(cgSettings.getStorageSec() + geocode + "/map_" + level); + if (image != null) { + maps.add(image); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run.2: " + e.toString()); + } + } + } + + loadMapsHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeosmaps.loadMaps.run: " + e.toString()); + } + } + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgeotouch.java b/src/cgeo/geocaching/cgeotouch.java index 8386018..5943ef2 100644 --- a/src/cgeo/geocaching/cgeotouch.java +++ b/src/cgeo/geocaching/cgeotouch.java @@ -1,11 +1,5 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.commons.lang3.StringUtils; import android.app.Dialog; @@ -26,423 +20,439 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class cgeotouch extends cgLogForm { - private cgTrackable trackable = null; - private List<Integer> types = new ArrayList<Integer>(); - private ProgressDialog waitDialog = null; - private String guid = null; - private String geocode = null; - private String[] viewstates = null; - private Boolean gettingViewstate = true; - private Calendar date = Calendar.getInstance(); - private int typeSelected = -1; - private int attempts = 0; - private CheckBox tweetCheck = null; - private LinearLayout tweetBox = null; - - private Handler showProgressHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - showProgress(true); - } - }; - - private Handler loadDataHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (cgBase.isEmpty(viewstates) && attempts < 2) { - showToast(res.getString(R.string.err_log_load_data_again)); - - loadData thread; - thread = new loadData(guid); - thread.start(); - - return; - } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { - showToast(res.getString(R.string.err_log_load_data)); - showProgress(false); - - return; - } - - gettingViewstate = false; // we're done, user can post log - - Button buttonPost = (Button)findViewById(R.id.post); - buttonPost.setEnabled(true); - buttonPost.setOnClickListener(new postListener()); - - showProgress(false); - } - }; - - private Handler postLogHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (msg.what == 1) { - showToast(res.getString(R.string.info_log_posted)); - - if (waitDialog != null) { - waitDialog.dismiss(); - } - finish(); - return; - } else if (msg.what >= 1000) { - if (msg.what == 1001) { - showToast(res.getString(R.string.warn_log_text_fill)); - } else if(msg.what == 1002) { - showToast(res.getString(R.string.err_log_failed_server)); - } else { - showToast(res.getString(R.string.err_log_post_failed)); - } - } else { - if (cgBase.errorRetrieve.get(msg.what) != null) { - showToast(res.getString(R.string.err_log_post_failed_because) + cgBase.errorRetrieve.get(msg.what) + "."); - } else { - showToast(res.getString(R.string.err_log_post_failed)); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } - }; - - public cgeotouch() { - super("c:geo-log-trackable"); - } + private cgTrackable trackable = null; + private List<Integer> types = new ArrayList<Integer>(); + private ProgressDialog waitDialog = null; + private String guid = null; + private String geocode = null; + private String[] viewstates = null; + private Boolean gettingViewstate = true; + private Calendar date = Calendar.getInstance(); + private int typeSelected = -1; + private int attempts = 0; + private CheckBox tweetCheck = null; + private LinearLayout tweetBox = null; + + private Handler showProgressHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + showProgress(true); + } + }; + + private Handler loadDataHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (cgBase.isEmpty(viewstates) && attempts < 2) { + showToast(res.getString(R.string.err_log_load_data_again)); + + loadData thread; + thread = new loadData(guid); + thread.start(); + + return; + } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { + showToast(res.getString(R.string.err_log_load_data)); + showProgress(false); + + return; + } + + gettingViewstate = false; // we're done, user can post log + + Button buttonPost = (Button) findViewById(R.id.post); + buttonPost.setEnabled(true); + buttonPost.setOnClickListener(new postListener()); + + showProgress(false); + } + }; + + private Handler postLogHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (msg.what == 1) { + showToast(res.getString(R.string.info_log_posted)); + + if (waitDialog != null) { + waitDialog.dismiss(); + } + finish(); + return; + } else if (msg.what >= 1000) { + if (msg.what == 1001) { + showToast(res.getString(R.string.warn_log_text_fill)); + } else if (msg.what == 1002) { + showToast(res.getString(R.string.err_log_failed_server)); + } else { + showToast(res.getString(R.string.err_log_post_failed)); + } + } else { + if (cgBase.errorRetrieve.get(msg.what) != null) { + showToast(res.getString(R.string.err_log_post_failed_because) + cgBase.errorRetrieve.get(msg.what) + "."); + } else { + showToast(res.getString(R.string.err_log_post_failed)); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } + }; + + public cgeotouch() { + super("c:geo-log-trackable"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.touch); + setTitle(res.getString(R.string.trackable_touch)); + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + geocode = extras.getString("geocode"); + guid = extras.getString("guid"); + } + + trackable = app.getTrackableByGeocode("logging trackable"); + + if (StringUtils.isNotBlank(trackable.name)) { + setTitle(res.getString(R.string.trackable_touch) + trackable.name); + } else { + setTitle(res.getString(R.string.trackable_touch) + trackable.geocode.toUpperCase()); + } + + app.setAction("logging trackable"); + + if (trackable == null || guid == null) { + showToast(res.getString(R.string.err_tb_forgot_saw)); + + finish(); + return; + } + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + SubMenu subMenu = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add); + + subMenu.add(0, 0x6, 0, res.getString(R.string.log_date_time)); + subMenu.add(0, 0x4, 0, res.getString(R.string.log_date)); + subMenu.add(0, 0x2, 0, res.getString(R.string.log_time)); + subMenu.add(0, 0x1, 0, res.getString(R.string.init_signature)); + subMenu.add(0, 0x7, 0, res.getString(R.string.log_date_time) + " & " + res.getString(R.string.init_signature)); + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (settings.getSignature() == null) { + menu.findItem(0x1).setVisible(false); + menu.findItem(0x7).setVisible(false); + } else { + menu.findItem(0x1).setVisible(true); + menu.findItem(0x7).setVisible(true); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + EditText text = null; + String textContent = null; + String dateString = null; + String timeString = null; + String addText = ""; + + if ((id >= 0x1 && id <= 0x7)) { + text = (EditText) findViewById(R.id.log); + textContent = text.getText().toString(); + + final long now = System.currentTimeMillis(); + dateString = base.formatDate(now); + timeString = base.formatTime(now); + + if ((id & 0x4) == 0x4) { + addText += dateString; + if ((id & 0x2) == 0x2) { + addText += " | "; + } + } + if ((id & 0x2) == 0x2) { + addText += timeString; + } + if ((id & 0x1) == 0x1 && settings.getSignature() != null) { + if (addText.length() > 0) { + addText += "\n"; + } + addText += settings.getSignature() + .replaceAll("\\[DATE\\]", dateString) + .replaceAll("\\[TIME\\]", timeString) + .replaceAll("\\[USER\\]", settings.getUsername()) + .replaceAll("\\[NUMBER\\]", ""); + } + if (textContent.length() > 0 && addText.length() > 0) { + addText = "\n" + addText; + } + text.setText(textContent + addText, TextView.BufferType.NORMAL); + text.setSelection(text.getText().toString().length()); + return true; + } + + return false; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + super.onCreateContextMenu(menu, view, info); + final int viewId = view.getId(); + + if (viewId == R.id.type) { + for (final int typeOne : types) + menu.add(viewId, typeOne, 0, cgBase.logTypes2.get(typeOne)); + } + } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.touch); - setTitle(res.getString(R.string.trackable_touch)); - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - geocode = extras.getString("geocode"); - guid = extras.getString("guid"); - } - - trackable = app.getTrackableByGeocode("logging trackable"); - - if (StringUtils.isNotBlank(trackable.name)) { - setTitle(res.getString(R.string.trackable_touch) + trackable.name); - } else { - setTitle(res.getString(R.string.trackable_touch) + trackable.geocode.toUpperCase()); - } - - app.setAction("logging trackable"); - - if (trackable == null || guid == null) { - showToast(res.getString(R.string.err_tb_forgot_saw)); - - finish(); - return; - } - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - SubMenu subMenu = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add); - - subMenu.add(0, 0x6, 0, res.getString(R.string.log_date_time)); - subMenu.add(0, 0x4, 0, res.getString(R.string.log_date)); - subMenu.add(0, 0x2, 0, res.getString(R.string.log_time)); - subMenu.add(0, 0x1, 0, res.getString(R.string.init_signature)); - subMenu.add(0, 0x7, 0, res.getString(R.string.log_date_time) + " & " + res.getString(R.string.init_signature)); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - if (settings.getSignature() == null) { - menu.findItem(0x1).setVisible(false); - menu.findItem(0x7).setVisible(false); - } else { - menu.findItem(0x1).setVisible(true); - menu.findItem(0x7).setVisible(true); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - - EditText text = null; - String textContent = null; - String dateString = null; - String timeString = null; - String addText = ""; - - if ((id >= 0x1 && id <= 0x7)) { - text = (EditText) findViewById(R.id.log); - textContent = text.getText().toString(); - - final long now = System.currentTimeMillis(); - dateString = base.formatDate(now); - timeString = base.formatTime(now); - - if ((id & 0x4) == 0x4) { - addText += dateString; - if ((id & 0x2) == 0x2) { - addText += " | "; - } - } - if ((id & 0x2) == 0x2) { - addText += timeString; - } - if ((id & 0x1) == 0x1 && settings.getSignature() != null) { - if (addText.length() > 0) { - addText += "\n"; - } - addText += settings.getSignature() - .replaceAll("\\[DATE\\]", dateString) - .replaceAll("\\[TIME\\]", timeString) - .replaceAll("\\[USER\\]", settings.getUsername()) - .replaceAll("\\[NUMBER\\]", ""); - } - if (textContent.length() > 0 && addText.length() > 0 ) { - addText = "\n" + addText; - } - text.setText(textContent + addText, TextView.BufferType.NORMAL); - text.setSelection(text.getText().toString().length()); - return true; - } - - return false; - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - - if (viewId == R.id.type) { - for (final int typeOne : types) menu.add(viewId, typeOne, 0, cgBase.logTypes2.get(typeOne)); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int group = item.getGroupId(); - final int id = item.getItemId(); - - if (group == R.id.type) { - setType(id); - - return true; - } - - return false; - } - - public void init() { - if (geocode != null) app.setAction("logging trackable"); - - types.clear(); - types.add(cgBase.LOG_RETRIEVED_IT); - types.add(cgBase.LOG_GRABBED_IT); - types.add(cgBase.LOG_NOTE); - types.add(cgBase.LOG_DISCOVERED_IT); - - if (typeSelected < 0 && cgBase.logTypes2.get(typeSelected) == null) typeSelected = types.get(2); - setType(typeSelected); - - Button typeButton = (Button)findViewById(R.id.type); - registerForContextMenu(typeButton); - typeButton.setText(cgBase.logTypes2.get(typeSelected)); - typeButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View view) { - openContextMenu(view); - } - }); - - Button dateButton = (Button)findViewById(R.id.date); - dateButton.setText(base.formatShortDate(date.getTime().getTime())); - dateButton.setOnClickListener(new cgeotouchDateListener()); - - if (tweetBox == null) tweetBox = (LinearLayout)findViewById(R.id.tweet_box); - if (tweetCheck == null) tweetCheck = (CheckBox)findViewById(R.id.tweet); + public boolean onContextItemSelected(MenuItem item) { + final int group = item.getGroupId(); + final int id = item.getItemId(); + + if (group == R.id.type) { + setType(id); + + return true; + } + + return false; + } + + public void init() { + if (geocode != null) + app.setAction("logging trackable"); + + types.clear(); + types.add(cgBase.LOG_RETRIEVED_IT); + types.add(cgBase.LOG_GRABBED_IT); + types.add(cgBase.LOG_NOTE); + types.add(cgBase.LOG_DISCOVERED_IT); + + if (typeSelected < 0 && cgBase.logTypes2.get(typeSelected) == null) + typeSelected = types.get(2); + setType(typeSelected); + + Button typeButton = (Button) findViewById(R.id.type); + registerForContextMenu(typeButton); + typeButton.setText(cgBase.logTypes2.get(typeSelected)); + typeButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + openContextMenu(view); + } + }); + + Button dateButton = (Button) findViewById(R.id.date); + dateButton.setText(base.formatShortDate(date.getTime().getTime())); + dateButton.setOnClickListener(new cgeotouchDateListener()); + + if (tweetBox == null) + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + if (tweetCheck == null) + tweetCheck = (CheckBox) findViewById(R.id.tweet); tweetCheck.setChecked(true); - Button buttonPost = (Button)findViewById(R.id.post); - if (cgBase.isEmpty(viewstates)) { - buttonPost.setEnabled(false); - buttonPost.setOnTouchListener(null); - buttonPost.setOnClickListener(null); - - loadData thread; - thread = new loadData(guid); - thread.start(); - } else { - buttonPost.setEnabled(true); - buttonPost.setOnClickListener(new postListener()); - } - } - - public void setDate(Calendar dateIn) { - date = dateIn; - - final Button dateButton = (Button)findViewById(R.id.date); - dateButton.setText(base.formatShortDate(date.getTime().getTime())); - } - - public void setType(int type) { - final Button typeButton = (Button)findViewById(R.id.type); - - if (cgBase.logTypes2.get(type) != null) typeSelected = type; - if (cgBase.logTypes2.get(typeSelected) == null) typeSelected = 0; - typeButton.setText(cgBase.logTypes2.get(typeSelected)); - - if (tweetBox == null) tweetBox = (LinearLayout)findViewById(R.id.tweet_box); - if (settings.twitter == 1) tweetBox.setVisibility(View.VISIBLE); - else tweetBox.setVisibility(View.GONE); - } - - private class cgeotouchDateListener implements View.OnClickListener { - public void onClick(View arg0) { - Dialog dateDialog = new cgeodate(cgeotouch.this, cgeotouch.this, date); - dateDialog.setCancelable(true); - dateDialog.show(); - } - } - - private class postListener implements View.OnClickListener { - public void onClick(View arg0) { - if (gettingViewstate == false) { - waitDialog = ProgressDialog.show(cgeotouch.this, null, res.getString(R.string.log_saving), true); - waitDialog.setCancelable(true); - - String tracking = ((EditText)findViewById(R.id.tracking)).getText().toString(); - String log = ((EditText)findViewById(R.id.log)).getText().toString(); - Thread thread = new postLog(postLogHandler, tracking, log); - thread.start(); - } else { - showToast(res.getString(R.string.err_log_load_data_still)); - } - } - } - - private class loadData extends Thread { - private String guid = null; - - public loadData(String guidIn) { - guid = guidIn; - - if (guid == null) { - showToast(res.getString(R.string.err_tb_forgot_saw)); - - finish(); - return; - } - } - - @Override - public void run() { - final Map<String, String> params = new HashMap<String, String>(); - - showProgressHandler.sendEmptyMessage(0); - gettingViewstate = true; - attempts ++; - - try { - if (StringUtils.isNotBlank(guid)) { - params.put("wid", guid); - } else { - loadDataHandler.sendEmptyMessage(0); - return; - } - - final String page = base.request(false, "www.geocaching.com", "/track/log.aspx", "GET", params, false, false, false).getData(); - - viewstates = cgBase.getViewstates(page); - - final List<Integer> typesPre = cgBase.parseTypes(page); - if (typesPre.size() > 0) { - types.clear(); - types.addAll(typesPre); - } - typesPre.clear(); - - if (types.contains(typeSelected) == false) { - typeSelected = types.get(0); - setType(typeSelected); - showToast(res.getString(R.string.info_log_type_changed)); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeotouch.loadData.run: " + e.toString()); - } - - loadDataHandler.sendEmptyMessage(0); - } - } - - private class postLog extends Thread { - Handler handler = null; - String tracking = null; - String log = null; - - public postLog(Handler handlerIn, String trackingIn, String logIn) { - handler = handlerIn; - tracking = trackingIn; - log = logIn; - } - - @Override - public void run() { - int ret = -1; - - ret = postLogFn(tracking, log); - - handler.sendEmptyMessage(ret); - } - } - - public int postLogFn(String tracking, String log) { - int status = -1; - - try { - if (tweetBox == null) tweetBox = (LinearLayout)findViewById(R.id.tweet_box); - if (tweetCheck == null) tweetCheck = (CheckBox)findViewById(R.id.tweet); - - status = base.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH ) + 1), date.get(Calendar.DATE), log); - - if ( - status == 1 && settings.twitter == 1 && - StringUtils.isNotBlank(settings.tokenPublic) && StringUtils.isNotBlank(settings.tokenSecret) && - tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE - ) { - cgBase.postTweetTrackable(app, settings, geocode); - } - - return status; - } catch (Exception e) { + Button buttonPost = (Button) findViewById(R.id.post); + if (cgBase.isEmpty(viewstates)) { + buttonPost.setEnabled(false); + buttonPost.setOnTouchListener(null); + buttonPost.setOnClickListener(null); + + loadData thread; + thread = new loadData(guid); + thread.start(); + } else { + buttonPost.setEnabled(true); + buttonPost.setOnClickListener(new postListener()); + } + } + + public void setDate(Calendar dateIn) { + date = dateIn; + + final Button dateButton = (Button) findViewById(R.id.date); + dateButton.setText(base.formatShortDate(date.getTime().getTime())); + } + + public void setType(int type) { + final Button typeButton = (Button) findViewById(R.id.type); + + if (cgBase.logTypes2.get(type) != null) + typeSelected = type; + if (cgBase.logTypes2.get(typeSelected) == null) + typeSelected = 0; + typeButton.setText(cgBase.logTypes2.get(typeSelected)); + + if (tweetBox == null) + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + if (settings.twitter == 1) + tweetBox.setVisibility(View.VISIBLE); + else + tweetBox.setVisibility(View.GONE); + } + + private class cgeotouchDateListener implements View.OnClickListener { + public void onClick(View arg0) { + Dialog dateDialog = new cgeodate(cgeotouch.this, cgeotouch.this, date); + dateDialog.setCancelable(true); + dateDialog.show(); + } + } + + private class postListener implements View.OnClickListener { + public void onClick(View arg0) { + if (gettingViewstate == false) { + waitDialog = ProgressDialog.show(cgeotouch.this, null, res.getString(R.string.log_saving), true); + waitDialog.setCancelable(true); + + String tracking = ((EditText) findViewById(R.id.tracking)).getText().toString(); + String log = ((EditText) findViewById(R.id.log)).getText().toString(); + Thread thread = new postLog(postLogHandler, tracking, log); + thread.start(); + } else { + showToast(res.getString(R.string.err_log_load_data_still)); + } + } + } + + private class loadData extends Thread { + private String guid = null; + + public loadData(String guidIn) { + guid = guidIn; + + if (guid == null) { + showToast(res.getString(R.string.err_tb_forgot_saw)); + + finish(); + return; + } + } + + @Override + public void run() { + final Map<String, String> params = new HashMap<String, String>(); + + showProgressHandler.sendEmptyMessage(0); + gettingViewstate = true; + attempts++; + + try { + if (StringUtils.isNotBlank(guid)) { + params.put("wid", guid); + } else { + loadDataHandler.sendEmptyMessage(0); + return; + } + + final String page = base.request(false, "www.geocaching.com", "/track/log.aspx", "GET", params, false, false, false).getData(); + + viewstates = cgBase.getViewstates(page); + + final List<Integer> typesPre = cgBase.parseTypes(page); + if (typesPre.size() > 0) { + types.clear(); + types.addAll(typesPre); + } + typesPre.clear(); + + if (types.contains(typeSelected) == false) { + typeSelected = types.get(0); + setType(typeSelected); + showToast(res.getString(R.string.info_log_type_changed)); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeotouch.loadData.run: " + e.toString()); + } + + loadDataHandler.sendEmptyMessage(0); + } + } + + private class postLog extends Thread { + Handler handler = null; + String tracking = null; + String log = null; + + public postLog(Handler handlerIn, String trackingIn, String logIn) { + handler = handlerIn; + tracking = trackingIn; + log = logIn; + } + + @Override + public void run() { + int ret = -1; + + ret = postLogFn(tracking, log); + + handler.sendEmptyMessage(ret); + } + } + + public int postLogFn(String tracking, String log) { + int status = -1; + + try { + if (tweetBox == null) + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + if (tweetCheck == null) + tweetCheck = (CheckBox) findViewById(R.id.tweet); + + status = base.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log); + + if (status == 1 && settings.twitter == 1 && + StringUtils.isNotBlank(settings.tokenPublic) && StringUtils.isNotBlank(settings.tokenSecret) && + tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE) { + cgBase.postTweetTrackable(app, settings, geocode); + } + + return status; + } catch (Exception e) { Log.e(cgSettings.tag, "cgeotouch.postLogFn: " + e.toString()); - } + } - return 1000; - } + return 1000; + } } diff --git a/src/cgeo/geocaching/cgeotrackable.java b/src/cgeo/geocaching/cgeotrackable.java index c323894..b1e6293 100644 --- a/src/cgeo/geocaching/cgeotrackable.java +++ b/src/cgeo/geocaching/cgeotrackable.java @@ -1,9 +1,6 @@ package cgeo.geocaching; -import java.net.URLEncoder; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import cgeo.geocaching.activity.AbstractActivity; import org.apache.commons.lang3.StringUtils; @@ -28,603 +25,605 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; + +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; public class cgeotrackable extends AbstractActivity { - public cgTrackable trackable = null; - public String geocode = null; - public String name = null; - public String guid = null; - public String id = null; - private String contextMenuUser = null; - private LayoutInflater inflater = null; - private ProgressDialog waitDialog = null; - private Handler loadTrackableHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - RelativeLayout itemLayout; - TextView itemName; - TextView itemValue; - - if (trackable != null && trackable.errorRetrieve != 0) { - showToast(res.getString(R.string.err_tb_details_download) + " " + cgBase.errorRetrieve.get(trackable.errorRetrieve) + "."); - - finish(); - return; - } - - if (trackable != null && StringUtils.isNotBlank(trackable.error)) { - showToast(res.getString(R.string.err_tb_details_download) + " " + trackable.error + "."); - - finish(); - return; - } - - if (trackable == null) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - if (StringUtils.isNotBlank(geocode)) { - showToast(res.getString(R.string.err_tb_find) + " " + geocode + "."); - } else { - showToast(res.getString(R.string.err_tb_find_that)); - } - - finish(); - return; - } - - try { - inflater = getLayoutInflater(); - geocode = trackable.geocode.toUpperCase(); - - if (StringUtils.isNotBlank(trackable.name)) { - setTitle(Html.fromHtml(trackable.name).toString()); - } else { - setTitle(trackable.name.toUpperCase()); - } - - ((ScrollView) findViewById(R.id.details_list_box)).setVisibility(View.VISIBLE); - LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); - - // actiobar icon - if (StringUtils.isNotBlank(trackable.iconUrl)) { - final tbIconHandler iconHandler = new tbIconHandler(((TextView) findViewById(R.id.actionbar_title))); - final tbIconThread iconThread = new tbIconThread(trackable.iconUrl, iconHandler); - iconThread.start(); - } - - // trackable name - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_name)); - if (StringUtils.isNotBlank(trackable.name)) { - itemValue.setText(Html.fromHtml(trackable.name).toString()); - } else { - itemValue.setText(res.getString(R.string.trackable_unknown)); - } - detailsList.addView(itemLayout); - - // trackable type - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - String tbType = null; - if (StringUtils.isNotBlank(trackable.type)) { - tbType = Html.fromHtml(trackable.type).toString(); - } else { - tbType = res.getString(R.string.trackable_unknown); - } - itemName.setText(res.getString(R.string.trackable_type)); - itemValue.setText(tbType); - detailsList.addView(itemLayout); - - // trackable geocode - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_code)); - itemValue.setText(trackable.geocode.toUpperCase()); - detailsList.addView(itemLayout); - - // trackable owner - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_owner)); - if (StringUtils.isNotBlank(trackable.owner)) { - itemValue.setText(Html.fromHtml(trackable.owner), TextView.BufferType.SPANNABLE); - itemLayout.setOnClickListener(new userActions()); - } else { - itemValue.setText(res.getString(R.string.trackable_unknown)); - } - detailsList.addView(itemLayout); - - // trackable spotted - if (StringUtils.isNotBlank(trackable.spottedName) || - trackable.spottedType == cgTrackable.SPOTTED_UNKNOWN || - trackable.spottedType == cgTrackable.SPOTTED_OWNER - ) { - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_spotted)); - String text = null; - - if (trackable.spottedType == cgTrackable.SPOTTED_CACHE) { - text = res.getString(R.string.trackable_spotted_in_cache) + " " + Html.fromHtml(trackable.spottedName).toString(); - } else if (trackable.spottedType == cgTrackable.SPOTTED_USER) { - text = res.getString(R.string.trackable_spotted_at_user) + " " + Html.fromHtml(trackable.spottedName).toString(); - } else if (trackable.spottedType == cgTrackable.SPOTTED_UNKNOWN) { - text = res.getString(R.string.trackable_spotted_unknown_location); - } else if (trackable.spottedType == cgTrackable.SPOTTED_OWNER) { - text = res.getString(R.string.trackable_spotted_owner); - } else { - text = "N/A"; - } - - itemValue.setText(text); - itemLayout.setClickable(true); - if (cgTrackable.SPOTTED_CACHE == trackable.spottedType) { - itemLayout.setOnClickListener(new View.OnClickListener() { - public void onClick(View arg0) { - Intent cacheIntent = new Intent(cgeotrackable.this, cgeodetail.class); - cacheIntent.putExtra("guid", (String) trackable.spottedGuid); - cacheIntent.putExtra("name", (String) trackable.spottedName); - startActivity(cacheIntent); - } - }); - } else if (cgTrackable.SPOTTED_USER == trackable.spottedType) { - itemLayout.setOnClickListener(new userActions()); - //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?guid=" + trackable.spottedGuid))); - } - - detailsList.addView(itemLayout); - } - - // trackable origin - if (StringUtils.isNotBlank(trackable.origin)) { - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_origin)); - itemValue.setText(Html.fromHtml(trackable.origin), TextView.BufferType.SPANNABLE); - detailsList.addView(itemLayout); - } - - // trackable released - if (trackable.released != null) { - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_released)); - itemValue.setText(base.formatDate(trackable.released.getTime())); - detailsList.addView(itemLayout); - } - - // trackable distance - if (trackable.distance != null) { - itemLayout = (RelativeLayout)inflater.inflate(R.layout.cache_item, null); - itemName = (TextView) itemLayout.findViewById(R.id.name); - itemValue = (TextView) itemLayout.findViewById(R.id.value); - - itemName.setText(res.getString(R.string.trackable_distance)); - itemValue.setText(base.getHumanDistance(trackable.distance)); - detailsList.addView(itemLayout); - } - - - // trackable goal - if (StringUtils.isNotBlank(trackable.goal)) { - ((LinearLayout) findViewById(R.id.goal_box)).setVisibility(View.VISIBLE); - TextView descView = (TextView) findViewById(R.id.goal); - descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(trackable.goal, new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); - descView.setMovementMethod(LinkMovementMethod.getInstance()); - } - - // trackable details - if (StringUtils.isNotBlank(trackable.details)) { - ((LinearLayout) findViewById(R.id.details_box)).setVisibility(View.VISIBLE); - TextView descView = (TextView) findViewById(R.id.details); - descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(trackable.details, new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); - descView.setMovementMethod(LinkMovementMethod.getInstance()); - } - - // trackable image - if (StringUtils.isNotBlank(trackable.image)) { - ((LinearLayout) findViewById(R.id.image_box)).setVisibility(View.VISIBLE); - LinearLayout imgView = (LinearLayout) findViewById(R.id.image); - - final ImageView trackableImage = (ImageView) inflater.inflate(R.layout.trackable_image, null); - - trackableImage.setImageResource(R.drawable.image_not_loaded); - trackableImage.setClickable(true); - trackableImage.setOnClickListener(new View.OnClickListener() { - - public void onClick(View arg0) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(trackable.image))); - } - }); - - // try to load image - final Handler handler = new Handler() { - - @Override - public void handleMessage(Message message) { - BitmapDrawable image = (BitmapDrawable) message.obj; - if (image != null) { - trackableImage.setImageDrawable((BitmapDrawable) message.obj); - } - } - }; - - new Thread() { - - @Override - public void run() { - BitmapDrawable image = null; - try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false); - - image = imgGetter.getDrawable(trackable.image); - Message message = handler.obtainMessage(0, image); - handler.sendMessage(message); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeospoilers.onCreate.onClick.run: " + e.toString()); - } - } - }.start(); - - imgView.addView(trackableImage); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeotrackable.loadTrackableHandler: " + e.toString() + Arrays.toString(e.getStackTrace())); - } - - displayLogs(); - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } - }; - - public cgeotrackable() { - super("c:geo-trackable-details"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.trackable_detail); - setTitle(res.getString(R.string.trackable)); - - // get parameters - Bundle extras = getIntent().getExtras(); - Uri uri = getIntent().getData(); - - // try to get data from extras - if (extras != null) { - geocode = extras.getString("geocode"); - name = extras.getString("name"); - guid = extras.getString("guid"); - id = extras.getString("id"); - } - - // try to get data from URI - if (geocode == null && guid == null && id == null && uri != null) { - String uriHost = uri.getHost().toLowerCase(); - if (uriHost.contains("geocaching.com")) { - geocode = uri.getQueryParameter("tracker"); - guid = uri.getQueryParameter("guid"); - id = uri.getQueryParameter("id"); - - if (StringUtils.isNotBlank(geocode)) { - geocode = geocode.toUpperCase(); - guid = null; - id = null; - } else if (StringUtils.isNotBlank(guid)) { - geocode = null; - guid = guid.toLowerCase(); - id = null; - } else if (StringUtils.isNotBlank(id)) { - geocode = null; - guid = null; - id = id.toLowerCase(); - } else { - showToast(res.getString(R.string.err_tb_details_open)); - finish(); - return; - } - } else if (uriHost.contains("coord.info")) { - String uriPath = uri.getPath().toLowerCase(); - if (uriPath != null && uriPath.startsWith("/tb")) { - geocode = uriPath.substring(1).toUpperCase(); - guid = null; - id = null; - } else { - showToast(res.getString(R.string.err_tb_details_open)); - finish(); - return; - } - } - } - - // no given data - if (geocode == null && guid == null && id == null) { - showToast(res.getString(R.string.err_tb_display)); - finish(); - return; - } - - if (StringUtils.isNotBlank(name)) { - waitDialog = ProgressDialog.show(this, Html.fromHtml(name).toString(), res.getString(R.string.trackable_details_loading), true); - } else if (StringUtils.isNotBlank(geocode)) { - waitDialog = ProgressDialog.show(this, geocode.toUpperCase(), res.getString(R.string.trackable_details_loading), true); - } else { - waitDialog = ProgressDialog.show(this, res.getString(R.string.trackable), res.getString(R.string.trackable_details_loading), true); - } - waitDialog.setCancelable(true); - - loadTrackable thread; - thread = new loadTrackable(loadTrackableHandler, geocode, guid, id); - thread.start(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - - if (viewId == R.id.author) { // Log item author - contextMenuUser = ((TextView)view).getText().toString(); - } else { // Trackable owner, and user holding trackable now - RelativeLayout itemLayout = (RelativeLayout)view; - TextView itemName = (TextView) itemLayout.findViewById(R.id.name); - - String selectedName = itemName.getText().toString(); - if (selectedName.equals(res.getString(R.string.trackable_owner))) { - contextMenuUser = trackable.owner; - } else if (selectedName.equals(res.getString(R.string.trackable_spotted))) { - contextMenuUser = trackable.spottedName; - } - } - - menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser); - menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden)); - menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found)); - menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser)); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int id = item.getItemId(); - - if (id == 1) { - cgeocaches.startActivityCacheOwner(this, contextMenuUser); - return true; - } else if (id == 2) { - cgeocaches.startActivityCacheUser(this, contextMenuUser); - return true; - } else if (id == 3) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser)))); - - return true; - } - return false; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, 1, 0, res.getString(R.string.trackable_log_touch)).setIcon(android.R.drawable.ic_menu_agenda); // log touch - - menu.add(0, 2, 0, res.getString(R.string.trackable_browser_open)).setIcon(android.R.drawable.ic_menu_info_details); // browser - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 1: - logTouch(); - return true; - case 2: - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/track/details.aspx?tracker=" + trackable.geocode))); - return true; - } - - return false; - } - - private class loadTrackable extends Thread { - - private Handler handler = null; - private String geocode = null; - private String guid = null; - private String id = null; - - public loadTrackable(Handler handlerIn, String geocodeIn, String guidIn, String idIn) { - handler = handlerIn; - geocode = geocodeIn; - guid = guidIn; - id = idIn; - - if (geocode == null && guid == null && id == null) { - showToast(res.getString(R.string.err_tb_forgot)); - - stop(); - finish(); - return; - } - } - - @Override - public void run() { - loadTrackableFn(geocode, guid, id); - handler.sendMessage(new Message()); - } - } - - public void loadTrackableFn(String geocode, String guid, String id) { - Map<String, String> params = new HashMap<String, String>(); - if (StringUtils.isNotBlank(geocode)) { - params.put("geocode", geocode); - } else if (StringUtils.isNotBlank(guid)) { - params.put("guid", guid); - } else if (StringUtils.isNotBlank(id)) { - params.put("id", id); - } else { - return; - } - - trackable = base.searchTrackable(params); - } - - private void displayLogs() { - // trackable logs - LinearLayout listView = (LinearLayout) findViewById(R.id.log_list); - listView.removeAllViews(); - - RelativeLayout rowView; - - if (trackable != null && trackable.logs != null) { - for (cgLog log : trackable.logs) { - rowView = (RelativeLayout) inflater.inflate(R.layout.trackable_logitem, null); - - if (log.date > 0) { - ((TextView) rowView.findViewById(R.id.added)).setText(base.formatShortDate(log.date)); - } - - - if (cgBase.logTypes1.containsKey(log.type)) { - ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(log.type)); - } else { - ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(4)); // note if type is unknown - } - ((TextView) rowView.findViewById(R.id.author)).setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE); - - if (StringUtils.isBlank(log.cacheName)) { - ((TextView) rowView.findViewById(R.id.location)).setVisibility(View.GONE); - } else { - ((TextView) rowView.findViewById(R.id.location)).setText(Html.fromHtml(log.cacheName)); - final String cacheGuid = log.cacheGuid; - final String cacheName = log.cacheName; - ((TextView) rowView.findViewById(R.id.location)).setOnClickListener(new View.OnClickListener() { - public void onClick(View arg0) { - Intent cacheIntent = new Intent(cgeotrackable.this, cgeodetail.class); - cacheIntent.putExtra("guid", (String) cacheGuid); - cacheIntent.putExtra("name", (String) Html.fromHtml(cacheName).toString()); - startActivity(cacheIntent); - } - }); - } - - ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(cgeotrackable.this, null, false, 0, false), null), TextView.BufferType.SPANNABLE); - - ((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions()); - listView.addView(rowView); - } - - if (trackable.logs.size() > 0) { - ((LinearLayout) findViewById(R.id.log_box)).setVisibility(View.VISIBLE); - } - } - } - - private class userActions implements View.OnClickListener { - - public void onClick(View view) { - if (view == null) { - return; - } - - try { - registerForContextMenu(view); - openContextMenu(view); - } catch (Exception e) { - // nothing - } - } - } - - private void logTouch() { - Intent logTouchIntent = new Intent(this, cgeotouch.class); - logTouchIntent.putExtra("geocode", trackable.geocode.toUpperCase()); - logTouchIntent.putExtra("guid", trackable.guid); - startActivity(logTouchIntent); - } - - private class tbIconThread extends Thread { - String url = null; - Handler handler = null; - - public tbIconThread(String urlIn, Handler handlerIn) { - url = urlIn; - handler = handlerIn; - } - - @Override - public void run() { - if (url == null || handler == null) { - return; - } - - BitmapDrawable image = null; - try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, trackable.geocode, false, 0, false); - - image = imgGetter.getDrawable(url); - Message message = handler.obtainMessage(0, image); - handler.sendMessage(message); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeotrackable.tbIconThread.run: " + e.toString()); - } - } - } - - private static class tbIconHandler extends Handler { - TextView view = null; - - public tbIconHandler(TextView viewIn) { - view = viewIn; - } - - @Override - public void handleMessage(Message message) { - BitmapDrawable image = (BitmapDrawable) message.obj; - if (image != null && view != null) { - view.setCompoundDrawablesWithIntrinsicBounds((Drawable) image, null, null, null); - } - } - } - - public static void startActivity(final AbstractActivity fromContext, - final String guid, final String geocode, final String name) { - Intent trackableIntent = new Intent(fromContext, cgeotrackable.class); - trackableIntent.putExtra("guid", guid); - trackableIntent.putExtra("geocode", geocode); - trackableIntent.putExtra("name", name); - fromContext.startActivity(trackableIntent); - } + public cgTrackable trackable = null; + public String geocode = null; + public String name = null; + public String guid = null; + public String id = null; + private String contextMenuUser = null; + private LayoutInflater inflater = null; + private ProgressDialog waitDialog = null; + private Handler loadTrackableHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + RelativeLayout itemLayout; + TextView itemName; + TextView itemValue; + + if (trackable != null && trackable.errorRetrieve != 0) { + showToast(res.getString(R.string.err_tb_details_download) + " " + cgBase.errorRetrieve.get(trackable.errorRetrieve) + "."); + + finish(); + return; + } + + if (trackable != null && StringUtils.isNotBlank(trackable.error)) { + showToast(res.getString(R.string.err_tb_details_download) + " " + trackable.error + "."); + + finish(); + return; + } + + if (trackable == null) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + if (StringUtils.isNotBlank(geocode)) { + showToast(res.getString(R.string.err_tb_find) + " " + geocode + "."); + } else { + showToast(res.getString(R.string.err_tb_find_that)); + } + + finish(); + return; + } + + try { + inflater = getLayoutInflater(); + geocode = trackable.geocode.toUpperCase(); + + if (StringUtils.isNotBlank(trackable.name)) { + setTitle(Html.fromHtml(trackable.name).toString()); + } else { + setTitle(trackable.name.toUpperCase()); + } + + ((ScrollView) findViewById(R.id.details_list_box)).setVisibility(View.VISIBLE); + LinearLayout detailsList = (LinearLayout) findViewById(R.id.details_list); + + // actiobar icon + if (StringUtils.isNotBlank(trackable.iconUrl)) { + final tbIconHandler iconHandler = new tbIconHandler(((TextView) findViewById(R.id.actionbar_title))); + final tbIconThread iconThread = new tbIconThread(trackable.iconUrl, iconHandler); + iconThread.start(); + } + + // trackable name + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_name)); + if (StringUtils.isNotBlank(trackable.name)) { + itemValue.setText(Html.fromHtml(trackable.name).toString()); + } else { + itemValue.setText(res.getString(R.string.trackable_unknown)); + } + detailsList.addView(itemLayout); + + // trackable type + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + String tbType = null; + if (StringUtils.isNotBlank(trackable.type)) { + tbType = Html.fromHtml(trackable.type).toString(); + } else { + tbType = res.getString(R.string.trackable_unknown); + } + itemName.setText(res.getString(R.string.trackable_type)); + itemValue.setText(tbType); + detailsList.addView(itemLayout); + + // trackable geocode + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_code)); + itemValue.setText(trackable.geocode.toUpperCase()); + detailsList.addView(itemLayout); + + // trackable owner + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_owner)); + if (StringUtils.isNotBlank(trackable.owner)) { + itemValue.setText(Html.fromHtml(trackable.owner), TextView.BufferType.SPANNABLE); + itemLayout.setOnClickListener(new userActions()); + } else { + itemValue.setText(res.getString(R.string.trackable_unknown)); + } + detailsList.addView(itemLayout); + + // trackable spotted + if (StringUtils.isNotBlank(trackable.spottedName) || + trackable.spottedType == cgTrackable.SPOTTED_UNKNOWN || + trackable.spottedType == cgTrackable.SPOTTED_OWNER + ) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_spotted)); + String text = null; + + if (trackable.spottedType == cgTrackable.SPOTTED_CACHE) { + text = res.getString(R.string.trackable_spotted_in_cache) + " " + Html.fromHtml(trackable.spottedName).toString(); + } else if (trackable.spottedType == cgTrackable.SPOTTED_USER) { + text = res.getString(R.string.trackable_spotted_at_user) + " " + Html.fromHtml(trackable.spottedName).toString(); + } else if (trackable.spottedType == cgTrackable.SPOTTED_UNKNOWN) { + text = res.getString(R.string.trackable_spotted_unknown_location); + } else if (trackable.spottedType == cgTrackable.SPOTTED_OWNER) { + text = res.getString(R.string.trackable_spotted_owner); + } else { + text = "N/A"; + } + + itemValue.setText(text); + itemLayout.setClickable(true); + if (cgTrackable.SPOTTED_CACHE == trackable.spottedType) { + itemLayout.setOnClickListener(new View.OnClickListener() { + public void onClick(View arg0) { + Intent cacheIntent = new Intent(cgeotrackable.this, cgeodetail.class); + cacheIntent.putExtra("guid", (String) trackable.spottedGuid); + cacheIntent.putExtra("name", (String) trackable.spottedName); + startActivity(cacheIntent); + } + }); + } else if (cgTrackable.SPOTTED_USER == trackable.spottedType) { + itemLayout.setOnClickListener(new userActions()); + //activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?guid=" + trackable.spottedGuid))); + } + + detailsList.addView(itemLayout); + } + + // trackable origin + if (StringUtils.isNotBlank(trackable.origin)) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_origin)); + itemValue.setText(Html.fromHtml(trackable.origin), TextView.BufferType.SPANNABLE); + detailsList.addView(itemLayout); + } + + // trackable released + if (trackable.released != null) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_released)); + itemValue.setText(base.formatDate(trackable.released.getTime())); + detailsList.addView(itemLayout); + } + + // trackable distance + if (trackable.distance != null) { + itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null); + itemName = (TextView) itemLayout.findViewById(R.id.name); + itemValue = (TextView) itemLayout.findViewById(R.id.value); + + itemName.setText(res.getString(R.string.trackable_distance)); + itemValue.setText(base.getHumanDistance(trackable.distance)); + detailsList.addView(itemLayout); + } + + // trackable goal + if (StringUtils.isNotBlank(trackable.goal)) { + ((LinearLayout) findViewById(R.id.goal_box)).setVisibility(View.VISIBLE); + TextView descView = (TextView) findViewById(R.id.goal); + descView.setVisibility(View.VISIBLE); + descView.setText(Html.fromHtml(trackable.goal, new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); + descView.setMovementMethod(LinkMovementMethod.getInstance()); + } + + // trackable details + if (StringUtils.isNotBlank(trackable.details)) { + ((LinearLayout) findViewById(R.id.details_box)).setVisibility(View.VISIBLE); + TextView descView = (TextView) findViewById(R.id.details); + descView.setVisibility(View.VISIBLE); + descView.setText(Html.fromHtml(trackable.details, new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); + descView.setMovementMethod(LinkMovementMethod.getInstance()); + } + + // trackable image + if (StringUtils.isNotBlank(trackable.image)) { + ((LinearLayout) findViewById(R.id.image_box)).setVisibility(View.VISIBLE); + LinearLayout imgView = (LinearLayout) findViewById(R.id.image); + + final ImageView trackableImage = (ImageView) inflater.inflate(R.layout.trackable_image, null); + + trackableImage.setImageResource(R.drawable.image_not_loaded); + trackableImage.setClickable(true); + trackableImage.setOnClickListener(new View.OnClickListener() { + + public void onClick(View arg0) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(trackable.image))); + } + }); + + // try to load image + final Handler handler = new Handler() { + + @Override + public void handleMessage(Message message) { + BitmapDrawable image = (BitmapDrawable) message.obj; + if (image != null) { + trackableImage.setImageDrawable((BitmapDrawable) message.obj); + } + } + }; + + new Thread() { + + @Override + public void run() { + BitmapDrawable image = null; + try { + cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false); + + image = imgGetter.getDrawable(trackable.image); + Message message = handler.obtainMessage(0, image); + handler.sendMessage(message); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeospoilers.onCreate.onClick.run: " + e.toString()); + } + } + }.start(); + + imgView.addView(trackableImage); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeotrackable.loadTrackableHandler: " + e.toString() + Arrays.toString(e.getStackTrace())); + } + + displayLogs(); + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } + }; + + public cgeotrackable() { + super("c:geo-trackable-details"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.trackable_detail); + setTitle(res.getString(R.string.trackable)); + + // get parameters + Bundle extras = getIntent().getExtras(); + Uri uri = getIntent().getData(); + + // try to get data from extras + if (extras != null) { + geocode = extras.getString("geocode"); + name = extras.getString("name"); + guid = extras.getString("guid"); + id = extras.getString("id"); + } + + // try to get data from URI + if (geocode == null && guid == null && id == null && uri != null) { + String uriHost = uri.getHost().toLowerCase(); + if (uriHost.contains("geocaching.com")) { + geocode = uri.getQueryParameter("tracker"); + guid = uri.getQueryParameter("guid"); + id = uri.getQueryParameter("id"); + + if (StringUtils.isNotBlank(geocode)) { + geocode = geocode.toUpperCase(); + guid = null; + id = null; + } else if (StringUtils.isNotBlank(guid)) { + geocode = null; + guid = guid.toLowerCase(); + id = null; + } else if (StringUtils.isNotBlank(id)) { + geocode = null; + guid = null; + id = id.toLowerCase(); + } else { + showToast(res.getString(R.string.err_tb_details_open)); + finish(); + return; + } + } else if (uriHost.contains("coord.info")) { + String uriPath = uri.getPath().toLowerCase(); + if (uriPath != null && uriPath.startsWith("/tb")) { + geocode = uriPath.substring(1).toUpperCase(); + guid = null; + id = null; + } else { + showToast(res.getString(R.string.err_tb_details_open)); + finish(); + return; + } + } + } + + // no given data + if (geocode == null && guid == null && id == null) { + showToast(res.getString(R.string.err_tb_display)); + finish(); + return; + } + + if (StringUtils.isNotBlank(name)) { + waitDialog = ProgressDialog.show(this, Html.fromHtml(name).toString(), res.getString(R.string.trackable_details_loading), true); + } else if (StringUtils.isNotBlank(geocode)) { + waitDialog = ProgressDialog.show(this, geocode.toUpperCase(), res.getString(R.string.trackable_details_loading), true); + } else { + waitDialog = ProgressDialog.show(this, res.getString(R.string.trackable), res.getString(R.string.trackable_details_loading), true); + } + waitDialog.setCancelable(true); + + loadTrackable thread; + thread = new loadTrackable(loadTrackableHandler, geocode, guid, id); + thread.start(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + super.onCreateContextMenu(menu, view, info); + final int viewId = view.getId(); + + if (viewId == R.id.author) { // Log item author + contextMenuUser = ((TextView) view).getText().toString(); + } else { // Trackable owner, and user holding trackable now + RelativeLayout itemLayout = (RelativeLayout) view; + TextView itemName = (TextView) itemLayout.findViewById(R.id.name); + + String selectedName = itemName.getText().toString(); + if (selectedName.equals(res.getString(R.string.trackable_owner))) { + contextMenuUser = trackable.owner; + } else if (selectedName.equals(res.getString(R.string.trackable_spotted))) { + contextMenuUser = trackable.spottedName; + } + } + + menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser); + menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden)); + menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found)); + menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser)); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + final int id = item.getItemId(); + + if (id == 1) { + cgeocaches.startActivityCacheOwner(this, contextMenuUser); + return true; + } else if (id == 2) { + cgeocaches.startActivityCacheUser(this, contextMenuUser); + return true; + } else if (id == 3) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser)))); + + return true; + } + return false; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, 1, 0, res.getString(R.string.trackable_log_touch)).setIcon(android.R.drawable.ic_menu_agenda); // log touch + + menu.add(0, 2, 0, res.getString(R.string.trackable_browser_open)).setIcon(android.R.drawable.ic_menu_info_details); // browser + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case 1: + logTouch(); + return true; + case 2: + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/track/details.aspx?tracker=" + trackable.geocode))); + return true; + } + + return false; + } + + private class loadTrackable extends Thread { + + private Handler handler = null; + private String geocode = null; + private String guid = null; + private String id = null; + + public loadTrackable(Handler handlerIn, String geocodeIn, String guidIn, String idIn) { + handler = handlerIn; + geocode = geocodeIn; + guid = guidIn; + id = idIn; + + if (geocode == null && guid == null && id == null) { + showToast(res.getString(R.string.err_tb_forgot)); + + stop(); + finish(); + return; + } + } + + @Override + public void run() { + loadTrackableFn(geocode, guid, id); + handler.sendMessage(new Message()); + } + } + + public void loadTrackableFn(String geocode, String guid, String id) { + Map<String, String> params = new HashMap<String, String>(); + if (StringUtils.isNotBlank(geocode)) { + params.put("geocode", geocode); + } else if (StringUtils.isNotBlank(guid)) { + params.put("guid", guid); + } else if (StringUtils.isNotBlank(id)) { + params.put("id", id); + } else { + return; + } + + trackable = base.searchTrackable(params); + } + + private void displayLogs() { + // trackable logs + LinearLayout listView = (LinearLayout) findViewById(R.id.log_list); + listView.removeAllViews(); + + RelativeLayout rowView; + + if (trackable != null && trackable.logs != null) { + for (cgLog log : trackable.logs) { + rowView = (RelativeLayout) inflater.inflate(R.layout.trackable_logitem, null); + + if (log.date > 0) { + ((TextView) rowView.findViewById(R.id.added)).setText(base.formatShortDate(log.date)); + } + + if (cgBase.logTypes1.containsKey(log.type)) { + ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(log.type)); + } else { + ((TextView) rowView.findViewById(R.id.type)).setText(cgBase.logTypes1.get(4)); // note if type is unknown + } + ((TextView) rowView.findViewById(R.id.author)).setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE); + + if (StringUtils.isBlank(log.cacheName)) { + ((TextView) rowView.findViewById(R.id.location)).setVisibility(View.GONE); + } else { + ((TextView) rowView.findViewById(R.id.location)).setText(Html.fromHtml(log.cacheName)); + final String cacheGuid = log.cacheGuid; + final String cacheName = log.cacheName; + ((TextView) rowView.findViewById(R.id.location)).setOnClickListener(new View.OnClickListener() { + public void onClick(View arg0) { + Intent cacheIntent = new Intent(cgeotrackable.this, cgeodetail.class); + cacheIntent.putExtra("guid", (String) cacheGuid); + cacheIntent.putExtra("name", (String) Html.fromHtml(cacheName).toString()); + startActivity(cacheIntent); + } + }); + } + + ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(cgeotrackable.this, null, false, 0, false), null), TextView.BufferType.SPANNABLE); + + ((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions()); + listView.addView(rowView); + } + + if (trackable.logs.size() > 0) { + ((LinearLayout) findViewById(R.id.log_box)).setVisibility(View.VISIBLE); + } + } + } + + private class userActions implements View.OnClickListener { + + public void onClick(View view) { + if (view == null) { + return; + } + + try { + registerForContextMenu(view); + openContextMenu(view); + } catch (Exception e) { + // nothing + } + } + } + + private void logTouch() { + Intent logTouchIntent = new Intent(this, cgeotouch.class); + logTouchIntent.putExtra("geocode", trackable.geocode.toUpperCase()); + logTouchIntent.putExtra("guid", trackable.guid); + startActivity(logTouchIntent); + } + + private class tbIconThread extends Thread { + String url = null; + Handler handler = null; + + public tbIconThread(String urlIn, Handler handlerIn) { + url = urlIn; + handler = handlerIn; + } + + @Override + public void run() { + if (url == null || handler == null) { + return; + } + + BitmapDrawable image = null; + try { + cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, trackable.geocode, false, 0, false); + + image = imgGetter.getDrawable(url); + Message message = handler.obtainMessage(0, image); + handler.sendMessage(message); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeotrackable.tbIconThread.run: " + e.toString()); + } + } + } + + private static class tbIconHandler extends Handler { + TextView view = null; + + public tbIconHandler(TextView viewIn) { + view = viewIn; + } + + @Override + public void handleMessage(Message message) { + BitmapDrawable image = (BitmapDrawable) message.obj; + if (image != null && view != null) { + view.setCompoundDrawablesWithIntrinsicBounds((Drawable) image, null, null, null); + } + } + } + + public static void startActivity(final AbstractActivity fromContext, + final String guid, final String geocode, final String name) { + Intent trackableIntent = new Intent(fromContext, cgeotrackable.class); + trackableIntent.putExtra("guid", guid); + trackableIntent.putExtra("geocode", geocode); + trackableIntent.putExtra("name", name); + fromContext.startActivity(trackableIntent); + } } diff --git a/src/cgeo/geocaching/cgeotrackables.java b/src/cgeo/geocaching/cgeotrackables.java index 1ad5e46..ed67782 100644 --- a/src/cgeo/geocaching/cgeotrackables.java +++ b/src/cgeo/geocaching/cgeotrackables.java @@ -1,7 +1,6 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.activity.AbstractActivity; import android.app.ProgressDialog; import android.os.Bundle; @@ -13,139 +12,141 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; -import cgeo.geocaching.activity.AbstractActivity; + +import java.util.ArrayList; +import java.util.List; public class cgeotrackables extends AbstractActivity { - private List<cgTrackable> trackables = new ArrayList<cgTrackable>(); - private String geocode = null; - private LayoutInflater inflater = null; - private LinearLayout addList = null; - private ProgressDialog waitDialog = null; - private Handler loadInventoryHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (inflater == null) { - inflater = getLayoutInflater(); - } - - if (addList == null) { - addList = (LinearLayout) findViewById(R.id.trackable_list); - } - - if (trackables.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - showToast("Sorry, c:geo failed to load cache inventory."); - - finish(); - return; - } else if (trackables.size() == 1){ - cgTrackable trackable = trackables.get(0); - cgeotrackable.startActivity(cgeotrackables.this, trackable.guid, trackable.geocode, trackable.name); - finish(); - return; - } else { - LinearLayout oneTbPre = null; - for (cgTrackable trackable : trackables) { - oneTbPre = (LinearLayout) inflater.inflate(R.layout.trackable_button, null); - - Button oneTb = (Button) oneTbPre.findViewById(R.id.button); - - if (trackable.name != null) { - oneTb.setText(Html.fromHtml(trackable.name).toString()); - } else { - oneTb.setText("some trackable"); - } - oneTb.setClickable(true); - oneTb.setOnClickListener(new buttonListener(trackable.guid, trackable.geocode, trackable.name)); - addList.addView(oneTbPre); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgeotrackables.loadInventoryHandler: " + e.toString()); - } - } - }; - - public cgeotrackables() { - super("c:geo-trackable-list"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.trackables); - setTitle("Trackables"); - - // get parameters - Bundle extras = getIntent().getExtras(); - - // try to get data from extras - if (extras != null) { - geocode = extras.getString("geocode"); - } - - if (geocode == null) { - showToast("Sorry, c:geo forgot for what cache you want to load trackables."); - finish(); - return; - } - - waitDialog = ProgressDialog.show(this, null, "loading cache inventory...", true); - waitDialog.setCancelable(true); - - (new loadInventory()).start(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - private class loadInventory extends Thread { - - @Override - public void run() { - try { - trackables = app.loadInventory(geocode); - - loadInventoryHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeotrackables.loadInventory.run: " + e.toString()); - } - } - } - - private class buttonListener implements View.OnClickListener { - - private String guid = null; - private String geocode = null; - private String name = null; - - public buttonListener(String guidIn, String geocodeIn, String nameIn) { - guid = guidIn; - geocode = geocodeIn; - name = nameIn; - } - - public void onClick(View arg0) { - cgeotrackable.startActivity(cgeotrackables.this, guid, geocode, name); - return; - } - } + private List<cgTrackable> trackables = new ArrayList<cgTrackable>(); + private String geocode = null; + private LayoutInflater inflater = null; + private LinearLayout addList = null; + private ProgressDialog waitDialog = null; + private Handler loadInventoryHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (inflater == null) { + inflater = getLayoutInflater(); + } + + if (addList == null) { + addList = (LinearLayout) findViewById(R.id.trackable_list); + } + + if (trackables.isEmpty()) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + showToast("Sorry, c:geo failed to load cache inventory."); + + finish(); + return; + } else if (trackables.size() == 1) { + cgTrackable trackable = trackables.get(0); + cgeotrackable.startActivity(cgeotrackables.this, trackable.guid, trackable.geocode, trackable.name); + finish(); + return; + } else { + LinearLayout oneTbPre = null; + for (cgTrackable trackable : trackables) { + oneTbPre = (LinearLayout) inflater.inflate(R.layout.trackable_button, null); + + Button oneTb = (Button) oneTbPre.findViewById(R.id.button); + + if (trackable.name != null) { + oneTb.setText(Html.fromHtml(trackable.name).toString()); + } else { + oneTb.setText("some trackable"); + } + oneTb.setClickable(true); + oneTb.setOnClickListener(new buttonListener(trackable.guid, trackable.geocode, trackable.name)); + addList.addView(oneTbPre); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgeotrackables.loadInventoryHandler: " + e.toString()); + } + } + }; + + public cgeotrackables() { + super("c:geo-trackable-list"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.trackables); + setTitle("Trackables"); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + if (extras != null) { + geocode = extras.getString("geocode"); + } + + if (geocode == null) { + showToast("Sorry, c:geo forgot for what cache you want to load trackables."); + finish(); + return; + } + + waitDialog = ProgressDialog.show(this, null, "loading cache inventory...", true); + waitDialog.setCancelable(true); + + (new loadInventory()).start(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + private class loadInventory extends Thread { + + @Override + public void run() { + try { + trackables = app.loadInventory(geocode); + + loadInventoryHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeotrackables.loadInventory.run: " + e.toString()); + } + } + } + + private class buttonListener implements View.OnClickListener { + + private String guid = null; + private String geocode = null; + private String name = null; + + public buttonListener(String guidIn, String geocodeIn, String nameIn) { + guid = guidIn; + geocode = geocodeIn; + name = nameIn; + } + + public void onClick(View arg0) { + cgeotrackable.startActivity(cgeotrackables.this, guid, geocode, name); + return; + } + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/cgeovisit.java b/src/cgeo/geocaching/cgeovisit.java index d7eba71..482ea27 100644 --- a/src/cgeo/geocaching/cgeovisit.java +++ b/src/cgeo/geocaching/cgeovisit.java @@ -1,12 +1,7 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import cgeo.geocaching.LogTemplateProvider.LogTemplate; +import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -29,796 +24,799 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; -import cgeo.geocaching.LogTemplateProvider.LogTemplate; -import cgeo.geocaching.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; public class cgeovisit extends cgLogForm { - static final String EXTRAS_FOUND = "found"; - static final String EXTRAS_TEXT = "text"; - static final String EXTRAS_GEOCODE = "geocode"; - static final String EXTRAS_ID = "id"; - - private static final int MENU_SIGNATURE = 1; - private static final int SUBMENU_VOTE = 2; - - private LayoutInflater inflater = null; - private cgCache cache = null; - private List<Integer> types = new ArrayList<Integer>(); - private ProgressDialog waitDialog = null; - private String cacheid = null; - private String geocode = null; - private String text = null; - private boolean alreadyFound = false; - private String[] viewstates = null; - private Boolean gettingViewstate = true; - private List<cgTrackableLog> trackables = null; - private Calendar date = Calendar.getInstance(); - private int typeSelected = 1; - private int attempts = 0; - private boolean progressBar = false; - private Button post = null; - private Button save = null; - private Button clear = null; - private CheckBox tweetCheck = null; - private LinearLayout tweetBox = null; - private double rating = 0.0; - private boolean tbChanged = false; - - // handlers - private Handler showProgressHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (progressBar) { - showProgress(true); - } - } - }; - private Handler loadDataHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (types.contains(typeSelected) == false) { - typeSelected = types.get(0); - setType(typeSelected); - - showToast(res.getString(R.string.info_log_type_changed)); - } - - if (cgBase.isEmpty(viewstates) && attempts < 2) { - showToast(res.getString(R.string.err_log_load_data_again)); - - loadData thread; - thread = new loadData(); - thread.start(); - - return; - } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { - showToast(res.getString(R.string.err_log_load_data)); - showProgress(false); - - return; - } - - gettingViewstate = false; // we're done, user can post log - - if (post == null) { - post = (Button) findViewById(R.id.post); - } - post.setEnabled(true); - post.setOnClickListener(new postListener()); - - // add trackables - if (CollectionUtils.isNotEmpty(trackables)) { - if (inflater == null) { - inflater = getLayoutInflater(); - } - - final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory); - inventoryView.removeAllViews(); - - for (cgTrackableLog tb : trackables) { - LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null); - - ((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode); - ((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name); - ((TextView) inventoryItem.findViewById(R.id.action)).setText(cgBase.logTypesTrackable.get(settings.trackableAutovisit ? 1 : 0)); - - inventoryItem.setId(tb.id); - final String tbCode = tb.trackCode; - inventoryItem.setClickable(true); - registerForContextMenu(inventoryItem); - inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() { - - public void onClick(View view) { - final Intent trackablesIntent = new Intent(cgeovisit.this, cgeotrackable.class); - trackablesIntent.putExtra(EXTRAS_GEOCODE, tbCode); - startActivity(trackablesIntent); - } - }); - inventoryItem.findViewById(R.id.action).setOnClickListener(new View.OnClickListener() { - - public void onClick(View view) { - openContextMenu(view); - } - }); - - inventoryView.addView(inventoryItem); - - if (settings.trackableAutovisit) + static final String EXTRAS_FOUND = "found"; + static final String EXTRAS_TEXT = "text"; + static final String EXTRAS_GEOCODE = "geocode"; + static final String EXTRAS_ID = "id"; + + private static final int MENU_SIGNATURE = 1; + private static final int SUBMENU_VOTE = 2; + + private LayoutInflater inflater = null; + private cgCache cache = null; + private List<Integer> types = new ArrayList<Integer>(); + private ProgressDialog waitDialog = null; + private String cacheid = null; + private String geocode = null; + private String text = null; + private boolean alreadyFound = false; + private String[] viewstates = null; + private Boolean gettingViewstate = true; + private List<cgTrackableLog> trackables = null; + private Calendar date = Calendar.getInstance(); + private int typeSelected = 1; + private int attempts = 0; + private boolean progressBar = false; + private Button post = null; + private Button save = null; + private Button clear = null; + private CheckBox tweetCheck = null; + private LinearLayout tweetBox = null; + private double rating = 0.0; + private boolean tbChanged = false; + + // handlers + private Handler showProgressHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (progressBar) { + showProgress(true); + } + } + }; + private Handler loadDataHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (types.contains(typeSelected) == false) { + typeSelected = types.get(0); + setType(typeSelected); + + showToast(res.getString(R.string.info_log_type_changed)); + } + + if (cgBase.isEmpty(viewstates) && attempts < 2) { + showToast(res.getString(R.string.err_log_load_data_again)); + + loadData thread; + thread = new loadData(); + thread.start(); + + return; + } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { + showToast(res.getString(R.string.err_log_load_data)); + showProgress(false); + + return; + } + + gettingViewstate = false; // we're done, user can post log + + if (post == null) { + post = (Button) findViewById(R.id.post); + } + post.setEnabled(true); + post.setOnClickListener(new postListener()); + + // add trackables + if (CollectionUtils.isNotEmpty(trackables)) { + if (inflater == null) { + inflater = getLayoutInflater(); + } + + final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory); + inventoryView.removeAllViews(); + + for (cgTrackableLog tb : trackables) { + LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null); + + ((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode); + ((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name); + ((TextView) inventoryItem.findViewById(R.id.action)).setText(cgBase.logTypesTrackable.get(settings.trackableAutovisit ? 1 : 0)); + + inventoryItem.setId(tb.id); + final String tbCode = tb.trackCode; + inventoryItem.setClickable(true); + registerForContextMenu(inventoryItem); + inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() { + + public void onClick(View view) { + final Intent trackablesIntent = new Intent(cgeovisit.this, cgeotrackable.class); + trackablesIntent.putExtra(EXTRAS_GEOCODE, tbCode); + startActivity(trackablesIntent); + } + }); + inventoryItem.findViewById(R.id.action).setOnClickListener(new View.OnClickListener() { + + public void onClick(View view) { + openContextMenu(view); + } + }); + + inventoryView.addView(inventoryItem); + + if (settings.trackableAutovisit) { - tb.action = 1; - tbChanged = true; + tb.action = 1; + tbChanged = true; + } + } + + if (inventoryView.getChildCount() > 0) { + ((LinearLayout) findViewById(R.id.inventory_box)).setVisibility(View.VISIBLE); + } + if (inventoryView.getChildCount() > 1) { + final LinearLayout inventoryChangeAllView = (LinearLayout) findViewById(R.id.inventory_changeall); + + Button changeButton = (Button) inventoryChangeAllView.findViewById(R.id.changebutton); + registerForContextMenu(changeButton); + changeButton.setOnClickListener(new View.OnClickListener() { + + public void onClick(View view) { + openContextMenu(view); + } + }); + + ((LinearLayout) findViewById(R.id.inventory_changeall)).setVisibility(View.VISIBLE); + } + } + + showProgress(false); + } + }; + + private Handler postLogHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (msg.what == 1) { + showToast(res.getString(R.string.info_log_posted)); + + if (waitDialog != null) { + waitDialog.dismiss(); + } + + finish(); + return; + } else if (msg.what == 2) { + showToast(res.getString(R.string.info_log_saved)); + + if (waitDialog != null) { + waitDialog.dismiss(); + } + + finish(); + return; + } else if (msg.what >= 1000) { + if (msg.what == 1001) { + showToast(res.getString(R.string.warn_log_text_fill)); + } else if (msg.what == 1002) { + showToast(res.getString(R.string.err_log_failed_server)); + } else { + showToast(res.getString(R.string.err_log_post_failed)); + } + } else { + if (cgBase.errorRetrieve.get(msg.what) != null) { + showToast(res.getString(R.string.err_log_post_failed_because) + " " + cgBase.errorRetrieve.get(msg.what) + "."); + } else { + showToast(res.getString(R.string.err_log_post_failed)); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } + }; + + public cgeovisit() { + super("c:geo-log"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.visit); + setTitle(res.getString(R.string.log_new_log)); + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + cacheid = extras.getString(EXTRAS_ID); + geocode = extras.getString(EXTRAS_GEOCODE); + text = extras.getString(EXTRAS_TEXT); + alreadyFound = extras.getBoolean(EXTRAS_FOUND); + } + + if ((StringUtils.isBlank(cacheid)) && StringUtils.isNotBlank(geocode)) { + cacheid = app.getCacheid(geocode); + } + if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(cacheid)) { + geocode = app.getGeocode(cacheid); + } + + cache = app.getCacheByGeocode(geocode); + + if (StringUtils.isNotBlank(cache.name)) { + setTitle(res.getString(R.string.log_new_log) + " " + cache.name); + } else { + setTitle(res.getString(R.string.log_new_log) + " " + cache.geocode.toUpperCase()); + } + + app.setAction(geocode); + + if (cache == null) { + showToast(res.getString(R.string.err_detail_cache_forgot_visit)); + + finish(); + return; + } + + init(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + SubMenu menuLog = null; + + menuLog = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add); + for (LogTemplate template : LogTemplateProvider.getTemplates()) { + menuLog.add(0, template.getItemId(), 0, template.getResourceId()); + } + menuLog.add(0, MENU_SIGNATURE, 0, res.getString(R.string.init_signature)); + + SubMenu menuStars = menu.addSubMenu(0, SUBMENU_VOTE, 0, res.getString(R.string.log_rating)).setIcon(android.R.drawable.ic_menu_sort_by_size); + menuStars.add(0, 10, 0, res.getString(R.string.log_no_rating)); + menuStars.add(0, 19, 0, res.getString(R.string.log_stars_5) + " (" + res.getString(R.string.log_stars_5_description) + ")"); + menuStars.add(0, 18, 0, res.getString(R.string.log_stars_45) + " (" + res.getString(R.string.log_stars_45_description) + ")"); + menuStars.add(0, 17, 0, res.getString(R.string.log_stars_4) + " (" + res.getString(R.string.log_stars_4_description) + ")"); + menuStars.add(0, 16, 0, res.getString(R.string.log_stars_35) + " (" + res.getString(R.string.log_stars_35_description) + ")"); + menuStars.add(0, 15, 0, res.getString(R.string.log_stars_3) + " (" + res.getString(R.string.log_stars_3_description) + ")"); + menuStars.add(0, 14, 0, res.getString(R.string.log_stars_25) + " (" + res.getString(R.string.log_stars_25_description) + ")"); + menuStars.add(0, 13, 0, res.getString(R.string.log_stars_2) + " (" + res.getString(R.string.log_stars_2_description) + ")"); + menuStars.add(0, 12, 0, res.getString(R.string.log_stars_15) + " (" + res.getString(R.string.log_stars_15_description) + ")"); + menuStars.add(0, 11, 0, res.getString(R.string.log_stars_1) + " (" + res.getString(R.string.log_stars_1_description) + ")"); + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + boolean signatureAvailable = settings.getSignature() != null; + menu.findItem(MENU_SIGNATURE).setVisible(signatureAvailable); + + boolean voteAvailable = settings.isGCvoteLogin() && typeSelected == cgBase.LOG_FOUND_IT && StringUtils.isNotBlank(cache.guid); + menu.findItem(SUBMENU_VOTE).setVisible(voteAvailable); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id == MENU_SIGNATURE) { + EditText log = (EditText) findViewById(R.id.log); + String content = log.getText().toString(); + if (StringUtils.isNotBlank(content)) { + insertIntoLog("\n"); + } + insertIntoLog(LogTemplateProvider.applyTemplates(settings.getSignature(), base, false)); + return true; + } else if (id >= 10 && id <= 19) { + rating = (id - 9) / 2.0; + + if (post == null) { + post = (Button) findViewById(R.id.post); + } + if (rating == 0.0) { + post.setText(res.getString(R.string.log_post_no_rate)); + } else { + post.setText(res.getString(R.string.log_post_rate) + " " + ratingTextValue(rating) + "*"); + } + return true; + } + LogTemplate template = LogTemplateProvider.getTemplate(id); + if (template != null) { + String newText = template.getValue(base, false); + insertIntoLog(newText); + return true; + } + return false; + } + + private void insertIntoLog(String newText) { + EditText log = (EditText) findViewById(R.id.log); + cgBase.insertAtPosition(log, newText, true); + } + + private static String ratingTextValue(final double rating) { + return String.format(Locale.getDefault(), "%.1f", rating); + } + + public boolean setRating(String guid, double vote) { + if (StringUtils.isBlank(guid)) { + return false; + } + if (vote < 0.0 || vote > 5.0) { + return false; + } + + final Map<String, String> login = settings.getGCvoteLogin(); + if (login == null) { + return false; + } + + final Map<String, String> params = new HashMap<String, String>(); + params.put("userName", login.get("username")); + params.put("password", login.get("password")); + params.put("cacheId", guid); + params.put("voteUser", String.format("%.1f", rating).replace(',', '.')); + params.put("version", "cgeo"); + + final String result = base.request(false, "gcvote.com", "/setVote.php", "GET", params, false, false, false).getData(); + + return result.trim().equalsIgnoreCase("ok"); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + super.onCreateContextMenu(menu, view, info); + final int viewId = view.getId(); + + if (viewId == R.id.type) { + for (final int typeOne : types) { + menu.add(viewId, typeOne, 0, cgBase.logTypes2.get(typeOne)); + Log.w(cgSettings.tag, "Adding " + typeOne + " " + cgBase.logTypes2.get(typeOne)); + } + } else if (viewId == R.id.changebutton) { + final int textId = ((TextView) findViewById(viewId)).getId(); + + menu.setHeaderTitle(res.getString(R.string.log_tb_changeall)); + for (final int logTbAction : cgBase.logTypesTrackable.keySet()) { + menu.add(textId, logTbAction, 0, cgBase.logTypesTrackable.get(logTbAction)); + } + } else { + final int realViewId = ((LinearLayout) findViewById(viewId)).getId(); + + for (final cgTrackableLog tb : trackables) { + if (tb.id == realViewId) { + menu.setHeaderTitle(tb.name); + } + } + for (final int logTbAction : cgBase.logTypesTrackable.keySet()) { + menu.add(realViewId, logTbAction, 0, cgBase.logTypesTrackable.get(logTbAction)); + } + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + final int group = item.getGroupId(); + final int id = item.getItemId(); + + if (group == R.id.type) { + setType(id); + + return true; + } else if (group == R.id.changebutton) { + try { + final String logTbAction = cgBase.logTypesTrackable.get(id); + if (logTbAction != null) { + final LinearLayout inventView = (LinearLayout) findViewById(R.id.inventory); + for (int count = 0; count < inventView.getChildCount(); count++) { + final LinearLayout tbView = (LinearLayout) inventView.getChildAt(count); + if (tbView == null) { + return false; + } + + final TextView tbText = (TextView) tbView.findViewById(R.id.action); + if (tbText == null) { + return false; + } + tbText.setText(logTbAction); + } + for (cgTrackableLog tb : trackables) { + tb.action = id; + } + tbChanged = true; + return true; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeovisit.onContextItemSelected: " + e.toString()); + } + } else { + try { + final String logTbAction = cgBase.logTypesTrackable.get(id); + if (logTbAction != null) { + final LinearLayout tbView = (LinearLayout) findViewById(group); + if (tbView == null) { + return false; + } + + final TextView tbText = (TextView) tbView.findViewById(R.id.action); + if (tbText == null) { + return false; + } + + for (cgTrackableLog tb : trackables) { + if (tb.id == group) { + tbChanged = true; + + tb.action = id; + tbText.setText(logTbAction); + + Log.i(cgSettings.tag, "Trackable " + tb.trackCode + " (" + tb.name + ") has new action: #" + id); + } + } + + return true; + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeovisit.onContextItemSelected: " + e.toString()); + } + } + + return false; + } + + public void init() { + if (geocode != null) { + app.setAction(geocode); + } + + types = cache.getPossibleLogTypes(settings); + + final cgLog log = app.loadLogOffline(geocode); + if (log != null) { + typeSelected = log.type; + date.setTime(new Date(log.date)); + text = log.log; + if (typeSelected == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { + if (post == null) { + post = (Button) findViewById(R.id.post); + } + post.setText(res.getString(R.string.log_post_no_rate)); + } + } else if (StringUtils.isNotBlank(settings.getSignature()) + && settings.signatureAutoinsert + && StringUtils.isBlank(((EditText) findViewById(R.id.log)).getText())) { + insertIntoLog(LogTemplateProvider.applyTemplates(settings.getSignature(), base, false)); + } + + if (types.contains(typeSelected) == false) { + if (alreadyFound) { + typeSelected = cgBase.LOG_NOTE; + } else { + typeSelected = types.get(0); + } + setType(typeSelected); + } + + Button typeButton = (Button) findViewById(R.id.type); + registerForContextMenu(typeButton); + typeButton.setText(cgBase.logTypes2.get(typeSelected)); + typeButton.setOnClickListener(new View.OnClickListener() { + + public void onClick(View view) { + openContextMenu(view); + } + }); + + Button dateButton = (Button) findViewById(R.id.date); + dateButton.setText(base.formatShortDate(date.getTime().getTime())); + dateButton.setOnClickListener(new cgeovisitDateListener()); + + EditText logView = (EditText) findViewById(R.id.log); + if (StringUtils.isBlank(logView.getText()) && StringUtils.isNotBlank(text)) { + logView.setText(text); + } + + if (tweetBox == null) { + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + } + if (tweetCheck == null) { + tweetCheck = (CheckBox) findViewById(R.id.tweet); + } + tweetCheck.setChecked(true); + + if (post == null) { + post = (Button) findViewById(R.id.post); + } + if (cgBase.isEmpty(viewstates)) { + post.setEnabled(false); + post.setOnTouchListener(null); + post.setOnClickListener(null); + + loadData thread; + thread = new loadData(); + thread.start(); + } else { + post.setEnabled(true); + post.setOnClickListener(new postListener()); + } + + if (save == null) { + save = (Button) findViewById(R.id.save); + } + save.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + String log = ((EditText) findViewById(R.id.log)).getText().toString(); + cache.logOffline(cgeovisit.this, log, date, typeSelected); + } + }); + + if (clear == null) { + clear = (Button) findViewById(R.id.clear); + } + clear.setOnClickListener(new clearListener()); + } + + public void setDate(Calendar dateIn) { + date = dateIn; + + final Button dateButton = (Button) findViewById(R.id.date); + dateButton.setText(base.formatShortDate(date.getTime().getTime())); + } + + public void setType(int type) { + final Button typeButton = (Button) findViewById(R.id.type); + + if (cgBase.logTypes2.get(type) != null) { + typeSelected = type; + } + if (cgBase.logTypes2.get(typeSelected) == null) { + typeSelected = 1; + } + typeButton.setText(cgBase.logTypes2.get(typeSelected)); + + if (tweetBox == null) { + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + } + + if (type == 2 && tbChanged == false) { + // TODO: change action + } else if (type != 2 && tbChanged == false) { + // TODO: change action + } + + if (type == cgBase.LOG_FOUND_IT && settings.twitter == 1) { + tweetBox.setVisibility(View.VISIBLE); + } else { + tweetBox.setVisibility(View.GONE); + } + + if (post == null) { + post = (Button) findViewById(R.id.post); + } + + if (type == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { + if (rating == 0) { + post.setText(res.getString(R.string.log_post_no_rate)); + } else { + post.setText(res.getString(R.string.log_post_rate) + " " + ratingTextValue(rating) + "*"); + } + } else { + post.setText(res.getString(R.string.log_post)); + } + } + + private class cgeovisitDateListener implements View.OnClickListener { + + public void onClick(View arg0) { + Dialog dateDialog = new cgeodate(cgeovisit.this, cgeovisit.this, date); + dateDialog.setCancelable(true); + dateDialog.show(); + } + } + + private class postListener implements View.OnClickListener { + + public void onClick(View arg0) { + if (gettingViewstate == false) { + waitDialog = ProgressDialog.show(cgeovisit.this, null, res.getString(R.string.log_saving), true); + waitDialog.setCancelable(true); + + String log = ((EditText) findViewById(R.id.log)).getText().toString(); + Thread thread = new postLog(postLogHandler, log); + thread.start(); + } else { + showToast(res.getString(R.string.err_log_load_data_still)); + } + } + } + + private class clearListener implements View.OnClickListener { + + public void onClick(View arg0) { + app.clearLogOffline(geocode); + + if (alreadyFound) { + typeSelected = cgBase.LOG_NOTE; + } else { + typeSelected = types.get(0); + } + date.setTime(new Date()); + text = null; + + setType(typeSelected); + + Button dateButton = (Button) findViewById(R.id.date); + dateButton.setText(base.formatShortDate(date.getTime().getTime())); + dateButton.setOnClickListener(new cgeovisitDateListener()); + + EditText logView = (EditText) findViewById(R.id.log); + if (StringUtils.isNotBlank(text)) { + logView.setText(text); + } else { + logView.setText(""); + } + + if (clear == null) { + clear = (Button) findViewById(R.id.clear); + } + clear.setOnClickListener(new clearListener()); + + showToast(res.getString(R.string.info_log_cleared)); + } + } + + private class loadData extends Thread { + + public loadData() { + if (cacheid == null) { + showToast(res.getString(R.string.err_detail_cache_forgot_visit)); + + finish(); + return; + } + } + + @Override + public void run() { + final Map<String, String> params = new HashMap<String, String>(); + + showProgressHandler.sendEmptyMessage(0); + gettingViewstate = true; + attempts++; + + try { + if (StringUtils.isNotBlank(cacheid)) { + params.put("ID", cacheid); + } else { + loadDataHandler.sendEmptyMessage(0); + return; + } + + final String page = base.request(false, "www.geocaching.com", "/seek/log.aspx", "GET", params, false, false, false).getData(); + + viewstates = cgBase.getViewstates(page); + trackables = cgBase.parseTrackableLog(page); + + final List<Integer> typesPre = cgBase.parseTypes(page); + if (CollectionUtils.isNotEmpty(typesPre)) { + types.clear(); + types.addAll(typesPre); + types.remove(Integer.valueOf(cgBase.LOG_UPDATE_COORDINATES)); + } + typesPre.clear(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeovisit.loadData.run: " + e.toString()); + } + + loadDataHandler.sendEmptyMessage(0); + } + } + + private class postLog extends Thread { + + Handler handler = null; + String log = null; + + public postLog(Handler handlerIn, String logIn) { + handler = handlerIn; + log = logIn; + } + + @Override + public void run() { + int ret = -1; + + ret = postLogFn(log); + + handler.sendEmptyMessage(ret); + } + } + + public int postLogFn(String log) { + int status = -1; + + try { + if (tweetBox == null) { + tweetBox = (LinearLayout) findViewById(R.id.tweet_box); + } + if (tweetCheck == null) { + tweetCheck = (CheckBox) findViewById(R.id.tweet); + } + + status = base.postLog(app, geocode, cacheid, viewstates, typeSelected, + date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), + log, trackables); + + if (status == 1) { + cgLog logNow = new cgLog(); + logNow.author = settings.getUsername(); + logNow.date = date.getTimeInMillis(); + logNow.type = typeSelected; + logNow.log = log; + + if (cache != null && null != cache.logs) { + cache.logs.add(0, logNow); + } + app.addLog(geocode, logNow); + + if (typeSelected == cgBase.LOG_FOUND_IT) { + app.markFound(geocode); + if (cache != null) { + cache.found = true; } - } - - if (inventoryView.getChildCount() > 0) { - ((LinearLayout) findViewById(R.id.inventory_box)).setVisibility(View.VISIBLE); - } - if (inventoryView.getChildCount() > 1) { - final LinearLayout inventoryChangeAllView = (LinearLayout) findViewById(R.id.inventory_changeall); - - Button changeButton = (Button) inventoryChangeAllView.findViewById(R.id.changebutton); - registerForContextMenu(changeButton); - changeButton.setOnClickListener(new View.OnClickListener() { - - public void onClick(View view) { - openContextMenu(view); - } - }); - - ((LinearLayout) findViewById(R.id.inventory_changeall)).setVisibility(View.VISIBLE); - } - } - - showProgress(false); - } - }; - - private Handler postLogHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (msg.what == 1) { - showToast(res.getString(R.string.info_log_posted)); - - if (waitDialog != null) { - waitDialog.dismiss(); - } - - finish(); - return; - } else if (msg.what == 2) { - showToast(res.getString(R.string.info_log_saved)); - - if (waitDialog != null) { - waitDialog.dismiss(); - } - - finish(); - return; - } else if (msg.what >= 1000) { - if (msg.what == 1001) { - showToast(res.getString(R.string.warn_log_text_fill)); - } else if (msg.what == 1002) { - showToast(res.getString(R.string.err_log_failed_server)); - } else { - showToast(res.getString(R.string.err_log_post_failed)); - } - } else { - if (cgBase.errorRetrieve.get(msg.what) != null) { - showToast(res.getString(R.string.err_log_post_failed_because) + " " + cgBase.errorRetrieve.get(msg.what) + "."); - } else { - showToast(res.getString(R.string.err_log_post_failed)); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } - }; - - public cgeovisit() { - super("c:geo-log"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.visit); - setTitle(res.getString(R.string.log_new_log)); - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - cacheid = extras.getString(EXTRAS_ID); - geocode = extras.getString(EXTRAS_GEOCODE); - text = extras.getString(EXTRAS_TEXT); - alreadyFound = extras.getBoolean(EXTRAS_FOUND); - } - - if ((StringUtils.isBlank(cacheid)) && StringUtils.isNotBlank(geocode)) { - cacheid = app.getCacheid(geocode); - } - if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(cacheid)) { - geocode = app.getGeocode(cacheid); - } - - cache = app.getCacheByGeocode(geocode); - - if (StringUtils.isNotBlank(cache.name)) { - setTitle(res.getString(R.string.log_new_log) + " " + cache.name); - } else { - setTitle(res.getString(R.string.log_new_log) + " " + cache.geocode.toUpperCase()); - } - - app.setAction(geocode); - - if (cache == null) { - showToast(res.getString(R.string.err_detail_cache_forgot_visit)); - - finish(); - return; - } - - init(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - SubMenu menuLog = null; - - menuLog = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add); - for (LogTemplate template : LogTemplateProvider.getTemplates()) { - menuLog.add(0, template.getItemId(), 0, template.getResourceId()); - } - menuLog.add(0, MENU_SIGNATURE, 0, res.getString(R.string.init_signature)); - - SubMenu menuStars = menu.addSubMenu(0, SUBMENU_VOTE, 0, res.getString(R.string.log_rating)).setIcon(android.R.drawable.ic_menu_sort_by_size); - menuStars.add(0, 10, 0, res.getString(R.string.log_no_rating)); - menuStars.add(0, 19, 0, res.getString(R.string.log_stars_5) + " (" + res.getString(R.string.log_stars_5_description) + ")"); - menuStars.add(0, 18, 0, res.getString(R.string.log_stars_45) + " (" + res.getString(R.string.log_stars_45_description) + ")"); - menuStars.add(0, 17, 0, res.getString(R.string.log_stars_4) + " (" + res.getString(R.string.log_stars_4_description) + ")"); - menuStars.add(0, 16, 0, res.getString(R.string.log_stars_35) + " (" + res.getString(R.string.log_stars_35_description) + ")"); - menuStars.add(0, 15, 0, res.getString(R.string.log_stars_3) + " (" + res.getString(R.string.log_stars_3_description) + ")"); - menuStars.add(0, 14, 0, res.getString(R.string.log_stars_25) + " (" + res.getString(R.string.log_stars_25_description) + ")"); - menuStars.add(0, 13, 0, res.getString(R.string.log_stars_2) + " (" + res.getString(R.string.log_stars_2_description) + ")"); - menuStars.add(0, 12, 0, res.getString(R.string.log_stars_15) + " (" + res.getString(R.string.log_stars_15_description) + ")"); - menuStars.add(0, 11, 0, res.getString(R.string.log_stars_1) + " (" + res.getString(R.string.log_stars_1_description) + ")"); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - boolean signatureAvailable = settings.getSignature() != null; - menu.findItem(MENU_SIGNATURE).setVisible(signatureAvailable); - - boolean voteAvailable = settings.isGCvoteLogin() && typeSelected == cgBase.LOG_FOUND_IT && StringUtils.isNotBlank(cache.guid); - menu.findItem(SUBMENU_VOTE).setVisible(voteAvailable); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - - if (id == MENU_SIGNATURE) { - EditText log = (EditText) findViewById(R.id.log); - String content = log.getText().toString(); - if (StringUtils.isNotBlank(content)) { - insertIntoLog("\n"); - } - insertIntoLog(LogTemplateProvider.applyTemplates(settings.getSignature(), base, false)); - return true; - } else if (id >= 10 && id <= 19) { - rating = (id - 9) / 2.0; - - if (post == null) { - post = (Button) findViewById(R.id.post); - } - if (rating == 0.0) { - post.setText(res.getString(R.string.log_post_no_rate)); - } else { - post.setText(res.getString(R.string.log_post_rate) + " " + ratingTextValue(rating) + "*"); - } - return true; - } - LogTemplate template = LogTemplateProvider.getTemplate(id); - if (template != null) { - String newText = template.getValue(base, false); - insertIntoLog(newText); - return true; - } - return false; - } - - private void insertIntoLog(String newText) { - EditText log = (EditText) findViewById(R.id.log); - cgBase.insertAtPosition(log, newText, true); - } - - private static String ratingTextValue(final double rating) { - return String.format(Locale.getDefault(), "%.1f", rating); - } - - public boolean setRating(String guid, double vote) { - if (StringUtils.isBlank(guid)) { - return false; - } - if (vote < 0.0 || vote > 5.0) { - return false; - } - - final Map<String, String> login = settings.getGCvoteLogin(); - if (login == null) { - return false; - } - - final Map<String, String> params = new HashMap<String, String>(); - params.put("userName", login.get("username")); - params.put("password", login.get("password")); - params.put("cacheId", guid); - params.put("voteUser", String.format("%.1f", rating).replace(',', '.')); - params.put("version", "cgeo"); - - final String result = base.request(false, "gcvote.com", "/setVote.php", "GET", params, false, false, false).getData(); - - return result.trim().equalsIgnoreCase("ok"); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - - if (viewId == R.id.type) { - for (final int typeOne : types) { - menu.add(viewId, typeOne, 0, cgBase.logTypes2.get(typeOne)); - Log.w(cgSettings.tag, "Adding " + typeOne + " " + cgBase.logTypes2.get(typeOne)); - } - } else if (viewId == R.id.changebutton) { - final int textId = ((TextView) findViewById(viewId)).getId(); - - menu.setHeaderTitle(res.getString(R.string.log_tb_changeall)); - for (final int logTbAction : cgBase.logTypesTrackable.keySet()) { - menu.add(textId, logTbAction, 0, cgBase.logTypesTrackable.get(logTbAction)); - } - } else { - final int realViewId = ((LinearLayout) findViewById(viewId)).getId(); - - for (final cgTrackableLog tb : trackables) { - if (tb.id == realViewId) { - menu.setHeaderTitle(tb.name); - } - } - for (final int logTbAction : cgBase.logTypesTrackable.keySet()) { - menu.add(realViewId, logTbAction, 0, cgBase.logTypesTrackable.get(logTbAction)); - } - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - final int group = item.getGroupId(); - final int id = item.getItemId(); - - if (group == R.id.type) { - setType(id); - - return true; - } else if (group == R.id.changebutton) { - try { - final String logTbAction = cgBase.logTypesTrackable.get(id); - if (logTbAction != null) { - final LinearLayout inventView = (LinearLayout) findViewById(R.id.inventory); - for (int count = 0; count < inventView.getChildCount(); count++) { - final LinearLayout tbView = (LinearLayout) inventView.getChildAt(count); - if (tbView == null) { - return false; - } - - final TextView tbText = (TextView) tbView.findViewById(R.id.action); - if (tbText == null) { - return false; - } - tbText.setText(logTbAction); - } - for (cgTrackableLog tb : trackables) { - tb.action = id; - } - tbChanged = true; - return true; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeovisit.onContextItemSelected: " + e.toString()); - } - } else { - try { - final String logTbAction = cgBase.logTypesTrackable.get(id); - if (logTbAction != null) { - final LinearLayout tbView = (LinearLayout) findViewById(group); - if (tbView == null) { - return false; - } - - final TextView tbText = (TextView) tbView.findViewById(R.id.action); - if (tbText == null) { - return false; - } - - for (cgTrackableLog tb : trackables) { - if (tb.id == group) { - tbChanged = true; - - tb.action = id; - tbText.setText(logTbAction); - - Log.i(cgSettings.tag, "Trackable " + tb.trackCode + " (" + tb.name + ") has new action: #" + id); - } - } - - return true; - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeovisit.onContextItemSelected: " + e.toString()); - } - } - - return false; - } - - public void init() { - if (geocode != null) { - app.setAction(geocode); - } - - types = cache.getPossibleLogTypes(settings); - - final cgLog log = app.loadLogOffline(geocode); - if (log != null) { - typeSelected = log.type; - date.setTime(new Date(log.date)); - text = log.log; - if (typeSelected == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { - if (post == null) { - post = (Button) findViewById(R.id.post); - } - post.setText(res.getString(R.string.log_post_no_rate)); - } - } else if (StringUtils.isNotBlank(settings.getSignature()) - && settings.signatureAutoinsert - && StringUtils.isBlank(((EditText) findViewById(R.id.log)).getText())) { - insertIntoLog(LogTemplateProvider.applyTemplates(settings.getSignature(), base, false)); - } - - if (types.contains(typeSelected) == false) { - if (alreadyFound) { - typeSelected = cgBase.LOG_NOTE; - } else { - typeSelected = types.get(0); - } - setType(typeSelected); - } - - Button typeButton = (Button) findViewById(R.id.type); - registerForContextMenu(typeButton); - typeButton.setText(cgBase.logTypes2.get(typeSelected)); - typeButton.setOnClickListener(new View.OnClickListener() { - - public void onClick(View view) { - openContextMenu(view); - } - }); - - Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(base.formatShortDate(date.getTime().getTime())); - dateButton.setOnClickListener(new cgeovisitDateListener()); - - EditText logView = (EditText) findViewById(R.id.log); - if (StringUtils.isBlank(logView.getText()) && StringUtils.isNotBlank(text) ) { - logView.setText(text); - } - - - if (tweetBox == null) { - tweetBox = (LinearLayout) findViewById(R.id.tweet_box); - } - if (tweetCheck == null) { - tweetCheck = (CheckBox) findViewById(R.id.tweet); - } - tweetCheck.setChecked(true); - - if (post == null) { - post = (Button) findViewById(R.id.post); - } - if (cgBase.isEmpty(viewstates)) { - post.setEnabled(false); - post.setOnTouchListener(null); - post.setOnClickListener(null); - - loadData thread; - thread = new loadData(); - thread.start(); - } else { - post.setEnabled(true); - post.setOnClickListener(new postListener()); - } - - if (save == null) { - save = (Button) findViewById(R.id.save); - } - save.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - String log = ((EditText) findViewById(R.id.log)).getText().toString(); - cache.logOffline(cgeovisit.this, log, date, typeSelected); - } - }); - - if (clear == null) { - clear = (Button) findViewById(R.id.clear); - } - clear.setOnClickListener(new clearListener()); - } - - public void setDate(Calendar dateIn) { - date = dateIn; - - final Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(base.formatShortDate(date.getTime().getTime())); - } - - public void setType(int type) { - final Button typeButton = (Button) findViewById(R.id.type); - - if (cgBase.logTypes2.get(type) != null) { - typeSelected = type; - } - if (cgBase.logTypes2.get(typeSelected) == null) { - typeSelected = 1; - } - typeButton.setText(cgBase.logTypes2.get(typeSelected)); - - if (tweetBox == null) { - tweetBox = (LinearLayout) findViewById(R.id.tweet_box); - } - - if (type == 2 && tbChanged == false) { - // TODO: change action - } else if (type != 2 && tbChanged == false) { - // TODO: change action - } - - if (type == cgBase.LOG_FOUND_IT && settings.twitter == 1) { - tweetBox.setVisibility(View.VISIBLE); - } else { - tweetBox.setVisibility(View.GONE); - } - - if (post == null) { - post = (Button) findViewById(R.id.post); - } - - if (type == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { - if (rating == 0) { - post.setText(res.getString(R.string.log_post_no_rate)); - } else { - post.setText(res.getString(R.string.log_post_rate) + " " + ratingTextValue(rating) + "*"); - } - } else { - post.setText(res.getString(R.string.log_post)); - } - } - - private class cgeovisitDateListener implements View.OnClickListener { - - public void onClick(View arg0) { - Dialog dateDialog = new cgeodate(cgeovisit.this, cgeovisit.this, date); - dateDialog.setCancelable(true); - dateDialog.show(); - } - } - - private class postListener implements View.OnClickListener { - - public void onClick(View arg0) { - if (gettingViewstate == false) { - waitDialog = ProgressDialog.show(cgeovisit.this, null, res.getString(R.string.log_saving), true); - waitDialog.setCancelable(true); - - String log = ((EditText) findViewById(R.id.log)).getText().toString(); - Thread thread = new postLog(postLogHandler, log); - thread.start(); - } else { - showToast(res.getString(R.string.err_log_load_data_still)); - } - } - } - - private class clearListener implements View.OnClickListener { - - public void onClick(View arg0) { - app.clearLogOffline(geocode); - - if (alreadyFound) { - typeSelected = cgBase.LOG_NOTE; - } else { - typeSelected = types.get(0); - } - date.setTime(new Date()); - text = null; - - setType(typeSelected); - - Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(base.formatShortDate(date.getTime().getTime())); - dateButton.setOnClickListener(new cgeovisitDateListener()); - - EditText logView = (EditText) findViewById(R.id.log); - if (StringUtils.isNotBlank(text)) { - logView.setText(text); - } else { - logView.setText(""); - } - - if (clear == null) { - clear = (Button) findViewById(R.id.clear); - } - clear.setOnClickListener(new clearListener()); - - showToast(res.getString(R.string.info_log_cleared)); - } - } - - private class loadData extends Thread { - - public loadData() { - if (cacheid == null) { - showToast(res.getString(R.string.err_detail_cache_forgot_visit)); - - finish(); - return; - } - } - - @Override - public void run() { - final Map<String, String> params = new HashMap<String, String>(); - - showProgressHandler.sendEmptyMessage(0); - gettingViewstate = true; - attempts++; - - try { - if (StringUtils.isNotBlank(cacheid)) { - params.put("ID", cacheid); - } else { - loadDataHandler.sendEmptyMessage(0); - return; - } - - final String page = base.request(false, "www.geocaching.com", "/seek/log.aspx", "GET", params, false, false, false).getData(); - - viewstates = cgBase.getViewstates(page); - trackables = cgBase.parseTrackableLog(page); - - final List<Integer> typesPre = cgBase.parseTypes(page); - if (CollectionUtils.isNotEmpty(typesPre)) { - types.clear(); - types.addAll(typesPre); - types.remove(Integer.valueOf(cgBase.LOG_UPDATE_COORDINATES)); - } - typesPre.clear(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeovisit.loadData.run: " + e.toString()); - } - - loadDataHandler.sendEmptyMessage(0); - } - } - - private class postLog extends Thread { - - Handler handler = null; - String log = null; - - public postLog(Handler handlerIn, String logIn) { - handler = handlerIn; - log = logIn; - } - - @Override - public void run() { - int ret = -1; - - ret = postLogFn(log); - - handler.sendEmptyMessage(ret); - } - } - - public int postLogFn(String log) { - int status = -1; - - try { - if (tweetBox == null) { - tweetBox = (LinearLayout) findViewById(R.id.tweet_box); - } - if (tweetCheck == null) { - tweetCheck = (CheckBox) findViewById(R.id.tweet); - } - - status = base.postLog(app, geocode, cacheid, viewstates, typeSelected, - date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), - log, trackables); - - if (status == 1) { - cgLog logNow = new cgLog(); - logNow.author = settings.getUsername(); - logNow.date = date.getTimeInMillis(); - logNow.type = typeSelected; - logNow.log = log; - - if (cache != null && null != cache.logs) { - cache.logs.add(0, logNow); - } - app.addLog(geocode, logNow); - - if (typeSelected == cgBase.LOG_FOUND_IT) { - app.markFound(geocode); - if (cache != null) { - cache.found = true; - } - } - - if (cache != null) { - app.putCacheInCache(cache); - } else { - app.removeCacheFromCache(geocode); - } - } - - if (status == 1) { - app.clearLogOffline(geocode); - } - - if ( - status == 1 && typeSelected == cgBase.LOG_FOUND_IT && settings.twitter == 1 - && StringUtils.isNotBlank(settings.tokenPublic) && StringUtils.isNotBlank(settings.tokenSecret) - && tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE - ) { - cgBase.postTweetCache(app, settings, geocode); - } - - if (status == 1 && typeSelected == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { - setRating(cache.guid, rating); - } - - return status; - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeovisit.postLogFn: " + e.toString()); - } - - return 1000; - } + } + + if (cache != null) { + app.putCacheInCache(cache); + } else { + app.removeCacheFromCache(geocode); + } + } + + if (status == 1) { + app.clearLogOffline(geocode); + } + + if (status == 1 && typeSelected == cgBase.LOG_FOUND_IT && settings.twitter == 1 + && StringUtils.isNotBlank(settings.tokenPublic) && StringUtils.isNotBlank(settings.tokenSecret) + && tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE) { + cgBase.postTweetCache(app, settings, geocode); + } + + if (status == 1 && typeSelected == cgBase.LOG_FOUND_IT && settings.isGCvoteLogin()) { + setRating(cache.guid, rating); + } + + return status; + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeovisit.postLogFn: " + e.toString()); + } + + return 1000; + } } diff --git a/src/cgeo/geocaching/cgeowaypoint.java b/src/cgeo/geocaching/cgeowaypoint.java index ffb6adc..e6dcb4f 100644 --- a/src/cgeo/geocaching/cgeowaypoint.java +++ b/src/cgeo/geocaching/cgeowaypoint.java @@ -1,5 +1,8 @@ package cgeo.geocaching; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; + import org.apache.commons.lang3.StringUtils; import android.app.ProgressDialog; @@ -18,330 +21,328 @@ import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; public class cgeowaypoint extends AbstractActivity { - private static final int MENU_ID_NAVIGATION = 0; - private static final int MENU_ID_CACHES_AROUND = 5; - private static final int MENU_ID_COMPASS = 2; - private cgWaypoint waypoint = null; - private String geocode = null; - private int id = -1; - private ProgressDialog waitDialog = null; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private Handler loadWaypointHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (waypoint == null) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - - showToast(res.getString(R.string.err_waypoint_load_failed)); - - finish(); - return; - } else { - final TextView identification = (TextView) findViewById(R.id.identification); - final TextView coords = (TextView) findViewById(R.id.coordinates); - final ImageView compass = (ImageView) findViewById(R.id.compass); - final View separator = (View) findViewById(R.id.separator); - - final View headline = (View) findViewById(R.id.headline); - registerNavigationMenu(headline); - - if (StringUtils.isNotBlank(waypoint.name)) { - setTitle(Html.fromHtml(waypoint.name.trim()).toString()); - } else { - setTitle(res.getString(R.string.waypoint_title)); - } - - if (waypoint.prefix.equalsIgnoreCase("OWN") == false) { - identification.setText(waypoint.prefix.trim() + "/" + waypoint.lookup.trim()); - } else { - identification.setText(res.getString(R.string.waypoint_custom)); - } - registerNavigationMenu(identification); - waypoint.setIcon(res, base, identification); - - if (waypoint.coords != null) { - coords.setText(Html.fromHtml(cgBase.formatCoords(waypoint.coords, true)), TextView.BufferType.SPANNABLE); - compass.setVisibility(View.VISIBLE); - separator.setVisibility(View.VISIBLE); - } else { - coords.setText(res.getString(R.string.waypoint_unknown_coordinates)); - compass.setVisibility(View.GONE); - separator.setVisibility(View.GONE); - } - registerNavigationMenu(coords); - - if (StringUtils.isNotBlank(waypoint.note)) { - final TextView note = (TextView) findViewById(R.id.note); - note.setText(Html.fromHtml(waypoint.note.trim()), TextView.BufferType.SPANNABLE); - registerNavigationMenu(note); - } - - Button buttonEdit = (Button) findViewById(R.id.edit); - buttonEdit.setOnClickListener(new editWaypointListener()); - - Button buttonDelete = (Button) findViewById(R.id.delete); - if (waypoint.isUserDefined()) { - buttonDelete.setOnClickListener(new deleteWaypointListener()); - buttonDelete.setVisibility(View.VISIBLE); - } - - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - Log.e(cgSettings.tag, "cgeowaypoint.loadWaypointHandler: " + e.toString()); - } - } - - private void registerNavigationMenu(View view) { - view.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - registerForContextMenu(v); - if (navigationPossible()) { - openContextMenu(v); - } - } - }); - } - }; - - public cgeowaypoint() { - super("c:geo-waypoint-details"); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.waypoint); - setTitle("waypoint"); - - // get parameters - Bundle extras = getIntent().getExtras(); - - // try to get data from extras - if (extras != null) { - id = extras.getInt("waypoint"); - geocode = extras.getString("geocode"); - } - - if (id <= 0) { - showToast(res.getString(R.string.err_waypoint_unknown)); - finish(); - return; - } - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); - waitDialog.setCancelable(true); - - (new loadWaypoint()).start(); - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - if (waitDialog == null) { - waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); - waitDialog.setCancelable(true); - - (new loadWaypoint()).start(); - } - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, MENU_ID_COMPASS, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass - - SubMenu subMenu = menu.addSubMenu(1, MENU_ID_NAVIGATION, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); - addNavigationMenuItems(subMenu); - - menu.add(0, MENU_ID_CACHES_AROUND, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around - - return true; - } - - private void addNavigationMenuItems(Menu menu) { - NavigationAppFactory.addMenuItems(menu, this, res); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - try { - boolean visible = waypoint != null && waypoint.coords != null; - menu.findItem(MENU_ID_NAVIGATION).setVisible(visible); - menu.findItem(MENU_ID_COMPASS).setVisible(visible); - menu.findItem(MENU_ID_CACHES_AROUND).setVisible(visible); - } catch (Exception e) { - // nothing - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int menuItem = item.getItemId(); - if (menuItem == MENU_ID_COMPASS) { - goCompass(null); - return true; - } else if (menuItem == MENU_ID_CACHES_AROUND) { - cachesAround(); - return true; - } - - return NavigationAppFactory.onMenuItemSelected(item, geo, this, res, null, null, waypoint, null); - } - - private void cachesAround() { - if (waypoint == null || waypoint.coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - } - - cgeocaches.startActivityCachesAround(this, waypoint.coords); - - finish(); - } - - private class loadWaypoint extends Thread { - - @Override - public void run() { - try { - waypoint = app.loadWaypoint(id); - - loadWaypointHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString()); - } - } - } - - private static class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - // nothing - } - } - - private class editWaypointListener implements View.OnClickListener { - - public void onClick(View arg0) { - Intent editIntent = new Intent(cgeowaypoint.this, cgeowaypointadd.class); - editIntent.putExtra("waypoint", id); - startActivity(editIntent); - } - } - - private class deleteWaypointListener implements View.OnClickListener { - - public void onClick(View arg0) { - if (app.deleteWaypoint(id) == false) { - showToast(res.getString(R.string.err_waypoint_delete_failed)); - } else { - app.removeCacheFromCache(geocode); - - finish(); - return; - } - } - } - - public void goCompass(View view) { - if (!navigationPossible()) { - return; - } - - Intent navigateIntent = new Intent(this, cgeonavigate.class); - navigateIntent.putExtra("latitude", waypoint.coords.getLatitude()); - navigateIntent.putExtra("longitude", waypoint.coords.getLongitude()); - navigateIntent.putExtra("geocode", waypoint.prefix.trim() + "/" + waypoint.lookup.trim()); - navigateIntent.putExtra("name", waypoint.name); - - cgeonavigate.coordinates.clear(); - cgeonavigate.coordinates.add(new cgCoord(waypoint)); - startActivity(navigateIntent); - } - - private boolean navigationPossible() { - if (waypoint == null || waypoint.coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - return false; - } - return true; - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - if (navigationPossible()) { - menu.setHeaderTitle(res.getString(R.string.cache_menu_navigate)); - addNavigationMenuItems(menu); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - return onOptionsItemSelected(item); - } + private static final int MENU_ID_NAVIGATION = 0; + private static final int MENU_ID_CACHES_AROUND = 5; + private static final int MENU_ID_COMPASS = 2; + private cgWaypoint waypoint = null; + private String geocode = null; + private int id = -1; + private ProgressDialog waitDialog = null; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private Handler loadWaypointHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (waypoint == null) { + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + + showToast(res.getString(R.string.err_waypoint_load_failed)); + + finish(); + return; + } else { + final TextView identification = (TextView) findViewById(R.id.identification); + final TextView coords = (TextView) findViewById(R.id.coordinates); + final ImageView compass = (ImageView) findViewById(R.id.compass); + final View separator = (View) findViewById(R.id.separator); + + final View headline = (View) findViewById(R.id.headline); + registerNavigationMenu(headline); + + if (StringUtils.isNotBlank(waypoint.name)) { + setTitle(Html.fromHtml(waypoint.name.trim()).toString()); + } else { + setTitle(res.getString(R.string.waypoint_title)); + } + + if (waypoint.prefix.equalsIgnoreCase("OWN") == false) { + identification.setText(waypoint.prefix.trim() + "/" + waypoint.lookup.trim()); + } else { + identification.setText(res.getString(R.string.waypoint_custom)); + } + registerNavigationMenu(identification); + waypoint.setIcon(res, base, identification); + + if (waypoint.coords != null) { + coords.setText(Html.fromHtml(cgBase.formatCoords(waypoint.coords, true)), TextView.BufferType.SPANNABLE); + compass.setVisibility(View.VISIBLE); + separator.setVisibility(View.VISIBLE); + } else { + coords.setText(res.getString(R.string.waypoint_unknown_coordinates)); + compass.setVisibility(View.GONE); + separator.setVisibility(View.GONE); + } + registerNavigationMenu(coords); + + if (StringUtils.isNotBlank(waypoint.note)) { + final TextView note = (TextView) findViewById(R.id.note); + note.setText(Html.fromHtml(waypoint.note.trim()), TextView.BufferType.SPANNABLE); + registerNavigationMenu(note); + } + + Button buttonEdit = (Button) findViewById(R.id.edit); + buttonEdit.setOnClickListener(new editWaypointListener()); + + Button buttonDelete = (Button) findViewById(R.id.delete); + if (waypoint.isUserDefined()) { + buttonDelete.setOnClickListener(new deleteWaypointListener()); + buttonDelete.setVisibility(View.VISIBLE); + } + + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + Log.e(cgSettings.tag, "cgeowaypoint.loadWaypointHandler: " + e.toString()); + } + } + + private void registerNavigationMenu(View view) { + view.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + registerForContextMenu(v); + if (navigationPossible()) { + openContextMenu(v); + } + } + }); + } + }; + + public cgeowaypoint() { + super("c:geo-waypoint-details"); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.waypoint); + setTitle("waypoint"); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + if (extras != null) { + id = extras.getInt("waypoint"); + geocode = extras.getString("geocode"); + } + + if (id <= 0) { + showToast(res.getString(R.string.err_waypoint_unknown)); + finish(); + return; + } + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); + waitDialog.setCancelable(true); + + (new loadWaypoint()).start(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + if (waitDialog == null) { + waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); + waitDialog.setCancelable(true); + + (new loadWaypoint()).start(); + } + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, MENU_ID_COMPASS, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass + + SubMenu subMenu = menu.addSubMenu(1, MENU_ID_NAVIGATION, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more); + addNavigationMenuItems(subMenu); + + menu.add(0, MENU_ID_CACHES_AROUND, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around + + return true; + } + + private void addNavigationMenuItems(Menu menu) { + NavigationAppFactory.addMenuItems(menu, this, res); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + try { + boolean visible = waypoint != null && waypoint.coords != null; + menu.findItem(MENU_ID_NAVIGATION).setVisible(visible); + menu.findItem(MENU_ID_COMPASS).setVisible(visible); + menu.findItem(MENU_ID_CACHES_AROUND).setVisible(visible); + } catch (Exception e) { + // nothing + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int menuItem = item.getItemId(); + if (menuItem == MENU_ID_COMPASS) { + goCompass(null); + return true; + } else if (menuItem == MENU_ID_CACHES_AROUND) { + cachesAround(); + return true; + } + + return NavigationAppFactory.onMenuItemSelected(item, geo, this, res, null, null, waypoint, null); + } + + private void cachesAround() { + if (waypoint == null || waypoint.coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + } + + cgeocaches.startActivityCachesAround(this, waypoint.coords); + + finish(); + } + + private class loadWaypoint extends Thread { + + @Override + public void run() { + try { + waypoint = app.loadWaypoint(id); + + loadWaypointHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString()); + } + } + } + + private static class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + // nothing + } + } + + private class editWaypointListener implements View.OnClickListener { + + public void onClick(View arg0) { + Intent editIntent = new Intent(cgeowaypoint.this, cgeowaypointadd.class); + editIntent.putExtra("waypoint", id); + startActivity(editIntent); + } + } + + private class deleteWaypointListener implements View.OnClickListener { + + public void onClick(View arg0) { + if (app.deleteWaypoint(id) == false) { + showToast(res.getString(R.string.err_waypoint_delete_failed)); + } else { + app.removeCacheFromCache(geocode); + + finish(); + return; + } + } + } + + public void goCompass(View view) { + if (!navigationPossible()) { + return; + } + + Intent navigateIntent = new Intent(this, cgeonavigate.class); + navigateIntent.putExtra("latitude", waypoint.coords.getLatitude()); + navigateIntent.putExtra("longitude", waypoint.coords.getLongitude()); + navigateIntent.putExtra("geocode", waypoint.prefix.trim() + "/" + waypoint.lookup.trim()); + navigateIntent.putExtra("name", waypoint.name); + + cgeonavigate.coordinates.clear(); + cgeonavigate.coordinates.add(new cgCoord(waypoint)); + startActivity(navigateIntent); + } + + private boolean navigationPossible() { + if (waypoint == null || waypoint.coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + return false; + } + return true; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + if (navigationPossible()) { + menu.setHeaderTitle(res.getString(R.string.cache_menu_navigate)); + addNavigationMenuItems(menu); + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + return onOptionsItemSelected(item); + } } diff --git a/src/cgeo/geocaching/cgeowaypointadd.java b/src/cgeo/geocaching/cgeowaypointadd.java index e2ebbb6..f4d1ba7 100644 --- a/src/cgeo/geocaching/cgeowaypointadd.java +++ b/src/cgeo/geocaching/cgeowaypointadd.java @@ -1,8 +1,10 @@ package cgeo.geocaching; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.geopoint.DistanceParser; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.GeopointFormatter; import org.apache.commons.lang3.StringUtils; @@ -17,351 +19,349 @@ import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.geopoint.DistanceParser; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.GeopointFormatter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class cgeowaypointadd extends AbstractActivity { - private String geocode = null; - private int id = -1; - private cgGeo geo = null; - private cgUpdateLoc geoUpdate = new update(); - private ProgressDialog waitDialog = null; - private cgWaypoint waypoint = null; - private String type = "own"; - private String prefix = "OWN"; - private String lookup = "---"; - /** - * number of waypoints that the corresponding cache has until now - */ - private int wpCount = 0; - private Handler loadWaypointHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (waypoint == null) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - - id = -1; - } else { - geocode = waypoint.geocode; - type = waypoint.type; - prefix = waypoint.prefix; - lookup = waypoint.lookup; - - app.setAction(geocode); - - ((Button) findViewById(R.id.buttonLatitude)).setText(cgBase.formatLatitude(waypoint.coords.getLatitude(), true)); - ((Button) findViewById(R.id.buttonLongitude)).setText(cgBase.formatLongitude(waypoint.coords.getLongitude(), true)); - ((EditText) findViewById(R.id.name)).setText(Html.fromHtml(waypoint.name.trim()).toString()); - ((EditText) findViewById(R.id.note)).setText(Html.fromHtml(waypoint.note.trim()).toString()); - - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog = null; - } - Log.e(cgSettings.tag, "cgeowaypointadd.loadWaypointHandler: " + e.toString()); - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.waypoint_new); - setTitle("waypoint"); - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - // get parameters - Bundle extras = getIntent().getExtras(); - if (extras != null) { - geocode = extras.getString("geocode"); - wpCount = extras.getInt("count", 0); - id = extras.getInt("waypoint"); - } - - if (StringUtils.isBlank(geocode) && id <= 0) { - showToast(res.getString(R.string.err_waypoint_cache_unknown)); - - finish(); - return; - } - - if (id <= 0) { - setTitle(res.getString(R.string.waypoint_add_title)); - } else { - setTitle(res.getString(R.string.waypoint_edit_title)); - } - - if (geocode != null) { - app.setAction(geocode); - } - - Button buttonLat = (Button) findViewById(R.id.buttonLatitude); - buttonLat.setOnClickListener(new coordDialogListener()); - Button buttonLon = (Button) findViewById(R.id.buttonLongitude); - buttonLon.setOnClickListener(new coordDialogListener()); - - Button addWaypoint = (Button) findViewById(R.id.add_waypoint); - addWaypoint.setOnClickListener(new coordsListener()); - - List<String> wayPointNames = new ArrayList<String>(cgBase.waypointTypes.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); - - - if (id > 0) { - waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); - waitDialog.setCancelable(true); - - (new loadWaypoint()).start(); - } - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - - if (geo == null) { - geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); - } - - if (id > 0) { - if (waitDialog == null) { - waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); - waitDialog.setCancelable(true); - - (new loadWaypoint()).start(); - } - } - } - - @Override - public void onDestroy() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onDestroy(); - } - - @Override - public void onStop() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (geo != null) { - geo = app.removeGeo(); - } - - super.onPause(); - } - - private class update extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null || geo.coordsNow == null) { - return; - } - - try { - Button bLat = (Button) findViewById(R.id.buttonLatitude); - Button bLon = (Button) findViewById(R.id.buttonLongitude); - bLat.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); - bLon.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - private class loadWaypoint extends Thread { - - @Override - public void run() { - try { - waypoint = app.loadWaypoint(id); - - loadWaypointHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString()); - } - } - } - - private class coordDialogListener implements View.OnClickListener { - - public void onClick(View arg0) { - Geopoint gp = null; - if (waypoint != null && waypoint.coords != null) - gp = waypoint.coords; - cgeocoords coordsDialog = new cgeocoords(cgeowaypointadd.this, settings, gp, geo); - coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { - @Override - public void update(final Geopoint gp) { - ((Button) findViewById(R.id.buttonLatitude)).setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); - ((Button) findViewById(R.id.buttonLongitude)).setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); - if (waypoint != null) { - waypoint.coords = gp; - } - } - }); - coordsDialog.show(); - } - } - - private class coordsListener implements View.OnClickListener { - - public void onClick(View arg0) { - List<Double> coords = new ArrayList<Double>(); - Double latitude = null; - Double longitude = null; - - final String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString(); - final String distanceText = ((EditText) findViewById(R.id.distance)).getText().toString(); - final String latText = ((Button) findViewById(R.id.buttonLatitude)).getText().toString(); - final String lonText = ((Button) findViewById(R.id.buttonLongitude)).getText().toString(); - - if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText) - && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) { - helpDialog(res.getString(R.string.err_point_no_position_given_title), res.getString(R.string.err_point_no_position_given)); - return; - } - - if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) { - // latitude & longitude - Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); - Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lon"); - - if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lat)); - return; - } - - if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { - showToast(res.getString(R.string.err_parse_lon)); - return; - } - - latitude = (Double) latParsed.get("coordinate"); - longitude = (Double) lonParsed.get("coordinate"); - } else { - if (geo == null || geo.coordsNow == null) { - showToast(res.getString(R.string.err_point_curr_position_unavailable)); - return; - } - - latitude = geo.coordsNow.getLatitude(); - longitude = geo.coordsNow.getLongitude(); - } - - if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) { - // bearing & distance - Double bearing = null; - try { - bearing = new Double(bearingText); - } catch (Exception e) { - // probably not a number - } - if (bearing == null) { - helpDialog(res.getString(R.string.err_point_bear_and_dist_title), res.getString(R.string.err_point_bear_and_dist)); - return; - } - - double distance; - try { - distance = DistanceParser.parseDistance(distanceText, settings.units); - } catch (NumberFormatException e) { - showToast(res.getString(R.string.err_parse_dist)); - return; - } - - Double latParsed = null; - Double lonParsed = null; - - final Geopoint coordsDst = new Geopoint(latitude, longitude).project(bearing, distance); - - latParsed = coordsDst.getLatitude(); - lonParsed = coordsDst.getLongitude(); - - if (latParsed == null || lonParsed == null) { - showToast(res.getString(R.string.err_point_location_error)); - return; - } - - coords.add(0, (Double) latParsed); - coords.add(1, (Double) lonParsed); - } else if (latitude != null && longitude != null) { - coords.add(0, latitude); - coords.add(1, longitude); - } else { - showToast(res.getString(R.string.err_point_location_error)); - return; - } - - String name = ((EditText) findViewById(R.id.name)).getText().toString().trim(); - // if no name is given, just give the waypoint its number as name - if (name.length() == 0) { - name = res.getString(R.string.waypoint) + " " + String.valueOf(wpCount + 1); - } - final String note = ((EditText) findViewById(R.id.note)).getText().toString().trim(); - - final cgWaypoint waypoint = new cgWaypoint(); - waypoint.type = type; - waypoint.geocode = geocode; - waypoint.prefix = prefix; - waypoint.lookup = lookup; - waypoint.name = name; - waypoint.coords = new Geopoint(coords.get(0), coords.get(1)); - waypoint.latitudeString = cgBase.formatLatitude(coords.get(0), true); - waypoint.longitudeString = cgBase.formatLongitude(coords.get(1), true); - waypoint.note = note; - - if (app.saveOwnWaypoint(id, geocode, waypoint)) { - app.removeCacheFromCache(geocode); - - finish(); - return; - } else { - showToast(res.getString(R.string.err_waypoint_add_failed)); - } - } - } - - public void goManual(View view) { - if (id >= 0) { - ActivityMixin.goManual(this, "c:geo-waypoint-edit"); - } else { - ActivityMixin.goManual(this, "c:geo-waypoint-new"); - } - } + private String geocode = null; + private int id = -1; + private cgGeo geo = null; + private cgUpdateLoc geoUpdate = new update(); + private ProgressDialog waitDialog = null; + private cgWaypoint waypoint = null; + private String type = "own"; + private String prefix = "OWN"; + private String lookup = "---"; + /** + * number of waypoints that the corresponding cache has until now + */ + private int wpCount = 0; + private Handler loadWaypointHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (waypoint == null) { + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + + id = -1; + } else { + geocode = waypoint.geocode; + type = waypoint.type; + prefix = waypoint.prefix; + lookup = waypoint.lookup; + + app.setAction(geocode); + + ((Button) findViewById(R.id.buttonLatitude)).setText(cgBase.formatLatitude(waypoint.coords.getLatitude(), true)); + ((Button) findViewById(R.id.buttonLongitude)).setText(cgBase.formatLongitude(waypoint.coords.getLongitude(), true)); + ((EditText) findViewById(R.id.name)).setText(Html.fromHtml(waypoint.name.trim()).toString()); + ((EditText) findViewById(R.id.note)).setText(Html.fromHtml(waypoint.note.trim()).toString()); + + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog = null; + } + Log.e(cgSettings.tag, "cgeowaypointadd.loadWaypointHandler: " + e.toString()); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.waypoint_new); + setTitle("waypoint"); + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + // get parameters + Bundle extras = getIntent().getExtras(); + if (extras != null) { + geocode = extras.getString("geocode"); + wpCount = extras.getInt("count", 0); + id = extras.getInt("waypoint"); + } + + if (StringUtils.isBlank(geocode) && id <= 0) { + showToast(res.getString(R.string.err_waypoint_cache_unknown)); + + finish(); + return; + } + + if (id <= 0) { + setTitle(res.getString(R.string.waypoint_add_title)); + } else { + setTitle(res.getString(R.string.waypoint_edit_title)); + } + + if (geocode != null) { + app.setAction(geocode); + } + + Button buttonLat = (Button) findViewById(R.id.buttonLatitude); + buttonLat.setOnClickListener(new coordDialogListener()); + Button buttonLon = (Button) findViewById(R.id.buttonLongitude); + buttonLon.setOnClickListener(new coordDialogListener()); + + Button addWaypoint = (Button) findViewById(R.id.add_waypoint); + addWaypoint.setOnClickListener(new coordsListener()); + + List<String> wayPointNames = new ArrayList<String>(cgBase.waypointTypes.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); + + if (id > 0) { + waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); + waitDialog.setCancelable(true); + + (new loadWaypoint()).start(); + } + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + + if (geo == null) { + geo = app.startGeo(this, geoUpdate, base, settings, 0, 0); + } + + if (id > 0) { + if (waitDialog == null) { + waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true); + waitDialog.setCancelable(true); + + (new loadWaypoint()).start(); + } + } + } + + @Override + public void onDestroy() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onDestroy(); + } + + @Override + public void onStop() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (geo != null) { + geo = app.removeGeo(); + } + + super.onPause(); + } + + private class update extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null || geo.coordsNow == null) { + return; + } + + try { + Button bLat = (Button) findViewById(R.id.buttonLatitude); + Button bLon = (Button) findViewById(R.id.buttonLongitude); + bLat.setHint(cgBase.formatLatitude(geo.coordsNow.getLatitude(), false)); + bLon.setHint(cgBase.formatLongitude(geo.coordsNow.getLongitude(), false)); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + private class loadWaypoint extends Thread { + + @Override + public void run() { + try { + waypoint = app.loadWaypoint(id); + + loadWaypointHandler.sendMessage(new Message()); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString()); + } + } + } + + private class coordDialogListener implements View.OnClickListener { + + public void onClick(View arg0) { + Geopoint gp = null; + if (waypoint != null && waypoint.coords != null) + gp = waypoint.coords; + cgeocoords coordsDialog = new cgeocoords(cgeowaypointadd.this, settings, gp, geo); + coordsDialog.setCancelable(true); + coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + @Override + public void update(final Geopoint gp) { + ((Button) findViewById(R.id.buttonLatitude)).setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); + ((Button) findViewById(R.id.buttonLongitude)).setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); + if (waypoint != null) { + waypoint.coords = gp; + } + } + }); + coordsDialog.show(); + } + } + + private class coordsListener implements View.OnClickListener { + + public void onClick(View arg0) { + List<Double> coords = new ArrayList<Double>(); + Double latitude = null; + Double longitude = null; + + final String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString(); + final String distanceText = ((EditText) findViewById(R.id.distance)).getText().toString(); + final String latText = ((Button) findViewById(R.id.buttonLatitude)).getText().toString(); + final String lonText = ((Button) findViewById(R.id.buttonLongitude)).getText().toString(); + + if (StringUtils.isBlank(bearingText) && StringUtils.isBlank(distanceText) + && StringUtils.isBlank(latText) && StringUtils.isBlank(lonText)) { + helpDialog(res.getString(R.string.err_point_no_position_given_title), res.getString(R.string.err_point_no_position_given)); + return; + } + + if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) { + // latitude & longitude + Map<String, Object> latParsed = cgBase.parseCoordinate(latText, "lat"); + Map<String, Object> lonParsed = cgBase.parseCoordinate(lonText, "lon"); + + if (latParsed == null || latParsed.get("coordinate") == null || latParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lat)); + return; + } + + if (lonParsed == null || lonParsed.get("coordinate") == null || lonParsed.get("string") == null) { + showToast(res.getString(R.string.err_parse_lon)); + return; + } + + latitude = (Double) latParsed.get("coordinate"); + longitude = (Double) lonParsed.get("coordinate"); + } else { + if (geo == null || geo.coordsNow == null) { + showToast(res.getString(R.string.err_point_curr_position_unavailable)); + return; + } + + latitude = geo.coordsNow.getLatitude(); + longitude = geo.coordsNow.getLongitude(); + } + + if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) { + // bearing & distance + Double bearing = null; + try { + bearing = new Double(bearingText); + } catch (Exception e) { + // probably not a number + } + if (bearing == null) { + helpDialog(res.getString(R.string.err_point_bear_and_dist_title), res.getString(R.string.err_point_bear_and_dist)); + return; + } + + double distance; + try { + distance = DistanceParser.parseDistance(distanceText, settings.units); + } catch (NumberFormatException e) { + showToast(res.getString(R.string.err_parse_dist)); + return; + } + + Double latParsed = null; + Double lonParsed = null; + + final Geopoint coordsDst = new Geopoint(latitude, longitude).project(bearing, distance); + + latParsed = coordsDst.getLatitude(); + lonParsed = coordsDst.getLongitude(); + + if (latParsed == null || lonParsed == null) { + showToast(res.getString(R.string.err_point_location_error)); + return; + } + + coords.add(0, (Double) latParsed); + coords.add(1, (Double) lonParsed); + } else if (latitude != null && longitude != null) { + coords.add(0, latitude); + coords.add(1, longitude); + } else { + showToast(res.getString(R.string.err_point_location_error)); + return; + } + + String name = ((EditText) findViewById(R.id.name)).getText().toString().trim(); + // if no name is given, just give the waypoint its number as name + if (name.length() == 0) { + name = res.getString(R.string.waypoint) + " " + String.valueOf(wpCount + 1); + } + final String note = ((EditText) findViewById(R.id.note)).getText().toString().trim(); + + final cgWaypoint waypoint = new cgWaypoint(); + waypoint.type = type; + waypoint.geocode = geocode; + waypoint.prefix = prefix; + waypoint.lookup = lookup; + waypoint.name = name; + waypoint.coords = new Geopoint(coords.get(0), coords.get(1)); + waypoint.latitudeString = cgBase.formatLatitude(coords.get(0), true); + waypoint.longitudeString = cgBase.formatLongitude(coords.get(1), true); + waypoint.note = note; + + if (app.saveOwnWaypoint(id, geocode, waypoint)) { + app.removeCacheFromCache(geocode); + + finish(); + return; + } else { + showToast(res.getString(R.string.err_waypoint_add_failed)); + } + } + } + + public void goManual(View view) { + if (id >= 0) { + ActivityMixin.goManual(this, "c:geo-waypoint-edit"); + } else { + ActivityMixin.goManual(this, "c:geo-waypoint-new"); + } + } } diff --git a/src/cgeo/geocaching/compatibility/AndroidLevel8.java b/src/cgeo/geocaching/compatibility/AndroidLevel8.java index a821502..9c5148a 100644 --- a/src/cgeo/geocaching/compatibility/AndroidLevel8.java +++ b/src/cgeo/geocaching/compatibility/AndroidLevel8.java @@ -3,25 +3,25 @@ package cgeo.geocaching.compatibility; import android.app.Activity; public class AndroidLevel8 { - static { - try { - Class.forName("cgeo.geocaching.compatibility.AndroidLevel8Internal"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + static { + try { + Class.forName("cgeo.geocaching.compatibility.AndroidLevel8Internal"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private AndroidLevel8Internal internal; + private AndroidLevel8Internal internal; - public static void check() { - // nothing - } + public static void check() { + // nothing + } - public AndroidLevel8() { - internal = new AndroidLevel8Internal(); - } + public AndroidLevel8() { + internal = new AndroidLevel8Internal(); + } - public int getRotation(Activity activity) { - return internal.getRotation(activity); - } + public int getRotation(Activity activity) { + return internal.getRotation(activity); + } } diff --git a/src/cgeo/geocaching/compatibility/AndroidLevel8Internal.java b/src/cgeo/geocaching/compatibility/AndroidLevel8Internal.java index c68f20e..45b465b 100644 --- a/src/cgeo/geocaching/compatibility/AndroidLevel8Internal.java +++ b/src/cgeo/geocaching/compatibility/AndroidLevel8Internal.java @@ -5,11 +5,11 @@ import android.view.Display; class AndroidLevel8Internal { - public AndroidLevel8Internal() { - } + public AndroidLevel8Internal() { + } - public static int getRotation(final Activity activity) { - Display display = activity.getWindowManager().getDefaultDisplay(); - return display.getRotation(); - } + public static int getRotation(final Activity activity) { + Display display = activity.getWindowManager().getDefaultDisplay(); + return display.getRotation(); + } } diff --git a/src/cgeo/geocaching/compatibility/Compatibility.java b/src/cgeo/geocaching/compatibility/Compatibility.java index bc58764..2f94915 100644 --- a/src/cgeo/geocaching/compatibility/Compatibility.java +++ b/src/cgeo/geocaching/compatibility/Compatibility.java @@ -9,64 +9,64 @@ import android.view.Surface; public final class Compatibility { - private static AndroidLevel8 level8; - private static boolean initialized = false; + private static AndroidLevel8 level8; + private static boolean initialized = false; - private static AndroidLevel8 getLevel8() { - if (!initialized) { - try { - final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); - if (sdk >= 8) { - level8 = new AndroidLevel8(); - } - } catch (Exception e) { - // nothing - } - initialized = true; - } - return level8; - } + private static AndroidLevel8 getLevel8() { + if (!initialized) { + try { + final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); + if (sdk >= 8) { + level8 = new AndroidLevel8(); + } + } catch (Exception e) { + // nothing + } + initialized = true; + } + return level8; + } - public static Float getDirectionNow(final Float directionNowPre, - final Activity activity) { - AndroidLevel8 level8 = getLevel8(); + public static Float getDirectionNow(final Float directionNowPre, + final Activity activity) { + AndroidLevel8 level8 = getLevel8(); - if (level8 != null) { - final int rotation = level8.getRotation(activity); - if (rotation == Surface.ROTATION_90) { - return directionNowPre + 90; - } else if (rotation == Surface.ROTATION_180) { - return directionNowPre + 180; - } else if (rotation == Surface.ROTATION_270) { - return directionNowPre + 270; - } - } else { - final Display display = activity.getWindowManager() - .getDefaultDisplay(); - final int rotation = display.getOrientation(); - if (rotation == Configuration.ORIENTATION_LANDSCAPE) { - return directionNowPre + 90; - } - } - return directionNowPre; - } + if (level8 != null) { + final int rotation = level8.getRotation(activity); + if (rotation == Surface.ROTATION_90) { + return directionNowPre + 90; + } else if (rotation == Surface.ROTATION_180) { + return directionNowPre + 180; + } else if (rotation == Surface.ROTATION_270) { + return directionNowPre + 270; + } + } else { + final Display display = activity.getWindowManager() + .getDefaultDisplay(); + final int rotation = display.getOrientation(); + if (rotation == Configuration.ORIENTATION_LANDSCAPE) { + return directionNowPre + 90; + } + } + return directionNowPre; + } - public static Uri getCalendarProviderURI() { - final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); - if (sdk >= 8) { - return Uri.parse("content://com.android.calendar/calendars"); - } else { - return Uri.parse("content://calendar/calendars"); - } - } + public static Uri getCalendarProviderURI() { + final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); + if (sdk >= 8) { + return Uri.parse("content://com.android.calendar/calendars"); + } else { + return Uri.parse("content://calendar/calendars"); + } + } - public static Uri getCalenderEventsProviderURI() { - final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); - if (sdk >= 8) { - return Uri.parse("content://com.android.calendar/events"); - } else { - return Uri.parse("content://calendar/events"); - } - } + public static Uri getCalenderEventsProviderURI() { + final int sdk = Integer.valueOf(Build.VERSION.SDK).intValue(); + if (sdk >= 8) { + return Uri.parse("content://com.android.calendar/events"); + } else { + return Uri.parse("content://calendar/events"); + } + } } diff --git a/src/cgeo/geocaching/connector/AbstractConnector.java b/src/cgeo/geocaching/connector/AbstractConnector.java index 24d13f8..50a328e 100644 --- a/src/cgeo/geocaching/connector/AbstractConnector.java +++ b/src/cgeo/geocaching/connector/AbstractConnector.java @@ -4,23 +4,23 @@ import cgeo.geocaching.cgCache; public abstract class AbstractConnector implements IConnector { - @Override - public boolean canHandle(String geocode) { - return false; - } + @Override + public boolean canHandle(String geocode) { + return false; + } - @Override - public boolean supportsRefreshCache(cgCache cache) { - return false; - } + @Override + public boolean supportsRefreshCache(cgCache cache) { + return false; + } - @Override - public boolean supportsWatchList() { - return false; - } + @Override + public boolean supportsWatchList() { + return false; + } - @Override - public boolean supportsLogging() { - return false; - } + @Override + public boolean supportsLogging() { + return false; + } } diff --git a/src/cgeo/geocaching/connector/ConnectorFactory.java b/src/cgeo/geocaching/connector/ConnectorFactory.java index d052231..867f48d 100644 --- a/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -3,29 +3,29 @@ package cgeo.geocaching.connector; import cgeo.geocaching.cgCache; public final class ConnectorFactory { - private static final GCConnector GC_CONNECTOR = new GCConnector(); - private static final IConnector[] connectors = new IConnector[] {GC_CONNECTOR, new OCConnector(), new OXConnector()}; + private static final GCConnector GC_CONNECTOR = new GCConnector(); + private static final IConnector[] connectors = new IConnector[] { GC_CONNECTOR, new OCConnector(), new OXConnector() }; - public static IConnector[] getConnectors() { - return connectors; - } + public static IConnector[] getConnectors() { + return connectors; + } - public static boolean canHandle(final String geocode) { - for (IConnector connector : connectors) { - if (connector.canHandle(geocode)) { - return true; - } - } - return false; - } + public static boolean canHandle(final String geocode) { + for (IConnector connector : connectors) { + if (connector.canHandle(geocode)) { + return true; + } + } + return false; + } - public static IConnector getConnector(cgCache cache) { - for (IConnector connector : connectors) { - if (connector.canHandle(cache.geocode)) { - return connector; - } - } - // in case of errors, assume GC as default - return GC_CONNECTOR; - } + public static IConnector getConnector(cgCache cache) { + for (IConnector connector : connectors) { + if (connector.canHandle(cache.geocode)) { + return connector; + } + } + // in case of errors, assume GC as default + return GC_CONNECTOR; + } } diff --git a/src/cgeo/geocaching/connector/GCConnector.java b/src/cgeo/geocaching/connector/GCConnector.java index 1d61d2f..c7db821 100644 --- a/src/cgeo/geocaching/connector/GCConnector.java +++ b/src/cgeo/geocaching/connector/GCConnector.java @@ -1,33 +1,33 @@ package cgeo.geocaching.connector; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + public class GCConnector extends AbstractConnector implements IConnector { - @Override - public boolean canHandle(String geocode) { - return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("GC"); - } - - @Override - public boolean supportsRefreshCache(cgCache cache) { - return true; - } - - @Override - public String getCacheUrl(cgCache cache) { - return "http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.geocode; - } - - @Override - public boolean supportsWatchList() { - return true; - } - - @Override - public boolean supportsLogging() { - return true; - } + @Override + public boolean canHandle(String geocode) { + return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("GC"); + } + + @Override + public boolean supportsRefreshCache(cgCache cache) { + return true; + } + + @Override + public String getCacheUrl(cgCache cache) { + return "http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.geocode; + } + + @Override + public boolean supportsWatchList() { + return true; + } + + @Override + public boolean supportsLogging() { + return true; + } } diff --git a/src/cgeo/geocaching/connector/IConnector.java b/src/cgeo/geocaching/connector/IConnector.java index 6366b5c..66defd6 100644 --- a/src/cgeo/geocaching/connector/IConnector.java +++ b/src/cgeo/geocaching/connector/IConnector.java @@ -3,9 +3,13 @@ package cgeo.geocaching.connector; import cgeo.geocaching.cgCache; public interface IConnector { - public boolean canHandle(final String geocode); - public boolean supportsRefreshCache(final cgCache cache); - public String getCacheUrl(final cgCache cache); - public boolean supportsWatchList(); - public boolean supportsLogging(); + public boolean canHandle(final String geocode); + + public boolean supportsRefreshCache(final cgCache cache); + + public String getCacheUrl(final cgCache cache); + + public boolean supportsWatchList(); + + public boolean supportsLogging(); } diff --git a/src/cgeo/geocaching/connector/OCConnector.java b/src/cgeo/geocaching/connector/OCConnector.java index 8d1c42f..1bc967c 100644 --- a/src/cgeo/geocaching/connector/OCConnector.java +++ b/src/cgeo/geocaching/connector/OCConnector.java @@ -1,21 +1,21 @@ package cgeo.geocaching.connector; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + /** * connector for OpenCaching.de (and several other country domains) - * + * */ public class OCConnector extends AbstractConnector implements IConnector { - @Override - public boolean canHandle(String geocode) { - return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("OC"); - } + @Override + public boolean canHandle(String geocode) { + return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("OC"); + } - @Override - public String getCacheUrl(cgCache cache) { - return "http://www.opencaching.de/viewcache.php?wp=" + cache.geocode; - } + @Override + public String getCacheUrl(cgCache cache) { + return "http://www.opencaching.de/viewcache.php?wp=" + cache.geocode; + } } diff --git a/src/cgeo/geocaching/connector/OXConnector.java b/src/cgeo/geocaching/connector/OXConnector.java index dc78044..3ea36a7 100644 --- a/src/cgeo/geocaching/connector/OXConnector.java +++ b/src/cgeo/geocaching/connector/OXConnector.java @@ -1,23 +1,23 @@ package cgeo.geocaching.connector; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + /** * connector for OpenCaching.com - * + * */ public class OXConnector extends AbstractConnector implements IConnector { - @Override - public boolean canHandle(String geocode) { - return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("OX"); - } + @Override + public boolean canHandle(String geocode) { + return StringUtils.isNotBlank(geocode) && geocode.toUpperCase().startsWith("OX"); + } - @Override - public String getCacheUrl(cgCache cache) { - return "http://www.opencaching.com/#!geocache/" + cache.geocode; - } + @Override + public String getCacheUrl(cgCache cache) { + return "http://www.opencaching.com/#!geocache/" + cache.geocode; + } } diff --git a/src/cgeo/geocaching/enumerations/CacheSize.java b/src/cgeo/geocaching/enumerations/CacheSize.java index f045c65..901be9e 100755..100644 --- a/src/cgeo/geocaching/enumerations/CacheSize.java +++ b/src/cgeo/geocaching/enumerations/CacheSize.java @@ -6,16 +6,16 @@ import java.util.Map; /**
* Enum listing cache sizes
- *
+ *
* @author koem
*/
public enum CacheSize {
- MICRO ("micro", 1),
- SMALL ("small", 2),
- REGULAR ("regular", 3),
- LARGE ("large", 4),
- NOT_CHOSEN ("not chosen", 0),
- OTHER ("other", 0);
+ MICRO("micro", 1),
+ SMALL("small", 2),
+ REGULAR("regular", 3),
+ LARGE("large", 4),
+ NOT_CHOSEN("not chosen", 0),
+ OTHER("other", 0);
public final String cgeoId;
public final int comparable;
@@ -28,7 +28,7 @@ public enum CacheSize { final public static Map<String, CacheSize> FIND_BY_CGEOID;
static {
final HashMap<String, CacheSize> mapping = new HashMap<String, CacheSize>();
- for (CacheSize cs: values()) {
+ for (CacheSize cs : values()) {
mapping.put(cs.cgeoId, cs);
}
FIND_BY_CGEOID = Collections.unmodifiableMap(mapping);
diff --git a/src/cgeo/geocaching/enumerations/CacheType.java b/src/cgeo/geocaching/enumerations/CacheType.java index b3c0e76..f30afc9 100755..100644 --- a/src/cgeo/geocaching/enumerations/CacheType.java +++ b/src/cgeo/geocaching/enumerations/CacheType.java @@ -1,14 +1,14 @@ package cgeo.geocaching.enumerations;
+import cgeo.geocaching.R;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import cgeo.geocaching.R;
-
/**
* Enum listing all cache types
- *
+ *
* @author koem
*/
public enum CacheType {
@@ -39,7 +39,7 @@ public enum CacheType { this.guid = guid;
this.stringId = stringId;
}
-
+
public final static Map<String, CacheType> FIND_BY_CGEOID;
static {
final HashMap<String, CacheType> mapping = new HashMap<String, CacheType>();
diff --git a/src/cgeo/geocaching/enumerations/WaypointType.java b/src/cgeo/geocaching/enumerations/WaypointType.java index 41bf7b8..cd4b31c 100755..100644 --- a/src/cgeo/geocaching/enumerations/WaypointType.java +++ b/src/cgeo/geocaching/enumerations/WaypointType.java @@ -6,7 +6,7 @@ import java.util.Map; /**
* Enum listing waypoint types
- *
+ *
* @author koem
*/
public enum WaypointType {
@@ -23,7 +23,7 @@ public enum WaypointType { private WaypointType(String cgeoId) {
this.cgeoId = cgeoId;
}
-
+
public static final Map<String, WaypointType> FIND_BY_CGEOID;
static {
final HashMap<String, WaypointType> mapping = new HashMap<String, WaypointType>();
diff --git a/src/cgeo/geocaching/files/FileList.java b/src/cgeo/geocaching/files/FileList.java index 08c8b11..fb0c698 100644 --- a/src/cgeo/geocaching/files/FileList.java +++ b/src/cgeo/geocaching/files/FileList.java @@ -1,8 +1,8 @@ package cgeo.geocaching.files; -import java.io.File; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.R; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.activity.AbstractListActivity; import org.apache.commons.lang3.ArrayUtils; @@ -14,231 +14,233 @@ import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.ArrayAdapter; -import cgeo.geocaching.R; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.activity.AbstractListActivity; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractListActivity { - private List<File> files = new ArrayList<File>(); - private T adapter = null; - private ProgressDialog waitDialog = null; - private loadFiles searchingThread = null; - private boolean endSearching = false; - private int listId = 1; - final private Handler changeWaitDialogHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (msg.obj != null && waitDialog != null) { - waitDialog.setMessage(res.getString(R.string.file_searching_in) + " " + (String) msg.obj); - } - } - }; - final private Handler loadFilesHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - try { - if (files == null || files.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - showToast(res.getString(R.string.file_list_no_files)); - - finish(); - return; - } else { - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - - if (waitDialog != null) { - waitDialog.dismiss(); - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgFileList.loadFilesHandler: " + e.toString()); - } - } - }; - private String[] extensions; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setTheme(); - setContentView(R.layout.gpx); - setTitle(); - - Bundle extras = getIntent().getExtras(); - if (extras != null) { - listId = extras.getInt("list"); - } - if (listId <= 0) { - listId = 1; - } - - setAdapter(); - - waitDialog = ProgressDialog.show( - this, - res.getString(R.string.file_title_searching), - res.getString(R.string.file_searching), - true, - true, - new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface arg0) { - if (searchingThread != null && searchingThread.isAlive()) { - searchingThread.notifyEnd(); - } - if (files.isEmpty()) { - finish(); - } - } - } - ); - - endSearching = false; - searchingThread = new loadFiles(); - searchingThread.start(); - } - - @Override - public void onResume() { - super.onResume(); - - getSettings().load(); - } - - protected abstract T getAdapter(List<File> files); - - private void setAdapter() { - if (adapter == null) { - adapter = getAdapter(files); - setListAdapter(adapter); - } - } - - /** - * Gets the base folder for file searches - * @return The folder to start the recursive search in - */ - protected abstract String[] getBaseFolders(); - - /** - * Triggers the deriving class to set the title - */ - protected abstract void setTitle(); - - private class loadFiles extends Thread { - public void notifyEnd() { - endSearching = true; - } - - @Override - public void run() { - List<File> list = new ArrayList<File>(); - - try { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - boolean loaded = false; - for(String baseFolder : getBaseFolders()) - { - final File dir = new File(baseFolder); - - if (dir.exists() && dir.isDirectory()) { - listDir(list, dir); - if (list.size() > 0) { - loaded = true; - break; - } - } - } - if (!loaded) { - listDir(list, Environment.getExternalStorageDirectory()); - } - } else { - Log.w(cgSettings.tag, "No external media mounted."); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgFileList.loadFiles.run: " + e.toString()); - } - - final Message msg = new Message(); - msg.obj = "loaded directories"; - changeWaitDialogHandler.sendMessage(msg); - - files.addAll(list); - list.clear(); - - loadFilesHandler.sendMessage(new Message()); - } - } - - private void listDir(List<File> result, File directory) { - if (directory == null || !directory.isDirectory() || !directory.canRead()) { - return; - } - - final File[] files = directory.listFiles(); - - if (ArrayUtils.isNotEmpty(files)) { - for (File file : files) { - if (endSearching) { - return; - } - if (!file.canRead()) { - continue; - } - String name = file.getName(); - if (file.isFile()) { - for (String ext : extensions) { - int extLength = ext.length(); - if (name.length() > extLength && name.substring(name.length() - extLength, name.length()).equalsIgnoreCase(ext)) { - result.add(file); // add file to list - break; - } - } - - } else if (file.isDirectory()) { - if (name.charAt(0) == '.') { - continue; // skip hidden directories - } - if (name.length() > 16) { - name = name.substring(0, 14) + "..."; - } - final Message msg = new Message(); - msg.obj = name; - changeWaitDialogHandler.sendMessage(msg); - - listDir(result, file); // go deeper - } - } - } - - return; - } - - protected FileList(final String extension) { - setExtensions(new String[] {extension}); - } - - protected FileList(final String[] extensions) { - setExtensions(extensions); - } - - private void setExtensions(String[] extensionsIn) { - for (String extension : extensionsIn) { - if (extension.length() == 0 || extension.charAt(0) != '.') { - extension = "." + extension; - } - } - extensions = extensionsIn; - } + private List<File> files = new ArrayList<File>(); + private T adapter = null; + private ProgressDialog waitDialog = null; + private loadFiles searchingThread = null; + private boolean endSearching = false; + private int listId = 1; + final private Handler changeWaitDialogHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (msg.obj != null && waitDialog != null) { + waitDialog.setMessage(res.getString(R.string.file_searching_in) + " " + (String) msg.obj); + } + } + }; + final private Handler loadFilesHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + try { + if (files == null || files.isEmpty()) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + + showToast(res.getString(R.string.file_list_no_files)); + + finish(); + return; + } else { + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + + if (waitDialog != null) { + waitDialog.dismiss(); + } + } catch (Exception e) { + if (waitDialog != null) { + waitDialog.dismiss(); + } + Log.e(cgSettings.tag, "cgFileList.loadFilesHandler: " + e.toString()); + } + } + }; + private String[] extensions; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(); + setContentView(R.layout.gpx); + setTitle(); + + Bundle extras = getIntent().getExtras(); + if (extras != null) { + listId = extras.getInt("list"); + } + if (listId <= 0) { + listId = 1; + } + + setAdapter(); + + waitDialog = ProgressDialog.show( + this, + res.getString(R.string.file_title_searching), + res.getString(R.string.file_searching), + true, + true, + new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface arg0) { + if (searchingThread != null && searchingThread.isAlive()) { + searchingThread.notifyEnd(); + } + if (files.isEmpty()) { + finish(); + } + } + } + ); + + endSearching = false; + searchingThread = new loadFiles(); + searchingThread.start(); + } + + @Override + public void onResume() { + super.onResume(); + + getSettings().load(); + } + + protected abstract T getAdapter(List<File> files); + + private void setAdapter() { + if (adapter == null) { + adapter = getAdapter(files); + setListAdapter(adapter); + } + } + + /** + * Gets the base folder for file searches + * + * @return The folder to start the recursive search in + */ + protected abstract String[] getBaseFolders(); + + /** + * Triggers the deriving class to set the title + */ + protected abstract void setTitle(); + + private class loadFiles extends Thread { + public void notifyEnd() { + endSearching = true; + } + + @Override + public void run() { + List<File> list = new ArrayList<File>(); + + try { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + boolean loaded = false; + for (String baseFolder : getBaseFolders()) + { + final File dir = new File(baseFolder); + + if (dir.exists() && dir.isDirectory()) { + listDir(list, dir); + if (list.size() > 0) { + loaded = true; + break; + } + } + } + if (!loaded) { + listDir(list, Environment.getExternalStorageDirectory()); + } + } else { + Log.w(cgSettings.tag, "No external media mounted."); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgFileList.loadFiles.run: " + e.toString()); + } + + final Message msg = new Message(); + msg.obj = "loaded directories"; + changeWaitDialogHandler.sendMessage(msg); + + files.addAll(list); + list.clear(); + + loadFilesHandler.sendMessage(new Message()); + } + } + + private void listDir(List<File> result, File directory) { + if (directory == null || !directory.isDirectory() || !directory.canRead()) { + return; + } + + final File[] files = directory.listFiles(); + + if (ArrayUtils.isNotEmpty(files)) { + for (File file : files) { + if (endSearching) { + return; + } + if (!file.canRead()) { + continue; + } + String name = file.getName(); + if (file.isFile()) { + for (String ext : extensions) { + int extLength = ext.length(); + if (name.length() > extLength && name.substring(name.length() - extLength, name.length()).equalsIgnoreCase(ext)) { + result.add(file); // add file to list + break; + } + } + + } else if (file.isDirectory()) { + if (name.charAt(0) == '.') { + continue; // skip hidden directories + } + if (name.length() > 16) { + name = name.substring(0, 14) + "..."; + } + final Message msg = new Message(); + msg.obj = name; + changeWaitDialogHandler.sendMessage(msg); + + listDir(result, file); // go deeper + } + } + } + + return; + } + + protected FileList(final String extension) { + setExtensions(new String[] { extension }); + } + + protected FileList(final String[] extensions) { + setExtensions(extensions); + } + + private void setExtensions(String[] extensionsIn) { + for (String extension : extensionsIn) { + if (extension.length() == 0 || extension.charAt(0) != '.') { + extension = "." + extension; + } + } + extensions = extensionsIn; + } } diff --git a/src/cgeo/geocaching/files/FileParser.java b/src/cgeo/geocaching/files/FileParser.java index 2939b59..c7f16c8 100644 --- a/src/cgeo/geocaching/files/FileParser.java +++ b/src/cgeo/geocaching/files/FileParser.java @@ -1,5 +1,12 @@ package cgeo.geocaching.files;
+import cgeo.geocaching.cgBase;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgSearch;
+
+import android.os.Handler;
+import android.os.Message;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -7,49 +14,40 @@ import java.io.FileReader; import java.io.IOException;
import java.util.Date;
-import android.os.Handler;
-import android.os.Message;
-import cgeo.geocaching.cgBase;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgSearch;
-
public abstract class FileParser {
- protected static StringBuilder readFile(File file)
- throws FileNotFoundException, IOException {
- StringBuilder buffer = new StringBuilder();
- BufferedReader input = new BufferedReader(new FileReader(file));
- try {
- String line = null;
- while (( line = input.readLine()) != null){
- buffer.append(line);
- }
- }
- finally {
- input.close();
- }
- return buffer;
- }
-
- static void showFinishedMessage(Handler handler, cgSearch search) {
- if (handler != null) {
- final Message msg = new Message();
- msg.obj = search.getCount();
- handler.sendMessage(msg);
- }
- }
-
- protected static void fixCache(cgCache cache) {
- cache.latitudeString = cgBase.formatLatitude(cache.coords.getLatitude(), true);
- cache.longitudeString = cgBase.formatLongitude(cache.coords.getLongitude(), true);
- if (cache.inventory != null) {
- cache.inventoryItems = cache.inventory.size();
- } else {
- cache.inventoryItems = 0;
- }
- cache.updated = new Date().getTime();
- cache.detailedUpdate = new Date().getTime();
- }
-
-
+ protected static StringBuilder readFile(File file)
+ throws FileNotFoundException, IOException {
+ StringBuilder buffer = new StringBuilder();
+ BufferedReader input = new BufferedReader(new FileReader(file));
+ try {
+ String line = null;
+ while ((line = input.readLine()) != null) {
+ buffer.append(line);
+ }
+ } finally {
+ input.close();
+ }
+ return buffer;
+ }
+
+ static void showFinishedMessage(Handler handler, cgSearch search) {
+ if (handler != null) {
+ final Message msg = new Message();
+ msg.obj = search.getCount();
+ handler.sendMessage(msg);
+ }
+ }
+
+ protected static void fixCache(cgCache cache) {
+ cache.latitudeString = cgBase.formatLatitude(cache.coords.getLatitude(), true);
+ cache.longitudeString = cgBase.formatLongitude(cache.coords.getLongitude(), true);
+ if (cache.inventory != null) {
+ cache.inventoryItems = cache.inventory.size();
+ } else {
+ cache.inventoryItems = 0;
+ }
+ cache.updated = new Date().getTime();
+ cache.detailedUpdate = new Date().getTime();
+ }
}
diff --git a/src/cgeo/geocaching/files/GPX10Parser.java b/src/cgeo/geocaching/files/GPX10Parser.java index 7bb3cb5..be3c857 100644 --- a/src/cgeo/geocaching/files/GPX10Parser.java +++ b/src/cgeo/geocaching/files/GPX10Parser.java @@ -2,18 +2,19 @@ package cgeo.geocaching.files; import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
+
import android.sax.Element;
public final class GPX10Parser extends GPXParser {
- public GPX10Parser(cgeoapplication appIn, int listIdIn,
- cgSearch searchIn) {
- super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/0", "1.0");
- }
+ public GPX10Parser(cgeoapplication appIn, int listIdIn,
+ cgSearch searchIn) {
+ super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/0", "1.0");
+ }
- @Override
- protected Element getCacheParent(Element waypoint) {
- return waypoint;
- }
+ @Override
+ protected Element getCacheParent(Element waypoint) {
+ return waypoint;
+ }
}
diff --git a/src/cgeo/geocaching/files/GPX11Parser.java b/src/cgeo/geocaching/files/GPX11Parser.java index d890e6d..9370450 100644 --- a/src/cgeo/geocaching/files/GPX11Parser.java +++ b/src/cgeo/geocaching/files/GPX11Parser.java @@ -2,18 +2,19 @@ package cgeo.geocaching.files; import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
+
import android.sax.Element;
public final class GPX11Parser extends GPXParser {
- public GPX11Parser(cgeoapplication appIn, int listIdIn,
- cgSearch searchIn) {
- super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/1", "1.1");
- }
+ public GPX11Parser(cgeoapplication appIn, int listIdIn,
+ cgSearch searchIn) {
+ super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/1", "1.1");
+ }
- @Override
- protected Element getCacheParent(Element waypoint) {
- return waypoint.getChild(namespace, "extensions");
- }
+ @Override
+ protected Element getCacheParent(Element waypoint) {
+ return waypoint.getChild(namespace, "extensions");
+ }
}
diff --git a/src/cgeo/geocaching/files/GPXParser.java b/src/cgeo/geocaching/files/GPXParser.java index a9978c5..1e1458a 100644 --- a/src/cgeo/geocaching/files/GPXParser.java +++ b/src/cgeo/geocaching/files/GPXParser.java @@ -1,17 +1,15 @@ package cgeo.geocaching.files; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import cgeo.geocaching.R; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgLog; +import cgeo.geocaching.cgSearch; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgTrackable; +import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.lang3.StringUtils; import org.xml.sax.Attributes; @@ -25,435 +23,437 @@ import android.sax.RootElement; import android.sax.StartElementListener; import android.util.Log; import android.util.Xml; -import cgeo.geocaching.R; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgLog; -import cgeo.geocaching.cgSearch; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgTrackable; -import cgeo.geocaching.cgeoapplication; -import cgeo.geocaching.connector.ConnectorFactory; -import cgeo.geocaching.geopoint.Geopoint; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public abstract class GPXParser extends FileParser { - private static final SimpleDateFormat formatSimple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 2010-04-20T07:00:00Z - private static final SimpleDateFormat formatTimezone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000'Z"); // 2010-04-20T01:01:03.000-04:00 - - private static final Pattern patternGeocode = Pattern.compile("([A-Z]{2}[0-9A-Z]+)", Pattern.CASE_INSENSITIVE); - private static final Pattern patternGuid = Pattern.compile(".*" + Pattern.quote("guid=") + "([0-9a-z\\-]+)", Pattern.CASE_INSENSITIVE); - private static final String[] nsGCList = new String[] { - "http://www.groundspeak.com/cache/1/1", // PQ 1.1 - "http://www.groundspeak.com/cache/1/0/1", // PQ 1.0.1 - "http://www.groundspeak.com/cache/1/0", // PQ 1.0 - }; - - private static final String GSAK_NS = "http://www.gsak.net/xmlv1/5"; - - private static cgeoapplication app = null; - private int listId = 1; - private cgSearch search = null; - final protected String namespace; - final private String version; - private Handler handler = null; - - private cgCache cache = new cgCache(); - private cgTrackable trackable = new cgTrackable(); - private cgLog log = new cgLog(); - - private String type = null; - private String sym = null; - private String name = null; - private String cmt = null; - private String desc = null; - protected String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier - - private final class UserDataListener implements EndTextElementListener { - private int index; - - public UserDataListener(int index) { - this.index = index; - } - - @Override - public void end(String user) { - userData[index] = validate(user); - } - } - - private static final class CacheAttributeTranslator { - // List of cache attributes matching IDs used in GPX files. - // The ID is represented by the position of the String in the array. - // Strings are not used as text but as resource IDs of strings, just to be aware of changes - // made in strings.xml which then will lead to compile errors here and not to runtime errors. - private static final int[] CACHE_ATTRIBUTES = { - -1, // 0 - R.string.attribute_dogs_yes, // 1 - R.string.attribute_fee_yes, // 2 - R.string.attribute_rappelling_yes, // 3 - R.string.attribute_boat_yes, // 4 - R.string.attribute_scuba_yes, // 5 - R.string.attribute_kids_yes, // 6 - R.string.attribute_onehour_yes, // 7 - R.string.attribute_scenic_yes, // 8 - R.string.attribute_hiking_yes, // 9 - R.string.attribute_climbing_yes, // 10 - R.string.attribute_wading_yes, // 11 - R.string.attribute_swimming_yes, // 12 - R.string.attribute_available_yes, // 13 - R.string.attribute_night_yes, // 14 - R.string.attribute_winter_yes, // 15 - -1, // 16 - R.string.attribute_poisonoak_yes, // 17 - R.string.attribute_dangerousanimals_yes, // 18 - R.string.attribute_ticks_yes, // 19 - R.string.attribute_mine_yes, // 20 - R.string.attribute_cliff_yes, // 21 - R.string.attribute_hunting_yes, // 22 - R.string.attribute_danger_yes, // 23 - R.string.attribute_wheelchair_yes, // 24 - R.string.attribute_parking_yes, // 25 - R.string.attribute_public_yes, // 26 - R.string.attribute_water_yes, // 27 - R.string.attribute_restrooms_yes, // 28 - R.string.attribute_phone_yes, // 29 - R.string.attribute_picnic_yes, // 30 - R.string.attribute_camping_yes, // 31 - R.string.attribute_bicycles_yes, // 32 - R.string.attribute_motorcycles_yes, // 33 - R.string.attribute_quads_yes, // 34 - R.string.attribute_jeeps_yes, // 35 - R.string.attribute_snowmobiles_yes, // 36 - R.string.attribute_horses_yes, // 37 - R.string.attribute_campfires_yes, // 38 - R.string.attribute_thorn_yes, // 39 - R.string.attribute_stealth_yes, // 40 - R.string.attribute_stroller_yes, // 41 - R.string.attribute_firstaid_yes, // 42 - R.string.attribute_cow_yes, // 43 - R.string.attribute_flashlight_yes, // 44 - R.string.attribute_landf_yes, // 45 - R.string.attribute_rv_yes, // 46 - R.string.attribute_field_puzzle_yes, // 47 - R.string.attribute_uv_yes, // 48 - R.string.attribute_snowshoes_yes, // 49 - R.string.attribute_skiis_yes, // 50 - R.string.attribute_s_tool_yes, // 51 - R.string.attribute_nightcache_yes, // 52 - R.string.attribute_parkngrab_yes, // 53 - R.string.attribute_abandonedbuilding_yes, // 54 - R.string.attribute_hike_short_yes, // 55 - R.string.attribute_hike_med_yes, // 56 - R.string.attribute_hike_long_yes, // 57 - R.string.attribute_fuel_yes, // 58 - R.string.attribute_food_yes, // 59 - R.string.attribute_wirelessbeacon_yes, // 60 - R.string.attribute_partnership_yes, // 61 - R.string.attribute_seasonal_yes, // 62 - R.string.attribute_touristok_yes, // 63 - R.string.attribute_treeclimbing_yes, // 64 - R.string.attribute_frontyard_yes, // 65 - R.string.attribute_teamwork_yes, // 66 - }; + private static final SimpleDateFormat formatSimple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 2010-04-20T07:00:00Z + private static final SimpleDateFormat formatTimezone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.000'Z"); // 2010-04-20T01:01:03.000-04:00 + + private static final Pattern patternGeocode = Pattern.compile("([A-Z]{2}[0-9A-Z]+)", Pattern.CASE_INSENSITIVE); + private static final Pattern patternGuid = Pattern.compile(".*" + Pattern.quote("guid=") + "([0-9a-z\\-]+)", Pattern.CASE_INSENSITIVE); + private static final String[] nsGCList = new String[] { + "http://www.groundspeak.com/cache/1/1", // PQ 1.1 + "http://www.groundspeak.com/cache/1/0/1", // PQ 1.0.1 + "http://www.groundspeak.com/cache/1/0", // PQ 1.0 + }; + + private static final String GSAK_NS = "http://www.gsak.net/xmlv1/5"; + + private static cgeoapplication app = null; + private int listId = 1; + private cgSearch search = null; + final protected String namespace; + final private String version; + private Handler handler = null; + + private cgCache cache = new cgCache(); + private cgTrackable trackable = new cgTrackable(); + private cgLog log = new cgLog(); + + private String type = null; + private String sym = null; + private String name = null; + private String cmt = null; + private String desc = null; + protected String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier + + private final class UserDataListener implements EndTextElementListener { + private int index; + + public UserDataListener(int index) { + this.index = index; + } + + @Override + public void end(String user) { + userData[index] = validate(user); + } + } + + private static final class CacheAttributeTranslator { + // List of cache attributes matching IDs used in GPX files. + // The ID is represented by the position of the String in the array. + // Strings are not used as text but as resource IDs of strings, just to be aware of changes + // made in strings.xml which then will lead to compile errors here and not to runtime errors. + private static final int[] CACHE_ATTRIBUTES = { + -1, // 0 + R.string.attribute_dogs_yes, // 1 + R.string.attribute_fee_yes, // 2 + R.string.attribute_rappelling_yes, // 3 + R.string.attribute_boat_yes, // 4 + R.string.attribute_scuba_yes, // 5 + R.string.attribute_kids_yes, // 6 + R.string.attribute_onehour_yes, // 7 + R.string.attribute_scenic_yes, // 8 + R.string.attribute_hiking_yes, // 9 + R.string.attribute_climbing_yes, // 10 + R.string.attribute_wading_yes, // 11 + R.string.attribute_swimming_yes, // 12 + R.string.attribute_available_yes, // 13 + R.string.attribute_night_yes, // 14 + R.string.attribute_winter_yes, // 15 + -1, // 16 + R.string.attribute_poisonoak_yes, // 17 + R.string.attribute_dangerousanimals_yes, // 18 + R.string.attribute_ticks_yes, // 19 + R.string.attribute_mine_yes, // 20 + R.string.attribute_cliff_yes, // 21 + R.string.attribute_hunting_yes, // 22 + R.string.attribute_danger_yes, // 23 + R.string.attribute_wheelchair_yes, // 24 + R.string.attribute_parking_yes, // 25 + R.string.attribute_public_yes, // 26 + R.string.attribute_water_yes, // 27 + R.string.attribute_restrooms_yes, // 28 + R.string.attribute_phone_yes, // 29 + R.string.attribute_picnic_yes, // 30 + R.string.attribute_camping_yes, // 31 + R.string.attribute_bicycles_yes, // 32 + R.string.attribute_motorcycles_yes, // 33 + R.string.attribute_quads_yes, // 34 + R.string.attribute_jeeps_yes, // 35 + R.string.attribute_snowmobiles_yes, // 36 + R.string.attribute_horses_yes, // 37 + R.string.attribute_campfires_yes, // 38 + R.string.attribute_thorn_yes, // 39 + R.string.attribute_stealth_yes, // 40 + R.string.attribute_stroller_yes, // 41 + R.string.attribute_firstaid_yes, // 42 + R.string.attribute_cow_yes, // 43 + R.string.attribute_flashlight_yes, // 44 + R.string.attribute_landf_yes, // 45 + R.string.attribute_rv_yes, // 46 + R.string.attribute_field_puzzle_yes, // 47 + R.string.attribute_uv_yes, // 48 + R.string.attribute_snowshoes_yes, // 49 + R.string.attribute_skiis_yes, // 50 + R.string.attribute_s_tool_yes, // 51 + R.string.attribute_nightcache_yes, // 52 + R.string.attribute_parkngrab_yes, // 53 + R.string.attribute_abandonedbuilding_yes, // 54 + R.string.attribute_hike_short_yes, // 55 + R.string.attribute_hike_med_yes, // 56 + R.string.attribute_hike_long_yes, // 57 + R.string.attribute_fuel_yes, // 58 + R.string.attribute_food_yes, // 59 + R.string.attribute_wirelessbeacon_yes, // 60 + R.string.attribute_partnership_yes, // 61 + R.string.attribute_seasonal_yes, // 62 + R.string.attribute_touristok_yes, // 63 + R.string.attribute_treeclimbing_yes, // 64 + R.string.attribute_frontyard_yes, // 65 + R.string.attribute_teamwork_yes, // 66 + }; private static final String YES = "_yes"; private static final String NO = "_no"; private static final Pattern BASENAME_PATTERN = Pattern.compile("^.*attribute_(.*)(_yes|_no)"); - // map GPX-Attribute-Id to baseName - public static String getBaseName(final int id) { - // get String out of array - if (CACHE_ATTRIBUTES.length <= id) { - return null; - } - final int stringId = CACHE_ATTRIBUTES[id]; - if (stringId == -1) { - return null; // id not found - } - // get text for string - String stringName = null; - try { - stringName = app.getResources().getResourceName(stringId); - } catch (NullPointerException e) { - return null; - } - if (stringName == null) { - return null; - } - // cut out baseName - final Matcher m = BASENAME_PATTERN.matcher(stringName); - if (! m.matches()) { - return null; - } - return m.group(1); - } - - // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes" - public static String getInternalId(final int attributeId, final boolean active) { - final String baseName = CacheAttributeTranslator.getBaseName(attributeId); - if (baseName == null) { - return null; - } - return baseName + (active ? YES : NO); - } - } - - protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) { - app = appIn; - listId = listIdIn; - search = searchIn; - namespace = namespaceIn; - version = versionIn; - } - - private static Date parseDate(String inputUntrimmed) throws ParseException { - final String input = inputUntrimmed.trim(); - if (input.length() >= 3 && input.charAt(input.length() - 3) == ':') { - final String removeColon = input.substring(0, input.length() - 3) + input.substring(input.length() - 2); - return formatTimezone.parse(removeColon); - } - return formatSimple.parse(input); - } - - public UUID parse(final InputStream stream, Handler handlerIn) { - handler = handlerIn; - - final RootElement root = new RootElement(namespace, "gpx"); - final Element waypoint = root.getChild(namespace, "wpt"); - - // waypoint - attributes - waypoint.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - try { - if (attrs.getIndex("lat") > -1 && attrs.getIndex("lon") > -1) { - cache.coords = new Geopoint(new Double(attrs.getValue("lat")), - new Double(attrs.getValue("lon"))); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse waypoint's latitude and/or longitude."); - } - } - }); - - // waypoint - waypoint.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isBlank(cache.geocode)) { - // try to find geocode somewhere else - findGeoCode(name); - findGeoCode(desc); - findGeoCode(cmt); - } - - if (StringUtils.isNotBlank(cache.geocode) - && cache.coords != null - && ((type == null && sym == null) - || (type != null && type.indexOf("geocache") > -1) - || (sym != null && sym.indexOf("geocache") > -1))) { - fixCache(cache); - cache.reason = listId; - cache.detailed = true; - - if (StringUtils.isBlank(cache.personalNote)) { - StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < userData.length; i++) { - if (StringUtils.isNotBlank(userData[i])) { - buffer.append(' ').append(userData[i]); - } - } - String note = buffer.toString().trim(); - if (StringUtils.isNotBlank(note)) { - cache.personalNote = note; - } - } - - app.addCacheToSearch(search, cache); - } - - showFinishedMessage(handler, search); - - resetCache(); - } - }); - - // waypoint.time - waypoint.getChild(namespace, "time").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.hidden = parseDate(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse cache date: " + e.toString()); - } - } - }); - - // waypoint.name - waypoint.getChild(namespace, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - name = body; - - final String content = body.trim(); - cache.name = content; - - findGeoCode(cache.name); - findGeoCode(cache.description); - } - }); - - // waypoint.desc - waypoint.getChild(namespace, "desc").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - desc = body; - - cache.shortdesc = validate(body); - } - }); - - // waypoint.cmt - waypoint.getChild(namespace, "cmt").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - cmt = body; - - cache.description = validate(body); - } - }); - - // waypoint.type - waypoint.getChild(namespace, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - final String[] content = body.split("\\|"); - if (content.length > 0) { - type = content[0].toLowerCase().trim(); - } - } - }); - - // waypoint.sym - waypoint.getChild(namespace, "sym").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - body = body.toLowerCase(); - sym = body; - if (body.indexOf("geocache") != -1 && body.indexOf("found") != -1) { - cache.found = true; - } - } - }); - - // waypoint.url - waypoint.getChild(namespace, "url").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String url) { - final Matcher matcher = patternGuid.matcher(url); - if (matcher.matches()) { - String guid = matcher.group(1); - if (StringUtils.isNotBlank(guid)) { - cache.guid = guid; - } - } - } - }); - - // for GPX 1.0, cache info comes from waypoint node (so called private children, - // for GPX 1.1 from extensions node - final Element cacheParent = getCacheParent(waypoint); - - - // GSAK extensions - final Element gsak = cacheParent.getChild(GSAK_NS, "wptExtension"); - gsak.getChild(GSAK_NS, "Watch").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String watchList) { - cache.onWatchlist = Boolean.valueOf(watchList.trim()); - } - }); - - gsak.getChild(GSAK_NS, "UserData").setEndTextElementListener(new UserDataListener(1)); - - for (int i = 2; i <= 4; i++) { - gsak.getChild(GSAK_NS, "User" + i).setEndTextElementListener(new UserDataListener(i)); - } - - // 3 different versions of the GC schema - for (String nsGC : nsGCList) { - // waypoints.cache - final Element gcCache = cacheParent.getChild(nsGC, "cache"); - - gcCache.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - try { - if (attrs.getIndex("id") > -1) { - cache.cacheId = attrs.getValue("id"); - } - if (attrs.getIndex("archived") > -1) { - cache.archived = attrs.getValue("archived").equalsIgnoreCase("true"); - } - if (attrs.getIndex("available") > -1) { - cache.disabled = !attrs.getValue("available").equalsIgnoreCase("true"); - } - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse cache attributes."); - } - } - }); - - // waypoint.cache.name - gcCache.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String cacheName) { - cache.name = validate(cacheName); - } - }); - - // waypoint.cache.owner - gcCache.getChild(nsGC, "owner").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String cacheOwner) { - cache.owner = validate(cacheOwner); - } - }); - - // waypoint.cache.type - gcCache.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - setType(validate(body.toLowerCase())); - } - }); - - // waypoint.cache.container - gcCache.getChild(nsGC, "container").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - cache.size = validate(body.toLowerCase()); - } - }); - - // waypoint.cache.attributes - // @see issue #299 + // map GPX-Attribute-Id to baseName + public static String getBaseName(final int id) { + // get String out of array + if (CACHE_ATTRIBUTES.length <= id) { + return null; + } + final int stringId = CACHE_ATTRIBUTES[id]; + if (stringId == -1) { + return null; // id not found + } + // get text for string + String stringName = null; + try { + stringName = app.getResources().getResourceName(stringId); + } catch (NullPointerException e) { + return null; + } + if (stringName == null) { + return null; + } + // cut out baseName + final Matcher m = BASENAME_PATTERN.matcher(stringName); + if (!m.matches()) { + return null; + } + return m.group(1); + } + + // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes" + public static String getInternalId(final int attributeId, final boolean active) { + final String baseName = CacheAttributeTranslator.getBaseName(attributeId); + if (baseName == null) { + return null; + } + return baseName + (active ? YES : NO); + } + } + + protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) { + app = appIn; + listId = listIdIn; + search = searchIn; + namespace = namespaceIn; + version = versionIn; + } + + private static Date parseDate(String inputUntrimmed) throws ParseException { + final String input = inputUntrimmed.trim(); + if (input.length() >= 3 && input.charAt(input.length() - 3) == ':') { + final String removeColon = input.substring(0, input.length() - 3) + input.substring(input.length() - 2); + return formatTimezone.parse(removeColon); + } + return formatSimple.parse(input); + } + + public UUID parse(final InputStream stream, Handler handlerIn) { + handler = handlerIn; + + final RootElement root = new RootElement(namespace, "gpx"); + final Element waypoint = root.getChild(namespace, "wpt"); + + // waypoint - attributes + waypoint.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + try { + if (attrs.getIndex("lat") > -1 && attrs.getIndex("lon") > -1) { + cache.coords = new Geopoint(new Double(attrs.getValue("lat")), + new Double(attrs.getValue("lon"))); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse waypoint's latitude and/or longitude."); + } + } + }); + + // waypoint + waypoint.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isBlank(cache.geocode)) { + // try to find geocode somewhere else + findGeoCode(name); + findGeoCode(desc); + findGeoCode(cmt); + } + + if (StringUtils.isNotBlank(cache.geocode) + && cache.coords != null + && ((type == null && sym == null) + || (type != null && type.indexOf("geocache") > -1) + || (sym != null && sym.indexOf("geocache") > -1))) { + fixCache(cache); + cache.reason = listId; + cache.detailed = true; + + if (StringUtils.isBlank(cache.personalNote)) { + StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < userData.length; i++) { + if (StringUtils.isNotBlank(userData[i])) { + buffer.append(' ').append(userData[i]); + } + } + String note = buffer.toString().trim(); + if (StringUtils.isNotBlank(note)) { + cache.personalNote = note; + } + } + + app.addCacheToSearch(search, cache); + } + + showFinishedMessage(handler, search); + + resetCache(); + } + }); + + // waypoint.time + waypoint.getChild(namespace, "time").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.hidden = parseDate(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse cache date: " + e.toString()); + } + } + }); + + // waypoint.name + waypoint.getChild(namespace, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + name = body; + + final String content = body.trim(); + cache.name = content; + + findGeoCode(cache.name); + findGeoCode(cache.description); + } + }); + + // waypoint.desc + waypoint.getChild(namespace, "desc").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + desc = body; + + cache.shortdesc = validate(body); + } + }); + + // waypoint.cmt + waypoint.getChild(namespace, "cmt").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + cmt = body; + + cache.description = validate(body); + } + }); + + // waypoint.type + waypoint.getChild(namespace, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + final String[] content = body.split("\\|"); + if (content.length > 0) { + type = content[0].toLowerCase().trim(); + } + } + }); + + // waypoint.sym + waypoint.getChild(namespace, "sym").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + body = body.toLowerCase(); + sym = body; + if (body.indexOf("geocache") != -1 && body.indexOf("found") != -1) { + cache.found = true; + } + } + }); + + // waypoint.url + waypoint.getChild(namespace, "url").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String url) { + final Matcher matcher = patternGuid.matcher(url); + if (matcher.matches()) { + String guid = matcher.group(1); + if (StringUtils.isNotBlank(guid)) { + cache.guid = guid; + } + } + } + }); + + // for GPX 1.0, cache info comes from waypoint node (so called private children, + // for GPX 1.1 from extensions node + final Element cacheParent = getCacheParent(waypoint); + + // GSAK extensions + final Element gsak = cacheParent.getChild(GSAK_NS, "wptExtension"); + gsak.getChild(GSAK_NS, "Watch").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String watchList) { + cache.onWatchlist = Boolean.valueOf(watchList.trim()); + } + }); + + gsak.getChild(GSAK_NS, "UserData").setEndTextElementListener(new UserDataListener(1)); + + for (int i = 2; i <= 4; i++) { + gsak.getChild(GSAK_NS, "User" + i).setEndTextElementListener(new UserDataListener(i)); + } + + // 3 different versions of the GC schema + for (String nsGC : nsGCList) { + // waypoints.cache + final Element gcCache = cacheParent.getChild(nsGC, "cache"); + + gcCache.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + try { + if (attrs.getIndex("id") > -1) { + cache.cacheId = attrs.getValue("id"); + } + if (attrs.getIndex("archived") > -1) { + cache.archived = attrs.getValue("archived").equalsIgnoreCase("true"); + } + if (attrs.getIndex("available") > -1) { + cache.disabled = !attrs.getValue("available").equalsIgnoreCase("true"); + } + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse cache attributes."); + } + } + }); + + // waypoint.cache.name + gcCache.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String cacheName) { + cache.name = validate(cacheName); + } + }); + + // waypoint.cache.owner + gcCache.getChild(nsGC, "owner").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String cacheOwner) { + cache.owner = validate(cacheOwner); + } + }); + + // waypoint.cache.type + gcCache.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + setType(validate(body.toLowerCase())); + } + }); + + // waypoint.cache.container + gcCache.getChild(nsGC, "container").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + cache.size = validate(body.toLowerCase()); + } + }); + + // waypoint.cache.attributes + // @see issue #299 // <groundspeak:attributes> // <groundspeak:attribute id="32" inc="1">Bicycles</groundspeak:attribute> @@ -474,10 +474,10 @@ public abstract class GPXParser extends FileParser { boolean attributeActive = Integer.parseInt(attrs.getValue("inc")) != 0; String internalId = CacheAttributeTranslator.getInternalId(attributeId, attributeActive); if (internalId != null) { - if (cache.attributes == null) { - cache.attributes = new ArrayList<String>(); - } - cache.attributes.add(internalId); + if (cache.attributes == null) { + cache.attributes = new ArrayList<String>(); + } + cache.attributes.add(internalId); } } } catch (NumberFormatException e) { @@ -487,308 +487,308 @@ public abstract class GPXParser extends FileParser { }); // waypoint.cache.difficulty - gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.difficulty = new Float(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse difficulty: " + e.toString()); - } - } - }); - - // waypoint.cache.terrain - gcCache.getChild(nsGC, "terrain").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - cache.terrain = new Float(body); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse terrain: " + e.toString()); - } - } - }); - - // waypoint.cache.country - gcCache.getChild(nsGC, "country").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String country) { - if (StringUtils.isBlank(cache.location)) { - cache.location = validate(country); - } else { - cache.location = cache.location + ", " + country.trim(); - } - } - }); - - // waypoint.cache.state - gcCache.getChild(nsGC, "state").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String state) { - if (StringUtils.isBlank(cache.location)) { - cache.location = validate(state); - } else { - cache.location = state.trim() + ", " + cache.location; - } - } - }); - - // waypoint.cache.encoded_hints - gcCache.getChild(nsGC, "encoded_hints").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String encoded) { - cache.hint = validate(encoded); - } - }); - - gcCache.getChild(nsGC, "short_description").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String shortDesc) { - cache.shortdesc = validate(shortDesc); - } - }); - - gcCache.getChild(nsGC, "long_description").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String desc) { - cache.description = validate(desc); - } - }); - - // waypoint.cache.travelbugs - final Element gcTBs = gcCache.getChild(nsGC, "travelbugs"); - - // waypoint.cache.travelbugs.travelbug - gcTBs.getChild(nsGC, "travelbug").setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - trackable = new cgTrackable(); - - try { - if (attrs.getIndex("ref") > -1) { - trackable.geocode = attrs.getValue("ref").toUpperCase(); - } - } catch (Exception e) { - // nothing - } - } - }); - - // waypoint.cache.travelbug - final Element gcTB = gcTBs.getChild(nsGC, "travelbug"); - - gcTB.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isNotBlank(trackable.geocode) && StringUtils.isNotBlank(trackable.name)) { - if (cache.inventory == null) { - cache.inventory = new ArrayList<cgTrackable>(); - } - cache.inventory.add(trackable); - } - } - }); - - // waypoint.cache.travelbugs.travelbug.name - gcTB.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String tbName) { - trackable.name = validate(tbName); - } - }); - - // waypoint.cache.logs - final Element gcLogs = gcCache.getChild(nsGC, "logs"); - - // waypoint.cache.log - final Element gcLog = gcLogs.getChild(nsGC, "log"); - - gcLog.setStartElementListener(new StartElementListener() { - - @Override - public void start(Attributes attrs) { - log = new cgLog(); - - try { - if (attrs.getIndex("id") > -1) { - log.id = Integer.parseInt(attrs.getValue("id")); - } - } catch (Exception e) { - // nothing - } - } - }); - - gcLog.setEndElementListener(new EndElementListener() { - - @Override - public void end() { - if (StringUtils.isNotBlank(log.log)) { - if (cache.logs == null) { - cache.logs = new ArrayList<cgLog>(); - } - cache.logs.add(log); - } - } - }); - - // waypoint.cache.logs.log.date - gcLog.getChild(nsGC, "date").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - try { - log.date = parseDate(body).getTime(); - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to parse log date: " + e.toString()); - } - } - }); - - // waypoint.cache.logs.log.type - gcLog.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String body) { - final String logType = validate(body).toLowerCase(); - if (cgBase.logTypes0.containsKey(logType)) { - log.type = cgBase.logTypes0.get(logType); - } else { - log.type = cgBase.LOG_NOTE; - } - } - }); - - // waypoint.cache.logs.log.finder - gcLog.getChild(nsGC, "finder").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String finderName) { - log.author = validate(finderName); - } - }); - - // waypoint.cache.logs.log.text - gcLog.getChild(nsGC, "text").setEndTextElementListener(new EndTextElementListener() { - - @Override - public void end(String logText) { - log.log = validate(logText); - } - }); - } - boolean parsed = false; - try { - Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler()); - parsed = true; - } catch (IOException e) { - Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not read file!"); - } catch (SAXException e) { - Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString()); - } - return parsed ? search.getCurrentId() : null; - } - - private UUID parse(final File file, final Handler handlerIn) { - if (file == null) { - return null; - } - - FileInputStream fis = null; - UUID result = null; - try { - fis = new FileInputStream(file); - result = parse(fis, handlerIn); - } catch (FileNotFoundException e) { - Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!"); - } - try { - if (fis != null) { - fis.close(); - } - } catch (IOException e) { - Log.e(cgSettings.tag, "Error after parsing .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not close file!"); - } - return result; - } - - protected abstract Element getCacheParent(Element waypoint); - - protected static String validate(String input) { - if ("nil".equalsIgnoreCase(input)) { - return ""; - } - return input.trim(); - } - - private void setType(String parsedString) { - final String knownType = cgBase.cacheTypes.get(parsedString); - if (knownType != null) { - cache.type = knownType; - } - else { - if (StringUtils.isBlank(cache.type)) { - cache.type = "mystery"; // default for not recognized types - } - } - } - - private void findGeoCode(final String input) { - if (input == null || StringUtils.isNotBlank(cache.geocode)) { - return; - } - final Matcher matcherGeocode = patternGeocode.matcher(input); - if (matcherGeocode.find()) { - if (matcherGeocode.groupCount() > 0) { - final String geocode = matcherGeocode.group(1); - if (ConnectorFactory.canHandle(geocode)) { - cache.geocode = geocode; - } - } - } - } - - private void resetCache() { - type = null; - sym = null; - name = null; - desc = null; - cmt = null; - - cache = new cgCache(); - for (int i = 0; i < userData.length; i++) { - userData[i] = null; - } - } - - public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) { - final cgSearch search = new cgSearch(); - UUID searchId = null; - - try { - GPXParser parser = new GPX10Parser(app, listId, search); - searchId = parser.parse(file, handler); - if (searchId == null) { - parser = new GPX11Parser(app, listId, search); - searchId = parser.parse(file, handler); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString()); - } - - Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId)); - - return search.getCurrentId(); - } + gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.difficulty = new Float(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse difficulty: " + e.toString()); + } + } + }); + + // waypoint.cache.terrain + gcCache.getChild(nsGC, "terrain").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + cache.terrain = new Float(body); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse terrain: " + e.toString()); + } + } + }); + + // waypoint.cache.country + gcCache.getChild(nsGC, "country").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String country) { + if (StringUtils.isBlank(cache.location)) { + cache.location = validate(country); + } else { + cache.location = cache.location + ", " + country.trim(); + } + } + }); + + // waypoint.cache.state + gcCache.getChild(nsGC, "state").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String state) { + if (StringUtils.isBlank(cache.location)) { + cache.location = validate(state); + } else { + cache.location = state.trim() + ", " + cache.location; + } + } + }); + + // waypoint.cache.encoded_hints + gcCache.getChild(nsGC, "encoded_hints").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String encoded) { + cache.hint = validate(encoded); + } + }); + + gcCache.getChild(nsGC, "short_description").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String shortDesc) { + cache.shortdesc = validate(shortDesc); + } + }); + + gcCache.getChild(nsGC, "long_description").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String desc) { + cache.description = validate(desc); + } + }); + + // waypoint.cache.travelbugs + final Element gcTBs = gcCache.getChild(nsGC, "travelbugs"); + + // waypoint.cache.travelbugs.travelbug + gcTBs.getChild(nsGC, "travelbug").setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + trackable = new cgTrackable(); + + try { + if (attrs.getIndex("ref") > -1) { + trackable.geocode = attrs.getValue("ref").toUpperCase(); + } + } catch (Exception e) { + // nothing + } + } + }); + + // waypoint.cache.travelbug + final Element gcTB = gcTBs.getChild(nsGC, "travelbug"); + + gcTB.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isNotBlank(trackable.geocode) && StringUtils.isNotBlank(trackable.name)) { + if (cache.inventory == null) { + cache.inventory = new ArrayList<cgTrackable>(); + } + cache.inventory.add(trackable); + } + } + }); + + // waypoint.cache.travelbugs.travelbug.name + gcTB.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String tbName) { + trackable.name = validate(tbName); + } + }); + + // waypoint.cache.logs + final Element gcLogs = gcCache.getChild(nsGC, "logs"); + + // waypoint.cache.log + final Element gcLog = gcLogs.getChild(nsGC, "log"); + + gcLog.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + log = new cgLog(); + + try { + if (attrs.getIndex("id") > -1) { + log.id = Integer.parseInt(attrs.getValue("id")); + } + } catch (Exception e) { + // nothing + } + } + }); + + gcLog.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (StringUtils.isNotBlank(log.log)) { + if (cache.logs == null) { + cache.logs = new ArrayList<cgLog>(); + } + cache.logs.add(log); + } + } + }); + + // waypoint.cache.logs.log.date + gcLog.getChild(nsGC, "date").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + try { + log.date = parseDate(body).getTime(); + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to parse log date: " + e.toString()); + } + } + }); + + // waypoint.cache.logs.log.type + gcLog.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + final String logType = validate(body).toLowerCase(); + if (cgBase.logTypes0.containsKey(logType)) { + log.type = cgBase.logTypes0.get(logType); + } else { + log.type = cgBase.LOG_NOTE; + } + } + }); + + // waypoint.cache.logs.log.finder + gcLog.getChild(nsGC, "finder").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String finderName) { + log.author = validate(finderName); + } + }); + + // waypoint.cache.logs.log.text + gcLog.getChild(nsGC, "text").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String logText) { + log.log = validate(logText); + } + }); + } + boolean parsed = false; + try { + Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler()); + parsed = true; + } catch (IOException e) { + Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not read file!"); + } catch (SAXException e) { + Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString()); + } + return parsed ? search.getCurrentId() : null; + } + + private UUID parse(final File file, final Handler handlerIn) { + if (file == null) { + return null; + } + + FileInputStream fis = null; + UUID result = null; + try { + fis = new FileInputStream(file); + result = parse(fis, handlerIn); + } catch (FileNotFoundException e) { + Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!"); + } + try { + if (fis != null) { + fis.close(); + } + } catch (IOException e) { + Log.e(cgSettings.tag, "Error after parsing .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not close file!"); + } + return result; + } + + protected abstract Element getCacheParent(Element waypoint); + + protected static String validate(String input) { + if ("nil".equalsIgnoreCase(input)) { + return ""; + } + return input.trim(); + } + + private void setType(String parsedString) { + final String knownType = cgBase.cacheTypes.get(parsedString); + if (knownType != null) { + cache.type = knownType; + } + else { + if (StringUtils.isBlank(cache.type)) { + cache.type = "mystery"; // default for not recognized types + } + } + } + + private void findGeoCode(final String input) { + if (input == null || StringUtils.isNotBlank(cache.geocode)) { + return; + } + final Matcher matcherGeocode = patternGeocode.matcher(input); + if (matcherGeocode.find()) { + if (matcherGeocode.groupCount() > 0) { + final String geocode = matcherGeocode.group(1); + if (ConnectorFactory.canHandle(geocode)) { + cache.geocode = geocode; + } + } + } + } + + private void resetCache() { + type = null; + sym = null; + name = null; + desc = null; + cmt = null; + + cache = new cgCache(); + for (int i = 0; i < userData.length; i++) { + userData[i] = null; + } + } + + public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) { + final cgSearch search = new cgSearch(); + UUID searchId = null; + + try { + GPXParser parser = new GPX10Parser(app, listId, search); + searchId = parser.parse(file, handler); + if (searchId == null) { + parser = new GPX11Parser(app, listId, search); + searchId = parser.parse(file, handler); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString()); + } + + Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId)); + + return search.getCurrentId(); + } } diff --git a/src/cgeo/geocaching/files/LocParser.java b/src/cgeo/geocaching/files/LocParser.java index 076005d..f631e10 100644 --- a/src/cgeo/geocaching/files/LocParser.java +++ b/src/cgeo/geocaching/files/LocParser.java @@ -1,17 +1,5 @@ package cgeo.geocaching.files;
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-
-import android.os.Handler;
-import android.util.Log;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgCacheWrap;
@@ -21,158 +9,171 @@ import cgeo.geocaching.cgSettings; import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
+import org.apache.commons.lang3.StringUtils;
+
+import android.os.Handler;
+import android.util.Log;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public final class LocParser extends FileParser {
- private static final Pattern patternGeocode = Pattern
- .compile("name id=\"([^\"]+)\"");
- private static final Pattern patternLat = Pattern
- .compile("lat=\"([^\"]+)\"");
- private static final Pattern patternLon = Pattern
- .compile("lon=\"([^\"]+)\"");
- // premium only >>
- private static final Pattern patternDifficulty = Pattern
- .compile("<difficulty>([^<]+)</difficulty>");
- private static final Pattern patternTerrain = Pattern
- .compile("<terrain>([^<]+)</terrain>");
- private static final Pattern patternContainer = Pattern
- .compile("<container>([^<]+)</container>");
- private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
-
- public static void parseLoc(final cgCacheWrap caches,
- final String fileContent) {
- final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
-
- // save found cache coordinates
- for (cgCache cache : caches.cacheList) {
- if (cidCoords.containsKey(cache.geocode)) {
- cgCoord coord = cidCoords.get(cache.geocode);
-
- copyCoordToCache(coord, cache);
- }
- }
- }
-
- private static void copyCoordToCache(final cgCoord coord, final cgCache cache) {
- cache.coords = coord.coords;
- cache.difficulty = coord.difficulty;
- cache.terrain = coord.terrain;
- cache.size = coord.size;
- cache.geocode = coord.geocode.toUpperCase();
- if (StringUtils.isBlank(cache.name)) {
- cache.name = coord.name;
- }
- }
-
- private static Map<String, cgCoord> parseCoordinates(
- final String fileContent) {
- final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
- if (StringUtils.isBlank(fileContent)) {
- return coords;
- }
- // >> premium only
-
- final String[] points = fileContent.split("<waypoint>");
-
- // parse coordinates
- for (String pointString : points) {
- final cgCoord pointCoord = new cgCoord();
-
- final Matcher matcherGeocode = patternGeocode.matcher(pointString);
- if (matcherGeocode.find()) {
- String geocode = matcherGeocode.group(1).trim().toUpperCase();
- pointCoord.name = geocode;
- pointCoord.geocode = geocode;
- }
- final Matcher matcherName = patternName.matcher(pointString);
- if (matcherName.find()) {
- String name = matcherName.group(1).trim();
- int pos = name.indexOf(" by ");
- if (pos > 0) {
- name = name.substring(0, pos).trim();
- }
- pointCoord.name = name;
- }
- final Matcher matcherLat = patternLat.matcher(pointString);
- final Matcher matcherLon = patternLon.matcher(pointString);
- if (matcherLat.find() && matcherLon.find()) {
- final Map<String, Object>tmpLat = cgBase.parseCoordinate(matcherLat.group(1).trim(), "lat");
- final Map<String, Object> tmpLon = cgBase.parseCoordinate(matcherLon.group(1).trim(), "lon");
- pointCoord.coords = new Geopoint((Double) tmpLat.get("coordinate"),
- (Double) tmpLon.get("coordinate"));
- }
- final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
- if (matcherDifficulty.find()) {
- pointCoord.difficulty = new Float(matcherDifficulty.group(1)
- .trim());
- }
- final Matcher matcherTerrain = patternTerrain.matcher(pointString);
- if (matcherTerrain.find()) {
- pointCoord.terrain = new Float(matcherTerrain.group(1).trim());
- }
- final Matcher matcherContainer = patternContainer.matcher(pointString);
- if (matcherContainer.find()) {
- final int size = Integer.parseInt(matcherContainer.group(1)
- .trim());
-
- if (size == 1) {
- pointCoord.size = "not chosen";
- } else if (size == 2) {
- pointCoord.size = "micro";
- } else if (size == 3) {
- pointCoord.size = "regular";
- } else if (size == 4) {
- pointCoord.size = "large";
- } else if (size == 5) {
- pointCoord.size = "virtual";
- } else if (size == 6) {
- pointCoord.size = "other";
- } else if (size == 8) {
- pointCoord.size = "small";
- } else {
- pointCoord.size = "unknown";
- }
- }
-
- if (StringUtils.isNotBlank(pointCoord.geocode)) {
- coords.put(pointCoord.geocode, pointCoord);
- }
- }
-
- Log.i(cgSettings.tag,
- "Coordinates found in .loc file: " + coords.size());
- return coords;
- }
-
- public static UUID parseLoc(cgeoapplication app, File file, int listId,
- Handler handler) {
- cgSearch search = new cgSearch();
- UUID searchId = null;
-
- try {
- Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
- final cgCacheWrap caches = new cgCacheWrap();
- for (Entry<String, cgCoord> entry : coords.entrySet()) {
- cgCoord coord = entry.getValue();
- if (StringUtils.isBlank(coord.geocode) || StringUtils.isBlank(coord.name)) {
- continue;
- }
- cgCache cache = new cgCache();
- copyCoordToCache(coord, cache);
- caches.cacheList.add(cache);
-
- fixCache(cache);
- cache.reason = listId;
- cache.detailed = false;
-
- app.addCacheToSearch(search, cache);
- }
- caches.totalCnt = caches.cacheList.size();
- showFinishedMessage(handler, search);
- } catch (Exception e) {
- Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString());
- }
-
- Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId));
-
- return search.getCurrentId();
- }
+ private static final Pattern patternGeocode = Pattern
+ .compile("name id=\"([^\"]+)\"");
+ private static final Pattern patternLat = Pattern
+ .compile("lat=\"([^\"]+)\"");
+ private static final Pattern patternLon = Pattern
+ .compile("lon=\"([^\"]+)\"");
+ // premium only >>
+ private static final Pattern patternDifficulty = Pattern
+ .compile("<difficulty>([^<]+)</difficulty>");
+ private static final Pattern patternTerrain = Pattern
+ .compile("<terrain>([^<]+)</terrain>");
+ private static final Pattern patternContainer = Pattern
+ .compile("<container>([^<]+)</container>");
+ private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
+
+ public static void parseLoc(final cgCacheWrap caches,
+ final String fileContent) {
+ final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
+
+ // save found cache coordinates
+ for (cgCache cache : caches.cacheList) {
+ if (cidCoords.containsKey(cache.geocode)) {
+ cgCoord coord = cidCoords.get(cache.geocode);
+
+ copyCoordToCache(coord, cache);
+ }
+ }
+ }
+
+ private static void copyCoordToCache(final cgCoord coord, final cgCache cache) {
+ cache.coords = coord.coords;
+ cache.difficulty = coord.difficulty;
+ cache.terrain = coord.terrain;
+ cache.size = coord.size;
+ cache.geocode = coord.geocode.toUpperCase();
+ if (StringUtils.isBlank(cache.name)) {
+ cache.name = coord.name;
+ }
+ }
+
+ private static Map<String, cgCoord> parseCoordinates(
+ final String fileContent) {
+ final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
+ if (StringUtils.isBlank(fileContent)) {
+ return coords;
+ }
+ // >> premium only
+
+ final String[] points = fileContent.split("<waypoint>");
+
+ // parse coordinates
+ for (String pointString : points) {
+ final cgCoord pointCoord = new cgCoord();
+
+ final Matcher matcherGeocode = patternGeocode.matcher(pointString);
+ if (matcherGeocode.find()) {
+ String geocode = matcherGeocode.group(1).trim().toUpperCase();
+ pointCoord.name = geocode;
+ pointCoord.geocode = geocode;
+ }
+ final Matcher matcherName = patternName.matcher(pointString);
+ if (matcherName.find()) {
+ String name = matcherName.group(1).trim();
+ int pos = name.indexOf(" by ");
+ if (pos > 0) {
+ name = name.substring(0, pos).trim();
+ }
+ pointCoord.name = name;
+ }
+ final Matcher matcherLat = patternLat.matcher(pointString);
+ final Matcher matcherLon = patternLon.matcher(pointString);
+ if (matcherLat.find() && matcherLon.find()) {
+ final Map<String, Object> tmpLat = cgBase.parseCoordinate(matcherLat.group(1).trim(), "lat");
+ final Map<String, Object> tmpLon = cgBase.parseCoordinate(matcherLon.group(1).trim(), "lon");
+ pointCoord.coords = new Geopoint((Double) tmpLat.get("coordinate"),
+ (Double) tmpLon.get("coordinate"));
+ }
+ final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
+ if (matcherDifficulty.find()) {
+ pointCoord.difficulty = new Float(matcherDifficulty.group(1)
+ .trim());
+ }
+ final Matcher matcherTerrain = patternTerrain.matcher(pointString);
+ if (matcherTerrain.find()) {
+ pointCoord.terrain = new Float(matcherTerrain.group(1).trim());
+ }
+ final Matcher matcherContainer = patternContainer.matcher(pointString);
+ if (matcherContainer.find()) {
+ final int size = Integer.parseInt(matcherContainer.group(1)
+ .trim());
+
+ if (size == 1) {
+ pointCoord.size = "not chosen";
+ } else if (size == 2) {
+ pointCoord.size = "micro";
+ } else if (size == 3) {
+ pointCoord.size = "regular";
+ } else if (size == 4) {
+ pointCoord.size = "large";
+ } else if (size == 5) {
+ pointCoord.size = "virtual";
+ } else if (size == 6) {
+ pointCoord.size = "other";
+ } else if (size == 8) {
+ pointCoord.size = "small";
+ } else {
+ pointCoord.size = "unknown";
+ }
+ }
+
+ if (StringUtils.isNotBlank(pointCoord.geocode)) {
+ coords.put(pointCoord.geocode, pointCoord);
+ }
+ }
+
+ Log.i(cgSettings.tag,
+ "Coordinates found in .loc file: " + coords.size());
+ return coords;
+ }
+
+ public static UUID parseLoc(cgeoapplication app, File file, int listId,
+ Handler handler) {
+ cgSearch search = new cgSearch();
+ UUID searchId = null;
+
+ try {
+ Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
+ final cgCacheWrap caches = new cgCacheWrap();
+ for (Entry<String, cgCoord> entry : coords.entrySet()) {
+ cgCoord coord = entry.getValue();
+ if (StringUtils.isBlank(coord.geocode) || StringUtils.isBlank(coord.name)) {
+ continue;
+ }
+ cgCache cache = new cgCache();
+ copyCoordToCache(coord, cache);
+ caches.cacheList.add(cache);
+
+ fixCache(cache);
+ cache.reason = listId;
+ cache.detailed = false;
+
+ app.addCacheToSearch(search, cache);
+ }
+ caches.totalCnt = caches.cacheList.size();
+ showFinishedMessage(handler, search);
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString());
+ }
+
+ Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId));
+
+ return search.getCurrentId();
+ }
}
diff --git a/src/cgeo/geocaching/filter/cgFilter.java b/src/cgeo/geocaching/filter/cgFilter.java index 4dc0d99..36463ba 100644 --- a/src/cgeo/geocaching/filter/cgFilter.java +++ b/src/cgeo/geocaching/filter/cgFilter.java @@ -1,30 +1,30 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.cgCache; + import java.util.ArrayList; import java.util.List; -import cgeo.geocaching.cgCache; - public abstract class cgFilter { String name; - + public cgFilter(String name) { this.name = name; } - - abstract boolean applyFilter(cgCache cache); - - public void filter(List<cgCache> list){ - List<cgCache> itemsToRemove = new ArrayList<cgCache>(); - for(cgCache item : list){ - if(!applyFilter(item)){ - itemsToRemove.add(item); - } - } - list.removeAll(itemsToRemove); - } - - public String getFilterName() { - return name; - } + + abstract boolean applyFilter(cgCache cache); + + public void filter(List<cgCache> list) { + List<cgCache> itemsToRemove = new ArrayList<cgCache>(); + for (cgCache item : list) { + if (!applyFilter(item)) { + itemsToRemove.add(item); + } + } + list.removeAll(itemsToRemove); + } + + public String getFilterName() { + return name; + } } diff --git a/src/cgeo/geocaching/filter/cgFilterBySize.java b/src/cgeo/geocaching/filter/cgFilterBySize.java index 34aff6f..818410e 100644 --- a/src/cgeo/geocaching/filter/cgFilterBySize.java +++ b/src/cgeo/geocaching/filter/cgFilterBySize.java @@ -3,12 +3,12 @@ package cgeo.geocaching.filter; import cgeo.geocaching.cgCache; public class cgFilterBySize extends cgFilter { - public cgFilterBySize(String size) { + public cgFilterBySize(String size) { super(size); } @Override - boolean applyFilter(cgCache cache) { - return name.equals(cache.size); - } + boolean applyFilter(cgCache cache) { + return name.equals(cache.size); + } } diff --git a/src/cgeo/geocaching/filter/cgFilterByTrackables.java b/src/cgeo/geocaching/filter/cgFilterByTrackables.java index 0866ff5..90cae99 100644 --- a/src/cgeo/geocaching/filter/cgFilterByTrackables.java +++ b/src/cgeo/geocaching/filter/cgFilterByTrackables.java @@ -3,12 +3,12 @@ package cgeo.geocaching.filter; import cgeo.geocaching.cgCache; public class cgFilterByTrackables extends cgFilter { - public cgFilterByTrackables(String name) { + public cgFilterByTrackables(String name) { super(name); } @Override - boolean applyFilter(cgCache cache) { - return cache.hasTrackables(); - } + boolean applyFilter(cgCache cache) { + return cache.hasTrackables(); + } } diff --git a/src/cgeo/geocaching/filter/cgFilterByType.java b/src/cgeo/geocaching/filter/cgFilterByType.java index 83216f3..57607a5 100644 --- a/src/cgeo/geocaching/filter/cgFilterByType.java +++ b/src/cgeo/geocaching/filter/cgFilterByType.java @@ -4,17 +4,17 @@ import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; public class cgFilterByType extends cgFilter { - public cgFilterByType(String type){ - super(type); - } + public cgFilterByType(String type) { + super(type); + } - @Override - boolean applyFilter(cgCache cache) { - return name.equals(cache.type); - } - - @Override - public String getFilterName() { - return cgBase.cacheTypesInv.get(name); - } + @Override + boolean applyFilter(cgCache cache) { + return name.equals(cache.type); + } + + @Override + public String getFilterName() { + return cgBase.cacheTypesInv.get(name); + } } diff --git a/src/cgeo/geocaching/geopoint/DistanceParser.java b/src/cgeo/geocaching/geopoint/DistanceParser.java index a5b3d7b..89fe53b 100644 --- a/src/cgeo/geocaching/geopoint/DistanceParser.java +++ b/src/cgeo/geocaching/geopoint/DistanceParser.java @@ -1,11 +1,11 @@ package cgeo.geocaching.geopoint; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import cgeo.geocaching.cgBase; import cgeo.geocaching.cgSettings; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public final class DistanceParser { private static final Pattern pattern = Pattern.compile("^([0-9\\.\\,]+)[ ]*(m|km|ft|yd|mi|)?$", Pattern.CASE_INSENSITIVE); @@ -13,11 +13,13 @@ public final class DistanceParser { /** * Parse a distance string composed by a number and an optional suffix * (such as "1.2km"). - * - * @param distanceText the string to analyze + * + * @param distanceText + * the string to analyze * @return the distance in kilometers - * - * @throws NumberFormatException if the given number is invalid + * + * @throws NumberFormatException + * if the given number is invalid */ public static float parseDistance(String distanceText, final int defaultUnit) { final Matcher matcher = pattern.matcher(distanceText); diff --git a/src/cgeo/geocaching/geopoint/Geopoint.java b/src/cgeo/geocaching/geopoint/Geopoint.java index a25f827..083adbf 100644 --- a/src/cgeo/geocaching/geopoint/Geopoint.java +++ b/src/cgeo/geocaching/geopoint/Geopoint.java @@ -7,250 +7,268 @@ import android.location.Location; */ public final class Geopoint { - public static final double deg2rad = Math.PI / 180; - public static final double rad2deg = 180 / Math.PI; - public static final float erad = 6371.0f; + public static final double deg2rad = Math.PI / 180; + public static final double rad2deg = 180 / Math.PI; + public static final float erad = 6371.0f; - private final double latitude; - private final double longitude; + private final double latitude; + private final double longitude; - /** - * Creates new Geopoint with given latitude and longitude (both degree). - * - * @param lat latitude - * @param lon longitude - */ - public Geopoint(final double lat, final double lon) - { - if (lat <= 90 && lat >= -90) { - latitude = lat; - } else { - throw new MalformedCoordinateException("malformed latitude: " + lat); - } - if (lon <= 180 && lon >=-180) { - longitude = lon; - } else { - throw new MalformedCoordinateException("malformed longitude: " + lon); - } - } + /** + * Creates new Geopoint with given latitude and longitude (both degree). + * + * @param lat + * latitude + * @param lon + * longitude + */ + public Geopoint(final double lat, final double lon) + { + if (lat <= 90 && lat >= -90) { + latitude = lat; + } else { + throw new MalformedCoordinateException("malformed latitude: " + lat); + } + if (lon <= 180 && lon >= -180) { + longitude = lon; + } else { + throw new MalformedCoordinateException("malformed longitude: " + lon); + } + } - /** - * Creates new Geopoint with given latitude and longitude (both microdegree). - * - * @param lat latitude - * @param lon longitude - */ - public Geopoint(final int lat, final int lon) - { - this(lat / 1e6, lon / 1e6); - } + /** + * Creates new Geopoint with given latitude and longitude (both microdegree). + * + * @param lat + * latitude + * @param lon + * longitude + */ + public Geopoint(final int lat, final int lon) + { + this(lat / 1e6, lon / 1e6); + } - /** - * Creates new Geopoint with latitude and longitude parsed from string. - * - * @param text string to parse - * @see GeopointParser.parse() - */ - public Geopoint(final String text) - { - this(GeopointParser.parseLatitude(text), GeopointParser.parseLongitude(text)); - } + /** + * Creates new Geopoint with latitude and longitude parsed from string. + * + * @param text + * string to parse + * @see GeopointParser.parse() + */ + public Geopoint(final String text) + { + this(GeopointParser.parseLatitude(text), GeopointParser.parseLongitude(text)); + } - /** - * Creates new Geopoint with given Location. - * - * @param gp the Location to clone - */ - public Geopoint(final Location loc) { - this(loc.getLatitude(), loc.getLongitude()); - } + /** + * Creates new Geopoint with given Location. + * + * @param gp + * the Location to clone + */ + public Geopoint(final Location loc) { + this(loc.getLatitude(), loc.getLongitude()); + } - /** - * Get latitude in degree. - * - * @return latitude - */ - public double getLatitude() - { - return latitude; - } + /** + * Get latitude in degree. + * + * @return latitude + */ + public double getLatitude() + { + return latitude; + } - /** - * Get latitude in microdegree. - * - * @return latitude - */ - public int getLatitudeE6() - { - return (int) (latitude * 1E6); - } + /** + * Get latitude in microdegree. + * + * @return latitude + */ + public int getLatitudeE6() + { + return (int) (latitude * 1E6); + } - /** - * Get longitude in degree. - * - * @return longitude - */ - public double getLongitude() - { - return longitude; - } + /** + * Get longitude in degree. + * + * @return longitude + */ + public double getLongitude() + { + return longitude; + } - /** - * Get longitude in microdegree. - * - * @return longitude - */ - public int getLongitudeE6() - { - return (int) (longitude * 1E6); - } + /** + * Get longitude in microdegree. + * + * @return longitude + */ + public int getLongitudeE6() + { + return (int) (longitude * 1E6); + } - /** - * Get distance and bearing from the current point to a target. - * - * @param target The target - * @return An array of floats: the distance in meters, then the bearing in degrees - */ - private float[] pathTo(final Geopoint target) { - float[] results = new float[2]; - android.location.Location.distanceBetween(getLatitude(), getLongitude(), target.getLatitude(), target.getLongitude(), results); - return results; - } + /** + * Get distance and bearing from the current point to a target. + * + * @param target + * The target + * @return An array of floats: the distance in meters, then the bearing in degrees + */ + private float[] pathTo(final Geopoint target) { + float[] results = new float[2]; + android.location.Location.distanceBetween(getLatitude(), getLongitude(), target.getLatitude(), target.getLongitude(), results); + return results; + } - /** - * Calculates distance to given Geopoint in km. - * - * @param gp target - * @return distance in km - * @throws GeopointException if there is an error in distance calculation - */ - public float distanceTo(final Geopoint gp) - { - return pathTo(gp)[0] / 1000; - } + /** + * Calculates distance to given Geopoint in km. + * + * @param gp + * target + * @return distance in km + * @throws GeopointException + * if there is an error in distance calculation + */ + public float distanceTo(final Geopoint gp) + { + return pathTo(gp)[0] / 1000; + } - /** - * Calculates bearing to given Geopoint in degree. - * - * @param gp target - * @return bearing in degree, in the [0,360[ range - */ - public float bearingTo(final Geopoint gp) - { - // Android library returns a bearing in the [-180;180] range - final float bearing = pathTo(gp)[1]; - return bearing < 0 ? bearing + 360 : bearing; - } + /** + * Calculates bearing to given Geopoint in degree. + * + * @param gp + * target + * @return bearing in degree, in the [0,360[ range + */ + public float bearingTo(final Geopoint gp) + { + // Android library returns a bearing in the [-180;180] range + final float bearing = pathTo(gp)[1]; + return bearing < 0 ? bearing + 360 : bearing; + } - /** - * Calculates geopoint from given bearing and distance. - * - * @param bearing bearing in degree - * @param distance distance in km - * @return the projected geopoint - */ - public Geopoint project(final double bearing, final double distance) - { - final double rlat1 = latitude * deg2rad; - final double rlon1 = longitude * deg2rad; - final double rbearing = bearing * deg2rad; - final double rdistance = distance / erad; + /** + * Calculates geopoint from given bearing and distance. + * + * @param bearing + * bearing in degree + * @param distance + * distance in km + * @return the projected geopoint + */ + public Geopoint project(final double bearing, final double distance) + { + final double rlat1 = latitude * deg2rad; + final double rlon1 = longitude * deg2rad; + final double rbearing = bearing * deg2rad; + final double rdistance = distance / erad; - final double rlat = Math.asin(Math.sin(rlat1) * Math.cos(rdistance) + Math.cos(rlat1) * Math.sin(rdistance) * Math.cos(rbearing)); - final double rlon = rlon1 + Math.atan2(Math.sin(rbearing) * Math.sin(rdistance) * Math.cos(rlat1), Math.cos(rdistance) - Math.sin(rlat1) * Math.sin(rlat)); + final double rlat = Math.asin(Math.sin(rlat1) * Math.cos(rdistance) + Math.cos(rlat1) * Math.sin(rdistance) * Math.cos(rbearing)); + final double rlon = rlon1 + Math.atan2(Math.sin(rbearing) * Math.sin(rdistance) * Math.cos(rlat1), Math.cos(rdistance) - Math.sin(rlat1) * Math.sin(rlat)); - return new Geopoint(rlat * rad2deg, rlon * rad2deg); - } + return new Geopoint(rlat * rad2deg, rlon * rad2deg); + } - /** - * Checks if given Geopoint is identical with this Geopoint. - * - * @param gp Geopoint to check - * @return true if identical, false otherwise - */ - public boolean isEqualTo(Geopoint gp) - { - return null != gp && gp.getLatitude() == latitude && gp.getLongitude() == longitude; - } + /** + * Checks if given Geopoint is identical with this Geopoint. + * + * @param gp + * Geopoint to check + * @return true if identical, false otherwise + */ + public boolean isEqualTo(Geopoint gp) + { + return null != gp && gp.getLatitude() == latitude && gp.getLongitude() == longitude; + } - /** - * Checks if given Geopoint is similar to this Geopoint with tolerance. - * - * @param gp Geopoint to check - * @param tolerance tolerance in km - * @return true if similar, false otherwise - */ - public boolean isEqualTo(Geopoint gp, double tolerance) - { - return null != gp && distanceTo(gp) <= tolerance; - } + /** + * Checks if given Geopoint is similar to this Geopoint with tolerance. + * + * @param gp + * Geopoint to check + * @param tolerance + * tolerance in km + * @return true if similar, false otherwise + */ + public boolean isEqualTo(Geopoint gp, double tolerance) + { + return null != gp && distanceTo(gp) <= tolerance; + } - /** - * Returns formatted coordinates. - * - * @param format the desired format - * @see GeopointFormatter - * @return formatted coordinates - */ - public String format(GeopointFormatter format) - { - return format.format(this); - } + /** + * Returns formatted coordinates. + * + * @param format + * the desired format + * @see GeopointFormatter + * @return formatted coordinates + */ + public String format(GeopointFormatter format) + { + return format.format(this); + } - /** - * Returns formatted coordinates. - * - * @param format the desired format - * @see GeopointFormatter - * @return formatted coordinates - */ - public String format(String format) - { - return GeopointFormatter.format(format, this); - } + /** + * Returns formatted coordinates. + * + * @param format + * the desired format + * @see GeopointFormatter + * @return formatted coordinates + */ + public String format(String format) + { + return GeopointFormatter.format(format, this); + } - /** - * Returns formatted coordinates. - * - * @param format the desired format - * @see GeopointFormatter - * @return formatted coordinates - */ - public String format(GeopointFormatter.Format format) - { - return GeopointFormatter.format(format, this); - } + /** + * Returns formatted coordinates. + * + * @param format + * the desired format + * @see GeopointFormatter + * @return formatted coordinates + */ + public String format(GeopointFormatter.Format format) + { + return GeopointFormatter.format(format, this); + } - /** - * Returns formatted coordinates with default format. - * Default format is decimalminutes, e.g. N 52° 36.123 E 010° 03.456 - * - * @return formatted coordinates - */ - public String toString() - { - return format(GeopointFormatter.Format.LAT_LON_DECMINUTE); - } + /** + * Returns formatted coordinates with default format. + * Default format is decimalminutes, e.g. N 52° 36.123 E 010° 03.456 + * + * @return formatted coordinates + */ + public String toString() + { + return format(GeopointFormatter.Format.LAT_LON_DECMINUTE); + } - public static class GeopointException - extends RuntimeException - { - private static final long serialVersionUID = 1L; + public static class GeopointException + extends RuntimeException + { + private static final long serialVersionUID = 1L; - public GeopointException(String msg) - { - super(msg); - } - } + public GeopointException(String msg) + { + super(msg); + } + } - public static class MalformedCoordinateException - extends GeopointException - { - private static final long serialVersionUID = 1L; + public static class MalformedCoordinateException + extends GeopointException + { + private static final long serialVersionUID = 1L; - public MalformedCoordinateException(String msg) - { - super(msg); - } - } + public MalformedCoordinateException(String msg) + { + super(msg); + } + } } diff --git a/src/cgeo/geocaching/geopoint/GeopointFormatter.java b/src/cgeo/geocaching/geopoint/GeopointFormatter.java index 9ca361a..a35bf5f 100644 --- a/src/cgeo/geocaching/geopoint/GeopointFormatter.java +++ b/src/cgeo/geocaching/geopoint/GeopointFormatter.java @@ -18,15 +18,15 @@ public class GeopointFormatter */ public enum Format { - LAT_LON_DECDEGREE ("%y6d %x6d"), - LAT_LON_DECMINUTE ("%yn %yd° %y3m %xn %xd° %x3m"), - LAT_LON_DECSECOND ("%yn %yd° %ym' %ys\" %xn %xd° %xm' %xs\""), - LAT_DECDEGREE ("%y6d"), - LAT_DECMINUTE ("%yn %yd° %y3m"), - LAT_DECSECOND ("%yn %yd° %ym' %ys\""), - LON_DECDEGREE ("%x6d"), - LON_DECMINUTE ("%xn %xd° %x3m"), - LON_DECSECOND ("%xn %xd° %xm' %xs\""); + LAT_LON_DECDEGREE("%y6d %x6d"), + LAT_LON_DECMINUTE("%yn %yd° %y3m %xn %xd° %x3m"), + LAT_LON_DECSECOND("%yn %yd° %ym' %ys\" %xn %xd° %xm' %xs\""), + LAT_DECDEGREE("%y6d"), + LAT_DECMINUTE("%yn %yd° %y3m"), + LAT_DECSECOND("%yn %yd° %ym' %ys\""), + LON_DECDEGREE("%x6d"), + LON_DECMINUTE("%xn %xd° %x3m"), + LON_DECSECOND("%xn %xd° %xm' %xs\""); private final String format; @@ -43,8 +43,9 @@ public class GeopointFormatter /** * Creates a new formatter with given format-string. - * - * @param format the format-string + * + * @param format + * the format-string * @see format() */ public GeopointFormatter(final String format) @@ -55,42 +56,45 @@ public class GeopointFormatter /** * Creates a new formatter with given default-format. - * - * @param format one of the default formats + * + * @param format + * one of the default formats * @see GeopointFormatter.Format */ public GeopointFormatter(final Format format) { - enumFormat = format; + enumFormat = format; this.format = format.toString(); } /** * Formats a Geopoint. - * + * * Syntax: - * %[dir][precision][value] - * - * [dir] - * y = latitude - * x = longitude - * - * [precision] (optional) - * 0..9, number of digits after the decimal point - * - * [value] - * n = direction - * d = degree - * m = minute - * s = second - * + * %[dir][precision][value] + * + * [dir] + * y = latitude + * x = longitude + * + * [precision] (optional) + * 0..9, number of digits after the decimal point + * + * [value] + * n = direction + * d = degree + * m = minute + * s = second + * * Example: - * "%yn %yd° %y3m" = "N 52° 36.123" - * + * "%yn %yd° %y3m" = "N 52° 36.123" + * * All other characters are not interpreted and can be used. - * - * @param gp the Geopoint to format - * @param format the format-string with syntax from above + * + * @param gp + * the Geopoint to format + * @param format + * the format-string with syntax from above * @return the formatted coordinates */ public static String format(final String format, final Geopoint gp) @@ -149,9 +153,11 @@ public class GeopointFormatter /** * Formats a Geopoint. - * - * @param gp the Geopoint to format - * @param format one of the default formats + * + * @param gp + * the Geopoint to format + * @param format + * one of the default formats * @see cgeo.geocaching.GeopointFormatter.Format * @return the formatted coordinates */ @@ -159,23 +165,23 @@ public class GeopointFormatter { // Don't parse often used formats - switch(format) + switch (format) { case LAT_LON_DECDEGREE: return String.format("%.6f %.6f", gp.getLatitude(), gp.getLongitude()); case LAT_LON_DECMINUTE: - final double lat = Math.abs(gp.getLatitude()); - final double lon = Math.abs(gp.getLongitude()); + final double lat = Math.abs(gp.getLatitude()); + final double lon = Math.abs(gp.getLongitude()); final boolean latPos = (gp.getLatitude() < 0); final boolean lonPos = (gp.getLongitude() < 0); return String.format("%s %02.0f° %.3f %s %03.0f° %.3f", (latPos) ? "S" : "N", - Math.floor(lat), - (lat - Math.floor(lat)) * 60, - (lonPos) ? "W" : "E", - Math.floor(lon), - (lon - Math.floor(lon)) * 60); + Math.floor(lat), + (lat - Math.floor(lat)) * 60, + (lonPos) ? "W" : "E", + Math.floor(lon), + (lon - Math.floor(lon)) * 60); default: return format(format.toString(), gp); @@ -184,25 +190,26 @@ public class GeopointFormatter /** * Formats a Geopoint with the format of this instance. - * - * @param gp the Geopoint to format + * + * @param gp + * the Geopoint to format * @return the formatted coordinates of the Geopoint */ public String format(final Geopoint gp) { if (null == enumFormat) { - return format(format, gp); + return format(format, gp); } else { - return format( enumFormat, gp); + return format(enumFormat, gp); } } /** * Returns the format of this instance. - * + * * @return the format of this instance. */ public String toString() diff --git a/src/cgeo/geocaching/geopoint/GeopointParser.java b/src/cgeo/geocaching/geopoint/GeopointParser.java index e250459..e351701 100644 --- a/src/cgeo/geocaching/geopoint/GeopointParser.java +++ b/src/cgeo/geocaching/geopoint/GeopointParser.java @@ -1,10 +1,10 @@ package cgeo.geocaching.geopoint; +import cgeo.geocaching.geopoint.Geopoint.GeopointException; + import java.util.regex.Matcher; import java.util.regex.Pattern; -import cgeo.geocaching.geopoint.Geopoint.GeopointException; - /** * Parse coordinates. */ @@ -19,35 +19,38 @@ public class GeopointParser LAT, LON } - + /** * Parses a pair of coordinates (latitude and longitude) out of a String. * Accepts following formats and combinations of it: - * X DD - * X DD° - * X DD° MM - * X DD° MM.MMM - * X DD° MM SS - * + * X DD + * X DD° + * X DD° MM + * X DD° MM.MMM + * X DD° MM SS + * * as well as: - * DD.DDDDDDD - * + * DD.DDDDDDD + * * Both . and , are accepted, also variable count of spaces (also 0) - * - * @param text the string to parse + * + * @param text + * the string to parse * @return an Geopoint with parsed latitude and longitude - * @throws ParseException if lat or lon could not be parsed + * @throws ParseException + * if lat or lon could not be parsed */ public static Geopoint parse(final String text) { - + double lat = parseLatitude(text); double lon = parseLongitude(text); - + return new Geopoint(lat, lon); } - - /* (non JavaDoc) + + /* + * (non JavaDoc) * Helper for coordinates-parsing. */ private static double parseHelper(final String text, final LatLon latlon) @@ -66,22 +69,22 @@ public class GeopointParser if (matcher.find()) { - int sign = 1; - int degree = 0; - int minutes = 0; - int seconds = 0; - + int sign = 1; + int degree = 0; + int minutes = 0; + int seconds = 0; + if (matcher.group(1).equalsIgnoreCase("S") || matcher.group(1).equalsIgnoreCase("W")) { sign = -1; } - + degree = Integer.parseInt(matcher.group(2)); - + if (null != matcher.group(4)) { minutes = Integer.parseInt(matcher.group(4)); - + if (null != matcher.group(6)) { seconds = Math.round(Float.parseFloat("0." + matcher.group(6)) * 60); @@ -91,7 +94,7 @@ public class GeopointParser seconds = Integer.parseInt(matcher.group(7)); } } - + return (double) sign * ((double) degree + (double) minutes / 60 + (double) seconds / 3600); } else // Nothing found with "N 52...", try to match string as decimaldegree @@ -110,17 +113,19 @@ public class GeopointParser } } } - + throw new ParseException("Could not parse coordinates as " + latlon + ": \"" + text + "\""); } /** * Parses latitude out of a given string. - * + * * @see parse() - * @param text the string to be parsed + * @param text + * the string to be parsed * @return the latitude as decimaldegree - * @throws ParseException if latitude could not be parsed + * @throws ParseException + * if latitude could not be parsed */ public static double parseLatitude(final String text) { @@ -129,22 +134,24 @@ public class GeopointParser /** * Parses longitude out of a given string. - * + * * @see parse() - * @param text the string to be parsed + * @param text + * the string to be parsed * @return the longitude as decimaldegree - * @throws ParseException if longitude could not be parsed + * @throws ParseException + * if longitude could not be parsed */ public static double parseLongitude(final String text) { return parseHelper(text, LatLon.LON); } - + public static class ParseException - extends GeopointException + extends GeopointException { private static final long serialVersionUID = 1L; - + public ParseException(String msg) { super(msg); diff --git a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java index 02e8c04..aed2d34 100644 --- a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java @@ -1,12 +1,5 @@ package cgeo.geocaching.googlemaps; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.drawable.Drawable; import cgeo.geocaching.cgSettings; import cgeo.geocaching.mapcommon.cgMapOverlay; import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; @@ -16,99 +9,108 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapView; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.drawable.Drawable; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + /** * Google specific implementation of the itemized cache overlay + * * @author rsudev - * + * */ public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem> implements ItemizedOverlayImpl { - private cgMapOverlay base; - private Lock lock = new ReentrantLock(); - - public googleCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { - super(boundCenterBottom(markerIn)); - base = new cgMapOverlay(settingsIn, this, contextIn, fromDetailIn); - } - - @Override - public cgMapOverlay getBase() { - return base; - } - - @Override - protected googleCacheOverlayItem createItem(int i) { - if (base == null) - return null; - - return (googleCacheOverlayItem) base.createItem(i); - } - - @Override - public int size() { - if (base == null) - return 0; - - return base.size(); - } - - @Override - protected boolean onTap(int arg0) { - if (base == null) - return false; - - return base.onTap(arg0); - } - - @Override - public void draw(Canvas canvas, MapView mapView, boolean shadow) { - base.draw(canvas, (MapViewImpl) mapView, shadow); - } - - @Override - public void superPopulate() { - populate(); - } - - @Override - public Drawable superBoundCenter(Drawable markerIn) { - return super.boundCenter(markerIn); - } - - @Override - public Drawable superBoundCenterBottom(Drawable marker) { - return super.boundCenterBottom(marker); - } - - @Override - public void superSetLastFocusedItemIndex(int i) { - super.setLastFocusedIndex(i); - } - - @Override - public boolean superOnTap(int index) { - return super.onTap(index); - } - - @Override - public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - super.draw(canvas, (MapView) mapView, shadow); - } - - @Override - public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - // Nothing to do here... - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private cgMapOverlay base; + private Lock lock = new ReentrantLock(); + + public googleCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { + super(boundCenterBottom(markerIn)); + base = new cgMapOverlay(settingsIn, this, contextIn, fromDetailIn); + } + + @Override + public cgMapOverlay getBase() { + return base; + } + + @Override + protected googleCacheOverlayItem createItem(int i) { + if (base == null) + return null; + + return (googleCacheOverlayItem) base.createItem(i); + } + + @Override + public int size() { + if (base == null) + return 0; + + return base.size(); + } + + @Override + protected boolean onTap(int arg0) { + if (base == null) + return false; + + return base.onTap(arg0); + } + + @Override + public void draw(Canvas canvas, MapView mapView, boolean shadow) { + base.draw(canvas, (MapViewImpl) mapView, shadow); + } + + @Override + public void superPopulate() { + populate(); + } + + @Override + public Drawable superBoundCenter(Drawable markerIn) { + return super.boundCenter(markerIn); + } + + @Override + public Drawable superBoundCenterBottom(Drawable marker) { + return super.boundCenterBottom(marker); + } + + @Override + public void superSetLastFocusedItemIndex(int i) { + super.setLastFocusedIndex(i); + } + + @Override + public boolean superOnTap(int index) { + return super.onTap(index); + } + + @Override + public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + super.draw(canvas, (MapView) mapView, shadow); + } + + @Override + public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + // Nothing to do here... + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleCacheOverlayItem.java b/src/cgeo/geocaching/googlemaps/googleCacheOverlayItem.java index 5f20dd4..4bc7671 100644 --- a/src/cgeo/geocaching/googlemaps/googleCacheOverlayItem.java +++ b/src/cgeo/geocaching/googlemaps/googleCacheOverlayItem.java @@ -7,22 +7,22 @@ import com.google.android.maps.GeoPoint; import com.google.android.maps.OverlayItem; public class googleCacheOverlayItem extends OverlayItem implements CacheOverlayItemImpl { - private String cacheType = null; - private cgCoord coord; - - public googleCacheOverlayItem(cgCoord coordinate, String type) { - super(new GeoPoint(coordinate.coords.getLatitudeE6(), coordinate.coords.getLongitudeE6()), coordinate.name, ""); - - this.cacheType = type; - this.coord = coordinate; - } - - public cgCoord getCoord() { - return coord; - } - - public String getType() { - return cacheType; - } + private String cacheType = null; + private cgCoord coord; + + public googleCacheOverlayItem(cgCoord coordinate, String type) { + super(new GeoPoint(coordinate.coords.getLatitudeE6(), coordinate.coords.getLongitudeE6()), coordinate.name, ""); + + this.cacheType = type; + this.coord = coordinate; + } + + public cgCoord getCoord() { + return coord; + } + + public String getType() { + return cacheType; + } } diff --git a/src/cgeo/geocaching/googlemaps/googleGeoPoint.java b/src/cgeo/geocaching/googlemaps/googleGeoPoint.java index a22e7d4..2c72d60 100644 --- a/src/cgeo/geocaching/googlemaps/googleGeoPoint.java +++ b/src/cgeo/geocaching/googlemaps/googleGeoPoint.java @@ -6,8 +6,8 @@ import com.google.android.maps.GeoPoint; public class googleGeoPoint extends GeoPoint implements GeoPointImpl { - public googleGeoPoint(int latitudeE6, int longitudeE6) { - super(latitudeE6, longitudeE6); - } + public googleGeoPoint(int latitudeE6, int longitudeE6) { + super(latitudeE6, longitudeE6); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleMapActivity.java b/src/cgeo/geocaching/googlemaps/googleMapActivity.java index ed5b33d..6c60a9a 100644 --- a/src/cgeo/geocaching/googlemaps/googleMapActivity.java +++ b/src/cgeo/geocaching/googlemaps/googleMapActivity.java @@ -1,122 +1,123 @@ package cgeo.geocaching.googlemaps; -import android.app.Activity; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; import cgeo.geocaching.mapcommon.MapBase; import cgeo.geocaching.mapcommon.cgeomap; import cgeo.geocaching.mapinterfaces.ActivityImpl; import com.google.android.maps.MapActivity; +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + public class googleMapActivity extends MapActivity implements ActivityImpl { - private MapBase mapBase; - - public googleMapActivity() { - mapBase = new cgeomap(this); - } - - @Override - protected boolean isRouteDisplayed() { - return false; - } - - @Override - public Activity getActivity() { - return this; - } - - @Override - protected void onCreate(Bundle icicle) { - mapBase.onCreate(icicle); - } - - @Override - protected void onDestroy() { - mapBase.onDestroy(); - } - - @Override - protected void onPause() { - mapBase.onPause(); - } - - @Override - protected void onResume() { - mapBase.onResume(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return mapBase.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return mapBase.onOptionsItemSelected(item); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - return mapBase.onPrepareOptionsMenu(menu); - } - - @Override - protected void onStop() { - mapBase.onStop(); - } - - @Override - public void superOnCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public boolean superOnCreateOptionsMenu(Menu menu) { - return super.onCreateOptionsMenu(menu); - } - - @Override - public void superOnDestroy() { - super.onDestroy(); - } - - @Override - public boolean superOnOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } - - @Override - public void superOnResume() { - super.onResume(); - } - - @Override - public void superOnStop() { - super.onStop(); - } - - @Override - public void superOnPause() { - super.onPause(); - } - - @Override - public boolean superOnPrepareOptionsMenu(Menu menu) { - return super.onPrepareOptionsMenu(menu); - } - - // close activity and open homescreen - public void goHome(View view) { - mapBase.goHome(view); - } - - // open manual entry - public void goManual(View view) { - mapBase.goManual(view); - } + private MapBase mapBase; + + public googleMapActivity() { + mapBase = new cgeomap(this); + } + + @Override + protected boolean isRouteDisplayed() { + return false; + } + + @Override + public Activity getActivity() { + return this; + } + + @Override + protected void onCreate(Bundle icicle) { + mapBase.onCreate(icicle); + } + + @Override + protected void onDestroy() { + mapBase.onDestroy(); + } + + @Override + protected void onPause() { + mapBase.onPause(); + } + + @Override + protected void onResume() { + mapBase.onResume(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return mapBase.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return mapBase.onOptionsItemSelected(item); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + return mapBase.onPrepareOptionsMenu(menu); + } + + @Override + protected void onStop() { + mapBase.onStop(); + } + + @Override + public void superOnCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public boolean superOnCreateOptionsMenu(Menu menu) { + return super.onCreateOptionsMenu(menu); + } + + @Override + public void superOnDestroy() { + super.onDestroy(); + } + + @Override + public boolean superOnOptionsItemSelected(MenuItem item) { + return super.onOptionsItemSelected(item); + } + + @Override + public void superOnResume() { + super.onResume(); + } + + @Override + public void superOnStop() { + super.onStop(); + } + + @Override + public void superOnPause() { + super.onPause(); + } + + @Override + public boolean superOnPrepareOptionsMenu(Menu menu) { + return super.onPrepareOptionsMenu(menu); + } + + // close activity and open homescreen + public void goHome(View view) { + mapBase.goHome(view); + } + + // open manual entry + public void goManual(View view) { + mapBase.goManual(view); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleMapController.java b/src/cgeo/geocaching/googlemaps/googleMapController.java index c779b32..fd413f8 100644 --- a/src/cgeo/geocaching/googlemaps/googleMapController.java +++ b/src/cgeo/geocaching/googlemaps/googleMapController.java @@ -1,37 +1,37 @@ package cgeo.geocaching.googlemaps; -import com.google.android.maps.GeoPoint; -import com.google.android.maps.MapController; - import cgeo.geocaching.mapinterfaces.GeoPointImpl; import cgeo.geocaching.mapinterfaces.MapControllerImpl; +import com.google.android.maps.GeoPoint; +import com.google.android.maps.MapController; + public class googleMapController implements MapControllerImpl { - private MapController mapController; - - public googleMapController(MapController mapControllerIn) { - mapController = mapControllerIn; - } - - @Override - public void animateTo(GeoPointImpl geoPoint) { - mapController.animateTo((GeoPoint)geoPoint); - } - - @Override - public void setCenter(GeoPointImpl geoPoint) { - mapController.setCenter((GeoPoint)geoPoint); - } - - @Override - public void setZoom(int mapzoom) { - mapController.setZoom(mapzoom); - } - - @Override - public void zoomToSpan(int latSpanE6, int lonSpanE6) { - mapController.zoomToSpan(latSpanE6, lonSpanE6); - } - + private MapController mapController; + + public googleMapController(MapController mapControllerIn) { + mapController = mapControllerIn; + } + + @Override + public void animateTo(GeoPointImpl geoPoint) { + mapController.animateTo((GeoPoint) geoPoint); + } + + @Override + public void setCenter(GeoPointImpl geoPoint) { + mapController.setCenter((GeoPoint) geoPoint); + } + + @Override + public void setZoom(int mapzoom) { + mapController.setZoom(mapzoom); + } + + @Override + public void zoomToSpan(int latSpanE6, int lonSpanE6) { + mapController.zoomToSpan(latSpanE6, lonSpanE6); + } + } diff --git a/src/cgeo/geocaching/googlemaps/googleMapFactory.java b/src/cgeo/geocaching/googlemaps/googleMapFactory.java index 96f90f8..890f638 100644 --- a/src/cgeo/geocaching/googlemaps/googleMapFactory.java +++ b/src/cgeo/geocaching/googlemaps/googleMapFactory.java @@ -1,6 +1,5 @@ package cgeo.geocaching.googlemaps; -import android.content.Context; import cgeo.geocaching.R; import cgeo.geocaching.cgCoord; import cgeo.geocaching.cgUser; @@ -12,38 +11,40 @@ import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; import com.google.android.maps.MapActivity; -public class googleMapFactory implements MapFactory{ - - @Override - public Class<?extends MapActivity> getMapClass() { - return googleMapActivity.class; - } - - @Override - public int getMapViewId() { - return R.id.map; - } - - @Override - public int getMapLayoutId() { - return R.layout.googlemap; - } - - @Override - public GeoPointImpl getGeoPointBase(final Geopoint coords) { - return new googleGeoPoint(coords.getLatitudeE6(), coords.getLongitudeE6()); - } - - @Override - public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) { - googleCacheOverlayItem baseItem = new googleCacheOverlayItem(coordinate, type); - return baseItem; - } - - @Override - public UserOverlayItemImpl getUserOverlayItemBase(Context context, cgUser userOne) { - googleUsersOverlayItem baseItem = new googleUsersOverlayItem(context, userOne); - return baseItem; - } +import android.content.Context; + +public class googleMapFactory implements MapFactory { + + @Override + public Class<? extends MapActivity> getMapClass() { + return googleMapActivity.class; + } + + @Override + public int getMapViewId() { + return R.id.map; + } + + @Override + public int getMapLayoutId() { + return R.layout.googlemap; + } + + @Override + public GeoPointImpl getGeoPointBase(final Geopoint coords) { + return new googleGeoPoint(coords.getLatitudeE6(), coords.getLongitudeE6()); + } + + @Override + public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) { + googleCacheOverlayItem baseItem = new googleCacheOverlayItem(coordinate, type); + return baseItem; + } + + @Override + public UserOverlayItemImpl getUserOverlayItemBase(Context context, cgUser userOne) { + googleUsersOverlayItem baseItem = new googleUsersOverlayItem(context, userOne); + return baseItem; + } } diff --git a/src/cgeo/geocaching/googlemaps/googleMapProjection.java b/src/cgeo/geocaching/googlemaps/googleMapProjection.java index 476d78d..ea4b97c 100644 --- a/src/cgeo/geocaching/googlemaps/googleMapProjection.java +++ b/src/cgeo/geocaching/googlemaps/googleMapProjection.java @@ -1,28 +1,29 @@ package cgeo.geocaching.googlemaps; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; + import com.google.android.maps.GeoPoint; import com.google.android.maps.Projection; import android.graphics.Point; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; public class googleMapProjection implements MapProjectionImpl { - - private Projection projection; - - public googleMapProjection(Projection projectionIn) { - projection = projectionIn; - } - - @Override - public void toPixels(GeoPointImpl leftGeo, Point left) { - projection.toPixels((GeoPoint) leftGeo, left); - } - - @Override - public Object getImpl() { - return projection; - } + + private Projection projection; + + public googleMapProjection(Projection projectionIn) { + projection = projectionIn; + } + + @Override + public void toPixels(GeoPointImpl leftGeo, Point left) { + projection.toPixels((GeoPoint) leftGeo, left); + } + + @Override + public Object getImpl() { + return projection; + } } diff --git a/src/cgeo/geocaching/googlemaps/googleMapView.java b/src/cgeo/geocaching/googlemaps/googleMapView.java index d31ea68..57defbe 100644 --- a/src/cgeo/geocaching/googlemaps/googleMapView.java +++ b/src/cgeo/geocaching/googlemaps/googleMapView.java @@ -1,14 +1,5 @@ package cgeo.geocaching.googlemaps; -import android.app.Activity; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.GestureDetector.SimpleOnGestureListener; import cgeo.geocaching.cgSettings; import cgeo.geocaching.mapcommon.cgMapMyOverlay; import cgeo.geocaching.mapcommon.cgMapOverlay; @@ -27,167 +18,177 @@ import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.Log; +import android.view.GestureDetector; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.MotionEvent; + public class googleMapView extends MapView implements MapViewImpl { - private GestureDetector gestureDetector; - private OnDragListener onDragListener; - - public googleMapView(Context context, AttributeSet attrs) { - super(context, attrs); - gestureDetector = new GestureDetector(context, new GestureListener()); - } - - public googleMapView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - gestureDetector = new GestureDetector(context, new GestureListener()); - } - - public googleMapView(Context context, String apiKey) { - super(context, apiKey); - gestureDetector = new GestureDetector(context, new GestureListener()); - } - - @Override - public void draw(Canvas canvas) { - try { - if (getMapZoomLevel() >= 22) { // to avoid too close zoom level (mostly on Samsung Galaxy S series) - getController().setZoom(22); - } - - super.draw(canvas); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapView.draw: " + e.toString()); - } - } - - @Override - public void displayZoomControls(boolean takeFocus) { - try { - super.displayZoomControls(takeFocus); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapView.displayZoomControls: " + e.toString()); - } - } - - @Override - public MapControllerImpl getMapController() { - return new googleMapController(getController()); - } - - @Override - public GeoPointImpl getMapViewCenter() { - GeoPoint point = getMapCenter(); - return new googleGeoPoint(point.getLatitudeE6(), point.getLongitudeE6()); - } - - @Override - public void addOverlay(OverlayImpl ovl) { - getOverlays().add((Overlay)ovl); - } - - @Override - public void clearOverlays() { - getOverlays().clear(); - } - - @Override - public MapProjectionImpl getMapProjection() { - return new googleMapProjection(getProjection()); - } - - @Override - public cgMapOverlay createAddMapOverlay(cgSettings settings, - Context context, Drawable drawable, boolean fromDetailIntent) { - - googleCacheOverlay ovl = new googleCacheOverlay(settings, context, drawable, fromDetailIntent); - getOverlays().add(ovl); - return ovl.getBase(); - } - - @Override - public cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn) { - googleUsersOverlay ovl = new googleUsersOverlay(context, markerIn); - getOverlays().add(ovl); - return ovl.getBase(); - } - - @Override - public cgMapMyOverlay createAddPositionOverlay(Activity activity, - cgSettings settingsIn) { - - googleOverlay ovl = new googleOverlay(activity, settingsIn, overlayType.PositionOverlay); - getOverlays().add(ovl); - return (cgMapMyOverlay) ovl.getBase(); - } - - @Override - public cgOverlayScale createAddScaleOverlay(Activity activity, - cgSettings settingsIn) { - - googleOverlay ovl = new googleOverlay(activity, settingsIn, overlayType.ScaleOverlay); - getOverlays().add(ovl); - return (cgOverlayScale) ovl.getBase(); - } - - @Override - public int getMapZoomLevel() { - return getZoomLevel(); - } - - @Override - public void setMapSource(cgSettings settings) { - - switch(settings.mapSource) { - case googleSat: - setSatellite(true); - break; - default: - setSatellite(false); - } - } - - @Override - public boolean needsScaleOverlay() { - return true; - } - - @Override - public void setBuiltinScale(boolean b) { - //Nothing to do for google maps... - } - - @Override - public void repaintRequired(OverlayBase overlay) { - invalidate(); - } - - @Override - public void setOnDragListener(OnDragListener onDragListener) { - this.onDragListener = onDragListener; - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - gestureDetector.onTouchEvent(ev); - return super.onTouchEvent(ev); - } - - private class GestureListener extends SimpleOnGestureListener { - @Override - public boolean onDoubleTap(MotionEvent e) { - getController().zoomInFixing((int) e.getX(), (int) e.getY()); - if (onDragListener != null) { - onDragListener.onDrag(); - } - return true; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, - float distanceX, float distanceY) { - if (onDragListener != null) { - onDragListener.onDrag(); - } - return super.onScroll(e1, e2, distanceX, distanceY); - } - } + private GestureDetector gestureDetector; + private OnDragListener onDragListener; + + public googleMapView(Context context, AttributeSet attrs) { + super(context, attrs); + gestureDetector = new GestureDetector(context, new GestureListener()); + } + + public googleMapView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + gestureDetector = new GestureDetector(context, new GestureListener()); + } + + public googleMapView(Context context, String apiKey) { + super(context, apiKey); + gestureDetector = new GestureDetector(context, new GestureListener()); + } + + @Override + public void draw(Canvas canvas) { + try { + if (getMapZoomLevel() >= 22) { // to avoid too close zoom level (mostly on Samsung Galaxy S series) + getController().setZoom(22); + } + + super.draw(canvas); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapView.draw: " + e.toString()); + } + } + + @Override + public void displayZoomControls(boolean takeFocus) { + try { + super.displayZoomControls(takeFocus); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapView.displayZoomControls: " + e.toString()); + } + } + + @Override + public MapControllerImpl getMapController() { + return new googleMapController(getController()); + } + + @Override + public GeoPointImpl getMapViewCenter() { + GeoPoint point = getMapCenter(); + return new googleGeoPoint(point.getLatitudeE6(), point.getLongitudeE6()); + } + + @Override + public void addOverlay(OverlayImpl ovl) { + getOverlays().add((Overlay) ovl); + } + + @Override + public void clearOverlays() { + getOverlays().clear(); + } + + @Override + public MapProjectionImpl getMapProjection() { + return new googleMapProjection(getProjection()); + } + + @Override + public cgMapOverlay createAddMapOverlay(cgSettings settings, + Context context, Drawable drawable, boolean fromDetailIntent) { + + googleCacheOverlay ovl = new googleCacheOverlay(settings, context, drawable, fromDetailIntent); + getOverlays().add(ovl); + return ovl.getBase(); + } + + @Override + public cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn) { + googleUsersOverlay ovl = new googleUsersOverlay(context, markerIn); + getOverlays().add(ovl); + return ovl.getBase(); + } + + @Override + public cgMapMyOverlay createAddPositionOverlay(Activity activity, + cgSettings settingsIn) { + + googleOverlay ovl = new googleOverlay(activity, settingsIn, overlayType.PositionOverlay); + getOverlays().add(ovl); + return (cgMapMyOverlay) ovl.getBase(); + } + + @Override + public cgOverlayScale createAddScaleOverlay(Activity activity, + cgSettings settingsIn) { + + googleOverlay ovl = new googleOverlay(activity, settingsIn, overlayType.ScaleOverlay); + getOverlays().add(ovl); + return (cgOverlayScale) ovl.getBase(); + } + + @Override + public int getMapZoomLevel() { + return getZoomLevel(); + } + + @Override + public void setMapSource(cgSettings settings) { + + switch (settings.mapSource) { + case googleSat: + setSatellite(true); + break; + default: + setSatellite(false); + } + } + + @Override + public boolean needsScaleOverlay() { + return true; + } + + @Override + public void setBuiltinScale(boolean b) { + //Nothing to do for google maps... + } + + @Override + public void repaintRequired(OverlayBase overlay) { + invalidate(); + } + + @Override + public void setOnDragListener(OnDragListener onDragListener) { + this.onDragListener = onDragListener; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + gestureDetector.onTouchEvent(ev); + return super.onTouchEvent(ev); + } + + private class GestureListener extends SimpleOnGestureListener { + @Override + public boolean onDoubleTap(MotionEvent e) { + getController().zoomInFixing((int) e.getX(), (int) e.getY()); + if (onDragListener != null) { + onDragListener.onDrag(); + } + return true; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, + float distanceX, float distanceY) { + if (onDragListener != null) { + onDragListener.onDrag(); + } + return super.onScroll(e1, e2, distanceX, distanceY); + } + } } diff --git a/src/cgeo/geocaching/googlemaps/googleOverlay.java b/src/cgeo/geocaching/googlemaps/googleOverlay.java index 8473faa..b47824e 100644 --- a/src/cgeo/geocaching/googlemaps/googleOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleOverlay.java @@ -1,10 +1,5 @@ package cgeo.geocaching.googlemaps; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import android.app.Activity; -import android.graphics.Canvas; import cgeo.geocaching.cgSettings; import cgeo.geocaching.mapcommon.cgMapMyOverlay; import cgeo.geocaching.mapcommon.cgOverlayScale; @@ -15,41 +10,47 @@ import cgeo.geocaching.mapinterfaces.OverlayImpl; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; +import android.app.Activity; +import android.graphics.Canvas; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + public class googleOverlay extends Overlay implements OverlayImpl { - private OverlayBase overlayBase = null; - private Lock lock = new ReentrantLock(); - - public googleOverlay(Activity activityIn, cgSettings settingsIn, overlayType ovlType) { - switch (ovlType) { - case PositionOverlay: - overlayBase = new cgMapMyOverlay(settingsIn, activityIn, this); - break; - case ScaleOverlay: - overlayBase = new cgOverlayScale(activityIn, settingsIn, this); - } - } - - @Override - public void draw(Canvas canvas, MapView mapView, boolean shadow) { - super.draw(canvas, mapView, shadow); - - if (overlayBase != null) { - overlayBase.draw(canvas, (MapViewImpl) mapView, shadow); - } - } - - public OverlayBase getBase() { - return overlayBase; - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private OverlayBase overlayBase = null; + private Lock lock = new ReentrantLock(); + + public googleOverlay(Activity activityIn, cgSettings settingsIn, overlayType ovlType) { + switch (ovlType) { + case PositionOverlay: + overlayBase = new cgMapMyOverlay(settingsIn, activityIn, this); + break; + case ScaleOverlay: + overlayBase = new cgOverlayScale(activityIn, settingsIn, this); + } + } + + @Override + public void draw(Canvas canvas, MapView mapView, boolean shadow) { + super.draw(canvas, mapView, shadow); + + if (overlayBase != null) { + overlayBase.draw(canvas, (MapViewImpl) mapView, shadow); + } + } + + public OverlayBase getBase() { + return overlayBase; + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java index f5f16a7..43b2a3c 100644 --- a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java @@ -1,12 +1,5 @@ package cgeo.geocaching.googlemaps; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.drawable.Drawable; import cgeo.geocaching.mapcommon.cgUsersOverlay; import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; import cgeo.geocaching.mapinterfaces.MapProjectionImpl; @@ -15,94 +8,102 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapView; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.drawable.Drawable; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem> implements ItemizedOverlayImpl { - private cgUsersOverlay base; - private Lock lock = new ReentrantLock(); - - public googleUsersOverlay(Context contextIn, Drawable markerIn) { - super(boundCenter(markerIn)); - base = new cgUsersOverlay(this, contextIn); - } - - @Override - public cgUsersOverlay getBase() { - return base; - } - - @Override - protected googleUsersOverlayItem createItem(int i) { - if (base == null) - return null; - - return (googleUsersOverlayItem) base.createItem(i); - } - - @Override - public int size() { - if (base == null) - return 0; - - return base.size(); - } - - @Override - protected boolean onTap(int arg0) { - if (base == null) - return false; - - return base.onTap(arg0); - } - - @Override - public void draw(Canvas canvas, MapView mapView, boolean shadow) { - base.draw(canvas, (MapViewImpl) mapView, shadow); - } - - @Override - public void superPopulate() { - populate(); - } - - @Override - public Drawable superBoundCenter(Drawable markerIn) { - return super.boundCenter(markerIn); - } - - @Override - public Drawable superBoundCenterBottom(Drawable marker) { - return super.boundCenterBottom(marker); - } - - @Override - public void superSetLastFocusedItemIndex(int i) { - super.setLastFocusedIndex(i); - } - - @Override - public boolean superOnTap(int index) { - return super.onTap(index); - } - - @Override - public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - super.draw(canvas, (MapView) mapView, shadow); - } - - @Override - public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - // Nothing to do here - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private cgUsersOverlay base; + private Lock lock = new ReentrantLock(); + + public googleUsersOverlay(Context contextIn, Drawable markerIn) { + super(boundCenter(markerIn)); + base = new cgUsersOverlay(this, contextIn); + } + + @Override + public cgUsersOverlay getBase() { + return base; + } + + @Override + protected googleUsersOverlayItem createItem(int i) { + if (base == null) + return null; + + return (googleUsersOverlayItem) base.createItem(i); + } + + @Override + public int size() { + if (base == null) + return 0; + + return base.size(); + } + + @Override + protected boolean onTap(int arg0) { + if (base == null) + return false; + + return base.onTap(arg0); + } + + @Override + public void draw(Canvas canvas, MapView mapView, boolean shadow) { + base.draw(canvas, (MapViewImpl) mapView, shadow); + } + + @Override + public void superPopulate() { + populate(); + } + + @Override + public Drawable superBoundCenter(Drawable markerIn) { + return super.boundCenter(markerIn); + } + + @Override + public Drawable superBoundCenterBottom(Drawable marker) { + return super.boundCenterBottom(marker); + } + + @Override + public void superSetLastFocusedItemIndex(int i) { + super.setLastFocusedIndex(i); + } + + @Override + public boolean superOnTap(int index) { + return super.onTap(index); + } + + @Override + public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + super.draw(canvas, (MapView) mapView, shadow); + } + + @Override + public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + // Nothing to do here + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleUsersOverlayItem.java b/src/cgeo/geocaching/googlemaps/googleUsersOverlayItem.java index 78491e5..915f291 100644 --- a/src/cgeo/geocaching/googlemaps/googleUsersOverlayItem.java +++ b/src/cgeo/geocaching/googlemaps/googleUsersOverlayItem.java @@ -1,7 +1,5 @@ package cgeo.geocaching.googlemaps; -import android.content.Context; -import android.graphics.drawable.Drawable; import cgeo.geocaching.R; import cgeo.geocaching.cgUser; import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; @@ -9,35 +7,38 @@ import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; import com.google.android.maps.GeoPoint; import com.google.android.maps.OverlayItem; +import android.content.Context; +import android.graphics.drawable.Drawable; + public class googleUsersOverlayItem extends OverlayItem implements UserOverlayItemImpl { - private Context context = null; - private cgUser user = null; - - public googleUsersOverlayItem(Context contextIn, cgUser userIn) { - super(new GeoPoint(userIn.coords.getLatitudeE6(), userIn.coords.getLongitudeE6()), userIn.username, ""); - - context = contextIn; - user = userIn; - } - - @Override - public Drawable getMarker(int state) { - Drawable marker = null; - - if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { - marker = context.getResources().getDrawable(R.drawable.user_location_active); - } else { - marker = context.getResources().getDrawable(R.drawable.user_location); - } - - marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); - marker.setAlpha(190); - setMarker(marker); - - return marker; - } - - public cgUser getUser() { - return user; - } + private Context context = null; + private cgUser user = null; + + public googleUsersOverlayItem(Context contextIn, cgUser userIn) { + super(new GeoPoint(userIn.coords.getLatitudeE6(), userIn.coords.getLongitudeE6()), userIn.username, ""); + + context = contextIn; + user = userIn; + } + + @Override + public Drawable getMarker(int state) { + Drawable marker = null; + + if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { + marker = context.getResources().getDrawable(R.drawable.user_location_active); + } else { + marker = context.getResources().getDrawable(R.drawable.user_location); + } + + marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); + marker.setAlpha(190); + setMarker(marker); + + return marker; + } + + public cgUser getUser() { + return user; + } } diff --git a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java index 99bf2fd..6a24f67 100644 --- a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java +++ b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java @@ -1,8 +1,5 @@ package cgeo.geocaching.mapcommon; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.drawable.Drawable; import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; import cgeo.geocaching.mapinterfaces.MapProjectionImpl; import cgeo.geocaching.mapinterfaces.MapViewImpl; @@ -10,55 +7,60 @@ import cgeo.geocaching.mapinterfaces.OverlayBase; import cgeo.geocaching.mapinterfaces.OverlayImpl; import cgeo.geocaching.mapinterfaces.OverlayItemImpl; +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.drawable.Drawable; + /** * Base class for itemized overlays. Delegates calls from deriving classes to the contained * provider-specific implementation. + * * @author rsudev - * + * */ public abstract class ItemizedOverlayBase implements OverlayBase { - - private ItemizedOverlayImpl ovlImpl; - protected ItemizedOverlayBase(ItemizedOverlayImpl ovlImplIn) { - ovlImpl = ovlImplIn; - } + private ItemizedOverlayImpl ovlImpl; + + protected ItemizedOverlayBase(ItemizedOverlayImpl ovlImplIn) { + ovlImpl = ovlImplIn; + } + + void populate() { + ovlImpl.superPopulate(); + } + + public boolean onTap(int index) { + return ovlImpl.superOnTap(index); + } + + Drawable boundCenter(Drawable markerIn) { + return ovlImpl.superBoundCenter(markerIn); + } + + Drawable boundCenterBottom(Drawable markerIn) { + return ovlImpl.superBoundCenterBottom(markerIn); + } + + void setLastFocusedItemIndex(int index) { + ovlImpl.superSetLastFocusedItemIndex(index); + } + + public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + ovlImpl.superDraw(canvas, mapView, shadow); + } + + public void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + ovlImpl.superDrawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); + } + + @Override + public OverlayImpl getOverlayImpl() { + return ovlImpl; + } - void populate() { - ovlImpl.superPopulate(); - } - - public boolean onTap(int index) { - return ovlImpl.superOnTap(index); - } - - Drawable boundCenter(Drawable markerIn) { - return ovlImpl.superBoundCenter(markerIn); - } - - Drawable boundCenterBottom(Drawable markerIn) { - return ovlImpl.superBoundCenterBottom(markerIn); - } - - void setLastFocusedItemIndex(int index){ - ovlImpl.superSetLastFocusedItemIndex(index); - } - - public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - ovlImpl.superDraw(canvas, mapView, shadow); - } - - public void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - ovlImpl.superDrawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); - } - - @Override - public OverlayImpl getOverlayImpl() { - return ovlImpl; - } + public abstract OverlayItemImpl createItem(int index); - public abstract OverlayItemImpl createItem(int index); - - public abstract int size(); + public abstract int size(); } diff --git a/src/cgeo/geocaching/mapcommon/MapBase.java b/src/cgeo/geocaching/mapcommon/MapBase.java index 1f2d769..377f08f 100644 --- a/src/cgeo/geocaching/mapcommon/MapBase.java +++ b/src/cgeo/geocaching/mapcommon/MapBase.java @@ -1,69 +1,71 @@ package cgeo.geocaching.mapcommon; +import cgeo.geocaching.mapinterfaces.ActivityImpl; + import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import cgeo.geocaching.mapinterfaces.ActivityImpl; /** * Base class for the map activity. Delegates base class calls to the * provider-specific implementation. + * * @author rsudev - * + * */ public abstract class MapBase { - ActivityImpl mapActivity; - - protected MapBase(ActivityImpl activity) { - mapActivity = activity; - } - - public Resources getResources() { - return mapActivity.getResources(); - } - - public Activity getActivity() { - return mapActivity.getActivity(); - } - - public void onCreate(Bundle savedInstanceState) { - mapActivity.superOnCreate(savedInstanceState); - } - - public void onResume() { - mapActivity.superOnResume(); - } - - public void onStop() { - mapActivity.superOnStop(); - } - - public void onPause() { - mapActivity.superOnPause(); - } - - public void onDestroy() { - mapActivity.superOnDestroy(); - } - - public boolean onCreateOptionsMenu(Menu menu) { - return mapActivity.superOnCreateOptionsMenu(menu); - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return mapActivity.superOnPrepareOptionsMenu(menu); - } - - public boolean onOptionsItemSelected(MenuItem item) { - return mapActivity.superOnOptionsItemSelected(item); - } - - public abstract void goHome(View view); - - public abstract void goManual(View view); + ActivityImpl mapActivity; + + protected MapBase(ActivityImpl activity) { + mapActivity = activity; + } + + public Resources getResources() { + return mapActivity.getResources(); + } + + public Activity getActivity() { + return mapActivity.getActivity(); + } + + public void onCreate(Bundle savedInstanceState) { + mapActivity.superOnCreate(savedInstanceState); + } + + public void onResume() { + mapActivity.superOnResume(); + } + + public void onStop() { + mapActivity.superOnStop(); + } + + public void onPause() { + mapActivity.superOnPause(); + } + + public void onDestroy() { + mapActivity.superOnDestroy(); + } + + public boolean onCreateOptionsMenu(Menu menu) { + return mapActivity.superOnCreateOptionsMenu(menu); + } + + public boolean onPrepareOptionsMenu(Menu menu) { + return mapActivity.superOnPrepareOptionsMenu(menu); + } + + public boolean onOptionsItemSelected(MenuItem item) { + return mapActivity.superOnOptionsItemSelected(item); + } + + public abstract void goHome(View view); + + public abstract void goManual(View view); } diff --git a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java index 46c42ce..dba8ba6 100644 --- a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java +++ b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java @@ -1,7 +1,14 @@ package cgeo.geocaching.mapcommon; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.R; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.MapFactory; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; +import cgeo.geocaching.mapinterfaces.OverlayBase; +import cgeo.geocaching.mapinterfaces.OverlayImpl; import android.app.Activity; import android.graphics.Bitmap; @@ -13,206 +20,205 @@ import android.graphics.Paint.Style; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Point; import android.location.Location; -import cgeo.geocaching.R; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.MapFactory; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; -import cgeo.geocaching.mapinterfaces.OverlayBase; -import cgeo.geocaching.mapinterfaces.OverlayImpl; + +import java.util.ArrayList; +import java.util.List; public class cgMapMyOverlay implements OverlayBase { - private cgSettings settings = null; - private Location coordinates = null; - private GeoPointImpl location = null; - private Float heading = 0f; - private Paint accuracyCircle = null; - private Paint historyLine = null; - private Paint historyLineShadow = null; - private Point center = new Point(); - private Point left = new Point(); - private Bitmap arrow = null; - private int widthArrowHalf = 0; - private int heightArrowHalf = 0; - private PaintFlagsDrawFilter setfil = null; - private PaintFlagsDrawFilter remfil = null; - private Location historyRecent = null; - private List<Location> history = new ArrayList<Location>(); - private Point historyPointN = new Point(); - private Point historyPointP = new Point(); - private Activity activity; - private MapFactory mapFactory = null; - private OverlayImpl ovlImpl = null; - - public cgMapMyOverlay(cgSettings settingsIn, Activity activity, OverlayImpl ovlImpl) { - settings = settingsIn; - this.activity = activity; - this.mapFactory = settings.getMapFactory(); - this.ovlImpl = ovlImpl; - } - - public void setCoordinates(Location coordinatesIn) { - coordinates = coordinatesIn; - location = settings.getMapFactory().getGeoPointBase(new Geopoint(coordinates)); - } - - public void setHeading(Float bearingNow) { - heading = bearingNow; - } - - @Override - public void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - - drawInternal(canvas, projection); - } + private cgSettings settings = null; + private Location coordinates = null; + private GeoPointImpl location = null; + private Float heading = 0f; + private Paint accuracyCircle = null; + private Paint historyLine = null; + private Paint historyLineShadow = null; + private Point center = new Point(); + private Point left = new Point(); + private Bitmap arrow = null; + private int widthArrowHalf = 0; + private int heightArrowHalf = 0; + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + private Location historyRecent = null; + private List<Location> history = new ArrayList<Location>(); + private Point historyPointN = new Point(); + private Point historyPointP = new Point(); + private Activity activity; + private MapFactory mapFactory = null; + private OverlayImpl ovlImpl = null; + + public cgMapMyOverlay(cgSettings settingsIn, Activity activity, OverlayImpl ovlImpl) { + settings = settingsIn; + this.activity = activity; + this.mapFactory = settings.getMapFactory(); + this.ovlImpl = ovlImpl; + } + + public void setCoordinates(Location coordinatesIn) { + coordinates = coordinatesIn; + location = settings.getMapFactory().getGeoPointBase(new Geopoint(coordinates)); + } + + public void setHeading(Float bearingNow) { + heading = bearingNow; + } + + @Override + public void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + + drawInternal(canvas, projection); + } @Override public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - drawInternal(canvas, mapView.getMapProjection()); + drawInternal(canvas, mapView.getMapProjection()); } private void drawInternal(Canvas canvas, MapProjectionImpl projection) { - if (coordinates == null || location == null) return; - - if (accuracyCircle == null) { - accuracyCircle = new Paint(); - accuracyCircle.setAntiAlias(true); - accuracyCircle.setStrokeWidth(1.0f); - } - - if (historyLine == null) { - historyLine = new Paint(); - historyLine.setAntiAlias(true); - historyLine.setStrokeWidth(3.0f); - historyLine.setColor(0xFFFFFFFF); - } - - if (historyLineShadow == null) { - historyLineShadow = new Paint(); - historyLineShadow.setAntiAlias(true); - historyLineShadow.setStrokeWidth(7.0f); - historyLineShadow.setColor(0x66000000); - } - - if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); - if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); - - canvas.setDrawFilter(setfil); - - double latitude = coordinates.getLatitude(); - double longitude = coordinates.getLongitude(); - float accuracy = coordinates.getAccuracy(); - - float[] result = new float[1]; - - Location.distanceBetween(latitude, longitude, latitude, longitude + 1, result); - float longitudeLineDistance = result[0]; - - final Geopoint leftCoords = new Geopoint(latitude, longitude - accuracy / longitudeLineDistance); - GeoPointImpl leftGeo = mapFactory.getGeoPointBase(leftCoords); - projection.toPixels(leftGeo, left); - projection.toPixels(location, center); - int radius = center.x - left.x; - - accuracyCircle.setColor(0x66000000); - accuracyCircle.setStyle(Style.STROKE); - canvas.drawCircle(center.x, center.y, radius, accuracyCircle); - - accuracyCircle.setColor(0x08000000); - accuracyCircle.setStyle(Style.FILL); - canvas.drawCircle(center.x, center.y, radius, accuracyCircle); - - if (coordinates.getAccuracy() < 50f && ((historyRecent != null && historyRecent.distanceTo(coordinates) > 5.0) || historyRecent == null)) { - if (historyRecent != null) history.add(historyRecent); - historyRecent = coordinates; - - int toRemove = history.size() - 700; - - if (toRemove > 0) { - for (int cnt = 0; cnt < toRemove; cnt ++) { - history.remove(cnt); - } - } - } - - if (settings.maptrail == 1) { - int size = history.size(); - if (size > 1) { - int alpha = 0; - int alphaCnt = size - 201; - if (alphaCnt < 1) alphaCnt = 1; - - for (int cnt = 1; cnt < size; cnt ++) { - Location prev = history.get(cnt - 1); - Location now = history.get(cnt); - - if (prev != null && now != null) { - projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(prev)), historyPointP); - projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(now)), historyPointN); - - if ((alphaCnt - cnt) > 0) { - alpha = 255 / (alphaCnt - cnt); - } - else { - alpha = 255; - } - - historyLineShadow.setAlpha(alpha); - historyLine.setAlpha(alpha); - - canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLineShadow); - canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLine); - } - } - } - - if (size > 0) { - Location prev = history.get(size - 1); - Location now = coordinates; - - if (prev != null && now != null) { - projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(prev)), historyPointP); - projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(now)), historyPointN); - - historyLineShadow.setAlpha(255); - historyLine.setAlpha(255); - - canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLineShadow); - canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLine); - } - } - } - - if (arrow == null) { - arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron); - widthArrowHalf = arrow.getWidth() / 2; - heightArrowHalf = arrow.getHeight() / 2; - } - - int marginLeft; - int marginTop; - - marginLeft = center.x - widthArrowHalf; - marginTop = center.y - heightArrowHalf; - - Matrix matrix = new Matrix(); - matrix.setRotate(heading.floatValue(), widthArrowHalf, heightArrowHalf); - matrix.postTranslate(marginLeft, marginTop); - - canvas.drawBitmap(arrow, matrix, null); - - canvas.setDrawFilter(remfil); - - //super.draw(canvas, mapView, shadow); - } - - @Override - public OverlayImpl getOverlayImpl() { - return this.ovlImpl; - } + if (coordinates == null || location == null) + return; + + if (accuracyCircle == null) { + accuracyCircle = new Paint(); + accuracyCircle.setAntiAlias(true); + accuracyCircle.setStrokeWidth(1.0f); + } + + if (historyLine == null) { + historyLine = new Paint(); + historyLine.setAntiAlias(true); + historyLine.setStrokeWidth(3.0f); + historyLine.setColor(0xFFFFFFFF); + } + + if (historyLineShadow == null) { + historyLineShadow = new Paint(); + historyLineShadow.setAntiAlias(true); + historyLineShadow.setStrokeWidth(7.0f); + historyLineShadow.setColor(0x66000000); + } + + if (setfil == null) + setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + if (remfil == null) + remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + + canvas.setDrawFilter(setfil); + + double latitude = coordinates.getLatitude(); + double longitude = coordinates.getLongitude(); + float accuracy = coordinates.getAccuracy(); + + float[] result = new float[1]; + + Location.distanceBetween(latitude, longitude, latitude, longitude + 1, result); + float longitudeLineDistance = result[0]; + + final Geopoint leftCoords = new Geopoint(latitude, longitude - accuracy / longitudeLineDistance); + GeoPointImpl leftGeo = mapFactory.getGeoPointBase(leftCoords); + projection.toPixels(leftGeo, left); + projection.toPixels(location, center); + int radius = center.x - left.x; + + accuracyCircle.setColor(0x66000000); + accuracyCircle.setStyle(Style.STROKE); + canvas.drawCircle(center.x, center.y, radius, accuracyCircle); + + accuracyCircle.setColor(0x08000000); + accuracyCircle.setStyle(Style.FILL); + canvas.drawCircle(center.x, center.y, radius, accuracyCircle); + + if (coordinates.getAccuracy() < 50f && ((historyRecent != null && historyRecent.distanceTo(coordinates) > 5.0) || historyRecent == null)) { + if (historyRecent != null) + history.add(historyRecent); + historyRecent = coordinates; + + int toRemove = history.size() - 700; + + if (toRemove > 0) { + for (int cnt = 0; cnt < toRemove; cnt++) { + history.remove(cnt); + } + } + } + + if (settings.maptrail == 1) { + int size = history.size(); + if (size > 1) { + int alpha = 0; + int alphaCnt = size - 201; + if (alphaCnt < 1) + alphaCnt = 1; + + for (int cnt = 1; cnt < size; cnt++) { + Location prev = history.get(cnt - 1); + Location now = history.get(cnt); + + if (prev != null && now != null) { + projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(prev)), historyPointP); + projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(now)), historyPointN); + + if ((alphaCnt - cnt) > 0) { + alpha = 255 / (alphaCnt - cnt); + } + else { + alpha = 255; + } + + historyLineShadow.setAlpha(alpha); + historyLine.setAlpha(alpha); + + canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLineShadow); + canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLine); + } + } + } + + if (size > 0) { + Location prev = history.get(size - 1); + Location now = coordinates; + + if (prev != null && now != null) { + projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(prev)), historyPointP); + projection.toPixels(mapFactory.getGeoPointBase(new Geopoint(now)), historyPointN); + + historyLineShadow.setAlpha(255); + historyLine.setAlpha(255); + + canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLineShadow); + canvas.drawLine(historyPointP.x, historyPointP.y, historyPointN.x, historyPointN.y, historyLine); + } + } + } + + if (arrow == null) { + arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron); + widthArrowHalf = arrow.getWidth() / 2; + heightArrowHalf = arrow.getHeight() / 2; + } + + int marginLeft; + int marginTop; + + marginLeft = center.x - widthArrowHalf; + marginTop = center.y - heightArrowHalf; + + Matrix matrix = new Matrix(); + matrix.setRotate(heading.floatValue(), widthArrowHalf, heightArrowHalf); + matrix.postTranslate(marginLeft, marginTop); + + canvas.drawBitmap(arrow, matrix, null); + + canvas.setDrawFilter(remfil); + + //super.draw(canvas, mapView, shadow); + } + + @Override + public OverlayImpl getOverlayImpl() { + return this.ovlImpl; + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java index db5fba4..1321fd2 100644 --- a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java +++ b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java @@ -1,7 +1,20 @@ package cgeo.geocaching.mapcommon; -import java.util.ArrayList; -import java.util.List; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCoord; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgeodetail; +import cgeo.geocaching.cgeonavigate; +import cgeo.geocaching.cgeopopup; +import cgeo.geocaching.cgeowaypoint; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; +import cgeo.geocaching.mapinterfaces.MapFactory; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; +import cgeo.geocaching.mapinterfaces.OverlayBase; import org.apache.commons.lang3.StringUtils; @@ -19,338 +32,328 @@ import android.graphics.Point; import android.location.Location; import android.text.Html; import android.util.Log; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCoord; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgeodetail; -import cgeo.geocaching.cgeonavigate; -import cgeo.geocaching.cgeopopup; -import cgeo.geocaching.cgeowaypoint; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; -import cgeo.geocaching.mapinterfaces.MapFactory; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; -import cgeo.geocaching.mapinterfaces.OverlayBase; + +import java.util.ArrayList; +import java.util.List; public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase { - private List<CacheOverlayItemImpl> items = new ArrayList<CacheOverlayItemImpl>(); - private Context context = null; - private Boolean fromDetail = false; - private boolean displayCircles = false; - private ProgressDialog waitDialog = null; - private Point center = new Point(); - private Point left = new Point(); - private Paint blockedCircle = null; - private PaintFlagsDrawFilter setfil = null; - private PaintFlagsDrawFilter remfil = null; - private cgSettings settings; - private MapFactory mapFactory = null; - - public cgMapOverlay(cgSettings settingsIn, ItemizedOverlayImpl ovlImpl, Context contextIn, Boolean fromDetailIn) { - super(ovlImpl); - - populate(); - settings = settingsIn; - - context = contextIn; - fromDetail = fromDetailIn; - - mapFactory = settings.getMapFactory(); - } - - public void updateItems(CacheOverlayItemImpl item) { - List<CacheOverlayItemImpl> itemsPre = new ArrayList<CacheOverlayItemImpl>(); - itemsPre.add(item); - - updateItems(itemsPre); - } - - public void updateItems(List<CacheOverlayItemImpl> itemsPre) { - if (itemsPre == null) { - return; - } - - for (CacheOverlayItemImpl item : itemsPre) { - item.setMarker(boundCenterBottom(item.getMarker(0))); - } - - // ensure no interference between the draw and content changing routines - getOverlayImpl().lock(); - try { - items = new ArrayList<CacheOverlayItemImpl>(itemsPre); - - setLastFocusedItemIndex(-1); // to reset tap during data change - populate(); - } finally { - getOverlayImpl().unlock(); - } - } - - public boolean getCircles() { - return displayCircles; - } - - public void switchCircles() { - displayCircles = !displayCircles; - } - - @Override - public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - - drawInternal(canvas, mapView.getMapProjection()); - - super.draw(canvas, mapView, false); - } - - @Override - public void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - - drawInternal(canvas, projection); - - super.drawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); - } - - private void drawInternal(Canvas canvas, MapProjectionImpl projection) { - - // prevent content changes - getOverlayImpl().lock(); - try { - if (displayCircles) { - if (blockedCircle == null) { - blockedCircle = new Paint(); - blockedCircle.setAntiAlias(true); - blockedCircle.setStrokeWidth(1.0f); - blockedCircle.setARGB(127, 0, 0, 0); - blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0)); - } - - if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); - if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); - - canvas.setDrawFilter(setfil); - - for (CacheOverlayItemImpl item : items) { - final cgCoord itemCoord = item.getCoord(); - float[] result = new float[1]; - - Location.distanceBetween(itemCoord.coords.getLatitude(), itemCoord.coords.getLongitude(), - itemCoord.coords.getLatitude(), itemCoord.coords.getLongitude() + 1, result); - final float longitudeLineDistance = result[0]; - - GeoPointImpl itemGeo = mapFactory.getGeoPointBase(itemCoord.coords); - - final Geopoint leftCoords = new Geopoint(itemCoord.coords.getLatitude(), - itemCoord.coords.getLongitude() - 161 / longitudeLineDistance); - GeoPointImpl leftGeo = mapFactory.getGeoPointBase(leftCoords); - - projection.toPixels(itemGeo, center); - projection.toPixels(leftGeo, left); - int radius = center.x - left.x; - - final String type = item.getType(); - if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) { - blockedCircle.setColor(0x66000000); - blockedCircle.setStyle(Style.STROKE); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); - } else { - blockedCircle.setColor(0x66BB0000); - blockedCircle.setStyle(Style.STROKE); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); - - blockedCircle.setColor(0x44BB0000); - blockedCircle.setStyle(Style.FILL); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); - } - } - canvas.setDrawFilter(remfil); - } - } finally { - getOverlayImpl().unlock(); - } - } - - @Override - public boolean onTap(int index) { - - try { - if (items.size() <= index) { - return false; - } - - if (waitDialog == null) { - waitDialog = new ProgressDialog(context); - waitDialog.setMessage("loading details..."); - waitDialog.setCancelable(false); - } - waitDialog.show(); - - CacheOverlayItemImpl item = null; - - // prevent concurrent changes - getOverlayImpl().lock(); - try { - if (index < items.size()) { - item = items.get(index); - } - } finally { - getOverlayImpl().unlock(); - } - - if (item == null) { - return false; - } - - cgCoord coordinate = item.getCoord(); - - if (StringUtils.isNotBlank(coordinate.type) && coordinate.type.equalsIgnoreCase("cache") && StringUtils.isNotBlank(coordinate.geocode)) { - Intent popupIntent = new Intent(context, cgeopopup.class); - - popupIntent.putExtra("fromdetail", fromDetail); - popupIntent.putExtra("geocode", coordinate.geocode); - - context.startActivity(popupIntent); - } else if (coordinate.type != null && coordinate.type.equalsIgnoreCase("waypoint") && coordinate.id != null && coordinate.id > 0) { - Intent popupIntent = new Intent(context, cgeowaypoint.class); - - popupIntent.putExtra("waypoint", coordinate.id); - popupIntent.putExtra("geocode", coordinate.geocode); - - context.startActivity(popupIntent); - } else { - waitDialog.dismiss(); - return false; - } - - waitDialog.dismiss(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapOverlay.onTap: " + e.toString()); - } - - return false; - } - - @Override - public CacheOverlayItemImpl createItem(int index) { - try { - return items.get(index); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapOverlay.createItem: " + e.toString()); - } - - return null; - } - - @Override - public int size() { - try { - return items.size(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapOverlay.size: " + e.toString()); - } - - return 0; - } - - public void infoDialog(int index) { - - final CacheOverlayItemImpl item = items.get(index); - final cgCoord coordinate = item.getCoord(); - - if (coordinate == null) { - Log.e(cgSettings.tag, "cgMapOverlay:infoDialog: No coordinates given"); - return; - } - - try { - AlertDialog.Builder dialog = new AlertDialog.Builder(context); - dialog.setCancelable(true); - - if (coordinate.type.equalsIgnoreCase("cache")) { - dialog.setTitle("cache"); - - String cacheType; - if (cgBase.cacheTypesInv.containsKey(coordinate.typeSpec)) { - cacheType = cgBase.cacheTypesInv.get(coordinate.typeSpec); - } else { - cacheType = cgBase.cacheTypesInv.get("mystery"); - } - - dialog.setMessage(Html.fromHtml(item.getTitle()) + "\n\ngeocode: " + coordinate.geocode.toUpperCase() + "\ntype: " + cacheType); - if (fromDetail == false) { - dialog.setPositiveButton("detail", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - Intent cachesIntent = new Intent(context, cgeodetail.class); - cachesIntent.putExtra("geocode", coordinate.geocode.toUpperCase()); - context.startActivity(cachesIntent); - - dialog.cancel(); - } - }); - } else { - dialog.setPositiveButton("navigate", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - cgeonavigate navigateActivity = new cgeonavigate(); - - cgeonavigate.coordinates.clear(); - cgeonavigate.coordinates.add(coordinate); - - Intent navigateIntent = new Intent(context, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", coordinate.coords.getLatitude()); - navigateIntent.putExtra("longitude", coordinate.coords.getLongitude()); - navigateIntent.putExtra("geocode", coordinate.geocode.toUpperCase()); - context.startActivity(navigateIntent); - dialog.cancel(); - } - }); - } - } else { - dialog.setTitle("waypoint"); - - String waypointType; - if (cgBase.cacheTypesInv.containsKey(coordinate.typeSpec)) { - waypointType = cgBase.waypointTypes.get(coordinate.typeSpec); - } else { - waypointType = cgBase.waypointTypes.get("waypoint"); - } - - dialog.setMessage(Html.fromHtml(item.getTitle()) + "\n\ntype: " + waypointType); - dialog.setPositiveButton("navigate", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - cgeonavigate navigateActivity = new cgeonavigate(); - - cgeonavigate.coordinates.clear(); - cgeonavigate.coordinates.add(coordinate); - - Intent navigateIntent = new Intent(context, navigateActivity.getClass()); - navigateIntent.putExtra("latitude", coordinate.coords.getLatitude()); - navigateIntent.putExtra("longitude", coordinate.coords.getLongitude()); - navigateIntent.putExtra("geocode", coordinate.name); - - context.startActivity(navigateIntent); - dialog.cancel(); - } - }); - } - - dialog.setNegativeButton("dismiss", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapOverlay.infoDialog: " + e.toString()); - } - } + private List<CacheOverlayItemImpl> items = new ArrayList<CacheOverlayItemImpl>(); + private Context context = null; + private Boolean fromDetail = false; + private boolean displayCircles = false; + private ProgressDialog waitDialog = null; + private Point center = new Point(); + private Point left = new Point(); + private Paint blockedCircle = null; + private PaintFlagsDrawFilter setfil = null; + private PaintFlagsDrawFilter remfil = null; + private cgSettings settings; + private MapFactory mapFactory = null; + + public cgMapOverlay(cgSettings settingsIn, ItemizedOverlayImpl ovlImpl, Context contextIn, Boolean fromDetailIn) { + super(ovlImpl); + + populate(); + settings = settingsIn; + + context = contextIn; + fromDetail = fromDetailIn; + + mapFactory = settings.getMapFactory(); + } + + public void updateItems(CacheOverlayItemImpl item) { + List<CacheOverlayItemImpl> itemsPre = new ArrayList<CacheOverlayItemImpl>(); + itemsPre.add(item); + + updateItems(itemsPre); + } + + public void updateItems(List<CacheOverlayItemImpl> itemsPre) { + if (itemsPre == null) { + return; + } + + for (CacheOverlayItemImpl item : itemsPre) { + item.setMarker(boundCenterBottom(item.getMarker(0))); + } + + // ensure no interference between the draw and content changing routines + getOverlayImpl().lock(); + try { + items = new ArrayList<CacheOverlayItemImpl>(itemsPre); + + setLastFocusedItemIndex(-1); // to reset tap during data change + populate(); + } finally { + getOverlayImpl().unlock(); + } + } + + public boolean getCircles() { + return displayCircles; + } + + public void switchCircles() { + displayCircles = !displayCircles; + } + + @Override + public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + + drawInternal(canvas, mapView.getMapProjection()); + + super.draw(canvas, mapView, false); + } + + @Override + public void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + + drawInternal(canvas, projection); + + super.drawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); + } + + private void drawInternal(Canvas canvas, MapProjectionImpl projection) { + + // prevent content changes + getOverlayImpl().lock(); + try { + if (displayCircles) { + if (blockedCircle == null) { + blockedCircle = new Paint(); + blockedCircle.setAntiAlias(true); + blockedCircle.setStrokeWidth(1.0f); + blockedCircle.setARGB(127, 0, 0, 0); + blockedCircle.setPathEffect(new DashPathEffect(new float[] { 3, 2 }, 0)); + } + + if (setfil == null) + setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + if (remfil == null) + remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + + canvas.setDrawFilter(setfil); + + for (CacheOverlayItemImpl item : items) { + final cgCoord itemCoord = item.getCoord(); + float[] result = new float[1]; + + Location.distanceBetween(itemCoord.coords.getLatitude(), itemCoord.coords.getLongitude(), + itemCoord.coords.getLatitude(), itemCoord.coords.getLongitude() + 1, result); + final float longitudeLineDistance = result[0]; + + GeoPointImpl itemGeo = mapFactory.getGeoPointBase(itemCoord.coords); + + final Geopoint leftCoords = new Geopoint(itemCoord.coords.getLatitude(), + itemCoord.coords.getLongitude() - 161 / longitudeLineDistance); + GeoPointImpl leftGeo = mapFactory.getGeoPointBase(leftCoords); + + projection.toPixels(itemGeo, center); + projection.toPixels(leftGeo, left); + int radius = center.x - left.x; + + final String type = item.getType(); + if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) { + blockedCircle.setColor(0x66000000); + blockedCircle.setStyle(Style.STROKE); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + } else { + blockedCircle.setColor(0x66BB0000); + blockedCircle.setStyle(Style.STROKE); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + + blockedCircle.setColor(0x44BB0000); + blockedCircle.setStyle(Style.FILL); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + } + } + canvas.setDrawFilter(remfil); + } + } finally { + getOverlayImpl().unlock(); + } + } + + @Override + public boolean onTap(int index) { + + try { + if (items.size() <= index) { + return false; + } + + if (waitDialog == null) { + waitDialog = new ProgressDialog(context); + waitDialog.setMessage("loading details..."); + waitDialog.setCancelable(false); + } + waitDialog.show(); + + CacheOverlayItemImpl item = null; + + // prevent concurrent changes + getOverlayImpl().lock(); + try { + if (index < items.size()) { + item = items.get(index); + } + } finally { + getOverlayImpl().unlock(); + } + + if (item == null) { + return false; + } + + cgCoord coordinate = item.getCoord(); + + if (StringUtils.isNotBlank(coordinate.type) && coordinate.type.equalsIgnoreCase("cache") && StringUtils.isNotBlank(coordinate.geocode)) { + Intent popupIntent = new Intent(context, cgeopopup.class); + + popupIntent.putExtra("fromdetail", fromDetail); + popupIntent.putExtra("geocode", coordinate.geocode); + + context.startActivity(popupIntent); + } else if (coordinate.type != null && coordinate.type.equalsIgnoreCase("waypoint") && coordinate.id != null && coordinate.id > 0) { + Intent popupIntent = new Intent(context, cgeowaypoint.class); + + popupIntent.putExtra("waypoint", coordinate.id); + popupIntent.putExtra("geocode", coordinate.geocode); + + context.startActivity(popupIntent); + } else { + waitDialog.dismiss(); + return false; + } + + waitDialog.dismiss(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapOverlay.onTap: " + e.toString()); + } + + return false; + } + + @Override + public CacheOverlayItemImpl createItem(int index) { + try { + return items.get(index); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapOverlay.createItem: " + e.toString()); + } + + return null; + } + + @Override + public int size() { + try { + return items.size(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapOverlay.size: " + e.toString()); + } + + return 0; + } + + public void infoDialog(int index) { + + final CacheOverlayItemImpl item = items.get(index); + final cgCoord coordinate = item.getCoord(); + + if (coordinate == null) { + Log.e(cgSettings.tag, "cgMapOverlay:infoDialog: No coordinates given"); + return; + } + + try { + AlertDialog.Builder dialog = new AlertDialog.Builder(context); + dialog.setCancelable(true); + + if (coordinate.type.equalsIgnoreCase("cache")) { + dialog.setTitle("cache"); + + String cacheType; + if (cgBase.cacheTypesInv.containsKey(coordinate.typeSpec)) { + cacheType = cgBase.cacheTypesInv.get(coordinate.typeSpec); + } else { + cacheType = cgBase.cacheTypesInv.get("mystery"); + } + + dialog.setMessage(Html.fromHtml(item.getTitle()) + "\n\ngeocode: " + coordinate.geocode.toUpperCase() + "\ntype: " + cacheType); + if (fromDetail == false) { + dialog.setPositiveButton("detail", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + Intent cachesIntent = new Intent(context, cgeodetail.class); + cachesIntent.putExtra("geocode", coordinate.geocode.toUpperCase()); + context.startActivity(cachesIntent); + + dialog.cancel(); + } + }); + } else { + dialog.setPositiveButton("navigate", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + cgeonavigate navigateActivity = new cgeonavigate(); + + cgeonavigate.coordinates.clear(); + cgeonavigate.coordinates.add(coordinate); + + Intent navigateIntent = new Intent(context, navigateActivity.getClass()); + navigateIntent.putExtra("latitude", coordinate.coords.getLatitude()); + navigateIntent.putExtra("longitude", coordinate.coords.getLongitude()); + navigateIntent.putExtra("geocode", coordinate.geocode.toUpperCase()); + context.startActivity(navigateIntent); + dialog.cancel(); + } + }); + } + } else { + dialog.setTitle("waypoint"); + + String waypointType; + if (cgBase.cacheTypesInv.containsKey(coordinate.typeSpec)) { + waypointType = cgBase.waypointTypes.get(coordinate.typeSpec); + } else { + waypointType = cgBase.waypointTypes.get("waypoint"); + } + + dialog.setMessage(Html.fromHtml(item.getTitle()) + "\n\ntype: " + waypointType); + dialog.setPositiveButton("navigate", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + cgeonavigate navigateActivity = new cgeonavigate(); + + cgeonavigate.coordinates.clear(); + cgeonavigate.coordinates.add(coordinate); + + Intent navigateIntent = new Intent(context, navigateActivity.getClass()); + navigateIntent.putExtra("latitude", coordinate.coords.getLatitude()); + navigateIntent.putExtra("longitude", coordinate.coords.getLongitude()); + navigateIntent.putExtra("geocode", coordinate.name); + + context.startActivity(navigateIntent); + dialog.cancel(); + } + }); + } + + dialog.setNegativeButton("dismiss", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + AlertDialog alert = dialog.create(); + alert.show(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapOverlay.infoDialog: " + e.toString()); + } + } } diff --git a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java index f7fb969..7c689a3 100644 --- a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java +++ b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java @@ -1,12 +1,5 @@ package cgeo.geocaching.mapcommon; -import android.app.Activity; -import android.graphics.BlurMaskFilter; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Point; -import android.graphics.Typeface; -import android.util.DisplayMetrics; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgSettings; import cgeo.geocaching.cgSettings.mapSourceEnum; @@ -17,137 +10,145 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl; import cgeo.geocaching.mapinterfaces.OverlayBase; import cgeo.geocaching.mapinterfaces.OverlayImpl; +import android.app.Activity; +import android.graphics.BlurMaskFilter; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.Typeface; +import android.util.DisplayMetrics; + public class cgOverlayScale implements OverlayBase { - private cgSettings settings = null; + private cgSettings settings = null; private Paint scale = null; private Paint scaleShadow = null; - private BlurMaskFilter blur = null; - private float pixelDensity = 0L; - private double pixels = 0d; - private int bottom = 0; - private double distance = 0d; - private double distanceRound = 0d; - private String units = null; - private OverlayImpl ovlImpl=null; + private BlurMaskFilter blur = null; + private float pixelDensity = 0L; + private double pixels = 0d; + private int bottom = 0; + private double distance = 0d; + private double distanceRound = 0d; + private String units = null; + private OverlayImpl ovlImpl = null; public cgOverlayScale(Activity activity, cgSettings settingsIn, OverlayImpl overlayImpl) { - settings = settingsIn; - this.ovlImpl = overlayImpl; - - DisplayMetrics metrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); - pixelDensity = metrics.density; - } - - @Override - public void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - // Scale overlay is only necessary for google maps, so the mapsforge - // related draw method needs not to be filled. - } - - @Override + settings = settingsIn; + this.ovlImpl = overlayImpl; + + DisplayMetrics metrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + pixelDensity = metrics.density; + } + + @Override + public void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + // Scale overlay is only necessary for google maps, so the mapsforge + // related draw method needs not to be filled. + } + + @Override public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - //super.draw(canvas, mapView, shadow); - - final double span = mapView.getLongitudeSpan() / 1e6; - final GeoPointImpl center = mapView.getMapViewCenter(); - - pixels = mapView.getWidth() / 2.0; // pixels related to following latitude span - bottom = mapView.getHeight() - 14; // pixels from bottom side of screen - - final Geopoint leftCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 - span /2); - final Geopoint rightCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 + span /2); - - distance = leftCoords.distanceTo(rightCoords) / 2; - distanceRound = 0d; - - if(settings.units == cgSettings.unitsImperial) { - distance /= cgBase.miles2km; - - if (distance > 100) { // 100+ mi > 1xx mi - distanceRound = Math.floor(distance / 100) * 100; - units = "mi"; - } else if (distance > 10) { // 10 - 100 mi > 1x mi - distanceRound = Math.floor(distance / 10) * 10; - units = "mi"; - } else if (distance > 1) { // 1 - 10 mi > 1.x mi - distanceRound = Math.floor(distance); - units = "mi"; - } else if (distance > 0.1) { // 0.1 mi - 1.0 mi > 1xx ft - distance *= 5280; - distanceRound = Math.floor(distance / 100) * 100; - units = "ft"; - } else { // 1 - 100 ft > 1x ft - distance *= 5280; - distanceRound = Math.round(distance / 10) * 10; - units = "ft"; - } - } else { - if (distance > 100) { // 100+ km > 1xx km - distanceRound = Math.floor(distance / 100) * 100; - units = "km"; - } else if (distance > 10) { // 10 - 100 km > 1x km - distanceRound = Math.floor(distance / 10) * 10; - units = "km"; - } else if (distance > 1) { // 1 - 10 km > 1.x km - distanceRound = Math.floor(distance); - units = "km"; - } else if (distance > 0.1) { // 100 m - 1 km > 1xx m - distance *= 1000; - distanceRound = Math.floor(distance / 100) * 100; - units = "m"; - } else { // 1 - 100 m > 1x m - distance *= 1000; - distanceRound = Math.round(distance / 10) * 10; - units = "m"; - } - } - - pixels = Math.round((pixels / distance) * distanceRound); - - if (blur == null) { - blur = new BlurMaskFilter(3, BlurMaskFilter.Blur.NORMAL); - } - - if (scaleShadow == null) { - scaleShadow = new Paint(); - scaleShadow.setAntiAlias(true); - scaleShadow.setStrokeWidth(4 * pixelDensity); - scaleShadow.setMaskFilter(blur); - scaleShadow.setTextSize(14 * pixelDensity); - scaleShadow.setTypeface(Typeface.DEFAULT_BOLD); - } - - if (scale == null) { - scale = new Paint(); - scale.setAntiAlias(true); - scale.setStrokeWidth(2 * pixelDensity); - scale.setTextSize(14 * pixelDensity); - scale.setTypeface(Typeface.DEFAULT_BOLD); - } - - if (mapSourceEnum.googleSat == settings.mapSource) { - scaleShadow.setColor(0xFF000000); - scale.setColor(0xFFFFFFFF); - } else { - scaleShadow.setColor(0xFFFFFFFF); - scale.setColor(0xFF000000); - } - - canvas.drawLine(10, bottom, 10, (bottom - (8 * pixelDensity)), scaleShadow); - canvas.drawLine((int)(pixels + 10), bottom, (int)(pixels + 10), (bottom - (8 * pixelDensity)), scaleShadow); - canvas.drawLine(8, bottom, (int)(pixels + 12), bottom, scaleShadow); - canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float)(pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scaleShadow); - - canvas.drawLine(11, bottom, 11, (bottom - (6 * pixelDensity)), scale); - canvas.drawLine((int)(pixels + 9), bottom, (int)(pixels + 9), (bottom - (6 * pixelDensity)), scale); - canvas.drawLine(10, bottom, (int)(pixels + 10), bottom, scale); - canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float)(pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale); + //super.draw(canvas, mapView, shadow); + + final double span = mapView.getLongitudeSpan() / 1e6; + final GeoPointImpl center = mapView.getMapViewCenter(); + + pixels = mapView.getWidth() / 2.0; // pixels related to following latitude span + bottom = mapView.getHeight() - 14; // pixels from bottom side of screen + + final Geopoint leftCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 - span / 2); + final Geopoint rightCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 + span / 2); + + distance = leftCoords.distanceTo(rightCoords) / 2; + distanceRound = 0d; + + if (settings.units == cgSettings.unitsImperial) { + distance /= cgBase.miles2km; + + if (distance > 100) { // 100+ mi > 1xx mi + distanceRound = Math.floor(distance / 100) * 100; + units = "mi"; + } else if (distance > 10) { // 10 - 100 mi > 1x mi + distanceRound = Math.floor(distance / 10) * 10; + units = "mi"; + } else if (distance > 1) { // 1 - 10 mi > 1.x mi + distanceRound = Math.floor(distance); + units = "mi"; + } else if (distance > 0.1) { // 0.1 mi - 1.0 mi > 1xx ft + distance *= 5280; + distanceRound = Math.floor(distance / 100) * 100; + units = "ft"; + } else { // 1 - 100 ft > 1x ft + distance *= 5280; + distanceRound = Math.round(distance / 10) * 10; + units = "ft"; + } + } else { + if (distance > 100) { // 100+ km > 1xx km + distanceRound = Math.floor(distance / 100) * 100; + units = "km"; + } else if (distance > 10) { // 10 - 100 km > 1x km + distanceRound = Math.floor(distance / 10) * 10; + units = "km"; + } else if (distance > 1) { // 1 - 10 km > 1.x km + distanceRound = Math.floor(distance); + units = "km"; + } else if (distance > 0.1) { // 100 m - 1 km > 1xx m + distance *= 1000; + distanceRound = Math.floor(distance / 100) * 100; + units = "m"; + } else { // 1 - 100 m > 1x m + distance *= 1000; + distanceRound = Math.round(distance / 10) * 10; + units = "m"; + } + } + + pixels = Math.round((pixels / distance) * distanceRound); + + if (blur == null) { + blur = new BlurMaskFilter(3, BlurMaskFilter.Blur.NORMAL); + } + + if (scaleShadow == null) { + scaleShadow = new Paint(); + scaleShadow.setAntiAlias(true); + scaleShadow.setStrokeWidth(4 * pixelDensity); + scaleShadow.setMaskFilter(blur); + scaleShadow.setTextSize(14 * pixelDensity); + scaleShadow.setTypeface(Typeface.DEFAULT_BOLD); + } + + if (scale == null) { + scale = new Paint(); + scale.setAntiAlias(true); + scale.setStrokeWidth(2 * pixelDensity); + scale.setTextSize(14 * pixelDensity); + scale.setTypeface(Typeface.DEFAULT_BOLD); + } + + if (mapSourceEnum.googleSat == settings.mapSource) { + scaleShadow.setColor(0xFF000000); + scale.setColor(0xFFFFFFFF); + } else { + scaleShadow.setColor(0xFFFFFFFF); + scale.setColor(0xFF000000); + } + + canvas.drawLine(10, bottom, 10, (bottom - (8 * pixelDensity)), scaleShadow); + canvas.drawLine((int) (pixels + 10), bottom, (int) (pixels + 10), (bottom - (8 * pixelDensity)), scaleShadow); + canvas.drawLine(8, bottom, (int) (pixels + 12), bottom, scaleShadow); + canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scaleShadow); + + canvas.drawLine(11, bottom, 11, (bottom - (6 * pixelDensity)), scale); + canvas.drawLine((int) (pixels + 9), bottom, (int) (pixels + 9), (bottom - (6 * pixelDensity)), scale); + canvas.drawLine(10, bottom, (int) (pixels + 10), bottom, scale); + canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale); } - @Override - public OverlayImpl getOverlayImpl() { - return ovlImpl; - } + @Override + public OverlayImpl getOverlayImpl() { + return ovlImpl; + } } diff --git a/src/cgeo/geocaching/mapcommon/cgUsersOverlay.java b/src/cgeo/geocaching/mapcommon/cgUsersOverlay.java index ce6f236..664a37d 100644 --- a/src/cgeo/geocaching/mapcommon/cgUsersOverlay.java +++ b/src/cgeo/geocaching/mapcommon/cgUsersOverlay.java @@ -1,9 +1,14 @@ package cgeo.geocaching.mapcommon; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import cgeo.geocaching.R; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgUser; +import cgeo.geocaching.cgeodetail; +import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; +import cgeo.geocaching.mapinterfaces.OverlayBase; +import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; import org.apache.commons.lang3.StringUtils; @@ -14,174 +19,170 @@ import android.content.Intent; import android.graphics.Canvas; import android.graphics.Point; import android.util.Log; -import cgeo.geocaching.R; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgUser; -import cgeo.geocaching.cgeodetail; -import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; -import cgeo.geocaching.mapinterfaces.OverlayBase; -import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class cgUsersOverlay extends ItemizedOverlayBase implements OverlayBase { - private List<UserOverlayItemImpl> items = new ArrayList<UserOverlayItemImpl>(); - private Context context = null; - private final Pattern patternGeocode = Pattern.compile("^(GC[A-Z0-9]+)(\\: ?(.+))?$", Pattern.CASE_INSENSITIVE); - - public cgUsersOverlay(ItemizedOverlayImpl ovlImplIn, Context contextIn) { - super(ovlImplIn); - populate(); - - context = contextIn; - } - - protected void updateItems(UserOverlayItemImpl item) { - List<UserOverlayItemImpl> itemsPre = new ArrayList<UserOverlayItemImpl>(); - itemsPre.add(item); - - updateItems(itemsPre); - } - - public void updateItems(List<UserOverlayItemImpl> itemsPre) { - if (itemsPre == null) { - return; - } - - for (UserOverlayItemImpl item : itemsPre) { - item.setMarker(boundCenter(item.getMarker(0))); - } - - items.clear(); - - if (itemsPre.size() > 0) { - items = new ArrayList<UserOverlayItemImpl>(itemsPre); - } - - setLastFocusedItemIndex(-1); // to reset tap during data change - populate(); - } - - @Override - public boolean onTap(int index) { - try { - if (items.size() <= index) { - return false; - } - - final UserOverlayItemImpl item = items.get(index); - final cgUser user = item.getUser(); - - // set action - String action = null; - String geocode = null; - final Matcher matcherGeocode = patternGeocode.matcher(user.action.trim()); - - if (user.action.length() == 0 || user.action.equalsIgnoreCase("pending")) { - action = "Looking around"; - } else if (user.action.equalsIgnoreCase("tweeting")) { - action = "Tweeting"; - } else if (matcherGeocode.find()) { - if (matcherGeocode.group(1) != null) { - geocode = matcherGeocode.group(1).trim().toUpperCase(); - } - if (matcherGeocode.group(3) != null) { - action = "Heading to " + geocode + " (" + matcherGeocode.group(3).trim() + ")"; - } else { - action = "Heading to " + geocode; - } - } else { - action = user.action; - } - - // set icon - int icon = -1; - if (user.client.equalsIgnoreCase("c:geo")) { - icon = R.drawable.client_cgeo; - } else if (user.client.equalsIgnoreCase("preCaching")) { - icon = R.drawable.client_precaching; - } else if (user.client.equalsIgnoreCase("Handy Geocaching")) { - icon = R.drawable.client_handygeocaching; - } - - final AlertDialog.Builder dialog = new AlertDialog.Builder(context); - if (icon > -1) { - dialog.setIcon(icon); - } - dialog.setTitle(user.username); - dialog.setMessage(action); - dialog.setCancelable(true); - if (StringUtils.isNotBlank(geocode)) { - dialog.setPositiveButton(geocode + "?", new cacheDetails(geocode)); - } - dialog.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - - return true; - } catch (Exception e) { - Log.e(cgSettings.tag, "cgUsersOverlay.onTap: " + e.toString()); - } - - return false; - } - - @Override - public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - super.draw(canvas, mapView, false); - } - - @Override - public void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - super.drawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); - } - - @Override - public UserOverlayItemImpl createItem(int index) { - try { - return items.get(index); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgUsersOverlay.createItem: " + e.toString()); - } - - return null; - } - - @Override - public int size() { - try { - return items.size(); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgUsersOverlay.size: " + e.toString()); - } - - return 0; - } - - private class cacheDetails implements DialogInterface.OnClickListener { - - private String geocode = null; - - public cacheDetails(String geocodeIn) { - geocode = geocodeIn; - } - - public void onClick(DialogInterface dialog, int id) { - if (geocode != null) { - Intent detailIntent = new Intent(context, cgeodetail.class); - detailIntent.putExtra("geocode", geocode); - context.startActivity(detailIntent); - } - - dialog.cancel(); - } - } + private List<UserOverlayItemImpl> items = new ArrayList<UserOverlayItemImpl>(); + private Context context = null; + private final Pattern patternGeocode = Pattern.compile("^(GC[A-Z0-9]+)(\\: ?(.+))?$", Pattern.CASE_INSENSITIVE); + + public cgUsersOverlay(ItemizedOverlayImpl ovlImplIn, Context contextIn) { + super(ovlImplIn); + populate(); + + context = contextIn; + } + + protected void updateItems(UserOverlayItemImpl item) { + List<UserOverlayItemImpl> itemsPre = new ArrayList<UserOverlayItemImpl>(); + itemsPre.add(item); + + updateItems(itemsPre); + } + + public void updateItems(List<UserOverlayItemImpl> itemsPre) { + if (itemsPre == null) { + return; + } + + for (UserOverlayItemImpl item : itemsPre) { + item.setMarker(boundCenter(item.getMarker(0))); + } + + items.clear(); + + if (itemsPre.size() > 0) { + items = new ArrayList<UserOverlayItemImpl>(itemsPre); + } + + setLastFocusedItemIndex(-1); // to reset tap during data change + populate(); + } + + @Override + public boolean onTap(int index) { + try { + if (items.size() <= index) { + return false; + } + + final UserOverlayItemImpl item = items.get(index); + final cgUser user = item.getUser(); + + // set action + String action = null; + String geocode = null; + final Matcher matcherGeocode = patternGeocode.matcher(user.action.trim()); + + if (user.action.length() == 0 || user.action.equalsIgnoreCase("pending")) { + action = "Looking around"; + } else if (user.action.equalsIgnoreCase("tweeting")) { + action = "Tweeting"; + } else if (matcherGeocode.find()) { + if (matcherGeocode.group(1) != null) { + geocode = matcherGeocode.group(1).trim().toUpperCase(); + } + if (matcherGeocode.group(3) != null) { + action = "Heading to " + geocode + " (" + matcherGeocode.group(3).trim() + ")"; + } else { + action = "Heading to " + geocode; + } + } else { + action = user.action; + } + + // set icon + int icon = -1; + if (user.client.equalsIgnoreCase("c:geo")) { + icon = R.drawable.client_cgeo; + } else if (user.client.equalsIgnoreCase("preCaching")) { + icon = R.drawable.client_precaching; + } else if (user.client.equalsIgnoreCase("Handy Geocaching")) { + icon = R.drawable.client_handygeocaching; + } + + final AlertDialog.Builder dialog = new AlertDialog.Builder(context); + if (icon > -1) { + dialog.setIcon(icon); + } + dialog.setTitle(user.username); + dialog.setMessage(action); + dialog.setCancelable(true); + if (StringUtils.isNotBlank(geocode)) { + dialog.setPositiveButton(geocode + "?", new cacheDetails(geocode)); + } + dialog.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + AlertDialog alert = dialog.create(); + alert.show(); + + return true; + } catch (Exception e) { + Log.e(cgSettings.tag, "cgUsersOverlay.onTap: " + e.toString()); + } + + return false; + } + + @Override + public void draw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + super.draw(canvas, mapView, false); + } + + @Override + public void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + super.drawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel); + } + + @Override + public UserOverlayItemImpl createItem(int index) { + try { + return items.get(index); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgUsersOverlay.createItem: " + e.toString()); + } + + return null; + } + + @Override + public int size() { + try { + return items.size(); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgUsersOverlay.size: " + e.toString()); + } + + return 0; + } + + private class cacheDetails implements DialogInterface.OnClickListener { + + private String geocode = null; + + public cacheDetails(String geocodeIn) { + geocode = geocodeIn; + } + + public void onClick(DialogInterface dialog, int id) { + if (geocode != null) { + Intent detailIntent = new Intent(context, cgeodetail.class); + detailIntent.putExtra("geocode", geocode); + context.startActivity(detailIntent); + } + + dialog.cancel(); + } + } } diff --git a/src/cgeo/geocaching/mapcommon/cgeomap.java b/src/cgeo/geocaching/mapcommon/cgeomap.java index f6bd400..9e33dbe 100644 --- a/src/cgeo/geocaching/mapcommon/cgeomap.java +++ b/src/cgeo/geocaching/mapcommon/cgeomap.java @@ -1,11 +1,28 @@ package cgeo.geocaching.mapcommon; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; +import cgeo.geocaching.R; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgCoord; +import cgeo.geocaching.cgDirection; +import cgeo.geocaching.cgGeo; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.cgSettings.mapSourceEnum; +import cgeo.geocaching.cgUpdateDir; +import cgeo.geocaching.cgUpdateLoc; +import cgeo.geocaching.cgUser; +import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.mapinterfaces.ActivityImpl; +import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.MapControllerImpl; +import cgeo.geocaching.mapinterfaces.MapFactory; +import cgeo.geocaching.mapinterfaces.MapViewImpl; +import cgeo.geocaching.mapinterfaces.OnDragListener; +import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; import org.apache.commons.lang3.StringUtils; @@ -25,1769 +42,1753 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; -import android.view.WindowManager; import android.view.ViewGroup.LayoutParams; +import android.view.WindowManager; import android.widget.ImageSwitcher; import android.widget.ImageView; -import android.widget.TextView; import android.widget.ImageView.ScaleType; +import android.widget.TextView; import android.widget.ViewSwitcher.ViewFactory; -import cgeo.geocaching.R; -import cgeo.geocaching.cgBase; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgCoord; -import cgeo.geocaching.cgDirection; -import cgeo.geocaching.cgGeo; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.cgUpdateDir; -import cgeo.geocaching.cgUpdateLoc; -import cgeo.geocaching.cgUser; -import cgeo.geocaching.cgWaypoint; -import cgeo.geocaching.cgeoapplication; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.cgSettings.mapSourceEnum; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.mapinterfaces.ActivityImpl; -import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.MapControllerImpl; -import cgeo.geocaching.mapinterfaces.MapFactory; -import cgeo.geocaching.mapinterfaces.MapViewImpl; -import cgeo.geocaching.mapinterfaces.OnDragListener; -import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; public class cgeomap extends MapBase implements OnDragListener, ViewFactory { - private static final int MENU_SELECT_MAPVIEW = 1; - private static final int MENU_MAP_LIVE = 2; - private static final int MENU_STORE_CACHES = 3; - private static final int MENU_TRAIL_MODE = 4; - private static final int MENU_CIRCLE_MODE = 5; - - private static final int SUBMENU_VIEW_GOOGLE_MAP = 10; - private static final int SUBMENU_VIEW_GOOGLE_SAT = 11; - private static final int SUBMENU_VIEW_MF_MAPNIK = 13; - private static final int SUBMENU_VIEW_MF_OSMARENDER = 14; - private static final int SUBMENU_VIEW_MF_CYCLEMAP = 15; - private static final int SUBMENU_VIEW_MF_OFFLINE = 16; - - private Resources res = null; - private Activity activity = null; - private MapViewImpl mapView = null; - private MapControllerImpl mapController = null; - private cgSettings settings = null; - private cgBase base = null; - private cgeoapplication app = null; - private SharedPreferences.Editor prefsEdit = null; - private cgGeo geo = null; - private cgDirection dir = null; - private cgUpdateLoc geoUpdate = new UpdateLoc(); - private cgUpdateDir dirUpdate = new UpdateDir(); - // from intent - private boolean fromDetailIntent = false; - private String searchIdIntent = null; - private String geocodeIntent = null; - private Geopoint coordsIntent = null; - private String waypointTypeIntent = null; - private int[] mapStateIntent = null; - // status data - private UUID searchId = null; - private String token = null; - private boolean noMapTokenShowed = false; - // map status data - private boolean followMyLocation = false; - private Integer centerLatitude = null; - private Integer centerLongitude = null; - private Integer spanLatitude = null; - private Integer spanLongitude = null; - private Integer centerLatitudeUsers = null; - private Integer centerLongitudeUsers = null; - private Integer spanLatitudeUsers = null; - private Integer spanLongitudeUsers = null; - // thread - private LoadTimer loadTimer = null; - private UsersTimer usersTimer = null; - private LoadThread loadThread = null; - private DownloadThread downloadThread = null; - private DisplayThread displayThread = null; - private UsersThread usersThread = null; - private DisplayUsersThread displayUsersThread = null; - private LoadDetails loadDetailsThread = null; - private volatile long loadThreadRun = 0L; - private volatile long usersThreadRun = 0L; - private volatile boolean downloaded = false; - // overlays - private cgMapOverlay overlayCaches = null; - private cgUsersOverlay overlayUsers = null; - private cgOverlayScale overlayScale = null; - private cgMapMyOverlay overlayMyLoc = null; - // data for overlays - private int cachesCnt = 0; - private Map<Integer, Drawable> iconsCache = new HashMap<Integer, Drawable>(); - private List<cgCache> caches = new ArrayList<cgCache>(); - private List<cgUser> users = new ArrayList<cgUser>(); - private List<cgCoord> coordinates = new ArrayList<cgCoord>(); - // storing for offline - private ProgressDialog waitDialog = null; - private int detailTotal = 0; - private int detailProgress = 0; - private Long detailProgressTime = 0L; - // views - private ImageSwitcher myLocSwitch = null; - // other things - private boolean live = true; // live map (live, dead) or rest (displaying caches on map) - private boolean liveChanged = false; // previous state for loadTimer - private boolean centered = false; // if map is already centered - private boolean alreadyCentered = false; // -""- for setting my location - // handlers - final private Handler displayHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - final int what = msg.what; - - if (what == 0) { - // set title - final StringBuilder title = new StringBuilder(); - - if (live) { - title.append(res.getString(R.string.map_live)); - } else { - title.append(res.getString(R.string.map_map)); - } - - if (caches != null && cachesCnt > 0) { - title.append(" ["); - title.append(caches.size()); - title.append(']'); - } - - ActivityMixin.setTitle(activity, title.toString()); - } else if (what == 1 && mapView != null) { - mapView.invalidate(); - } - } - }; - final private Handler showProgressHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - final int what = msg.what; - - if (what == 0) { - ActivityMixin.showProgress(activity, false); - } else if (what == 1) { - ActivityMixin.showProgress(activity, true); - } - } - }; - final private Handler loadDetailsHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (msg.what == 0) { - if (waitDialog != null) { - int secondsElapsed = (int)((System.currentTimeMillis() - detailProgressTime) / 1000); - int secondsRemaining; - if (detailProgress > 0) //DP can be zero and cause devisionByZero - secondsRemaining = (detailTotal - detailProgress) * secondsElapsed / detailProgress; - else - secondsRemaining = (detailTotal - detailProgress) * secondsElapsed; - - waitDialog.setProgress(detailProgress); - if (secondsRemaining < 40) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); - } else if (secondsRemaining < 90) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%d", (secondsRemaining / 60)) + " " + res.getString(R.string.caches_eta_min)); - } else { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%d", (secondsRemaining / 60)) + " " + res.getString(R.string.caches_eta_mins)); - } - } - } else { - if (waitDialog != null) { - waitDialog.dismiss(); - waitDialog.setOnCancelListener(null); - } - - if (geo == null) { - geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(activity, dirUpdate); - } - } - } - }; - final private Handler noMapTokenHandler = new Handler() { - - @Override - public void handleMessage(Message msg) { - if (!noMapTokenShowed) { - ActivityMixin.showToast(activity, res.getString(R.string.map_token_err)); - - noMapTokenShowed = true; - } - } - }; - - public cgeomap(ActivityImpl activity) { - super(activity); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // class init - res = this.getResources(); - activity = this.getActivity(); - app = (cgeoapplication) activity.getApplication(); - app.setAction(null); - settings = new cgSettings(activity, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); - base = new cgBase(app, settings, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); - prefsEdit = activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE).edit(); - MapFactory mapFactory = settings.getMapFactory(); - - // reset status - noMapTokenShowed = false; - - // set layout - activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - - // set layout - ActivityMixin.setTheme(activity); - activity.setContentView(settings.getMapFactory().getMapLayoutId()); - ActivityMixin.setTitle(activity, res.getString(R.string.map_map)); - - if (geo == null) { - geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(activity, dirUpdate); - } - - // initialize map - mapView = (MapViewImpl) activity.findViewById(mapFactory.getMapViewId()); - mapView.setMapSource(settings); - if (!mapView.needsScaleOverlay()) { - mapView.setBuiltinScale(true); - } - mapView.setBuiltInZoomControls(true); - mapView.displayZoomControls(true); - mapView.preLoad(); - mapView.setOnDragListener(this); - - // initialize overlays - mapView.clearOverlays(); - - if (overlayMyLoc == null) { - overlayMyLoc = mapView.createAddPositionOverlay(activity, settings); - } - - if (settings.publicLoc > 0 && overlayUsers == null) { - overlayUsers = mapView.createAddUsersOverlay(activity, getResources().getDrawable(R.drawable.user_location)); - } - - if (overlayCaches == null) { - overlayCaches = mapView.createAddMapOverlay(settings, mapView.getContext(), getResources().getDrawable(R.drawable.marker), fromDetailIntent); - } - - if (overlayScale == null && mapView.needsScaleOverlay()) { - overlayScale = mapView.createAddScaleOverlay(activity, settings); - } - - mapView.invalidate(); - - mapController = mapView.getMapController(); - mapController.setZoom(settings.mapzoom); - - // start location and directory services - if (geo != null) { - geoUpdate.updateLoc(geo); - } - if (dir != null) { - dirUpdate.updateDir(dir); - } - - // get parameters - Bundle extras = activity.getIntent().getExtras(); - if (extras != null) { - fromDetailIntent = extras.getBoolean("detail"); - searchIdIntent = extras.getString("searchid"); - geocodeIntent = extras.getString("geocode"); - final double latitudeIntent = extras.getDouble("latitude"); - final double longitudeIntent = extras.getDouble("longitude"); - coordsIntent = new Geopoint(latitudeIntent, longitudeIntent); - waypointTypeIntent = extras.getString("wpttype"); - mapStateIntent = extras.getIntArray("mapstate"); - - if ("".equals(searchIdIntent)) { - searchIdIntent = null; - } - if (coordsIntent.getLatitude() == 0.0 || coordsIntent.getLongitude() == 0.0) { - coordsIntent = null; - } - } - - // live or death - if (searchIdIntent == null && geocodeIntent == null && coordsIntent == null) { - live = true; - } else { - live = false; - } - - if (null == mapStateIntent) { - if (live) { - followMyLocation = true; - } else { - followMyLocation = false; - } - } else { - followMyLocation = 1 == mapStateIntent[3] ? true : false; - } - if (geocodeIntent != null || searchIdIntent != null || coordsIntent != null || mapStateIntent != null) { - centerMap(geocodeIntent, searchIdIntent, coordsIntent, mapStateIntent); - } - - // prepare my location button - myLocSwitch = (ImageSwitcher) activity.findViewById(R.id.my_position); - myLocSwitch.setFactory(this); - myLocSwitch.setInAnimation(activity, android.R.anim.fade_in); - myLocSwitch.setOutAnimation(activity, android.R.anim.fade_out); - myLocSwitch.setOnClickListener(new MyLocationListener()); - switchMyLocationButton(); - - startTimer(); - - // show the filter warning bar if the filter is set - if (settings.cacheType != null) { - String cacheType = cgBase.cacheTypesInv.get(settings.cacheType); - ((TextView)activity.findViewById(R.id.filter_text)).setText(cacheType); + private static final int MENU_SELECT_MAPVIEW = 1; + private static final int MENU_MAP_LIVE = 2; + private static final int MENU_STORE_CACHES = 3; + private static final int MENU_TRAIL_MODE = 4; + private static final int MENU_CIRCLE_MODE = 5; + + private static final int SUBMENU_VIEW_GOOGLE_MAP = 10; + private static final int SUBMENU_VIEW_GOOGLE_SAT = 11; + private static final int SUBMENU_VIEW_MF_MAPNIK = 13; + private static final int SUBMENU_VIEW_MF_OSMARENDER = 14; + private static final int SUBMENU_VIEW_MF_CYCLEMAP = 15; + private static final int SUBMENU_VIEW_MF_OFFLINE = 16; + + private Resources res = null; + private Activity activity = null; + private MapViewImpl mapView = null; + private MapControllerImpl mapController = null; + private cgSettings settings = null; + private cgBase base = null; + private cgeoapplication app = null; + private SharedPreferences.Editor prefsEdit = null; + private cgGeo geo = null; + private cgDirection dir = null; + private cgUpdateLoc geoUpdate = new UpdateLoc(); + private cgUpdateDir dirUpdate = new UpdateDir(); + // from intent + private boolean fromDetailIntent = false; + private String searchIdIntent = null; + private String geocodeIntent = null; + private Geopoint coordsIntent = null; + private String waypointTypeIntent = null; + private int[] mapStateIntent = null; + // status data + private UUID searchId = null; + private String token = null; + private boolean noMapTokenShowed = false; + // map status data + private boolean followMyLocation = false; + private Integer centerLatitude = null; + private Integer centerLongitude = null; + private Integer spanLatitude = null; + private Integer spanLongitude = null; + private Integer centerLatitudeUsers = null; + private Integer centerLongitudeUsers = null; + private Integer spanLatitudeUsers = null; + private Integer spanLongitudeUsers = null; + // thread + private LoadTimer loadTimer = null; + private UsersTimer usersTimer = null; + private LoadThread loadThread = null; + private DownloadThread downloadThread = null; + private DisplayThread displayThread = null; + private UsersThread usersThread = null; + private DisplayUsersThread displayUsersThread = null; + private LoadDetails loadDetailsThread = null; + private volatile long loadThreadRun = 0L; + private volatile long usersThreadRun = 0L; + private volatile boolean downloaded = false; + // overlays + private cgMapOverlay overlayCaches = null; + private cgUsersOverlay overlayUsers = null; + private cgOverlayScale overlayScale = null; + private cgMapMyOverlay overlayMyLoc = null; + // data for overlays + private int cachesCnt = 0; + private Map<Integer, Drawable> iconsCache = new HashMap<Integer, Drawable>(); + private List<cgCache> caches = new ArrayList<cgCache>(); + private List<cgUser> users = new ArrayList<cgUser>(); + private List<cgCoord> coordinates = new ArrayList<cgCoord>(); + // storing for offline + private ProgressDialog waitDialog = null; + private int detailTotal = 0; + private int detailProgress = 0; + private Long detailProgressTime = 0L; + // views + private ImageSwitcher myLocSwitch = null; + // other things + private boolean live = true; // live map (live, dead) or rest (displaying caches on map) + private boolean liveChanged = false; // previous state for loadTimer + private boolean centered = false; // if map is already centered + private boolean alreadyCentered = false; // -""- for setting my location + // handlers + final private Handler displayHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + final int what = msg.what; + + if (what == 0) { + // set title + final StringBuilder title = new StringBuilder(); + + if (live) { + title.append(res.getString(R.string.map_live)); + } else { + title.append(res.getString(R.string.map_map)); + } + + if (caches != null && cachesCnt > 0) { + title.append(" ["); + title.append(caches.size()); + title.append(']'); + } + + ActivityMixin.setTitle(activity, title.toString()); + } else if (what == 1 && mapView != null) { + mapView.invalidate(); + } + } + }; + final private Handler showProgressHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + final int what = msg.what; + + if (what == 0) { + ActivityMixin.showProgress(activity, false); + } else if (what == 1) { + ActivityMixin.showProgress(activity, true); + } + } + }; + final private Handler loadDetailsHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (msg.what == 0) { + if (waitDialog != null) { + int secondsElapsed = (int) ((System.currentTimeMillis() - detailProgressTime) / 1000); + int secondsRemaining; + if (detailProgress > 0) //DP can be zero and cause devisionByZero + secondsRemaining = (detailTotal - detailProgress) * secondsElapsed / detailProgress; + else + secondsRemaining = (detailTotal - detailProgress) * secondsElapsed; + + waitDialog.setProgress(detailProgress); + if (secondsRemaining < 40) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); + } else if (secondsRemaining < 90) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%d", (secondsRemaining / 60)) + " " + res.getString(R.string.caches_eta_min)); + } else { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%d", (secondsRemaining / 60)) + " " + res.getString(R.string.caches_eta_mins)); + } + } + } else { + if (waitDialog != null) { + waitDialog.dismiss(); + waitDialog.setOnCancelListener(null); + } + + if (geo == null) { + geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(activity, dirUpdate); + } + } + } + }; + final private Handler noMapTokenHandler = new Handler() { + + @Override + public void handleMessage(Message msg) { + if (!noMapTokenShowed) { + ActivityMixin.showToast(activity, res.getString(R.string.map_token_err)); + + noMapTokenShowed = true; + } + } + }; + + public cgeomap(ActivityImpl activity) { + super(activity); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // class init + res = this.getResources(); + activity = this.getActivity(); + app = (cgeoapplication) activity.getApplication(); + app.setAction(null); + settings = new cgSettings(activity, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); + base = new cgBase(app, settings, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); + prefsEdit = activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE).edit(); + MapFactory mapFactory = settings.getMapFactory(); + + // reset status + noMapTokenShowed = false; + + // set layout + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + // set layout + ActivityMixin.setTheme(activity); + activity.setContentView(settings.getMapFactory().getMapLayoutId()); + ActivityMixin.setTitle(activity, res.getString(R.string.map_map)); + + if (geo == null) { + geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(activity, dirUpdate); + } + + // initialize map + mapView = (MapViewImpl) activity.findViewById(mapFactory.getMapViewId()); + mapView.setMapSource(settings); + if (!mapView.needsScaleOverlay()) { + mapView.setBuiltinScale(true); + } + mapView.setBuiltInZoomControls(true); + mapView.displayZoomControls(true); + mapView.preLoad(); + mapView.setOnDragListener(this); + + // initialize overlays + mapView.clearOverlays(); + + if (overlayMyLoc == null) { + overlayMyLoc = mapView.createAddPositionOverlay(activity, settings); + } + + if (settings.publicLoc > 0 && overlayUsers == null) { + overlayUsers = mapView.createAddUsersOverlay(activity, getResources().getDrawable(R.drawable.user_location)); + } + + if (overlayCaches == null) { + overlayCaches = mapView.createAddMapOverlay(settings, mapView.getContext(), getResources().getDrawable(R.drawable.marker), fromDetailIntent); + } + + if (overlayScale == null && mapView.needsScaleOverlay()) { + overlayScale = mapView.createAddScaleOverlay(activity, settings); + } + + mapView.invalidate(); + + mapController = mapView.getMapController(); + mapController.setZoom(settings.mapzoom); + + // start location and directory services + if (geo != null) { + geoUpdate.updateLoc(geo); + } + if (dir != null) { + dirUpdate.updateDir(dir); + } + + // get parameters + Bundle extras = activity.getIntent().getExtras(); + if (extras != null) { + fromDetailIntent = extras.getBoolean("detail"); + searchIdIntent = extras.getString("searchid"); + geocodeIntent = extras.getString("geocode"); + final double latitudeIntent = extras.getDouble("latitude"); + final double longitudeIntent = extras.getDouble("longitude"); + coordsIntent = new Geopoint(latitudeIntent, longitudeIntent); + waypointTypeIntent = extras.getString("wpttype"); + mapStateIntent = extras.getIntArray("mapstate"); + + if ("".equals(searchIdIntent)) { + searchIdIntent = null; + } + if (coordsIntent.getLatitude() == 0.0 || coordsIntent.getLongitude() == 0.0) { + coordsIntent = null; + } + } + + // live or death + if (searchIdIntent == null && geocodeIntent == null && coordsIntent == null) { + live = true; + } else { + live = false; + } + + if (null == mapStateIntent) { + if (live) { + followMyLocation = true; + } else { + followMyLocation = false; + } + } else { + followMyLocation = 1 == mapStateIntent[3] ? true : false; + } + if (geocodeIntent != null || searchIdIntent != null || coordsIntent != null || mapStateIntent != null) { + centerMap(geocodeIntent, searchIdIntent, coordsIntent, mapStateIntent); + } + + // prepare my location button + myLocSwitch = (ImageSwitcher) activity.findViewById(R.id.my_position); + myLocSwitch.setFactory(this); + myLocSwitch.setInAnimation(activity, android.R.anim.fade_in); + myLocSwitch.setOutAnimation(activity, android.R.anim.fade_out); + myLocSwitch.setOnClickListener(new MyLocationListener()); + switchMyLocationButton(); + + startTimer(); + + // show the filter warning bar if the filter is set + if (settings.cacheType != null) { + String cacheType = cgBase.cacheTypesInv.get(settings.cacheType); + ((TextView) activity.findViewById(R.id.filter_text)).setText(cacheType); activity.findViewById(R.id.filter_bar).setVisibility(View.VISIBLE); - } - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); - - app.setAction(null); - if (geo == null) { - geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(activity, dirUpdate); - } - - if (geo != null) { - geoUpdate.updateLoc(geo); - } - if (dir != null) { - dirUpdate.updateDir(dir); - } - - startTimer(); - } - - @Override - public void onStop() { - if (loadTimer != null) { - loadTimer.stopIt(); - loadTimer = null; - } - - if (usersTimer != null) { - usersTimer.stopIt(); - usersTimer = null; - } - - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - savePrefs(); - - if (mapView != null) { - mapView.destroyDrawingCache(); - } - - super.onStop(); - } - - @Override - public void onPause() { - if (loadTimer != null) { - loadTimer.stopIt(); - loadTimer = null; - } - - if (usersTimer != null) { - usersTimer.stopIt(); - usersTimer = null; - } - - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - savePrefs(); - - if (mapView != null) { - mapView.destroyDrawingCache(); - } - - super.onPause(); - } - - @Override - public void onDestroy() { - if (loadTimer != null) { - loadTimer.stopIt(); - loadTimer = null; - } - - if (usersTimer != null) { - usersTimer.stopIt(); - usersTimer = null; - } - - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - savePrefs(); - - if (mapView != null) { - mapView.destroyDrawingCache(); - } - - super.onDestroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - SubMenu submenu = menu.addSubMenu(1, MENU_SELECT_MAPVIEW, 0, res.getString(R.string.map_view_map)).setIcon(android.R.drawable.ic_menu_more); - addMapViewMenuItems(submenu); - - menu.add(0, MENU_MAP_LIVE, 0, res.getString(R.string.map_live_disable)).setIcon(android.R.drawable.ic_menu_close_clear_cancel); - menu.add(0, MENU_STORE_CACHES, 0, res.getString(R.string.caches_store_offline)).setIcon(android.R.drawable.ic_menu_set_as).setEnabled(false); - menu.add(0, MENU_TRAIL_MODE, 0, res.getString(R.string.map_trail_hide)).setIcon(android.R.drawable.ic_menu_recent_history); - menu.add(0, MENU_CIRCLE_MODE, 0, res.getString(R.string.map_circles_hide)).setIcon(android.R.drawable.ic_menu_view); - - return true; - } - - private void addMapViewMenuItems(final Menu menu) { - String[] mapViews = res.getStringArray(R.array.map_sources); - mapSourceEnum mapSource = settings.mapSource; - - menu.add(1, SUBMENU_VIEW_GOOGLE_MAP, 0, mapViews[0]).setCheckable(true).setChecked(mapSource == mapSourceEnum.googleMap); - menu.add(1, SUBMENU_VIEW_GOOGLE_SAT, 0, mapViews[1]).setCheckable(true).setChecked(mapSource == mapSourceEnum.googleSat); - menu.add(1, SUBMENU_VIEW_MF_MAPNIK, 0, mapViews[2]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeMapnik); - menu.add(1, SUBMENU_VIEW_MF_OSMARENDER, 0, mapViews[3]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeOsmarender); - menu.add(1, SUBMENU_VIEW_MF_CYCLEMAP, 0, mapViews[4]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeCycle); - menu.add(1, SUBMENU_VIEW_MF_OFFLINE, 0, mapViews[5]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeOffline); - menu.setGroupCheckable(1, true, true); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - MenuItem item; - try { - item = menu.findItem(MENU_TRAIL_MODE); // show trail - if (settings.maptrail == 1) { - item.setTitle(res.getString(R.string.map_trail_hide)); - } else { - item.setTitle(res.getString(R.string.map_trail_show)); - } - - item = menu.findItem(MENU_MAP_LIVE); // live map - if (live == false) { - item.setEnabled(false); - item.setTitle(res.getString(R.string.map_live_enable)); - } else { - if (settings.maplive == 1) { - item.setTitle(res.getString(R.string.map_live_disable)); - } else { - item.setTitle(res.getString(R.string.map_live_enable)); - } - } - - item = menu.findItem(MENU_STORE_CACHES); // store loaded - if (live && !isLoading() && app.getNotOfflineCount(searchId) > 0 && caches != null && caches.size() > 0) { - item.setEnabled(true); - } else { - item.setEnabled(false); - } - - item = menu.findItem(MENU_CIRCLE_MODE); // show circles - if (overlayCaches != null && overlayCaches.getCircles()) { - item.setTitle(res.getString(R.string.map_circles_hide)); - } else { - item.setTitle(res.getString(R.string.map_circles_show)); - } - - item = menu.findItem(SUBMENU_VIEW_MF_OFFLINE); - if (settings.hasValidMapFile()) { - item.setEnabled(true); - } else { - item.setEnabled(false); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeomap.onPrepareOptionsMenu: " + e.toString()); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int id = item.getItemId(); - - if (id == MENU_TRAIL_MODE) { - if (settings.maptrail == 1) { - prefsEdit.putInt("maptrail", 0); - prefsEdit.commit(); - - settings.maptrail = 0; - } else { - prefsEdit.putInt("maptrail", 1); - prefsEdit.commit(); - - settings.maptrail = 1; - } - } else if (id == MENU_MAP_LIVE) { - if (settings.maplive == 1) { - settings.liveMapDisable(); - } else { - settings.liveMapEnable(); - } - liveChanged = true; - searchId = null; - searchIdIntent = null; - } else if (id == MENU_STORE_CACHES) { - if (live && !isLoading() && caches != null && !caches.isEmpty()) { - final List<String> geocodes = new ArrayList<String>(); - - List<cgCache> cachesProtected = new ArrayList<cgCache>(caches); - try { - if (cachesProtected.size() > 0) { - final GeoPointImpl mapCenter = mapView.getMapViewCenter(); - final int mapCenterLat = mapCenter.getLatitudeE6(); - final int mapCenterLon = mapCenter.getLongitudeE6(); - final int mapSpanLat = mapView.getLatitudeSpan(); - final int mapSpanLon = mapView.getLongitudeSpan(); - - for (cgCache oneCache : cachesProtected) { - if (oneCache != null && oneCache.coords != null) { - if (cgBase.isCacheInViewPort(mapCenterLat, mapCenterLon, mapSpanLat, mapSpanLon, oneCache.coords) && app.isOffline(oneCache.geocode, null) == false) { - geocodes.add(oneCache.geocode); - } - } - } - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeomap.onOptionsItemSelected.#4: " + e.toString()); - } - - detailTotal = geocodes.size(); - - if (detailTotal == 0) { - ActivityMixin.showToast(activity, res.getString(R.string.warn_save_nothing)); - - return true; - } - - waitDialog = new ProgressDialog(activity); - waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - waitDialog.setCancelable(true); - waitDialog.setMax(detailTotal); - waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - public void onCancel(DialogInterface arg0) { - try { - if (loadDetailsThread != null) { - loadDetailsThread.stopIt(); - } - - if (geo == null) { - geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); - } - if (settings.useCompass == 1 && dir == null) { - dir = app.startDir(activity, dirUpdate); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.onPrepareOptionsMenu.onCancel: " + e.toString()); - } - } - }); - - Float etaTime = Float.valueOf((detailTotal * (float) 7) / 60); - if (etaTime < 0.4) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); - } else if (etaTime < 1.5) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%.0f", etaTime) + " " + res.getString(R.string.caches_eta_min)); - } else { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%.0f", etaTime) + " " + res.getString(R.string.caches_eta_mins)); - } - waitDialog.show(); - - detailProgressTime = System.currentTimeMillis(); - - loadDetailsThread = new LoadDetails(loadDetailsHandler, geocodes); - loadDetailsThread.start(); - - return true; - } - } else if (id == MENU_CIRCLE_MODE) { - if (overlayCaches == null) { - return false; - } - - overlayCaches.switchCircles(); - mapView.invalidate(); - - } else if (SUBMENU_VIEW_GOOGLE_MAP <= id && SUBMENU_VIEW_MF_OFFLINE >= id) { - - item.setChecked(true); - mapSourceEnum mapSource = getMapSourceFromMenuId(id); - - boolean mapRestartRequired = switchMapSource(mapSource); - - if (mapRestartRequired) { - // close old mapview - activity.finish(); - - // prepare information to restart a similar view - Intent mapIntent = new Intent(activity, settings.getMapFactory().getMapClass()); - - mapIntent.putExtra("detail", fromDetailIntent); - mapIntent.putExtra("searchid", searchIdIntent); - mapIntent.putExtra("geocode", geocodeIntent); - if (coordsIntent != null) { - mapIntent.putExtra("latitude", coordsIntent.getLatitude()); - mapIntent.putExtra("longitude", coordsIntent.getLongitude()); - } - mapIntent.putExtra("wpttype", waypointTypeIntent); - int[] mapState = new int[4]; - GeoPointImpl mapCenter = mapView.getMapViewCenter(); - mapState[0] = mapCenter.getLatitudeE6(); - mapState[1] = mapCenter.getLongitudeE6(); - mapState[2] = mapView.getMapZoomLevel(); - mapState[3] = followMyLocation ? 1 : 0; - mapIntent.putExtra("mapstate", mapState); - - // start the new map - activity.startActivity(mapIntent); - - } - - return true; - } - - - return false; - } - - private static mapSourceEnum getMapSourceFromMenuId(int menuItemId) { - - switch(menuItemId) { - case SUBMENU_VIEW_GOOGLE_MAP: - return mapSourceEnum.googleMap; - case SUBMENU_VIEW_GOOGLE_SAT: - return mapSourceEnum.googleSat; - case SUBMENU_VIEW_MF_OSMARENDER: - return mapSourceEnum.mapsforgeOsmarender; - case SUBMENU_VIEW_MF_MAPNIK: - return mapSourceEnum.mapsforgeMapnik; - case SUBMENU_VIEW_MF_CYCLEMAP: - return mapSourceEnum.mapsforgeCycle; - case SUBMENU_VIEW_MF_OFFLINE: - return mapSourceEnum.mapsforgeOffline; - default: - return mapSourceEnum.googleMap; - } - } - - private boolean switchMapSource(mapSourceEnum mapSource) { - - settings.mapSource = mapSource; - - prefsEdit.putInt("mapsource", settings.mapSource.ordinal()); - prefsEdit.commit(); - - boolean mapRestartRequired = settings.mapSource.isGoogleMapSource()!= settings.mapSourceUsed.isGoogleMapSource(); - - if (!mapRestartRequired) { - mapView.setMapSource(settings); - } - - return mapRestartRequired; - } - - private void savePrefs() { - if (mapView == null) { - return; - } - - if (prefsEdit == null) { - prefsEdit = activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE).edit(); - } - - prefsEdit.putInt("mapzoom", mapView.getMapZoomLevel()); - prefsEdit.commit(); - } - - // set center of map to my location - private void myLocationInMiddle() { - if (geo == null) { - return; - } - if (!followMyLocation) { - return; - } - - centerMap(geo.coordsNow); - } - - // class: update location - private class UpdateLoc extends cgUpdateLoc { - - @Override - public void updateLoc(cgGeo geo) { - if (geo == null) { - return; - } - - try { - boolean repaintRequired = false; - - if (overlayMyLoc == null && mapView != null) { - overlayMyLoc = mapView.createAddPositionOverlay(activity, settings); - } - - if (overlayMyLoc != null && geo.location != null) { - overlayMyLoc.setCoordinates(geo.location); - } - - if (geo.coordsNow != null) { - if (followMyLocation) { - myLocationInMiddle(); - } else { - repaintRequired = true; - } - } - - if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h - if (geo.bearingNow != null) { - overlayMyLoc.setHeading(geo.bearingNow); - } else { - overlayMyLoc.setHeading(0f); - } - repaintRequired = true; - } - - if (repaintRequired && mapView != null) { - mapView.repaintRequired(overlayMyLoc); - } - - } catch (Exception e) { - Log.w(cgSettings.tag, "Failed to update location."); - } - } - } - - // class: update direction - private class UpdateDir extends cgUpdateDir { - - @Override - public void updateDir(cgDirection dir) { - if (dir == null || dir.directionNow == null) { - return; - } - - if (overlayMyLoc != null && mapView != null && (geo == null || geo.speedNow == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h - overlayMyLoc.setHeading(dir.directionNow); - mapView.invalidate(); - } - } - } - - public void startTimer() { - if (coordsIntent != null) { - // display just one point - (new DisplayPointThread()).start(); - } else { - // start timer - if (loadTimer != null) { - loadTimer.stopIt(); - loadTimer = null; - } - loadTimer = new LoadTimer(); - loadTimer.start(); - } - - if (settings.publicLoc > 0) { - if (usersTimer != null) { - usersTimer.stopIt(); - usersTimer = null; - } - usersTimer = new UsersTimer(); - usersTimer.start(); - } - } - - // loading timer - private class LoadTimer extends Thread { - - private volatile boolean stop = false; - - public void stopIt() { - stop = true; - - if (loadThread != null) { - loadThread.stopIt(); - loadThread = null; - } - - if (downloadThread != null) { - downloadThread.stopIt(); - downloadThread = null; - } - - if (displayThread != null) { - displayThread.stopIt(); - displayThread = null; - } - } - - @Override - public void run() { - GeoPointImpl mapCenterNow; - int centerLatitudeNow; - int centerLongitudeNow; - int spanLatitudeNow; - int spanLongitudeNow; - boolean moved = false; - boolean force = false; - long currentTime = 0; - - while (!stop) { - try { - sleep(250); - - if (mapView != null) { - // get current viewport - mapCenterNow = mapView.getMapViewCenter(); - centerLatitudeNow = mapCenterNow.getLatitudeE6(); - centerLongitudeNow = mapCenterNow.getLongitudeE6(); - spanLatitudeNow = mapView.getLatitudeSpan(); - spanLongitudeNow = mapView.getLongitudeSpan(); - - // check if map moved or zoomed - moved = false; - force = false; - - if (liveChanged) { - moved = true; - force = true; - } else if (live && settings.maplive == 1 && downloaded == false) { - moved = true; - } else if (centerLatitude == null || centerLongitude == null) { - moved = true; - } else if (spanLatitude == null || spanLongitude == null) { - moved = true; - } else if (((Math.abs(spanLatitudeNow - spanLatitude) > 50) || (Math.abs(spanLongitudeNow - spanLongitude) > 50) || // changed zoom - (Math.abs(centerLatitudeNow - centerLatitude) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitude) > (spanLongitudeNow / 4)) // map moved - ) && (cachesCnt <= 0 || caches == null || caches.isEmpty() - || !cgBase.isInViewPort(centerLatitude, centerLongitude, centerLatitudeNow, centerLongitudeNow, spanLatitude, spanLongitude, spanLatitudeNow, spanLongitudeNow))) { - moved = true; - } - - if (moved && caches != null && centerLatitude != null && centerLongitude != null && ((Math.abs(centerLatitudeNow - centerLatitude) > (spanLatitudeNow * 1.2)) || (Math.abs(centerLongitudeNow - centerLongitude) > (spanLongitudeNow * 1.2)))) { - force = true; - } - - //LeeB - // save new values - if (moved) { - liveChanged = false; - - currentTime = System.currentTimeMillis(); - - if (1000 < (currentTime - loadThreadRun)) { - // from web - if (20000 < (currentTime - loadThreadRun)) { - force = true; // probably stucked thread - } - - if (force && loadThread != null && loadThread.isWorking()) { - loadThread.stopIt(); - - try { - sleep(100); - } catch (Exception e) { - // nothing - } - } - - if (loadThread != null && loadThread.isWorking()) { - continue; - } - - centerLatitude = centerLatitudeNow; - centerLongitude = centerLongitudeNow; - spanLatitude = spanLatitudeNow; - spanLongitude = spanLongitudeNow; - - showProgressHandler.sendEmptyMessage(1); // show progress - - loadThread = new LoadThread(centerLatitude, centerLongitude, spanLatitude, spanLongitude); - loadThread.setName("loadThread"); - loadThread.start(); //loadThread will kick off downloadThread once it's done - } - } - } - - if (!isLoading()) { - showProgressHandler.sendEmptyMessage(0); // hide progress - } - - yield(); - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeomap.LoadTimer.run: " + e.toString()); - } - } - } - } - - // loading timer - private class UsersTimer extends Thread { - - private volatile boolean stop = false; - - public void stopIt() { - stop = true; - - if (usersThread != null) { - usersThread.stopIt(); - usersThread = null; - } - - if (displayUsersThread != null) { - displayUsersThread.stopIt(); - displayUsersThread = null; - } - } - - @Override - public void run() { - GeoPointImpl mapCenterNow; - int centerLatitudeNow; - int centerLongitudeNow; - int spanLatitudeNow; - int spanLongitudeNow; - boolean moved = false; - long currentTime = 0; - - while (!stop) { - try { - sleep(250); - - if (mapView != null) { - // get current viewport - mapCenterNow = mapView.getMapViewCenter(); - centerLatitudeNow = mapCenterNow.getLatitudeE6(); - centerLongitudeNow = mapCenterNow.getLongitudeE6(); - spanLatitudeNow = mapView.getLatitudeSpan(); - spanLongitudeNow = mapView.getLongitudeSpan(); - - // check if map moved or zoomed - moved = false; - - currentTime = System.currentTimeMillis(); - - if (60000 < (currentTime - usersThreadRun)) { - moved = true; - } else if (centerLatitudeUsers == null || centerLongitudeUsers == null) { - moved = true; - } else if (spanLatitudeUsers == null || spanLongitudeUsers == null) { - moved = true; - } else if (((Math.abs(spanLatitudeNow - spanLatitudeUsers) > 50) || (Math.abs(spanLongitudeNow - spanLongitudeUsers) > 50) || // changed zoom - (Math.abs(centerLatitudeNow - centerLatitudeUsers) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitudeUsers) > (spanLongitudeNow / 4)) // map moved - ) && !cgBase.isInViewPort(centerLatitudeUsers, centerLongitudeUsers, centerLatitudeNow, centerLongitudeNow, spanLatitudeUsers, spanLongitudeUsers, spanLatitudeNow, spanLongitudeNow)) { - moved = true; - } - - // save new values - if (moved && (1000 < (currentTime - usersThreadRun))) { - if (usersThread != null && usersThread.isWorking()) { - continue; - } - - centerLatitudeUsers = centerLatitudeNow; - centerLongitudeUsers = centerLongitudeNow; - spanLatitudeUsers = spanLatitudeNow; - spanLongitudeUsers = spanLongitudeNow; - - usersThread = new UsersThread(centerLatitude, centerLongitude, spanLatitude, spanLongitude); - usersThread.start(); - } - } - - yield(); - } catch (Exception e) { - Log.w(cgSettings.tag, "cgeomap.LoadUsersTimer.run: " + e.toString()); - } - } - } - } - - // load caches from database - private class LoadThread extends DoThread { - - public LoadThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); - } - - @Override - public void run() { - try { - stop = false; - working = true; - loadThreadRun = System.currentTimeMillis(); - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - //LeeB - I think this can be done better: - //1. fetch and draw(in another thread) caches from the db (fast? db read will be the slow bit) - //2. fetch and draw(in another thread) and then insert into the db caches from geocaching.com - dont draw/insert if exist in memory? - - // stage 1 - pull and render from the DB only - - if (fromDetailIntent || StringUtils.isNotEmpty(searchIdIntent)) { - searchId = UUID.fromString(searchIdIntent); - } else { - if (!live || settings.maplive == 0) { - searchId = app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, settings.cacheType); - } else { - searchId = app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, settings.cacheType); - } - } - - if (searchId != null) { - downloaded = true; - } - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - caches = app.getCaches(searchId); - - //if in live map and stored caches are found / disables are also shown. - if (live && settings.maplive >= 1) { - final boolean excludeMine = settings.excludeMine > 0; - final boolean excludeDisabled = settings.excludeDisabled > 0; - - for (int i = caches.size() - 1; i >= 0; i--) { - cgCache cache = caches.get(i); - if ((cache.found && excludeMine) || (cache.own && excludeMine) || (cache.disabled && excludeDisabled)) { - caches.remove(i); - } - } - - } - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - //render - if (displayThread != null && displayThread.isWorking()) { - displayThread.stopIt(); - } - displayThread = new DisplayThread(centerLat, centerLon, spanLat, spanLon); - displayThread.start(); - - if (stop) { - displayThread.stopIt(); - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - //*** this needs to be in it's own thread - // stage 2 - pull and render from geocaching.com - //this should just fetch and insert into the db _and_ be cancel-able if the viewport changes - - if (live && settings.maplive >= 1) { - if (downloadThread != null && downloadThread.isWorking()) { - downloadThread.stopIt(); - } - downloadThread = new DownloadThread(centerLat, centerLon, spanLat, spanLon); - downloadThread.setName("downloadThread"); - downloadThread.start(); - } - } finally { - working = false; - } - } - } - - // load caches from internet - private class DownloadThread extends DoThread { - - public DownloadThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); - } - - @Override - public void run() { //first time we enter we have crappy long/lat.... - try { - stop = false; - working = true; - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); - double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); - double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); - double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); - double llCache; - - if (latMin > latMax) { - llCache = latMax; - latMax = latMin; - latMin = llCache; - } - if (lonMin > lonMax) { - llCache = lonMax; - lonMax = lonMin; - lonMin = llCache; - } - - //*** this needs to be in it's own thread - // stage 2 - pull and render from geocaching.com - //this should just fetch and insert into the db _and_ be cancel-able if the viewport changes - - if (token == null) { - token = base.getMapUserToken(noMapTokenHandler); - } - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - Map<String, String> params = new HashMap<String, String>(); - params.put("usertoken", token); - params.put("latitude-min", String.format((Locale) null, "%.6f", latMin)); - params.put("latitude-max", String.format((Locale) null, "%.6f", latMax)); - params.put("longitude-min", String.format((Locale) null, "%.6f", lonMin)); - params.put("longitude-max", String.format((Locale) null, "%.6f", lonMax)); - - searchId = base.searchByViewport(params, 0); - if (searchId != null) { - downloaded = true; - } - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - caches = app.getCaches(searchId, centerLat, centerLon, spanLat, spanLon); - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - //render - if (displayThread != null && displayThread.isWorking()) { - displayThread.stopIt(); - } - displayThread = new DisplayThread(centerLat, centerLon, spanLat, spanLon); - displayThread.start(); - - } finally { - working = false; - } - } - } - - // display (down)loaded caches - private class DisplayThread extends DoThread { - - public DisplayThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); - } - - @Override - public void run() { - try { - stop = false; - working = true; - - if (mapView == null || caches == null) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - // display caches - final List<cgCache> cachesProtected = new ArrayList<cgCache>(caches); - final List<CacheOverlayItemImpl> items = new ArrayList<CacheOverlayItemImpl>(); - - if (cachesProtected != null && !cachesProtected.isEmpty()) { - int icon = 0; - Drawable pin = null; - CacheOverlayItemImpl item = null; - - for (cgCache cacheOne : cachesProtected) { - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - if (cacheOne.coords == null) { - continue; - } - - final cgCoord coord = new cgCoord(cacheOne); - coordinates.add(coord); - - item = settings.getMapFactory().getCacheOverlayItem(coord, cacheOne.type); - icon = cgBase.getMarkerIcon(true, cacheOne.type, cacheOne.own, cacheOne.found, cacheOne.disabled || cacheOne.archived); - pin = null; - - if (iconsCache.containsKey(icon)) { - pin = iconsCache.get(icon); - } else { - pin = getResources().getDrawable(icon); - pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); - - iconsCache.put(icon, pin); - } - item.setMarker(pin); - - items.add(item); - } - - overlayCaches.updateItems(items); - displayHandler.sendEmptyMessage(1); - - cachesCnt = cachesProtected.size(); - - if (stop) { - displayHandler.sendEmptyMessage(0); - working = false; - - return; - } - - // display cache waypoints - if (cachesCnt == 1 && (geocodeIntent != null || searchIdIntent != null) && !live) { - if (cachesCnt == 1 && live == false) { - cgCache oneCache = cachesProtected.get(0); - - if (oneCache != null && oneCache.waypoints != null && !oneCache.waypoints.isEmpty()) { - for (cgWaypoint oneWaypoint : oneCache.waypoints) { - if (oneWaypoint.coords == null) { - continue; - } - - cgCoord coord = new cgCoord(oneWaypoint); - - coordinates.add(coord); - item = settings.getMapFactory().getCacheOverlayItem(coord, null); - - icon = cgBase.getMarkerIcon(false, oneWaypoint.type, false, false, false); - if (iconsCache.containsKey(icon)) { - pin = iconsCache.get(icon); - } else { - pin = getResources().getDrawable(icon); - pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); - iconsCache.put(icon, pin); - } - item.setMarker(pin); - - items.add(item); - } - - overlayCaches.updateItems(items); - displayHandler.sendEmptyMessage(1); - } - } - } - } else { - overlayCaches.updateItems(items); - displayHandler.sendEmptyMessage(1); - } - - cachesProtected.clear(); - - displayHandler.sendEmptyMessage(0); - } finally { - working = false; - } - } - } - - // load users from Go 4 Cache - private class UsersThread extends DoThread { - - public UsersThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); - } - - @Override - public void run() { - try { - stop = false; - working = true; - usersThreadRun = System.currentTimeMillis(); - - if (stop) { - return; - } - - double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); - double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); - double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); - double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); - double llCache; - - if (latMin > latMax) { - llCache = latMax; - latMax = latMin; - latMin = llCache; - } - if (lonMin > lonMax) { - llCache = lonMax; - lonMax = lonMin; - lonMin = llCache; - } - - users = base.getGeocachersInViewport(settings.getUsername(), latMin, latMax, lonMin, lonMax); - - if (stop) { - return; - } - - if (displayUsersThread != null && displayUsersThread.isWorking()) { - displayUsersThread.stopIt(); - } - displayUsersThread = new DisplayUsersThread(users, centerLat, centerLon, spanLat, spanLon); - displayUsersThread.start(); - } finally { - working = false; - } - } - } - - // display users of Go 4 Cache - private class DisplayUsersThread extends DoThread { - - private List<cgUser> users = null; - - public DisplayUsersThread(List<cgUser> usersIn, long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); - - users = usersIn; - } - - @Override - public void run() { - try { - stop = false; - working = true; - - if (mapView == null || users == null || users.isEmpty()) { - return; - } - - // display users - List<UserOverlayItemImpl> items = new ArrayList<UserOverlayItemImpl>(); - - int counter = 0; - UserOverlayItemImpl item = null; - - for (cgUser userOne : users) { - if (stop) { - return; - } - - if (userOne.coords == null) { - continue; - } - - item = settings.getMapFactory().getUserOverlayItemBase(activity, userOne); - items.add(item); - - counter++; - if ((counter % 10) == 0) { - overlayUsers.updateItems(items); - displayHandler.sendEmptyMessage(1); - } - } - - overlayUsers.updateItems(items); - } finally { - working = false; - } - } - } - - // display one point - private class DisplayPointThread extends Thread { - - @Override - public void run() { - if (mapView == null || caches == null) { - return; - } - - if (coordsIntent != null) { - cgCoord coord = new cgCoord(); - coord.type = "waypoint"; - coord.coords = coordsIntent; - coord.name = "some place"; - - coordinates.add(coord); - CacheOverlayItemImpl item = settings.getMapFactory().getCacheOverlayItem(coord, null); - - final int icon = cgBase.getMarkerIcon(false, waypointTypeIntent, false, false, false); - Drawable pin = null; - if (iconsCache.containsKey(icon)) { - pin = iconsCache.get(icon); - } else { - pin = getResources().getDrawable(icon); - pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); - iconsCache.put(icon, pin); - } - item.setMarker(pin); - - overlayCaches.updateItems(item); - displayHandler.sendEmptyMessage(1); - - cachesCnt = 1; - } else { - cachesCnt = 0; - } - - displayHandler.sendEmptyMessage(0); - } - } - - // parent for those above :) - private class DoThread extends Thread { - - protected boolean working = true; - protected boolean stop = false; - protected long centerLat = 0L; - protected long centerLon = 0L; - protected long spanLat = 0L; - protected long spanLon = 0L; - - public DoThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { - centerLat = centerLatIn; - centerLon = centerLonIn; - spanLat = spanLatIn; - spanLon = spanLonIn; - } - - public synchronized boolean isWorking() { - return working; - } - - public synchronized void stopIt() { - stop = true; - } - } - - // get if map is loading something - private synchronized boolean isLoading() { - boolean loading = false; - - if (loadThread != null && loadThread.isWorking()) { - loading = true; - } else if (downloadThread != null && downloadThread.isWorking()) { - loading = true; - } else if (displayThread != null && displayThread.isWorking()) { - loading = true; - } - - return loading; - } - - // store caches - private class LoadDetails extends Thread { - - private Handler handler = null; - private List<String> geocodes = null; - private volatile boolean stop = false; - private long last = 0L; - - public LoadDetails(Handler handlerIn, List<String> geocodesIn) { - handler = handlerIn; - geocodes = geocodesIn; - } - - public void stopIt() { - stop = true; - } - - @Override - public void run() { - if (geocodes == null || geocodes.isEmpty()) { - return; - } - - if (dir != null) { - dir = app.removeDir(); - } - if (geo != null) { - geo = app.removeGeo(); - } - - for (String geocode : geocodes) { - try { - if (stop) { - break; - } - - if (!app.isOffline(geocode, null)) { - if ((System.currentTimeMillis() - last) < 1500) { - try { - int delay = 1000 + ((Double) (Math.random() * 1000)).intValue() - (int) (System.currentTimeMillis() - last); - if (delay < 0) { - delay = 500; - } - - sleep(delay); - } catch (Exception e) { - // nothing - } - } - - if (stop) { - Log.i(cgSettings.tag, "Stopped storing process."); - - break; - } - - base.storeCache(app, activity, null, geocode, 1, handler); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeocaches.LoadDetails.run: " + e.toString()); - } finally { - // one more cache over - detailProgress++; - handler.sendEmptyMessage(0); - } - - yield(); - - last = System.currentTimeMillis(); - } - - // we're done - handler.sendEmptyMessage(1); - } - } - - // center map to desired location - private void centerMap(final Geopoint coords) { - if (coords == null) { - return; - } - if (mapView == null) { - return; - } - - if (!alreadyCentered) { - alreadyCentered = true; - - mapController.setCenter(makeGeoPoint(coords)); - } else { - mapController.animateTo(makeGeoPoint(coords)); - } - } - - // move map to view results of searchIdIntent - private void centerMap(String geocodeCenter, String searchIdCenter, final Geopoint coordsCenter, int[] mapState) { - - if (!centered && mapState != null) { - try { - mapController.setCenter(settings.getMapFactory().getGeoPointBase(new Geopoint(mapState[0] / 1.0e6, mapState[1] / 1.0e6))); - mapController.setZoom(mapState[2]); - } catch (Exception e) { - // nothing at all - } - - centered = true; - alreadyCentered = true; - } else if (!centered && (geocodeCenter != null || searchIdIntent != null)) { - try { - List<Object> viewport = null; - - if (geocodeCenter != null) { - viewport = app.getBounds(geocodeCenter); - } else { - viewport = app.getBounds(UUID.fromString(searchIdCenter)); - } - - if (viewport == null) return; - - Integer cnt = (Integer) viewport.get(0); - Integer minLat = null; - Integer maxLat = null; - Integer minLon = null; - Integer maxLon = null; - - if (viewport.get(1) != null) { - minLat = (int)((Double) viewport.get(1) * 1e6); - } - if (viewport.get(2) != null) { - maxLat = (int)((Double) viewport.get(2) * 1e6); - } - if (viewport.get(3) != null) { - maxLon = (int)((Double) viewport.get(3) * 1e6); - } - if (viewport.get(4) != null) { - minLon = (int)((Double) viewport.get(4) * 1e6); - } - - if (cnt == null || cnt <= 0 || minLat == null || maxLat == null || minLon == null || maxLon == null) { - return; - } - - int centerLat = 0; - int centerLon = 0; - - if ((Math.abs(maxLat) - Math.abs(minLat)) != 0) { - centerLat = minLat + ((maxLat - minLat) / 2); - } else { - centerLat = maxLat; - } - if ((Math.abs(maxLon) - Math.abs(minLon)) != 0) { - centerLon = minLon + ((maxLon - minLon) / 2); - } else { - centerLon = maxLon; - } - - if (cnt != null && cnt > 0) { - mapController.setCenter(settings.getMapFactory().getGeoPointBase(new Geopoint(centerLat, centerLon))); - if (Math.abs(maxLat - minLat) != 0 && Math.abs(maxLon - minLon) != 0) { - mapController.zoomToSpan(Math.abs(maxLat - minLat), Math.abs(maxLon - minLon)); - } - } - } catch (Exception e) { - // nothing at all - } - - centered = true; - alreadyCentered = true; - } else if (!centered && coordsCenter != null) { - try { - mapController.setCenter(makeGeoPoint(coordsCenter)); - } catch (Exception e) { - // nothing at all - } - - centered = true; - alreadyCentered = true; - } - } - - // switch My Location button image - private void switchMyLocationButton() { - if (followMyLocation) { - myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_on); - myLocationInMiddle(); - } else { - myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_off); - } - } - - // set my location listener - private class MyLocationListener implements View.OnClickListener { - public void onClick(View view) { - followMyLocation = !followMyLocation; - switchMyLocationButton(); - } - } - - @Override - public void onDrag() { - if (followMyLocation) { - followMyLocation = false; - switchMyLocationButton(); - } - } - - // make geopoint - private GeoPointImpl makeGeoPoint(final Geopoint coords) { - return settings.getMapFactory().getGeoPointBase(coords); - } - - // close activity and open homescreen - public void goHome(View view) { - ActivityMixin.goHome(activity); - } - - // open manual entry - public void goManual(View view) { - ActivityMixin.goManual(activity, "c:geo-live-map"); - } - - @Override - public View makeView() { - ImageView imageView = new ImageView(activity); - imageView.setScaleType(ScaleType.CENTER); - imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); - return imageView; - } + } + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + + app.setAction(null); + if (geo == null) { + geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(activity, dirUpdate); + } + + if (geo != null) { + geoUpdate.updateLoc(geo); + } + if (dir != null) { + dirUpdate.updateDir(dir); + } + + startTimer(); + } + + @Override + public void onStop() { + if (loadTimer != null) { + loadTimer.stopIt(); + loadTimer = null; + } + + if (usersTimer != null) { + usersTimer.stopIt(); + usersTimer = null; + } + + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + savePrefs(); + + if (mapView != null) { + mapView.destroyDrawingCache(); + } + + super.onStop(); + } + + @Override + public void onPause() { + if (loadTimer != null) { + loadTimer.stopIt(); + loadTimer = null; + } + + if (usersTimer != null) { + usersTimer.stopIt(); + usersTimer = null; + } + + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + savePrefs(); + + if (mapView != null) { + mapView.destroyDrawingCache(); + } + + super.onPause(); + } + + @Override + public void onDestroy() { + if (loadTimer != null) { + loadTimer.stopIt(); + loadTimer = null; + } + + if (usersTimer != null) { + usersTimer.stopIt(); + usersTimer = null; + } + + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + savePrefs(); + + if (mapView != null) { + mapView.destroyDrawingCache(); + } + + super.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + + SubMenu submenu = menu.addSubMenu(1, MENU_SELECT_MAPVIEW, 0, res.getString(R.string.map_view_map)).setIcon(android.R.drawable.ic_menu_more); + addMapViewMenuItems(submenu); + + menu.add(0, MENU_MAP_LIVE, 0, res.getString(R.string.map_live_disable)).setIcon(android.R.drawable.ic_menu_close_clear_cancel); + menu.add(0, MENU_STORE_CACHES, 0, res.getString(R.string.caches_store_offline)).setIcon(android.R.drawable.ic_menu_set_as).setEnabled(false); + menu.add(0, MENU_TRAIL_MODE, 0, res.getString(R.string.map_trail_hide)).setIcon(android.R.drawable.ic_menu_recent_history); + menu.add(0, MENU_CIRCLE_MODE, 0, res.getString(R.string.map_circles_hide)).setIcon(android.R.drawable.ic_menu_view); + + return true; + } + + private void addMapViewMenuItems(final Menu menu) { + String[] mapViews = res.getStringArray(R.array.map_sources); + mapSourceEnum mapSource = settings.mapSource; + + menu.add(1, SUBMENU_VIEW_GOOGLE_MAP, 0, mapViews[0]).setCheckable(true).setChecked(mapSource == mapSourceEnum.googleMap); + menu.add(1, SUBMENU_VIEW_GOOGLE_SAT, 0, mapViews[1]).setCheckable(true).setChecked(mapSource == mapSourceEnum.googleSat); + menu.add(1, SUBMENU_VIEW_MF_MAPNIK, 0, mapViews[2]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeMapnik); + menu.add(1, SUBMENU_VIEW_MF_OSMARENDER, 0, mapViews[3]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeOsmarender); + menu.add(1, SUBMENU_VIEW_MF_CYCLEMAP, 0, mapViews[4]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeCycle); + menu.add(1, SUBMENU_VIEW_MF_OFFLINE, 0, mapViews[5]).setCheckable(true).setChecked(mapSource == mapSourceEnum.mapsforgeOffline); + menu.setGroupCheckable(1, true, true); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + MenuItem item; + try { + item = menu.findItem(MENU_TRAIL_MODE); // show trail + if (settings.maptrail == 1) { + item.setTitle(res.getString(R.string.map_trail_hide)); + } else { + item.setTitle(res.getString(R.string.map_trail_show)); + } + + item = menu.findItem(MENU_MAP_LIVE); // live map + if (live == false) { + item.setEnabled(false); + item.setTitle(res.getString(R.string.map_live_enable)); + } else { + if (settings.maplive == 1) { + item.setTitle(res.getString(R.string.map_live_disable)); + } else { + item.setTitle(res.getString(R.string.map_live_enable)); + } + } + + item = menu.findItem(MENU_STORE_CACHES); // store loaded + if (live && !isLoading() && app.getNotOfflineCount(searchId) > 0 && caches != null && caches.size() > 0) { + item.setEnabled(true); + } else { + item.setEnabled(false); + } + + item = menu.findItem(MENU_CIRCLE_MODE); // show circles + if (overlayCaches != null && overlayCaches.getCircles()) { + item.setTitle(res.getString(R.string.map_circles_hide)); + } else { + item.setTitle(res.getString(R.string.map_circles_show)); + } + + item = menu.findItem(SUBMENU_VIEW_MF_OFFLINE); + if (settings.hasValidMapFile()) { + item.setEnabled(true); + } else { + item.setEnabled(false); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeomap.onPrepareOptionsMenu: " + e.toString()); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int id = item.getItemId(); + + if (id == MENU_TRAIL_MODE) { + if (settings.maptrail == 1) { + prefsEdit.putInt("maptrail", 0); + prefsEdit.commit(); + + settings.maptrail = 0; + } else { + prefsEdit.putInt("maptrail", 1); + prefsEdit.commit(); + + settings.maptrail = 1; + } + } else if (id == MENU_MAP_LIVE) { + if (settings.maplive == 1) { + settings.liveMapDisable(); + } else { + settings.liveMapEnable(); + } + liveChanged = true; + searchId = null; + searchIdIntent = null; + } else if (id == MENU_STORE_CACHES) { + if (live && !isLoading() && caches != null && !caches.isEmpty()) { + final List<String> geocodes = new ArrayList<String>(); + + List<cgCache> cachesProtected = new ArrayList<cgCache>(caches); + try { + if (cachesProtected.size() > 0) { + final GeoPointImpl mapCenter = mapView.getMapViewCenter(); + final int mapCenterLat = mapCenter.getLatitudeE6(); + final int mapCenterLon = mapCenter.getLongitudeE6(); + final int mapSpanLat = mapView.getLatitudeSpan(); + final int mapSpanLon = mapView.getLongitudeSpan(); + + for (cgCache oneCache : cachesProtected) { + if (oneCache != null && oneCache.coords != null) { + if (cgBase.isCacheInViewPort(mapCenterLat, mapCenterLon, mapSpanLat, mapSpanLon, oneCache.coords) && app.isOffline(oneCache.geocode, null) == false) { + geocodes.add(oneCache.geocode); + } + } + } + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeomap.onOptionsItemSelected.#4: " + e.toString()); + } + + detailTotal = geocodes.size(); + + if (detailTotal == 0) { + ActivityMixin.showToast(activity, res.getString(R.string.warn_save_nothing)); + + return true; + } + + waitDialog = new ProgressDialog(activity); + waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + waitDialog.setCancelable(true); + waitDialog.setMax(detailTotal); + waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + public void onCancel(DialogInterface arg0) { + try { + if (loadDetailsThread != null) { + loadDetailsThread.stopIt(); + } + + if (geo == null) { + geo = app.startGeo(activity, geoUpdate, base, settings, 0, 0); + } + if (settings.useCompass == 1 && dir == null) { + dir = app.startDir(activity, dirUpdate); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.onPrepareOptionsMenu.onCancel: " + e.toString()); + } + } + }); + + Float etaTime = Float.valueOf((detailTotal * (float) 7) / 60); + if (etaTime < 0.4) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); + } else if (etaTime < 1.5) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%.0f", etaTime) + " " + res.getString(R.string.caches_eta_min)); + } else { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + String.format(Locale.getDefault(), "%.0f", etaTime) + " " + res.getString(R.string.caches_eta_mins)); + } + waitDialog.show(); + + detailProgressTime = System.currentTimeMillis(); + + loadDetailsThread = new LoadDetails(loadDetailsHandler, geocodes); + loadDetailsThread.start(); + + return true; + } + } else if (id == MENU_CIRCLE_MODE) { + if (overlayCaches == null) { + return false; + } + + overlayCaches.switchCircles(); + mapView.invalidate(); + + } else if (SUBMENU_VIEW_GOOGLE_MAP <= id && SUBMENU_VIEW_MF_OFFLINE >= id) { + + item.setChecked(true); + mapSourceEnum mapSource = getMapSourceFromMenuId(id); + + boolean mapRestartRequired = switchMapSource(mapSource); + + if (mapRestartRequired) { + // close old mapview + activity.finish(); + + // prepare information to restart a similar view + Intent mapIntent = new Intent(activity, settings.getMapFactory().getMapClass()); + + mapIntent.putExtra("detail", fromDetailIntent); + mapIntent.putExtra("searchid", searchIdIntent); + mapIntent.putExtra("geocode", geocodeIntent); + if (coordsIntent != null) { + mapIntent.putExtra("latitude", coordsIntent.getLatitude()); + mapIntent.putExtra("longitude", coordsIntent.getLongitude()); + } + mapIntent.putExtra("wpttype", waypointTypeIntent); + int[] mapState = new int[4]; + GeoPointImpl mapCenter = mapView.getMapViewCenter(); + mapState[0] = mapCenter.getLatitudeE6(); + mapState[1] = mapCenter.getLongitudeE6(); + mapState[2] = mapView.getMapZoomLevel(); + mapState[3] = followMyLocation ? 1 : 0; + mapIntent.putExtra("mapstate", mapState); + + // start the new map + activity.startActivity(mapIntent); + + } + + return true; + } + + return false; + } + + private static mapSourceEnum getMapSourceFromMenuId(int menuItemId) { + + switch (menuItemId) { + case SUBMENU_VIEW_GOOGLE_MAP: + return mapSourceEnum.googleMap; + case SUBMENU_VIEW_GOOGLE_SAT: + return mapSourceEnum.googleSat; + case SUBMENU_VIEW_MF_OSMARENDER: + return mapSourceEnum.mapsforgeOsmarender; + case SUBMENU_VIEW_MF_MAPNIK: + return mapSourceEnum.mapsforgeMapnik; + case SUBMENU_VIEW_MF_CYCLEMAP: + return mapSourceEnum.mapsforgeCycle; + case SUBMENU_VIEW_MF_OFFLINE: + return mapSourceEnum.mapsforgeOffline; + default: + return mapSourceEnum.googleMap; + } + } + + private boolean switchMapSource(mapSourceEnum mapSource) { + + settings.mapSource = mapSource; + + prefsEdit.putInt("mapsource", settings.mapSource.ordinal()); + prefsEdit.commit(); + + boolean mapRestartRequired = settings.mapSource.isGoogleMapSource() != settings.mapSourceUsed.isGoogleMapSource(); + + if (!mapRestartRequired) { + mapView.setMapSource(settings); + } + + return mapRestartRequired; + } + + private void savePrefs() { + if (mapView == null) { + return; + } + + if (prefsEdit == null) { + prefsEdit = activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE).edit(); + } + + prefsEdit.putInt("mapzoom", mapView.getMapZoomLevel()); + prefsEdit.commit(); + } + + // set center of map to my location + private void myLocationInMiddle() { + if (geo == null) { + return; + } + if (!followMyLocation) { + return; + } + + centerMap(geo.coordsNow); + } + + // class: update location + private class UpdateLoc extends cgUpdateLoc { + + @Override + public void updateLoc(cgGeo geo) { + if (geo == null) { + return; + } + + try { + boolean repaintRequired = false; + + if (overlayMyLoc == null && mapView != null) { + overlayMyLoc = mapView.createAddPositionOverlay(activity, settings); + } + + if (overlayMyLoc != null && geo.location != null) { + overlayMyLoc.setCoordinates(geo.location); + } + + if (geo.coordsNow != null) { + if (followMyLocation) { + myLocationInMiddle(); + } else { + repaintRequired = true; + } + } + + if (settings.useCompass == 0 || (geo.speedNow != null && geo.speedNow > 5)) { // use GPS when speed is higher than 18 km/h + if (geo.bearingNow != null) { + overlayMyLoc.setHeading(geo.bearingNow); + } else { + overlayMyLoc.setHeading(0f); + } + repaintRequired = true; + } + + if (repaintRequired && mapView != null) { + mapView.repaintRequired(overlayMyLoc); + } + + } catch (Exception e) { + Log.w(cgSettings.tag, "Failed to update location."); + } + } + } + + // class: update direction + private class UpdateDir extends cgUpdateDir { + + @Override + public void updateDir(cgDirection dir) { + if (dir == null || dir.directionNow == null) { + return; + } + + if (overlayMyLoc != null && mapView != null && (geo == null || geo.speedNow == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h + overlayMyLoc.setHeading(dir.directionNow); + mapView.invalidate(); + } + } + } + + public void startTimer() { + if (coordsIntent != null) { + // display just one point + (new DisplayPointThread()).start(); + } else { + // start timer + if (loadTimer != null) { + loadTimer.stopIt(); + loadTimer = null; + } + loadTimer = new LoadTimer(); + loadTimer.start(); + } + + if (settings.publicLoc > 0) { + if (usersTimer != null) { + usersTimer.stopIt(); + usersTimer = null; + } + usersTimer = new UsersTimer(); + usersTimer.start(); + } + } + + // loading timer + private class LoadTimer extends Thread { + + private volatile boolean stop = false; + + public void stopIt() { + stop = true; + + if (loadThread != null) { + loadThread.stopIt(); + loadThread = null; + } + + if (downloadThread != null) { + downloadThread.stopIt(); + downloadThread = null; + } + + if (displayThread != null) { + displayThread.stopIt(); + displayThread = null; + } + } + + @Override + public void run() { + GeoPointImpl mapCenterNow; + int centerLatitudeNow; + int centerLongitudeNow; + int spanLatitudeNow; + int spanLongitudeNow; + boolean moved = false; + boolean force = false; + long currentTime = 0; + + while (!stop) { + try { + sleep(250); + + if (mapView != null) { + // get current viewport + mapCenterNow = mapView.getMapViewCenter(); + centerLatitudeNow = mapCenterNow.getLatitudeE6(); + centerLongitudeNow = mapCenterNow.getLongitudeE6(); + spanLatitudeNow = mapView.getLatitudeSpan(); + spanLongitudeNow = mapView.getLongitudeSpan(); + + // check if map moved or zoomed + moved = false; + force = false; + + if (liveChanged) { + moved = true; + force = true; + } else if (live && settings.maplive == 1 && downloaded == false) { + moved = true; + } else if (centerLatitude == null || centerLongitude == null) { + moved = true; + } else if (spanLatitude == null || spanLongitude == null) { + moved = true; + } else if (((Math.abs(spanLatitudeNow - spanLatitude) > 50) || (Math.abs(spanLongitudeNow - spanLongitude) > 50) || // changed zoom + (Math.abs(centerLatitudeNow - centerLatitude) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitude) > (spanLongitudeNow / 4)) // map moved + ) && (cachesCnt <= 0 || caches == null || caches.isEmpty() + || !cgBase.isInViewPort(centerLatitude, centerLongitude, centerLatitudeNow, centerLongitudeNow, spanLatitude, spanLongitude, spanLatitudeNow, spanLongitudeNow))) { + moved = true; + } + + if (moved && caches != null && centerLatitude != null && centerLongitude != null && ((Math.abs(centerLatitudeNow - centerLatitude) > (spanLatitudeNow * 1.2)) || (Math.abs(centerLongitudeNow - centerLongitude) > (spanLongitudeNow * 1.2)))) { + force = true; + } + + //LeeB + // save new values + if (moved) { + liveChanged = false; + + currentTime = System.currentTimeMillis(); + + if (1000 < (currentTime - loadThreadRun)) { + // from web + if (20000 < (currentTime - loadThreadRun)) { + force = true; // probably stucked thread + } + + if (force && loadThread != null && loadThread.isWorking()) { + loadThread.stopIt(); + + try { + sleep(100); + } catch (Exception e) { + // nothing + } + } + + if (loadThread != null && loadThread.isWorking()) { + continue; + } + + centerLatitude = centerLatitudeNow; + centerLongitude = centerLongitudeNow; + spanLatitude = spanLatitudeNow; + spanLongitude = spanLongitudeNow; + + showProgressHandler.sendEmptyMessage(1); // show progress + + loadThread = new LoadThread(centerLatitude, centerLongitude, spanLatitude, spanLongitude); + loadThread.setName("loadThread"); + loadThread.start(); //loadThread will kick off downloadThread once it's done + } + } + } + + if (!isLoading()) { + showProgressHandler.sendEmptyMessage(0); // hide progress + } + + yield(); + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeomap.LoadTimer.run: " + e.toString()); + } + } + } + } + + // loading timer + private class UsersTimer extends Thread { + + private volatile boolean stop = false; + + public void stopIt() { + stop = true; + + if (usersThread != null) { + usersThread.stopIt(); + usersThread = null; + } + + if (displayUsersThread != null) { + displayUsersThread.stopIt(); + displayUsersThread = null; + } + } + + @Override + public void run() { + GeoPointImpl mapCenterNow; + int centerLatitudeNow; + int centerLongitudeNow; + int spanLatitudeNow; + int spanLongitudeNow; + boolean moved = false; + long currentTime = 0; + + while (!stop) { + try { + sleep(250); + + if (mapView != null) { + // get current viewport + mapCenterNow = mapView.getMapViewCenter(); + centerLatitudeNow = mapCenterNow.getLatitudeE6(); + centerLongitudeNow = mapCenterNow.getLongitudeE6(); + spanLatitudeNow = mapView.getLatitudeSpan(); + spanLongitudeNow = mapView.getLongitudeSpan(); + + // check if map moved or zoomed + moved = false; + + currentTime = System.currentTimeMillis(); + + if (60000 < (currentTime - usersThreadRun)) { + moved = true; + } else if (centerLatitudeUsers == null || centerLongitudeUsers == null) { + moved = true; + } else if (spanLatitudeUsers == null || spanLongitudeUsers == null) { + moved = true; + } else if (((Math.abs(spanLatitudeNow - spanLatitudeUsers) > 50) || (Math.abs(spanLongitudeNow - spanLongitudeUsers) > 50) || // changed zoom + (Math.abs(centerLatitudeNow - centerLatitudeUsers) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitudeUsers) > (spanLongitudeNow / 4)) // map moved + ) && !cgBase.isInViewPort(centerLatitudeUsers, centerLongitudeUsers, centerLatitudeNow, centerLongitudeNow, spanLatitudeUsers, spanLongitudeUsers, spanLatitudeNow, spanLongitudeNow)) { + moved = true; + } + + // save new values + if (moved && (1000 < (currentTime - usersThreadRun))) { + if (usersThread != null && usersThread.isWorking()) { + continue; + } + + centerLatitudeUsers = centerLatitudeNow; + centerLongitudeUsers = centerLongitudeNow; + spanLatitudeUsers = spanLatitudeNow; + spanLongitudeUsers = spanLongitudeNow; + + usersThread = new UsersThread(centerLatitude, centerLongitude, spanLatitude, spanLongitude); + usersThread.start(); + } + } + + yield(); + } catch (Exception e) { + Log.w(cgSettings.tag, "cgeomap.LoadUsersTimer.run: " + e.toString()); + } + } + } + } + + // load caches from database + private class LoadThread extends DoThread { + + public LoadThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); + } + + @Override + public void run() { + try { + stop = false; + working = true; + loadThreadRun = System.currentTimeMillis(); + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + //LeeB - I think this can be done better: + //1. fetch and draw(in another thread) caches from the db (fast? db read will be the slow bit) + //2. fetch and draw(in another thread) and then insert into the db caches from geocaching.com - dont draw/insert if exist in memory? + + // stage 1 - pull and render from the DB only + + if (fromDetailIntent || StringUtils.isNotEmpty(searchIdIntent)) { + searchId = UUID.fromString(searchIdIntent); + } else { + if (!live || settings.maplive == 0) { + searchId = app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, settings.cacheType); + } else { + searchId = app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, settings.cacheType); + } + } + + if (searchId != null) { + downloaded = true; + } + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + caches = app.getCaches(searchId); + + //if in live map and stored caches are found / disables are also shown. + if (live && settings.maplive >= 1) { + final boolean excludeMine = settings.excludeMine > 0; + final boolean excludeDisabled = settings.excludeDisabled > 0; + + for (int i = caches.size() - 1; i >= 0; i--) { + cgCache cache = caches.get(i); + if ((cache.found && excludeMine) || (cache.own && excludeMine) || (cache.disabled && excludeDisabled)) { + caches.remove(i); + } + } + + } + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + //render + if (displayThread != null && displayThread.isWorking()) { + displayThread.stopIt(); + } + displayThread = new DisplayThread(centerLat, centerLon, spanLat, spanLon); + displayThread.start(); + + if (stop) { + displayThread.stopIt(); + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + //*** this needs to be in it's own thread + // stage 2 - pull and render from geocaching.com + //this should just fetch and insert into the db _and_ be cancel-able if the viewport changes + + if (live && settings.maplive >= 1) { + if (downloadThread != null && downloadThread.isWorking()) { + downloadThread.stopIt(); + } + downloadThread = new DownloadThread(centerLat, centerLon, spanLat, spanLon); + downloadThread.setName("downloadThread"); + downloadThread.start(); + } + } finally { + working = false; + } + } + } + + // load caches from internet + private class DownloadThread extends DoThread { + + public DownloadThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); + } + + @Override + public void run() { //first time we enter we have crappy long/lat.... + try { + stop = false; + working = true; + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); + double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); + double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); + double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); + double llCache; + + if (latMin > latMax) { + llCache = latMax; + latMax = latMin; + latMin = llCache; + } + if (lonMin > lonMax) { + llCache = lonMax; + lonMax = lonMin; + lonMin = llCache; + } + + //*** this needs to be in it's own thread + // stage 2 - pull and render from geocaching.com + //this should just fetch and insert into the db _and_ be cancel-able if the viewport changes + + if (token == null) { + token = base.getMapUserToken(noMapTokenHandler); + } + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + Map<String, String> params = new HashMap<String, String>(); + params.put("usertoken", token); + params.put("latitude-min", String.format((Locale) null, "%.6f", latMin)); + params.put("latitude-max", String.format((Locale) null, "%.6f", latMax)); + params.put("longitude-min", String.format((Locale) null, "%.6f", lonMin)); + params.put("longitude-max", String.format((Locale) null, "%.6f", lonMax)); + + searchId = base.searchByViewport(params, 0); + if (searchId != null) { + downloaded = true; + } + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + caches = app.getCaches(searchId, centerLat, centerLon, spanLat, spanLon); + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + //render + if (displayThread != null && displayThread.isWorking()) { + displayThread.stopIt(); + } + displayThread = new DisplayThread(centerLat, centerLon, spanLat, spanLon); + displayThread.start(); + + } finally { + working = false; + } + } + } + + // display (down)loaded caches + private class DisplayThread extends DoThread { + + public DisplayThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); + } + + @Override + public void run() { + try { + stop = false; + working = true; + + if (mapView == null || caches == null) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + // display caches + final List<cgCache> cachesProtected = new ArrayList<cgCache>(caches); + final List<CacheOverlayItemImpl> items = new ArrayList<CacheOverlayItemImpl>(); + + if (cachesProtected != null && !cachesProtected.isEmpty()) { + int icon = 0; + Drawable pin = null; + CacheOverlayItemImpl item = null; + + for (cgCache cacheOne : cachesProtected) { + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + if (cacheOne.coords == null) { + continue; + } + + final cgCoord coord = new cgCoord(cacheOne); + coordinates.add(coord); + + item = settings.getMapFactory().getCacheOverlayItem(coord, cacheOne.type); + icon = cgBase.getMarkerIcon(true, cacheOne.type, cacheOne.own, cacheOne.found, cacheOne.disabled || cacheOne.archived); + pin = null; + + if (iconsCache.containsKey(icon)) { + pin = iconsCache.get(icon); + } else { + pin = getResources().getDrawable(icon); + pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); + + iconsCache.put(icon, pin); + } + item.setMarker(pin); + + items.add(item); + } + + overlayCaches.updateItems(items); + displayHandler.sendEmptyMessage(1); + + cachesCnt = cachesProtected.size(); + + if (stop) { + displayHandler.sendEmptyMessage(0); + working = false; + + return; + } + + // display cache waypoints + if (cachesCnt == 1 && (geocodeIntent != null || searchIdIntent != null) && !live) { + if (cachesCnt == 1 && live == false) { + cgCache oneCache = cachesProtected.get(0); + + if (oneCache != null && oneCache.waypoints != null && !oneCache.waypoints.isEmpty()) { + for (cgWaypoint oneWaypoint : oneCache.waypoints) { + if (oneWaypoint.coords == null) { + continue; + } + + cgCoord coord = new cgCoord(oneWaypoint); + + coordinates.add(coord); + item = settings.getMapFactory().getCacheOverlayItem(coord, null); + + icon = cgBase.getMarkerIcon(false, oneWaypoint.type, false, false, false); + if (iconsCache.containsKey(icon)) { + pin = iconsCache.get(icon); + } else { + pin = getResources().getDrawable(icon); + pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); + iconsCache.put(icon, pin); + } + item.setMarker(pin); + + items.add(item); + } + + overlayCaches.updateItems(items); + displayHandler.sendEmptyMessage(1); + } + } + } + } else { + overlayCaches.updateItems(items); + displayHandler.sendEmptyMessage(1); + } + + cachesProtected.clear(); + + displayHandler.sendEmptyMessage(0); + } finally { + working = false; + } + } + } + + // load users from Go 4 Cache + private class UsersThread extends DoThread { + + public UsersThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); + } + + @Override + public void run() { + try { + stop = false; + working = true; + usersThreadRun = System.currentTimeMillis(); + + if (stop) { + return; + } + + double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4); + double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4); + double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4); + double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4); + double llCache; + + if (latMin > latMax) { + llCache = latMax; + latMax = latMin; + latMin = llCache; + } + if (lonMin > lonMax) { + llCache = lonMax; + lonMax = lonMin; + lonMin = llCache; + } + + users = base.getGeocachersInViewport(settings.getUsername(), latMin, latMax, lonMin, lonMax); + + if (stop) { + return; + } + + if (displayUsersThread != null && displayUsersThread.isWorking()) { + displayUsersThread.stopIt(); + } + displayUsersThread = new DisplayUsersThread(users, centerLat, centerLon, spanLat, spanLon); + displayUsersThread.start(); + } finally { + working = false; + } + } + } + + // display users of Go 4 Cache + private class DisplayUsersThread extends DoThread { + + private List<cgUser> users = null; + + public DisplayUsersThread(List<cgUser> usersIn, long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); + + users = usersIn; + } + + @Override + public void run() { + try { + stop = false; + working = true; + + if (mapView == null || users == null || users.isEmpty()) { + return; + } + + // display users + List<UserOverlayItemImpl> items = new ArrayList<UserOverlayItemImpl>(); + + int counter = 0; + UserOverlayItemImpl item = null; + + for (cgUser userOne : users) { + if (stop) { + return; + } + + if (userOne.coords == null) { + continue; + } + + item = settings.getMapFactory().getUserOverlayItemBase(activity, userOne); + items.add(item); + + counter++; + if ((counter % 10) == 0) { + overlayUsers.updateItems(items); + displayHandler.sendEmptyMessage(1); + } + } + + overlayUsers.updateItems(items); + } finally { + working = false; + } + } + } + + // display one point + private class DisplayPointThread extends Thread { + + @Override + public void run() { + if (mapView == null || caches == null) { + return; + } + + if (coordsIntent != null) { + cgCoord coord = new cgCoord(); + coord.type = "waypoint"; + coord.coords = coordsIntent; + coord.name = "some place"; + + coordinates.add(coord); + CacheOverlayItemImpl item = settings.getMapFactory().getCacheOverlayItem(coord, null); + + final int icon = cgBase.getMarkerIcon(false, waypointTypeIntent, false, false, false); + Drawable pin = null; + if (iconsCache.containsKey(icon)) { + pin = iconsCache.get(icon); + } else { + pin = getResources().getDrawable(icon); + pin.setBounds(0, 0, pin.getIntrinsicWidth(), pin.getIntrinsicHeight()); + iconsCache.put(icon, pin); + } + item.setMarker(pin); + + overlayCaches.updateItems(item); + displayHandler.sendEmptyMessage(1); + + cachesCnt = 1; + } else { + cachesCnt = 0; + } + + displayHandler.sendEmptyMessage(0); + } + } + + // parent for those above :) + private class DoThread extends Thread { + + protected boolean working = true; + protected boolean stop = false; + protected long centerLat = 0L; + protected long centerLon = 0L; + protected long spanLat = 0L; + protected long spanLon = 0L; + + public DoThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + centerLat = centerLatIn; + centerLon = centerLonIn; + spanLat = spanLatIn; + spanLon = spanLonIn; + } + + public synchronized boolean isWorking() { + return working; + } + + public synchronized void stopIt() { + stop = true; + } + } + + // get if map is loading something + private synchronized boolean isLoading() { + boolean loading = false; + + if (loadThread != null && loadThread.isWorking()) { + loading = true; + } else if (downloadThread != null && downloadThread.isWorking()) { + loading = true; + } else if (displayThread != null && displayThread.isWorking()) { + loading = true; + } + + return loading; + } + + // store caches + private class LoadDetails extends Thread { + + private Handler handler = null; + private List<String> geocodes = null; + private volatile boolean stop = false; + private long last = 0L; + + public LoadDetails(Handler handlerIn, List<String> geocodesIn) { + handler = handlerIn; + geocodes = geocodesIn; + } + + public void stopIt() { + stop = true; + } + + @Override + public void run() { + if (geocodes == null || geocodes.isEmpty()) { + return; + } + + if (dir != null) { + dir = app.removeDir(); + } + if (geo != null) { + geo = app.removeGeo(); + } + + for (String geocode : geocodes) { + try { + if (stop) { + break; + } + + if (!app.isOffline(geocode, null)) { + if ((System.currentTimeMillis() - last) < 1500) { + try { + int delay = 1000 + ((Double) (Math.random() * 1000)).intValue() - (int) (System.currentTimeMillis() - last); + if (delay < 0) { + delay = 500; + } + + sleep(delay); + } catch (Exception e) { + // nothing + } + } + + if (stop) { + Log.i(cgSettings.tag, "Stopped storing process."); + + break; + } + + base.storeCache(app, activity, null, geocode, 1, handler); + } + } catch (Exception e) { + Log.e(cgSettings.tag, "cgeocaches.LoadDetails.run: " + e.toString()); + } finally { + // one more cache over + detailProgress++; + handler.sendEmptyMessage(0); + } + + yield(); + + last = System.currentTimeMillis(); + } + + // we're done + handler.sendEmptyMessage(1); + } + } + + // center map to desired location + private void centerMap(final Geopoint coords) { + if (coords == null) { + return; + } + if (mapView == null) { + return; + } + + if (!alreadyCentered) { + alreadyCentered = true; + + mapController.setCenter(makeGeoPoint(coords)); + } else { + mapController.animateTo(makeGeoPoint(coords)); + } + } + + // move map to view results of searchIdIntent + private void centerMap(String geocodeCenter, String searchIdCenter, final Geopoint coordsCenter, int[] mapState) { + + if (!centered && mapState != null) { + try { + mapController.setCenter(settings.getMapFactory().getGeoPointBase(new Geopoint(mapState[0] / 1.0e6, mapState[1] / 1.0e6))); + mapController.setZoom(mapState[2]); + } catch (Exception e) { + // nothing at all + } + + centered = true; + alreadyCentered = true; + } else if (!centered && (geocodeCenter != null || searchIdIntent != null)) { + try { + List<Object> viewport = null; + + if (geocodeCenter != null) { + viewport = app.getBounds(geocodeCenter); + } else { + viewport = app.getBounds(UUID.fromString(searchIdCenter)); + } + + if (viewport == null) + return; + + Integer cnt = (Integer) viewport.get(0); + Integer minLat = null; + Integer maxLat = null; + Integer minLon = null; + Integer maxLon = null; + + if (viewport.get(1) != null) { + minLat = (int) ((Double) viewport.get(1) * 1e6); + } + if (viewport.get(2) != null) { + maxLat = (int) ((Double) viewport.get(2) * 1e6); + } + if (viewport.get(3) != null) { + maxLon = (int) ((Double) viewport.get(3) * 1e6); + } + if (viewport.get(4) != null) { + minLon = (int) ((Double) viewport.get(4) * 1e6); + } + + if (cnt == null || cnt <= 0 || minLat == null || maxLat == null || minLon == null || maxLon == null) { + return; + } + + int centerLat = 0; + int centerLon = 0; + + if ((Math.abs(maxLat) - Math.abs(minLat)) != 0) { + centerLat = minLat + ((maxLat - minLat) / 2); + } else { + centerLat = maxLat; + } + if ((Math.abs(maxLon) - Math.abs(minLon)) != 0) { + centerLon = minLon + ((maxLon - minLon) / 2); + } else { + centerLon = maxLon; + } + + if (cnt != null && cnt > 0) { + mapController.setCenter(settings.getMapFactory().getGeoPointBase(new Geopoint(centerLat, centerLon))); + if (Math.abs(maxLat - minLat) != 0 && Math.abs(maxLon - minLon) != 0) { + mapController.zoomToSpan(Math.abs(maxLat - minLat), Math.abs(maxLon - minLon)); + } + } + } catch (Exception e) { + // nothing at all + } + + centered = true; + alreadyCentered = true; + } else if (!centered && coordsCenter != null) { + try { + mapController.setCenter(makeGeoPoint(coordsCenter)); + } catch (Exception e) { + // nothing at all + } + + centered = true; + alreadyCentered = true; + } + } + + // switch My Location button image + private void switchMyLocationButton() { + if (followMyLocation) { + myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_on); + myLocationInMiddle(); + } else { + myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_off); + } + } + + // set my location listener + private class MyLocationListener implements View.OnClickListener { + public void onClick(View view) { + followMyLocation = !followMyLocation; + switchMyLocationButton(); + } + } + + @Override + public void onDrag() { + if (followMyLocation) { + followMyLocation = false; + switchMyLocationButton(); + } + } + + // make geopoint + private GeoPointImpl makeGeoPoint(final Geopoint coords) { + return settings.getMapFactory().getGeoPointBase(coords); + } + + // close activity and open homescreen + public void goHome(View view) { + ActivityMixin.goHome(activity); + } + + // open manual entry + public void goManual(View view) { + ActivityMixin.goManual(activity, "c:geo-live-map"); + } + + @Override + public View makeView() { + ImageView imageView = new ImageView(activity); + imageView.setScaleType(ScaleType.CENTER); + imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); + return imageView; + } } diff --git a/src/cgeo/geocaching/mapinterfaces/ActivityImpl.java b/src/cgeo/geocaching/mapinterfaces/ActivityImpl.java index a3e772c..e99c018 100644 --- a/src/cgeo/geocaching/mapinterfaces/ActivityImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/ActivityImpl.java @@ -10,33 +10,34 @@ import android.view.View; /** * Defines the common functions of the provider-specific * MapActivity implementations. + * * @author rsudev - * + * */ public interface ActivityImpl { - Resources getResources(); + Resources getResources(); - Activity getActivity(); + Activity getActivity(); - void superOnCreate(Bundle savedInstanceState); + void superOnCreate(Bundle savedInstanceState); - void superOnResume(); + void superOnResume(); - void superOnDestroy(); + void superOnDestroy(); - void superOnStop(); + void superOnStop(); - void superOnPause(); + void superOnPause(); - boolean superOnCreateOptionsMenu(Menu menu); + boolean superOnCreateOptionsMenu(Menu menu); - boolean superOnPrepareOptionsMenu(Menu menu); + boolean superOnPrepareOptionsMenu(Menu menu); - boolean superOnOptionsItemSelected(MenuItem item); - - public abstract void goHome(View view); + boolean superOnOptionsItemSelected(MenuItem item); - public abstract void goManual(View view); + public abstract void goHome(View view); + + public abstract void goManual(View view); } diff --git a/src/cgeo/geocaching/mapinterfaces/CacheOverlayItemImpl.java b/src/cgeo/geocaching/mapinterfaces/CacheOverlayItemImpl.java index bdb8511..efe5c12 100644 --- a/src/cgeo/geocaching/mapinterfaces/CacheOverlayItemImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/CacheOverlayItemImpl.java @@ -4,14 +4,15 @@ import cgeo.geocaching.cgCoord; /** * Covers the common functions of the provider-specific - * CacheOverlayItem implementations + * CacheOverlayItem implementations + * * @author rsudev - * + * */ public interface CacheOverlayItemImpl extends OverlayItemImpl { - public cgCoord getCoord(); - - public String getType(); + public cgCoord getCoord(); + + public String getType(); } diff --git a/src/cgeo/geocaching/mapinterfaces/GeoPointImpl.java b/src/cgeo/geocaching/mapinterfaces/GeoPointImpl.java index c6e80d4..b45b0fd 100644 --- a/src/cgeo/geocaching/mapinterfaces/GeoPointImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/GeoPointImpl.java @@ -3,13 +3,14 @@ package cgeo.geocaching.mapinterfaces; /** * Defines the common functions of the provider-specific * GeoPoint implementations + * * @author rsudev - * + * */ public interface GeoPointImpl { - int getLatitudeE6(); + int getLatitudeE6(); - int getLongitudeE6(); + int getLongitudeE6(); } diff --git a/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java index 08e28ad..c4adcef 100644 --- a/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java @@ -1,33 +1,35 @@ package cgeo.geocaching.mapinterfaces; +import cgeo.geocaching.mapcommon.ItemizedOverlayBase; + import android.graphics.Canvas; import android.graphics.Point; import android.graphics.drawable.Drawable; -import cgeo.geocaching.mapcommon.ItemizedOverlayBase; /** * Defines the common functions to access the provider-specific * ItemizedOverlay implementation + * * @author rsudev - * + * */ public interface ItemizedOverlayImpl extends OverlayImpl { - ItemizedOverlayBase getBase(); + ItemizedOverlayBase getBase(); - void superPopulate(); + void superPopulate(); - void superSetLastFocusedItemIndex(int i); + void superSetLastFocusedItemIndex(int i); - Drawable superBoundCenter(Drawable markerIn); + Drawable superBoundCenter(Drawable markerIn); - Drawable superBoundCenterBottom(Drawable marker); + Drawable superBoundCenterBottom(Drawable marker); - boolean superOnTap(int index); + boolean superOnTap(int index); - void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow); + void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow); - void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, MapProjectionImpl projection, - byte drawZoomLevel); + void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, MapProjectionImpl projection, + byte drawZoomLevel); } diff --git a/src/cgeo/geocaching/mapinterfaces/MapControllerImpl.java b/src/cgeo/geocaching/mapinterfaces/MapControllerImpl.java index dbdb955..18a4ab6 100644 --- a/src/cgeo/geocaching/mapinterfaces/MapControllerImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/MapControllerImpl.java @@ -3,17 +3,18 @@ package cgeo.geocaching.mapinterfaces; /** * Defines the common functions of the provider-specific * MapController implementations + * * @author rsudev - * + * */ public interface MapControllerImpl { - void setZoom(int mapzoom); + void setZoom(int mapzoom); - void setCenter(GeoPointImpl geoPoint); + void setCenter(GeoPointImpl geoPoint); - void animateTo(GeoPointImpl geoPoint); + void animateTo(GeoPointImpl geoPoint); - void zoomToSpan(int latSpanE6, int lonSpanE6); + void zoomToSpan(int latSpanE6, int lonSpanE6); } diff --git a/src/cgeo/geocaching/mapinterfaces/MapFactory.java b/src/cgeo/geocaching/mapinterfaces/MapFactory.java index f43ceaf..26703c5 100644 --- a/src/cgeo/geocaching/mapinterfaces/MapFactory.java +++ b/src/cgeo/geocaching/mapinterfaces/MapFactory.java @@ -1,30 +1,32 @@ package cgeo.geocaching.mapinterfaces; -import android.app.Activity; -import android.content.Context; import cgeo.geocaching.cgCoord; import cgeo.geocaching.cgUser; import cgeo.geocaching.geopoint.Geopoint; +import android.app.Activity; +import android.content.Context; + /** * Defines functions of a factory class to get implementation specific objects * (GeoPoints, OverlayItems, ...) + * * @author rsudev - * + * */ public interface MapFactory { - public Class<?extends Activity> getMapClass(); + public Class<? extends Activity> getMapClass(); - public int getMapViewId(); + public int getMapViewId(); - public int getMapLayoutId(); + public int getMapLayoutId(); - public GeoPointImpl getGeoPointBase(final Geopoint coords); + public GeoPointImpl getGeoPointBase(final Geopoint coords); - CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type); + CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type); - public UserOverlayItemImpl getUserOverlayItemBase(Context context, - cgUser userOne); + public UserOverlayItemImpl getUserOverlayItemBase(Context context, + cgUser userOne); } diff --git a/src/cgeo/geocaching/mapinterfaces/MapProjectionImpl.java b/src/cgeo/geocaching/mapinterfaces/MapProjectionImpl.java index 10d36ee..cad29f7 100644 --- a/src/cgeo/geocaching/mapinterfaces/MapProjectionImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/MapProjectionImpl.java @@ -5,13 +5,14 @@ import android.graphics.Point; /** * Defines common functions of the provider-specific * MapProjection implementations + * * @author rsudev - * + * */ public interface MapProjectionImpl { - - Object getImpl(); - void toPixels(GeoPointImpl leftGeo, Point left); + Object getImpl(); + + void toPixels(GeoPointImpl leftGeo, Point left); } diff --git a/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java b/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java index 4c23f63..9a1d4f8 100644 --- a/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java @@ -1,70 +1,72 @@ package cgeo.geocaching.mapinterfaces; -import android.app.Activity; -import android.content.Context; -import android.graphics.drawable.Drawable; import cgeo.geocaching.cgSettings; import cgeo.geocaching.mapcommon.cgMapMyOverlay; import cgeo.geocaching.mapcommon.cgMapOverlay; import cgeo.geocaching.mapcommon.cgOverlayScale; import cgeo.geocaching.mapcommon.cgUsersOverlay; +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; + /** * Defines common functions of the provider-specific * MapView implementations + * * @author rsudev - * + * */ public interface MapViewImpl { - void invalidate(); + void invalidate(); + + void setBuiltInZoomControls(boolean b); + + void displayZoomControls(boolean b); - void setBuiltInZoomControls(boolean b); + void preLoad(); - void displayZoomControls(boolean b); + void clearOverlays(); - void preLoad(); + void addOverlay(OverlayImpl ovl); - void clearOverlays(); - - void addOverlay(OverlayImpl ovl); + MapControllerImpl getMapController(); - MapControllerImpl getMapController(); + void destroyDrawingCache(); - void destroyDrawingCache(); + GeoPointImpl getMapViewCenter(); - GeoPointImpl getMapViewCenter(); + int getLatitudeSpan(); - int getLatitudeSpan(); + int getLongitudeSpan(); - int getLongitudeSpan(); + int getMapZoomLevel(); - int getMapZoomLevel(); + int getWidth(); - int getWidth(); + int getHeight(); - int getHeight(); + MapProjectionImpl getMapProjection(); - MapProjectionImpl getMapProjection(); + Context getContext(); - Context getContext(); + cgMapOverlay createAddMapOverlay(cgSettings settings, Context context, + Drawable drawable, boolean fromDetailIntent); - cgMapOverlay createAddMapOverlay(cgSettings settings, Context context, - Drawable drawable, boolean fromDetailIntent); + cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn); - cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn); - - cgOverlayScale createAddScaleOverlay(Activity activity, cgSettings settingsIn); + cgOverlayScale createAddScaleOverlay(Activity activity, cgSettings settingsIn); - cgMapMyOverlay createAddPositionOverlay(Activity activity, cgSettings settingsIn); + cgMapMyOverlay createAddPositionOverlay(Activity activity, cgSettings settingsIn); - boolean needsScaleOverlay(); + boolean needsScaleOverlay(); - void setBuiltinScale(boolean b); + void setBuiltinScale(boolean b); - void setMapSource(cgSettings settings); + void setMapSource(cgSettings settings); - void repaintRequired(OverlayBase overlay); + void repaintRequired(OverlayBase overlay); - void setOnDragListener(OnDragListener onDragListener); + void setOnDragListener(OnDragListener onDragListener); } diff --git a/src/cgeo/geocaching/mapinterfaces/OnDragListener.java b/src/cgeo/geocaching/mapinterfaces/OnDragListener.java index ebeb13f..04c4469 100644 --- a/src/cgeo/geocaching/mapinterfaces/OnDragListener.java +++ b/src/cgeo/geocaching/mapinterfaces/OnDragListener.java @@ -2,11 +2,12 @@ package cgeo.geocaching.mapinterfaces; /** * Notifies the parent class when a MapView has been dragged + * * @author cachapa - * + * */ public interface OnDragListener { - - public void onDrag(); - + + public void onDrag(); + } diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayBase.java b/src/cgeo/geocaching/mapinterfaces/OverlayBase.java index 17a4d85..024ec40 100644 --- a/src/cgeo/geocaching/mapinterfaces/OverlayBase.java +++ b/src/cgeo/geocaching/mapinterfaces/OverlayBase.java @@ -5,16 +5,17 @@ import android.graphics.Point; /** * Defines the base functions of the provider-independent - * Overlay implementations + * Overlay implementations + * * @author rsudev - * + * */ public interface OverlayBase { - void draw(Canvas canvas, MapViewImpl mapView, boolean shadow); + void draw(Canvas canvas, MapViewImpl mapView, boolean shadow); - void drawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel); + void drawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel); - OverlayImpl getOverlayImpl(); + OverlayImpl getOverlayImpl(); } diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java index ba45532..fe79c7e 100644 --- a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java @@ -3,18 +3,19 @@ package cgeo.geocaching.mapinterfaces; /** * Marker interface of the provider-specific * Overlay implementations + * * @author rsudev - * + * */ public interface OverlayImpl { - public enum overlayType { - PositionOverlay, - ScaleOverlay - } + public enum overlayType { + PositionOverlay, + ScaleOverlay + } - void lock(); + void lock(); + + void unlock(); - void unlock(); - } diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayItemImpl.java b/src/cgeo/geocaching/mapinterfaces/OverlayItemImpl.java index 0f0297e..642cb8d 100644 --- a/src/cgeo/geocaching/mapinterfaces/OverlayItemImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/OverlayItemImpl.java @@ -5,14 +5,15 @@ import android.graphics.drawable.Drawable; /** * Common functions of the provider-specific * OverlayItem implementations + * * @author rsudev - * + * */ public interface OverlayItemImpl { - public String getTitle(); - - public Drawable getMarker(int index); - - public void setMarker(Drawable markerIn); + public String getTitle(); + + public Drawable getMarker(int index); + + public void setMarker(Drawable markerIn); } diff --git a/src/cgeo/geocaching/mapinterfaces/UserOverlayItemImpl.java b/src/cgeo/geocaching/mapinterfaces/UserOverlayItemImpl.java index 6b1532d..48d6280 100644 --- a/src/cgeo/geocaching/mapinterfaces/UserOverlayItemImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/UserOverlayItemImpl.java @@ -5,10 +5,11 @@ import cgeo.geocaching.cgUser; /** * Common functions of the provider-specific * UserOverlayItem implementations + * * @author rsudev - * + * */ public interface UserOverlayItemImpl extends OverlayItemImpl { - public cgUser getUser(); + public cgUser getUser(); } diff --git a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java index 1e3b287..1bfc102 100644 --- a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java @@ -1,7 +1,10 @@ package cgeo.geocaching.mapsforge; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.mapcommon.cgMapOverlay; +import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; import org.mapsforge.android.maps.ItemizedOverlay; import org.mapsforge.android.maps.Projection; @@ -10,103 +13,99 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.drawable.Drawable; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.mapcommon.cgMapOverlay; -import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implements ItemizedOverlayImpl { - private cgMapOverlay base; - private Lock lock = new ReentrantLock(); - - public mfCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { - super(boundCenterBottom(markerIn)); - base = new cgMapOverlay(settingsIn, this, contextIn, fromDetailIn); - } - - @Override - public cgMapOverlay getBase() { - return base; - } - - @Override - protected mfCacheOverlayItem createItem(int i) { - if (base == null) - return null; - - return (mfCacheOverlayItem) base.createItem(i); - } - - @Override - public int size() { - if (base == null) - return 0; - - return base.size(); - } - - @Override - protected boolean onTap(int arg0) { - if (base == null) - return false; - - return base.onTap(arg0); - } - - @Override - protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, - Projection projection, byte drawZoomLevel) { - base.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); - } - - @Override - public void superPopulate() { - populate(); - } - - @Override - public Drawable superBoundCenter(Drawable markerIn) { - return super.boundCenter(markerIn); - } - - @Override - public Drawable superBoundCenterBottom(Drawable marker) { - return super.boundCenterBottom(marker); - } - - @Override - public void superSetLastFocusedItemIndex(int i) { - // nothing to do - } - - @Override - public boolean superOnTap(int index) { - return super.onTap(index); - } - - @Override - public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - // nothing to do here... - } - - @Override - public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private cgMapOverlay base; + private Lock lock = new ReentrantLock(); + + public mfCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { + super(boundCenterBottom(markerIn)); + base = new cgMapOverlay(settingsIn, this, contextIn, fromDetailIn); + } + + @Override + public cgMapOverlay getBase() { + return base; + } + + @Override + protected mfCacheOverlayItem createItem(int i) { + if (base == null) + return null; + + return (mfCacheOverlayItem) base.createItem(i); + } + + @Override + public int size() { + if (base == null) + return 0; + + return base.size(); + } + + @Override + protected boolean onTap(int arg0) { + if (base == null) + return false; + + return base.onTap(arg0); + } + + @Override + protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, + Projection projection, byte drawZoomLevel) { + base.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); + } + + @Override + public void superPopulate() { + populate(); + } + + @Override + public Drawable superBoundCenter(Drawable markerIn) { + return super.boundCenter(markerIn); + } + + @Override + public Drawable superBoundCenterBottom(Drawable marker) { + return super.boundCenterBottom(marker); + } + + @Override + public void superSetLastFocusedItemIndex(int i) { + // nothing to do + } + + @Override + public boolean superOnTap(int index) { + return super.onTap(index); + } + + @Override + public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + // nothing to do here... + } + + @Override + public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } - diff --git a/src/cgeo/geocaching/mapsforge/mfCacheOverlayItem.java b/src/cgeo/geocaching/mapsforge/mfCacheOverlayItem.java index b4c7c19..038b29b 100644 --- a/src/cgeo/geocaching/mapsforge/mfCacheOverlayItem.java +++ b/src/cgeo/geocaching/mapsforge/mfCacheOverlayItem.java @@ -1,34 +1,35 @@ package cgeo.geocaching.mapsforge; +import cgeo.geocaching.cgCoord; +import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; + import org.mapsforge.android.maps.GeoPoint; import org.mapsforge.android.maps.OverlayItem; import android.graphics.drawable.Drawable; -import cgeo.geocaching.cgCoord; -import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl; public class mfCacheOverlayItem extends OverlayItem implements CacheOverlayItemImpl { - private String cacheType = null; - private cgCoord coord; - - public mfCacheOverlayItem(cgCoord coordinate, String type) { - super(new GeoPoint(coordinate.coords.getLatitudeE6(), coordinate.coords.getLongitudeE6()), coordinate.name, ""); - - this.cacheType = type; - this.coord = coordinate; - } - - public cgCoord getCoord() { - return coord; - } - - public String getType() { - return cacheType; - } - - @Override - public Drawable getMarker(int index) { - return getMarker(); - } + private String cacheType = null; + private cgCoord coord; + + public mfCacheOverlayItem(cgCoord coordinate, String type) { + super(new GeoPoint(coordinate.coords.getLatitudeE6(), coordinate.coords.getLongitudeE6()), coordinate.name, ""); + + this.cacheType = type; + this.coord = coordinate; + } + + public cgCoord getCoord() { + return coord; + } + + public String getType() { + return cacheType; + } + + @Override + public Drawable getMarker(int index) { + return getMarker(); + } } diff --git a/src/cgeo/geocaching/mapsforge/mfGeoPoint.java b/src/cgeo/geocaching/mapsforge/mfGeoPoint.java index 1261887..905d3bf 100644 --- a/src/cgeo/geocaching/mapsforge/mfGeoPoint.java +++ b/src/cgeo/geocaching/mapsforge/mfGeoPoint.java @@ -1,12 +1,12 @@ package cgeo.geocaching.mapsforge; -import org.mapsforge.android.maps.GeoPoint; - import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import org.mapsforge.android.maps.GeoPoint; + public class mfGeoPoint extends GeoPoint implements GeoPointImpl { - public mfGeoPoint(int latitudeE6, int longitudeE6) { - super(latitudeE6, longitudeE6); - } + public mfGeoPoint(int latitudeE6, int longitudeE6) { + super(latitudeE6, longitudeE6); + } } diff --git a/src/cgeo/geocaching/mapsforge/mfMapActivity.java b/src/cgeo/geocaching/mapsforge/mfMapActivity.java index f6d2ac3..79ff290 100644 --- a/src/cgeo/geocaching/mapsforge/mfMapActivity.java +++ b/src/cgeo/geocaching/mapsforge/mfMapActivity.java @@ -1,5 +1,9 @@ package cgeo.geocaching.mapsforge; +import cgeo.geocaching.mapcommon.MapBase; +import cgeo.geocaching.mapcommon.cgeomap; +import cgeo.geocaching.mapinterfaces.ActivityImpl; + import org.mapsforge.android.maps.MapActivity; import android.app.Activity; @@ -7,111 +11,107 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import cgeo.geocaching.mapcommon.MapBase; -import cgeo.geocaching.mapcommon.cgeomap; -import cgeo.geocaching.mapinterfaces.ActivityImpl; - public class mfMapActivity extends MapActivity implements ActivityImpl { - private MapBase mapBase; - - public mfMapActivity() { - mapBase = new cgeomap(this); - } - - @Override - public Activity getActivity() { - return this; - } - - @Override - protected void onCreate(Bundle icicle) { - mapBase.onCreate(icicle); - } - - @Override - protected void onDestroy() { - mapBase.onDestroy(); - } - - @Override - protected void onPause() { - mapBase.onPause(); - } - - @Override - protected void onResume() { - mapBase.onResume(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return mapBase.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return mapBase.onOptionsItemSelected(item); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - return mapBase.onPrepareOptionsMenu(menu); - } - - @Override - protected void onStop() { - mapBase.onStop(); - } - - @Override - public void superOnCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public boolean superOnCreateOptionsMenu(Menu menu) { - return super.onCreateOptionsMenu(menu); - } - - @Override - public void superOnDestroy() { - super.onDestroy(); - } - - @Override - public boolean superOnOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } - - @Override - public void superOnResume() { - super.onResume(); - } - - @Override - public void superOnStop() { - super.onStop(); - } - - @Override - public void superOnPause() { - super.onPause(); - } - - @Override - public boolean superOnPrepareOptionsMenu(Menu menu) { - return super.onPrepareOptionsMenu(menu); - } - - // close activity and open homescreen - public void goHome(View view) { - mapBase.goHome(view); - } - - // open manual entry - public void goManual(View view) { - mapBase.goManual(view); - } + private MapBase mapBase; + + public mfMapActivity() { + mapBase = new cgeomap(this); + } + + @Override + public Activity getActivity() { + return this; + } + + @Override + protected void onCreate(Bundle icicle) { + mapBase.onCreate(icicle); + } + + @Override + protected void onDestroy() { + mapBase.onDestroy(); + } + + @Override + protected void onPause() { + mapBase.onPause(); + } + + @Override + protected void onResume() { + mapBase.onResume(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return mapBase.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return mapBase.onOptionsItemSelected(item); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + return mapBase.onPrepareOptionsMenu(menu); + } + + @Override + protected void onStop() { + mapBase.onStop(); + } + + @Override + public void superOnCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public boolean superOnCreateOptionsMenu(Menu menu) { + return super.onCreateOptionsMenu(menu); + } + + @Override + public void superOnDestroy() { + super.onDestroy(); + } + + @Override + public boolean superOnOptionsItemSelected(MenuItem item) { + return super.onOptionsItemSelected(item); + } + + @Override + public void superOnResume() { + super.onResume(); + } + + @Override + public void superOnStop() { + super.onStop(); + } + + @Override + public void superOnPause() { + super.onPause(); + } + + @Override + public boolean superOnPrepareOptionsMenu(Menu menu) { + return super.onPrepareOptionsMenu(menu); + } + + // close activity and open homescreen + public void goHome(View view) { + mapBase.goHome(view); + } + + // open manual entry + public void goManual(View view) { + mapBase.goManual(view); + } } diff --git a/src/cgeo/geocaching/mapsforge/mfMapController.java b/src/cgeo/geocaching/mapsforge/mfMapController.java index 932e640..f31d9b2 100644 --- a/src/cgeo/geocaching/mapsforge/mfMapController.java +++ b/src/cgeo/geocaching/mapsforge/mfMapController.java @@ -1,49 +1,48 @@ package cgeo.geocaching.mapsforge; -import org.mapsforge.android.maps.GeoPoint; -import org.mapsforge.android.maps.MapController; - import cgeo.geocaching.mapinterfaces.GeoPointImpl; import cgeo.geocaching.mapinterfaces.MapControllerImpl; +import org.mapsforge.android.maps.GeoPoint; +import org.mapsforge.android.maps.MapController; + public class mfMapController implements MapControllerImpl { - private MapController mapController; - private int maxZoomLevel; - - public mfMapController(MapController mapControllerIn, int maxZoomLevelIn) { - mapController = mapControllerIn; - maxZoomLevel = maxZoomLevelIn; - } - - @Override - public void animateTo(GeoPointImpl geoPoint) { - mapController.setCenter((GeoPoint)geoPoint); - } - - @Override - public void setCenter(GeoPointImpl geoPoint) { - mapController.setCenter((GeoPoint)geoPoint); - } - - @Override - public void setZoom(int mapzoom) { - int mfzoom = mapzoom-1; - if (mfzoom > maxZoomLevel) { - mfzoom = maxZoomLevel; - } - mapController.setZoom(mfzoom); - } - - @Override - public void zoomToSpan(int latSpanE6, int lonSpanE6) { - - if (latSpanE6 != 0 && lonSpanE6 != 0) { - // calculate zoomlevel - int distDegree = Math.max(latSpanE6, lonSpanE6); - int zoomLevel = (int) Math.floor(Math.log(360.0*1e6/distDegree)/Math.log(2)); - mapController.setZoom(zoomLevel+1); - } - } + private MapController mapController; + private int maxZoomLevel; + + public mfMapController(MapController mapControllerIn, int maxZoomLevelIn) { + mapController = mapControllerIn; + maxZoomLevel = maxZoomLevelIn; + } + + @Override + public void animateTo(GeoPointImpl geoPoint) { + mapController.setCenter((GeoPoint) geoPoint); + } + + @Override + public void setCenter(GeoPointImpl geoPoint) { + mapController.setCenter((GeoPoint) geoPoint); + } + + @Override + public void setZoom(int mapzoom) { + int mfzoom = mapzoom - 1; + if (mfzoom > maxZoomLevel) { + mfzoom = maxZoomLevel; + } + mapController.setZoom(mfzoom); + } + + @Override + public void zoomToSpan(int latSpanE6, int lonSpanE6) { + + if (latSpanE6 != 0 && lonSpanE6 != 0) { + // calculate zoomlevel + int distDegree = Math.max(latSpanE6, lonSpanE6); + int zoomLevel = (int) Math.floor(Math.log(360.0 * 1e6 / distDegree) / Math.log(2)); + mapController.setZoom(zoomLevel + 1); + } + } } - diff --git a/src/cgeo/geocaching/mapsforge/mfMapFactory.java b/src/cgeo/geocaching/mapsforge/mfMapFactory.java index 5266e99..7e41951 100644 --- a/src/cgeo/geocaching/mapsforge/mfMapFactory.java +++ b/src/cgeo/geocaching/mapsforge/mfMapFactory.java @@ -1,7 +1,5 @@ package cgeo.geocaching.mapsforge; -import android.app.Activity; -import android.content.Context; import cgeo.geocaching.R; import cgeo.geocaching.cgCoord; import cgeo.geocaching.cgUser; @@ -11,38 +9,41 @@ import cgeo.geocaching.mapinterfaces.GeoPointImpl; import cgeo.geocaching.mapinterfaces.MapFactory; import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; -public class mfMapFactory implements MapFactory{ - - @Override - public Class<?extends Activity> getMapClass() { - return mfMapActivity.class; - } - - @Override - public int getMapViewId() { - return R.id.mfmap; - } - - @Override - public int getMapLayoutId() { - return R.layout.mfmap; - } - - @Override - public GeoPointImpl getGeoPointBase(final Geopoint coords) { - return new mfGeoPoint(coords.getLatitudeE6(), coords.getLongitudeE6()); - } - - @Override - public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) { - mfCacheOverlayItem baseItem = new mfCacheOverlayItem(coordinate, type); - return baseItem; - } - - @Override - public UserOverlayItemImpl getUserOverlayItemBase(Context context, cgUser userOne) { - mfUsersOverlayItem baseItem = new mfUsersOverlayItem(context, userOne); - return baseItem; - } +import android.app.Activity; +import android.content.Context; + +public class mfMapFactory implements MapFactory { + + @Override + public Class<? extends Activity> getMapClass() { + return mfMapActivity.class; + } + + @Override + public int getMapViewId() { + return R.id.mfmap; + } + + @Override + public int getMapLayoutId() { + return R.layout.mfmap; + } + + @Override + public GeoPointImpl getGeoPointBase(final Geopoint coords) { + return new mfGeoPoint(coords.getLatitudeE6(), coords.getLongitudeE6()); + } + + @Override + public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) { + mfCacheOverlayItem baseItem = new mfCacheOverlayItem(coordinate, type); + return baseItem; + } + + @Override + public UserOverlayItemImpl getUserOverlayItemBase(Context context, cgUser userOne) { + mfUsersOverlayItem baseItem = new mfUsersOverlayItem(context, userOne); + return baseItem; + } } diff --git a/src/cgeo/geocaching/mapsforge/mfMapProjection.java b/src/cgeo/geocaching/mapsforge/mfMapProjection.java index 7252b17..f3e6dc1 100644 --- a/src/cgeo/geocaching/mapsforge/mfMapProjection.java +++ b/src/cgeo/geocaching/mapsforge/mfMapProjection.java @@ -1,28 +1,29 @@ package cgeo.geocaching.mapsforge; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; + import org.mapsforge.android.maps.GeoPoint; import org.mapsforge.android.maps.Projection; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; import android.graphics.Point; public class mfMapProjection implements MapProjectionImpl { - private Projection projection; + private Projection projection; - public mfMapProjection(Projection projectionIn) { - projection = projectionIn; - } + public mfMapProjection(Projection projectionIn) { + projection = projectionIn; + } - @Override - public void toPixels(GeoPointImpl leftGeo, Point left) { - projection.toPixels((GeoPoint) leftGeo, left); - } + @Override + public void toPixels(GeoPointImpl leftGeo, Point left) { + projection.toPixels((GeoPoint) leftGeo, left); + } - @Override - public Object getImpl() { - return projection; - } + @Override + public Object getImpl() { + return projection; + } } diff --git a/src/cgeo/geocaching/mapsforge/mfMapView.java b/src/cgeo/geocaching/mapsforge/mfMapView.java index 19e3b8d..a4d1e40 100644 --- a/src/cgeo/geocaching/mapsforge/mfMapView.java +++ b/src/cgeo/geocaching/mapsforge/mfMapView.java @@ -1,5 +1,19 @@ package cgeo.geocaching.mapsforge; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.mapcommon.cgMapMyOverlay; +import cgeo.geocaching.mapcommon.cgMapOverlay; +import cgeo.geocaching.mapcommon.cgOverlayScale; +import cgeo.geocaching.mapcommon.cgUsersOverlay; +import cgeo.geocaching.mapinterfaces.GeoPointImpl; +import cgeo.geocaching.mapinterfaces.MapControllerImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; +import cgeo.geocaching.mapinterfaces.OnDragListener; +import cgeo.geocaching.mapinterfaces.OverlayBase; +import cgeo.geocaching.mapinterfaces.OverlayImpl; +import cgeo.geocaching.mapinterfaces.OverlayImpl.overlayType; + import org.mapsforge.android.maps.GeoPoint; import org.mapsforge.android.maps.MapDatabase; import org.mapsforge.android.maps.MapView; @@ -14,231 +28,218 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; -import android.view.MotionEvent; import android.view.GestureDetector.SimpleOnGestureListener; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.mapcommon.cgMapMyOverlay; -import cgeo.geocaching.mapcommon.cgMapOverlay; -import cgeo.geocaching.mapcommon.cgOverlayScale; -import cgeo.geocaching.mapcommon.cgUsersOverlay; -import cgeo.geocaching.mapinterfaces.GeoPointImpl; -import cgeo.geocaching.mapinterfaces.MapControllerImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; -import cgeo.geocaching.mapinterfaces.OnDragListener; -import cgeo.geocaching.mapinterfaces.OverlayBase; -import cgeo.geocaching.mapinterfaces.OverlayImpl; -import cgeo.geocaching.mapinterfaces.OverlayImpl.overlayType; +import android.view.MotionEvent; public class mfMapView extends MapView implements MapViewImpl { - private GestureDetector gestureDetector; - private OnDragListener onDragListener; - - public mfMapView(Context context, AttributeSet attrs) { - super(context, attrs); - gestureDetector = new GestureDetector(context, new GestureListener()); - } - - @Override - public void draw(Canvas canvas) { - try { - if (getMapZoomLevel() >= 22) { // to avoid too close zoom level (mostly on Samsung Galaxy S series) - getController().setZoom(22); - } - - super.draw(canvas); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgMapView.draw: " + e.toString()); - } - } - - @Override - public void displayZoomControls(boolean takeFocus) { - // nothing to do here - } - - @Override - public MapControllerImpl getMapController() { - return new mfMapController(getController(), getMaxZoomLevel()); - } - - @Override - public GeoPointImpl getMapViewCenter() { - GeoPoint point = getMapCenter(); - return new mfGeoPoint(point.getLatitudeE6(), point.getLongitudeE6()); - } - - @Override - public void addOverlay(OverlayImpl ovl) { - getOverlays().add((Overlay)ovl); - } - - @Override - public void clearOverlays() { - getOverlays().clear(); - } - - @Override - public MapProjectionImpl getMapProjection() { - return new mfMapProjection(getProjection()); - } - - @Override - public cgMapOverlay createAddMapOverlay(cgSettings settings, - Context context, Drawable drawable, boolean fromDetailIntent) { - - mfCacheOverlay ovl = new mfCacheOverlay(settings, context, drawable, fromDetailIntent); - getOverlays().add(ovl); - return ovl.getBase(); - } - - @Override - public cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn) { - mfUsersOverlay ovl = new mfUsersOverlay(context, markerIn); - getOverlays().add(ovl); - return ovl.getBase(); - } - - @Override - public cgMapMyOverlay createAddPositionOverlay(Activity activity, - cgSettings settingsIn) { - mfOverlay ovl = new mfOverlay(activity, settingsIn, overlayType.PositionOverlay); - getOverlays().add(ovl); - return (cgMapMyOverlay) ovl.getBase(); - } - - @Override - public cgOverlayScale createAddScaleOverlay(Activity activity, - cgSettings settingsIn) { - mfOverlay ovl = new mfOverlay(activity, settingsIn, overlayType.ScaleOverlay); - getOverlays().add(ovl); - return (cgOverlayScale) ovl.getBase(); - } - - @Override - public int getLatitudeSpan() { - - int span = 0; - - Projection projection = getProjection(); - - if (projection != null && getHeight() > 0) { - - GeoPoint low = projection.fromPixels(0, 0); - GeoPoint high = projection.fromPixels(0, getHeight()); - - if (low != null && high != null) { - span = Math.abs(high.getLatitudeE6() - low.getLatitudeE6()); - } - } - - return span; - } - - @Override - public int getLongitudeSpan() { - - int span = 0; - - Projection projection = getProjection(); - - if (projection != null && getWidth() > 0) { - GeoPoint low = projection.fromPixels(0, 0); - GeoPoint high = projection.fromPixels(getWidth(), 0); - - if (low != null && high != null) { - span = Math.abs(high.getLongitudeE6() - low.getLongitudeE6()); - } - } - - return span; - } - - @Override - public void preLoad() { - // Nothing to do here - } - - @Override - public int getMapZoomLevel() { - return getZoomLevel()+1; - } - - @Override - public boolean needsScaleOverlay() { - return false; - } - - @Override - public void setBuiltinScale(boolean b) { - setScaleBar(b); - } - - @Override - public void setMapSource(cgSettings settings) { - - switch(settings.mapSource) { - case mapsforgeOsmarender: - setMapViewMode(MapViewMode.OSMARENDER_TILE_DOWNLOAD); - break; - case mapsforgeCycle: - setMapViewMode(MapViewMode.OPENCYCLEMAP_TILE_DOWNLOAD); - break; - case mapsforgeOffline: - if (MapDatabase.isValidMapFile(settings.getMapFile())) { - setMapViewMode(MapViewMode.CANVAS_RENDERER); - super.setMapFile(settings.getMapFile()); - } else { - setMapViewMode(MapViewMode.MAPNIK_TILE_DOWNLOAD); - } - break; - default: - setMapViewMode(MapViewMode.MAPNIK_TILE_DOWNLOAD); - } - } - - @Override - public void repaintRequired(OverlayBase overlay) { - - try { - mfOverlay ovl = (mfOverlay) overlay.getOverlayImpl(); - - if (ovl != null) { - ovl.requestRedraw(); - } - - } catch (Exception e) { - Log.e(cgSettings.tag, "mfMapView.repaintRequired: " + e.toString()); - } - } - - @Override - public void setOnDragListener(OnDragListener onDragListener) { - this.onDragListener = onDragListener; - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - gestureDetector.onTouchEvent(ev); - return super.onTouchEvent(ev); - } - - private class GestureListener extends SimpleOnGestureListener { - @Override - public boolean onDoubleTap(MotionEvent e) { - if (onDragListener != null) { - onDragListener.onDrag(); - } - return true; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, - float distanceX, float distanceY) { - if (onDragListener != null) { - onDragListener.onDrag(); - } - return super.onScroll(e1, e2, distanceX, distanceY); - } - } + private GestureDetector gestureDetector; + private OnDragListener onDragListener; + + public mfMapView(Context context, AttributeSet attrs) { + super(context, attrs); + gestureDetector = new GestureDetector(context, new GestureListener()); + } + + @Override + public void draw(Canvas canvas) { + try { + if (getMapZoomLevel() >= 22) { // to avoid too close zoom level (mostly on Samsung Galaxy S series) + getController().setZoom(22); + } + + super.draw(canvas); + } catch (Exception e) { + Log.e(cgSettings.tag, "cgMapView.draw: " + e.toString()); + } + } + + @Override + public void displayZoomControls(boolean takeFocus) { + // nothing to do here + } + + @Override + public MapControllerImpl getMapController() { + return new mfMapController(getController(), getMaxZoomLevel()); + } + + @Override + public GeoPointImpl getMapViewCenter() { + GeoPoint point = getMapCenter(); + return new mfGeoPoint(point.getLatitudeE6(), point.getLongitudeE6()); + } + + @Override + public void addOverlay(OverlayImpl ovl) { + getOverlays().add((Overlay) ovl); + } + + @Override + public void clearOverlays() { + getOverlays().clear(); + } + + @Override + public MapProjectionImpl getMapProjection() { + return new mfMapProjection(getProjection()); + } + + @Override + public cgMapOverlay createAddMapOverlay(cgSettings settings, + Context context, Drawable drawable, boolean fromDetailIntent) { + + mfCacheOverlay ovl = new mfCacheOverlay(settings, context, drawable, fromDetailIntent); + getOverlays().add(ovl); + return ovl.getBase(); + } + + @Override + public cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn) { + mfUsersOverlay ovl = new mfUsersOverlay(context, markerIn); + getOverlays().add(ovl); + return ovl.getBase(); + } + + @Override + public cgMapMyOverlay createAddPositionOverlay(Activity activity, + cgSettings settingsIn) { + mfOverlay ovl = new mfOverlay(activity, settingsIn, overlayType.PositionOverlay); + getOverlays().add(ovl); + return (cgMapMyOverlay) ovl.getBase(); + } + + @Override + public cgOverlayScale createAddScaleOverlay(Activity activity, + cgSettings settingsIn) { + mfOverlay ovl = new mfOverlay(activity, settingsIn, overlayType.ScaleOverlay); + getOverlays().add(ovl); + return (cgOverlayScale) ovl.getBase(); + } + + @Override + public int getLatitudeSpan() { + + int span = 0; + + Projection projection = getProjection(); + + if (projection != null && getHeight() > 0) { + + GeoPoint low = projection.fromPixels(0, 0); + GeoPoint high = projection.fromPixels(0, getHeight()); + + if (low != null && high != null) { + span = Math.abs(high.getLatitudeE6() - low.getLatitudeE6()); + } + } + + return span; + } + + @Override + public int getLongitudeSpan() { + + int span = 0; + + Projection projection = getProjection(); + + if (projection != null && getWidth() > 0) { + GeoPoint low = projection.fromPixels(0, 0); + GeoPoint high = projection.fromPixels(getWidth(), 0); + + if (low != null && high != null) { + span = Math.abs(high.getLongitudeE6() - low.getLongitudeE6()); + } + } + + return span; + } + + @Override + public void preLoad() { + // Nothing to do here + } + + @Override + public int getMapZoomLevel() { + return getZoomLevel() + 1; + } + + @Override + public boolean needsScaleOverlay() { + return false; + } + + @Override + public void setBuiltinScale(boolean b) { + setScaleBar(b); + } + + @Override + public void setMapSource(cgSettings settings) { + + switch (settings.mapSource) { + case mapsforgeOsmarender: + setMapViewMode(MapViewMode.OSMARENDER_TILE_DOWNLOAD); + break; + case mapsforgeCycle: + setMapViewMode(MapViewMode.OPENCYCLEMAP_TILE_DOWNLOAD); + break; + case mapsforgeOffline: + if (MapDatabase.isValidMapFile(settings.getMapFile())) { + setMapViewMode(MapViewMode.CANVAS_RENDERER); + super.setMapFile(settings.getMapFile()); + } else { + setMapViewMode(MapViewMode.MAPNIK_TILE_DOWNLOAD); + } + break; + default: + setMapViewMode(MapViewMode.MAPNIK_TILE_DOWNLOAD); + } + } + + @Override + public void repaintRequired(OverlayBase overlay) { + + try { + mfOverlay ovl = (mfOverlay) overlay.getOverlayImpl(); + + if (ovl != null) { + ovl.requestRedraw(); + } + + } catch (Exception e) { + Log.e(cgSettings.tag, "mfMapView.repaintRequired: " + e.toString()); + } + } + + @Override + public void setOnDragListener(OnDragListener onDragListener) { + this.onDragListener = onDragListener; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + gestureDetector.onTouchEvent(ev); + return super.onTouchEvent(ev); + } + + private class GestureListener extends SimpleOnGestureListener { + @Override + public boolean onDoubleTap(MotionEvent e) { + if (onDragListener != null) { + onDragListener.onDrag(); + } + return true; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, + float distanceX, float distanceY) { + if (onDragListener != null) { + onDragListener.onDrag(); + } + return super.onScroll(e1, e2, distanceX, distanceY); + } + } } diff --git a/src/cgeo/geocaching/mapsforge/mfOverlay.java b/src/cgeo/geocaching/mapsforge/mfOverlay.java index f764c6b..69ec499 100644 --- a/src/cgeo/geocaching/mapsforge/mfOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfOverlay.java @@ -1,7 +1,10 @@ package cgeo.geocaching.mapsforge; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; +import cgeo.geocaching.cgSettings; +import cgeo.geocaching.mapcommon.cgMapMyOverlay; +import cgeo.geocaching.mapcommon.cgOverlayScale; +import cgeo.geocaching.mapinterfaces.OverlayBase; +import cgeo.geocaching.mapinterfaces.OverlayImpl; import org.mapsforge.android.maps.Overlay; import org.mapsforge.android.maps.Projection; @@ -9,48 +12,46 @@ import org.mapsforge.android.maps.Projection; import android.app.Activity; import android.graphics.Canvas; import android.graphics.Point; -import cgeo.geocaching.cgSettings; -import cgeo.geocaching.mapcommon.cgMapMyOverlay; -import cgeo.geocaching.mapcommon.cgOverlayScale; -import cgeo.geocaching.mapinterfaces.OverlayBase; -import cgeo.geocaching.mapinterfaces.OverlayImpl; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class mfOverlay extends Overlay implements OverlayImpl { - private OverlayBase overlayBase = null; - private Lock lock = new ReentrantLock(); - - public mfOverlay(Activity activityIn, cgSettings settingsIn, OverlayImpl.overlayType ovlType) { - - switch (ovlType) { - case PositionOverlay: - overlayBase = new cgMapMyOverlay(settingsIn, activityIn, this); - break; - case ScaleOverlay: - overlayBase = new cgOverlayScale(activityIn, settingsIn, this); - } - } - - @Override - protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, - Projection projection, byte drawZoomLevel) { - - if (overlayBase != null) { - overlayBase.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); - } - } - - public OverlayBase getBase() { - return overlayBase; - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private OverlayBase overlayBase = null; + private Lock lock = new ReentrantLock(); + + public mfOverlay(Activity activityIn, cgSettings settingsIn, OverlayImpl.overlayType ovlType) { + + switch (ovlType) { + case PositionOverlay: + overlayBase = new cgMapMyOverlay(settingsIn, activityIn, this); + break; + case ScaleOverlay: + overlayBase = new cgOverlayScale(activityIn, settingsIn, this); + } + } + + @Override + protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, + Projection projection, byte drawZoomLevel) { + + if (overlayBase != null) { + overlayBase.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); + } + } + + public OverlayBase getBase() { + return overlayBase; + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java index 6e2819c..06b9f3e 100644 --- a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java @@ -1,7 +1,9 @@ package cgeo.geocaching.mapsforge; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; +import cgeo.geocaching.mapcommon.cgUsersOverlay; +import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; +import cgeo.geocaching.mapinterfaces.MapProjectionImpl; +import cgeo.geocaching.mapinterfaces.MapViewImpl; import org.mapsforge.android.maps.ItemizedOverlay; import org.mapsforge.android.maps.Projection; @@ -10,102 +12,101 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.drawable.Drawable; -import cgeo.geocaching.mapcommon.cgUsersOverlay; -import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; -import cgeo.geocaching.mapinterfaces.MapProjectionImpl; -import cgeo.geocaching.mapinterfaces.MapViewImpl; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implements ItemizedOverlayImpl { - private cgUsersOverlay base; - private Lock lock = new ReentrantLock(); - - public mfUsersOverlay(Context contextIn, Drawable markerIn) { - super(boundCenter(markerIn)); - base = new cgUsersOverlay(this, contextIn); - } - - @Override - public cgUsersOverlay getBase() { - return base; - } - - @Override - protected mfUsersOverlayItem createItem(int i) { - if (base == null) - return null; - - return (mfUsersOverlayItem) base.createItem(i); - } - - @Override - public int size() { - if (base == null) - return 0; - - return base.size(); - } - - @Override - protected boolean onTap(int arg0) { - if (base == null) - return false; - - return base.onTap(arg0); - } - - @Override - protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, - Projection projection, byte drawZoomLevel) { - - base.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); - } - - @Override - public void superPopulate() { - populate(); - } - - @Override - public Drawable superBoundCenter(Drawable markerIn) { - return super.boundCenter(markerIn); - } - - @Override - public Drawable superBoundCenterBottom(Drawable marker) { - return super.boundCenterBottom(marker); - } - - @Override - public void superSetLastFocusedItemIndex(int i) { - // Nothing to do here - } - - @Override - public boolean superOnTap(int index) { - return super.onTap(index); - } - - @Override - public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { - // Nothing to do here - } - - @Override - public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, - MapProjectionImpl projection, byte drawZoomLevel) { - - super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); - } - - @Override - public void lock() { - lock.lock(); - } - - @Override - public void unlock() { - lock.unlock(); - } + private cgUsersOverlay base; + private Lock lock = new ReentrantLock(); + + public mfUsersOverlay(Context contextIn, Drawable markerIn) { + super(boundCenter(markerIn)); + base = new cgUsersOverlay(this, contextIn); + } + + @Override + public cgUsersOverlay getBase() { + return base; + } + + @Override + protected mfUsersOverlayItem createItem(int i) { + if (base == null) + return null; + + return (mfUsersOverlayItem) base.createItem(i); + } + + @Override + public int size() { + if (base == null) + return 0; + + return base.size(); + } + + @Override + protected boolean onTap(int arg0) { + if (base == null) + return false; + + return base.onTap(arg0); + } + + @Override + protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, + Projection projection, byte drawZoomLevel) { + + base.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), drawZoomLevel); + } + + @Override + public void superPopulate() { + populate(); + } + + @Override + public Drawable superBoundCenter(Drawable markerIn) { + return super.boundCenter(markerIn); + } + + @Override + public Drawable superBoundCenterBottom(Drawable marker) { + return super.boundCenterBottom(marker); + } + + @Override + public void superSetLastFocusedItemIndex(int i) { + // Nothing to do here + } + + @Override + public boolean superOnTap(int index) { + return super.onTap(index); + } + + @Override + public void superDraw(Canvas canvas, MapViewImpl mapView, boolean shadow) { + // Nothing to do here + } + + @Override + public void superDrawOverlayBitmap(Canvas canvas, Point drawPosition, + MapProjectionImpl projection, byte drawZoomLevel) { + + super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); + } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/mapsforge/mfUsersOverlayItem.java b/src/cgeo/geocaching/mapsforge/mfUsersOverlayItem.java index 69f4877..d53a863 100644 --- a/src/cgeo/geocaching/mapsforge/mfUsersOverlayItem.java +++ b/src/cgeo/geocaching/mapsforge/mfUsersOverlayItem.java @@ -1,43 +1,44 @@ package cgeo.geocaching.mapsforge; +import cgeo.geocaching.R; +import cgeo.geocaching.cgUser; +import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; + import org.mapsforge.android.maps.GeoPoint; import org.mapsforge.android.maps.OverlayItem; import android.content.Context; import android.graphics.drawable.Drawable; -import cgeo.geocaching.R; -import cgeo.geocaching.cgUser; -import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl; public class mfUsersOverlayItem extends OverlayItem implements UserOverlayItemImpl { - private Context context = null; - private cgUser user = null; - - public mfUsersOverlayItem(Context contextIn, cgUser userIn) { - super(new GeoPoint((int)(userIn.coords.getLatitudeE6()), userIn.coords.getLongitudeE6()), userIn.username, ""); - - context = contextIn; - user = userIn; - } - - @Override - public Drawable getMarker(int state) { - Drawable marker = null; - - if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { - marker = context.getResources().getDrawable(R.drawable.user_location_active); - } else { - marker = context.getResources().getDrawable(R.drawable.user_location); - } - - marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); - marker.setAlpha(190); - setMarker(marker); - - return marker; - } - - public cgUser getUser() { - return user; - } + private Context context = null; + private cgUser user = null; + + public mfUsersOverlayItem(Context contextIn, cgUser userIn) { + super(new GeoPoint((int) (userIn.coords.getLatitudeE6()), userIn.coords.getLongitudeE6()), userIn.username, ""); + + context = contextIn; + user = userIn; + } + + @Override + public Drawable getMarker(int state) { + Drawable marker = null; + + if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { + marker = context.getResources().getDrawable(R.drawable.user_location_active); + } else { + marker = context.getResources().getDrawable(R.drawable.user_location); + } + + marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); + marker.setAlpha(190); + setMarker(marker); + + return marker; + } + + public cgUser getUser() { + return user; + } } diff --git a/src/cgeo/geocaching/sorting/AbstractCacheComparator.java b/src/cgeo/geocaching/sorting/AbstractCacheComparator.java index 4630888..a7a3336 100644 --- a/src/cgeo/geocaching/sorting/AbstractCacheComparator.java +++ b/src/cgeo/geocaching/sorting/AbstractCacheComparator.java @@ -1,42 +1,46 @@ package cgeo.geocaching.sorting; -import android.util.Log; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgSettings; +import android.util.Log; + /** * abstract super implementation for all cache comparators - * + * */ public abstract class AbstractCacheComparator implements CacheComparator { - @Override - public final int compare(cgCache cache1, cgCache cache2) { - try { - // first check that we have all necessary data for the comparison - if (!canCompare(cache1, cache2)) { - return 0; - } - return compareCaches(cache1, cache2); - } catch (Exception e) { - Log.e(cgSettings.tag, "AbstractCacheComparator.compare: " + e.toString()); - } - return 0; - } + @Override + public final int compare(cgCache cache1, cgCache cache2) { + try { + // first check that we have all necessary data for the comparison + if (!canCompare(cache1, cache2)) { + return 0; + } + return compareCaches(cache1, cache2); + } catch (Exception e) { + Log.e(cgSettings.tag, "AbstractCacheComparator.compare: " + e.toString()); + } + return 0; + } - /** - * check necessary preconditions (like missing fields) before running the comparison itself - * @param cache1 - * @param cache2 - * @return - */ - protected abstract boolean canCompare(final cgCache cache1, final cgCache cache2); + /** + * check necessary preconditions (like missing fields) before running the comparison itself + * + * @param cache1 + * @param cache2 + * @return + */ + protected abstract boolean canCompare(final cgCache cache1, final cgCache cache2); - /** - * compares two caches. Logging and exception handling is implemented outside this method already. - * @param cache1 - * @param cache2 - * @return an integer < 0 if cache1 is less than cache2, 0 if they are equal, and > 0 if cache1 is greater than cache2. - */ - protected abstract int compareCaches(final cgCache cache1, final cgCache cache2); + /** + * compares two caches. Logging and exception handling is implemented outside this method already. + * + * @param cache1 + * @param cache2 + * @return an integer < 0 if cache1 is less than cache2, 0 if they are equal, and > 0 if cache1 is greater than + * cache2. + */ + protected abstract int compareCaches(final cgCache cache1, final cgCache cache2); } diff --git a/src/cgeo/geocaching/sorting/DateComparator.java b/src/cgeo/geocaching/sorting/DateComparator.java index f1d08a4..acc4ff2 100644 --- a/src/cgeo/geocaching/sorting/DateComparator.java +++ b/src/cgeo/geocaching/sorting/DateComparator.java @@ -1,34 +1,35 @@ package cgeo.geocaching.sorting; -import java.util.Date; - import cgeo.geocaching.cgCache; +import java.util.Date; + /** * compares caches by date + * * @author bananeweizen - * + * */ public class DateComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return true; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return true; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - Date date1 = cache1.hidden; - Date date2 = cache2.hidden; - if (date1 != null && date2 != null) { - return date1.compareTo(date2); - } - if (date1 != null) { - return -1; - } - if (date2 != null) { - return 1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + Date date1 = cache1.hidden; + Date date2 = cache2.hidden; + if (date1 != null && date2 != null) { + return date1.compareTo(date2); + } + if (date1 != null) { + return -1; + } + if (date2 != null) { + return 1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/DifficultyComparator.java b/src/cgeo/geocaching/sorting/DifficultyComparator.java index cb16b7c..ad55691 100644 --- a/src/cgeo/geocaching/sorting/DifficultyComparator.java +++ b/src/cgeo/geocaching/sorting/DifficultyComparator.java @@ -4,22 +4,22 @@ import cgeo.geocaching.cgCache; /** * sorts caches by difficulty - * + * */ public class DifficultyComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.difficulty != null && cache2.difficulty != null; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.difficulty != null && cache2.difficulty != null; + } - @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { - if (cache1.difficulty > cache2.difficulty) { - return 1; - } else if (cache2.difficulty > cache1.difficulty) { - return -1; - } - return 0; - } + @Override + protected int compareCaches(final cgCache cache1, final cgCache cache2) { + if (cache1.difficulty > cache2.difficulty) { + return 1; + } else if (cache2.difficulty > cache1.difficulty) { + return -1; + } + return 0; + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/sorting/DistanceComparator.java b/src/cgeo/geocaching/sorting/DistanceComparator.java index 9a5b551..9bc05a2 100644 --- a/src/cgeo/geocaching/sorting/DistanceComparator.java +++ b/src/cgeo/geocaching/sorting/DistanceComparator.java @@ -5,36 +5,36 @@ import cgeo.geocaching.geopoint.Geopoint; /** * sorts caches by distance to current position - * + * */ public class DistanceComparator extends AbstractCacheComparator { - private final Geopoint coords; + private final Geopoint coords; - public DistanceComparator(final Geopoint coords) { - this.coords = coords; - } + public DistanceComparator(final Geopoint coords) { + this.coords = coords; + } - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return true; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return true; + } - @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { - if ((cache1.coords == null || cache2.coords == null) - && cache1.distance != null && cache2.distance != null) { - return Double.compare(cache1.distance, cache2.distance); - } else { - if (cache1.coords == null) { - return 1; - } - if (cache2.coords == null) { - return -1; - } + @Override + protected int compareCaches(final cgCache cache1, final cgCache cache2) { + if ((cache1.coords == null || cache2.coords == null) + && cache1.distance != null && cache2.distance != null) { + return Double.compare(cache1.distance, cache2.distance); + } else { + if (cache1.coords == null) { + return 1; + } + if (cache2.coords == null) { + return -1; + } + + return Float.compare(coords.distanceTo(cache1.coords), + coords.distanceTo(cache2.coords)); + } + } - return Float.compare(coords.distanceTo(cache1.coords), - coords.distanceTo(cache2.coords)); - } - } - } diff --git a/src/cgeo/geocaching/sorting/FindsComparator.java b/src/cgeo/geocaching/sorting/FindsComparator.java index 8553f4b..efde22d 100644 --- a/src/cgeo/geocaching/sorting/FindsComparator.java +++ b/src/cgeo/geocaching/sorting/FindsComparator.java @@ -5,36 +5,36 @@ import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; public class FindsComparator extends AbstractCacheComparator implements - CacheComparator { - - private cgeoapplication app; - - public FindsComparator(cgeoapplication app) { - this.app = app; - } - - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.logCounts != null && cache2.logCounts != null; - } - - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - int finds1 = getFindsCount(cache1); - int finds2 = getFindsCount(cache2); - return finds2 - finds1; - } - - private int getFindsCount(cgCache cache) { - int finds = 0; - if (cache.logCounts.isEmpty()) { - cache.logCounts = app.loadLogCounts(cache.geocode); - } - Integer logged = cache.logCounts.get(cgBase.LOG_FOUND_IT); - if (logged != null) { - finds = logged; - } - return finds; - } + CacheComparator { + + private cgeoapplication app; + + public FindsComparator(cgeoapplication app) { + this.app = app; + } + + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.logCounts != null && cache2.logCounts != null; + } + + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + int finds1 = getFindsCount(cache1); + int finds2 = getFindsCount(cache2); + return finds2 - finds1; + } + + private int getFindsCount(cgCache cache) { + int finds = 0; + if (cache.logCounts.isEmpty()) { + cache.logCounts = app.loadLogCounts(cache.geocode); + } + Integer logged = cache.logCounts.get(cgBase.LOG_FOUND_IT); + if (logged != null) { + finds = logged; + } + return finds; + } } diff --git a/src/cgeo/geocaching/sorting/GeocodeComparator.java b/src/cgeo/geocaching/sorting/GeocodeComparator.java index 957545b..004970b 100644 --- a/src/cgeo/geocaching/sorting/GeocodeComparator.java +++ b/src/cgeo/geocaching/sorting/GeocodeComparator.java @@ -1,28 +1,28 @@ package cgeo.geocaching.sorting; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + /** * sorts caches by GC code, therefore effectively sorting by cache age - * + * */ public class GeocodeComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return StringUtils.isNotBlank(cache1.geocode) - && StringUtils.isNotBlank(cache2.geocode); - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return StringUtils.isNotBlank(cache1.geocode) + && StringUtils.isNotBlank(cache2.geocode); + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - if (cache1.geocode.length() > cache2.geocode.length()) { - return 1; - } else if (cache2.geocode.length() > cache1.geocode.length()) { - return -1; - } - return cache1.geocode.compareToIgnoreCase(cache2.geocode); - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + if (cache1.geocode.length() > cache2.geocode.length()) { + return 1; + } else if (cache2.geocode.length() > cache1.geocode.length()) { + return -1; + } + return cache1.geocode.compareToIgnoreCase(cache2.geocode); + } } diff --git a/src/cgeo/geocaching/sorting/InventoryComparator.java b/src/cgeo/geocaching/sorting/InventoryComparator.java index c126e41..ed4dcb7 100644 --- a/src/cgeo/geocaching/sorting/InventoryComparator.java +++ b/src/cgeo/geocaching/sorting/InventoryComparator.java @@ -4,25 +4,26 @@ import cgeo.geocaching.cgCache; /** * sorts caches by number of items in inventory + * * @author bananeweizen - * + * */ public class InventoryComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return true; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return true; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - int itemCount1 = cache1.inventoryItems; - int itemCount2 = cache2.inventoryItems; - if (itemCount1 < itemCount2) { - return 1; - } else if (itemCount2 < itemCount1) { - return -1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + int itemCount1 = cache1.inventoryItems; + int itemCount2 = cache2.inventoryItems; + if (itemCount1 < itemCount2) { + return 1; + } else if (itemCount2 < itemCount1) { + return -1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/NameComparator.java b/src/cgeo/geocaching/sorting/NameComparator.java index 9f72258..43707f6 100644 --- a/src/cgeo/geocaching/sorting/NameComparator.java +++ b/src/cgeo/geocaching/sorting/NameComparator.java @@ -1,22 +1,22 @@ package cgeo.geocaching.sorting; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + /** * sorts caches by name - * + * */ public class NameComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return StringUtils.isNotBlank(cache1.name) && StringUtils.isNotBlank(cache2.name); - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return StringUtils.isNotBlank(cache1.name) && StringUtils.isNotBlank(cache2.name); + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - return cache1.name.compareToIgnoreCase(cache2.name); - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + return cache1.name.compareToIgnoreCase(cache2.name); + } } diff --git a/src/cgeo/geocaching/sorting/PopularityComparator.java b/src/cgeo/geocaching/sorting/PopularityComparator.java index cc1a6ea..eb02f44 100644 --- a/src/cgeo/geocaching/sorting/PopularityComparator.java +++ b/src/cgeo/geocaching/sorting/PopularityComparator.java @@ -4,22 +4,22 @@ import cgeo.geocaching.cgCache; /** * sorts caches by popularity (favorite count) - * + * */ public class PopularityComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.favouriteCnt != null && cache2.favouriteCnt != null; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.favouriteCnt != null && cache2.favouriteCnt != null; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - if (cache1.favouriteCnt < cache2.favouriteCnt) { - return 1; - } else if (cache2.favouriteCnt < cache1.favouriteCnt) { - return -1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + if (cache1.favouriteCnt < cache2.favouriteCnt) { + return 1; + } else if (cache2.favouriteCnt < cache1.favouriteCnt) { + return -1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/RatingComparator.java b/src/cgeo/geocaching/sorting/RatingComparator.java index 3cdf474..4542ed5 100644 --- a/src/cgeo/geocaching/sorting/RatingComparator.java +++ b/src/cgeo/geocaching/sorting/RatingComparator.java @@ -4,33 +4,33 @@ import cgeo.geocaching.cgCache; /** * sorts caches by gcvote.com rating - * + * */ public class RatingComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.rating != null && cache2.rating != null; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.rating != null && cache2.rating != null; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - Float rating1 = cache1.rating; - Float rating2 = cache2.rating; + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + Float rating1 = cache1.rating; + Float rating2 = cache2.rating; - // voting can be disabled for caches, then assume an average rating instead - if (rating1 == 0.0) { - rating1 = 2.5f; - } - if (rating2 == 0.0) { - rating2 = 2.5f; - } + // voting can be disabled for caches, then assume an average rating instead + if (rating1 == 0.0) { + rating1 = 2.5f; + } + if (rating2 == 0.0) { + rating2 = 2.5f; + } - if (rating1 < rating2) { - return 1; - } else if (rating2 < rating1) { - return -1; - } - return 0; - } + if (rating1 < rating2) { + return 1; + } else if (rating2 < rating1) { + return -1; + } + return 0; + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/sorting/SizeComparator.java b/src/cgeo/geocaching/sorting/SizeComparator.java index cff5c49..56ca593 100644 --- a/src/cgeo/geocaching/sorting/SizeComparator.java +++ b/src/cgeo/geocaching/sorting/SizeComparator.java @@ -1,50 +1,51 @@ package cgeo.geocaching.sorting; -import org.apache.commons.lang3.StringUtils; - import cgeo.geocaching.cgCache; +import org.apache.commons.lang3.StringUtils; + /** * sorts caches by size - * + * */ public class SizeComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return StringUtils.isNotBlank(cache1.size) && StringUtils.isNotBlank(cache2.size); - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return StringUtils.isNotBlank(cache1.size) && StringUtils.isNotBlank(cache2.size); + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - int size1 = getSize(cache1); - int size2 = getSize(cache2); - if (size1 < size2) { - return 1; - } else if (size2 < size1) { - return -1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + int size1 = getSize(cache1); + int size2 = getSize(cache2); + if (size1 < size2) { + return 1; + } else if (size2 < size1) { + return -1; + } + return 0; + } - /** - * speed optimized comparison of size string - * @param cache - * @return - */ - private static int getSize(final cgCache cache) { - char c = cache.size.charAt(0); - switch (c) { - case 'm': // micro - return 1; - case 's': // small - return 2; - case 'r': // regular - return 3; - case 'l': // large - return 4; - default: - return 0; - } - } + /** + * speed optimized comparison of size string + * + * @param cache + * @return + */ + private static int getSize(final cgCache cache) { + char c = cache.size.charAt(0); + switch (c) { + case 'm': // micro + return 1; + case 's': // small + return 2; + case 'r': // regular + return 3; + case 'l': // large + return 4; + default: + return 0; + } + } }
\ No newline at end of file diff --git a/src/cgeo/geocaching/sorting/StateComparator.java b/src/cgeo/geocaching/sorting/StateComparator.java index 787af5a..232fa92 100644 --- a/src/cgeo/geocaching/sorting/StateComparator.java +++ b/src/cgeo/geocaching/sorting/StateComparator.java @@ -4,29 +4,29 @@ import cgeo.geocaching.cgCache; /** * sort caches by state (normal, disabled, archived) - * + * */ public class StateComparator extends AbstractCacheComparator implements - CacheComparator { + CacheComparator { - @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { - return true; - } + @Override + protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + return true; + } - @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { - return getState(cache1) - getState(cache2); - } + @Override + protected int compareCaches(final cgCache cache1, final cgCache cache2) { + return getState(cache1) - getState(cache2); + } - private static int getState(final cgCache cache) { - if (cache.disabled) { - return 1; - } - if (cache.archived) { - return 2; - } - return 0; - } + private static int getState(final cgCache cache) { + if (cache.disabled) { + return 1; + } + if (cache.archived) { + return 2; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/TerrainComparator.java b/src/cgeo/geocaching/sorting/TerrainComparator.java index bf66af9..484889e 100644 --- a/src/cgeo/geocaching/sorting/TerrainComparator.java +++ b/src/cgeo/geocaching/sorting/TerrainComparator.java @@ -4,22 +4,22 @@ import cgeo.geocaching.cgCache; /** * sorts caches by terrain rating - * + * */ public class TerrainComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.terrain != null && cache2.terrain != null; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.terrain != null && cache2.terrain != null; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - if (cache1.terrain > cache2.terrain) { - return 1; - } else if (cache2.terrain > cache1.terrain) { - return -1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + if (cache1.terrain > cache2.terrain) { + return 1; + } else if (cache2.terrain > cache1.terrain) { + return -1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/VisitComparator.java b/src/cgeo/geocaching/sorting/VisitComparator.java index 79a8ac5..5dfeed4 100644 --- a/src/cgeo/geocaching/sorting/VisitComparator.java +++ b/src/cgeo/geocaching/sorting/VisitComparator.java @@ -4,23 +4,23 @@ import cgeo.geocaching.cgCache; /** * sorts caches by last visited date - * + * */ public class VisitComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return cache1.visitedDate != null && cache1.visitedDate > 0 - && cache2.visitedDate != null && cache2.visitedDate > 0; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return cache1.visitedDate != null && cache1.visitedDate > 0 + && cache2.visitedDate != null && cache2.visitedDate > 0; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - if (cache1.visitedDate > cache2.visitedDate) { - return -1; - } else if (cache1.visitedDate < cache2.visitedDate) { - return 1; - } - return 0; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + if (cache1.visitedDate > cache2.visitedDate) { + return -1; + } else if (cache1.visitedDate < cache2.visitedDate) { + return 1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/sorting/VoteComparator.java b/src/cgeo/geocaching/sorting/VoteComparator.java index 0039c7c..181b19c 100644 --- a/src/cgeo/geocaching/sorting/VoteComparator.java +++ b/src/cgeo/geocaching/sorting/VoteComparator.java @@ -4,36 +4,36 @@ import cgeo.geocaching.cgCache; /** * sorts caches by the users own voting (if available at all) - * + * * @author bananeweizen - * + * */ public class VoteComparator extends AbstractCacheComparator { - @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { - return true; - } + @Override + protected boolean canCompare(cgCache cache1, cgCache cache2) { + return true; + } - @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { - // if there is no vote available, put that cache at the end of the list - float vote1 = 0; - if (cache1.myVote != null) { - vote1 = cache1.myVote; - } + @Override + protected int compareCaches(cgCache cache1, cgCache cache2) { + // if there is no vote available, put that cache at the end of the list + float vote1 = 0; + if (cache1.myVote != null) { + vote1 = cache1.myVote; + } - float vote2 = 0; - if (cache2.myVote != null) { - vote2 = cache2.myVote; - } + float vote2 = 0; + if (cache2.myVote != null) { + vote2 = cache2.myVote; + } - // compare - if (vote1 < vote2) { - return 1; - } else if (vote2 < vote1) { - return -1; - } - return 0; - } + // compare + if (vote1 < vote2) { + return 1; + } else if (vote2 < vote1) { + return -1; + } + return 0; + } } diff --git a/src/cgeo/geocaching/utils/CollectionUtils.java b/src/cgeo/geocaching/utils/CollectionUtils.java index 89b4b51..b7c6f3f 100644 --- a/src/cgeo/geocaching/utils/CollectionUtils.java +++ b/src/cgeo/geocaching/utils/CollectionUtils.java @@ -5,21 +5,20 @@ import java.util.Map; public class CollectionUtils {
- public static <T> boolean isEmpty(List<T> list) {
+ public static <T> boolean isEmpty(List<T> list) {
return (list != null && list.size() == 0);
}
- public static <T,T2> boolean isEmpty(Map<T,T2> map) {
+
+ public static <T, T2> boolean isEmpty(Map<T, T2> map) {
return (map != null && map.size() == 0);
}
-
- public static <T> boolean isNotEmpty(List<T> list) {
+ public static <T> boolean isNotEmpty(List<T> list) {
return (list != null && list.size() != 0);
}
- public static <T,T2> boolean isNotEmpty(Map<T,T2> map) {
+ public static <T, T2> boolean isNotEmpty(Map<T, T2> map) {
return (map != null && map.size() != 0);
}
-
}
|
