aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching
diff options
context:
space:
mode:
authorblafoo <github@blafoo.de>2011-08-29 21:22:02 +0200
committerblafoo <github@blafoo.de>2011-08-29 21:22:02 +0200
commitc49f2c54eea35ddd69121503fc604c75326913f9 (patch)
treee0c78545204c9374239206ed28a8c2c97ea80488 /src/cgeo/geocaching
parentfcf623e1aeaf1ca5c891ad59605d4e8759dfadc1 (diff)
parent48ec48f87f7b736411f28cb76ac1add8c61d2e10 (diff)
downloadcgeo-c49f2c54eea35ddd69121503fc604c75326913f9.zip
cgeo-c49f2c54eea35ddd69121503fc604c75326913f9.tar.gz
cgeo-c49f2c54eea35ddd69121503fc604c75326913f9.tar.bz2
Merge remote-tracking branch 'upstream/master' into javadoc
Diffstat (limited to 'src/cgeo/geocaching')
-rw-r--r--src/cgeo/geocaching/LogTemplateProvider.java10
-rw-r--r--src/cgeo/geocaching/UnknownTagsHandler.java33
-rw-r--r--src/cgeo/geocaching/activity/ActivityMixin.java3
-rw-r--r--src/cgeo/geocaching/cgBase.java296
-rw-r--r--src/cgeo/geocaching/cgCache.java12
-rw-r--r--src/cgeo/geocaching/cgSettings.java15
-rw-r--r--src/cgeo/geocaching/cgeo.java97
-rw-r--r--src/cgeo/geocaching/cgeoadvsearch.java4
-rw-r--r--src/cgeo/geocaching/cgeoapplication.java4
-rw-r--r--src/cgeo/geocaching/cgeocaches.java174
-rw-r--r--src/cgeo/geocaching/cgeocoords.java20
-rw-r--r--src/cgeo/geocaching/cgeodetail.java78
-rw-r--r--src/cgeo/geocaching/cgeogpxes.java23
-rw-r--r--src/cgeo/geocaching/cgeohelpers.java47
-rw-r--r--src/cgeo/geocaching/cgeoinit.java7
-rw-r--r--src/cgeo/geocaching/cgeopopup.java4
-rw-r--r--src/cgeo/geocaching/connector/ConnectorFactory.java2
-rw-r--r--src/cgeo/geocaching/connector/OCConnector.java4
-rw-r--r--src/cgeo/geocaching/connector/OXConnector.java21
-rw-r--r--src/cgeo/geocaching/files/GPXParser.java239
-rw-r--r--src/cgeo/geocaching/googlemaps/googleCacheOverlay.java15
-rw-r--r--src/cgeo/geocaching/googlemaps/googleMapFactory.java8
-rw-r--r--src/cgeo/geocaching/googlemaps/googleMapView.java42
-rw-r--r--src/cgeo/geocaching/googlemaps/googleOverlay.java37
-rw-r--r--src/cgeo/geocaching/googlemaps/googleUsersOverlay.java16
-rw-r--r--src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java9
-rw-r--r--src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java33
-rw-r--r--src/cgeo/geocaching/mapcommon/cgMapOverlay.java124
-rw-r--r--src/cgeo/geocaching/mapcommon/cgOverlayScale.java16
-rw-r--r--src/cgeo/geocaching/mapcommon/cgeomap.java22
-rw-r--r--src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java4
-rw-r--r--src/cgeo/geocaching/mapinterfaces/MapFactory.java2
-rw-r--r--src/cgeo/geocaching/mapinterfaces/MapViewImpl.java13
-rw-r--r--src/cgeo/geocaching/mapinterfaces/OverlayBase.java1
-rw-r--r--src/cgeo/geocaching/mapinterfaces/OverlayImpl.java9
-rw-r--r--src/cgeo/geocaching/mapsforge/mfCacheOverlay.java14
-rw-r--r--src/cgeo/geocaching/mapsforge/mfMapController.java10
-rw-r--r--src/cgeo/geocaching/mapsforge/mfMapFactory.java8
-rw-r--r--src/cgeo/geocaching/mapsforge/mfMapView.java41
-rw-r--r--src/cgeo/geocaching/mapsforge/mfOverlay.java38
-rw-r--r--src/cgeo/geocaching/mapsforge/mfUsersOverlay.java14
-rw-r--r--src/cgeo/geocaching/sorting/FindsComparator.java40
42 files changed, 1032 insertions, 577 deletions
diff --git a/src/cgeo/geocaching/LogTemplateProvider.java b/src/cgeo/geocaching/LogTemplateProvider.java
index a6beda3..210f863 100644
--- a/src/cgeo/geocaching/LogTemplateProvider.java
+++ b/src/cgeo/geocaching/LogTemplateProvider.java
@@ -62,6 +62,14 @@ public class LogTemplateProvider {
return base.formatTime(System.currentTimeMillis());
}
},
+ new LogTemplate("DATETIME", R.string.init_signature_template_datetime) {
+
+ @Override
+ String getValue(final cgBase base) {
+ final long currentTime = System.currentTimeMillis();
+ return base.formatFullDate(currentTime) + " " + base.formatTime(currentTime);
+ }
+ },
new LogTemplate("USER", R.string.init_signature_template_user) {
@Override
@@ -117,7 +125,7 @@ public class LogTemplateProvider {
int findCount = -1;
try {
- final Pattern findPattern = Pattern.compile("<strong><img.+?icon_smile.+?title=\"Caches Found\" /> ([,\\d]+)</strong>", Pattern.CASE_INSENSITIVE);
+ 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) {
diff --git a/src/cgeo/geocaching/UnknownTagsHandler.java b/src/cgeo/geocaching/UnknownTagsHandler.java
new file mode 100644
index 0000000..f1b418c
--- /dev/null
+++ b/src/cgeo/geocaching/UnknownTagsHandler.java
@@ -0,0 +1,33 @@
+package cgeo.geocaching;
+
+import org.xml.sax.XMLReader;
+
+import android.text.Editable;
+import android.text.Html.TagHandler;
+import android.text.Spannable;
+import android.text.style.StrikethroughSpan;
+
+public class UnknownTagsHandler implements TagHandler {
+
+ private static final int UNDEFINED_POSITION = -1;
+ int strikePos = UNDEFINED_POSITION;
+
+ public void handleTag(boolean opening, String tag, Editable output,
+ XMLReader xmlReader) {
+ if(tag.equalsIgnoreCase("strike") || tag.equals("s")) {
+ handleStrike(opening, output);
+ }
+ }
+
+ private void handleStrike(boolean opening, Editable output) {
+ int length = output.length();
+ if(opening) {
+ strikePos = length;
+ } else {
+ if (strikePos > UNDEFINED_POSITION) {
+ output.setSpan(new StrikethroughSpan(), strikePos, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ strikePos = UNDEFINED_POSITION;
+ }
+ }
+ }
+}
diff --git a/src/cgeo/geocaching/activity/ActivityMixin.java b/src/cgeo/geocaching/activity/ActivityMixin.java
index 68a4403..acbb405 100644
--- a/src/cgeo/geocaching/activity/ActivityMixin.java
+++ b/src/cgeo/geocaching/activity/ActivityMixin.java
@@ -120,6 +120,9 @@ public final class ActivityMixin {
}
protected static void addVisitMenu(IAbstractActivity activity, Menu menu, cgCache cache) {
+ if (cache == null) {
+ return;
+ }
if (!cache.supportsLogging()) {
return;
}
diff --git a/src/cgeo/geocaching/cgBase.java b/src/cgeo/geocaching/cgBase.java
index 92082a3..2483438 100644
--- a/src/cgeo/geocaching/cgBase.java
+++ b/src/cgeo/geocaching/cgBase.java
@@ -86,6 +86,7 @@ public class cgBase {
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);
@@ -94,7 +95,6 @@ public class cgBase {
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 patternLogs = Pattern.compile("<table class=\"LogsTable\">(.*?)</table>\\s*<p", 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);
@@ -125,22 +125,22 @@ public class cgBase {
"yyyy/MM/dd",
"dd/MMM/yyyy",
"MMM/dd/yyyy",
- "dd MMM yy"
+ "dd MMM yy",
+ "dd/MM/yyyy"
};
-
+
HashMap<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
- public final static SimpleDateFormat dateGPXIn = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 2010-04-20T07:00:00Z
private Resources res = null;
private HashMap<String, String> cookies = new HashMap<String, String>();
private static final String passMatch = "[/\\?&]*[Pp]ass(word)?=[^&^#^$]+";
@@ -1313,14 +1313,17 @@ public class cgBase {
}
// cache found
- try {
- final Matcher matcherFound = patternFound.matcher(page);
- if (matcherFound.find()) {
- if (matcherFound.group() != null && matcherFound.group().length() > 0) {
- cache.found = true;
- }
+ try
+ {
+ final Matcher matcherFound = patternFound.matcher(page);
+ final Matcher matcherFoundAlternative = patternFoundAlternative.matcher(page);
+
+ if (matcherFound.find() || matcherFoundAlternative.find()) {
+ cache.found = true;
}
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
// failed to parse found
Log.w(cgSettings.tag, "cgeoBase.parseCache: Failed to parse found");
}
@@ -1571,7 +1574,7 @@ public class cgBase {
try
{
final Matcher matcherLogCounts = patternCountLogs.matcher(page);
-
+
if (matcherLogCounts.find())
{
final Matcher matcherLog = patternCountLog.matcher(matcherLogCounts.group(1));
@@ -1580,7 +1583,7 @@ public class cgBase {
{
String typeStr = matcherLog.group(1);
String countStr = matcherLog.group(2);
-
+
if (typeStr != null
&& typeStr.length() > 0
&& logTypes.containsKey(typeStr.toLowerCase())
@@ -1601,72 +1604,67 @@ public class cgBase {
// cache logs
try
{
-// final Matcher matcherLogs = patternLogs.matcher(page);
-//
-// if (matcherLogs.find())
-// {
- /*
- 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));
+ /*
+ 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();
- while (matcherLog.find())
+ if (logTypes.containsKey(matcherLog.group(3).toLowerCase()))
{
- final cgLog logDone = new cgLog();
-
- if (logTypes.containsKey(matcherLog.group(3).toLowerCase()))
- {
- logDone.type = logTypes.get(matcherLog.group(3).toLowerCase());
- }
- else
- {
- logDone.type = logTypes.get("icon_note");
- }
+ logDone.type = logTypes.get(matcherLog.group(3).toLowerCase());
+ }
+ 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.");
- }
+ 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();
+ logDone.author = Html.fromHtml(matcherLog.group(1)).toString();
- if (null != matcherLog.group(2))
- {
- logDone.found = Integer.parseInt(matcherLog.group(2).replaceAll(",", ""));
- }
+ if (null != matcherLog.group(2))
+ {
+ logDone.found = Integer.parseInt(matcherLog.group(2).replaceAll(",", ""));
+ }
- logDone.log = matcherLog.group(6);
+ logDone.log = matcherLog.group(6);
- final Matcher matcherImg = patternLogImgs.matcher(matcherLog.group(7));
- while (matcherImg.find())
+ 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)
{
- 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);
+ logDone.logImages = new ArrayList<cgImage>();
}
+ logDone.logImages.add(logImage);
+ }
- if (null == cache.logs)
- {
- cache.logs = new ArrayList<cgLog>();
- }
- cache.logs.add(logDone);
+ if (null == cache.logs)
+ {
+ cache.logs = new ArrayList<cgLog>();
}
-// }
+ cache.logs.add(logDone);
+ }
}
catch (Exception e)
{
@@ -1896,16 +1894,27 @@ public class cgBase {
// And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler!
}
- private static Date parseGcCustomDate(String input)
+ public Date parseGcCustomDate(String input)
throws ParseException
{
if (input == null)
{
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
@@ -1914,9 +1923,25 @@ public class cgBase {
}
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();
+
+ final Pattern pattern = Pattern.compile("<option selected=\"selected\" value=\"([ /Mdy-]+)\">", Pattern.CASE_INSENSITIVE);
+ final Matcher matcher = pattern.matcher(result);
+
+ if (matcher.find())
+ {
+ settings.setGcCustomDate(matcher.group(1));
+ }
+ }
public cgRating getRating(String guid, String geocode) {
ArrayList<String> guids = null;
@@ -2079,10 +2104,10 @@ public class cgBase {
final Pattern patternSpottedOwner = 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);
final Pattern patternGoal = Pattern.compile("<h3>\\W*Current GOAL[^<]*</h3>[^<]*<p[^>]*>(.*)</p>[^<]*<h3>\\W*About This Item[^<]*</h3>", Pattern.CASE_INSENSITIVE);
final Pattern patternDetailsImage = 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);
- final Pattern patternLogs = Pattern.compile("<table class=\"TrackableItemLogTable Table\">(.*)<\\/table>[^<]*<ul", Pattern.CASE_INSENSITIVE);
final Pattern patternIcon = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE);
final Pattern patternType = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"[^\"]+\" alt=\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE);
final Pattern patternDistance = Pattern.compile("<h4[^>]*\\W*Tracking History \\(([0-9\\.,]+(km|mi))[^\\)]*\\)", Pattern.CASE_INSENSITIVE);
+ final Pattern patternLog = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^\\.]+).gif[^>]+>&nbsp;([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?guid=([^\"]+)\">([^<]+)</a>.+?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE);
final cgTrackable trackable = new cgTrackable();
@@ -2289,90 +2314,47 @@ public class cgBase {
}
// trackable logs
- try {
- final Matcher matcherLogs = patternLogs.matcher(page);
- while (matcherLogs.find()) {
- if (matcherLogs.groupCount() > 0) {
- final Pattern patternLog = Pattern.compile("[^>]*>" +
- "[^<]*<td[^<]*<img src=[\"|'].*\\/icons\\/([^\\.]+)\\.[a-z]{2,5}[\"|'][^>]*>&nbsp;(\\d+).(\\d+).(\\d+)[^<]*</td>" +
- "[^<]*<td>[^<]*<a href=[^>]+>([^<]+)<.a>([^<]*|[^<]*<a href=[\"|'].*guid=([^\"]*)\">([^<]*)</a>[^<]*)</td>" +
- "[^<]*<td>[^<]*</td>" +
- "[^<]*<td[^<]*<a href=[^>]+>[^<]+</a>[^<]*</td>[^<]*</tr>" +
- "[^<]*<tr[^>]*>[^<]*<td[^>]*>(.*?)</td>[^<]*</tr>.*" +
- "");
- // 1 filename == type
- // 2 month
- // 3 date
- // 4 year
- // 5 user
- // 6 action dependent
- // 7 cache guid
- // 8 cache name
- // 9 text
- final String[] logs = matcherLogs.group(1).split("<tr class=\"Data BorderTop");
- final int logsCnt = logs.length;
-
- for (int k = 1; k < logsCnt; k++) {
- final Matcher matcherLog = patternLog.matcher(logs[k]);
- if (matcherLog.find()) {
- final cgLog logDone = new cgLog();
-
- String logTmp = matcherLog.group(9);
- logTmp = Pattern.compile("<p>").matcher(logTmp).replaceAll("\n");
- logTmp = Pattern.compile("<br[^>]*>").matcher(logTmp).replaceAll("\n");
- logTmp = Pattern.compile("<\\/p>").matcher(logTmp).replaceAll("");
- logTmp = Pattern.compile("\r+").matcher(logTmp).replaceAll("\n");
-
- int day = -1;
- try {
- day = Integer.parseInt(matcherLog.group(3));
- } catch (Exception e) {
- Log.w(cgSettings.tag, "Failed to parse logs date (day): " + e.toString());
- }
-
- int month = -1;
- try {
- month = Integer.parseInt(matcherLog.group(2));
- month -= 1;
- } catch (Exception e) {
- Log.w(cgSettings.tag, "Failed to parse logs date (month): " + e.toString());
- }
-
- int year = -1;
- try {
- year = Integer.parseInt(matcherLog.group(4));
- } catch (Exception e) {
- Log.w(cgSettings.tag, "Failed to parse logs date (year): " + e.toString());
- }
-
- long logDate;
- if (year > 0 && month >= 0 && day > 0) {
- Calendar date = Calendar.getInstance();
- date.set(year, month, day, 12, 0, 0);
- logDate = date.getTimeInMillis();
- logDate = (logDate / 1000L) * 1000L;
- } else {
- logDate = 0;
- }
-
- if (logTypes.containsKey(matcherLog.group(1).toLowerCase())) {
- logDone.type = logTypes.get(matcherLog.group(1).toLowerCase());
- } else {
- logDone.type = logTypes.get("icon_note");
- }
-
- logDone.author = Html.fromHtml(matcherLog.group(5)).toString();
- logDone.date = logDate;
- logDone.log = logTmp;
- if (matcherLog.group(7) != null && matcherLog.group(8) != null) {
- logDone.cacheGuid = matcherLog.group(7);
- logDone.cacheName = matcherLog.group(8);
- }
-
- trackable.logs.add(logDone);
- }
- }
+ try
+ {
+ final Matcher matcherLogs = patternLog.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()))
+ {
+ logDone.type = logTypes.get(matcherLogs.group(1).toLowerCase());
+ }
+ else
+ {
+ 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
diff --git a/src/cgeo/geocaching/cgCache.java b/src/cgeo/geocaching/cgCache.java
index 72c1e86..d528aac 100644
--- a/src/cgeo/geocaching/cgCache.java
+++ b/src/cgeo/geocaching/cgCache.java
@@ -296,9 +296,15 @@ public class cgCache {
return true;
}
- public boolean logOffline(final IAbstractActivity fromActivity, final int logType) {
- logOffline(fromActivity, "", Calendar.getInstance(), logType);
- return true;
+ public boolean logOffline(final IAbstractActivity fromActivity, final int logType, final cgSettings settings, final cgBase base) {
+ String log = "";
+ if (settings.getSignature() != null
+ && settings.signatureAutoinsert
+ && settings.getSignature().length() > 0) {
+ log = LogTemplateProvider.applyTemplates(settings.getSignature(), base);
+ }
+ logOffline(fromActivity, log, Calendar.getInstance(), logType);
+ return true;
}
void logOffline(final IAbstractActivity fromActivity, final String log, Calendar date, final int logType) {
diff --git a/src/cgeo/geocaching/cgSettings.java b/src/cgeo/geocaching/cgSettings.java
index b2d2cf5..7c6be93 100644
--- a/src/cgeo/geocaching/cgSettings.java
+++ b/src/cgeo/geocaching/cgSettings.java
@@ -56,6 +56,7 @@ public class cgSettings {
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);
@@ -608,4 +609,18 @@ public class cgSettings {
public boolean getLoadDirImg() {
return prefs.getBoolean(KEY_LOAD_DIRECTION_IMG, true);
}
+
+ void setGcCustomDate(final String format) {
+ editSettings(new PrefRunnable() {
+
+ @Override
+ public void edit(Editor edit) {
+ edit.putString(KEY_GC_CUSTOM_DATE, format);
+ }
+ });
+ }
+
+ public String getGcCustomDate() {
+ return prefs.getString(KEY_GC_CUSTOM_DATE, null);
+ }
}
diff --git a/src/cgeo/geocaching/cgeo.java b/src/cgeo/geocaching/cgeo.java
index 3a509db..df167fb 100644
--- a/src/cgeo/geocaching/cgeo.java
+++ b/src/cgeo/geocaching/cgeo.java
@@ -12,6 +12,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.location.Address;
import android.location.Geocoder;
@@ -31,6 +32,15 @@ import cgeo.geocaching.activity.ActivityMixin;
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;
@@ -217,43 +227,100 @@ public class cgeo extends AbstractActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, 0, 0, res.getString(R.string.menu_about)).setIcon(android.R.drawable.ic_menu_help);
- menu.add(0, 1, 0, res.getString(R.string.menu_helpers)).setIcon(android.R.drawable.ic_menu_add);
- menu.add(0, 2, 0, res.getString(R.string.menu_settings)).setIcon(android.R.drawable.ic_menu_preferences);
- menu.add(0, 3, 0, res.getString(R.string.menu_history)).setIcon(android.R.drawable.ic_menu_recent_history);
+ 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();
- if (id == 0) {
+ switch (id) {
+ case MENU_ABOUT:
showAbout(null);
-
return true;
- } else if (id == 1) {
+ case MENU_HELPERS:
context.startActivity(new Intent(context, cgeohelpers.class));
-
return true;
- } else if (id == 2) {
+ case MENU_SETTINGS:
context.startActivity(new Intent(context, cgeoinit.class));
-
return true;
- } else if (id == 3) {
+ 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 (scan == null || scan.length() == 0) {
+ 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) {
+ ArrayList<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
@@ -303,6 +370,11 @@ public class cgeo extends AbstractActivity {
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;
@@ -382,6 +454,7 @@ public class cgeo extends AbstractActivity {
final RelativeLayout findByOffline = (RelativeLayout) findViewById(R.id.search_offline);
findByOffline.setClickable(true);
findByOffline.setOnClickListener(new cgeoFindByOfflineListener());
+ registerForContextMenu(findByOffline);
(new countBubbleUpdate()).start();
diff --git a/src/cgeo/geocaching/cgeoadvsearch.java b/src/cgeo/geocaching/cgeoadvsearch.java
index d2b3fc7..f6f2159 100644
--- a/src/cgeo/geocaching/cgeoadvsearch.java
+++ b/src/cgeo/geocaching/cgeoadvsearch.java
@@ -438,9 +438,7 @@ public class cgeoadvsearch extends AbstractActivity {
return;
}
- final Intent cachesIntent = new Intent(this, cgeodetail.class);
- cachesIntent.putExtra("geocode", geocodeText.toUpperCase());
- startActivity(cachesIntent);
+ cgeodetail.startActivity(this, geocodeText);
}
private class findTrackableAction implements TextView.OnEditorActionListener {
diff --git a/src/cgeo/geocaching/cgeoapplication.java b/src/cgeo/geocaching/cgeoapplication.java
index e165c0f..fece371 100644
--- a/src/cgeo/geocaching/cgeoapplication.java
+++ b/src/cgeo/geocaching/cgeoapplication.java
@@ -746,6 +746,10 @@ public class cgeoapplication extends Application {
return storage.loadInventory(geocode);
}
+ public HashMap<Integer,Integer> loadLogCounts(String geocode) {
+ return storage.loadLogCounts(geocode);
+ }
+
public ArrayList<cgImage> loadSpoilers(String geocode) {
return storage.loadSpoilers(geocode);
}
diff --git a/src/cgeo/geocaching/cgeocaches.java b/src/cgeo/geocaching/cgeocaches.java
index 214969f..40b379f 100644
--- a/src/cgeo/geocaching/cgeocaches.java
+++ b/src/cgeo/geocaching/cgeocaches.java
@@ -16,6 +16,7 @@ import java.util.Locale;
import android.app.AlertDialog;
import android.app.ProgressDialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
@@ -50,6 +51,7 @@ import cgeo.geocaching.filter.cgFilterByType;
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;
@@ -61,6 +63,7 @@ import cgeo.geocaching.sorting.VoteComparator;
public class cgeocaches extends AbstractListActivity {
+ 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;
@@ -120,11 +123,11 @@ public class cgeocaches extends AbstractListActivity {
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 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 Double latitude = null;
@@ -342,7 +345,7 @@ public class cgeocaches extends AbstractListActivity {
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));
@@ -398,9 +401,8 @@ public class cgeocaches extends AbstractListActivity {
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+".");
- //Once a cache is downloaded I used switchList to refresh it.
- switchList(listId, -1);
- } else if (msg.what == -2) {
+ refreshCurrentList();
+ } else if (msg.what == -2) {
if (waitDialog != null) {
waitDialog.dismiss();
waitDialog.setOnCancelListener(null);
@@ -436,31 +438,25 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void handleMessage(Message msg) {
- setAdapter();
-
- if (msg.what > -1) {
- cacheList.get(msg.what).statusChecked = false;
- } else {
- if (adapter != null) {
- adapter.setSelectMode(false, true);
- }
+ if (adapter != null) {
+ adapter.setSelectMode(false, true);
+ }
- switchList(listId, -1);
+ refreshCurrentList();
- cacheList.clear();
+ cacheList.clear();
- final ArrayList<cgCache> cacheListTmp = app.getCaches(searchId);
- if (cacheListTmp != null && cacheListTmp.isEmpty() == false) {
- cacheList.addAll(cacheListTmp);
- cacheListTmp.clear();
+ final ArrayList<cgCache> cacheListTmp = app.getCaches(searchId);
+ if (cacheListTmp != null && cacheListTmp.isEmpty() == false) {
+ cacheList.addAll(cacheListTmp);
+ cacheListTmp.clear();
- Collections.sort((List<cgCache>)cacheList, gcComparator);
- }
+ Collections.sort((List<cgCache>)cacheList, gcComparator);
+ }
- if (waitDialog != null) {
- waitDialog.dismiss();
- waitDialog.setOnCancelListener(null);
- }
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ waitDialog.setOnCancelListener(null);
}
}
};
@@ -545,7 +541,7 @@ public class cgeocaches extends AbstractListActivity {
// get parameters
Bundle extras = getIntent().getExtras();
if (extras != null) {
- type = extras.getString("type");
+ type = extras.getString(EXTRAS_LIST_TYPE);
latitude = extras.getDouble("latitude");
longitude = extras.getDouble("longitude");
cachetype = extras.getString("cachetype");
@@ -754,6 +750,7 @@ public class cgeocaches extends AbstractListActivity {
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);
ArrayList<String> sortedLabels = new ArrayList<String>(comparators.keySet());
Collections.sort(sortedLabels);
@@ -981,7 +978,10 @@ public class cgeocaches extends AbstractListActivity {
return false;
case MENU_SORT_DATE:
setComparator(item, new DateComparator());
- return false;
+ return true;
+ case MENU_SORT_FINDS:
+ setComparator(item, new FindsComparator(app));
+ return true;
case SUBMENU_FILTER_TYPE:
selectedFilter = res.getString(R.string.caches_filter_type);
openContextMenu(getListView());
@@ -1032,7 +1032,7 @@ public class cgeocaches extends AbstractListActivity {
if (adapter == null) {
return;
}
-
+
if (contextMenuMoveToList) {
createFakeContextMenuMoveToList(menu);
return;
@@ -1225,7 +1225,7 @@ public class cgeocaches extends AbstractListActivity {
cgBase.dropCache(app, this, cache, new Handler() {
@Override
public void handleMessage(Message msg) {
- switchList(listId, -1); // refresh
+ refreshCurrentList();
}
});
return true;
@@ -1236,8 +1236,7 @@ public class cgeocaches extends AbstractListActivity {
}
adapter.resetChecks();
- // refresh list by switching to the current list
- switchListById(listId);
+ 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;
@@ -1250,8 +1249,7 @@ public class cgeocaches extends AbstractListActivity {
}
adapter.resetChecks();
- // refresh list by switching to the current list
- switchListById(listId);
+ refreshCurrentList();
return true;
}
@@ -1260,19 +1258,19 @@ public class cgeocaches extends AbstractListActivity {
// https://code.google.com/p/android/issues/detail?id=7139
lastMenuInfo = info;
- // create a searchId for a single cache (as if in details view)
- HashMap<String, String> params = new HashMap<String, String>();
- params.put("geocode", cache.geocode);
- Long singleSearchId = base.searchByGeocode(params, 0, false);
-
- if (NavigationAppFactory.onMenuItemSelected(item, geo, this,
- res, cache, singleSearchId, null, null)) {
- return true;
- }
-
if (cache != null) {
+ // create a searchId for a single cache (as if in details view)
+ HashMap<String, String> params = new HashMap<String, String>();
+ params.put("geocode", cache.geocode);
+ Long 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);
+ cache.logOffline(this, logType, settings, base);
}
return true;
}
@@ -1414,11 +1412,13 @@ public class cgeocaches extends AbstractListActivity {
}
private void importGpx() {
- final Intent intent = new Intent(this, cgeogpxes.class);
- intent.putExtra("list", listId);
- startActivity(intent);
+ cgeogpxes.startSubActivity(this, listId);
+ }
- finish();
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ refreshCurrentList();
}
public void refreshStored() {
@@ -2139,9 +2139,6 @@ public class cgeocaches extends AbstractListActivity {
final ArrayList<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList);
for (cgCache cache : cacheListTemp) {
if (checked > 0 && cache.statusChecked == false) {
- handler.sendEmptyMessage(0);
-
- yield();
continue;
}
@@ -2152,10 +2149,6 @@ public class cgeocaches extends AbstractListActivity {
}
app.markDropped(cache.geocode);
-
- handler.sendEmptyMessage(cacheList.indexOf(cache));
-
- yield();
} catch (Exception e) {
Log.e(cgSettings.tag, "cgeocaches.geocachesDropDetails: " + e.toString());
}
@@ -2382,7 +2375,7 @@ public class cgeocaches extends AbstractListActivity {
builder.setTitle(res.getString(R.string.list_title));
builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int item) {
- switchListByOrder(item);
+ switchListById(lists.get(item).id);
return;
}
@@ -2390,30 +2383,11 @@ public class cgeocaches extends AbstractListActivity {
builder.create().show();
}
- public void switchListByOrder(int order) {
- switchList(-1, order);
- }
-
public void switchListById(int id) {
- switchList(id, -1);
- }
-
- private class MoveHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- Thread threadPure = new geocachesLoadByOffline(loadCachesHandler, latitude, longitude, msg.what);
- threadPure.start();
- }
- }
-
- public void switchList(int id, int order) {
cgList list = null;
if (id >= 0) {
list = app.getList(id);
- } else if (order >= 0) {
- lists = app.getLists();
- list = lists.get(order);
} else {
return;
}
@@ -2433,6 +2407,14 @@ public class cgeocaches extends AbstractListActivity {
(new moveCachesToList(listId, new MoveHandler())).start();
}
+ private class MoveHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ Thread threadPure = new geocachesLoadByOffline(loadCachesHandler, latitude, longitude, msg.what);
+ threadPure.start();
+ }
+ }
+
private class moveCachesToList extends Thread {
int listId = -1;
Handler handler = null;
@@ -2493,21 +2475,33 @@ public class cgeocaches extends AbstractListActivity {
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) {
- 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));
- }
+ removeListInternal();
}
});
alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() {
@@ -2542,4 +2536,14 @@ public class cgeocaches extends AbstractListActivity {
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);
+ }
+} \ No newline at end of file
diff --git a/src/cgeo/geocaching/cgeocoords.java b/src/cgeo/geocaching/cgeocoords.java
index 218a403..229b3a6 100644
--- a/src/cgeo/geocaching/cgeocoords.java
+++ b/src/cgeo/geocaching/cgeocoords.java
@@ -256,15 +256,16 @@ public class cgeocoords extends Dialog {
}
private static String addZeros(int value, int len) {
- String zeros = "";
+ StringBuilder zeros = new StringBuilder();
if (value == 0) {
value = 1;
}
- while (value < Math.pow(10, len-1)) {
- zeros += "0";
+ double wantedLength = Math.pow(10, len-1);
+ while (value < wantedLength) {
+ zeros.append('0');
value *= 10;
}
- return zeros;
+ return zeros.toString();
}
private class buttonClickListener implements View.OnClickListener {
@@ -272,8 +273,11 @@ public class cgeocoords extends Dialog {
@Override
public void onClick(View v) {
Button e = (Button) v;
- char[] c = e.getText().toString().toCharArray();
- switch (c[0]) {
+ CharSequence text = e.getText();
+ if (text == null || text.length() == 0) {
+ return;
+ }
+ switch (text.charAt(0)) {
case 'N':
e.setText("S");
break;
@@ -421,8 +425,8 @@ public class cgeocoords extends Dialog {
longitude = lonDeg + lonMin/60.0 + lonSec/60.0/60.0 + lonSecFrac/60.0/60.0;
break;
}
- latitude *= (bLat.getText().toString() == "S" ? -1 : 1);
- longitude *= (bLon.getText().toString() == "W" ? -1 : 1);
+ latitude *= (bLat.getText().toString().equalsIgnoreCase("S") ? -1 : 1);
+ longitude *= (bLon.getText().toString().equalsIgnoreCase("W") ? -1 : 1);
}
private class CoordinateFormatListener implements OnItemSelectedListener {
diff --git a/src/cgeo/geocaching/cgeodetail.java b/src/cgeo/geocaching/cgeodetail.java
index 7f5e7e5..225e345 100644
--- a/src/cgeo/geocaching/cgeodetail.java
+++ b/src/cgeo/geocaching/cgeodetail.java
@@ -17,6 +17,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
+import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -175,38 +176,43 @@ public class cgeodetail extends AbstractActivity {
@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 (image != null && view != null) {
- view.setImageDrawable(image);
-
- if (scroll.getScrollY() == 0) {
- scroll.scrollTo(0, (int) (80 * pixelRatio));
- }
- view.setVisibility(View.VISIBLE);
- view.setOnClickListener(new View.OnClickListener() {
+ 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
- }
+ @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) {
- if (longDesc == null && cache != null && cache.description != null) {
- longDesc = Html.fromHtml(cache.description.trim(), new cgHtmlImg(cgeodetail.this, geocode, true, cache.reason, false), null);
- }
+ parseLongDescription();
if (longDesc != null) {
((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE);
@@ -542,7 +548,7 @@ public class cgeodetail extends AbstractActivity {
}
int logType = menuItem - MENU_LOG_VISIT_OFFLINE;
- cache.logOffline(this, logType);
+ cache.logOffline(this, logType, settings, base);
return true;
}
@@ -659,11 +665,12 @@ public class cgeodetail extends AbstractActivity {
itemName.setText(res.getString(R.string.cache_type));
- String size = null;
+ String size = "";
if (cache.size != null && cache.size.length() > 0) {
- size = " (" + cache.size + ")";
- } else {
- 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
@@ -947,9 +954,7 @@ public class cgeodetail extends AbstractActivity {
// cache long desc
if (longDescDisplayed) {
- if (longDesc == null && cache != null && cache.description != null) {
- longDesc = Html.fromHtml(cache.description.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), null);
- }
+ parseLongDescription();
if (longDesc != null && longDesc.length() > 0) {
((LinearLayout) findViewById(R.id.desc_box)).setVisibility(View.VISIBLE);
@@ -1098,6 +1103,12 @@ public class cgeodetail extends AbstractActivity {
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);
@@ -1368,8 +1379,7 @@ public class cgeodetail extends AbstractActivity {
if (cache == null || cache.description == null || handler == null) {
return;
}
-
- longDesc = Html.fromHtml(cache.description.trim(), new cgHtmlImg(cgeodetail.this, geocode, true, cache.reason, false), null);
+ parseLongDescription();
handler.sendMessage(new Message());
}
}
@@ -2071,4 +2081,10 @@ public class cgeodetail extends AbstractActivity {
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);
+ }
}
diff --git a/src/cgeo/geocaching/cgeogpxes.java b/src/cgeo/geocaching/cgeogpxes.java
index 64d5bf8..db26a1f 100644
--- a/src/cgeo/geocaching/cgeogpxes.java
+++ b/src/cgeo/geocaching/cgeogpxes.java
@@ -3,21 +3,24 @@ package cgeo.geocaching;
import java.io.File;
import java.util.ArrayList;
-import cgeo.geocaching.files.FileList;
-import cgeo.geocaching.files.GPXParser;
-import cgeo.geocaching.files.LocParser;
-
+import android.app.Activity;
import android.app.ProgressDialog;
+import android.content.Intent;
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;
public class cgeogpxes extends FileList<cgGPXListAdapter> {
+ private static final String EXTRAS_LIST_ID = "list";
+
public cgeogpxes() {
super(new String[] {"gpx"
- // TODO , "loc"
+ // TODO , "loc"
});
}
@@ -70,14 +73,14 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
Bundle extras = getIntent().getExtras();
if (extras != null) {
- listId = extras.getInt("list");
+ listId = extras.getInt(EXTRAS_LIST_ID);
}
if (listId <= 0) {
listId = 1;
}
}
-
+
@Override
protected void setTitle() {
setTitle(res.getString(R.string.gpx_import_title));
@@ -118,4 +121,10 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
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 056f631..85cf422 100644
--- a/src/cgeo/geocaching/cgeohelpers.java
+++ b/src/cgeo/geocaching/cgeohelpers.java
@@ -27,52 +27,37 @@ public class cgeohelpers extends AbstractActivity {
settings.load();
}
- public void installManual(View view) {
- final Locale loc = Locale.getDefault();
- final String lng = loc.getLanguage();
-
+ private void installFromMarket(String marketId) {
try {
- if (lng.equalsIgnoreCase("de")) {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:gnu.android.app.cgeomanual.de")));
- } else {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:gnu.android.app.cgeomanual.en")));
- }
+ 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 installLocus(View view) {
- try {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:menion.android.locus")));
- } catch (Exception e) {
- // market not available in standard emulator
- }
+ 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");
+ }
+ }
- finish();
+ public void installLocus(View view) {
+ installFromMarket("menion.android.locus");
}
public void installGpsStatus(View view) {
- try {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:com.eclipsim.gpsstatus2")));
- } catch (Exception e) {
- // market not available in standard emulator
- }
-
- finish();
+ installFromMarket("com.eclipsim.gpsstatus2");
}
public void installBluetoothGps(View view) {
- try {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:googoo.android.btgps")));
- } catch (Exception e) {
- // market not available in standard emulator
- }
-
- finish();
+ installFromMarket("googoo.android.btgps");
}
}
diff --git a/src/cgeo/geocaching/cgeoinit.java b/src/cgeo/geocaching/cgeoinit.java
index 46ba767..e3111e2 100644
--- a/src/cgeo/geocaching/cgeoinit.java
+++ b/src/cgeo/geocaching/cgeoinit.java
@@ -1024,7 +1024,12 @@ public class cgeoinit extends AbstractActivity {
@Override
public void run() {
- logInHandler.sendEmptyMessage(base.login());
+ final int loginResult = base.login();
+ if (1 == loginResult)
+ {
+ base.detectGcCustomDate();
+ }
+ logInHandler.sendEmptyMessage(loginResult);
}
}).start();
}
diff --git a/src/cgeo/geocaching/cgeopopup.java b/src/cgeo/geocaching/cgeopopup.java
index 5e78531..54be58c 100644
--- a/src/cgeo/geocaching/cgeopopup.java
+++ b/src/cgeo/geocaching/cgeopopup.java
@@ -186,9 +186,9 @@ public class cgeopopup extends AbstractActivity {
if (NavigationAppFactory.onMenuItemSelected(item, geo, this, res, cache, null, null, null)) {
return true;
}
-
+
int logType = menuItem - MENU_LOG_VISIT_OFFLINE;
- cache.logOffline(this, logType);
+ cache.logOffline(this, logType, settings, base);
return true;
}
diff --git a/src/cgeo/geocaching/connector/ConnectorFactory.java b/src/cgeo/geocaching/connector/ConnectorFactory.java
index 9d8f955..d052231 100644
--- a/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -4,7 +4,7 @@ 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()};
+ private static final IConnector[] connectors = new IConnector[] {GC_CONNECTOR, new OCConnector(), new OXConnector()};
public static IConnector[] getConnectors() {
return connectors;
diff --git a/src/cgeo/geocaching/connector/OCConnector.java b/src/cgeo/geocaching/connector/OCConnector.java
index efe4232..d23b3cd 100644
--- a/src/cgeo/geocaching/connector/OCConnector.java
+++ b/src/cgeo/geocaching/connector/OCConnector.java
@@ -2,6 +2,10 @@ package cgeo.geocaching.connector;
import cgeo.geocaching.cgCache;
+/**
+ * connector for OpenCaching.de (and several other country domains)
+ *
+ */
public class OCConnector extends AbstractConnector implements IConnector {
@Override
public boolean canHandle(String geocode) {
diff --git a/src/cgeo/geocaching/connector/OXConnector.java b/src/cgeo/geocaching/connector/OXConnector.java
new file mode 100644
index 0000000..75d404e
--- /dev/null
+++ b/src/cgeo/geocaching/connector/OXConnector.java
@@ -0,0 +1,21 @@
+package cgeo.geocaching.connector;
+
+import cgeo.geocaching.cgCache;
+
+/**
+ * connector for OpenCaching.com
+ *
+ */
+public class OXConnector extends AbstractConnector implements IConnector {
+
+ @Override
+ public boolean canHandle(String geocode) {
+ return geocode != null && geocode.toUpperCase().startsWith("OX");
+ }
+
+ @Override
+ public String getCacheUrl(cgCache cache) {
+ return "http://www.opencaching.com/#!geocache/" + cache.geocode;
+ }
+
+}
diff --git a/src/cgeo/geocaching/files/GPXParser.java b/src/cgeo/geocaching/files/GPXParser.java
index cc864ce..c96e30c 100644
--- a/src/cgeo/geocaching/files/GPXParser.java
+++ b/src/cgeo/geocaching/files/GPXParser.java
@@ -4,7 +4,11 @@ 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.regex.Matcher;
import java.util.regex.Pattern;
@@ -17,7 +21,6 @@ import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
-import android.text.Html;
import android.util.Log;
import android.util.Xml;
import cgeo.geocaching.cgBase;
@@ -31,43 +34,52 @@ import cgeo.geocaching.connector.ConnectorFactory;
public abstract class GPXParser extends FileParser {
- private cgSearch search = null;
- private Handler handler = null;
+ 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 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 cgeoapplication app = null;
private int listId = 1;
+ private cgSearch search = null;
+ protected String namespace = null;
+ private String version;
+ private Handler handler = null;
+
private cgCache cache = new cgCache();
private cgTrackable trackable = new cgTrackable();
private cgLog log = new cgLog();
- private boolean htmlShort = true;
- private boolean htmlLong = true;
+
private String type = null;
private String sym = null;
- protected String namespace = null;
- private ArrayList<String> nsGCList = new ArrayList<String>();
- private static final Pattern patternGeocode = Pattern.compile("([A-Z]{2}[0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
private String name = null;
private String cmt = null;
private String desc = null;
- private String version;
public GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) {
app = appIn;
listId = listIdIn;
search = searchIn;
-
- nsGCList.add("http://www.groundspeak.com/cache/1/1"); // PQ 1.1
- nsGCList.add("http://www.groundspeak.com/cache/1/0/1"); // PQ 1.0.1
- nsGCList.add("http://www.groundspeak.com/cache/1/0"); // PQ 1.0
-
namespace = namespaceIn;
version = versionIn;
}
- public long parse(File file, Handler handlerIn) {
- handler = handlerIn;
- if (file == null) {
- return 0l;
+ private static Date parseDate(String input) throws ParseException {
+ input = input.trim();
+ if (input.length() >= 3 && input.charAt(input.length() - 3) == ':') {
+ String removeColon = input.substring(0, input.length() - 3) + input.substring(input.length() - 2);
+ return formatTimezone.parse(removeColon);
}
+ return formatSimple.parse(input);
+ }
+
+ public long parse(final InputStream stream, Handler handlerIn) {
+ handler = handlerIn;
final RootElement root = new RootElement(namespace, "gpx");
final Element waypoint = root.getChild(namespace, "wpt");
@@ -75,6 +87,7 @@ public abstract class GPXParser extends FileParser {
// waypoint - attributes
waypoint.setStartElementListener(new StartElementListener() {
+ @Override
public void start(Attributes attrs) {
try {
if (attrs.getIndex("lat") > -1) {
@@ -92,6 +105,7 @@ public abstract class GPXParser extends FileParser {
// waypoint
waypoint.setEndElementListener(new EndElementListener() {
+ @Override
public void end() {
if (cache.geocode == null || cache.geocode.length() == 0) {
// try to find geocode somewhere else
@@ -114,8 +128,6 @@ public abstract class GPXParser extends FileParser {
showFinishedMessage(handler, search);
- htmlShort = true;
- htmlLong = true;
type = null;
sym = null;
name = null;
@@ -130,9 +142,10 @@ public abstract class GPXParser extends FileParser {
// waypoint.time
waypoint.getChild(namespace, "time").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
try {
- cache.hidden = cgBase.dateGPXIn.parse(body.trim());
+ cache.hidden = parseDate(body);
} catch (Exception e) {
Log.w(cgSettings.tag, "Failed to parse cache date: " + e.toString());
}
@@ -142,10 +155,11 @@ public abstract class GPXParser extends FileParser {
// waypoint.name
waypoint.getChild(namespace, "name").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
name = body;
- final String content = Html.fromHtml(body).toString().trim();
+ final String content = body.trim();
cache.name = content;
findGeoCode(cache.name);
@@ -156,28 +170,29 @@ public abstract class GPXParser extends FileParser {
// waypoint.desc
waypoint.getChild(namespace, "desc").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
desc = body;
- final String content = Html.fromHtml(body).toString().trim();
- cache.shortdesc = content;
+ cache.shortdesc = validate(body);
}
});
// waypoint.cmt
waypoint.getChild(namespace, "cmt").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
cmt = body;
- final String content = Html.fromHtml(body).toString().trim();
- cache.description = content;
+ 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) {
@@ -189,6 +204,7 @@ public abstract class GPXParser extends FileParser {
// waypoint.sym
waypoint.getChild(namespace, "sym").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
body = body.toLowerCase();
sym = body;
@@ -208,6 +224,7 @@ public abstract class GPXParser extends FileParser {
gcCache.setStartElementListener(new StartElementListener() {
+ @Override
public void start(Attributes attrs) {
try {
if (attrs.getIndex("id") > -1) {
@@ -228,42 +245,43 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.name
gcCache.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- final String content = Html.fromHtml(body).toString().trim();
- cache.name = validate(content);
+ @Override
+ public void end(String cacheName) {
+ cache.name = validate(cacheName);
}
});
// waypoint.cache.owner
gcCache.getChild(nsGC, "owner").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- final String content = Html.fromHtml(body).toString().trim();
- cache.owner = validate(content);
+ @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) {
- String parsedString = validate(body.toLowerCase());
- setType(parsedString);
+ setType(validate(body.toLowerCase()));
}
});
// waypoint.cache.container
gcCache.getChild(nsGC, "container").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
- final String content = body.toLowerCase();
- cache.size = validate(content);
+ cache.size = validate(body.toLowerCase());
}
});
// waypoint.cache.difficulty
gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
try {
cache.difficulty = new Float(body);
@@ -276,6 +294,7 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.terrain
gcCache.getChild(nsGC, "terrain").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
try {
cache.terrain = new Float(body);
@@ -288,11 +307,12 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.country
gcCache.getChild(nsGC, "country").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
+ @Override
+ public void end(String country) {
if (cache.location == null || cache.location.length() == 0) {
- cache.location = validate(body.trim());
+ cache.location = validate(country);
} else {
- cache.location = cache.location + ", " + body.trim();
+ cache.location = cache.location + ", " + country.trim();
}
}
});
@@ -300,11 +320,12 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.state
gcCache.getChild(nsGC, "state").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
+ @Override
+ public void end(String state) {
if (cache.location == null || cache.location.length() == 0) {
- cache.location = validate(body.trim());
+ cache.location = validate(state);
} else {
- cache.location = body.trim() + ", " + cache.location;
+ cache.location = state.trim() + ", " + cache.location;
}
}
});
@@ -312,63 +333,25 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.encoded_hints
gcCache.getChild(nsGC, "encoded_hints").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- cache.hint = validate(body.trim());
- }
- });
-
- // waypoint.cache.short_description
- gcCache.getChild(nsGC, "short_description").setStartElementListener(new StartElementListener() {
-
- public void start(Attributes attrs) {
- try {
- if (attrs.getIndex("html") > -1) {
- final String at = attrs.getValue("html");
- if (at.equalsIgnoreCase("false")) {
- htmlShort = false;
- }
- }
- } catch (Exception e) {
- // nothing
- }
+ @Override
+ public void end(String encoded) {
+ cache.hint = validate(encoded);
}
});
gcCache.getChild(nsGC, "short_description").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- if (!htmlShort) {
- cache.shortdesc = Html.fromHtml(body).toString();
- } else {
- cache.shortdesc = body;
- }
- }
- });
-
- // waypoint.cache.long_description
- gcCache.getChild(nsGC, "long_description").setStartElementListener(new StartElementListener() {
-
- public void start(Attributes attrs) {
- try {
- if (attrs.getIndex("html") > -1) {
- if (attrs.getValue("html").equalsIgnoreCase("false")) {
- htmlLong = false;
- }
- }
- } catch (Exception e) {
- // nothing
- }
+ @Override
+ public void end(String shortDesc) {
+ cache.shortdesc = validate(shortDesc);
}
});
gcCache.getChild(nsGC, "long_description").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- if (htmlLong == false) {
- cache.description = Html.fromHtml(body).toString().trim();
- } else {
- cache.description = body;
- }
+ @Override
+ public void end(String desc) {
+ cache.description = validate(desc);
}
});
@@ -378,6 +361,7 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.travelbugs.travelbug
gcTBs.getChild(nsGC, "travelbug").setStartElementListener(new StartElementListener() {
+ @Override
public void start(Attributes attrs) {
trackable = new cgTrackable();
@@ -396,10 +380,12 @@ public abstract class GPXParser extends FileParser {
gcTB.setEndElementListener(new EndElementListener() {
+ @Override
public void end() {
if (trackable.geocode != null && trackable.geocode.length() > 0 && trackable.name != null && trackable.name.length() > 0) {
- if (cache.inventory == null)
+ if (cache.inventory == null) {
cache.inventory = new ArrayList<cgTrackable>();
+ }
cache.inventory.add(trackable);
}
}
@@ -408,9 +394,9 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.travelbugs.travelbug.name
gcTB.getChild(nsGC, "name").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- String content = Html.fromHtml(body).toString();
- trackable.name = content;
+ @Override
+ public void end(String tbName) {
+ trackable.name = validate(tbName);
}
});
@@ -422,6 +408,7 @@ public abstract class GPXParser extends FileParser {
gcLog.setStartElementListener(new StartElementListener() {
+ @Override
public void start(Attributes attrs) {
log = new cgLog();
@@ -437,10 +424,12 @@ public abstract class GPXParser extends FileParser {
gcLog.setEndElementListener(new EndElementListener() {
+ @Override
public void end() {
if (log.log != null && log.log.length() > 0) {
- if (cache.logs == null)
+ if (cache.logs == null) {
cache.logs = new ArrayList<cgLog>();
+ }
cache.logs.add(log);
}
}
@@ -449,9 +438,10 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.logs.log.date
gcLog.getChild(nsGC, "date").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
try {
- log.date = cgBase.dateGPXIn.parse(body.trim()).getTime();
+ log.date = parseDate(body).getTime();
} catch (Exception e) {
Log.w(cgSettings.tag, "Failed to parse log date: " + e.toString());
}
@@ -461,12 +451,13 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.logs.log.type
gcLog.getChild(nsGC, "type").setEndTextElementListener(new EndTextElementListener() {
+ @Override
public void end(String body) {
- final String content = body.trim().toLowerCase();
- if (cgBase.logTypes0.containsKey(content)) {
- log.type = cgBase.logTypes0.get(content);
+ final String logType = validate(body).toLowerCase();
+ if (cgBase.logTypes0.containsKey(logType)) {
+ log.type = cgBase.logTypes0.get(logType);
} else {
- log.type = 4;
+ log.type = cgBase.LOG_NOTE;
}
}
});
@@ -474,42 +465,54 @@ public abstract class GPXParser extends FileParser {
// waypoint.cache.logs.log.finder
gcLog.getChild(nsGC, "finder").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- String content = Html.fromHtml(body).toString();
- log.author = content;
+ @Override
+ public void end(String finderName) {
+ log.author = validate(finderName);
}
});
- // waypoint.cache.logs.log.finder
+ // waypoint.cache.logs.log.text
gcLog.getChild(nsGC, "text").setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- String content = Html.fromHtml(body).toString();
- log.log = content;
+ @Override
+ public void end(String logText) {
+ log.log = validate(logText);
}
});
}
- FileInputStream fis = null;
boolean parsed = false;
try {
- fis = new FileInputStream(file);
- } catch (FileNotFoundException e) {
- Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": file not found!");
- }
- try {
- Xml.parse(fis, Xml.Encoding.UTF_8, root.getContentHandler());
+ Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler());
parsed = true;
} catch (IOException e) {
- Log.e(cgSettings.tag, "Cannot parse .gpx file " + file.getAbsolutePath() + " as GPX " + version + ": could not read file!");
+ 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 " + file.getAbsolutePath() + " as GPX " + version + ": could not parse XML - " + e.toString());
+ Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString());
+ }
+ return parsed ? search.getCurrentId() : 0l;
+ }
+
+ private long parse(final File file, final Handler handlerIn) {
+ if (file == null) {
+ return 0l;
+ }
+
+ FileInputStream fis = null;
+ long result = 0l;
+ 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 {
- fis.close();
+ 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 parsed ? search.getCurrentId() : 0l;
+ return result;
}
protected abstract Element getCacheParent(Element waypoint);
@@ -518,7 +521,7 @@ public abstract class GPXParser extends FileParser {
if ("nil".equalsIgnoreCase(input)) {
return "";
}
- return input;
+ return input.trim();
}
private void setType(String parsedString) {
diff --git a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
index 68929cf..02e8c04 100644
--- a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
@@ -1,10 +1,12 @@
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;
@@ -22,6 +24,7 @@ import com.google.android.maps.MapView;
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));
@@ -98,4 +101,14 @@ public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem>
// Nothing to do here...
}
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
}
diff --git a/src/cgeo/geocaching/googlemaps/googleMapFactory.java b/src/cgeo/geocaching/googlemaps/googleMapFactory.java
index 28bfca5..ba62737 100644
--- a/src/cgeo/geocaching/googlemaps/googleMapFactory.java
+++ b/src/cgeo/geocaching/googlemaps/googleMapFactory.java
@@ -7,8 +7,6 @@ import cgeo.geocaching.cgUser;
import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl;
import cgeo.geocaching.mapinterfaces.GeoPointImpl;
import cgeo.geocaching.mapinterfaces.MapFactory;
-import cgeo.geocaching.mapinterfaces.OverlayBase;
-import cgeo.geocaching.mapinterfaces.OverlayImpl;
import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl;
import com.google.android.maps.MapActivity;
@@ -36,12 +34,6 @@ public class googleMapFactory implements MapFactory{
}
@Override
- public OverlayImpl getOverlayBaseWrapper(OverlayBase ovlIn) {
- googleOverlay baseOvl = new googleOverlay(ovlIn);
- return baseOvl;
- }
-
- @Override
public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) {
googleCacheOverlayItem baseItem = new googleCacheOverlayItem(coordinate, type);
return baseItem;
diff --git a/src/cgeo/geocaching/googlemaps/googleMapView.java b/src/cgeo/geocaching/googlemaps/googleMapView.java
index 737e64e..6fa1eb7 100644
--- a/src/cgeo/geocaching/googlemaps/googleMapView.java
+++ b/src/cgeo/geocaching/googlemaps/googleMapView.java
@@ -1,18 +1,23 @@
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 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.OverlayBase;
import cgeo.geocaching.mapinterfaces.OverlayImpl;
+import cgeo.geocaching.mapinterfaces.OverlayImpl.overlayType;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
@@ -97,6 +102,24 @@ public class googleMapView extends MapView implements MapViewImpl{
}
@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();
}
@@ -105,14 +128,12 @@ public class googleMapView extends MapView implements MapViewImpl{
public void setMapSource(cgSettings settings) {
switch(settings.mapSource) {
- case googleSat:
- setSatellite(true);
- break;
- default:
- setSatellite(false);
- }
-
-
+ case googleSat:
+ setSatellite(true);
+ break;
+ default:
+ setSatellite(false);
+ }
}
@Override
@@ -124,4 +145,9 @@ public class googleMapView extends MapView implements MapViewImpl{
public void setBuiltinScale(boolean b) {
//Nothing to do for google maps...
}
+
+ @Override
+ public void repaintRequired(OverlayBase overlay) {
+ invalidate();
+ }
}
diff --git a/src/cgeo/geocaching/googlemaps/googleOverlay.java b/src/cgeo/geocaching/googlemaps/googleOverlay.java
index 3847d9f..8473faa 100644
--- a/src/cgeo/geocaching/googlemaps/googleOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleOverlay.java
@@ -1,6 +1,13 @@
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;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
import cgeo.geocaching.mapinterfaces.OverlayBase;
import cgeo.geocaching.mapinterfaces.OverlayImpl;
@@ -10,17 +17,39 @@ import com.google.android.maps.Overlay;
public class googleOverlay extends Overlay implements OverlayImpl {
- private OverlayBase overlayBase;
+ private OverlayBase overlayBase = null;
+ private Lock lock = new ReentrantLock();
- public googleOverlay(OverlayBase overlayBaseIn) {
- overlayBase = overlayBaseIn;
+ 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);
- overlayBase.draw(canvas, (MapViewImpl) 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 5019e6e..f5f16a7 100644
--- a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java
@@ -1,5 +1,8 @@
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;
@@ -15,6 +18,7 @@ import com.google.android.maps.MapView;
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));
@@ -91,4 +95,14 @@ public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem>
// Nothing to do here
}
-} \ No newline at end of file
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
+}
diff --git a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
index 41739e2..4e0379c 100644
--- a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
+++ b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
@@ -6,6 +6,8 @@ import android.graphics.drawable.Drawable;
import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl;
import cgeo.geocaching.mapinterfaces.MapProjectionImpl;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
+import cgeo.geocaching.mapinterfaces.OverlayBase;
+import cgeo.geocaching.mapinterfaces.OverlayImpl;
import cgeo.geocaching.mapinterfaces.OverlayItemImpl;
/**
@@ -14,7 +16,7 @@ import cgeo.geocaching.mapinterfaces.OverlayItemImpl;
* @author rsudev
*
*/
-public abstract class ItemizedOverlayBase {
+public abstract class ItemizedOverlayBase implements OverlayBase {
private ItemizedOverlayImpl ovlImpl;
@@ -50,6 +52,11 @@ public abstract class ItemizedOverlayBase {
MapProjectionImpl projection, byte drawZoomLevel) {
ovlImpl.superDrawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel);
}
+
+ @Override
+ public OverlayImpl getOverlayImpl() {
+ return ovlImpl;
+ }
public abstract OverlayItemImpl createItem(int index);
diff --git a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
index cbf065c..b8c8723 100644
--- a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
+++ b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
@@ -6,10 +6,11 @@ import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
-import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
+import android.graphics.Paint.Style;
import android.location.Location;
import cgeo.geocaching.R;
import cgeo.geocaching.cgBase;
@@ -19,6 +20,7 @@ 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;
public class cgMapMyOverlay implements OverlayBase {
private cgSettings settings = null;
@@ -31,8 +33,8 @@ public class cgMapMyOverlay implements OverlayBase {
private Point center = new Point();
private Point left = new Point();
private Bitmap arrow = null;
- private int widthArrow = 0;
- private int heightArrow = 0;
+ private int widthArrowHalf = 0;
+ private int heightArrowHalf = 0;
private PaintFlagsDrawFilter setfil = null;
private PaintFlagsDrawFilter remfil = null;
private Location historyRecent = null;
@@ -41,11 +43,13 @@ public class cgMapMyOverlay implements OverlayBase {
private Point historyPointP = new Point();
private Activity activity;
private MapFactory mapFactory = null;
+ private OverlayImpl ovlImpl = null;
- public cgMapMyOverlay(cgSettings settingsIn, Activity activity) {
+ 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) {
@@ -184,22 +188,29 @@ public class cgMapMyOverlay implements OverlayBase {
if (arrow == null) {
arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron);
- widthArrow = arrow.getWidth();
- heightArrow = arrow.getHeight();
+ widthArrowHalf = arrow.getWidth() / 2;
+ heightArrowHalf = arrow.getHeight() / 2;
}
int marginLeft;
int marginTop;
- marginLeft = center.x - (widthArrow / 2);
- marginTop = center.y - (heightArrow / 2);
+ marginLeft = center.x - widthArrowHalf;
+ marginTop = center.y - heightArrowHalf;
+
+ Matrix matrix = new Matrix();
+ matrix.setRotate(heading.floatValue(), widthArrowHalf, heightArrowHalf);
+ matrix.postTranslate(marginLeft, marginTop);
- canvas.rotate(heading.floatValue(), center.x, center.y);
- canvas.drawBitmap(arrow, marginLeft, marginTop, null);
- canvas.rotate(-(heading.floatValue()), center.x, center.y);
+ 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 80eba5a..d3f7c00 100644
--- a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
+++ b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
@@ -10,9 +10,9 @@ import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
-import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
+import android.graphics.Paint.Style;
import android.location.Location;
import android.text.Html;
import android.util.Log;
@@ -74,10 +74,16 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
item.setMarker(boundCenterBottom(item.getMarker(0)));
}
- items = new ArrayList<CacheOverlayItemImpl>(itemsPre);
-
- setLastFocusedItemIndex(-1); // to reset tap during data change
- populate();
+ // 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() {
@@ -107,51 +113,56 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
private void drawInternal(Canvas canvas, MapProjectionImpl projection) {
- 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.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
- final float longitudeLineDistance = result[0];
-
- GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
- GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
-
- 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);
+ // 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.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
+ final float longitudeLineDistance = result[0];
+
+ GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
+ GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
+
+ 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);
}
-
- canvas.setDrawFilter(remfil);
+ } finally {
+ getOverlayImpl().unlock();
}
}
@@ -170,7 +181,22 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
}
waitDialog.show();
- CacheOverlayItemImpl item = items.get(index);
+ 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 (coordinate.type != null && coordinate.type.equalsIgnoreCase("cache") && coordinate.geocode != null && coordinate.geocode.length() > 0) {
diff --git a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
index 4aae3d5..b8d6f09 100644
--- a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
+++ b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
@@ -14,6 +14,7 @@ import cgeo.geocaching.mapinterfaces.GeoPointImpl;
import cgeo.geocaching.mapinterfaces.MapProjectionImpl;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
import cgeo.geocaching.mapinterfaces.OverlayBase;
+import cgeo.geocaching.mapinterfaces.OverlayImpl;
public class cgOverlayScale implements OverlayBase {
private cgSettings settings = null;
@@ -26,9 +27,11 @@ public class cgOverlayScale implements OverlayBase {
private double distance = 0d;
private double distanceRound = 0d;
private String units = null;
+ private OverlayImpl ovlImpl=null;
- public cgOverlayScale(Activity activity, cgSettings settingsIn) {
+ public cgOverlayScale(Activity activity, cgSettings settingsIn, OverlayImpl overlayImpl) {
settings = settingsIn;
+ this.ovlImpl = overlayImpl;
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
@@ -38,8 +41,8 @@ public class cgOverlayScale implements OverlayBase {
@Override
public void drawOverlayBitmap(Canvas canvas, Point drawPosition,
MapProjectionImpl projection, byte drawZoomLevel) {
- // TODO Auto-generated method stub
-
+ // Scale overlay is only necessary for google maps, so the mapsforge
+ // related draw method needs not to be filled.
}
@Override
@@ -138,4 +141,9 @@ public class cgOverlayScale implements OverlayBase {
canvas.drawLine(10, bottom, (int)(pixels + 10), bottom, scale);
canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float)(pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale);
}
-} \ No newline at end of file
+
+ @Override
+ public OverlayImpl getOverlayImpl() {
+ return ovlImpl;
+ }
+}
diff --git a/src/cgeo/geocaching/mapcommon/cgeomap.java b/src/cgeo/geocaching/mapcommon/cgeomap.java
index 474b881..8500e1c 100644
--- a/src/cgeo/geocaching/mapcommon/cgeomap.java
+++ b/src/cgeo/geocaching/mapcommon/cgeomap.java
@@ -28,13 +28,13 @@ 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.cgSettings.mapSourceEnum;
import cgeo.geocaching.mapinterfaces.ActivityImpl;
import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl;
import cgeo.geocaching.mapinterfaces.GeoPointImpl;
@@ -269,8 +269,7 @@ public class cgeomap extends MapBase {
mapView.clearOverlays();
if (overlayMyLoc == null) {
- overlayMyLoc = new cgMapMyOverlay(settings, activity);
- mapView.addOverlay(mapFactory.getOverlayBaseWrapper(overlayMyLoc));
+ overlayMyLoc = mapView.createAddPositionOverlay(activity, settings);
}
if (settings.publicLoc > 0 && overlayUsers == null) {
@@ -282,8 +281,7 @@ public class cgeomap extends MapBase {
}
if (overlayScale == null && mapView.needsScaleOverlay()) {
- overlayScale = new cgOverlayScale(activity, settings);
- mapView.addOverlay(mapFactory.getOverlayBaseWrapper(overlayScale));
+ overlayScale = mapView.createAddScaleOverlay(activity, settings);
}
mapView.invalidate();
@@ -747,9 +745,10 @@ public class cgeomap extends MapBase {
}
try {
+ boolean repaintRequired = false;
+
if (overlayMyLoc == null && mapView != null) {
- overlayMyLoc = new cgMapMyOverlay(settings, activity);
- mapView.addOverlay(settings.getMapFactory().getOverlayBaseWrapper(overlayMyLoc));
+ overlayMyLoc = mapView.createAddPositionOverlay(activity, settings);
}
if (overlayMyLoc != null && geo.location != null) {
@@ -760,8 +759,7 @@ public class cgeomap extends MapBase {
if (followMyLocation) {
myLocationInMiddle();
} else {
- // move blue arrow
- mapView.invalidate();
+ repaintRequired = true;
}
}
@@ -771,7 +769,13 @@ public class cgeomap extends MapBase {
} else {
overlayMyLoc.setHeading(Double.valueOf(0));
}
+ repaintRequired = true;
+ }
+
+ if (repaintRequired) {
+ mapView.repaintRequired(overlayMyLoc);
}
+
} catch (Exception e) {
Log.w(cgSettings.tag, "Failed to update location.");
}
diff --git a/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java
index 73eed1f..08e28ad 100644
--- a/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java
+++ b/src/cgeo/geocaching/mapinterfaces/ItemizedOverlayImpl.java
@@ -1,9 +1,9 @@
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
@@ -11,7 +11,7 @@ import android.graphics.drawable.Drawable;
* @author rsudev
*
*/
-public interface ItemizedOverlayImpl {
+public interface ItemizedOverlayImpl extends OverlayImpl {
ItemizedOverlayBase getBase();
diff --git a/src/cgeo/geocaching/mapinterfaces/MapFactory.java b/src/cgeo/geocaching/mapinterfaces/MapFactory.java
index 620f673..4348c40 100644
--- a/src/cgeo/geocaching/mapinterfaces/MapFactory.java
+++ b/src/cgeo/geocaching/mapinterfaces/MapFactory.java
@@ -21,8 +21,6 @@ public interface MapFactory {
public GeoPointImpl getGeoPointBase(int latE6, int lonE6);
- public OverlayImpl getOverlayBaseWrapper(OverlayBase ovlIn);
-
CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type);
public UserOverlayItemImpl getUserOverlayItemBase(Context context,
diff --git a/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java b/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java
index 5c955ed..8e99b3d 100644
--- a/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java
+++ b/src/cgeo/geocaching/mapinterfaces/MapViewImpl.java
@@ -1,10 +1,13 @@
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.content.Context;
-import android.graphics.drawable.Drawable;
/**
* Defines common functions of the provider-specific
@@ -50,6 +53,10 @@ public interface MapViewImpl {
Drawable drawable, boolean fromDetailIntent);
cgUsersOverlay createAddUsersOverlay(Context context, Drawable markerIn);
+
+ cgOverlayScale createAddScaleOverlay(Activity activity, cgSettings settingsIn);
+
+ cgMapMyOverlay createAddPositionOverlay(Activity activity, cgSettings settingsIn);
boolean needsScaleOverlay();
@@ -57,4 +64,6 @@ public interface MapViewImpl {
void setMapSource(cgSettings settings);
+ void repaintRequired(OverlayBase overlay);
+
}
diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayBase.java b/src/cgeo/geocaching/mapinterfaces/OverlayBase.java
index 59afb49..17a4d85 100644
--- a/src/cgeo/geocaching/mapinterfaces/OverlayBase.java
+++ b/src/cgeo/geocaching/mapinterfaces/OverlayBase.java
@@ -16,4 +16,5 @@ public interface OverlayBase {
void drawOverlayBitmap(Canvas canvas, Point drawPosition,
MapProjectionImpl projection, byte drawZoomLevel);
+ OverlayImpl getOverlayImpl();
}
diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
index 6680b6a..ba45532 100644
--- a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
+++ b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
@@ -8,4 +8,13 @@ package cgeo.geocaching.mapinterfaces;
*/
public interface OverlayImpl {
+ public enum overlayType {
+ PositionOverlay,
+ ScaleOverlay
+ }
+
+ void lock();
+
+ void unlock();
+
}
diff --git a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
index 6333133..1e3b287 100644
--- a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.ItemizedOverlay;
import org.mapsforge.android.maps.Projection;
@@ -17,6 +20,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl;
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));
@@ -94,5 +98,15 @@ public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implemen
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/mfMapController.java b/src/cgeo/geocaching/mapsforge/mfMapController.java
index 45efef2..932e640 100644
--- a/src/cgeo/geocaching/mapsforge/mfMapController.java
+++ b/src/cgeo/geocaching/mapsforge/mfMapController.java
@@ -9,9 +9,11 @@ import cgeo.geocaching.mapinterfaces.MapControllerImpl;
public class mfMapController implements MapControllerImpl {
private MapController mapController;
+ private int maxZoomLevel;
- public mfMapController(MapController mapControllerIn) {
+ public mfMapController(MapController mapControllerIn, int maxZoomLevelIn) {
mapController = mapControllerIn;
+ maxZoomLevel = maxZoomLevelIn;
}
@Override
@@ -26,7 +28,11 @@ public class mfMapController implements MapControllerImpl {
@Override
public void setZoom(int mapzoom) {
- mapController.setZoom(mapzoom-1);
+ int mfzoom = mapzoom-1;
+ if (mfzoom > maxZoomLevel) {
+ mfzoom = maxZoomLevel;
+ }
+ mapController.setZoom(mfzoom);
}
@Override
diff --git a/src/cgeo/geocaching/mapsforge/mfMapFactory.java b/src/cgeo/geocaching/mapsforge/mfMapFactory.java
index fa665ec..00204dd 100644
--- a/src/cgeo/geocaching/mapsforge/mfMapFactory.java
+++ b/src/cgeo/geocaching/mapsforge/mfMapFactory.java
@@ -8,8 +8,6 @@ import cgeo.geocaching.cgUser;
import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl;
import cgeo.geocaching.mapinterfaces.GeoPointImpl;
import cgeo.geocaching.mapinterfaces.MapFactory;
-import cgeo.geocaching.mapinterfaces.OverlayBase;
-import cgeo.geocaching.mapinterfaces.OverlayImpl;
import cgeo.geocaching.mapinterfaces.UserOverlayItemImpl;
public class mfMapFactory implements MapFactory{
@@ -35,12 +33,6 @@ public class mfMapFactory implements MapFactory{
}
@Override
- public OverlayImpl getOverlayBaseWrapper(OverlayBase ovlIn) {
- mfOverlay baseOvl = new mfOverlay(ovlIn);
- return baseOvl;
- }
-
- @Override
public CacheOverlayItemImpl getCacheOverlayItem(cgCoord coordinate, String type) {
mfCacheOverlayItem baseItem = new mfCacheOverlayItem(coordinate, type);
return baseItem;
diff --git a/src/cgeo/geocaching/mapsforge/mfMapView.java b/src/cgeo/geocaching/mapsforge/mfMapView.java
index de4bd1a..1e83f33 100644
--- a/src/cgeo/geocaching/mapsforge/mfMapView.java
+++ b/src/cgeo/geocaching/mapsforge/mfMapView.java
@@ -7,19 +7,24 @@ import org.mapsforge.android.maps.MapViewMode;
import org.mapsforge.android.maps.Overlay;
import org.mapsforge.android.maps.Projection;
+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 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.OverlayBase;
import cgeo.geocaching.mapinterfaces.OverlayImpl;
+import cgeo.geocaching.mapinterfaces.OverlayImpl.overlayType;
public class mfMapView extends MapView implements MapViewImpl {
@@ -47,7 +52,7 @@ public class mfMapView extends MapView implements MapViewImpl {
@Override
public MapControllerImpl getMapController() {
- return new mfMapController(getController());
+ return new mfMapController(getController(), getMaxZoomLevel());
}
@Override
@@ -88,6 +93,22 @@ public class mfMapView extends MapView implements MapViewImpl {
}
@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;
@@ -160,10 +181,28 @@ public class mfMapView extends MapView implements MapViewImpl {
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());
+ }
+ }
+
}
diff --git a/src/cgeo/geocaching/mapsforge/mfOverlay.java b/src/cgeo/geocaching/mapsforge/mfOverlay.java
index e015307..f764c6b 100644
--- a/src/cgeo/geocaching/mapsforge/mfOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfOverlay.java
@@ -1,26 +1,56 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.Overlay;
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;
public class mfOverlay extends Overlay implements OverlayImpl {
- private OverlayBase overlayBase;
+ private OverlayBase overlayBase = null;
+ private Lock lock = new ReentrantLock();
- public mfOverlay(OverlayBase overlayBaseIn) {
- overlayBase = overlayBaseIn;
+ 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) {
- overlayBase.drawOverlayBitmap(canvas, drawPosition, new mfMapProjection(projection), 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 8f3ba04..6e2819c 100644
--- a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.ItemizedOverlay;
import org.mapsforge.android.maps.Projection;
@@ -15,6 +18,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl;
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));
@@ -94,4 +98,14 @@ public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implemen
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/sorting/FindsComparator.java b/src/cgeo/geocaching/sorting/FindsComparator.java
new file mode 100644
index 0000000..8553f4b
--- /dev/null
+++ b/src/cgeo/geocaching/sorting/FindsComparator.java
@@ -0,0 +1,40 @@
+package cgeo.geocaching.sorting;
+
+import cgeo.geocaching.cgBase;
+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;
+ }
+
+}