diff options
33 files changed, 530 insertions, 249 deletions
diff --git a/project/attributes/Noun Project - Creative Commons Attribution.pdf b/project/attributes/Noun Project - Creative Commons Attribution.pdf Binary files differnew file mode 100644 index 0000000..14f0c29 --- /dev/null +++ b/project/attributes/Noun Project - Creative Commons Attribution.pdf diff --git a/project/attributes/iconlist.txt b/project/attributes/iconlist.txt index fbfcdc1..69c9e75 100644 --- a/project/attributes/iconlist.txt +++ b/project/attributes/iconlist.txt @@ -2,98 +2,97 @@ # - internal name: used as # a) name of string, prefixed with "attribute_" # b) name of icon, prefixed with "attribute_" -# - yn: y = normal icon will be generated -# n = striked thru icon will be generated +# - gsx: id used in groundspeak GPX files # - man: graphic is selfmade or overhauled # - license: type of license # - copyright holder: Name of person # - URL: icon is based on graphic downloadable here # -# internal name | yn | man | license | copyright holder | URL +# internal name | gsx | man | license | copyright holder | URL # # Permissions (allowed / not allowed) # -dogs | yn | | CC | | http://thenounproject.com/noun/dog/#icon-No364 -bicycles | yn | x | PD | | http://thenounproject.com/noun/bicycle/#icon-No536 -motorcycles | yn | | PD | | http://thenounproject.com/noun/motorcycle/#icon-No53 -quads | yn | | PD | USA National Park Service | http://thenounproject.com/noun/4-wheeler/#icon-No228 -jeeps | yn | | PD | USA National Park Service | http://thenounproject.com/noun/jeep/#icon-No57 -snowmobiles | yn | | PD | USA National Park Service | http://thenounproject.com/noun/snowmobile/#icon-No505 -horses | yn | | PD | USA National Park Service | http://thenounproject.com/noun/horseback-trail/#icon-No329 -campfires | yn | | PD | USA National Park Service | http://thenounproject.com/noun/campfire/#icon-No196 -rv | yn | | PD | USA National Park Service | http://thenounproject.com/noun/camper/#icon-No86 +dogs | 1 | | CC | | http://thenounproject.com/noun/dog/#icon-No364 +bicycles | 32 | x | PD | | http://thenounproject.com/noun/bicycle/#icon-No536 +motorcycles | 33 | | PD | | http://thenounproject.com/noun/motorcycle/#icon-No53 +quads | 34 | | PD | USA National Park Service | http://thenounproject.com/noun/4-wheeler/#icon-No228 +jeeps | 35 | | PD | USA National Park Service | http://thenounproject.com/noun/jeep/#icon-No57 +snowmobiles | 36 | | PD | USA National Park Service | http://thenounproject.com/noun/snowmobile/#icon-No505 +horses | 37 | | PD | USA National Park Service | http://thenounproject.com/noun/horseback-trail/#icon-No329 +campfires | 38 | | PD | USA National Park Service | http://thenounproject.com/noun/campfire/#icon-No196 +rv | 46 | | PD | USA National Park Service | http://thenounproject.com/noun/camper/#icon-No86 # # Conditions (yes / no) # -kids | yn | x | PD | Jack Biesek, Gladys Brenner, Margaret Faye, Healther Merrifield, Kate Keating, Wendy Olmstead, Todd Pierce, Jamie Cowgill, Jim Bolek | http://thenounproject.com/noun/teddy-bear/#icon-No610 -onehour | yn | x | CC | The Noun Project | http://thenounproject.com/noun/stopwatch/#icon-No282 -scenic | yn | | PD | USA National Park Service | http://thenounproject.com/noun/binoculars/#icon-No112 -hiking | yn | | PD | USA National Park Service | http://thenounproject.com/noun/hiker/#icon-No562 -climbing | yn | | PD | USA National Park Service | http://thenounproject.com/noun/climbing/#icon-No526 -wading | y | x | PD | USA National Park Service | http://thenounproject.com/noun/wading/#icon-No581 -swimming | y | | PD | USA National Park Service | http://thenounproject.com/noun/swimming/#icon-No226 -available | yn | x | PD | koem | -night | yn | | PD | | http://thenounproject.com/noun/moon/#icon-No128 -winter | yn | | PD | USA National Park Service | http://thenounproject.com/noun/snow/#icon-No64 -stealth | yn | x | PD | Celine | http://www.specialweb.com/original/icons4.html -firstaid | y | | PD | Roger Cook, Dan Shanosky | http://thenounproject.com/noun/first-aid/#icon-No535 -cow | y | | PD | | http://www.openclipart.org/people/Anonymous/mucca.svg -field_puzzle | yn | x | PD | nicubunu | http://www.openclipart.org/detail/15169/red-jigsaw-piece-13-by-nicubunu -nightcache | yn | x | PD | | http://thenounproject.com/noun/moon/#icon-No128 -parkngrab | yn | x | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/parking/#icon-No27 -abandonedbuilding | yn | x | CC | The Noun Project | http://thenounproject.com/noun/home/#icon-No293 -hike_short | yn | x | PD | koem | -hike_med | yn | x | PD | koem | -hike_long | yn | x | PD | koem | -seasonal | yn | x | PD | USA National Park Service | http://thenounproject.com/noun/sun/#icon-No76 http://thenounproject.com/noun/snow/#icon-No64 -touristok | yn | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/baggage/#icon-No12 -frontyard | yn | x | PD | koem | -teamwork | yn | | CC | The Noun Project | http://thenounproject.com/noun/community/#icon-No288 +kids | 6 | x | PD | Jack Biesek, Gladys Brenner, Margaret Faye, Healther Merrifield, Kate Keating, Wendy Olmstead, Todd Pierce, Jamie Cowgill, Jim Bolek | http://thenounproject.com/noun/teddy-bear/#icon-No610 +onehour | 7 | x | CC | The Noun Project | http://thenounproject.com/noun/stopwatch/#icon-No282 +scenic | 8 | | PD | USA National Park Service | http://thenounproject.com/noun/binoculars/#icon-No112 +hiking | 9 | | PD | USA National Park Service | http://thenounproject.com/noun/hiker/#icon-No562 +climbing | 10 | | PD | USA National Park Service | http://thenounproject.com/noun/climbing/#icon-No526 +wading | 11 | x | PD | USA National Park Service | http://thenounproject.com/noun/wading/#icon-No581 +swimming | 12 | | PD | USA National Park Service | http://thenounproject.com/noun/swimming/#icon-No226 +available | 13 | x | PD | koem | +night | 14 | | PD | | http://thenounproject.com/noun/moon/#icon-No128 +winter | 15 | | PD | USA National Park Service | http://thenounproject.com/noun/snow/#icon-No64 +stealth | 40 | x | PD | Celine | http://www.specialweb.com/original/icons4.html +firstaid | 42 | | PD | Roger Cook, Dan Shanosky | http://thenounproject.com/noun/first-aid/#icon-No535 +cow | 43 | | PD | | http://www.openclipart.org/people/Anonymous/mucca.svg +field_puzzle | 47 | x | PD | nicubunu | http://www.openclipart.org/detail/15169/red-jigsaw-piece-13-by-nicubunu +nightcache | 52 | x | PD | | http://thenounproject.com/noun/moon/#icon-No128 +parkngrab | 53 | x | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/parking/#icon-No27 +abandonedbuilding | 54 | x | CC | The Noun Project | http://thenounproject.com/noun/home/#icon-No293 +hike_short | 55 | x | PD | koem | +hike_med | 56 | x | PD | koem | +hike_long | 57 | x | PD | koem | +seasonal | 62 | x | PD | USA National Park Service | http://thenounproject.com/noun/sun/#icon-No76 http://thenounproject.com/noun/snow/#icon-No64 +touristok | 63 | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/baggage/#icon-No12 +frontyard | 65 | x | PD | koem | +teamwork | 66 | | CC | The Noun Project | http://thenounproject.com/noun/community/#icon-No288 # # other # -landf | y | x | PD | koem | -partnership | y | | PD | worker | http://www.openclipart.org/detail/152875/hand-shake-by-worker +landf | 45 | x | PD | koem | +partnership | 61 | | PD | worker | http://www.openclipart.org/detail/152875/hand-shake-by-worker # # Equipment (required / not required) # -fee | y | x | PD | koem | -rappelling | y | | PD | USA National Park Service | http://thenounproject.com/noun/rock-climbing/#icon-No529 -boat | y | | PD | USA National Park Service | http://thenounproject.com/noun/motorboat/#icon-No661 -scuba | y | | PD | USA National Park Service | http://thenounproject.com/noun/scuba-diving/#icon-No242 -flashlight | y | | CC | The Noun Project | http://thenounproject.com/noun/flashlight/#icon-No516 -uv | y | x | PD | koem | -snowshoes | y | | PD | USA National Park Service | http://thenounproject.com/noun/snow-shoeing/#icon-No388 -skiis | y | | PD | USA National Park Service | http://thenounproject.com/noun/cross-country-skiing/#icon-No510 -s_tool | y | | CC | The Noun Project | http://thenounproject.com/noun/gears/#icon-No179 -wirelessbeacon | y | x | PD | | http://thenounproject.com/noun/non-ionizing-radiation/#icon-No277 -treeclimbing | yn | | CC | The Noun Project | http://thenounproject.com/noun/tree/#icon-No173 +fee | 2 | x | PD | koem | +rappelling | 3 | | PD | USA National Park Service | http://thenounproject.com/noun/rock-climbing/#icon-No529 +boat | 4 | | PD | USA National Park Service | http://thenounproject.com/noun/motorboat/#icon-No661 +scuba | 5 | | PD | USA National Park Service | http://thenounproject.com/noun/scuba-diving/#icon-No242 +flashlight | 44 | | CC | The Noun Project | http://thenounproject.com/noun/flashlight/#icon-No516 +uv | 48 | x | PD | koem | +snowshoes | 49 | | PD | USA National Park Service | http://thenounproject.com/noun/snow-shoeing/#icon-No388 +skiis | 50 | | PD | USA National Park Service | http://thenounproject.com/noun/cross-country-skiing/#icon-No510 +s_tool | 51 | | CC | The Noun Project | http://thenounproject.com/noun/gears/#icon-No179 +wirelessbeacon | 60 | x | PD | | http://thenounproject.com/noun/non-ionizing-radiation/#icon-No277 +treeclimbing | 64 | | CC | The Noun Project | http://thenounproject.com/noun/tree/#icon-No173 # # Hazards (present / not present) # -poisonoak | yn | | CC | The Noun Project | http://thenounproject.com/noun/mushroom/#icon-No309 -dangerousanimals | y | | PD | USA National Park Service | http://thenounproject.com/noun/snake/#icon-No201 -ticks | y | x | PD | koem | -mine | y | | PD | USA National Park Service | http://thenounproject.com/noun/rock-collecting/#icon-No528 -cliff | y | | PD | USA National Park Service | http://thenounproject.com/noun/falling-rocks/#icon-No520 -hunting | y | | CC | The Noun Project | http://thenounproject.com/noun/location/#icon-No418 -danger | y | x | PD | ryanlerch | http://www.openclipart.org/detail/1448/skull-and-crossbones-by-ryanlerch -thorn | y | | PD | emilie.rollandin | http://www.openclipart.org/detail/68125/spine-by-emilie.rollandin +poisonoak | 17 | | CC | The Noun Project | http://thenounproject.com/noun/mushroom/#icon-No309 +dangerousanimals | 18 | | PD | USA National Park Service | http://thenounproject.com/noun/snake/#icon-No201 +ticks | 19 | x | PD | koem | +mine | 20 | | PD | USA National Park Service | http://thenounproject.com/noun/rock-collecting/#icon-No528 +cliff | 21 | | PD | USA National Park Service | http://thenounproject.com/noun/falling-rocks/#icon-No520 +hunting | 22 | | CC | The Noun Project | http://thenounproject.com/noun/location/#icon-No418 +danger | 23 | x | PD | ryanlerch | http://www.openclipart.org/detail/1448/skull-and-crossbones-by-ryanlerch +thorn | 39 | | PD | emilie.rollandin | http://www.openclipart.org/detail/68125/spine-by-emilie.rollandin # # Facilities # -wheelchair | yn | | PD | USA National Park Service | http://thenounproject.com/noun/wheelchair-accessible/#icon-No354 -parking | yn | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/parking/#icon-No27 -public | y | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/bus/#icon-No97 -water | yn | | PD | USA National Park Service | http://thenounproject.com/noun/drinking-water/#icon-No214 -restrooms | yn | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/unisex/#icon-No50 -phone | yn | | PD | | http://thenounproject.com/noun/telephone/#icon-No127 -picnic | yn | | PD | USA National Park Service | http://thenounproject.com/noun/picnic-table/#icon-No208 -camping | yn | | PD | USA National Park Service | http://thenounproject.com/noun/campground/#icon-No209 -stroller | yn | | PD | USA National Park Service | http://thenounproject.com/noun/stroller/#icon-No161 -fuel | yn | | PD | | http://thenounproject.com/noun/gas/#icon-No155 -food | yn | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/restaurant/#icon-No33 +wheelchair | 24 | | PD | USA National Park Service | http://thenounproject.com/noun/wheelchair-accessible/#icon-No354 +parking | 25 | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/parking/#icon-No27 +public | 26 | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/bus/#icon-No97 +water | 27 | | PD | USA National Park Service | http://thenounproject.com/noun/drinking-water/#icon-No214 +restrooms | 28 | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/unisex/#icon-No50 +phone | 29 | | PD | | http://thenounproject.com/noun/telephone/#icon-No127 +picnic | 30 | | PD | USA National Park Service | http://thenounproject.com/noun/picnic-table/#icon-No208 +camping | 31 | | PD | USA National Park Service | http://thenounproject.com/noun/campground/#icon-No209 +stroller | 41 | | PD | USA National Park Service | http://thenounproject.com/noun/stroller/#icon-No161 +fuel | 58 | | PD | | http://thenounproject.com/noun/gas/#icon-No155 +food | 59 | | PD | Roger Cook, Don Shanosky | http://thenounproject.com/noun/restaurant/#icon-No33 # # own # -icon_not_found | y | x | PD | | selfmade +icon_not_found | | x | PD | koem | selfmade diff --git a/project/attributes/makeGpxIdArray.sh b/project/attributes/makeGpxIdArray.sh new file mode 100755 index 0000000..f348771 --- /dev/null +++ b/project/attributes/makeGpxIdArray.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +require () { + hash $1 2>&- || { echo >&2 "I require $1 but it's not installed. Aborting."; exit 1; } +} + +require sed + +echo "private final int[] CACHE_ATTRIBUTES = {" + +cat iconlist.txt | grep -v "^#" \ + | cut -d "|" -f 1,2 \ + | sed "s/ *$//" \ + | grep "[0-9]$" \ + | sort -nk 3 \ + | sed "s/^\([^ ]*\)[ \|]*\([0-9]*\)$/ R.string.attribute_\1_yes, \/\/ GPX-ID \2/" \ + > $0.tmp + +maxid=`tail -n 1 $0.tmp | sed "s/^.* \([0-9]*\)$/\1/"` + +for n in `seq 0 $maxid`; do + l=`grep " $n$" $0.tmp` + if [ -z "$l" ]; then + echo " -1, // GPX-ID $n" + else + echo "$l" + fi +done + +echo "};" diff --git a/project/localization/findmissingtranslations.sh b/project/localization/findmissingtranslations.sh index 0e08d0a..0e08d0a 100644..100755 --- a/project/localization/findmissingtranslations.sh +++ b/project/localization/findmissingtranslations.sh diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index da84191..5cb7d31 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -287,6 +287,7 @@ <string name="caches_sort_inventory">Inventaranzahl</string> <string name="caches_sort_date">Datum</string> <string name="caches_sort_finds">Funde</string> + <string name="caches_sort_state">Status</string> <string name="caches_select">Wähle von Liste</string> <string name="caches_select_mode">Auswahlmodus</string> <string name="caches_select_mode_exit">Auswahlmodus beenden</string> @@ -487,6 +488,7 @@ <string name="cache_offline_time_days">Tagen</string> <string name="cache_premium">Premium</string> <string name="cache_attributes">Attribute</string> + <string name="cache_attributes_no_icons">(aktualisiere den Cache um die Attribut-Icons anzuzeigen)</string> <string name="cache_inventory">Inventar</string> <string name="cache_log_offline">Offline-Log</string> <string name="cache_log_images_loading">Lade Logbild …</string> diff --git a/res/values/strings.xml b/res/values/strings.xml index 726a389..1fa5656 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -288,6 +288,7 @@ <string name="caches_sort_inventory">count of inventory</string> <string name="caches_sort_date">date</string> <string name="caches_sort_finds">finds</string> + <string name="caches_sort_state">state</string> <string name="caches_select">Select from list</string> <string name="caches_select_mode">Select mode</string> <string name="caches_select_mode_exit">Exit select mode</string> @@ -488,6 +489,7 @@ <string name="cache_offline_time_days">days ago</string> <string name="cache_premium">Premium</string> <string name="cache_attributes">Attributes</string> + <string name="cache_attributes_no_icons">(refresh cache to show attribute icons)</string> <string name="cache_inventory">Inventory</string> <string name="cache_log_offline">Offline log</string> <string name="cache_log_images_loading">Loading log Image …</string> @@ -909,7 +911,6 @@ · inkantis (localization PL)\n · <a href="http://www.jaytech.cz/">Jan Žatecký</a> (graphic)\n · <a href="http://joachim-wilke.de/">JoWi24</a> (code)\n - · <a href="http://github.com/koem">Köm</a> (code, artwork computation)\n · MichielK (code, loc. NL)\n · ncorreia (code, localization PT)\n · Pascal (localization NL)\n @@ -923,13 +924,26 @@ · thiasB (code, loc. DE EN)\n · YraFyra (code, loc. SV)\n · zenobios (code, loc. DE EN)\n + · <a href="http://github.com/koem">Karsten Priegnitz</a> (code, artwork computation)\n \n · <a href="http://code.google.com/p/mapsforge/">Mapsforge</a> (OSM-rendering)\n - · <a href="http://thenounproject.com/">The Noun Project</a> (graphics)\n + · <a href="http://thenounproject.com/">The Noun Project</a> (basis for attribute icons)\n </string> <!-- changelog --> <string name="changelog">\n + <b>Next release</b>\n + · new: sort by state, sort by find count\n + · new: experimental support for .gpx from opencaching.com\n + · new: scan QR code to open cache description\n + · new: context menu on stored caches button (main screen)\n + · fix: performance of GPX import\n + · fix: performance of deleting caches from list\n + · fix: return to list after GPX import\n + · fix: fill signature when logging offline\n + · fix: show strikethrough in caches\n + · fix: no more empty map previews\n + \n\n <b>26.08.2011</b>\n · new: street view\n · new: attribute icons\n diff --git a/src/cgeo/geocaching/LogTemplateProvider.java b/src/cgeo/geocaching/LogTemplateProvider.java index 210f863..08931a7 100644 --- a/src/cgeo/geocaching/LogTemplateProvider.java +++ b/src/cgeo/geocaching/LogTemplateProvider.java @@ -16,7 +16,7 @@ public class LogTemplateProvider { private String template;
private int resourceId;
- public LogTemplate(String template, int resourceId) {
+ protected LogTemplate(String template, int resourceId) {
this.template = template;
this.resourceId = resourceId;
}
diff --git a/src/cgeo/geocaching/StaticMapsProvider.java b/src/cgeo/geocaching/StaticMapsProvider.java index b649f7b..927a99c 100644 --- a/src/cgeo/geocaching/StaticMapsProvider.java +++ b/src/cgeo/geocaching/StaticMapsProvider.java @@ -28,7 +28,7 @@ public class StaticMapsProvider { private static void downloadMapsInThread(final cgCache cache, String latlonMap, int edge, String waypoints) { createStorageDirectory(cache); - + downloadMap(cache, 20, "satellite", 1, latlonMap, edge, waypoints); downloadMap(cache, 18, "satellite", 2, latlonMap, edge, waypoints); downloadMap(cache, 16, "roadmap", 3, latlonMap, edge, waypoints); @@ -54,7 +54,7 @@ public class StaticMapsProvider { private static void downloadMap(cgCache cache, int zoom, String mapType, int level, String latlonMap, int edge, String waypoints) { String mapUrl = "http://maps.google.com/maps/api/staticmap?center=" + latlonMap; String markerUrl = getMarkerUrl(cache); - + String url = mapUrl + "&zoom=" + zoom + "&size=" + edge + "x" + edge + "&maptype=" + mapType + "&markers=icon%3A" + markerUrl + "%7C" + latlonMap + waypoints + "&sensor=false"; final String fileName = getStaticMapsDirectory(cache) + "/map_" + level; @@ -125,7 +125,7 @@ public class StaticMapsProvider { || cache.longitude == null || cache.geocode == null || cache.geocode.length() == 0) { return; } - + final String latlonMap = String.format((Locale) null, "%.6f", cache.latitude) + "," + String.format((Locale) null, "%.6f", cache.longitude); final Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final int maxWidth = display.getWidth() - 25; @@ -144,11 +144,13 @@ public class StaticMapsProvider { continue; } - waypoints.append("&markers=icon%3A" + MARKERS_URL + "marker_waypoint_"); + waypoints.append("&markers=icon%3A"); + waypoints.append(MARKERS_URL); + waypoints.append("marker_waypoint_"); waypoints.append(waypoint.type); waypoints.append(".png%7C"); waypoints.append(String.format((Locale) null, "%.6f", waypoint.latitude)); - waypoints.append(","); + waypoints.append(','); waypoints.append(String.format((Locale) null, "%.6f", waypoint.longitude)); } } @@ -156,7 +158,7 @@ public class StaticMapsProvider { // download map images in separate background thread for higher performance downloadMaps(cache, latlonMap, edge, waypoints.toString()); } - + private static void downloadMaps(final cgCache cache, final String latlonMap, final int edge, final String waypoints) { Thread staticMapsThread = new Thread("getting static map") {@Override diff --git a/src/cgeo/geocaching/activity/AbstractActivity.java b/src/cgeo/geocaching/activity/AbstractActivity.java index 825cc9b..96e3e6b 100644 --- a/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/src/cgeo/geocaching/activity/AbstractActivity.java @@ -21,11 +21,11 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi protected cgBase base = null; protected SharedPreferences prefs = null; - public AbstractActivity() { + protected AbstractActivity() { this(null); } - public AbstractActivity(final String helpTopic) { + protected AbstractActivity(final String helpTopic) { this.helpTopic = helpTopic; } @@ -76,7 +76,7 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi final public cgSettings getSettings() { return settings; } - + public void addVisitMenu(Menu menu, cgCache cache) { ActivityMixin.addVisitMenu(this, menu, cache); } diff --git a/src/cgeo/geocaching/activity/AbstractListActivity.java b/src/cgeo/geocaching/activity/AbstractListActivity.java index 9cb3284..873a717 100644 --- a/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -22,11 +22,11 @@ public abstract class AbstractListActivity extends ListActivity implements protected cgBase base = null; protected SharedPreferences prefs = null; - public AbstractListActivity() { + protected AbstractListActivity() { this(null); } - public AbstractListActivity(final String helpTopic) { + protected AbstractListActivity(final String helpTopic) { this.helpTopic = helpTopic; } @@ -73,7 +73,7 @@ public abstract class AbstractListActivity extends ListActivity implements final public void setTitle(final String title) { ActivityMixin.setTitle(this, title); } - + final public cgSettings getSettings() { return settings; } diff --git a/src/cgeo/geocaching/apps/AbstractApp.java b/src/cgeo/geocaching/apps/AbstractApp.java index ba8333c..007a4f6 100644 --- a/src/cgeo/geocaching/apps/AbstractApp.java +++ b/src/cgeo/geocaching/apps/AbstractApp.java @@ -54,7 +54,7 @@ public abstract class AbstractApp implements App { final List<ResolveInfo> list = packageManager.queryIntentActivities( intent, PackageManager.MATCH_DEFAULT_ONLY); - return (list.size() > 0); + return list.size() > 0; } @Override diff --git a/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java b/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java index 54d7709..5fd8542 100644 --- a/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java +++ b/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java @@ -7,7 +7,7 @@ import cgeo.geocaching.apps.AbstractApp; abstract class AbstractGeneralApp extends AbstractApp implements GeneralApp { - AbstractGeneralApp(String name, String packageName) { + protected AbstractGeneralApp(String name, String packageName) { super(name, null); this.packageName = packageName; } diff --git a/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java b/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java index 5ae8f44..f14c053 100644 --- a/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java +++ b/src/cgeo/geocaching/apps/cache/navi/AbstractNavigationApp.java @@ -4,11 +4,11 @@ import cgeo.geocaching.apps.AbstractApp; abstract class AbstractNavigationApp extends AbstractApp implements NavigationApp { - AbstractNavigationApp(String name, String intent, String packageName) { + protected AbstractNavigationApp(String name, String intent, String packageName) { super(name, intent, packageName); } - AbstractNavigationApp(String name, String intent) { + protected AbstractNavigationApp(String name, String intent) { super(name, intent); } diff --git a/src/cgeo/geocaching/cgBase.java b/src/cgeo/geocaching/cgBase.java index 79e67b5..057dd3f 100644 --- a/src/cgeo/geocaching/cgBase.java +++ b/src/cgeo/geocaching/cgBase.java @@ -422,10 +422,10 @@ public class cgBase { String[] viewstates = new String[count]; // Get the viewstates + int no; final Matcher matcherViewstates = patternViewstates.matcher(page); while (matcherViewstates.find()) { String sno = matcherViewstates.group(1); // number of viewstate - int no; if ("".equals(sno)) no = 0; else @@ -585,13 +585,13 @@ public class cgBase { // on every page final Matcher matcherLogged2In = patternLogged2In.matcher(page); - while (matcherLogged2In.find()) { + if (matcherLogged2In.find()) { return true; } // after login final Matcher matcherLoggedIn = patternLoggedIn.matcher(page); - while (matcherLoggedIn.find()) { + if (matcherLoggedIn.find()) { return true; } @@ -914,9 +914,7 @@ public class cgBase { final String host = "www.geocaching.com"; final String path = "/seek/nearest.aspx"; final StringBuilder params = new StringBuilder(); - params.append("__EVENTTARGET="); - params.append("&"); - params.append("__EVENTARGUMENT="); + params.append("__EVENTTARGET=&__EVENTARGUMENT="); if (caches.viewstates != null && caches.viewstates.length > 0) { params.append("&__VIEWSTATE="); params.append(urlencode_rfc3986(caches.viewstates[0])); @@ -929,21 +927,17 @@ public class cgBase { } } for (String cid : cids) { - params.append("&"); - params.append("CID="); + params.append("&CID="); params.append(urlencode_rfc3986(cid)); } if (recaptchaChallenge != null && recaptchaText != null && recaptchaText.length() > 0) { - params.append("&"); - params.append("recaptcha_challenge_field="); + params.append("&recaptcha_challenge_field="); params.append(urlencode_rfc3986(recaptchaChallenge)); - params.append("&"); - params.append("recaptcha_response_field="); + params.append("&recaptcha_response_field="); params.append(urlencode_rfc3986(recaptchaText)); } - params.append("&"); - params.append("ctl00%24ContentBody%24uxDownloadLoc=Download+Waypoints"); + params.append("&ctl00%24ContentBody%24uxDownloadLoc=Download+Waypoints"); final String coordinates = request(false, host, path, "POST", params.toString(), 0, true).getData(); @@ -1903,7 +1897,7 @@ public class cgBase { } input = input.trim(); - + if (null != settings //&& null != settings.getGcCustomDate() && gcCustomDateFormats.containsKey(settings.getGcCustomDate())) @@ -1926,17 +1920,17 @@ public class cgBase { 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)); @@ -2328,7 +2322,7 @@ public class cgBase { while (matcherLogs.find()) { final cgLog logDone = new cgLog(); - + if (logTypes.containsKey(matcherLogs.group(1).toLowerCase())) { logDone.type = logTypes.get(matcherLogs.group(1).toLowerCase()); @@ -2339,15 +2333,15 @@ public class cgBase { } 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); @@ -3605,7 +3599,7 @@ public class cgBase { if (c > 300) { logUpdated.append("&#"); logUpdated.append(Integer.toString((int) c)); - logUpdated.append(";"); + logUpdated.append(';'); } else { logUpdated.append(c); } @@ -3645,7 +3639,7 @@ public class cgBase { if (tb.action > 0) { hdnSelected.append(action); - hdnSelected.append(","); + hdnSelected.append(','); } } @@ -3706,7 +3700,7 @@ public class cgBase { params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$repTravelBugs$ctl" + ctl + "$ddlAction", action); if (tb.action > 0) { hdnSelected.append(action); - hdnSelected.append(","); + hdnSelected.append(','); } } @@ -5022,7 +5016,7 @@ public class cgBase { } return out; } - + public static int getCacheIcon(final String type) { fillIconsMap(); Integer iconId = gcIcons.get("type_" + type); diff --git a/src/cgeo/geocaching/cgCache.java b/src/cgeo/geocaching/cgCache.java index ee212e1..1fed844 100644 --- a/src/cgeo/geocaching/cgCache.java +++ b/src/cgeo/geocaching/cgCache.java @@ -275,7 +275,7 @@ public class cgCache { } public boolean isEventCache() { - return ("event".equalsIgnoreCase(type) || "mega".equalsIgnoreCase(type) || "cito".equalsIgnoreCase(type)); + return "event".equalsIgnoreCase(type) || "mega".equalsIgnoreCase(type) || "cito".equalsIgnoreCase(type); } public boolean logVisit(IAbstractActivity fromActivity) { diff --git a/src/cgeo/geocaching/cgCacheListAdapter.java b/src/cgeo/geocaching/cgCacheListAdapter.java index 57c6e5f..8ef1e8f 100644 --- a/src/cgeo/geocaching/cgCacheListAdapter.java +++ b/src/cgeo/geocaching/cgCacheListAdapter.java @@ -51,7 +51,7 @@ public class cgCacheListAdapter extends ArrayAdapter<cgCache> { private Double latitude = null; private Double longitude = null; private Double azimuth = Double.valueOf(0); - private long lastSort = 0l; + private long lastSort = 0L; private boolean sort = true; private int checked = 0; private boolean selectMode = false; diff --git a/src/cgeo/geocaching/cgData.java b/src/cgeo/geocaching/cgData.java index ab24864..34d15d3 100644 --- a/src/cgeo/geocaching/cgData.java +++ b/src/cgeo/geocaching/cgData.java @@ -35,7 +35,7 @@ public class cgData { private cgDbHelper dbHelper = null; private SQLiteDatabase databaseRO = null; private SQLiteDatabase databaseRW = null; - private static final int dbVersion = 55; + private static final int dbVersion = 56; private static final String dbName = "data"; private static final String dbTableCaches = "cg_caches"; private static final String dbTableLists = "cg_lists"; @@ -778,6 +778,18 @@ public class cgData { } } + + // make all internal attribute names lowercase + // @see issue #299 + if (oldVersion < 56) { // update to 56 + try { + db.execSQL("update " + dbTableAttributes + " set attribute = " + + "lower(attribute) where attribute like \"%_yes\" " + + "or attribute like \"%_no\""); + } catch (Exception e) { + Log.e(cgSettings.tag, "Failed to upgrade to ver. 56: " + e.toString()); + } + } } db.setTransactionSuccessful(); @@ -1239,7 +1251,7 @@ public class cgData { if (statusOk == false) { cache.detailed = false; - cache.detailedUpdate = 0l; + cache.detailedUpdate = 0L; } init(); @@ -1592,7 +1604,7 @@ public class cgData { if (oneTrackable.released != null) { values.put("released", oneTrackable.released.getTime()); } else { - values.put("released", 0l); + values.put("released", 0L); } values.put("goal", oneTrackable.goal); values.put("description", oneTrackable.details); @@ -1626,9 +1638,9 @@ public class cgData { if (all.length() > 0) { all.append(", "); } - all.append("\""); + all.append('"'); all.append((String) one); - all.append("\""); + all.append('"'); } if (where.length() > 0) { @@ -1636,7 +1648,7 @@ public class cgData { } where.append("geocode in ("); where.append(all); - where.append(")"); + where.append(')'); } cursor = databaseRO.query( @@ -1727,9 +1739,9 @@ public class cgData { if (all.length() > 0) { all.append(", "); } - all.append("\""); + all.append('"'); all.append((String) one); - all.append("\""); + all.append('"'); } if (where.length() > 0) { @@ -1737,16 +1749,16 @@ public class cgData { } where.append("geocode in ("); where.append(all); - where.append(")"); + where.append(')'); } else if (guids != null && guids.length > 0) { StringBuilder all = new StringBuilder(); for (Object one : guids) { if (all.length() > 0) { all.append(", "); } - all.append("\""); + all.append('"'); all.append((String) one); - all.append("\""); + all.append('"'); } if (where.length() > 0) { @@ -1754,7 +1766,7 @@ public class cgData { } where.append("guid in ("); where.append(all); - where.append(")"); + where.append(')'); } else { return caches; } @@ -1781,8 +1793,7 @@ public class cgData { if (where.length() > 0) { where.append(" and "); } - where.append("("); - where.append("latitude >= "); + where.append("(latitude >= "); where.append(String.format((Locale) null, "%.6f", latMin)); where.append(" and latitude <= "); where.append(String.format((Locale) null, "%.6f", latMax)); @@ -1790,7 +1801,7 @@ public class cgData { where.append(String.format((Locale) null, "%.6f", lonMin)); where.append(" and longitude <= "); where.append(String.format((Locale) null, "%.6f", lonMax)); - where.append(")"); + where.append(')'); } cursor = databaseRO.query( @@ -1876,13 +1887,13 @@ public class cgData { cache.rating = (Float) cursor.getFloat(cursor.getColumnIndex("rating")); cache.votes = (Integer) cursor.getInt(cursor.getColumnIndex("votes")); cache.myVote = (Float) cursor.getFloat(cursor.getColumnIndex("myvote")); - cache.disabled = cursor.getLong(cursor.getColumnIndex("disabled")) == 1l; - cache.archived = cursor.getLong(cursor.getColumnIndex("archived")) == 1l; - cache.members = cursor.getLong(cursor.getColumnIndex("members")) == 1l; - cache.found = cursor.getLong(cursor.getColumnIndex("found")) == 1l; - cache.favourite = cursor.getLong(cursor.getColumnIndex("favourite")) == 1l; + cache.disabled = cursor.getLong(cursor.getColumnIndex("disabled")) == 1L; + cache.archived = cursor.getLong(cursor.getColumnIndex("archived")) == 1L; + cache.members = cursor.getLong(cursor.getColumnIndex("members")) == 1L; + cache.found = cursor.getLong(cursor.getColumnIndex("found")) == 1L; + cache.favourite = cursor.getLong(cursor.getColumnIndex("favourite")) == 1L; cache.inventoryItems = (Integer) cursor.getInt(cursor.getColumnIndex("inventoryunknown")); - cache.onWatchlist = cursor.getLong(cursor.getColumnIndex("onWatchlist")) == 1l; + cache.onWatchlist = cursor.getLong(cursor.getColumnIndex("onWatchlist")) == 1L; if (loadA) { ArrayList<String> attributes = loadAttributes(cache.geocode); @@ -2468,7 +2479,7 @@ public class cgData { if (cachetype != null) { specifySql.append(" and type = \""); specifySql.append(cachetype); - specifySql.append("\""); + specifySql.append('"'); } try { @@ -2518,7 +2529,7 @@ public class cgData { if (cachetype != null) { specifySql.append(" and type = \""); specifySql.append(cachetype); - specifySql.append("\""); + specifySql.append('"'); } try { @@ -2602,7 +2613,7 @@ public class cgData { if (cachetype != null) { where.append(" and type = \""); where.append(cachetype); - where.append("\""); + where.append('"'); } // offline caches only @@ -2652,7 +2663,7 @@ public class cgData { // cachetype limitation if (cachetype != null) { where.append(cachetype); - where.append("\""); + where.append('"'); } // offline caches only diff --git a/src/cgeo/geocaching/cgDestination.java b/src/cgeo/geocaching/cgDestination.java index eb82889..0a2a493 100644 --- a/src/cgeo/geocaching/cgDestination.java +++ b/src/cgeo/geocaching/cgDestination.java @@ -1,13 +1,13 @@ package cgeo.geocaching; public class cgDestination { - + private long id; - + private long date; - + private double latitude; - + private double longitude; public cgDestination() { @@ -63,8 +63,9 @@ public class cgDestination { return true; if (obj == null) return false; - if (getClass() != obj.getClass()) + if (!(obj instanceof cgDestination)) { return false; + } cgDestination other = (cgDestination) obj; if (Double.doubleToLongBits(latitude) != Double .doubleToLongBits(other.latitude)) @@ -83,5 +84,5 @@ public class cgDestination { this.id = id; } - + } diff --git a/src/cgeo/geocaching/cgGeo.java b/src/cgeo/geocaching/cgGeo.java index 4ae2e32..8a191dd 100644 --- a/src/cgeo/geocaching/cgGeo.java +++ b/src/cgeo/geocaching/cgGeo.java @@ -30,7 +30,7 @@ public class cgGeo { private Integer distance = 0; private Location locGps = null; private Location locNet = null; - private long locGpsLast = 0l; + private long locGpsLast = 0L; private boolean g4cRunning = false; private Double lastGo4cacheLat = null; private Double lastGo4cacheLon = null; diff --git a/src/cgeo/geocaching/cgeo.java b/src/cgeo/geocaching/cgeo.java index df167fb..9f87c5b 100644 --- a/src/cgeo/geocaching/cgeo.java +++ b/src/cgeo/geocaching/cgeo.java @@ -250,7 +250,7 @@ public class cgeo extends AbstractActivity { final List<ResolveInfo> list = packageManager.queryIntentActivities( new Intent(intent), PackageManager.MATCH_DEFAULT_ONLY); - return (list.size() > 0); + return list.size() > 0; } @Override diff --git a/src/cgeo/geocaching/cgeoaddresses.java b/src/cgeo/geocaching/cgeoaddresses.java index a5e7f37..797c018 100644 --- a/src/cgeo/geocaching/cgeoaddresses.java +++ b/src/cgeo/geocaching/cgeoaddresses.java @@ -54,7 +54,7 @@ public class cgeoaddresses extends AbstractActivity { while (address.getAddressLine(index) != null) { if (allAdd.length() > 0) { - allAdd.append("\n"); + allAdd.append('\n'); } if (allAddLine.length() > 0) { allAddLine.append("; "); diff --git a/src/cgeo/geocaching/cgeoauth.java b/src/cgeo/geocaching/cgeoauth.java index 0343adf..1c2e8bb 100644 --- a/src/cgeo/geocaching/cgeoauth.java +++ b/src/cgeo/geocaching/cgeoauth.java @@ -170,7 +170,7 @@ public class cgeoauth extends AbstractActivity { while ((lineOne = br.readLine()) != null) { sb.append(lineOne); - sb.append("\n"); + sb.append('\n'); } code = connection.getResponseCode(); @@ -275,7 +275,7 @@ public class cgeoauth extends AbstractActivity { while ((lineOne = br.readLine()) != null) { sb.append(lineOne); - sb.append("\n"); + sb.append('\n'); } code = connection.getResponseCode(); diff --git a/src/cgeo/geocaching/cgeocaches.java b/src/cgeo/geocaching/cgeocaches.java index c01ae72..ddc383e 100644 --- a/src/cgeo/geocaching/cgeocaches.java +++ b/src/cgeo/geocaching/cgeocaches.java @@ -59,6 +59,7 @@ import cgeo.geocaching.sorting.NameComparator; import cgeo.geocaching.sorting.PopularityComparator; import cgeo.geocaching.sorting.RatingComparator; import cgeo.geocaching.sorting.SizeComparator; +import cgeo.geocaching.sorting.StateComparator; import cgeo.geocaching.sorting.TerrainComparator; import cgeo.geocaching.sorting.VoteComparator; @@ -125,6 +126,7 @@ public class cgeocaches extends AbstractListActivity { private static final int SUBMENU_MANAGE_HISTORY = 60; private static final int MENU_SORT_DATE = 61; private static final int MENU_SORT_FINDS = 62; + private static final int MENU_SORT_STATE = 63; private static final int CONTEXT_MENU_MOVE_TO_LIST = 1000; private static final int MENU_MOVE_SELECTED_OR_ALL_TO_LIST = 1200; @@ -152,7 +154,7 @@ public class cgeocaches extends AbstractListActivity { private String title = ""; private int detailTotal = 0; private int detailProgress = 0; - private long detailProgressTime = 0l; + private long detailProgressTime = 0L; private geocachesLoadDetails threadD = null; private geocachesLoadFromWeb threadW = null; private geocachesDropDetails threadR = null; @@ -752,6 +754,7 @@ public class cgeocaches extends AbstractListActivity { comparators.put(res.getString(R.string.caches_sort_inventory), MENU_SORT_INVENTORY); comparators.put(res.getString(R.string.caches_sort_date), MENU_SORT_DATE); comparators.put(res.getString(R.string.caches_sort_finds), MENU_SORT_FINDS); + comparators.put(res.getString(R.string.caches_sort_state), MENU_SORT_STATE); ArrayList<String> sortedLabels = new ArrayList<String>(comparators.keySet()); Collections.sort(sortedLabels); @@ -983,6 +986,9 @@ public class cgeocaches extends AbstractListActivity { case MENU_SORT_FINDS: setComparator(item, new FindsComparator(app)); return true; + case MENU_SORT_STATE: + setComparator(item, new StateComparator()); + return true; case SUBMENU_FILTER_TYPE: selectedFilter = res.getString(R.string.caches_filter_type); openContextMenu(getListView()); @@ -1937,7 +1943,7 @@ public class cgeocaches extends AbstractListActivity { private int reason = 1; private volatile boolean needToStop = false; private int checked = 0; - private long last = 0l; + private long last = 0L; public geocachesLoadDetails(Handler handlerIn, int reasonIn) { setPriority(Thread.MIN_PRIORITY); @@ -2274,9 +2280,9 @@ public class cgeocaches extends AbstractListActivity { if (null != logTypes.get(log.type)) { fieldNoteBuffer.append(cache.geocode) - .append(",") + .append(',') .append(fieldNoteDateFormat.format(new Date(log.date))) - .append(",") + .append(',') .append(logTypes.get(log.type)) .append(",\"") .append(log.log.replaceAll("\"", "'")) @@ -2547,7 +2553,7 @@ public class cgeocaches extends AbstractListActivity { cachesIntent.putExtra(EXTRAS_LIST_TYPE, "offline"); context.startActivity(cachesIntent); } - + public static void startActivityCachesAround(final AbstractActivity context, final Double latitude, final Double longitude) { cgeocaches cachesActivity = new cgeocaches(); @@ -2559,7 +2565,7 @@ public class cgeocaches extends AbstractListActivity { context.startActivity(cachesIntent); } - + public static void startActivityCacheOwner(final AbstractActivity context, final String userName) { final Intent cachesIntent = new Intent(context, cgeocaches.class); @@ -2569,7 +2575,7 @@ public class cgeocaches extends AbstractListActivity { context.startActivity(cachesIntent); } - + public static void startActivityCacheUser(final AbstractActivity context, final String userName) { final Intent cachesIntent = new Intent(context, cgeocaches.class); diff --git a/src/cgeo/geocaching/cgeodetail.java b/src/cgeo/geocaching/cgeodetail.java index e4d748c..90d02f5 100644 --- a/src/cgeo/geocaching/cgeodetail.java +++ b/src/cgeo/geocaching/cgeodetail.java @@ -86,9 +86,15 @@ public class cgeodetail extends AbstractActivity { private ProgressDialog watchlistDialog = null; // progress dialog for watchlist add/remove private Thread watchlistThread = null; // thread for watchlist add/remove private HashMap<Integer, String> calendars = new HashMap<Integer, String>(); + private ViewGroup attributeIconsLayout; // layout for attribute icons private ViewGroup attributeDescriptionsLayout; // layout for attribute descriptions private boolean attributesShowAsIcons = true; // default: show icons + /** <code>noAttributeImagesFound</code> + * This will be the case if the cache was imported with an older version of c:geo. + * These older versions parsed the attribute description from the tooltip in the web + * page and put them into the DB. No icons can be matched for these. */ + private boolean noAttributeIconsFound = false; private int attributeBoxMaxWidth; private Handler storeCacheHandler = new Handler() { @@ -801,7 +807,8 @@ public class cgeodetail extends AbstractActivity { // cache attributes if (cache.attributes != null && cache.attributes.size() > 0) { - final LinearLayout attribBox = (LinearLayout) findViewById(R.id.attributes_innerbox); + final LinearLayout attribBox = (LinearLayout) findViewById( + R.id.attributes_innerbox); // maximum width for attribute icons is screen width - paddings of parents attributeBoxMaxWidth = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) @@ -827,10 +834,18 @@ public class cgeodetail extends AbstractActivity { } ); // icons or text? - if (attributesShowAsIcons) + // + // also show icons when noAttributeImagesFound == true. Explanation: + // 1. no icons could be found in the first invocation of this method + // 2. user refreshes cache from web + // 3. now this method is called again + // 4. attributeShowAsIcons is false but noAttributeImagesFound is true + // => try to show them now + if (attributesShowAsIcons || noAttributeIconsFound) { showAttributeIcons(attribBox, attributeBoxMaxWidth); - else + } else { showAttributeDescriptions(attribBox); + } findViewById(R.id.attributes_box).setVisibility(View.VISIBLE); } @@ -843,7 +858,7 @@ public class cgeodetail extends AbstractActivity { StringBuilder inventoryString = new StringBuilder(); for (cgTrackable inventoryItem : cache.inventory) { if (inventoryString.length() > 0) { - inventoryString.append("\n"); + inventoryString.append('\n'); } // avoid HTML parsing where possible if (inventoryItem.name.indexOf('<') >= 0 || inventoryItem.name.indexOf('&') >= 0 ) { @@ -1926,8 +1941,14 @@ public class cgeodetail extends AbstractActivity { * and makes it visible */ private void showAttributeIcons(LinearLayout attribBox, int parentWidth) { - if (attributeIconsLayout == null) + if (attributeIconsLayout == null) { attributeIconsLayout = createAttributeIconsLayout(parentWidth); + // no matching icons found? show text + if (noAttributeIconsFound) { + showAttributeDescriptions(attribBox); + return; + } + } attribBox.removeAllViews(); attribBox.addView(attributeIconsLayout); attributesShowAsIcons = true; @@ -1938,8 +1959,9 @@ public class cgeodetail extends AbstractActivity { * and makes it visible */ private void showAttributeDescriptions(LinearLayout attribBox) { - if (attributeDescriptionsLayout == null) + if (attributeDescriptionsLayout == null) { attributeDescriptionsLayout = createAttributeDescriptionsLayout(); + } attribBox.removeAllViews(); attribBox.addView(attributeDescriptionsLayout); attributesShowAsIcons = false; @@ -1949,10 +1971,17 @@ public class cgeodetail extends AbstractActivity { * toggle attribute descriptions and icons */ private void toggleAttributeDisplay(LinearLayout attribBox, int parentWidth) { - if (attributesShowAsIcons) + // Don't toggle when there are no icons to show. + if (noAttributeIconsFound) { + return; + } + + // toggle + if (attributesShowAsIcons) { showAttributeDescriptions(attribBox); - else + } else { showAttributeIcons(attribBox, parentWidth); + } } private ViewGroup createAttributeIconsLayout(int parentWidth) { @@ -1963,11 +1992,14 @@ public class cgeodetail extends AbstractActivity { LinearLayout attributeRow = newAttributeIconsRow(); rows.addView(attributeRow); + noAttributeIconsFound = true; + for(String attributeName : cache.attributes) { boolean strikethru = attributeName.endsWith("_no"); // cut off _yes / _no - if (attributeName.endsWith("_no") || attributeName.endsWith("_yes")) + if (attributeName.endsWith("_no") || attributeName.endsWith("_yes")) { attributeName = attributeName.substring(0, attributeName.lastIndexOf("_")); + } // check if another attribute icon fits in this row attributeRow.measure(0, 0); int rowWidth = attributeRow.getMeasuredWidth(); @@ -1981,26 +2013,30 @@ public class cgeodetail extends AbstractActivity { // dynamically search icon of the attribute Drawable d = null; - int id = res.getIdentifier("attribute_" + attributeName, "drawable", base.context.getPackageName()); - if (id > 0) + int id = res.getIdentifier("attribute_" + attributeName, "drawable", + base.context.getPackageName()); + if (id > 0) { + noAttributeIconsFound = false; d = res.getDrawable(id); - else + iv.setImageDrawable(d); + // strike through? + if (strikethru) { + // generate strikethru image with same properties as attribute image + ImageView strikethruImage = new ImageView(this); + strikethruImage.setLayoutParams(iv.getLayoutParams()); + d = res.getDrawable(R.drawable.attribute__strikethru); + strikethruImage.setImageDrawable(d); + fl.addView(strikethruImage); + } + } else { d = res.getDrawable(R.drawable.attribute_icon_not_found); - iv.setImageDrawable(d); - - // strike through? - if (strikethru) { - // generate strikethru image with same properties as attribute image - ImageView strikethruImage = new ImageView(this); - strikethruImage.setLayoutParams(iv.getLayoutParams()); - d = res.getDrawable(R.drawable.attribute__strikethru); - strikethruImage.setImageDrawable(d); - fl.addView(strikethruImage); - } + iv.setImageDrawable(d); + } + attributeRow.addView(fl); } - return rows; + return rows; } private LinearLayout newAttributeIconsRow() { @@ -2012,7 +2048,8 @@ public class cgeodetail extends AbstractActivity { } private ViewGroup createAttributeDescriptionsLayout() { - final LinearLayout descriptions = (LinearLayout) inflater.inflate(R.layout.attribute_descriptions, null); + final LinearLayout descriptions = (LinearLayout) inflater.inflate( + R.layout.attribute_descriptions, null); TextView attribView = (TextView) descriptions.getChildAt(0); StringBuilder buffer = new StringBuilder(); @@ -2021,19 +2058,21 @@ public class cgeodetail extends AbstractActivity { attribute = cache.attributes.get(i); // dynamically search for a translation of the attribute - int id = res.getIdentifier("attribute_" + attribute, "string", base.context.getPackageName()); + int id = res.getIdentifier("attribute_" + attribute, "string", + base.context.getPackageName()); if (id > 0) { String translated = res.getString(id); if (translated != null && translated.length() > 0) { attribute = translated; } } - if (buffer.length() > 0) { - buffer.append('\n'); - } + if (buffer.length() > 0) buffer.append('\n'); buffer.append(attribute); } + if (noAttributeIconsFound) + buffer.append("\n\n").append(res.getString(R.string.cache_attributes_no_icons)); + attribView.setText(buffer); return descriptions; diff --git a/src/cgeo/geocaching/files/FileList.java b/src/cgeo/geocaching/files/FileList.java index 67e89a0..eae1e4d 100644 --- a/src/cgeo/geocaching/files/FileList.java +++ b/src/cgeo/geocaching/files/FileList.java @@ -127,7 +127,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis * @return The folder to start the recursive search in */ protected abstract String[] getBaseFolders(); - + /** * Triggers the deriving class to set the title */ @@ -221,18 +221,18 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis return; } - - public FileList(final String extension) { + + protected FileList(final String extension) { setExtensions(new String[] {extension}); } - public FileList(final String[] extensions) { + protected FileList(final String[] extensions) { setExtensions(extensions); } private void setExtensions(String[] extensionsIn) { for (String extension : extensionsIn) { - if (!extension.startsWith(".")) { + if (extension.length() == 0 || extension.charAt(0) != '.') { extension = "." + extension; } } diff --git a/src/cgeo/geocaching/files/GPXParser.java b/src/cgeo/geocaching/files/GPXParser.java index c96e30c..e6b5748 100644 --- a/src/cgeo/geocaching/files/GPXParser.java +++ b/src/cgeo/geocaching/files/GPXParser.java @@ -23,6 +23,7 @@ import android.sax.RootElement; import android.sax.StartElementListener; import android.util.Log; import android.util.Xml; +import cgeo.geocaching.R; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgLog; @@ -54,6 +55,7 @@ public abstract class GPXParser extends FileParser { private cgCache cache = new cgCache(); private cgTrackable trackable = new cgTrackable(); private cgLog log = new cgLog(); + private CacheAttribute cacheAttribute = null; private String type = null; private String sym = null; @@ -61,7 +63,123 @@ public abstract class GPXParser extends FileParser { private String cmt = null; private String desc = null; - public GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) { + private class CacheAttribute { + // List of cache attributes matching IDs used in GPX files. + // The ID is represented by the position of the String in the array. + // Strings are not used as text but as resource IDs of strings, just to be aware of changes + // made in strings.xml which then will lead to compile errors here and not to runtime errors. + private final int[] CACHE_ATTRIBUTES = { + -1, // 0 + R.string.attribute_dogs_yes, // 1 + R.string.attribute_fee_yes, // 2 + R.string.attribute_rappelling_yes, // 3 + R.string.attribute_boat_yes, // 4 + R.string.attribute_scuba_yes, // 5 + R.string.attribute_kids_yes, // 6 + R.string.attribute_onehour_yes, // 7 + R.string.attribute_scenic_yes, // 8 + R.string.attribute_hiking_yes, // 9 + R.string.attribute_climbing_yes, // 10 + R.string.attribute_wading_yes, // 11 + R.string.attribute_swimming_yes, // 12 + R.string.attribute_available_yes, // 13 + R.string.attribute_night_yes, // 14 + R.string.attribute_winter_yes, // 15 + -1, // 16 + R.string.attribute_poisonoak_yes, // 17 + R.string.attribute_dangerousanimals_yes, // 18 + R.string.attribute_ticks_yes, // 19 + R.string.attribute_mine_yes, // 20 + R.string.attribute_cliff_yes, // 21 + R.string.attribute_hunting_yes, // 22 + R.string.attribute_danger_yes, // 23 + R.string.attribute_wheelchair_yes, // 24 + R.string.attribute_parking_yes, // 25 + R.string.attribute_public_yes, // 26 + R.string.attribute_water_yes, // 27 + R.string.attribute_restrooms_yes, // 28 + R.string.attribute_phone_yes, // 29 + R.string.attribute_picnic_yes, // 30 + R.string.attribute_camping_yes, // 31 + R.string.attribute_bicycles_yes, // 32 + R.string.attribute_motorcycles_yes, // 33 + R.string.attribute_quads_yes, // 34 + R.string.attribute_jeeps_yes, // 35 + R.string.attribute_snowmobiles_yes, // 36 + R.string.attribute_horses_yes, // 37 + R.string.attribute_campfires_yes, // 38 + R.string.attribute_thorn_yes, // 39 + R.string.attribute_stealth_yes, // 40 + R.string.attribute_stroller_yes, // 41 + R.string.attribute_firstaid_yes, // 42 + R.string.attribute_cow_yes, // 43 + R.string.attribute_flashlight_yes, // 44 + R.string.attribute_landf_yes, // 45 + R.string.attribute_rv_yes, // 46 + R.string.attribute_field_puzzle_yes, // 47 + R.string.attribute_uv_yes, // 48 + R.string.attribute_snowshoes_yes, // 49 + R.string.attribute_skiis_yes, // 50 + R.string.attribute_s_tool_yes, // 51 + R.string.attribute_nightcache_yes, // 52 + R.string.attribute_parkngrab_yes, // 53 + R.string.attribute_abandonedbuilding_yes, // 54 + R.string.attribute_hike_short_yes, // 55 + R.string.attribute_hike_med_yes, // 56 + R.string.attribute_hike_long_yes, // 57 + R.string.attribute_fuel_yes, // 58 + R.string.attribute_food_yes, // 59 + R.string.attribute_wirelessbeacon_yes, // 60 + R.string.attribute_partnership_yes, // 61 + R.string.attribute_seasonal_yes, // 62 + R.string.attribute_touristok_yes, // 63 + R.string.attribute_treeclimbing_yes, // 64 + R.string.attribute_frontyard_yes, // 65 + R.string.attribute_teamwork_yes, // 66 + }; + private static final String YES = "_yes"; + private static final String NO = "_no"; + private final Pattern BASENAME_PATTERN = Pattern.compile("^.*attribute_(.*)(_yes|_no)"); + + private Boolean active = null; // for yes/no + private String baseName; // "food", "parkngrab", ... + + public void setActive(boolean active) { + this.active = active; + } + // map GPX-Attribute-Id to baseName + public void setBaseName(int id) { + this.baseName = null; + // get String out of array + if (CACHE_ATTRIBUTES.length <= id) + return; + int stringId = CACHE_ATTRIBUTES[id]; + if (stringId == -1) + return; // id not found + // get text for string + String stringName = null; + try { + stringName = app.getResources().getResourceName(stringId); + } catch (NullPointerException e) { + return; + } + if (stringName == null) + return; + // cut out baseName + Matcher m = BASENAME_PATTERN.matcher(stringName); + if (! m.matches()) + return; + this.baseName = m.group(1); + } + // @return baseName + "_yes" or "_no" e.g. "food_no" or "uv_yes" + public String getInternalId() { + if (baseName == null || active == null) + return null; + return baseName + (active ? YES : NO); + } + } + + protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) { app = appIn; listId = listIdIn; search = searchIn; @@ -278,7 +396,51 @@ public abstract class GPXParser extends FileParser { } }); - // waypoint.cache.difficulty + // waypoint.cache.attributes + // @see issue #299 + + // <groundspeak:attributes> + // <groundspeak:attribute id="32" inc="1">Bicycles</groundspeak:attribute> + // <groundspeak:attribute id="13" inc="1">Available at all times</groundspeak:attribute> + // where inc = 0 => _no, inc = 1 => _yes + // IDs see array CACHE_ATTRIBUTES + final Element gcAttributes = gcCache.getChild(nsGC, "attributes"); + + // waypoint.cache.attribute + final Element gcAttribute = gcAttributes.getChild(nsGC, "attribute"); + + gcAttribute.setStartElementListener(new StartElementListener() { + @Override + public void start(Attributes attrs) { + cacheAttribute = new CacheAttribute(); + try { + if (attrs.getIndex("id") > -1) { + cacheAttribute.setBaseName(Integer.parseInt(attrs.getValue("id"))); + } + if (attrs.getIndex("inc") > -1) { + cacheAttribute.setActive(Integer.parseInt(attrs.getValue("inc")) != 0); + } + } catch (Exception e) { + // nothing + } + } + }); + + gcAttribute.setEndElementListener(new EndElementListener() { + @Override + public void end() { + if (cacheAttribute != null) { + String internalId = cacheAttribute.getInternalId(); + if (internalId != null) { + if (cache.attributes == null) + cache.attributes = new ArrayList<String>(); + cache.attributes.add(internalId); + } + } + } + }); + + // waypoint.cache.difficulty gcCache.getChild(nsGC, "difficulty").setEndTextElementListener(new EndTextElementListener() { @Override @@ -489,16 +651,16 @@ public abstract class GPXParser extends FileParser { } catch (SAXException e) { Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString()); } - return parsed ? search.getCurrentId() : 0l; + return parsed ? search.getCurrentId() : 0L; } private long parse(final File file, final Handler handlerIn) { if (file == null) { - return 0l; + return 0L; } FileInputStream fis = null; - long result = 0l; + long result = 0L; try { fis = new FileInputStream(file); result = parse(fis, handlerIn); @@ -553,12 +715,12 @@ public abstract class GPXParser extends FileParser { public static Long parseGPX(cgeoapplication app, File file, int listId, Handler handler) { cgSearch search = new cgSearch(); - long searchId = 0l; + long searchId = 0L; try { GPXParser parser = new GPX10Parser(app, listId, search); searchId = parser.parse(file, handler); - if (searchId == 0l) { + if (searchId == 0L) { parser = new GPX11Parser(app, listId, search); searchId = parser.parse(file, handler); } diff --git a/src/cgeo/geocaching/files/LocParser.java b/src/cgeo/geocaching/files/LocParser.java index 152293c..fd68fdc 100644 --- a/src/cgeo/geocaching/files/LocParser.java +++ b/src/cgeo/geocaching/files/LocParser.java @@ -144,7 +144,7 @@ public final class LocParser extends FileParser { public static long parseLoc(cgeoapplication app, File file, int listId,
Handler handler) {
cgSearch search = new cgSearch();
- long searchId = 0l;
+ long searchId = 0L;
try {
HashMap<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
diff --git a/src/cgeo/geocaching/geopoint/Geopoint.java b/src/cgeo/geocaching/geopoint/Geopoint.java index 533854b..85149be 100644 --- a/src/cgeo/geocaching/geopoint/Geopoint.java +++ b/src/cgeo/geocaching/geopoint/Geopoint.java @@ -9,7 +9,7 @@ public class Geopoint public static final double deg2rad = Math.PI / 180; public static final double rad2deg = 180 / Math.PI; public static final float erad = 6371.0f; - + private double latitude; private double longitude; @@ -76,7 +76,7 @@ public class Geopoint return this; } - + /** * Set latitude in microdegree. * @@ -113,7 +113,7 @@ public class Geopoint { return latitude; } - + /** * Get latitude in microdegree. * @@ -144,7 +144,7 @@ public class Geopoint return this; } - + /** * Set longitude in microdegree. * @@ -181,7 +181,7 @@ public class Geopoint { return longitude; } - + /** * Get longitude in microdegree. * @@ -268,7 +268,7 @@ public class Geopoint double c = Math.acos(Math.sin(lat2) * Math.sin(lat1) + Math.cos(lat2) * Math.cos(lat1) * Math.cos(lon2 - lon1)); double A = Math.asin(Math.cos(lat2) * Math.sin(lon2 - lon1) / Math.sin(c)); double result = A * rad2deg; - + if (ilat2 > ilat1 && ilon2 > ilon1) { // result don't need change @@ -285,7 +285,7 @@ public class Geopoint { result += 360f; } - + return result; } } @@ -318,7 +318,7 @@ public class Geopoint */ public boolean isEqualTo(Geopoint gp) { - return (null != gp && gp.getLatitude() == latitude && gp.getLongitude() == longitude); + return null != gp && gp.getLatitude() == latitude && gp.getLongitude() == longitude; } /** @@ -330,7 +330,7 @@ public class Geopoint */ public boolean isEqualTo(Geopoint gp, double tolerance) { - return (null != gp && distanceTo(gp) <= tolerance); + return null != gp && distanceTo(gp) <= tolerance; } /** diff --git a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java index 4e0379c..99bf2fd 100644 --- a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java +++ b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java @@ -20,7 +20,7 @@ public abstract class ItemizedOverlayBase implements OverlayBase { private ItemizedOverlayImpl ovlImpl; - public ItemizedOverlayBase(ItemizedOverlayImpl ovlImplIn) { + protected ItemizedOverlayBase(ItemizedOverlayImpl ovlImplIn) { ovlImpl = ovlImplIn; } diff --git a/src/cgeo/geocaching/mapcommon/MapBase.java b/src/cgeo/geocaching/mapcommon/MapBase.java index 1f967a0..1f2d769 100644 --- a/src/cgeo/geocaching/mapcommon/MapBase.java +++ b/src/cgeo/geocaching/mapcommon/MapBase.java @@ -18,7 +18,7 @@ public abstract class MapBase { ActivityImpl mapActivity; - public MapBase(ActivityImpl activity) { + protected MapBase(ActivityImpl activity) { mapActivity = activity; } diff --git a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java index b8d6f09..cb73c75 100644 --- a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java +++ b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java @@ -21,7 +21,7 @@ public class cgOverlayScale implements OverlayBase { private Paint scale = null; private Paint scaleShadow = null; private BlurMaskFilter blur = null; - private float pixelDensity = 0l; + private float pixelDensity = 0L; private double pixels = 0d; private int bottom = 0; private double distance = 0d; diff --git a/src/cgeo/geocaching/mapcommon/cgeomap.java b/src/cgeo/geocaching/mapcommon/cgeomap.java index 9360899..9574661 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; @@ -101,8 +101,8 @@ public class cgeomap extends MapBase { private UsersThread usersThread = null; private DisplayUsersThread displayUsersThread = null; private LoadDetails loadDetailsThread = null; - private volatile long loadThreadRun = 0l; - private volatile long usersThreadRun = 0l; + private volatile long loadThreadRun = 0L; + private volatile long usersThreadRun = 0L; private volatile boolean downloaded = false; // overlays private cgMapOverlay overlayCaches = null; @@ -119,7 +119,7 @@ public class cgeomap extends MapBase { private ProgressDialog waitDialog = null; private int detailTotal = 0; private int detailProgress = 0; - private Long detailProgressTime = 0l; + private Long detailProgressTime = 0L; // views private ImageView myLocSwitch = null; // other things @@ -145,10 +145,9 @@ public class cgeomap extends MapBase { } if (caches != null && cachesCnt > 0) { - title.append(" "); - title.append("["); + title.append(" ["); title.append(caches.size()); - title.append("]"); + title.append(']'); } ActivityMixin.setTitle(activity, title.toString()); @@ -308,7 +307,7 @@ public class cgeomap extends MapBase { waypointTypeIntent = extras.getString("wpttype"); mapStateIntent = extras.getIntArray("mapstate"); - if (searchIdIntent == 0l) { + if (searchIdIntent == 0L) { searchIdIntent = null; } if (latitudeIntent == 0.0) { @@ -746,7 +745,7 @@ public class cgeomap extends MapBase { try { boolean repaintRequired = false; - + if (overlayMyLoc == null && mapView != null) { overlayMyLoc = mapView.createAddPositionOverlay(activity, settings); } @@ -771,11 +770,11 @@ public class cgeomap extends MapBase { } repaintRequired = true; } - + if (repaintRequired) { mapView.repaintRequired(overlayMyLoc); } - + } catch (Exception e) { Log.w(cgSettings.tag, "Failed to update location."); } @@ -942,7 +941,7 @@ public class cgeomap extends MapBase { } catch (Exception e) { Log.w(cgSettings.tag, "cgeomap.LoadTimer.run: " + e.toString()); } - }; + } } } @@ -1024,7 +1023,7 @@ public class cgeomap extends MapBase { } catch (Exception e) { Log.w(cgSettings.tag, "cgeomap.LoadUsersTimer.run: " + e.toString()); } - }; + } } } @@ -1080,24 +1079,14 @@ public class cgeomap extends MapBase { //if in live map and stored caches are found / disables are also shown. if (live && settings.maplive >= 1) { - // I know code is crude, but temporary fix - int i = 0; - boolean excludeMine = settings.excludeMine > 0; - boolean excludeDisabled = settings.excludeDisabled > 0; - - while (i < caches.size()) - { - boolean remove = false; - if ((caches.get(i).found) && (excludeMine)) - remove = true; - if ((caches.get(i).own) && (excludeMine)) - remove = true; - if ((caches.get(i).disabled) && (excludeDisabled)) - remove = true; - if (remove) + final boolean excludeMine = settings.excludeMine > 0; + final boolean excludeDisabled = settings.excludeDisabled > 0; + + for (int i = caches.size() - 1; i >= 0; i--) { + cgCache cache = caches.get(i); + if ((cache.found && excludeMine) || (cache.own && excludeMine) || (cache.disabled && excludeDisabled)) { caches.remove(i); - else - i++; + } } } @@ -1508,10 +1497,10 @@ public class cgeomap extends MapBase { protected boolean working = true; protected boolean stop = false; - protected long centerLat = 0l; - protected long centerLon = 0l; - protected long spanLat = 0l; - protected long spanLon = 0l; + protected long centerLat = 0L; + protected long centerLon = 0L; + protected long spanLat = 0L; + protected long spanLon = 0L; public DoThread(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { centerLat = centerLatIn; @@ -1550,7 +1539,7 @@ public class cgeomap extends MapBase { private Handler handler = null; private ArrayList<String> geocodes = null; private volatile boolean stop = false; - private long last = 0l; + private long last = 0L; public LoadDetails(Handler handlerIn, ArrayList<String> geocodesIn) { handler = handlerIn; diff --git a/src/cgeo/geocaching/sorting/StateComparator.java b/src/cgeo/geocaching/sorting/StateComparator.java new file mode 100644 index 0000000..787af5a --- /dev/null +++ b/src/cgeo/geocaching/sorting/StateComparator.java @@ -0,0 +1,32 @@ +package cgeo.geocaching.sorting; + +import cgeo.geocaching.cgCache; + +/** + * sort caches by state (normal, disabled, archived) + * + */ +public class StateComparator extends AbstractCacheComparator implements + CacheComparator { + + @Override + protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + return true; + } + + @Override + protected int compareCaches(final cgCache cache1, final cgCache cache2) { + return getState(cache1) - getState(cache2); + } + + private static int getState(final cgCache cache) { + if (cache.disabled) { + return 1; + } + if (cache.archived) { + return 2; + } + return 0; + } + +} |
