aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore28
-rw-r--r--cgeo-calendar/res/drawable-hdpi/ic_launcher.pngbin8956 -> 7237 bytes
-rw-r--r--cgeo-calendar/res/drawable-ldpi/ic_launcher.pngbin3256 -> 2875 bytes
-rw-r--r--cgeo-calendar/res/drawable-mdpi/ic_launcher.pngbin4939 -> 4229 bytes
-rw-r--r--cgeo-calendar/res/drawable-xhdpi/ic_launcher.pngbin0 -> 10448 bytes
-rw-r--r--cgeo-calendar/res/values-es/strings.xml1
-rw-r--r--cgeo-calendar/src/cgeo/calendar/AddEntry.java13
-rw-r--r--cgeo-calendar/src/cgeo/calendar/AddEntryLevel14.java11
-rw-r--r--cgeo-contacts/res/drawable-hdpi/cgeo.pngbin6941 -> 7432 bytes
-rw-r--r--cgeo-contacts/res/drawable-ldpi/cgeo.pngbin3018 -> 2887 bytes
-rw-r--r--cgeo-contacts/res/drawable-mdpi/cgeo.pngbin4942 -> 4308 bytes
-rw-r--r--cgeo-contacts/res/drawable-xhdpi/cgeo.pngbin10795 -> 10883 bytes
-rw-r--r--cgeo-contacts/res/values-cs/strings.xml6
-rw-r--r--cgeo-contacts/res/values-de/strings.xml4
-rw-r--r--cgeo-contacts/res/values-es/strings.xml6
-rw-r--r--cgeo-contacts/res/values-it/strings.xml6
-rw-r--r--cgeo-contacts/res/values-nl/strings.xml6
-rw-r--r--cgeo-contacts/res/values-pl/strings.xml6
-rw-r--r--cgeo-contacts/res/values-pt/strings.xml6
-rw-r--r--cgeo-contacts/res/values-sv/strings.xml6
-rwxr-xr-xcrowdin/download8
-rwxr-xr-xcrowdin/globals2
-rwxr-xr-xcrowdin/local-patches14
-rw-r--r--main/.factorypath2
-rw-r--r--main/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--main/.settings/org.eclipse.jdt.ui.prefs5
-rw-r--r--main/AndroidManifest.xml106
-rw-r--r--main/compile-libs/androidannotations-2.7.1.jarbin555665 -> 0 bytes
-rw-r--r--main/compile-libs/androidannotations-3.0.1.jarbin0 -> 617458 bytes
-rw-r--r--main/libs/android-support-v4.jarbin621451 -> 627582 bytes
-rw-r--r--main/libs/androidannotations-api-2.7.1.jarbin61745 -> 0 bytes
-rw-r--r--main/libs/androidannotations-api-3.0.1.jarbin0 -> 87369 bytes
-rw-r--r--main/libs/commons-lang3-3.1.jarbin315805 -> 0 bytes
-rw-r--r--main/libs/commons-lang3-3.1.jar.properties1
-rw-r--r--main/libs/commons-lang3-3.2.1.jarbin0 -> 385091 bytes
-rw-r--r--main/libs/commons-lang3-3.2.1.jar.properties1
-rw-r--r--main/libs/rxjava-android-0.17.0-RC6.jarbin0 -> 30327 bytes
-rw-r--r--main/libs/rxjava-core-0.17.0-RC6.jarbin0 -> 710179 bytes
-rw-r--r--main/libs/src/commons-lang3-3.1-src.zipbin880646 -> 0 bytes
-rw-r--r--main/libs/src/commons-lang3-3.2.1-sources.jarbin0 -> 440579 bytes
-rw-r--r--main/lint.xml3
-rw-r--r--main/proguard-project.txt6
-rw-r--r--main/project/rawimages/c-geo_calendar_icon.svg778
-rw-r--r--main/project/rawimages/c-geo_contacts_icon.svg635
-rw-r--r--main/project/rawimages/cgeo-calendar_ic_512x512.psdbin461979 -> 0 bytes
-rw-r--r--main/project/rawimages/cgeo-calendar_ic_launcher.psdbin386255 -> 0 bytes
-rw-r--r--main/res/layout/livemapinfo.xml7
-rw-r--r--main/res/layout/main_activity.xml17
-rw-r--r--main/res/layout/search_activity.xml8
-rw-r--r--main/res/menu/details_context.xml5
-rw-r--r--main/res/values-cs/strings.xml146
-rw-r--r--main/res/values-da/strings.xml1
-rw-r--r--main/res/values-de/strings.xml232
-rw-r--r--main/res/values-es/strings.xml76
-rw-r--r--main/res/values-fr/strings.xml55
-rw-r--r--main/res/values-hu/strings.xml5
-rw-r--r--main/res/values-it/strings.xml111
-rw-r--r--main/res/values-ja/strings.xml5
-rw-r--r--main/res/values-nb/strings.xml3
-rw-r--r--main/res/values-nl/strings.xml175
-rw-r--r--main/res/values-pl/strings.xml139
-rw-r--r--main/res/values-pt/strings.xml13
-rw-r--r--main/res/values-sk/strings.xml9
-rw-r--r--main/res/values-sl/strings.xml18
-rw-r--r--main/res/values-sv/strings.xml307
-rw-r--r--main/res/values/changelog_master.xml14
-rw-r--r--main/res/values/preference_keys.xml14
-rw-r--r--main/res/values/strings.xml23
-rw-r--r--main/res/xml/preferences.xml69
-rw-r--r--main/res/xml/searchable.xml1
-rw-r--r--main/src/cgeo/calendar/CalendarAddon.java58
-rw-r--r--main/src/cgeo/calendar/ICalendar.java2
-rw-r--r--main/src/cgeo/contacts/IContacts.java2
-rw-r--r--main/src/cgeo/geocaching/AbstractPopupActivity.java2
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java450
-rw-r--r--main/src/cgeo/geocaching/CacheListActivity.java289
-rw-r--r--main/src/cgeo/geocaching/CacheMenuHandler.java55
-rw-r--r--main/src/cgeo/geocaching/CachePopup.java6
-rw-r--r--main/src/cgeo/geocaching/CgeoApplication.java76
-rw-r--r--main/src/cgeo/geocaching/CompassActivity.java5
-rw-r--r--main/src/cgeo/geocaching/CreateShortcutActivity.java10
-rw-r--r--main/src/cgeo/geocaching/DataStore.java182
-rw-r--r--main/src/cgeo/geocaching/DirectionProvider.java92
-rw-r--r--main/src/cgeo/geocaching/EditWaypointActivity.java10
-rw-r--r--main/src/cgeo/geocaching/GeoDataProvider.java148
-rw-r--r--main/src/cgeo/geocaching/Geocache.java47
-rw-r--r--main/src/cgeo/geocaching/ImageSelectActivity.java3
-rw-r--r--main/src/cgeo/geocaching/ImagesActivity.java9
-rw-r--r--main/src/cgeo/geocaching/Intents.java4
-rw-r--r--main/src/cgeo/geocaching/LogCacheActivity.java8
-rw-r--r--main/src/cgeo/geocaching/LogTrackableActivity.java4
-rw-r--r--main/src/cgeo/geocaching/MainActivity.java210
-rw-r--r--main/src/cgeo/geocaching/PocketQueryList.java134
-rw-r--r--main/src/cgeo/geocaching/SearchActivity.java80
-rw-r--r--main/src/cgeo/geocaching/SearchResult.java2
-rw-r--r--main/src/cgeo/geocaching/StaticMapsActivity.java9
-rw-r--r--main/src/cgeo/geocaching/StaticMapsProvider.java4
-rw-r--r--main/src/cgeo/geocaching/StatusFragment.java129
-rw-r--r--main/src/cgeo/geocaching/TrackableActivity.java46
-rw-r--r--main/src/cgeo/geocaching/UsefulAppsActivity.java1
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractActivity.java59
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractListActivity.java23
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java1
-rw-r--r--main/src/cgeo/geocaching/activity/ActivityMixin.java2
-rw-r--r--main/src/cgeo/geocaching/activity/Keyboard.java40
-rw-r--r--main/src/cgeo/geocaching/activity/Progress.java17
-rw-r--r--main/src/cgeo/geocaching/apps/AbstractLocusApp.java7
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java14
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/AbstractRadarApp.java45
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java22
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java28
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/RadarApp.java12
-rw-r--r--main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java2
-rw-r--r--main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java3
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java16
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java41
-rw-r--r--main/src/cgeo/geocaching/connector/UserAction.java10
-rw-r--r--main/src/cgeo/geocaching/connector/capability/FieldNotesCapability.java13
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECApi.java4
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECConnector.java2
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECLogin.java1
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java73
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java10
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCLogin.java15
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java2
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java79
-rw-r--r--main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java114
-rw-r--r--main/src/cgeo/geocaching/connector/gc/SearchHandler.java126
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java5
-rw-r--r--main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java4
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiConnector.java12
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java6
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java16
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java100
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OXGPXParser.java4
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java1
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java4
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java27
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java8
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java4
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java17
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheAttribute.java8
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheListType.java31
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheSize.java37
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheType.java2
-rw-r--r--main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java2
-rw-r--r--main/src/cgeo/geocaching/enumerations/LogType.java15
-rw-r--r--main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java23
-rw-r--r--main/src/cgeo/geocaching/enumerations/StatusCode.java2
-rw-r--r--main/src/cgeo/geocaching/export/FieldNotes.java65
-rw-r--r--main/src/cgeo/geocaching/export/FieldnoteExport.java129
-rw-r--r--main/src/cgeo/geocaching/export/GpxExport.java2
-rw-r--r--main/src/cgeo/geocaching/export/GpxSerializer.java4
-rw-r--r--main/src/cgeo/geocaching/files/GPXParser.java135
-rw-r--r--main/src/cgeo/geocaching/files/LocalStorage.java20
-rw-r--r--main/src/cgeo/geocaching/files/SimpleDirChooser.java4
-rw-r--r--main/src/cgeo/geocaching/filter/DistanceFilter.java2
-rw-r--r--main/src/cgeo/geocaching/filter/FilterUserInterface.java13
-rw-r--r--main/src/cgeo/geocaching/filter/ModifiedFilter.java2
-rw-r--r--main/src/cgeo/geocaching/geopoint/Geopoint.java26
-rw-r--r--main/src/cgeo/geocaching/geopoint/GeopointParser.java36
-rw-r--r--main/src/cgeo/geocaching/geopoint/Viewport.java68
-rw-r--r--main/src/cgeo/geocaching/list/PseudoList.java6
-rw-r--r--main/src/cgeo/geocaching/list/StoredList.java40
-rw-r--r--main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java35
-rw-r--r--main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java2
-rw-r--r--main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java2
-rw-r--r--main/src/cgeo/geocaching/loaders/NextPageGeocacheListLoader.java2
-rw-r--r--main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java4
-rw-r--r--main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java2
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java76
-rw-r--r--main/src/cgeo/geocaching/maps/MapProviderFactory.java2
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleCacheOverlay.java5
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java2
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleMapView.java11
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/ItemizedOverlayImpl.java2
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java7
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlay.java5
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java8
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeCacheOverlay.java5
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java8
-rw-r--r--main/src/cgeo/geocaching/network/HtmlImage.java293
-rw-r--r--main/src/cgeo/geocaching/network/Network.java94
-rw-r--r--main/src/cgeo/geocaching/network/OAuth.java5
-rw-r--r--main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java88
-rw-r--r--main/src/cgeo/geocaching/network/StatusUpdater.java56
-rw-r--r--main/src/cgeo/geocaching/search/AutoCompleteAdapter.java71
-rw-r--r--main/src/cgeo/geocaching/search/SuggestionProvider.java57
-rw-r--r--main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java93
-rw-r--r--main/src/cgeo/geocaching/settings/AbstractClickablePreference.java30
-rw-r--r--main/src/cgeo/geocaching/settings/CheckECCredentialsPreference.java14
-rw-r--r--main/src/cgeo/geocaching/settings/CheckGcCredentialsPreference.java18
-rw-r--r--main/src/cgeo/geocaching/settings/OAuthPreference.java24
-rw-r--r--main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java118
-rw-r--r--main/src/cgeo/geocaching/settings/Settings.java18
-rw-r--r--main/src/cgeo/geocaching/settings/SettingsActivity.java110
-rw-r--r--main/src/cgeo/geocaching/settings/TemplateTextPreference.java2
-rw-r--r--main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java35
-rw-r--r--main/src/cgeo/geocaching/sorting/CacheComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java9
-rw-r--r--main/src/cgeo/geocaching/sorting/DateComparator.java7
-rw-r--r--main/src/cgeo/geocaching/sorting/DifficultyComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/DistanceComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/FindsComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/GeocodeComparator.java13
-rw-r--r--main/src/cgeo/geocaching/sorting/InventoryComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/NameComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/PopularityComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/RatingComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/SizeComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/StateComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/StorageTimeComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/TerrainComparator.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/VisitComparator.java5
-rw-r--r--main/src/cgeo/geocaching/sorting/VoteComparator.java5
-rw-r--r--main/src/cgeo/geocaching/speech/SpeechService.java4
-rw-r--r--main/src/cgeo/geocaching/speech/TextFactory.java2
-rw-r--r--main/src/cgeo/geocaching/twitter/Twitter.java1
-rw-r--r--main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java1
-rw-r--r--main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java2
-rw-r--r--main/src/cgeo/geocaching/ui/CacheDetailsCreator.java21
-rw-r--r--main/src/cgeo/geocaching/ui/EditNoteDialog.java15
-rw-r--r--main/src/cgeo/geocaching/ui/ImagesList.java116
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java4
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/Dialogs.java29
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java13
-rw-r--r--main/src/cgeo/geocaching/utils/CancellableHandler.java16
-rw-r--r--main/src/cgeo/geocaching/utils/CryptUtils.java3
-rw-r--r--main/src/cgeo/geocaching/utils/FileUtils.java27
-rw-r--r--main/src/cgeo/geocaching/utils/GeoDirHandler.java108
-rw-r--r--main/src/cgeo/geocaching/utils/IObserver.java22
-rw-r--r--main/src/cgeo/geocaching/utils/ISubject.java57
-rw-r--r--main/src/cgeo/geocaching/utils/ImageUtils.java2
-rw-r--r--main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java4
-rw-r--r--main/src/cgeo/geocaching/utils/LogTemplateProvider.java4
-rw-r--r--main/src/cgeo/geocaching/utils/MemorySubject.java45
-rw-r--r--main/src/cgeo/geocaching/utils/RunnableWithArgument.java7
-rw-r--r--main/src/cgeo/geocaching/utils/Subject.java76
-rw-r--r--main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java11
-rw-r--r--main/src/cgeo/geocaching/utils/TextUtils.java1
-rw-r--r--main/thirdparty/android/support/v4/app/FragmentListActivity.java4
-rw-r--r--main/thirdparty/com/viewpagerindicator/TitlePageIndicator.java6
-rw-r--r--tests/.settings/org.eclipse.jdt.core.prefs28
-rw-r--r--tests/libs/org.eclipse.jdt.annotation_1.1.0.v20130513-1648.jarbin0 -> 14613 bytes
-rw-r--r--tests/res/raw/gc3t1xg_gsak.gpx310
-rw-r--r--tests/src/cgeo/geocaching/CgeoApplicationTest.java36
-rw-r--r--tests/src/cgeo/geocaching/GeocacheTest.java8
-rw-r--r--tests/src/cgeo/geocaching/SettingsTest.java2
-rw-r--r--tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java24
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java10
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/GCParserTest.java11
-rw-r--r--tests/src/cgeo/geocaching/connector/trackable/GeokretyConnectorTest.java13
-rw-r--r--tests/src/cgeo/geocaching/connector/trackable/TravelBugConnectorTest.java11
-rw-r--r--tests/src/cgeo/geocaching/enumerations/CacheAttributeTest.java3
-rw-r--r--tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java2
-rw-r--r--tests/src/cgeo/geocaching/enumerations/LogTypeTest.java3
-rw-r--r--tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java6
-rw-r--r--tests/src/cgeo/geocaching/export/ExportTest.java6
-rw-r--r--tests/src/cgeo/geocaching/files/GPXParserTest.java23
-rw-r--r--tests/src/cgeo/geocaching/geopoint/GeoPointParserTest.java16
-rw-r--r--tests/src/cgeo/geocaching/geopoint/ViewportTest.java17
-rw-r--r--tests/src/cgeo/geocaching/network/OAuthTest.java8
-rw-r--r--tests/src/cgeo/geocaching/sorting/DistanceComparatorTest.java2
-rw-r--r--tests/src/cgeo/geocaching/utils/LogTemplateProviderTest.java4
-rw-r--r--tests/src/cgeo/geocaching/utils/MemorySubjectTest.java79
266 files changed, 6237 insertions, 3245 deletions
diff --git a/.gitignore b/.gitignore
index 20b6028..0cdff83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,22 @@
+# generated code
bin/
gen/
+annotation_gen/
+
+# vm crash logs
+hs_err_pid*.log
+
+# developer specific settings and credentials
+local.properties
+private.properties
+/crowdin/credentials
+/main/res/values/mapsapikey.xml
+
+# eclipse plugin settings which cannot be shared
+org.moreunit.prefs
+
/main/project/localization/*.missing
/main/project/attributes/drawable-mdpi/
/main/project/attributes/iconlist1res.html
/main/project/settings/drawable-mdpi/
-/main/local.properties
-/main/private.properties
-/main/res/values/mapsapikey.xml
-/tests/local.properties
-/tests/private.properties
-/tests/hs_err_pid*.log
-/cgeo-calendar/local.properties
-/cgeo-calendar/private.properties
-/crowdin/credentials
-.directory
-org.moreunit.prefs
-annotation_gen/
+.directory \ No newline at end of file
diff --git a/cgeo-calendar/res/drawable-hdpi/ic_launcher.png b/cgeo-calendar/res/drawable-hdpi/ic_launcher.png
index 030e1ff..95d97ba 100644
--- a/cgeo-calendar/res/drawable-hdpi/ic_launcher.png
+++ b/cgeo-calendar/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/cgeo-calendar/res/drawable-ldpi/ic_launcher.png b/cgeo-calendar/res/drawable-ldpi/ic_launcher.png
index 4697998..135a15c 100644
--- a/cgeo-calendar/res/drawable-ldpi/ic_launcher.png
+++ b/cgeo-calendar/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/cgeo-calendar/res/drawable-mdpi/ic_launcher.png b/cgeo-calendar/res/drawable-mdpi/ic_launcher.png
index a7720ad..63bcae4 100644
--- a/cgeo-calendar/res/drawable-mdpi/ic_launcher.png
+++ b/cgeo-calendar/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/cgeo-calendar/res/drawable-xhdpi/ic_launcher.png b/cgeo-calendar/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..f08bf5c
--- /dev/null
+++ b/cgeo-calendar/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/cgeo-calendar/res/values-es/strings.xml b/cgeo-calendar/res/values-es/strings.xml
index b27b546..48e41c8 100644
--- a/cgeo-calendar/res/values-es/strings.xml
+++ b/cgeo-calendar/res/values-es/strings.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
+ <string name="app_name">c:geo - calendario (complemento)</string>
<string name="calendars">Calendarios</string>
<string name="event_success">Escondite/Evento añadido al calendario</string>
<string name="event_fail">Error al añadir escondite/evento al calendario</string>
diff --git a/cgeo-calendar/src/cgeo/calendar/AddEntry.java b/cgeo-calendar/src/cgeo/calendar/AddEntry.java
index ce8658d..cdb59d9 100644
--- a/cgeo-calendar/src/cgeo/calendar/AddEntry.java
+++ b/cgeo-calendar/src/cgeo/calendar/AddEntry.java
@@ -30,12 +30,13 @@ class AddEntry extends AbstractAddEntry {
// values
final ContentValues event = new ContentValues();
event.put("calendar_id", calendarId);
- if (entry.getStartTimeMinutes() >= 0) {
- event.put("dtstart", eventDate.getTime() + entry.getStartTimeMinutes() * 60000L);
- }
- else {
- event.put("dtstart", eventDate.getTime() + 43200000); // noon
- event.put("dtend", eventDate.getTime() + 43200000 + 3600000); // + one hour
+ final long eventTime = eventDate.getTime();
+ final int entryStartTimeMinutes = entry.getStartTimeMinutes();
+ if (entryStartTimeMinutes >= 0) {
+ event.put("dtstart", eventTime + entryStartTimeMinutes * 60000L);
+ } else {
+ event.put("dtstart", eventTime); // midnight
+ event.put("dtend", eventTime + 86400000); // + one day
event.put("allDay", 1);
}
event.put("eventTimezone", "UTC");
diff --git a/cgeo-calendar/src/cgeo/calendar/AddEntryLevel14.java b/cgeo-calendar/src/cgeo/calendar/AddEntryLevel14.java
index b6a451e..0ceed67 100644
--- a/cgeo-calendar/src/cgeo/calendar/AddEntryLevel14.java
+++ b/cgeo-calendar/src/cgeo/calendar/AddEntryLevel14.java
@@ -32,11 +32,12 @@ class AddEntryLevel14 extends AbstractAddEntry {
.putExtra("description", description)
.putExtra("hasAlarm", false)
.putExtra("eventTimezone", "UTC");
- if (entry.getStartTimeMinutes() >= 0) {
- intent.putExtra("beginTime", eventDate.getTime() + entry.getStartTimeMinutes() * 60000L);
- }
- else {
- intent.putExtra("beginTime", eventDate.getTime() + 43200000);
+ final long eventTime = eventDate.getTime();
+ final int entryStartTimeMinutes = entry.getStartTimeMinutes();
+ if (entryStartTimeMinutes >= 0) {
+ intent.putExtra("beginTime", eventTime + entryStartTimeMinutes * 60000L);
+ } else {
+ intent.putExtra("beginTime", eventTime);
intent.putExtra("allDay", true);
}
if (entry.getCoords().length() > 0) {
diff --git a/cgeo-contacts/res/drawable-hdpi/cgeo.png b/cgeo-contacts/res/drawable-hdpi/cgeo.png
index 6ac8672..e635d5d 100644
--- a/cgeo-contacts/res/drawable-hdpi/cgeo.png
+++ b/cgeo-contacts/res/drawable-hdpi/cgeo.png
Binary files differ
diff --git a/cgeo-contacts/res/drawable-ldpi/cgeo.png b/cgeo-contacts/res/drawable-ldpi/cgeo.png
index 3dbbd0a..1d8ab34 100644
--- a/cgeo-contacts/res/drawable-ldpi/cgeo.png
+++ b/cgeo-contacts/res/drawable-ldpi/cgeo.png
Binary files differ
diff --git a/cgeo-contacts/res/drawable-mdpi/cgeo.png b/cgeo-contacts/res/drawable-mdpi/cgeo.png
index 126feb3..9bb0cac 100644
--- a/cgeo-contacts/res/drawable-mdpi/cgeo.png
+++ b/cgeo-contacts/res/drawable-mdpi/cgeo.png
Binary files differ
diff --git a/cgeo-contacts/res/drawable-xhdpi/cgeo.png b/cgeo-contacts/res/drawable-xhdpi/cgeo.png
index cea22bc..2122008 100644
--- a/cgeo-contacts/res/drawable-xhdpi/cgeo.png
+++ b/cgeo-contacts/res/drawable-xhdpi/cgeo.png
Binary files differ
diff --git a/cgeo-contacts/res/values-cs/strings.xml b/cgeo-contacts/res/values-cs/strings.xml
new file mode 100644
index 0000000..4bd1597
--- /dev/null
+++ b/cgeo-contacts/res/values-cs/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - Kontakty (doplněk)</string>
+ <string name="contact_not_found">Kontakt s přezdívkou %s nenalezen. Přidej ho nejprve do databáze kontaktů.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-de/strings.xml b/cgeo-contacts/res/values-de/strings.xml
index 0a81a75..9f71385 100644
--- a/cgeo-contacts/res/values-de/strings.xml
+++ b/cgeo-contacts/res/values-de/strings.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
<resources>
-
<string name="app_name">c:geo - Kontakte (Erweiterung)</string>
<string name="contact_not_found">Kontakt mit Alias/Spitzname %s nicht gefunden. Bitte zuerst im Adressbuch hinzufügen.</string>
-
</resources>
-
diff --git a/cgeo-contacts/res/values-es/strings.xml b/cgeo-contacts/res/values-es/strings.xml
new file mode 100644
index 0000000..e593b72
--- /dev/null
+++ b/cgeo-contacts/res/values-es/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - contactos (complemento)</string>
+ <string name="contact_not_found">El contacto con alias %s no se ha encontrado. Primero añádelo a tu aplicación de contactos.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-it/strings.xml b/cgeo-contacts/res/values-it/strings.xml
new file mode 100644
index 0000000..dbe5be1
--- /dev/null
+++ b/cgeo-contacts/res/values-it/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - contacts (add-on)</string>
+ <string name="contact_not_found">Contatto con alias/nickname %s non trovato. Aggiungilo prima nei tuoi contatti.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-nl/strings.xml b/cgeo-contacts/res/values-nl/strings.xml
new file mode 100644
index 0000000..d27d7c6
--- /dev/null
+++ b/cgeo-contacts/res/values-nl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo contacten (plug-in)</string>
+ <string name="contact_not_found">Contact met alias/bijnaam %s niet gevonden. Voeg hem (eerst) toe aan je telefoon-contacten.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-pl/strings.xml b/cgeo-contacts/res/values-pl/strings.xml
new file mode 100644
index 0000000..6d919f0
--- /dev/null
+++ b/cgeo-contacts/res/values-pl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - kontakty (dodatek)</string>
+ <string name="contact_not_found">Kontakt z aliasem/nazwą %s nie został znaleziony. Dodaj go najpierw do swoich kontaktów.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-pt/strings.xml b/cgeo-contacts/res/values-pt/strings.xml
new file mode 100644
index 0000000..22ee733
--- /dev/null
+++ b/cgeo-contacts/res/values-pt/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - contactos (add-on)</string>
+ <string name="contact_not_found">Contacto com apelido/alcunha %s não encontrado. Adicione-o primeiro na sua aplicação de contactos.</string>
+</resources>
diff --git a/cgeo-contacts/res/values-sv/strings.xml b/cgeo-contacts/res/values-sv/strings.xml
new file mode 100644
index 0000000..dbb1d7c
--- /dev/null
+++ b/cgeo-contacts/res/values-sv/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.net-->
+<resources>
+ <string name="app_name">c:geo - Kontakttillägg</string>
+ <string name="contact_not_found">Ingen kontakt med aliaset/smeknamnet %s hittades. Lägg till den i dina kontakter först.</string>
+</resources>
diff --git a/crowdin/download b/crowdin/download
index 89483c5..6a45c83 100755
--- a/crowdin/download
+++ b/crowdin/download
@@ -62,6 +62,14 @@ _do wget "http://api.crowdin.net/api/project/cgeo/download/all.zip?key=${CROWDIN
|| die "crowdin download failed."
_do unzip -o ${ZIPFILE} || die "unzip of ${ZIPFILE} failed."
+# fix unicode entities for ellipsis character
+for f in */*/*values-*/strings.xml; do
+ sed -i 's/&#8230;/…/g' $f
+done
+
+# apply local patches to particular strings
+. "`dirname $0`/local-patches"
+
# check for changes
if [ -z "`git diff`" ]; then
debug "no changes, finishing."
diff --git a/crowdin/globals b/crowdin/globals
index 0efd147..dc2e9c9 100755
--- a/crowdin/globals
+++ b/crowdin/globals
@@ -37,7 +37,7 @@ debug () { echo "`date +%Y-%m-%d.%H:%M:%S` `basename $0`: $@"; }
# use this function for executing commands.
_do () { debug "$@"; eval "$@"; }
-require_tools git curl wget unzip
+require_tools git curl wget unzip sed
git rev-parse --show-toplevel >& /dev/null || die "Please start this script from within a repo. Aborting."
cd "`git rev-parse --show-toplevel`"
diff --git a/crowdin/local-patches b/crowdin/local-patches
new file mode 100755
index 0000000..d671c81
--- /dev/null
+++ b/crowdin/local-patches
@@ -0,0 +1,14 @@
+#
+# This file contains special handlings that must be done on
+# crowdin strings. For example, some sentences must get a
+# ignore-typo flag so that lint does not give a false
+# positive.
+#
+# All the fixes should be idempotent so that this script can be applied
+# to the fixed version as well.
+
+# Fix a lint confusion between Portuguese word "com" and "geocaching.com"
+# name, which can be flagged as a repetition of the same word.
+
+sed -i -e '/geocaching\.com com/s/\(<string name="[^"]*"\)>/\1 tools:ignore="Typos">/' \
+ main/res/values-pt/strings.xml
diff --git a/main/.factorypath b/main/.factorypath
index f18f942..323bc61 100644
--- a/main/.factorypath
+++ b/main/.factorypath
@@ -1,4 +1,4 @@
<factorypath>
<factorypathentry kind="WKSPJAR" id="/cgeo/libs/butterknife-4.0.1.jar" enabled="true" runInBatchMode="false"/>
- <factorypathentry kind="WKSPJAR" id="/cgeo/compile-libs/androidannotations-2.7.1.jar" enabled="true" runInBatchMode="false"/>
+ <factorypathentry kind="WKSPJAR" id="/cgeo/compile-libs/androidannotations-3.0.1.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
diff --git a/main/.settings/org.eclipse.jdt.core.prefs b/main/.settings/org.eclipse.jdt.core.prefs
index 3e9e8a8..2fc1133 100644
--- a/main/.settings/org.eclipse.jdt.core.prefs
+++ b/main/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
@@ -83,7 +83,7 @@ org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
@@ -192,7 +192,7 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
diff --git a/main/.settings/org.eclipse.jdt.ui.prefs b/main/.settings/org.eclipse.jdt.ui.prefs
index 92e2c88..a80d8c1 100644
--- a/main/.settings/org.eclipse.jdt.ui.prefs
+++ b/main/.settings/org.eclipse.jdt.ui.prefs
@@ -1,11 +1,14 @@
-#Tue Feb 21 06:54:46 CET 2012
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_cgeo
formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=cgeo;com;org;android;java;javax;
+org.eclipse.jdt.ui.keywordthis=false
org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.overrideannotation=true
org.eclipse.jdt.ui.staticondemandthreshold=99
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
diff --git a/main/AndroidManifest.xml b/main/AndroidManifest.xml
index 1884a9b..d83f2b3 100644
--- a/main/AndroidManifest.xml
+++ b/main/AndroidManifest.xml
@@ -111,8 +111,8 @@
android:name=".twitter.TwitterAuthorizationActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/auth_twitter"
- android:windowSoftInputMode="stateHidden"
- android:launchMode="singleTask" >
+ android:launchMode="singleTask"
+ android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -142,11 +142,11 @@
android:label="@string/search_address_result"
android:windowSoftInputMode="stateHidden" >
</activity>
- <activity
+ <activity
android:name=".settings.SettingsActivity"
+ android:configChanges="keyboardHidden|orientation"
android:label="@string/settings_titlebar"
- android:theme="@style/settings"
- android:configChanges="keyboardHidden|orientation" >
+ android:theme="@style/settings" >
</activity>
<activity
android:name=".CacheListActivity"
@@ -308,6 +308,8 @@
android:name="cgeo.geocaching.TrackableActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name" >
+
+ <!-- TravelBug URL via coord.info redirection -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -326,6 +328,19 @@
<category android:name="android.intent.category.BROWSABLE" />
<data
+ android:host="www.coord.info"
+ android:pathPrefix="/TB"
+ android:scheme="http" />
+ </intent-filter>
+
+ <!-- TravelBug URL tracking page -->
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data
android:host="geocaching.com"
android:pathPrefix="/track/details.aspx"
android:scheme="http" />
@@ -341,6 +356,56 @@
android:pathPrefix="/track/details.aspx"
android:scheme="http" />
</intent-filter>
+
+ <!-- GeoKrety URLs -->
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data
+ android:host="geokrety.org"
+ android:pathPrefix="/konkret.php"
+ android:scheme="http" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data
+ android:host="www.geokrety.org"
+ android:pathPrefix="/konkret.php"
+ android:scheme="http" />
+ </intent-filter>
+
+ <!--
+ Geokrety QR code URLs, not yet implemented
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data
+ android:host="geokrety.org"
+ android:pathPrefix="/m/qr.php"
+ android:scheme="http" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data
+ android:host="www.geokrety.org"
+ android:pathPrefix="/m/qr.php"
+ android:scheme="http" />
+ </intent-filter>
+ -->
</activity>
<activity
android:name=".CompassActivity"
@@ -358,10 +423,6 @@
android:label="@string/map_file_select_title" >
</activity>
- <provider
- android:name=".apps.LocusDataStorageProvider"
- android:authorities="cgeo.geocaching.apps.locusdatastorageprovider" />
-
<activity
android:name="WaypointPopup"
android:configChanges="keyboardHidden|orientation"
@@ -387,8 +448,8 @@
android:name=".connector.oc.OCDEAuthorizationActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name"
- android:windowSoftInputMode="stateHidden"
- android:launchMode="singleTask">
+ android:launchMode="singleTask"
+ android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -405,8 +466,8 @@
android:name=".connector.oc.OCPLAuthorizationActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name"
- android:windowSoftInputMode="stateHidden"
- android:launchMode="singleTask">
+ android:launchMode="singleTask"
+ android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -421,12 +482,23 @@
</activity>
<activity
android:name=".CreateShortcutActivity"
- android:label="@string/create_shortcut" >
+ android:label="@string/cgeo_shortcut" >
<intent-filter>
- <action android:name="android.intent.action.CREATE_SHORTCUT"/>
- <category android:name="android.intent.category.DEFAULT"/>
+ <action android:name="android.intent.action.CREATE_SHORTCUT" />
+
+ <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <!-- provide enhanced meta data for caches (and waypoints) when invoking Locus from c:geo -->
+ <provider
+ android:name=".apps.LocusDataStorageProvider"
+ android:authorities="cgeo.geocaching.apps.locusdatastorageprovider" />
+
+ <!-- search suggestions for the search bar at the top -->
+ <provider
+ android:name=".search.SuggestionProvider"
+ android:authorities="cgeo.geocaching.search.SuggestionProvider" />
</application>
-</manifest>
+
+</manifest> \ No newline at end of file
diff --git a/main/compile-libs/androidannotations-2.7.1.jar b/main/compile-libs/androidannotations-2.7.1.jar
deleted file mode 100644
index 5fb9634..0000000
--- a/main/compile-libs/androidannotations-2.7.1.jar
+++ /dev/null
Binary files differ
diff --git a/main/compile-libs/androidannotations-3.0.1.jar b/main/compile-libs/androidannotations-3.0.1.jar
new file mode 100644
index 0000000..4c96d6c
--- /dev/null
+++ b/main/compile-libs/androidannotations-3.0.1.jar
Binary files differ
diff --git a/main/libs/android-support-v4.jar b/main/libs/android-support-v4.jar
index 9056828..96644ed 100644
--- a/main/libs/android-support-v4.jar
+++ b/main/libs/android-support-v4.jar
Binary files differ
diff --git a/main/libs/androidannotations-api-2.7.1.jar b/main/libs/androidannotations-api-2.7.1.jar
deleted file mode 100644
index a829474..0000000
--- a/main/libs/androidannotations-api-2.7.1.jar
+++ /dev/null
Binary files differ
diff --git a/main/libs/androidannotations-api-3.0.1.jar b/main/libs/androidannotations-api-3.0.1.jar
new file mode 100644
index 0000000..90bfe7a
--- /dev/null
+++ b/main/libs/androidannotations-api-3.0.1.jar
Binary files differ
diff --git a/main/libs/commons-lang3-3.1.jar b/main/libs/commons-lang3-3.1.jar
deleted file mode 100644
index a85e539..0000000
--- a/main/libs/commons-lang3-3.1.jar
+++ /dev/null
Binary files differ
diff --git a/main/libs/commons-lang3-3.1.jar.properties b/main/libs/commons-lang3-3.1.jar.properties
deleted file mode 100644
index adbaad3..0000000
--- a/main/libs/commons-lang3-3.1.jar.properties
+++ /dev/null
@@ -1 +0,0 @@
-src=src/commons-lang3-3.1-src.zip \ No newline at end of file
diff --git a/main/libs/commons-lang3-3.2.1.jar b/main/libs/commons-lang3-3.2.1.jar
new file mode 100644
index 0000000..6bf4f93
--- /dev/null
+++ b/main/libs/commons-lang3-3.2.1.jar
Binary files differ
diff --git a/main/libs/commons-lang3-3.2.1.jar.properties b/main/libs/commons-lang3-3.2.1.jar.properties
new file mode 100644
index 0000000..7a8b7da
--- /dev/null
+++ b/main/libs/commons-lang3-3.2.1.jar.properties
@@ -0,0 +1 @@
+src=src/commons-lang3-3.2.1-sources.jar \ No newline at end of file
diff --git a/main/libs/rxjava-android-0.17.0-RC6.jar b/main/libs/rxjava-android-0.17.0-RC6.jar
new file mode 100644
index 0000000..32c46a0
--- /dev/null
+++ b/main/libs/rxjava-android-0.17.0-RC6.jar
Binary files differ
diff --git a/main/libs/rxjava-core-0.17.0-RC6.jar b/main/libs/rxjava-core-0.17.0-RC6.jar
new file mode 100644
index 0000000..33b8d4b
--- /dev/null
+++ b/main/libs/rxjava-core-0.17.0-RC6.jar
Binary files differ
diff --git a/main/libs/src/commons-lang3-3.1-src.zip b/main/libs/src/commons-lang3-3.1-src.zip
deleted file mode 100644
index 13010f4..0000000
--- a/main/libs/src/commons-lang3-3.1-src.zip
+++ /dev/null
Binary files differ
diff --git a/main/libs/src/commons-lang3-3.2.1-sources.jar b/main/libs/src/commons-lang3-3.2.1-sources.jar
new file mode 100644
index 0000000..efe36e8
--- /dev/null
+++ b/main/libs/src/commons-lang3-3.2.1-sources.jar
Binary files differ
diff --git a/main/lint.xml b/main/lint.xml
index a420bfa..a8e2ddf 100644
--- a/main/lint.xml
+++ b/main/lint.xml
@@ -6,6 +6,9 @@
<issue id="ExportedContentProvider" severity="ignore" />
<issue id="InvalidPackage" severity="ignore" />
<issue id="MissingTranslation" severity="ignore" />
+ <issue id="MissingQuantity">
+ <ignore path="res/values-pl/strings.xml" />
+ </issue>
<issue id="Registered" severity="ignore" />
<issue id="UnusedResources">
<ignore path="res/drawable-mdpi/attribute_maintenance.png" />
diff --git a/main/proguard-project.txt b/main/proguard-project.txt
index 03ef6b3..bb064b9 100644
--- a/main/proguard-project.txt
+++ b/main/proguard-project.txt
@@ -13,6 +13,11 @@
# apache.commons.collections has some bean related collections, which are undefined in Android
-dontwarn java.beans.*
+# rxjava includes references to the test frameworks within their class files
+-dontwarn org.mockito.**
+-dontwarn org.junit.**
+-dontwarn org.robolectric.**
+
#-dontnote org.apache.commons.logging.**
-keep public class cgeo.geocaching.*
@@ -23,6 +28,7 @@
-keep class ch.boye.httpclientandroidlib.client.HttpClient { *; }
-dontnote ch.boye.httpclientandroidlib.**
-dontwarn ch.boye.httpclientandroidlib.impl.auth.NegotiateScheme
+-dontwarn org.springframework.**
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
diff --git a/main/project/rawimages/c-geo_calendar_icon.svg b/main/project/rawimages/c-geo_calendar_icon.svg
new file mode 100644
index 0000000..370dfbd
--- /dev/null
+++ b/main/project/rawimages/c-geo_calendar_icon.svg
@@ -0,0 +1,778 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2985"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ width="512"
+ height="512"
+ sodipodi:docname="c-geo_contacts_icon.svg"
+ inkscape:export-filename=""
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <metadata
+ id="metadata2991">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs2989">
+ <linearGradient
+ id="linearGradient6127">
+ <stop
+ style="stop-color:#ec781b;stop-opacity:1;"
+ offset="0"
+ id="stop6129" />
+ <stop
+ style="stop-color:#e14218;stop-opacity:1;"
+ offset="1"
+ id="stop6131" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4555">
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0"
+ id="stop4557" />
+ <stop
+ style="stop-color:#505050;stop-opacity:1;"
+ offset="1"
+ id="stop4559" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3837">
+ <stop
+ style="stop-color:#fbf9d4;stop-opacity:1;"
+ offset="0"
+ id="stop3839" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3841" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3936">
+ <stop
+ style="stop-color:#f7991d;stop-opacity:1;"
+ offset="0"
+ id="stop3938" />
+ <stop
+ style="stop-color:#f8b339;stop-opacity:1;"
+ offset="1"
+ id="stop3940" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3928">
+ <stop
+ id="stop3930"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.12849163;" />
+ <stop
+ id="stop3932"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.0726257;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3863">
+ <stop
+ style="stop-color:#ffc34a;stop-opacity:1;"
+ offset="0"
+ id="stop3865" />
+ <stop
+ style="stop-color:#f9a62f;stop-opacity:1;"
+ offset="1"
+ id="stop3867" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3801">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1;"
+ offset="0"
+ id="stop3803" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3805" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3890">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3892" />
+ <stop
+ id="stop3900"
+ offset="0.29212967"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3898"
+ offset="0.35852277"
+ style="stop-color:#d8dada;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d8dada;stop-opacity:1;"
+ offset="1"
+ id="stop3894" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3864">
+ <stop
+ style="stop-color:#aad04a;stop-opacity:1;"
+ offset="0"
+ id="stop3866" />
+ <stop
+ id="stop3872"
+ offset="0.29795828"
+ style="stop-color:#cfdc8d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#98bc40;stop-opacity:1;"
+ offset="0.36036199"
+ id="stop3882" />
+ <stop
+ style="stop-color:#48873e;stop-opacity:1;"
+ offset="1"
+ id="stop3868" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3838">
+ <stop
+ style="stop-color:#61b647;stop-opacity:1;"
+ offset="0"
+ id="stop3840" />
+ <stop
+ style="stop-color:#92c746;stop-opacity:1;"
+ offset="1"
+ id="stop3842" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3828">
+ <stop
+ id="stop3830"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.13333334;" />
+ <stop
+ id="stop3832"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.11111111;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3796">
+ <stop
+ style="stop-color:#000000;stop-opacity:0.05555556;"
+ offset="0"
+ id="stop3798" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.10555556;"
+ offset="1"
+ id="stop3800" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3796"
+ id="linearGradient3802"
+ x1="15.959242"
+ y1="343.29277"
+ x2="176.26119"
+ y2="343.29277"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3796"
+ id="linearGradient3810"
+ x1="335.7388"
+ y1="344.35822"
+ x2="496.04077"
+ y2="344.35822"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="linearGradient3880"
+ x1="66.473442"
+ y1="197.85721"
+ x2="453.37692"
+ y2="197.85721"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3890"
+ id="linearGradient3896"
+ x1="70.62744"
+ y1="258.14891"
+ x2="435.78817"
+ y2="258.14891"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter3916"
+ x="-0.73785931"
+ width="2.4757186"
+ y="-0.25739279"
+ height="1.5147856">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="5.7505801"
+ id="feGaussianBlur3918" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3838"
+ id="radialGradient3922"
+ cx="283.49646"
+ cy="-10.861603"
+ fx="283.49646"
+ fy="-10.861603"
+ r="193.19952"
+ gradientTransform="matrix(-0.66393007,1.0294724,-1.0210616,-0.65850585,497.86851,-252.56237)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3801"
+ id="linearGradient3807"
+ x1="175.76119"
+ y1="344.35821"
+ x2="336.23881"
+ y2="344.35821"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3869"
+ x1="39.90625"
+ y1="351.5625"
+ x2="175.7036"
+ y2="351.5625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3877"
+ x1="39.90625"
+ y1="411.14062"
+ x2="175.75117"
+ y2="411.14062"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3885"
+ x1="39.90625"
+ y1="294.22113"
+ x2="175.74925"
+ y2="294.22113"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3928"
+ id="linearGradient3934"
+ gradientUnits="userSpaceOnUse"
+ x1="335.7388"
+ y1="344.35822"
+ x2="496.04077"
+ y2="344.35822" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3942"
+ x1="336.25"
+ y1="304.70312"
+ x2="472.1875"
+ y2="304.70312"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3950"
+ x1="336.43512"
+ y1="373.8125"
+ x2="472.1875"
+ y2="373.8125"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3958"
+ x1="336.24496"
+ y1="420.28125"
+ x2="472.1875"
+ y2="420.28125"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3966"
+ x1="336.25"
+ y1="459.6875"
+ x2="471.8985"
+ y2="459.6875"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3837"
+ id="linearGradient3843"
+ x1="72.743576"
+ y1="272.0433"
+ x2="73.038445"
+ y2="196.93991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4.1012061,5.4616772)" />
+ <filter
+ id="filter4143"
+ style="color-interpolation-filters:sRGB;"
+ inkscape:label="Drop Shadow">
+ <feFlood
+ id="feFlood4145"
+ flood-opacity="0.5"
+ flood-color="rgb(255,255,255)"
+ result="flood" />
+ <feComposite
+ in2="SourceGraphic"
+ id="feComposite4147"
+ in="flood"
+ operator="in"
+ result="composite1" />
+ <feGaussianBlur
+ id="feGaussianBlur4149"
+ in="composite"
+ stdDeviation="0.7"
+ result="blur" />
+ <feOffset
+ id="feOffset4151"
+ dx="1.5"
+ dy="0"
+ result="offset" />
+ <feComposite
+ in2="offset"
+ id="feComposite4153"
+ in="SourceGraphic"
+ operator="over"
+ result="fbSourceGraphic" />
+ <feColorMatrix
+ result="fbSourceGraphicAlpha"
+ in="fbSourceGraphic"
+ values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
+ id="feColorMatrix4297" />
+ <feFlood
+ id="feFlood4299"
+ flood-opacity="0.4"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ in="fbSourceGraphic" />
+ <feComposite
+ id="feComposite4301"
+ in2="fbSourceGraphic"
+ in="flood"
+ operator="in"
+ result="composite1" />
+ <feGaussianBlur
+ id="feGaussianBlur4303"
+ in="composite"
+ stdDeviation="0.8"
+ result="blur" />
+ <feOffset
+ id="feOffset4305"
+ dx="0.4"
+ dy="-2.5"
+ result="offset" />
+ <feComposite
+ id="feComposite4307"
+ in2="offset"
+ in="fbSourceGraphic"
+ operator="over"
+ result="composite2" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient4565"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6127"
+ id="radialGradient6133"
+ cx="120.81452"
+ cy="380.25443"
+ fx="120.81452"
+ fy="380.25443"
+ r="155.75519"
+ gradientTransform="matrix(0.62519145,-0.4100565,0.49214634,0.75034946,-161.40245,178.54198)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6310"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6314"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6316"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.91194349,0,11.919778)"
+ cx="165.90219"
+ cy="135.3651"
+ fx="165.90219"
+ fy="135.3651"
+ r="109.14613" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1058"
+ id="namedview2987"
+ showgrid="false"
+ inkscape:zoom="0.6138847"
+ inkscape:cx="-122.80069"
+ inkscape:cy="131.43587"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2985"
+ inkscape:snap-bbox="false"
+ inkscape:snap-nodes="true"
+ inkscape:bbox-nodes="false"
+ inkscape:bbox-paths="false"
+ inkscape:object-nodes="true"
+ inkscape:object-paths="true"
+ inkscape:snap-global="false" />
+ <path
+ style="fill:#000000;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:0.7062937"
+ d="m 22.337543,475.26062 0,28.21584 159.595867,-8.22962 161.06544,7.34788 159.00804,-7.34788 0,-272.16532 -57.31343,-5.29048 z"
+ id="path3812"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 16.459242,494.95293 0,-303.32032 220.436278,22.92537 102.87027,-21.74971 155.77497,14.69575 0,272.16533 -159.30195,16.45924 -160.47762,-15.87141 z"
+ id="path2998"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3869);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 39.90625 379.59375 L 100.46875 348.9375 L 39.90625 323.53125 L 39.90625 379.59375 z "
+ id="path3022" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 447.71875 L 175.75 380.46875 L 175.75 455.875 L 175.8125 455.875 L 335.84375 471.6875 L 336.25 471.65625 L 336.25 447.71875 z "
+ id="path3913" />
+ <path
+ style="fill:url(#linearGradient3966);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 447.71875 L 336.25 471.65625 L 382.53125 467.125 L 336.25 447.71875 z "
+ id="path3824" />
+ <path
+ style="fill:url(#linearGradient3877);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 175.75118 380.46593 L 110.4375 353.09375 L 39.90625 388.8125 L 39.90625 469.1875 L 175.75059 455.88106 "
+ id="path3020" />
+ <path
+ style="fill:url(#linearGradient3958);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 336.24497 437.85561 L 401.0625 465.3125 L 472.1875 458.375 L 472.1875 411.65625 L 472.1875 411.65625 L 401.53125 375.25 L 336.24729 403.39996 "
+ id="path3836" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.24729 403.39996 L 295.9375 420.78125 L 336.24497 437.85561 "
+ id="path3018" />
+ <path
+ style="fill:url(#linearGradient3950);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 472.1875 344.78125 L 410.84375 371.25 L 472.1875 402.84375 L 472.1875 344.78125 z "
+ id="path3016" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 215.5 L 231.9375 238.90625 L 175.75 232.9375 L 175.75 369.90625 L 285.375 416.34375 L 336.25 394.1875 L 336.25 215.5 z "
+ id="path3918" />
+ <path
+ style="fill:url(#linearGradient3942);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 215.5 L 336.25 394.1875 L 472.1875 334.96875 L 472.1875 229.34375 L 337.5 215.21875 L 336.25 215.5 z "
+ id="path3831" />
+ <path
+ style="fill:url(#linearGradient3885);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 175.74925 232.94454 L 39.90625 218.53125 L 39.90625 312.375 L 175.74798 369.91102 "
+ id="path3002" />
+ <path
+ style="fill:url(#linearGradient3807);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 336.23881,496.12859 -160.47762,-15.87141 0,-272.05717 160.47762,-15.61218 z"
+ id="path3928"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3934);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 495.54076,479.66935 -159.30195,16.45924 0,-303.54076 159.30195,14.91619 z"
+ id="path3026"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3802);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 16.459242,494.95293 159.301948,-14.69575 0,-272.05717 -159.301948,-16.5674 z"
+ id="path3024"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.39768341;stroke:none"
+ d="m 442.88428,146.84389 23.48471,20.36727 c 2.79219,2.93915 2.97845,9.95135 1.03915,18.08115 l -10.39147,31.79789 c -2.64524,4.8496 -9.97581,7.27402 -9.97581,7.27402 0,0 2.60526,7.16885 1.87047,11.43062 L 431.03801,303.54719 211.9859,415.98286 c -4.40873,2.49828 -13.14978,2.5487 -15.79502,-0.83132 L 89.158777,293.57139 86.041338,228.93647 z"
+ id="path3924"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:#5c5d5d;fill-opacity:1;stroke:none"
+ d="m 423.82549,175.46728 c 9.40528,3.52698 10.28702,11.16877 10.58094,18.51665 l -17.6349,67.60046 -215.73364,110.51205 c -13.2323,6.03571 -18.60274,3.52699 -24.10104,-3.23306 L 74.360505,252.1791 69.657865,181.93341 c -0.207829,-7.48186 9.405281,-12.34443 9.405281,-12.34443 z"
+ id="path3920"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="fill:url(#linearGradient3896);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 435.28817,168.41332 -18.81056,76.41791 -220.73019,109.63031 c -6.23488,2.07829 -10.747,1.83787 -14.69576,-1.17566 L 77.887486,234.5442 71.12744,160.47761 z"
+ id="path3884"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:#868786;fill-opacity:1;stroke:none"
+ d="m 452.87691,130.92395 c 1.17566,3.96786 -9.35911,40.28156 -9.35911,40.28156 -2.49395,7.58577 -8.6705,10.28703 -8.6705,10.28703 L 201.3318,287.88978 c -7.17011,2.90961 -14.01254,1.62667 -16.45924,-1.0287 L 69.36395,171.64638 c -2.390037,-3.32527 -2.351321,-12.93226 -2.351321,-12.93226 z"
+ id="path3818"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:url(#linearGradient3880);fill-opacity:1;stroke:none"
+ d="m 452.87691,130.92395 -10.53477,36.60762 c -1.36085,4.47005 -5.29048,6.17222 -5.29048,6.17222 l -235.13203,107.5729 c -10.70321,3.94876 -16.16532,-1.17566 -16.16532,-1.17566 L 69.657865,165.18025 c -3.11744,-2.90961 -2.645236,-6.46613 -2.645236,-6.46613 0,0 -1.053122,-22.11238 -0.03919,-45.77105 z"
+ id="path3816"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffd0;fill-opacity:0.94405589;stroke:none;filter:url(#filter3916)"
+ id="path3902"
+ sodipodi:cx="185.59158"
+ sodipodi:cy="226.65034"
+ sodipodi:rx="9.3523197"
+ sodipodi:ry="26.809982"
+ d="m 194.9439,226.65034 a 9.3523197,26.809982 0 1 1 -18.70464,0 9.3523197,26.809982 0 1 1 18.70464,0 z"
+ transform="matrix(0.88331111,0,0,1.0869978,29.761821,-12.444045)" />
+ <path
+ style="fill:url(#radialGradient3922);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 327.42135,24.101033 452.04133,125.79564 c 3.52698,4.70264 -1.46957,7.64179 -1.46957,7.64179 l -246.00689,99.93111 c -5.77133,2.79957 -11.57831,0.83438 -14.69575,-1.76349 L 70.53961,121.68083 c -10.580941,-12.05052 5.29047,-17.04708 5.29047,-17.04708 L 311.25603,23.513203 c 9.40528,-3.820896 16.16532,0.58783 16.16532,0.58783 z"
+ id="path3814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <g
+ transform="matrix(1.0487801,-0.41271929,0.76389884,0.65287682,0,0)"
+ style="font-size:27.52445984px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3843);fill-opacity:1;stroke:none;filter:url(#filter4143);font-family:'232MKSDRoundMedium';-inkscape-font-specification:'232MKSDRoundMedium'"
+ id="text3833">
+ <path
+ d="m 9.8964838,251.44327 c -1.6511043,3.04006 -3.9467671,5.43501 -6.8869951,7.18485 -2.94029722,1.74985 -6.1280177,2.62477 -9.5631709,2.62477 l -0.3961345,0 c -5.1527923,0 -9.5621783,-1.81637 -13.2281713,-5.44912 -3.666016,-3.63274 -5.499018,-8.02549 -5.499012,-13.17828 l 0,-20.71088 c -6e-6,-5.15071 1.832996,-9.55959 5.499012,-13.22666 3.665993,-3.66696 8.075379,-5.50046 13.2281713,-5.50052 l 0.3961345,0 c 3.3686269,6e-5 6.52308417,0.87548 9.4633813,2.62628 2.9402281,1.75091 5.2358908,4.1131 6.8869951,7.08658 0.3971008,0.72579 0.5956718,1.51805 0.5957138,2.3768 -4.2e-5,1.3205 -0.4793342,2.46001 -1.4378777,3.41855 -0.9586246,0.95863 -2.0981402,1.43792 -3.4185501,1.43788 -1.9151893,4e-5 -3.3354259,-0.85875 -4.2607139,-2.57639 -1.71762205,-3.10451 -4.3272689,-4.6568 -7.8289485,-4.65684 l -0.3961345,0 c -2.4433557,4e-5 -4.5404473,0.87497 -6.2912813,2.62477 -1.750871,1.74988 -2.626297,3.87974 -2.626281,6.38955 l 0,20.71088 c -1.6e-5,2.44335 0.87541,4.54045 2.626281,6.29129 1.750834,1.75086 3.8479256,2.62629 6.2912813,2.62628 l 0.3961345,0 c 3.5016796,1e-5 6.11132645,-1.58554 7.8289485,-4.75664 0.925288,-1.71758 2.3455246,-2.57637 4.2607139,-2.57639 1.3869363,2e-5 2.559211,0.47881 3.5168278,1.43637 0.957535,0.95759 1.436323,2.13087 1.436366,3.51985 -4.3e-5,0.79228 -0.197606,1.55128 -0.5926902,2.27702 z"
+ style="font-size:99.08805847px"
+ id="path4310" />
+ <path
+ d="m 34.109071,221.22213 c -1.8e-5,1.58458 -0.577588,2.95492 -1.732711,4.11103 -1.155155,1.15619 -2.526001,1.73426 -4.112541,1.73423 -1.584549,3e-5 -2.954891,-0.57804 -4.11103,-1.73423 -1.156155,-1.15611 -1.734228,-2.52645 -1.734222,-4.11103 -6e-6,-1.65102 0.578067,-3.03799 1.734222,-4.16092 1.156139,-1.12284 2.526481,-1.68428 4.11103,-1.68433 1.58654,5e-5 2.957386,0.56149 4.112541,1.68433 1.155123,1.12293 1.732693,2.5099 1.732711,4.16092 z m 0,28.53681 c -1.8e-5,1.65107 -0.577588,3.03855 -1.732711,4.16244 -1.155155,1.12389 -2.526001,1.68584 -4.112541,1.68584 -1.584549,0 -2.954891,-0.56195 -4.11103,-1.68584 -1.156155,-1.12389 -1.734228,-2.51137 -1.734222,-4.16244 -6e-6,-1.58453 0.578067,-2.95487 1.734222,-4.11103 1.156139,-1.15613 2.526481,-1.73421 4.11103,-1.73422 1.58654,1e-5 2.957386,0.57809 4.112541,1.73422 1.155123,1.15616 1.732693,2.5265 1.732711,4.11103 z"
+ style="font-size:99.08805847px"
+ id="path4312" />
+ <path
+ d="m 83.876868,261.8486 c -4.3e-5,5.15277 -1.816918,9.56215 -5.450629,13.22817 -3.633788,3.66599 -8.027046,5.499 -13.179788,5.49902 l -0.396135,0 c -3.435203,-2e-5 -6.622419,-0.89158 -9.561659,-2.67467 -2.93927,-1.78312 -5.234428,-4.16144 -6.885483,-7.13496 -0.39715,-0.72575 -0.595721,-1.51802 -0.595714,-2.3768 -7e-6,-1.32247 0.478781,-2.46249 1.436366,-3.42007 0.957567,-0.95758 2.097586,-1.43636 3.420062,-1.43636 1.981666,0 3.435166,0.85879 4.360504,2.57639 1.651045,3.10455 4.259684,4.65683 7.825924,4.65684 l 0.396135,0 c 2.445321,-1e-5 4.542917,-0.87543 6.292793,-2.62628 1.749813,-1.75086 2.624735,-3.84795 2.624769,-6.29128 l 0,-2.57638 c -3.4e-5,-0.33062 -0.164334,-0.4294 -0.4929,-0.29635 -2.642944,1.38698 -5.451162,2.08046 -8.424662,2.08046 l -0.396135,0 c -5.152792,0 -9.545546,-1.833 -13.178276,-5.49901 -3.632753,-3.666 -5.449124,-8.07538 -5.449118,-13.22817 l 0,-20.11517 c -6e-6,-5.15273 1.816365,-9.56211 5.449118,-13.22817 3.63273,-3.66595 8.025484,-5.49895 13.178276,-5.49901 l 0.396135,0 c 5.152742,6e-5 9.546,1.83306 13.179788,5.49901 3.633711,3.66606 5.450586,8.07544 5.450629,13.22817 z m -9.712855,-19.51945 0,-20.11517 c -3.4e-5,-2.50982 -0.874956,-4.64017 -2.624769,-6.39107 -1.749876,-1.75081 -3.847472,-2.62623 -6.292793,-2.62628 l -0.396135,0 c -2.443356,5e-5 -4.540447,0.87547 -6.291281,2.62628 -1.750871,1.7509 -2.626297,3.88125 -2.626281,6.39107 l 0,20.11517 c -1.6e-5,2.44335 0.87541,4.54044 2.626281,6.29128 1.750834,1.75087 3.847925,2.62629 6.291281,2.62628 l 0.396135,0 c 2.445321,1e-5 4.542917,-0.87541 6.292793,-2.62628 1.749813,-1.75084 2.624735,-3.84793 2.624769,-6.29128 z"
+ style="font-size:99.08805847px"
+ id="path4314" />
+ <path
+ d="m 133.61443,232.22016 c -4e-5,1.387 -0.4627,2.55978 -1.38798,3.51834 -0.92536,0.95861 -2.08151,1.4379 -3.46845,1.43788 l -22.49197,0 c -0.39716,2e-5 -0.59573,0.16533 -0.59571,0.49592 l 0,4.95319 c -2e-5,2.44335 0.87541,4.54045 2.62628,6.29129 1.75083,1.75086 3.84792,2.62629 6.29128,2.62628 l 0.39613,0 c 3.50168,1e-5 6.11133,-1.55228 7.82895,-4.65685 0.92529,-1.71758 2.34553,-2.57637 4.26072,-2.57639 1.38693,2e-5 2.54308,0.47881 3.46844,1.43637 0.92528,0.95759 1.38794,2.09761 1.38798,3.42006 -4e-5,0.85881 -0.19861,1.65107 -0.59571,2.37681 -1.58458,2.97353 -3.84698,5.33522 -6.7872,7.08506 -2.9403,1.74985 -6.12802,2.62477 -9.56318,2.62477 l -0.39613,0 c -5.15279,0 -9.54555,-1.81637 -13.17828,-5.44912 -3.632749,-3.63274 -5.44912,-8.02549 -5.449114,-13.17828 l 0,-20.71088 c -6e-6,-5.15071 1.816365,-9.55959 5.449114,-13.22666 3.63273,-3.66696 8.02549,-5.50046 13.17828,-5.50052 l 0.39613,0 c 5.15275,6e-5 9.54601,1.83356 13.17979,5.50052 3.63371,3.66707 5.45059,8.07595 5.45063,13.22666 z m -9.71285,-5.34933 0,-4.95622 c -4e-5,-2.50981 -0.87496,-4.63967 -2.62477,-6.38955 -1.74988,-1.7498 -3.84747,-2.62473 -6.2928,-2.62477 l -0.39613,0 c -2.44336,4e-5 -4.54045,0.87497 -6.29128,2.62477 -1.75087,1.74988 -2.6263,3.87974 -2.62628,6.38955 l 0,4.95622 c -2e-5,0.33065 0.19855,0.49596 0.59571,0.49593 l 17.04286,0 c 0.39509,3e-5 0.59265,-0.16528 0.59269,-0.49593 z"
+ style="font-size:99.08805847px"
+ id="path4316" />
+ <path
+ d="m 183.35199,242.62549 c -4e-5,5.15279 -1.81692,9.54554 -5.45063,13.17828 -3.63379,3.63275 -8.02705,5.44912 -13.17979,5.44912 l -0.39613,0 c -5.1528,0 -9.54555,-1.81637 -13.17828,-5.44912 -3.63275,-3.63274 -5.44912,-8.02549 -5.44912,-13.17828 l 0,-20.71088 c 0,-5.15071 1.81637,-9.55959 5.44912,-13.22666 3.63273,-3.66696 8.02548,-5.50046 13.17828,-5.50052 l 0.39613,0 c 5.15274,6e-5 9.546,1.83356 13.17979,5.50052 3.63371,3.66707 5.45059,8.07595 5.45063,13.22666 z m -9.71286,0 0,-20.71088 c -3e-5,-2.50981 -0.87495,-4.63967 -2.62477,-6.38955 -1.74987,-1.7498 -3.84747,-2.62473 -6.29279,-2.62477 l -0.39613,0 c -2.44336,4e-5 -4.54045,0.87497 -6.29128,2.62477 -1.75088,1.74988 -2.6263,3.87974 -2.62629,6.38955 l 0,20.71088 c -1e-5,2.44335 0.87541,4.54045 2.62629,6.29129 1.75083,1.75086 3.84792,2.62629 6.29128,2.62628 l 0.39613,0 c 2.44532,1e-5 4.54292,-0.87542 6.29279,-2.62628 1.74982,-1.75084 2.62474,-3.84794 2.62477,-6.29129 z"
+ style="font-size:99.08805847px"
+ id="path4318" />
+ </g>
+ <path
+ style="opacity:0.91503268000000004;fill:url(#radialGradient6133);fill-opacity:1;stroke:#bf2e09;stroke-opacity:1;stroke-width:3.12519685000000003;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:butt"
+ d="m 53.302303,271.79074 c -26.1162,0.24119 -45.8291492,25.27246 -45.8291492,52.10199 l 0,128.66335 c 0,29.10808 23.4386242,52.5467 52.5467002,52.5467 l 128.663346,0 c 26.82952,0 51.86079,-19.71295 52.10198,-45.82915 C 241.73293,356.65218 155.92375,270.84299 53.302303,271.79074 z"
+ id="path4571"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssss" />
+ <g
+ transform="matrix(0.66579695,0,0,0.66579695,-6.0735094,317.96382)"
+ id="g6234"
+ style="fill:url(#radialGradient6310);fill-opacity:1">
+ <rect
+ inkscape:tile-y0="93.946388"
+ inkscape:tile-x0="57.756062"
+ inkscape:tile-h="63.615372"
+ inkscape:tile-w="63.615372"
+ inkscape:tile-cy="125.75407"
+ inkscape:tile-cx="89.563747"
+ y="93.946388"
+ x="57.756062"
+ height="63.615372"
+ width="63.615372"
+ id="rect6180"
+ style="fill:url(#radialGradient6332);fill-opacity:1;stroke:none" />
+ <use
+ height="1052.3622"
+ width="744.09448"
+ id="use6220"
+ transform="translate(0,76.338446)"
+ xlink:href="#rect6180"
+ inkscape:tiled-clone-of="#rect6180"
+ y="0"
+ x="0"
+ style="fill:url(#radialGradient6314);fill-opacity:1" />
+ <use
+ height="1052.3622"
+ width="744.09448"
+ id="use6222"
+ transform="translate(76.338446,0)"
+ xlink:href="#rect6180"
+ inkscape:tiled-clone-of="#rect6180"
+ y="0"
+ x="0"
+ style="fill:url(#radialGradient6316);fill-opacity:1" />
+ <use
+ height="1052.3622"
+ width="744.09448"
+ id="use6224"
+ transform="translate(76.338446,76.338446)"
+ xlink:href="#rect6180"
+ inkscape:tiled-clone-of="#rect6180"
+ y="0"
+ x="0"
+ style="fill:url(#radialGradient6318);fill-opacity:1" />
+ <use
+ height="1052.3622"
+ width="744.09448"
+ id="use6226"
+ transform="translate(152.67689,0)"
+ xlink:href="#rect6180"
+ inkscape:tiled-clone-of="#rect6180"
+ y="0"
+ x="0"
+ style="fill:url(#radialGradient6320);fill-opacity:1" />
+ <use
+ height="1052.3622"
+ width="744.09448"
+ id="use6228"
+ transform="translate(152.67689,76.338446)"
+ xlink:href="#rect6180"
+ inkscape:tiled-clone-of="#rect6180"
+ y="0"
+ x="0"
+ style="fill:url(#radialGradient6322);fill-opacity:1" />
+ <rect
+ y="36.829994"
+ x="57.756062"
+ height="44.553471"
+ width="216.29227"
+ id="rect6232"
+ style="fill:url(#radialGradient6324);fill-opacity:1;stroke:none" />
+ </g>
+</svg>
diff --git a/main/project/rawimages/c-geo_contacts_icon.svg b/main/project/rawimages/c-geo_contacts_icon.svg
new file mode 100644
index 0000000..4ad0da3
--- /dev/null
+++ b/main/project/rawimages/c-geo_contacts_icon.svg
@@ -0,0 +1,635 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2985"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ width="512"
+ height="512"
+ sodipodi:docname="c-geo_icon.svg"
+ inkscape:export-filename=""
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <metadata
+ id="metadata2991">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs2989">
+ <linearGradient
+ id="linearGradient6127">
+ <stop
+ style="stop-color:#00c0ff;stop-opacity:1;"
+ offset="0"
+ id="stop6129" />
+ <stop
+ style="stop-color:#3486cb;stop-opacity:1;"
+ offset="1"
+ id="stop6131" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4555">
+ <stop
+ style="stop-color:#898989;stop-opacity:1;"
+ offset="0"
+ id="stop4557" />
+ <stop
+ style="stop-color:#505050;stop-opacity:1;"
+ offset="1"
+ id="stop4559" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3837">
+ <stop
+ style="stop-color:#fbf9d4;stop-opacity:1;"
+ offset="0"
+ id="stop3839" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3841" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3936">
+ <stop
+ style="stop-color:#f7991d;stop-opacity:1;"
+ offset="0"
+ id="stop3938" />
+ <stop
+ style="stop-color:#f8b339;stop-opacity:1;"
+ offset="1"
+ id="stop3940" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3928">
+ <stop
+ id="stop3930"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.12849163;" />
+ <stop
+ id="stop3932"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.0726257;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3863">
+ <stop
+ style="stop-color:#ffc34a;stop-opacity:1;"
+ offset="0"
+ id="stop3865" />
+ <stop
+ style="stop-color:#f9a62f;stop-opacity:1;"
+ offset="1"
+ id="stop3867" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3801">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.1;"
+ offset="0"
+ id="stop3803" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3805" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3890">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3892" />
+ <stop
+ id="stop3900"
+ offset="0.29212967"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3898"
+ offset="0.35852277"
+ style="stop-color:#d8dada;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d8dada;stop-opacity:1;"
+ offset="1"
+ id="stop3894" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3864">
+ <stop
+ style="stop-color:#aad04a;stop-opacity:1;"
+ offset="0"
+ id="stop3866" />
+ <stop
+ id="stop3872"
+ offset="0.29795828"
+ style="stop-color:#cfdc8d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#98bc40;stop-opacity:1;"
+ offset="0.36036199"
+ id="stop3882" />
+ <stop
+ style="stop-color:#48873e;stop-opacity:1;"
+ offset="1"
+ id="stop3868" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3838">
+ <stop
+ style="stop-color:#61b647;stop-opacity:1;"
+ offset="0"
+ id="stop3840" />
+ <stop
+ style="stop-color:#92c746;stop-opacity:1;"
+ offset="1"
+ id="stop3842" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3828">
+ <stop
+ id="stop3830"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.13333334;" />
+ <stop
+ id="stop3832"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0.11111111;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3796">
+ <stop
+ style="stop-color:#000000;stop-opacity:0.05555556;"
+ offset="0"
+ id="stop3798" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.10555556;"
+ offset="1"
+ id="stop3800" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3796"
+ id="linearGradient3802"
+ x1="15.959242"
+ y1="343.29277"
+ x2="176.26119"
+ y2="343.29277"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3796"
+ id="linearGradient3810"
+ x1="335.7388"
+ y1="344.35822"
+ x2="496.04077"
+ y2="344.35822"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="linearGradient3880"
+ x1="66.473442"
+ y1="197.85721"
+ x2="453.37692"
+ y2="197.85721"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3890"
+ id="linearGradient3896"
+ x1="70.62744"
+ y1="258.14891"
+ x2="435.78817"
+ y2="258.14891"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter3916"
+ x="-0.73785931"
+ width="2.4757186"
+ y="-0.25739279"
+ height="1.5147856">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="5.7505801"
+ id="feGaussianBlur3918" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3838"
+ id="radialGradient3922"
+ cx="283.49646"
+ cy="-10.861603"
+ fx="283.49646"
+ fy="-10.861603"
+ r="193.19952"
+ gradientTransform="matrix(-0.66393007,1.0294724,-1.0210616,-0.65850585,497.86851,-252.56237)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3801"
+ id="linearGradient3807"
+ x1="175.76119"
+ y1="344.35821"
+ x2="336.23881"
+ y2="344.35821"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3869"
+ x1="39.90625"
+ y1="351.5625"
+ x2="175.7036"
+ y2="351.5625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3877"
+ x1="39.90625"
+ y1="411.14062"
+ x2="175.75117"
+ y2="411.14062"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3863"
+ id="linearGradient3885"
+ x1="39.90625"
+ y1="294.22113"
+ x2="175.74925"
+ y2="294.22113"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3928"
+ id="linearGradient3934"
+ gradientUnits="userSpaceOnUse"
+ x1="335.7388"
+ y1="344.35822"
+ x2="496.04077"
+ y2="344.35822" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3942"
+ x1="336.25"
+ y1="304.70312"
+ x2="472.1875"
+ y2="304.70312"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3950"
+ x1="336.43512"
+ y1="373.8125"
+ x2="472.1875"
+ y2="373.8125"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3958"
+ x1="336.24496"
+ y1="420.28125"
+ x2="472.1875"
+ y2="420.28125"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3936"
+ id="linearGradient3966"
+ x1="336.25"
+ y1="459.6875"
+ x2="471.8985"
+ y2="459.6875"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3837"
+ id="linearGradient3843"
+ x1="72.743576"
+ y1="272.0433"
+ x2="73.038445"
+ y2="196.93991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4.1012061,5.4616772)" />
+ <filter
+ id="filter4143"
+ style="color-interpolation-filters:sRGB;"
+ inkscape:label="Drop Shadow">
+ <feFlood
+ id="feFlood4145"
+ flood-opacity="0.5"
+ flood-color="rgb(255,255,255)"
+ result="flood" />
+ <feComposite
+ in2="SourceGraphic"
+ id="feComposite4147"
+ in="flood"
+ operator="in"
+ result="composite1" />
+ <feGaussianBlur
+ id="feGaussianBlur4149"
+ in="composite"
+ stdDeviation="0.7"
+ result="blur" />
+ <feOffset
+ id="feOffset4151"
+ dx="1.5"
+ dy="0"
+ result="offset" />
+ <feComposite
+ in2="offset"
+ id="feComposite4153"
+ in="SourceGraphic"
+ operator="over"
+ result="fbSourceGraphic" />
+ <feColorMatrix
+ result="fbSourceGraphicAlpha"
+ in="fbSourceGraphic"
+ values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
+ id="feColorMatrix4297" />
+ <feFlood
+ id="feFlood4299"
+ flood-opacity="0.4"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ in="fbSourceGraphic" />
+ <feComposite
+ id="feComposite4301"
+ in2="fbSourceGraphic"
+ in="flood"
+ operator="in"
+ result="composite1" />
+ <feGaussianBlur
+ id="feGaussianBlur4303"
+ in="composite"
+ stdDeviation="0.8"
+ result="blur" />
+ <feOffset
+ id="feOffset4305"
+ dx="0.4"
+ dy="-2.5"
+ result="offset" />
+ <feComposite
+ id="feComposite4307"
+ in2="offset"
+ in="fbSourceGraphic"
+ operator="over"
+ result="composite2" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient4565"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6127"
+ id="radialGradient6133"
+ cx="120.81452"
+ cy="380.25443"
+ fx="120.81452"
+ fy="380.25443"
+ r="155.75519"
+ gradientTransform="matrix(0.62519145,-0.4100565,0.49214634,0.75034946,-161.40245,178.54198)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4555"
+ id="radialGradient6137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.4036302,0,-177.2632)"
+ cx="357.5"
+ cy="439.17227"
+ fx="357.5"
+ fy="439.17227"
+ r="129.875" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1058"
+ id="namedview2987"
+ showgrid="false"
+ inkscape:zoom="1.7363281"
+ inkscape:cx="256"
+ inkscape:cy="256"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2985"
+ inkscape:snap-bbox="false"
+ inkscape:snap-nodes="true"
+ inkscape:bbox-nodes="false"
+ inkscape:bbox-paths="false"
+ inkscape:object-nodes="true"
+ inkscape:object-paths="true"
+ inkscape:snap-global="false" />
+ <path
+ style="fill:#000000;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:0.7062937"
+ d="m 22.337543,475.26062 0,28.21584 159.595867,-8.22962 161.06544,7.34788 159.00804,-7.34788 0,-272.16532 -57.31343,-5.29048 z"
+ id="path3812"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 16.459242,494.95293 0,-303.32032 220.436278,22.92537 102.87027,-21.74971 155.77497,14.69575 0,272.16533 -159.30195,16.45924 -160.47762,-15.87141 z"
+ id="path2998"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3869);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 39.90625 379.59375 L 100.46875 348.9375 L 39.90625 323.53125 L 39.90625 379.59375 z "
+ id="path3022" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 447.71875 L 175.75 380.46875 L 175.75 455.875 L 175.8125 455.875 L 335.84375 471.6875 L 336.25 471.65625 L 336.25 447.71875 z "
+ id="path3913" />
+ <path
+ style="fill:url(#linearGradient3966);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 447.71875 L 336.25 471.65625 L 382.53125 467.125 L 336.25 447.71875 z "
+ id="path3824" />
+ <path
+ style="fill:url(#linearGradient3877);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 175.75118 380.46593 L 110.4375 353.09375 L 39.90625 388.8125 L 39.90625 469.1875 L 175.75059 455.88106 "
+ id="path3020" />
+ <path
+ style="fill:url(#linearGradient3958);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 336.24497 437.85561 L 401.0625 465.3125 L 472.1875 458.375 L 472.1875 411.65625 L 472.1875 411.65625 L 401.53125 375.25 L 336.24729 403.39996 "
+ id="path3836" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.24729 403.39996 L 295.9375 420.78125 L 336.24497 437.85561 "
+ id="path3018" />
+ <path
+ style="fill:url(#linearGradient3950);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 472.1875 344.78125 L 410.84375 371.25 L 472.1875 402.84375 L 472.1875 344.78125 z "
+ id="path3016" />
+ <path
+ style="fill:#fdd069;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 215.5 L 231.9375 238.90625 L 175.75 232.9375 L 175.75 369.90625 L 285.375 416.34375 L 336.25 394.1875 L 336.25 215.5 z "
+ id="path3918" />
+ <path
+ style="fill:url(#linearGradient3942);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 336.25 215.5 L 336.25 394.1875 L 472.1875 334.96875 L 472.1875 229.34375 L 337.5 215.21875 L 336.25 215.5 z "
+ id="path3831" />
+ <path
+ style="fill:url(#linearGradient3885);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
+ d="M 175.74925 232.94454 L 39.90625 218.53125 L 39.90625 312.375 L 175.74798 369.91102 "
+ id="path3002" />
+ <path
+ style="fill:url(#linearGradient3807);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 336.23881,496.12859 -160.47762,-15.87141 0,-272.05717 160.47762,-15.61218 z"
+ id="path3928"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3934);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 495.54076,479.66935 -159.30195,16.45924 0,-303.54076 159.30195,14.91619 z"
+ id="path3026"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient3802);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 16.459242,494.95293 159.301948,-14.69575 0,-272.05717 -159.301948,-16.5674 z"
+ id="path3024"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.39768341;stroke:none"
+ d="m 442.88428,146.84389 23.48471,20.36727 c 2.79219,2.93915 2.97845,9.95135 1.03915,18.08115 l -10.39147,31.79789 c -2.64524,4.8496 -9.97581,7.27402 -9.97581,7.27402 0,0 2.60526,7.16885 1.87047,11.43062 L 431.03801,303.54719 211.9859,415.98286 c -4.40873,2.49828 -13.14978,2.5487 -15.79502,-0.83132 L 89.158777,293.57139 86.041338,228.93647 z"
+ id="path3924"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:#5c5d5d;fill-opacity:1;stroke:none"
+ d="m 423.82549,175.46728 c 9.40528,3.52698 10.28702,11.16877 10.58094,18.51665 l -17.6349,67.60046 -215.73364,110.51205 c -13.2323,6.03571 -18.60274,3.52699 -24.10104,-3.23306 L 74.360505,252.1791 69.657865,181.93341 c -0.207829,-7.48186 9.405281,-12.34443 9.405281,-12.34443 z"
+ id="path3920"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="fill:url(#linearGradient3896);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 435.28817,168.41332 -18.81056,76.41791 -220.73019,109.63031 c -6.23488,2.07829 -10.747,1.83787 -14.69576,-1.17566 L 77.887486,234.5442 71.12744,160.47761 z"
+ id="path3884"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:#868786;fill-opacity:1;stroke:none"
+ d="m 452.87691,130.92395 c 1.17566,3.96786 -9.35911,40.28156 -9.35911,40.28156 -2.49395,7.58577 -8.6705,10.28703 -8.6705,10.28703 L 201.3318,287.88978 c -7.17011,2.90961 -14.01254,1.62667 -16.45924,-1.0287 L 69.36395,171.64638 c -2.390037,-3.32527 -2.351321,-12.93226 -2.351321,-12.93226 z"
+ id="path3818"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:url(#linearGradient3880);fill-opacity:1;stroke:none"
+ d="m 452.87691,130.92395 -10.53477,36.60762 c -1.36085,4.47005 -5.29048,6.17222 -5.29048,6.17222 l -235.13203,107.5729 c -10.70321,3.94876 -16.16532,-1.17566 -16.16532,-1.17566 L 69.657865,165.18025 c -3.11744,-2.90961 -2.645236,-6.46613 -2.645236,-6.46613 0,0 -1.053122,-22.11238 -0.03919,-45.77105 z"
+ id="path3816"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffd0;fill-opacity:0.94405589;stroke:none;filter:url(#filter3916)"
+ id="path3902"
+ sodipodi:cx="185.59158"
+ sodipodi:cy="226.65034"
+ sodipodi:rx="9.3523197"
+ sodipodi:ry="26.809982"
+ d="m 194.9439,226.65034 a 9.3523197,26.809982 0 1 1 -18.70464,0 9.3523197,26.809982 0 1 1 18.70464,0 z"
+ transform="matrix(0.88331111,0,0,1.0869978,29.761821,-12.444045)" />
+ <path
+ style="fill:url(#radialGradient3922);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 327.42135,24.101033 452.04133,125.79564 c 3.52698,4.70264 -1.46957,7.64179 -1.46957,7.64179 l -246.00689,99.93111 c -5.77133,2.79957 -11.57831,0.83438 -14.69575,-1.76349 L 70.53961,121.68083 c -10.580941,-12.05052 5.29047,-17.04708 5.29047,-17.04708 L 311.25603,23.513203 c 9.40528,-3.820896 16.16532,0.58783 16.16532,0.58783 z"
+ id="path3814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ <g
+ transform="matrix(1.0487801,-0.41271929,0.76389884,0.65287682,0,0)"
+ style="font-size:27.52445984px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3843);fill-opacity:1;stroke:none;filter:url(#filter4143);font-family:'232MKSDRoundMedium';-inkscape-font-specification:'232MKSDRoundMedium'"
+ id="text3833">
+ <path
+ d="m 9.8964838,251.44327 c -1.6511043,3.04006 -3.9467671,5.43501 -6.8869951,7.18485 -2.94029722,1.74985 -6.1280177,2.62477 -9.5631709,2.62477 l -0.3961345,0 c -5.1527923,0 -9.5621783,-1.81637 -13.2281713,-5.44912 -3.666016,-3.63274 -5.499018,-8.02549 -5.499012,-13.17828 l 0,-20.71088 c -6e-6,-5.15071 1.832996,-9.55959 5.499012,-13.22666 3.665993,-3.66696 8.075379,-5.50046 13.2281713,-5.50052 l 0.3961345,0 c 3.3686269,6e-5 6.52308417,0.87548 9.4633813,2.62628 2.9402281,1.75091 5.2358908,4.1131 6.8869951,7.08658 0.3971008,0.72579 0.5956718,1.51805 0.5957138,2.3768 -4.2e-5,1.3205 -0.4793342,2.46001 -1.4378777,3.41855 -0.9586246,0.95863 -2.0981402,1.43792 -3.4185501,1.43788 -1.9151893,4e-5 -3.3354259,-0.85875 -4.2607139,-2.57639 -1.71762205,-3.10451 -4.3272689,-4.6568 -7.8289485,-4.65684 l -0.3961345,0 c -2.4433557,4e-5 -4.5404473,0.87497 -6.2912813,2.62477 -1.750871,1.74988 -2.626297,3.87974 -2.626281,6.38955 l 0,20.71088 c -1.6e-5,2.44335 0.87541,4.54045 2.626281,6.29129 1.750834,1.75086 3.8479256,2.62629 6.2912813,2.62628 l 0.3961345,0 c 3.5016796,1e-5 6.11132645,-1.58554 7.8289485,-4.75664 0.925288,-1.71758 2.3455246,-2.57637 4.2607139,-2.57639 1.3869363,2e-5 2.559211,0.47881 3.5168278,1.43637 0.957535,0.95759 1.436323,2.13087 1.436366,3.51985 -4.3e-5,0.79228 -0.197606,1.55128 -0.5926902,2.27702 z"
+ style="font-size:99.08805847px"
+ id="path4310" />
+ <path
+ d="m 34.109071,221.22213 c -1.8e-5,1.58458 -0.577588,2.95492 -1.732711,4.11103 -1.155155,1.15619 -2.526001,1.73426 -4.112541,1.73423 -1.584549,3e-5 -2.954891,-0.57804 -4.11103,-1.73423 -1.156155,-1.15611 -1.734228,-2.52645 -1.734222,-4.11103 -6e-6,-1.65102 0.578067,-3.03799 1.734222,-4.16092 1.156139,-1.12284 2.526481,-1.68428 4.11103,-1.68433 1.58654,5e-5 2.957386,0.56149 4.112541,1.68433 1.155123,1.12293 1.732693,2.5099 1.732711,4.16092 z m 0,28.53681 c -1.8e-5,1.65107 -0.577588,3.03855 -1.732711,4.16244 -1.155155,1.12389 -2.526001,1.68584 -4.112541,1.68584 -1.584549,0 -2.954891,-0.56195 -4.11103,-1.68584 -1.156155,-1.12389 -1.734228,-2.51137 -1.734222,-4.16244 -6e-6,-1.58453 0.578067,-2.95487 1.734222,-4.11103 1.156139,-1.15613 2.526481,-1.73421 4.11103,-1.73422 1.58654,1e-5 2.957386,0.57809 4.112541,1.73422 1.155123,1.15616 1.732693,2.5265 1.732711,4.11103 z"
+ style="font-size:99.08805847px"
+ id="path4312" />
+ <path
+ d="m 83.876868,261.8486 c -4.3e-5,5.15277 -1.816918,9.56215 -5.450629,13.22817 -3.633788,3.66599 -8.027046,5.499 -13.179788,5.49902 l -0.396135,0 c -3.435203,-2e-5 -6.622419,-0.89158 -9.561659,-2.67467 -2.93927,-1.78312 -5.234428,-4.16144 -6.885483,-7.13496 -0.39715,-0.72575 -0.595721,-1.51802 -0.595714,-2.3768 -7e-6,-1.32247 0.478781,-2.46249 1.436366,-3.42007 0.957567,-0.95758 2.097586,-1.43636 3.420062,-1.43636 1.981666,0 3.435166,0.85879 4.360504,2.57639 1.651045,3.10455 4.259684,4.65683 7.825924,4.65684 l 0.396135,0 c 2.445321,-1e-5 4.542917,-0.87543 6.292793,-2.62628 1.749813,-1.75086 2.624735,-3.84795 2.624769,-6.29128 l 0,-2.57638 c -3.4e-5,-0.33062 -0.164334,-0.4294 -0.4929,-0.29635 -2.642944,1.38698 -5.451162,2.08046 -8.424662,2.08046 l -0.396135,0 c -5.152792,0 -9.545546,-1.833 -13.178276,-5.49901 -3.632753,-3.666 -5.449124,-8.07538 -5.449118,-13.22817 l 0,-20.11517 c -6e-6,-5.15273 1.816365,-9.56211 5.449118,-13.22817 3.63273,-3.66595 8.025484,-5.49895 13.178276,-5.49901 l 0.396135,0 c 5.152742,6e-5 9.546,1.83306 13.179788,5.49901 3.633711,3.66606 5.450586,8.07544 5.450629,13.22817 z m -9.712855,-19.51945 0,-20.11517 c -3.4e-5,-2.50982 -0.874956,-4.64017 -2.624769,-6.39107 -1.749876,-1.75081 -3.847472,-2.62623 -6.292793,-2.62628 l -0.396135,0 c -2.443356,5e-5 -4.540447,0.87547 -6.291281,2.62628 -1.750871,1.7509 -2.626297,3.88125 -2.626281,6.39107 l 0,20.11517 c -1.6e-5,2.44335 0.87541,4.54044 2.626281,6.29128 1.750834,1.75087 3.847925,2.62629 6.291281,2.62628 l 0.396135,0 c 2.445321,1e-5 4.542917,-0.87541 6.292793,-2.62628 1.749813,-1.75084 2.624735,-3.84793 2.624769,-6.29128 z"
+ style="font-size:99.08805847px"
+ id="path4314" />
+ <path
+ d="m 133.61443,232.22016 c -4e-5,1.387 -0.4627,2.55978 -1.38798,3.51834 -0.92536,0.95861 -2.08151,1.4379 -3.46845,1.43788 l -22.49197,0 c -0.39716,2e-5 -0.59573,0.16533 -0.59571,0.49592 l 0,4.95319 c -2e-5,2.44335 0.87541,4.54045 2.62628,6.29129 1.75083,1.75086 3.84792,2.62629 6.29128,2.62628 l 0.39613,0 c 3.50168,1e-5 6.11133,-1.55228 7.82895,-4.65685 0.92529,-1.71758 2.34553,-2.57637 4.26072,-2.57639 1.38693,2e-5 2.54308,0.47881 3.46844,1.43637 0.92528,0.95759 1.38794,2.09761 1.38798,3.42006 -4e-5,0.85881 -0.19861,1.65107 -0.59571,2.37681 -1.58458,2.97353 -3.84698,5.33522 -6.7872,7.08506 -2.9403,1.74985 -6.12802,2.62477 -9.56318,2.62477 l -0.39613,0 c -5.15279,0 -9.54555,-1.81637 -13.17828,-5.44912 -3.632749,-3.63274 -5.44912,-8.02549 -5.449114,-13.17828 l 0,-20.71088 c -6e-6,-5.15071 1.816365,-9.55959 5.449114,-13.22666 3.63273,-3.66696 8.02549,-5.50046 13.17828,-5.50052 l 0.39613,0 c 5.15275,6e-5 9.54601,1.83356 13.17979,5.50052 3.63371,3.66707 5.45059,8.07595 5.45063,13.22666 z m -9.71285,-5.34933 0,-4.95622 c -4e-5,-2.50981 -0.87496,-4.63967 -2.62477,-6.38955 -1.74988,-1.7498 -3.84747,-2.62473 -6.2928,-2.62477 l -0.39613,0 c -2.44336,4e-5 -4.54045,0.87497 -6.29128,2.62477 -1.75087,1.74988 -2.6263,3.87974 -2.62628,6.38955 l 0,4.95622 c -2e-5,0.33065 0.19855,0.49596 0.59571,0.49593 l 17.04286,0 c 0.39509,3e-5 0.59265,-0.16528 0.59269,-0.49593 z"
+ style="font-size:99.08805847px"
+ id="path4316" />
+ <path
+ d="m 183.35199,242.62549 c -4e-5,5.15279 -1.81692,9.54554 -5.45063,13.17828 -3.63379,3.63275 -8.02705,5.44912 -13.17979,5.44912 l -0.39613,0 c -5.1528,0 -9.54555,-1.81637 -13.17828,-5.44912 -3.63275,-3.63274 -5.44912,-8.02549 -5.44912,-13.17828 l 0,-20.71088 c 0,-5.15071 1.81637,-9.55959 5.44912,-13.22666 3.63273,-3.66696 8.02548,-5.50046 13.17828,-5.50052 l 0.39613,0 c 5.15274,6e-5 9.546,1.83356 13.17979,5.50052 3.63371,3.66707 5.45059,8.07595 5.45063,13.22666 z m -9.71286,0 0,-20.71088 c -3e-5,-2.50981 -0.87495,-4.63967 -2.62477,-6.38955 -1.74987,-1.7498 -3.84747,-2.62473 -6.29279,-2.62477 l -0.39613,0 c -2.44336,4e-5 -4.54045,0.87497 -6.29128,2.62477 -1.75088,1.74988 -2.6263,3.87974 -2.62629,6.38955 l 0,20.71088 c -1e-5,2.44335 0.87541,4.54045 2.62629,6.29129 1.75083,1.75086 3.84792,2.62629 6.29128,2.62628 l 0.39613,0 c 2.44532,1e-5 4.54292,-0.87542 6.29279,-2.62628 1.74982,-1.75084 2.62474,-3.84794 2.62477,-6.29129 z"
+ style="font-size:99.08805847px"
+ id="path4318" />
+ </g>
+ <path
+ style="opacity:0.91503268000000004;fill:url(#radialGradient6133);fill-opacity:1;stroke:#546cbf;stroke-opacity:1;stroke-width:3.12519685000000003;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:butt"
+ d="m 53.302303,271.79074 c -26.1162,0.24119 -45.8291492,25.27246 -45.8291492,52.10199 l 0,128.66335 c 0,29.10808 23.4386242,52.5467 52.5467002,52.5467 l 128.663346,0 c 26.82952,0 51.86079,-19.71295 52.10198,-45.82915 C 241.73293,356.65218 155.92375,270.84299 53.302303,271.79074 z"
+ id="path4571"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssss" />
+ <g
+ transform="matrix(0.50408368,0,0,0.50408368,-73.375097,175.04359)"
+ id="g4019"
+ style="opacity:0.88888891;fill:url(#radialGradient4565);fill-opacity:1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4009"
+ d="m 311.40625,414.46875 c -43.80747,32.9716 -76.51103,111.56242 -83.78125,207 l 259.75,0 c -7.27022,-95.43758 -39.97378,-174.0284 -83.78125,-207 -13.7999,7.16781 -29.46883,11.21875 -46.09375,11.21875 -16.62492,0 -32.29385,-4.05094 -46.09375,-11.21875 z"
+ style="fill:url(#radialGradient6135);fill-opacity:1;stroke:none" />
+ <path
+ transform="translate(0,92.33324)"
+ d="m 426.15342,233.20062 c 0,37.9188 -30.73926,68.65806 -68.65806,68.65806 -37.9188,0 -68.65806,-30.73926 -68.65806,-68.65806 0,-37.9188 30.73926,-68.65806 68.65806,-68.65806 37.9188,0 68.65806,30.73926 68.65806,68.65806 z"
+ sodipodi:ry="68.658058"
+ sodipodi:rx="68.658058"
+ sodipodi:cy="233.20062"
+ sodipodi:cx="357.49536"
+ id="path4011"
+ style="fill:url(#radialGradient6137);fill-opacity:1;stroke:none"
+ sodipodi:type="arc" />
+ </g>
+</svg>
diff --git a/main/project/rawimages/cgeo-calendar_ic_512x512.psd b/main/project/rawimages/cgeo-calendar_ic_512x512.psd
deleted file mode 100644
index a862a1e..0000000
--- a/main/project/rawimages/cgeo-calendar_ic_512x512.psd
+++ /dev/null
Binary files differ
diff --git a/main/project/rawimages/cgeo-calendar_ic_launcher.psd b/main/project/rawimages/cgeo-calendar_ic_launcher.psd
deleted file mode 100644
index c950655..0000000
--- a/main/project/rawimages/cgeo-calendar_ic_launcher.psd
+++ /dev/null
Binary files differ
diff --git a/main/res/layout/livemapinfo.xml b/main/res/layout/livemapinfo.xml
index 1b1e9ea..889febc 100644
--- a/main/res/layout/livemapinfo.xml
+++ b/main/res/layout/livemapinfo.xml
@@ -19,13 +19,6 @@
android:textColor="?text_color"
android:textSize="14sp" />
- <CheckBox
- android:id="@+id/live_map_hint_hide"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="left"
- android:text="@string/live_map_note_dontshow"
- android:visibility="gone" />
</LinearLayout>
</ScrollView> \ No newline at end of file
diff --git a/main/res/layout/main_activity.xml b/main/res/layout/main_activity.xml
index ef86954..9e124a1 100644
--- a/main/res/layout/main_activity.xml
+++ b/main/res/layout/main_activity.xml
@@ -35,8 +35,7 @@
android:gravity="center"
android:orientation="vertical" >
- <LinearLayout
- style="@style/icon_mainscreen_row" >
+ <LinearLayout style="@style/icon_mainscreen_row" >
<LinearLayout
style="@style/icon_mainscreen_cell"
@@ -52,8 +51,7 @@
android:text="@string/live_map_button" />
</LinearLayout>
- <LinearLayout
- style="@style/icon_mainscreen_cell" >
+ <LinearLayout style="@style/icon_mainscreen_cell" >
<ImageView
android:id="@+id/nearest"
@@ -76,8 +74,7 @@
style="@style/icon_mainscreen_count"
android:textIsSelectable="false" />
- <LinearLayout
- style="@style/icon_mainscreen_cell_counter" >
+ <LinearLayout style="@style/icon_mainscreen_cell_counter" >
<ImageView
android:id="@+id/search_offline"
@@ -91,8 +88,7 @@
</RelativeLayout>
</LinearLayout>
- <LinearLayout
- style="@style/icon_mainscreen_row" >
+ <LinearLayout style="@style/icon_mainscreen_row" >
<LinearLayout
style="@style/icon_mainscreen_cell"
@@ -146,7 +142,6 @@
android:layout_alignParentBottom="true"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
- android:onClick="cgeoNavSettings"
android:orientation="vertical" >
<LinearLayout
@@ -158,11 +153,13 @@
<TextView
android:id="@+id/nav_location"
style="@style/location_current"
+ android:onClick="cgeoNavSettings"
android:text="@string/loc_trying" />
<RelativeLayout
android:layout_width="fill_parent"
- android:layout_height="wrap_content" >
+ android:layout_height="wrap_content"
+ android:onClick="cgeoNavSettings" >
<TextView
android:id="@+id/nav_type"
diff --git a/main/res/layout/search_activity.xml b/main/res/layout/search_activity.xml
index 25f914b..28256f1 100644
--- a/main/res/layout/search_activity.xml
+++ b/main/res/layout/search_activity.xml
@@ -53,7 +53,7 @@
android:text="@string/search_address" />
</RelativeLayout>
- <EditText
+ <AutoCompleteTextView
android:id="@+id/address"
style="@style/edittext_full"
android:hint="@string/search_address"
@@ -98,7 +98,7 @@
android:text="@string/search_kw" />
</RelativeLayout>
- <EditText
+ <AutoCompleteTextView
android:id="@+id/keyword"
style="@style/edittext_full"
android:hint="@string/search_kw_prefill"
@@ -119,7 +119,7 @@
android:text="@string/search_fbu" />
</RelativeLayout>
- <EditText
+ <AutoCompleteTextView
android:id="@+id/finder"
style="@style/edittext_full"
android:hint="@string/search_fbu_prefill"
@@ -140,7 +140,7 @@
android:text="@string/search_hbu" />
</RelativeLayout>
- <EditText
+ <AutoCompleteTextView
android:id="@+id/owner"
style="@style/edittext_full"
android:hint="@string/search_hbu_prefill"
diff --git a/main/res/menu/details_context.xml b/main/res/menu/details_context.xml
index 0ae2f6d..3125459 100644
--- a/main/res/menu/details_context.xml
+++ b/main/res/menu/details_context.xml
@@ -17,5 +17,10 @@
android:id="@+id/menu_cache_share_field"
android:title="@string/cache_share_field">
</item>
+ <item
+ android:id="@+id/menu_calendar"
+ android:title="@string/cache_menu_event"
+ android:visible="false">
+ </item>
</menu> \ No newline at end of file
diff --git a/main/res/values-cs/strings.xml b/main/res/values-cs/strings.xml
index 66286f0..7e523f6 100644
--- a/main/res/values-cs/strings.xml
+++ b/main/res/values-cs/strings.xml
@@ -16,10 +16,10 @@
<string name="multi">Multi-keš</string>
<string name="mystery">Mystery keš</string>
<string name="letterbox">Dopisní schránka</string>
- <string name="event">Událost</string>
- <string name="mega">Mega-událost</string>
+ <string name="event">Keš události</string>
+ <string name="mega">Keš Mega-události</string>
<string name="earth">Earthcache</string>
- <string name="cito">Událost cache in trash out</string>
+ <string name="cito">Událost Cache In Trash Out</string>
<string name="webcam">Webcam keš</string>
<string name="virtual">Virtuální keš</string>
<string name="wherigo">Wherigo keš</string>
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">Virtuální</string>
<string name="cache_size_notchosen">Nezvolena</string>
<string name="cache_size_unknown">Neznámá</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Velmi velká</string>
<string name="wp_final">Cíl</string>
<string name="wp_stage">Část multi-keše</string>
<string name="wp_puzzle">Otázka</string>
@@ -56,11 +58,11 @@
<string name="log_placed">Umístěn</string>
<string name="log_grabbed">Převzat</string>
<string name="log_movecollection">Přesunuto do sbírky</string>
- <string name="log_moveinventory">Přesunuto do inventáře</string>
+ <string name="log_moveinventory">Přesunuto do Inventáře</string>
<string name="log_maintained">Provádění údržby</string>
<string name="log_maintenance_needed">Vyžaduje údržbu</string>
<string name="log_update">Změna souřadnic</string>
- <string name="log_archived">Archivace</string>
+ <string name="log_archived">Archivována</string>
<string name="log_unarchived">Odarchivována</string>
<string name="log_needs_archived">Vyžaduje archivaci</string>
<string name="log_discovered">Spatřen</string>
@@ -68,7 +70,7 @@
<string name="log_retractlisting">Vrácení Listingu</string>
<string name="log_marked_missing">Označeno za ztracené</string>
<string name="log_tb_nothing">Beze změny</string>
- <string name="log_tb_visit">Návštíveno</string>
+ <string name="log_tb_visit">Navštíveno</string>
<string name="log_tb_drop">Nechat zde</string>
<string name="log_tb_changeall">Změnit vše</string>
<string name="log_save">Uložit</string>
@@ -117,15 +119,15 @@
<string name="log_image_scale">Měřítko</string>
<string name="log_password_title">Logovací heslo:</string>
<string name="log_hint_log_password">Zadej své logovací heslo</string>
+ <string name="log_oc_team_comment">Komentář týmu OC</string>
<string name="translate_to_sys_lang">Přeložit do %s</string>
<string name="translate_to_english">Přeložit do angličtiny</string>
<string name="translate_length_warning">Při velkém množství textu může překládání selhat.</string>
<string name="err_none">OK</string>
- <string name="err_start">Komunikace nezačala</string>
<string name="err_parse">Čtení přihlašovací obrazovky selhalo</string>
<string name="err_server">Nelze se připojit na Geocaching.com. Stránka může být nedostupná nebo je chyba v tvém připojení k Internetu</string>
+ <string name="err_server_ec">Nelze se připojit na Extremcaching.com. Stránka může být nedostupná nebo je chyba v tvém připojení k Internetu.</string>
<string name="err_login">Nejsou uloženy žádné přihlašovací údaje</string>
- <string name="err_login_failed">c:geo se nemůže přihlásit.</string>
<string name="err_login_failed_toast">Nelze se přihlásit. c:geo bude pracovat Offline s uloženými informacemi. Zkontroluj nastavení přihlašování a připojení k Internetu.</string>
<string name="err_unknown">Neznámá chyba</string>
<string name="err_comm">Neznámá komunikační chyba</string>
@@ -177,8 +179,8 @@
<string name="err_log_load_data">c:geo nemůže načíst data požadovaná k zalogování návštěvy.</string>
<string name="err_log_load_data_again">c:geo nemůže načíst data požadovaná k zalogování návštěvy. Zkouší to znovu.</string>
<string name="err_log_load_data_still">c:geo stále načítá data požadovaná k odeslání Logu. Prosím, počkej ještě chvíli.</string>
- <string name="err_log_failed_server">c:geo nemůže odeslat Log, protože server neodpovídá.</string>
<string name="err_log_post_failed">Zdá se, že tvůj Log nebyl odeslán. Prosím, zkontroluj to na Geocaching.com.</string>
+ <string name="err_log_post_failed_ec">Zdá se, že tvůj Log nebyl odeslán. Prosím, zkontroluj to na Extremcaching.com.</string>
<string name="err_logimage_post_failed">Zdá se, že tvůj obrázek nebyl nahrán. Zkontroluj to, prosím, na Geocaching.com.</string>
<string name="err_search_address_forgot">c:geo zapomnělo hledanou adresu.</string>
<string name="err_parse_lat">c:geo nemůže dopočítat zeměpisnou šířku.</string>
@@ -202,6 +204,8 @@
<string name="warn_deprecated_mapfile">Používáš zastaralou verzi 0.2.4 mapového souboru.\nZvaž přepnutí na mapovou verzi 0.3.0.\nV příštím vydání již nebude verze 0.2.4 podporována.</string>
<string name="warn_nonexistant_mapfile">Zvolený soubor map neexistuje.\nOffline mapy nejsou dostupné.</string>
<string name="warn_rendertheme_missing">Téma pro mapu není k dispozici.</string>
+ <string name="warn_pocket_query_select">Nevybrán žádný Databázový požadavek.</string>
+ <string name="warn_no_pocket_query_found">V síti nebyl nalezen žádný Databázový požadavek.</string>
<string name="info_log_posted">c:geo úspěšně zaslalo tvůj Log.</string>
<string name="info_log_saved">c:geo úspěšně uložilo tvůj Log.</string>
<string name="info_log_cleared">Zápis byl vyprázdněn.</string>
@@ -222,6 +226,8 @@
<string name="menu_history">Historie</string>
<string name="menu_filter">Filtr</string>
<string name="menu_scan_geo">Naskenovat geokód</string>
+ <string name="menu_pocket_queries">Databázové požadavky</string>
+ <string name="menu_scan_description">C:geo může skenovat geokódy, které jsou vytištěné jako QR kód. K tomu nezbytná aplikace však není nainstalována. Chceš přejít na Google Play a nainstalovat ji?</string>
<string name="live_map_button">Aktivní mapa</string>
<string name="caches_nearby_button">Nejbližší</string>
<string name="advanced_search_button">Hledání</string>
@@ -245,8 +251,8 @@
<string name="caches_sort_difficulty">Obtížnosti</string>
<string name="caches_sort_terrain">Terénu</string>
<string name="caches_sort_size">Velikosti</string>
- <string name="caches_sort_favorites">Oblíbenosti</string>
- <string name="caches_sort_favorites_ratio">Oblíbenosti [%]</string>
+ <string name="caches_sort_favorites">Oblíbené</string>
+ <string name="caches_sort_favorites_ratio">Oblíbené [%]</string>
<string name="caches_sort_name">Jména</string>
<string name="caches_sort_geocode">Geokódu</string>
<string name="caches_sort_rating">Hodnocení</string>
@@ -289,6 +295,9 @@
<string name="caches_filter_modified">S upravenými souřadnicemi</string>
<string name="caches_filter_origin">Původ keše</string>
<string name="caches_filter_distance">Vzdálenost</string>
+ <string name="caches_filter_personal_note">S osobní poznámkou</string>
+ <string name="caches_filter_popularity">Oblíbené</string>
+ <string name="caches_filter_popularity_ratio">Oblíbené [%]</string>
<string name="caches_removing_from_history">Čištění Historie…</string>
<string name="caches_clear_offlinelogs">Smazat offline Logy</string>
<string name="caches_clear_offlinelogs_progress">Mazání offline logů</string>
@@ -311,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo nedokázalo odstranit aktuální seznam</string>
<string name="list_dialog_rename_title">Přejmenovat seznam</string>
<string name="list_dialog_rename">Přejmenovat</string>
+ <string name="list_not_available">Seznam již není dostupný, přepínání na výchozí seznam</string>
<string name="about_version">Verze</string>
<string name="about_changelog">Změny</string>
<string name="about_donate">Podpora vývoje</string>
@@ -328,6 +338,7 @@
<string name="settings_title_map_data">Data map</string>
<string name="settings_title_map_content">Obsah map</string>
<string name="settings_title_gpx">GPX</string>
+ <string name="settings_title_basicmembers">Možnosti pro běžné členy</string>
<string name="settings_title_navigation">Navigace</string>
<string name="settings_title_system">Systém</string>
<string name="settings_title_navigation_menu">Navigační menu</string>
@@ -337,10 +348,16 @@
<string name="settings_category_logging_other">Další možnosti logování</string>
<string name="settings_goto_url_button">více …</string>
<string name="settings_title_gc">Geocaching.com</string>
+ <string name="settings_title_ec">Extremcaching.com</string>
+ <string name="settings_title_ox">Opencaching.com (Garmin)</string>
<string name="settings_activate_gc">Aktivace</string>
+ <string name="settings_activate_ec">Aktivace</string>
+ <string name="settings_activate_ox">Aktivace</string>
<string name="settings_gc_legal_note">Používáním služeb Geocaching.com souhlasíš s Podmínkami použití společnosti Groundspeak.</string>
<string name="settings_info_facebook_login_title">Facebook přihlášení</string>
<string name="settings_info_facebook_login">Přes c:geo se sice na Geocaching.com pomocí Facebook účtu nepřihlásíš, ale je tu jednoduché řešení …</string>
+ <string name="settings_authorize">Autorizovat c:geo</string>
+ <string name="settings_reauthorize">Znovu autorizovat c:geo</string>
<string name="init_oc">opencaching.de</string>
<string name="settings_activate_oc">Aktivace opencaching.de na Aktivní mapě a ve vyhledávání</string>
<string name="init_oc_de_description">Autorizovat c:geo pro hledání keší a přístup/filtrování tvých nalezených keší služby opencaching.de.</string>
@@ -359,7 +376,10 @@
<string name="init_login_popup_failed">Přihlášení selhalo</string>
<string name="init_login_popup_failed_reason">Přihlášení se nezdařilo, protože:</string>
<string name="init_login_popup_not_authorized">Neautorizováno</string>
+ <string name="init_login_popup_invalid_timestamp">Místní čas je neplatný, nastav systémový čas</string>
+ <string name="init_login_popup_invalid_token">Neplatná autorizace, opakuj akci</string>
<string name="init_signature">Podpis</string>
+ <string name="init_template_help">Zástupné řetězce jako [NAME] budou po použití šablony nahrazeny.</string>
<string name="init_signature_template_button">Vložit šablonu</string>
<string name="init_signature_template_date">Datum</string>
<string name="init_signature_template_time">Čas</string>
@@ -367,6 +387,9 @@
<string name="init_signature_template_user">Uživatel</string>
<string name="init_signature_template_number">Číslo nálezu</string>
<string name="init_signature_template_owner">Vlastník</string>
+ <string name="init_signature_template_name">Jméno</string>
+ <string name="init_signature_template_url">URL</string>
+ <string name="init_signature_template_log">Text logu</string>
<string name="init_ratingwanted">Načítat hodnocení keše z GCvote.com</string>
<string name="init_summary_ratingwanted">Načítat hodnocení keše z GCvote.com</string>
<string name="init_friendlogswanted">Načítat doplňkový Logbook s logy od kámošů</string>
@@ -378,7 +401,7 @@
<string name="init_skin">Používat světlý vzhled\n(Vyžaduje restart)</string>
<string name="init_summary_skin">Používat světlý vzhled\n(Vyžaduje restart)</string>
<string name="init_address">Zobrazovat adresu na hlavní obrazovce</string>
- <string name="init_summary_address">Zobrazovat adresu na hlavní obrazovce</string>
+ <string name="init_summary_address">Zobrazovat adresu místo souřadnic na hlavní obrazovce</string>
<string name="init_captcha">Zobrazovat obrázek CAPTCHA, pokud je třeba (pouze Běžní uživatelé)</string>
<string name="init_summary_captcha">Zobrazit obrázek CAPTCHA, pokud je třeba (pouze Běžní členové)</string>
<string name="init_useenglish">Používat angličtinu pro c:geo\n(Vyžaduje restart)</string>
@@ -422,6 +445,8 @@
<string name="settings_info_themes_title">Info o stylech mapy</string>
<string name="settings_info_themes">c:geo podporuje vlastní styly pro offline mapy. Ty mohou být použity pro změnu barevného stylu mapy (např. noční mapa), pro zvýranění důležitých objektů (jako jsou např. cykloztezky) nebo pro určení šířky čar.</string>
<string name="init_mapsource_select">Vyber mapový zdroj</string>
+ <string name="settings_title_scale_map_text">Měřítko textu mapy</string>
+ <string name="settings_summary_scale_map_text">Velikost textových popisků offline mapy dle DPI zařízení</string>
<string name="init_map_directory_description">Složka s offline mapami</string>
<string name="init_gpx_exportdir">Složka pro GPX export</string>
<string name="init_gpx_importdir">Složka pro GPX import</string>
@@ -454,15 +479,39 @@
<string name="init_use_native_ua">Identifikovat se jako webový prohlížeč Android. Řeší problémy v některých sítích.</string>
<string name="init_summary_use_native_ua">Identifikovat se jako webový prohlížeč Android. Řeší problémy v některých sítích.</string>
<string name="init_rendertheme_folder">Složka témat mapy</string>
+ <string name="init_maintenance">Údržba</string>
+ <string name="init_maintenance_directories_note">c:geo ukládá obrázky, obrázky z logů a další soubory vázané ke keši v samostatném adresáři. V některých případech (jako import/export databáze) může tento adresář obsahovat staré soubory, které se zde dají smazat.</string>
+ <string name="init_maintenance_directories">Odstranit osamocené soubory</string>
+ <string name="settings_open_website">Otevřít webovou stránku</string>
+ <string name="settings_settings">Nastavení</string>
+ <string name="settings_information">Informace</string>
+ <string name="settings_twitter_cache_message">Zpráva pro nalezení keše</string>
+ <string name="settings_twitter_trackable_message">Zpráva pro nalezení sledovatelného předmětu</string>
+ <string name="init_ec_icons">Mapové ikony</string>
+ <string name="settings_ec_icons_other">Vlastní styl</string>
+ <string name="settings_ec_icons_oc">Jako OC</string>
+ <string name="settings_features">Podporované funkce</string>
+ <string name="feature_description">V c:geo (kromě offline funkcí) jsou podporovány následující <b>online</b> funkce tohoto webu:</string>
+ <string name="feature_personal_notes">Osobní poznámka</string>
+ <string name="feature_online_logging">Zalogování online</string>
+ <string name="feature_log_images">Připojit k logům obrázky</string>
+ <string name="feature_watch_list">Sledované</string>
+ <string name="feature_own_coordinates">Ukládání modifikovaných souřadnic</string>
+ <string name="feature_search_keyword">Hledat podle klíčového slova</string>
+ <string name="feature_search_live_map">Aktivní mapa</string>
+ <string name="feature_search_center">Hledat podle pozice</string>
+ <string name="feature_search_geocode">Hledat podle geokódu</string>
+ <string name="feature_search_owner">Hledat podle vlastníka</string>
+ <string name="feature_search_finder">Hledat podle nálezce</string>
<string name="map_source_google_map">Google: Mapa</string>
<string name="map_source_google_satellite">Google: Satelitní</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
<string name="map_source_osm_cyclemap">OSM: Cyklomapa</string>
<string name="map_source_osm_offline">Offline</string>
<string name="init_sendToCgeo">Poslat do c:geo</string>
- <string name="settings_info_send2cgeo_title">Info o send2cgeo</string>
+ <string name="settings_info_send2cgeo_title">Info o send2c:geo</string>
<string name="init_sendToCgeo_name">Název tvého zařízení</string>
- <string name="init_sendToCgeo_description"><b>Send2cgeo</b> umožňuje stahovat keše přímo ze stránky Geocaching.com pomocí speciálního pluginu pro Firefox a Chrome. Před registrací zkoukni <a href="http://send2.cgeo.org/">http://send2.cgeo.org/</a>. Pokud chceš používat funkci send2cgeo, musíš se zaregistrovat. c:geo bude pracovat normálně i bez registrace.</string>
+ <string name="init_sendToCgeo_description"><b>Send2c:geo</b> umožňuje stahovat keše přímo ze stránky Geocaching.com pomocí speciálního pluginu pro Firefox a Chrome. Před registrací zkoukni <a href="http://send2.cgeo.org/">http://send2.cgeo.org/</a>. Pokud chceš používat funkci send2c:geo, musíš se zaregistrovat. c:geo bude pracovat normálně i bez registrace.</string>
<string name="init_sendToCgeo_register">Požádat o registraci</string>
<string name="init_sendToCgeo_registering">Registrace tvého zařízení pro funkci Poslat do c:geo…</string>
<string name="init_sendToCgeo_register_ok">Registrace úspěšně dokončena. PIN kód je ####. Použij ho na stránce c:geo pro přidání zařízení do Tvého prohlížeče.</string>
@@ -473,6 +522,10 @@
<string name="auth_authorize">Autorizovat c:geo</string>
<string name="auth_start">Zahájit autorizaci</string>
<string name="auth_again">Znovu autorizovat</string>
+ <string name="auth_dialog_waiting">Čekání na %s…</string>
+ <string name="auth_explain_short">Následující proces umožní <b>c:geu</b> přístup k %s.</string>
+ <string name="auth_explain_long">Stisknutím tlačítka \"Autorizovat c:geo\" bude proces zahájen. Tento proces otevře webový prohlížeč se stránkou %s. Na této stránce se přihlaš a povol <b>c:geu</b> přistupovat k tvému účtu. To je vše.</string>
+ <string name="auth_dialog_completed_twitter">c:geo nyní může posílat zprávy na Tvůj Twitter.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo je nyní autorizováno pro interakce s %s.</string>
@@ -496,6 +549,8 @@
<string name="cache_log_image_default_title">Fotografie</string>
<string name="cache_personal_note">Osobní poznámka</string>
<string name="cache_personal_note_edit">Upravit</string>
+ <string name="cache_personal_note_limit">Omezení osobní poznámky</string>
+ <string name="cache_personal_note_truncation">Tato osobní poznámka bude po %d znacích zkrácena webem Geocaching.com.</string>
<string name="cache_personal_note_upload">Nahrát</string>
<string name="cache_personal_note_uploading">Nahrávání osobní poznámky</string>
<string name="cache_personal_note_upload_done">Osobní poznámka nahrána</string>
@@ -572,6 +627,7 @@
<string name="cache_menu_oruxmaps">OruxMaps</string>
<string name="cache_menu_cachebeacon">Cache Beacon</string>
<string name="cache_menu_navigon">Navigon</string>
+ <string name="cache_menu_pebble">Pebble</string>
<string name="cache_status">Stav</string>
<string name="cache_status_offline_log">Připravený Log</string>
<string name="cache_status_found">Nalezena</string>
@@ -599,7 +655,6 @@
<string name="cache_coordinates">Souřadnice</string>
<string name="cache_coordinates_original">Původní souřadnice</string>
<string name="cache_spoiler_images_title">Obrázky s nápovědou</string>
- <string name="cache_images_title">Obrázky</string>
<string name="cache_log_types">Typy zápisů</string>
<string name="cache_coordinates_no">Tato keš nemá souřadnice.</string>
<string name="cache_clear_history">Vymazat historii</string>
@@ -618,9 +673,10 @@
<string name="file_title_searching">Hledání</string>
<string name="simple_dir_chooser_title">Vyber umístění</string>
<string name="simple_dir_chooser_current_path">Cesta:</string>
+ <string name="simple_dir_chooser_invalid_path">Chybná cesta</string>
<string name="gpx_import_loading_caches">Nahrávání keší z .GPX souboru</string>
- <string name="gpx_import_loading_waypoints">Načítám soubor s Body trasy</string>
- <string name="gpx_import_store_static_maps">Ukládám statické mapy</string>
+ <string name="gpx_import_loading_waypoints">Načítání souboru s Body trasy</string>
+ <string name="gpx_import_store_static_maps">Ukládání statických map</string>
<string name="gpx_import_caches_imported">Keše importovány</string>
<string name="gpx_import_static_maps_skipped">Stažení statických map zrušeno</string>
<string name="gpx_import_title_static_maps">Uložit statické mapy</string>
@@ -635,6 +691,7 @@
<string name="gpx_import_delete_title">Smazat soubor</string>
<string name="gpx_import_delete_message">Chceš smazat %s?</string>
<string name="gpx_import_select_list_title">Import GPX do seznamu</string>
+ <string name="gpx_import_android">Import z Androidu</string>
<string name="map_file_select_title">Vyber soubor map</string>
<string name="web_import_title">Import z webu</string>
<string name="web_import_waiting">Čekání na nové keše z webu…</string>
@@ -705,7 +762,6 @@
<string name="map_strategy_auto">Závislá na rychlosti</string>
<string name="map_strategy_detailed">Detailní</string>
<string name="live_map_notification">Na nové Aktivní mapě nemusí být souřadnice vždy přesné. Případné nepřesné souřadnice jsou na mapě označeny oranžovým kruhem.\nPři otevření detailů keše nebo jejím uložení pro Offline použití jsou již souřadnice přesné.\n\nVíce informací o všech změnách lze najít na stránce \"O programu\" v aplikaci.</string>
- <string name="live_map_note_dontshow">Příště nezobrazovat</string>
<string name="search_bar_hint">Hledaní kešek</string>
<string name="search_bar_desc">Keše (GC-kód, klíčové slovo), Sledovatelné předměty (TB-kód)</string>
<string name="search_coordinates">Souřadnice</string>
@@ -731,6 +787,9 @@
<string name="search_address_started">Vyhledávání míst</string>
<string name="search_address_result">Nalezená místa</string>
<string name="search_own_caches">Hledat moje keše</string>
+ <string name="search_pocket_title">Databázový požadavek</string>
+ <string name="search_pocket_loading">Načítání seznamu Databázových požadavků</string>
+ <string name="search_pocket_select">Zvol Databázový požadavek</string>
<string name="trackable">Sledovatelný předmět</string>
<string name="trackable_details_loading">Načítání detailů…</string>
<string name="trackable_log_touch">Hlášení zahlédnutí</string>
@@ -763,6 +822,7 @@
<string name="user_menu_view_found">Nalezené keše</string>
<string name="user_menu_open_browser">Otevřít profil v prohlížeči</string>
<string name="user_menu_send_message">Odeslat zprávu</string>
+ <string name="user_menu_open_contact">Otevřít kartu kontaktu</string>
<string name="navigation">Navigace</string>
<string name="compass_title">Kompas</string>
<string name="use_gps">Použít GPS</string>
@@ -771,12 +831,17 @@
<string name="destination_set">Cíl nastaven</string>
<string name="navigation_direct_navigation">Přímá navigace</string>
<string name="navigation_target">Cíl</string>
+ <string name="err_nav_no_coordinates">Nelze spustit navigaci bez souřadnic</string>
<string name="license">Licence</string>
<string name="license_show">Zobrazit licenci</string>
<string name="license_dismiss">Zamítnout</string>
<string name="helper_calendar_title">c:geo modul kalendáře</string>
- <string name="helper_calendar_missing">c:geo modul kalendáře není nainstalován.</string>
+ <string name="helper_calendar_missing">Doplněk pro c:geo - Kalendář není nainstalován.</string>
<string name="helper_calendar_description">Umožňuje exportovat události keší do tvého kalendáře.</string>
+ <string name="helper_sendtocgeo_title">Poslat do c:geo</string>
+ <string name="helper_contacts_title">c:geo - kontakty (doplněk)</string>
+ <string name="helper_contacts_description">Umožňuje otevřít vizitku (z tvého seznamu kontaktů) přímo z logu keše, můžeš tak snadněji kontaktovat kamarády o pomoc.</string>
+ <string name="helper_sendtocgeo_description">Odeslat do c:geo (Send to c:geo) je rozšíření prohlížeče <strong>pro tvůj počítač</strong>. Umožňuje zaslání keše do tvého mobilního zařízení jediným klepnutím, přímo z prohlížeče, při procházení webu Geocaching.com.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Jednoduše použitelná aplikace zobrazující Online mapy a dovolující je přímo stahovat pro Offline použití (pouze rastrové mapy). Také podporuje záznam trasy, zpracování bodů zájmu a další užitečné funkce.</string>
<string name="helper_gpsstatus_title">GPS Status</string>
@@ -787,6 +852,8 @@
<string name="helper_barcode_description">Jsou zde skripty Greasemonkey a stránky, které ti umožní zobrazit geokód jako čárový kód. S touto aplikací může c:geo přečíst daný geokód přímo z tvého displeje.</string>
<string name="helper_pocketquery_title">Pocket Query Creator</string>
<string name="helper_pocketquery_description">Umožňuje snadné vytváření a stažení PQ podle současné pozice nebo bodu na mapě. Vyžaduje Premium účet na Geocaching.com.</string>
+ <string name="helper_google_translate_title">Překladač Google</string>
+ <string name="helper_google_translate_description">Pokud si v aplikaci Překladač Google stáhneš překladový balíček, můžeš jednoduše překládat popisy keší v c:geu dlouhým podržením textu (a to bez připojení k Internetu).</string>
<string name="addon_missing_title">Chybějící modul</string>
<string name="addon_download_prompt">Získat nyní z Google Play.</string>
<string name="export">Export</string>
@@ -796,9 +863,9 @@
<string name="export_fieldnotes_info">Poznámky z terénu budou uloženy do /sdcard/field-notes s názvem souboru podle aktuálního data a času.</string>
<string name="export_fieldnotes_upload">Nahrát na geocaching.com</string>
<string name="export_fieldnotes_uploading">Nahrávání…</string>
- <string name="export_fieldnotes_upload_success">Nahrání na geocaching.com bylo úspěšné</string>
+ <string name="export_fieldnotes_upload_success">Nahrávání na geocaching.com bylo úspěšné</string>
<string name="export_fieldnotes_onlynew">Jen od předchozího nahrání</string>
- <string name="export_fieldnotes_creating">Vytvářím soubor poznámek z terénu…</string>
+ <string name="export_fieldnotes_creating">Vytváření souboru poznámek z terénu…</string>
<string name="export_gpx">GPX</string>
<string name="export_gpx_info">GPX soubor bude exportován do %1$s s názvem souboru podle aktuálního data a času.</string>
<string name="export_gpx_to">Odeslat GPX</string>
@@ -994,6 +1061,38 @@
<string name="attribute_unknown_no">Neznámý atribut negativní</string>
<string name="attribute_geotour_yes">Část Geocesty</string>
<string name="attribute_geotour_no">Není součástí Geocesty</string>
+ <string name="attribute_kids_2_yes">Vem své děti</string>
+ <string name="attribute_kids_2_no">Neber své děti</string>
+ <string name="attribute_historic_site_yes">Historické místo</string>
+ <string name="attribute_historic_site_no">Žádné historické místo</string>
+ <string name="attribute_magnetic_yes">Magnetická keš</string>
+ <string name="attribute_magnetic_no">Nemagnetická keš</string>
+ <string name="attribute_usb_cache_yes">Dead drop USB keš</string>
+ <string name="attribute_usb_cache_no">Žádná Dead drop USB keš</string>
+ <string name="attribute_shovel_yes">Můžeš potřebovat lopatu</string>
+ <string name="attribute_shovel_no">Nepotřebuješ lopatu</string>
+ <string name="attribute_specific_access_yes">Přístupná v určitý čas (může vyžadovat vstupní poplatek)</string>
+ <string name="attribute_specific_access_no">Přístupná kdykoliv</string>
+ <string name="attribute_pedestrian_only_yes">Přístup pouze pěšky</string>
+ <string name="attribute_pedestrian_only_no">Přístup ne pouze pěšky</string>
+ <string name="attribute_nature_cache_yes">Skrytá v přírodním prostředí (lesy, hory, atd.)</string>
+ <string name="attribute_nature_cache_no">Není skryta v přírodním prostředí</string>
+ <string name="attribute_byop_yes">Vem si něco na psaní</string>
+ <string name="attribute_byop_no">Vlastní tužka není třeba</string>
+ <string name="attribute_safari_cache_yes">Reverzní cache</string>
+ <string name="attribute_safari_cache_no">Není reverzní keš</string>
+ <string name="attribute_quick_cache_yes">Rychlá keš</string>
+ <string name="attribute_quick_cache_no">Není to rychlá keš</string>
+ <string name="attribute_wherigo_yes">Wherigo keš</string>
+ <string name="attribute_wherigo_no">Není to Wherigo keš</string>
+ <string name="attribute_audio_cache_yes">Popis obsahuje zvukový soubor</string>
+ <string name="attribute_audio_cache_no">Popis neobsahuje zvukový soubor</string>
+ <string name="attribute_geohotel_yes">GeoHotelová keš</string>
+ <string name="attribute_geohotel_no">Není to GeoHotelová keš</string>
+ <string name="attribute_survey_marker_yes">Poblíž měřičské značky</string>
+ <string name="attribute_survey_marker_no">Není v blízkosti měřičské značky</string>
+ <string name="attribute_offset_cache_yes">Offset keš</string>
+ <string name="attribute_offset_cache_no">Není to Offset keš</string>
<string name="quote">Učinit Geocaching lehčí a uživatelé línější.</string>
<string name="powered_by">carnero</string>
<string name="support">Podpora: <a href="">support@cgeo.org</a></string>
@@ -1013,7 +1112,7 @@
<string name="tts_service">Mluvící kompas</string>
<string name="tts_start">Začít mluvit</string>
<string name="tts_stop">Přestat mluvit</string>
- <string name="err_tts_lang_not_supported">Převod na řeč není pro tento jazyk k dispozici.</string>
+ <string name="err_tts_lang_not_supported">Převod textu na řeč není pro tento jazyk k dispozici.</string>
<string name="tts_one_kilometer">jeden kilometr</string>
<string name="tts_one_meter">jeden metr</string>
<string name="tts_one_mile">jedna míle</string>
@@ -1021,6 +1120,9 @@
<string name="tts_one_oclock">jedna hodina</string>
<string name="tts_oclock">%s hodin</string>
<string name="clipboard_copy_ok">Zkopírováno do schránky</string>
+ <string name="percent_favorite_points">%\ oblíbené</string>
+ <string name="cgeo_shortcut">c:geo zástupce</string>
+ <string name="create_shortcut">Vytvořit zástupce</string>
<string-array name="log_image_scales">
<item>Bez měřítka</item>
<item>512 px</item>
diff --git a/main/res/values-da/strings.xml b/main/res/values-da/strings.xml
index d784056..6b23d3d 100644
--- a/main/res/values-da/strings.xml
+++ b/main/res/values-da/strings.xml
@@ -53,7 +53,6 @@
<string name="log_clear">Fjern</string>
<string name="log_webcam">Webcamfoto taget</string>
<string name="err_none">Ok</string>
- <string name="err_start">Forbindelse ikke oprettet</string>
<string name="err_parse">Login-side kan ikke indlæses</string>
<string name="err_server">Kan ikke forbinde til Geocaching.com (server eller forbindelsesfejl?)</string>
<string name="err_login">Ingen login gemt</string>
diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml
index 927cce0..9d45699 100644
--- a/main/res/values-de/strings.xml
+++ b/main/res/values-de/strings.xml
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">Virtual</string>
<string name="cache_size_notchosen">Nicht gewählt</string>
<string name="cache_size_unknown">Unbekannt</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Sehr groß</string>
<string name="wp_final">Final</string>
<string name="wp_stage">Station eines Multi-Cache</string>
<string name="wp_puzzle">Station mit Frage</string>
@@ -54,7 +56,7 @@
<string name="log_attended">Habe teilgenommen</string>
<string name="log_retrieved">Mitgenommen</string>
<string name="log_placed">Abgelegt</string>
- <string name="log_grabbed">Woanders gefunden</string>
+ <string name="log_grabbed">Woanders mitgenommen</string>
<string name="log_movecollection">Zur Sammlung hinzufügen</string>
<string name="log_moveinventory">Zum Inventar hinzufügen</string>
<string name="log_maintained">Wartung durchgeführt</string>
@@ -117,16 +119,15 @@
<string name="log_image_scale">Skalierung</string>
<string name="log_password_title">Log-Passwort:</string>
<string name="log_hint_log_password">Log-Passwort eingeben</string>
+ <string name="log_oc_team_comment">OC Team Bemerkung</string>
<string name="translate_to_sys_lang">Übersetze in %s</string>
<string name="translate_to_english">Übersetze in Englisch</string>
<string name="translate_length_warning">Die Übersetzung kann bei sehr langen Texten evtl. fehlschlagen.</string>
<string name="err_none">OK</string>
- <string name="err_start">Kommunikation nicht gestartet</string>
<string name="err_parse">Parsing der Anmeldung gescheitert</string>
<string name="err_server">Verbindung zu Geocaching.com konnte nicht hergestellt werden (Server oder Verbindung inaktiv?)</string>
<string name="err_server_ec">Verbindung zu Extremcaching.com konnte nicht hergestellt werden (Server oder Verbindung inaktiv?)</string>
<string name="err_login">Keine Anmeldedaten gespeichert.</string>
- <string name="err_login_failed">Login fehlgeschlagen.</string>
<string name="err_login_failed_toast">c:geo konnte sich nicht einloggen und arbeitet im Offline-Modus. Bitte die Login-Daten in den Einstellungen überprüfen oder eine Internetverbindung herstellen.</string>
<string name="err_unknown">Unbekannter Fehler</string>
<string name="err_comm">Unbekannter Kommunikationsfehler</string>
@@ -151,13 +152,13 @@
<string name="err_watchlist_still_managing">c:geo versucht noch immer die Watchlist zu aktualisieren.</string>
<string name="err_watchlist_failed">Ändern der Watchlist nicht erfolgreich.</string>
<string name="err_application_no">c:geo konnte keine passende Anwendung finden.</string>
- <string name="err_auth_initialize">c:geo konnte die Autorisierung nicht initialisieren.</string>
+ <string name="err_auth_initialize">c:geo konnte die Autorisierung nicht starten.</string>
<string name="err_auth_process">Autorisierung fehlgeschlagen.</string>
<string name="err_cannot_log_visit">c:geo hat nicht genügend Informationen um den Besuch zu loggen. Bitte über die Cache-Details versuchen.</string>
<string name="err_download_fail">c:geo konnte keine Caches laden, weil </string>
<string name="err_dwld_details_failed">Download der Cache-Details fehlgeschlagen.</string>
<string name="err_load_descr_failed">Laden der Cachebeschreibung fehlgeschlagen.</string>
- <string name="err_location_unknown">c:geo erkennt die Position des Caches nicht.</string>
+ <string name="err_location_unknown">c:geo kennt die Position des Caches nicht.</string>
<string name="err_missing_device_name">Vor der Registrierung muss ein Name für das Endgerät festlegt werden.</string>
<string name="err_favorite_failed">Ändern des Favoriten-Status ist fehlgeschlagen.</string>
<string name="err_select_logimage_failed">Auswahl eines Bildes für das Log ist fehlgeschlagen.</string>
@@ -174,13 +175,12 @@
<string name="err_point_no_position_given">Mindestens Längen- und Breitengrad oder Entfernung und Richtung angeben. Auch alle Angaben sind möglich.</string>
<string name="err_point_curr_position_unavailable">c:geo hat noch keine aktuelle Koordinaten. Bitte einen Moment warten…</string>
<string name="err_point_bear_and_dist_title">Hilfe benötigt?</string>
- <string name="err_point_bear_and_dist">Angaben zu Richtung und Entfernung sind notwendig. Richtung: 0 bis 360 Grad</string>
+ <string name="err_point_bear_and_dist">Angaben zu Richtung und Entfernung sind notwendig. Richtung: 0 bis 360 Grad relativ zum Norden. Die Entfernung benötigt keine Bezeichnung der Einheiten. </string>
<string name="err_log_load_data">c:geo konnte die benötigten Daten nicht laden, um den Besuch zu loggen.</string>
<string name="err_log_load_data_again">c:geo konnte die benötigten Daten nicht laden, um den Besuch zu loggen. Bitte erneut versuchen.</string>
<string name="err_log_load_data_still">c:geo lädt gerade die benötigten Daten. Bitte kurz warten.</string>
- <string name="err_log_failed_server">c:geo konnte Log nicht senden, weil der Server nicht antwortete.</string>
- <string name="err_log_post_failed">c:geo konnte Log nicht absenden.</string>
- <string name="err_log_post_failed_ec">Es scheint dass Ihr Log nicht hochgeladen werden konnte. Bitte prüfen Sie es auf Extremcaching.com nach.</string>
+ <string name="err_log_post_failed">c:geo konnte den Log nicht absenden. Bitte auf geocaching.com überprüfen.</string>
+ <string name="err_log_post_failed_ec">c:geo konnte den Log nicht absenden. Bitte auf Extremcaching.com überprüfen.</string>
<string name="err_logimage_post_failed">Es scheint dass Ihr Logfoto nicht hochgeladen werden konnte. Bitte prüfen Sie es auf Geocaching.com nach.</string>
<string name="err_search_address_forgot">c:geo hat die Adresse vergessen, die gesucht wurde.</string>
<string name="err_parse_lat">c:geo konnte den Breitengrad nicht verarbeiten.</string>
@@ -193,8 +193,8 @@
<string name="warn_no_keyword">Kein Stichwort angegeben.</string>
<string name="warn_no_username">Kein Benutzername angegeben.</string>
<string name="warn_search_help_title">Hilfe benötigt?</string>
- <string name="warn_search_help_address">Adresse oder Ort eingeben, z.B. Straßenname und Ort \"Dorfstraße 333, Berlin, Deutschland\", Ort \"Berlin\" oder den Namen eines beliebigen Ortes wie z.B. \"Tiergarten\".</string>
- <string name="warn_search_help_gccode">Geocode eingeben. z.B. \"GC1VCAZ\".</string>
+ <string name="warn_search_help_address">Adresse oder Ort eingeben, z. B. Postanschrift \"Dorfstraße 333, Berlin, Deutschland\", einen Ort \"Berlin\" oder den Namen eines beliebigen Ortes wie \"Tiergarten\".</string>
+ <string name="warn_search_help_gccode">Geocode eingeben, z. B. \"GC1VCAZ\".</string>
<string name="warn_search_help_keyword">Stichwörter eingeben, die im Namen des zu suchenden Caches enthalten sind.</string>
<string name="warn_search_help_user">Name eines Benutzers auf geocaching.com eingeben.</string>
<string name="warn_search_help_tb">Code des Trackables eingeben, z.B. \"TB29QMZ\".</string>
@@ -205,7 +205,7 @@
<string name="warn_nonexistant_mapfile">Die gewählte Datei existiert nicht.\nOffline Karte ist nicht verfügbar.</string>
<string name="warn_rendertheme_missing">Das gewählte Karten-Theme wurde nicht gefunden.</string>
<string name="warn_pocket_query_select">Kein Pocket Query ausgewählt.</string>
- <string name="warn_no_pocket_query_found">Kein Pocket Query online gefunden.</string>
+ <string name="warn_no_pocket_query_found">Kein Pocket Query online gefunden</string>
<string name="info_log_posted">Log erfolgreich gesendet.</string>
<string name="info_log_saved">Log erfolgreich gespeichert.</string>
<string name="info_log_cleared">Log wurde geleert.</string>
@@ -226,6 +226,8 @@
<string name="menu_history">Verlauf</string>
<string name="menu_filter">Filter</string>
<string name="menu_scan_geo">Geocode scannen</string>
+ <string name="menu_pocket_queries">Pocket Queries</string>
+ <string name="menu_scan_description">c:geo kann Geocodes, die als QR code abgebildet sind scannen. Die dafür notwendige App ist nicht installiert. Wollen sie Google Play öffnen, um sie zu installieren?</string>
<string name="live_map_button">Live-Karte</string>
<string name="caches_nearby_button">In der Nähe</string>
<string name="advanced_search_button">Suche</string>
@@ -272,7 +274,7 @@
<string name="caches_drop_all_ask">Sollen wirklich alle Caches von dieser Liste gelöscht werden?</string>
<string name="caches_drop_stored">Gespeicherte löschen</string>
<string name="caches_drop_progress">Entferne Caches…</string>
- <string name="caches_drop_all_and_list">Alle und Liste löschen</string>
+ <string name="caches_drop_all_and_list">Alle Caches und Liste löschen</string>
<string name="caches_delete_events">Vergangene Events löschen</string>
<string name="caches_refresh_selected">Ausgewählte aktualisieren</string>
<string name="caches_refresh_all">Alle aktualisieren</string>
@@ -293,6 +295,7 @@
<string name="caches_filter_modified">Mit geänderten Koordinaten</string>
<string name="caches_filter_origin">Herkunft</string>
<string name="caches_filter_distance">Entfernung</string>
+ <string name="caches_filter_personal_note">Mit persönlicher Notiz</string>
<string name="caches_filter_popularity">Favoriten</string>
<string name="caches_filter_popularity_ratio">Favoriten [%]</string>
<string name="caches_removing_from_history">Lösche aus Verlauf…</string>
@@ -317,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo konnte die Liste nicht löschen</string>
<string name="list_dialog_rename_title">Liste umbenennen</string>
<string name="list_dialog_rename">Umbenennen</string>
+ <string name="list_not_available">Liste nicht mehr vorhanden, wechsele zur Standardliste</string>
<string name="about_version">Version</string>
<string name="about_changelog">Änderungen</string>
<string name="about_donate">Spenden</string>
@@ -345,6 +349,7 @@
<string name="settings_goto_url_button">mehr …</string>
<string name="settings_title_gc">Geocaching.com</string>
<string name="settings_title_ec">Extremcaching.com</string>
+ <string name="settings_title_ox">Opencaching.com (Garmin)</string>
<string name="settings_activate_gc">Aktivieren</string>
<string name="settings_activate_ec">Aktivieren</string>
<string name="settings_activate_ox">Aktivieren</string>
@@ -352,7 +357,7 @@
<string name="settings_info_facebook_login_title">Facebook-Login</string>
<string name="settings_info_facebook_login">c:geo kann sich zwar nicht per Facebook bei Geocaching.com einloggen, aber es gibt eine einfache Abhilfe …</string>
<string name="settings_authorize">c:geo autorisieren</string>
- <string name="settings_reauthorize">c:geo erneut autorisieren</string>
+ <string name="settings_reauthorize">c:geo neu autorisieren</string>
<string name="init_oc">Opencaching.de</string>
<string name="settings_activate_oc">Aktivieren</string>
<string name="init_oc_de_description">Autorisiere c:geo auf opencaching.de zuzugreifen um Caches zu suchen und nach deinen Funden zu filtern.</string>
@@ -371,7 +376,10 @@
<string name="init_login_popup_failed">Login fehlgeschlagen</string>
<string name="init_login_popup_failed_reason">Login fehlgeschlagen:</string>
<string name="init_login_popup_not_authorized">Nicht autorisiert</string>
+ <string name="init_login_popup_invalid_timestamp">Lokale Zeit ungültig, Gerätezeit einstellen</string>
+ <string name="init_login_popup_invalid_token">Genehmigung ungültig, Neu aktivieren</string>
<string name="init_signature">Signatur</string>
+ <string name="init_template_help">Platzhalter-Zeichenfolgen wie [NAME] werden später erweitert, wenn diese Vorlage verwendet wird.</string>
<string name="init_signature_template_button">Platzhalter einfügen</string>
<string name="init_signature_template_date">Datum</string>
<string name="init_signature_template_time">Zeit</string>
@@ -379,9 +387,12 @@
<string name="init_signature_template_user">Benutzer</string>
<string name="init_signature_template_number">Nummer</string>
<string name="init_signature_template_owner">Besitzer</string>
+ <string name="init_signature_template_name">Name</string>
+ <string name="init_signature_template_url">URL</string>
+ <string name="init_signature_template_log">Log text</string>
<string name="init_ratingwanted">GCvote-Bewertung</string>
<string name="init_summary_ratingwanted">Lade Cache-Bewertung von GCvote.com</string>
- <string name="init_friendlogswanted">Logs von Freunden</string>
+ <string name="init_friendlogswanted">Logs von Freunden zeigen</string>
<string name="init_summary_friendlogswanted">Lade zusätzliche Logbuch-Seite für Logs von Freunden</string>
<string name="init_openlastdetailspage">Zuletzt genutzte Seite</string>
<string name="init_summary_openlastdetailspage">Öffne Details mit zuletzt genutzter Seite</string>
@@ -390,7 +401,7 @@
<string name="init_skin">Helle Oberfläche</string>
<string name="init_summary_skin">Helle Oberfläche (Neustart erforderlich)</string>
<string name="init_address">Ort statt Koordinaten</string>
- <string name="init_summary_address">Ort statt Koordinaten im Startbildschirm anzeigen</string>
+ <string name="init_summary_address">Adresse statt Koordinaten im Startbildschirm anzeigen</string>
<string name="init_captcha">Zeige CAPTCHA</string>
<string name="init_summary_captcha">Zeige CAPTCHA wenn notwendig (nur Basic Member)</string>
<string name="init_useenglish">Auf Englisch</string>
@@ -410,30 +421,32 @@
<string name="init_units">Imperiale Einheiten</string>
<string name="init_summary_units">Imperiale Einheiten (Meilen/Fuß)</string>
<string name="init_log_offline">Offline loggen</string>
- <string name="init_summary_log_offline">Offline loggen (Dialog für Online-Log nicht anzeigen)</string>
+ <string name="init_summary_log_offline">Offline loggen aktivieren (Dialog für Online-Log wird nicht angezeigt beim loggen, Logs werden nicht hochgeladen)</string>
<string name="init_choose_list">Nach Liste fragen</string>
<string name="init_summary_choose_list">Beim Speichern von Caches nach Liste fragen</string>
<string name="init_livelist">Richtung zum Cache</string>
- <string name="init_summary_livelist">Richtung zum Cache in der Cache-Liste anzeigen</string>
+ <string name="init_summary_livelist">Richtung zu Caches in der Liste anzeigen</string>
<string name="init_backup">Sicherung</string>
<string name="init_backup_backup">Sicherung</string>
<string name="init_backup_running">Erzeuge Sicherung der Cache-Datenbank…</string>
<string name="init_backup_note">Hinweis: Diese Option sichert die Datenbank von c:geo. Nur Caches und Wegpunkte werden gesichert, keine Einstellungen. Login-Daten und Passwörter werden die App nicht verlassen.</string>
<string name="init_backup_restore">Wiederherstellung</string>
- <string name="init_backup_success">Datenbank von c:geo wurde erfolgreich in Datei geschrieben</string>
- <string name="init_backup_failed">Sicherung der Datenbank fehlgeschlagen.</string>
+ <string name="init_backup_success">Datenbank von c:geo wurde erfolgreich kopiert nach:</string>
+ <string name="init_backup_failed">Sicherung der Datenbank von c:geo fehlgeschlagen.</string>
<string name="init_backup_unnecessary">Datenbank ist leer, keine Sicherung notwendig.</string>
- <string name="init_restore_success">Wiederherstellung beendet.</string>
+ <string name="init_restore_success">Wiederherstellung fertig.</string>
<string name="init_restore_failed">Wiederherstellung fehlgeschlagen.</string>
<string name="init_restore_running">Wiederherstellung der Cache-Datenbank…</string>
- <string name="init_restore_confirm">Die Cache-Datenbank ist leer. Soll die vorhandene Sicherung wiederhergestellt werden?</string>
- <string name="init_backup_last">Backup verfügbar von</string>
+ <string name="init_restore_confirm">Die Datenbank ist leer. Soll die vorhandene Sicherung wiederhergestellt werden?</string>
+ <string name="init_backup_last">Backup verfügbar vom</string>
<string name="init_backup_last_no">Keine Datei mit Datenbanksicherung gefunden.</string>
<string name="settings_info_offline_maps_title">Info zu Offline-Karten</string>
<string name="settings_info_offline_maps">c:ego ermöglicht es Offline-Karten zu verwenden. Die Karten können bei Mapsforge heruntergeladen werden oder es können eigene Karten aus OSM-Daten erstellt werden. Es mus zuerst ein Verzeichnis mit Offline-Karten gewählt werden, bevor eine Offline-Karte ausgewählt werden kann.</string>
<string name="settings_info_themes_title">Info zu Karten-Themes</string>
- <string name="settings_info_themes">c:geo kann eigene Karten-Themes für Offline-Karten verwenden. Du kannst sie dazu benutzen, um die Farbauswahl der Karte (z. B. für eine Nachtansicht) zu verändern oder um bestimmte Objekte wie z. B. Radwege oder Höhenlinien hervorzuheben.</string>
+ <string name="settings_info_themes">c:geo kann eigene Karten-Themes für Offline-Karten verwenden. Du kannst sie benutzen, um die Farbauswahl der Karte (z. B. für eine Nachtansicht) zu verändern oder um bestimmte Objekte wie Radwege oder Höhenlinien hervorzuheben.</string>
<string name="init_mapsource_select">Kartenquelle wählen</string>
+ <string name="settings_title_scale_map_text">Textgröße anpassen</string>
+ <string name="settings_summary_scale_map_text">Textgröße der Bezeichnungen auf der Offline-Karte entsprechend der Bildschirmauflösung anpassen</string>
<string name="init_map_directory_description">Verzeichnis mit Offline-Karten</string>
<string name="init_gpx_exportdir">Verzeichnis für GPX-Exporte</string>
<string name="init_gpx_importdir">Verzeichnis für GPX-Importe</string>
@@ -444,7 +457,7 @@
<string name="init_summary_trackautovisit">Trackables automatisch auf \"besuchen\" setzen</string>
<string name="init_sigautoinsert">Automatisch einfügen</string>
<string name="init_loaddirectionimg">Richtungs-Grafik</string>
- <string name="init_summary_loaddirectionimg">Richtungs-Grafik laden wenn nötig (nur Basic Member)</string>
+ <string name="init_summary_loaddirectionimg">Richtungs-Pfeil laden wenn nötig (nur Basic-Member)</string>
<string name="init_default_navigation_tool">Standardnavigation</string>
<string name="init_secondary_navigation_tool">Zweitnavigation</string>
<string name="init_default_navigation_tool_description">Hier kann das bevorzugte Navigationswerkzeug festgelegt werden.</string>
@@ -466,12 +479,15 @@
<string name="init_use_native_ua">Android-Browser</string>
<string name="init_summary_use_native_ua">Als Android-Browser identifizieren. Löst Login-Probleme einiger Netzanbieter.</string>
<string name="init_rendertheme_folder">Karten-Themes-Verzeichnis</string>
- <string name="settings_open_website">Öffne Webseite</string>
+ <string name="init_maintenance">Wartung</string>
+ <string name="init_maintenance_directories_note">c:geo speichert Bilder, Log-Bilder und weitere Dateien zu einem Cache in einem separaten Verzeichnis. In manchen Fällen (z.B. bei Sichern und Wiederherstellen der Datenbank) kann dieses Verzeichnis unnötige Daten enthalten, die gelöscht werden können.</string>
+ <string name="init_maintenance_directories">Verwaiste Daten löschen</string>
+ <string name="settings_open_website">Webseite öffnen</string>
<string name="settings_settings">Einstellungen</string>
<string name="settings_information">Information</string>
- <string name="settings_twitter_cache_message">Nachricht für gefundene Caches</string>
- <string name="settings_twitter_trackable_message">Nachricht für gefundene Trackables</string>
- <string name="init_ec_icons">Icons auf der Karte</string>
+ <string name="settings_twitter_cache_message">Nachricht für gefundenen Cache</string>
+ <string name="settings_twitter_trackable_message">Nachricht für gefundenen Trackable</string>
+ <string name="init_ec_icons">Kartensymbole</string>
<string name="settings_ec_icons_other">Eigener Stil</string>
<string name="settings_ec_icons_oc">Wie OC-Caches</string>
<string name="settings_features">Unterstützte Funktionen</string>
@@ -483,7 +499,7 @@
<string name="feature_own_coordinates">Modifizierte Cache-Koordinaten</string>
<string name="feature_search_keyword">Stichwortsuche</string>
<string name="feature_search_live_map">Live-Karte</string>
- <string name="feature_search_center">Suche mit Koordinaten </string>
+ <string name="feature_search_center">Suche mit Koordinaten</string>
<string name="feature_search_geocode">Suche mit Geocode</string>
<string name="feature_search_owner">Suche nach Besitzer</string>
<string name="feature_search_finder">Suche nach Finder</string>
@@ -507,9 +523,9 @@
<string name="auth_start">Starte Autorisierung</string>
<string name="auth_again">Neustarten</string>
<string name="auth_dialog_waiting">Warte auf %s…</string>
- <string name="auth_explain_short">Der folgende Prozess erlaubt <b>c:geo</b> auf %s zuzugreifen.</string>
- <string name="auth_explain_long">Ein Klick auf \"c:geo autorisieren\" startet den Prozess. Dieser Prozess öffnet einen Webbrowser mit einer %s Seite um sich dort einzuloggen und <b>c:geo</b> Zugriff zu erlauben.</string>
- <string name="auth_dialog_completed_twitter">c:geo ist nun autorisiert auf Twitter zu posten.</string>
+ <string name="auth_explain_short">Der folgende Prozess erlaubt es <b>c:geo</b> auf %s zuzugreifen.</string>
+ <string name="auth_explain_long">\"Starte Autorisierung\" öffnet die Webseite von %s. Bitte dort anmelden und <b>c:geo</b> Zugriff auf den Account erlauben. Das ist alles.</string>
+ <string name="auth_dialog_completed_twitter">c:geo ist nun autorisiert, Tweets bei Twitter zu erstellen.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo ist nun autorisiert, Caches zu laden und auf %s zu loggen.</string>
@@ -533,14 +549,14 @@
<string name="cache_log_image_default_title">Bild</string>
<string name="cache_personal_note">Persönliche Notiz</string>
<string name="cache_personal_note_edit">Bearbeiten</string>
- <string name="cache_personal_note_limit">Upload persönlicher Notizen begrenzt</string>
+ <string name="cache_personal_note_limit">Upload der persönlicher Notiz ist begrenzt</string>
<string name="cache_personal_note_truncation">Diese persönliche Notiz wird von Geocaching.com nach %d Zeichen abgeschnitten.</string>
<string name="cache_personal_note_upload">Hochladen</string>
- <string name="cache_personal_note_uploading">Persönliche Notizen werden gesendet</string>
- <string name="cache_personal_note_upload_done">Persönliche Notizen wurden hochgeladen</string>
- <string name="cache_personal_note_upload_cancelled">Hochladen der Notizen abgebrochen</string>
+ <string name="cache_personal_note_uploading">Persönliche Notiz wird gesendet</string>
+ <string name="cache_personal_note_upload_done">Persönliche Notiz wurde hochgeladen</string>
+ <string name="cache_personal_note_upload_cancelled">Hochladen der Notiz abgebrochen</string>
<string name="cache_personal_note_unstored">Cache noch nicht gespeichert</string>
- <string name="cache_personal_note_store">Der Cache wird zunächst gespeichert, damit persönliche Notizen möglich sind.</string>
+ <string name="cache_personal_note_store">Der Cache wird zunächst gespeichert, damit die persönliche Notiz möglich ist.</string>
<string name="cache_description">Beschreibung</string>
<string name="cache_description_long">Ausführliche Beschreibung</string>
<string name="cache_description_table_note">Diese Beschreibung enthält Tabellenelemente, die evtl. nur auf %s korrekt angezeigt werden.</string>
@@ -611,6 +627,7 @@
<string name="cache_menu_oruxmaps">OruxMaps</string>
<string name="cache_menu_cachebeacon">Cache Beacon</string>
<string name="cache_menu_navigon">Navigon</string>
+ <string name="cache_menu_pebble">Pebble Smartwatch</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Gespeicherter Log</string>
<string name="cache_status_found">Gefunden</string>
@@ -638,7 +655,6 @@
<string name="cache_coordinates">Koordinaten</string>
<string name="cache_coordinates_original">Ursprüngliche Koordinaten</string>
<string name="cache_spoiler_images_title">Hinweisbilder</string>
- <string name="cache_images_title">Bilder</string>
<string name="cache_log_types">Logs</string>
<string name="cache_coordinates_no">Dieser Cache hat keine Koordinaten.</string>
<string name="cache_clear_history">Verlauf leeren</string>
@@ -675,6 +691,7 @@
<string name="gpx_import_delete_title">Datei löschen</string>
<string name="gpx_import_delete_message">Datei %s löschen?</string>
<string name="gpx_import_select_list_title">Importiere GPX nach</string>
+ <string name="gpx_import_android">Import von Android</string>
<string name="map_file_select_title">Kartendatei wählen</string>
<string name="web_import_title">Aus dem Internet importieren</string>
<string name="web_import_waiting">Warte auf neue Caches aus dem Internet…</string>
@@ -728,8 +745,8 @@
<string name="map_trail_hide">Spur ausblenden</string>
<string name="map_circles_show">Kreise anzeigen</string>
<string name="map_circles_hide">Kreise verbergen</string>
- <string name="map_mycaches_show">Eigene/Gefundene anzeigen</string>
- <string name="map_mycaches_hide">Eigene/Gefundene verbergen</string>
+ <string name="map_mycaches_show">Eigene/gefundene Caches anzeigen</string>
+ <string name="map_mycaches_hide">Eigene/gefundene Caches ausblenden</string>
<string name="map_theme_builtin">Standard</string>
<string name="map_theme_select">Kartendarstellung wählen</string>
<string name="map_live_enable">Aktualisierung einschalten</string>
@@ -745,7 +762,6 @@
<string name="map_strategy_auto">Geschwindigkeitsabhängig</string>
<string name="map_strategy_detailed">Detailliert</string>
<string name="live_map_notification">Auf der neuen Live-Karte sind die Koordinaten nicht immer genau. Eventuell ungenaue Koordinaten sind mit einem orangen Kreis markiert.\nDas Öffnen der Cache-Details oder das Speichern des Cache liefert immer genaue Koordinaten.\n\nMehr Informationen über alle Änderungen befinden sich auf der \"Über c:geo\"-Seite in der App.</string>
- <string name="live_map_note_dontshow">Nicht mehr anzeigen</string>
<string name="search_bar_hint">Suche nach Caches</string>
<string name="search_bar_desc">Caches (Geocode, Stichwort), Trackables (TB-Code)</string>
<string name="search_coordinates">Koordinaten</string>
@@ -772,7 +788,7 @@
<string name="search_address_result">Gefundene Orte</string>
<string name="search_own_caches">Meine Caches suchen</string>
<string name="search_pocket_title">Pocket Query</string>
- <string name="search_pocket_loading">Lade Liste der Pocket Queries</string>
+ <string name="search_pocket_loading">Eine Liste von Pocket Queries laden</string>
<string name="search_pocket_select">Pocket Query wählen</string>
<string name="trackable">Trackable</string>
<string name="trackable_details_loading">Lade Details des Trackable…</string>
@@ -793,7 +809,7 @@
<string name="trackable_origin">Ursprungsort</string>
<string name="trackable_unknown">Unbekannt</string>
<string name="trackable_released">Ausgesetzt</string>
- <string name="trackable_distance">Gereiste Strecke</string>
+ <string name="trackable_distance">Zurückgelegte Strecke</string>
<string name="trackable_touch">Trackable-Aktion</string>
<string name="trackable_not_activated">Trackable nicht aktiviert</string>
<string name="geokret_type_traditional">Traditionell</string>
@@ -806,7 +822,7 @@
<string name="user_menu_view_found">Gefundene Caches</string>
<string name="user_menu_open_browser">Profil im Browser öffnen</string>
<string name="user_menu_send_message">Nachricht senden</string>
- <string name="user_menu_open_contact">Öffne Adressbuch</string>
+ <string name="user_menu_open_contact">Kontakt öffnen</string>
<string name="navigation">Navigation</string>
<string name="compass_title">Kompass</string>
<string name="use_gps">Nur GPS nutzen</string>
@@ -815,14 +831,19 @@
<string name="destination_set">Ziel setzen</string>
<string name="navigation_direct_navigation">Direkte Navigation</string>
<string name="navigation_target">Ziel</string>
+ <string name="err_nav_no_coordinates">Die Navigation kann ohne Koordinaten nicht gestartet werden</string>
<string name="license">Lizenz</string>
<string name="license_show">Zeige Lizenz</string>
<string name="license_dismiss">Ablehnen</string>
<string name="helper_calendar_title">c:geo Kalender Add-on</string>
- <string name="helper_calendar_missing">c:geo Kalender Add-on nicht installiert</string>
+ <string name="helper_calendar_missing">Das c:geo Kalender Add-on ist nicht installiert.</string>
<string name="helper_calendar_description">Ermöglicht die Übernahme von Event-Caches in den Kalender.</string>
+ <string name="helper_sendtocgeo_title">Send to c:geo</string>
+ <string name="helper_contacts_title">c:geo Kontakte Add-on</string>
+ <string name="helper_contacts_description">Ermöglicht das direkte Öffnen von Kontakten (aus dem eigenen Adressbuch) von Logeinträgen aus, so dass man Freunde einfacher um Hilfe fragen kann.</string>
+ <string name="helper_sendtocgeo_description">Send to c:geo ist eine Browsererweiterung <strong>für Ihren PC</strong>. Beim Durchsuchen von geocaching.com können Sie Caches mit einem Klick im Browser direkt an Ihr Smartphone übermitteln.</string>
<string name="helper_locus_title">Locus</string>
- <string name="helper_locus_description">Sehr gute App für Online- und Offline-Karten (nur Rasterkarten) mit vielen weiteren Funktionen wie z.B. Trackaufzeichnung, POIs und vieles mehr.</string>
+ <string name="helper_locus_description">Sehr gute App für Online- und Offline-Karten (nur Rasterkarten) mit vielen weiteren Funktionen wie z. B. Trackaufzeichnung, POIs und vieles mehr.</string>
<string name="helper_gpsstatus_title">GPS-Status</string>
<string name="helper_gpsstatus_description">Das Radar dieser App kann in c:geo verwendet und zusätzlich viele GPS-bezogene Informationen abgerufen werden.</string>
<string name="helper_bluetoothgps_title">Bluetooth GPS</string>
@@ -830,9 +851,9 @@
<string name="helper_barcode_title">Barcode-Scanner</string>
<string name="helper_barcode_description">Es gibt GreaseMonkey-Scripte und Webseiten, die Geocodes als Strichcode darstellen können. Bei Verwendung dieser Skripte kann c:geo über diese App den Geocode eines Caches direkt vom Bildschirm des Computers ablesen.</string>
<string name="helper_pocketquery_title">Pocket Query Creator</string>
- <string name="helper_pocketquery_description">Ermöglicht das einfache Erzeugen und Herunterladen von Pocket Queries basierend auf der aktuellen Position oder einem auf der Karte gewählten Punkt. Setzt eine Premiummitgliedschaft bei geocaching.com voraus.</string>
+ <string name="helper_pocketquery_description">Ermöglicht das einfache Erzeugen und Herunterladen von Pocket Queries basierend auf der aktuellen Position oder einem auf der Karte gewählten Punkt. Setzt eine Premium-Mitgliedschaft bei geocaching.com voraus.</string>
<string name="helper_google_translate_title">Google Übersetzer</string>
- <string name="helper_google_translate_description">Wenn man Sprachpakete in der Übersetzer-App herunterlädt, kann man Cachebeschreibungen durch langen Klick darauf auch offline übersetzen.</string>
+ <string name="helper_google_translate_description">Wenn Sie Übersetzungspakete mit der Google Übersetzer-App herunterladen, können Sie Cache-Beschreibungen in c:geo durch langes Drücken auf den Cache-Beschreibungstext übersetzen (ohne Internetverbindung) .</string>
<string name="addon_missing_title">Add-On fehlt</string>
<string name="addon_download_prompt">Jetzt im Google Play Store herunterladen</string>
<string name="export">Exportieren</string>
@@ -846,7 +867,7 @@
<string name="export_fieldnotes_onlynew">Nur seit letztem Export</string>
<string name="export_fieldnotes_creating">Erstelle Field Notes…</string>
<string name="export_gpx">GPX</string>
- <string name="export_gpx_info">GPX-Datei wird nach %1$s mit dem aktuellen Datum und Zeit als Dateiname exportiert.</string>
+ <string name="export_gpx_info">GPX-Datei wird nach %1$s mit aktuellem Datum und Zeit als Dateiname exportiert.</string>
<string name="export_gpx_to">Exportierte GPX-Datei senden an</string>
<string name="attribute_dogs_yes">Hunde erlaubt</string>
<string name="attribute_dogs_no">Hunde nicht erlaubt</string>
@@ -872,8 +893,8 @@
<string name="attribute_onehour_no">Benötigt mehr als eine Stunde</string>
<string name="attribute_scenic_yes">Besondere Aussicht</string>
<string name="attribute_scenic_no">Keine besondere Aussicht</string>
- <string name="attribute_hiking_yes">Anstrengender Marsch</string>
- <string name="attribute_hiking_no">Kein anstrengender Marsch</string>
+ <string name="attribute_hiking_yes">Anstrengende Wanderung</string>
+ <string name="attribute_hiking_no">Keine anstrengende Wanderung</string>
<string name="attribute_climbing_yes">Schwierige Kletterei</string>
<string name="attribute_climbing_no">Keine schwierige Kletterei</string>
<string name="attribute_wading_yes">Waten möglicherweise nötig</string>
@@ -900,12 +921,12 @@
<string name="attribute_parkngrab_no">Kein Halten und Mitnehmen</string>
<string name="attribute_abandonedbuilding_yes">Leerstehendes Gebäude</string>
<string name="attribute_abandonedbuilding_no">Kein leerstehendes Gebäude</string>
- <string name="attribute_hike_short_yes">Kurzer Marsch (weniger als 1 km)</string>
- <string name="attribute_hike_short_no">Kein kurzer Marsch</string>
- <string name="attribute_hike_med_yes">Mittlerer Marsch (1 bis 10 km)</string>
- <string name="attribute_hike_med_no">Kein mittlerer Marsch</string>
- <string name="attribute_hike_long_yes">Langer Marsch (mehr als 10 km)</string>
- <string name="attribute_hike_long_no">Kein langer Marsch</string>
+ <string name="attribute_hike_short_yes">Kurze Wanderung (weniger als 1 km)</string>
+ <string name="attribute_hike_short_no">Keine kurze Wanderung</string>
+ <string name="attribute_hike_med_yes">Mittlere Wanderung (1 bis 10 km)</string>
+ <string name="attribute_hike_med_no">Keine mittlere Wanderung</string>
+ <string name="attribute_hike_long_yes">Lange Wanderung (mehr als 10 km)</string>
+ <string name="attribute_hike_long_no">Keine lange Wanderung</string>
<string name="attribute_seasonal_yes">Saisonabhängiger Zugang</string>
<string name="attribute_seasonal_no">Zugang nicht saisonabhängig</string>
<string name="attribute_touristok_yes">Touristenfreundlich</string>
@@ -917,47 +938,47 @@
<string name="attribute_landf_yes">\'Lost and found\' Tour</string>
<string name="attribute_landf_no">Keine \'Lost and found\' Tour</string>
<string name="attribute_partnership_yes">Partnerschafts-Cache</string>
- <string name="attribute_partnership_no">kein Partnerschafts-Cache</string>
- <string name="attribute_fee_yes">Eintrittsgeld notwendig</string>
- <string name="attribute_fee_no">Kein Eintrittsgeld notwendig</string>
- <string name="attribute_rappelling_yes">Kletterausrüstung notwendig</string>
- <string name="attribute_rappelling_no">Kletterausrüstung nicht notwendig</string>
- <string name="attribute_boat_yes">Boot notwendig</string>
- <string name="attribute_boat_no">Boot nicht notwendig</string>
- <string name="attribute_scuba_yes">Tauchausrüstung notwendig</string>
- <string name="attribute_scuba_no">Tauchausrüstung nicht notwendig</string>
- <string name="attribute_flashlight_yes">Taschenlampe notwendig</string>
- <string name="attribute_flashlight_no">Taschenlampe nicht notwendig</string>
- <string name="attribute_uv_yes">UV-Taschenlampe notwendig</string>
- <string name="attribute_uv_no">UV-Taschenlampe nicht notwendig</string>
- <string name="attribute_snowshoes_yes">Schneeschuhe notwendig</string>
- <string name="attribute_snowshoes_no">Schneeschuhe nicht notwendig</string>
- <string name="attribute_skiis_yes">Ski notwendig</string>
- <string name="attribute_skiis_no">Ski nicht notwendig</string>
- <string name="attribute_s_tool_yes">Besondere Werkzeuge notwendig</string>
- <string name="attribute_s_tool_no">Besondere Werkzeuge nicht notwendig</string>
- <string name="attribute_wirelessbeacon_yes">Radiosignal</string>
- <string name="attribute_wirelessbeacon_no">Kein Radiosignal</string>
- <string name="attribute_treeclimbing_yes">Auf Bäume klettern notwendig</string>
- <string name="attribute_treeclimbing_no">Auf Bäume klettern nicht notwendig</string>
+ <string name="attribute_partnership_no">Kein Partnerschafts-Cache</string>
+ <string name="attribute_fee_yes">Eintritts- oder Parkplatzgebühr</string>
+ <string name="attribute_fee_no">Keine Eintritts- oder Parkplatzgebühr</string>
+ <string name="attribute_rappelling_yes">Kletterausrüstung erforderlich</string>
+ <string name="attribute_rappelling_no">Keine Kletterausrüstung erforderlich</string>
+ <string name="attribute_boat_yes">Boot erforderlich</string>
+ <string name="attribute_boat_no">Kein Boot erforderlich</string>
+ <string name="attribute_scuba_yes">Tauchausrüstung erforderlich</string>
+ <string name="attribute_scuba_no">Tauchausrüstung nicht erforderlich</string>
+ <string name="attribute_flashlight_yes">Taschenlampe erforderlich</string>
+ <string name="attribute_flashlight_no">Taschenlampe nicht erforderlich</string>
+ <string name="attribute_uv_yes">UV-Lampe erforderlich</string>
+ <string name="attribute_uv_no">UV-Lampe nicht erforderlich</string>
+ <string name="attribute_snowshoes_yes">Schneeschuhe erforderlich</string>
+ <string name="attribute_snowshoes_no">Schneeschuhe nicht erforderlich</string>
+ <string name="attribute_skiis_yes">Langlauf-Ski erforderlich</string>
+ <string name="attribute_skiis_no">Langlauf-Ski nicht erforderlich</string>
+ <string name="attribute_s_tool_yes">Besondere Werkzeuge erforderlich</string>
+ <string name="attribute_s_tool_no">Keine besonderen Werkzeuge erforderlich</string>
+ <string name="attribute_wirelessbeacon_yes">Cache mit Funk-Sender (Chirp)</string>
+ <string name="attribute_wirelessbeacon_no">Kein Cache mit Funk-Sender (Chirp)</string>
+ <string name="attribute_treeclimbing_yes">Auf Bäume klettern erforderlich</string>
+ <string name="attribute_treeclimbing_no">Auf Bäume klettern nicht erforderlich</string>
<string name="attribute_poisonoak_yes">Giftige Pflanzen</string>
<string name="attribute_poisonoak_no">Keine giftigen Pflanzen</string>
<string name="attribute_dangerousanimals_yes">Gefährliche Tiere</string>
<string name="attribute_dangerousanimals_no">Keine gefährlichen Tiere</string>
<string name="attribute_ticks_yes">Zecken</string>
<string name="attribute_ticks_no">Keine Zecken</string>
- <string name="attribute_mine_yes">Verlassene Minen</string>
- <string name="attribute_mine_no">Keine verlassenen Minen</string>
- <string name="attribute_cliff_yes">Kliff/Abhang</string>
- <string name="attribute_cliff_no">Kein Kliff/Abhang</string>
+ <string name="attribute_mine_yes">Stillgelegtes Bergwerk</string>
+ <string name="attribute_mine_no">Kein stillgelegtes Bergwerk</string>
+ <string name="attribute_cliff_yes">Abhang / Steinschlaggefahr</string>
+ <string name="attribute_cliff_no">Kein Abhang / Steinschlaggefahr</string>
<string name="attribute_hunting_yes">Jagdgebiet</string>
<string name="attribute_hunting_no">Kein Jagdgebiet</string>
<string name="attribute_danger_yes">Gefährliches Gebiet</string>
<string name="attribute_danger_no">Kein gefährliches Gebiet</string>
<string name="attribute_thorn_yes">Dornen</string>
<string name="attribute_thorn_no">Keine Dornen</string>
- <string name="attribute_wheelchair_yes">Rollstuhlgängig</string>
- <string name="attribute_wheelchair_no">Nicht Rollstuhlgängig</string>
+ <string name="attribute_wheelchair_yes">Rollstuhlgerecht</string>
+ <string name="attribute_wheelchair_no">Nicht Rollstuhlgerecht</string>
<string name="attribute_parking_yes">Parkplatz vorhanden</string>
<string name="attribute_parking_no">Kein Parkplatz vorhanden</string>
<string name="attribute_public_yes">Öffentliche Verkehrsmittel</string>
@@ -1040,6 +1061,38 @@
<string name="attribute_unknown_no">Keine unbekannten Attribute</string>
<string name="attribute_geotour_yes">Teil einer GeoTour</string>
<string name="attribute_geotour_no">Kein Teil einer GeoTour</string>
+ <string name="attribute_kids_2_yes">Kinderfreundlich</string>
+ <string name="attribute_kids_2_no">Nicht kinderfreundlich</string>
+ <string name="attribute_historic_site_yes">Historische Stätte</string>
+ <string name="attribute_historic_site_no">Keine historische Stätte</string>
+ <string name="attribute_magnetic_yes">Magnetischer Cache</string>
+ <string name="attribute_magnetic_no">Kein magnetischer Cache</string>
+ <string name="attribute_usb_cache_yes">\"dead drop\" USB-Cache</string>
+ <string name="attribute_usb_cache_no">Kein \"dead drop\" USB-Cache</string>
+ <string name="attribute_shovel_yes">Sie brauchen vielleicht eine Schaufel</string>
+ <string name="attribute_shovel_no">Sie brauchen keine Schaufel</string>
+ <string name="attribute_specific_access_yes">Verfügbar zu bestimmten Zeiten (könnte Eintritt kosten)</string>
+ <string name="attribute_specific_access_no">Zu jeder Zeit erreichbar</string>
+ <string name="attribute_pedestrian_only_yes">Zugang nur für Fußgänger</string>
+ <string name="attribute_pedestrian_only_no">Zugang nicht nur für Fußgänger</string>
+ <string name="attribute_nature_cache_yes">Versteckt in natürlicher Umgebung (Wald, Berg, usw.)</string>
+ <string name="attribute_nature_cache_no">Nicht versteckt in natürlicher Umgebung</string>
+ <string name="attribute_byop_yes">Eigener Stift erforderlich</string>
+ <string name="attribute_byop_no">Eigener Stift nicht erforderlich</string>
+ <string name="attribute_safari_cache_yes">Reverse Cache</string>
+ <string name="attribute_safari_cache_no">Kein Reverse Cache</string>
+ <string name="attribute_quick_cache_yes">Schneller Cache</string>
+ <string name="attribute_quick_cache_no">Kein schneller Cache</string>
+ <string name="attribute_wherigo_yes">Wherigo Cache</string>
+ <string name="attribute_wherigo_no">kein Wherigo Cache</string>
+ <string name="attribute_audio_cache_yes">Beschreibung enthält eine Audio-Datei</string>
+ <string name="attribute_audio_cache_no">Beschreibung enthält keine Audio-Datei</string>
+ <string name="attribute_geohotel_yes">GeoHotel Cache</string>
+ <string name="attribute_geohotel_no">kein GeoHotel Cache</string>
+ <string name="attribute_survey_marker_yes">In der Nähe eines Vermessungspunktes</string>
+ <string name="attribute_survey_marker_no">Nicht in der Nähe eines Vermessungspunktes</string>
+ <string name="attribute_offset_cache_yes">Offset Cache</string>
+ <string name="attribute_offset_cache_no">Kein Offset Cache</string>
<string name="quote">Um Geocachen einfacher zu machen, um es Anwendern bequemer zu machen.</string>
<string name="powered_by">carnero</string>
<string name="support">Support: <a href="">support@cgeo.org</a></string>
@@ -1067,6 +1120,9 @@
<string name="tts_one_oclock">ein Uhr</string>
<string name="tts_oclock">%s Uhr</string>
<string name="clipboard_copy_ok">In Zwischenablage kopiert</string>
+ <string name="percent_favorite_points">% Favoriten</string>
+ <string name="cgeo_shortcut">c:geo Shortcut</string>
+ <string name="create_shortcut">Shortcut erstellen</string>
<string-array name="log_image_scales">
<item>Keine Skalierung</item>
<item>512 px</item>
@@ -1110,6 +1166,4 @@
<item quantity="one">%s Favorit</item>
<item quantity="other">%s Favoriten</item>
</plurals>
- <string name="percent_favorite_points">% Favoriten</string>
- <string name="create_shortcut">Shortcut erstellen</string>
</resources>
diff --git a/main/res/values-es/strings.xml b/main/res/values-es/strings.xml
index b502385..0e208c9 100644
--- a/main/res/values-es/strings.xml
+++ b/main/res/values-es/strings.xml
@@ -77,6 +77,7 @@
<string name="log_post">Enviar registro</string>
<string name="log_post_rate">Enviar registro y puntuación</string>
<string name="log_post_no_rate">Enviar registro sin puntuar</string>
+ <string name="log_post_not_possible">Cargando página de registro…</string>
<string name="log_add">Añadir</string>
<string name="log_rating">Puntuación</string>
<string name="log_no_rating">Sin puntuación</string>
@@ -113,26 +114,34 @@
<string name="log_image_caption">Título</string>
<string name="log_image_description">Descripción</string>
<string name="log_image_scale">Redimensionamiento</string>
+ <string name="translate_to_sys_lang">Traducir al %s</string>
+ <string name="translate_to_english">Traducir al inglés</string>
+ <string name="translate_length_warning">La traducción podría fallar con un texto muy largo.</string>
<string name="err_none">Aceptar</string>
- <string name="err_start">Comunicación no iniciada</string>
<string name="err_parse">Error procesando la página de acceso</string>
<string name="err_server">Error conectando a Geocaching.com (¿servidor o conexión caidos?)</string>
<string name="err_login">No hay información de acceso guardada</string>
- <string name="err_login_failed">Lo siento, c:geo no puede conectarse.</string>
+ <string name="err_login_failed_toast">c:geo no puede iniciar sesión. c:geo puede funcionar sin conexión con los caches que hayan sido almacenados. Comprueba las opciones de inicio de sesión o active la conexión a internet.</string>
<string name="err_unknown">Error desconocido</string>
<string name="err_comm">Error de comunicación desconocido</string>
<string name="err_missing_auth">Falta nombre de usuario o contraseña.</string>
<string name="err_wrong">Información de acceso errónea</string>
+ <string name="err_maintenance">Geocaching.com no está disponible debido a labores de mantenimiento. c:geo puede funcionar sin conexión con los caches que hayan sido almacenados previamente.</string>
<string name="err_license">El usuario no ha aceptado las condiciones de Geocaching.com license agreement, por lo que c:geo no puede cargar las coordenadas de los escondites.</string>
+ <string name="err_unvalidated_account">Antes debe validar su cuenta en la página web Geocaching.com.</string>
+ <string name="err_unpublished">El caché solicitado aún no ha sido publicado.</string>
+ <string name="err_premium_only">Este caché solo está disponible para los miembros Premium de Geocaching.com.</string>
<string name="err_detail_open">Lo siento, c:geo no puede abrir los detalles del escondite.</string>
<string name="err_detail_cache">Lo siento, c:geo no puee mostrar el escondite que quieres. ¿Segur que es un geocache?</string>
<string name="err_detail_cache_find">Lo siento, c:geo no puede encontrar escondites</string>
<string name="err_detail_cache_find_some">Lo siento, c:geo no puede encontrar ese escondite.</string>
<string name="err_detail_cache_find_any">Lo siento, c:geo no puede encontrar algunos escondites.</string>
<string name="err_detail_cache_forgot">Lo siento, c:geo ha olvidado el escondite que quieres.</string>
+ <string name="err_detail_google_maps_limit_reached">c:geo no ha podido descargar los mapas estáticos. Quizá haya alcanzado el límite de uso del API de Google Maps.</string>
<string name="err_detail_no_spoiler">c:geo no ha encontrado imágenes/pista para este escondite.</string>
<string name="err_detail_no_map_static">c:geo no ha encontrado mapas estáticos para este escondite.</string>
<string name="err_detail_not_load_map_static">Lo siento, c:geo no ha podido cargar mapas estáticos.</string>
+ <string name="err_detail_still_working">Todavía hay otra tarea en ejecución.</string>
<string name="err_watchlist_still_managing">Seguir gestionando tu lista de seguimiento.</string>
<string name="err_watchlist_failed">Error al cambiar la lista de seguimiento.</string>
<string name="err_application_no">c:geo no encuentra ninguna aplicación válida.</string>
@@ -144,6 +153,9 @@
<string name="err_load_descr_failed">Lo siento, c:geo no ha podido cargar la descripción.</string>
<string name="err_location_unknown">c:geo no conoce la ubicación del escondite.</string>
<string name="err_missing_device_name">Debes indicar un nombre de dispositivo antes de registrarte.</string>
+ <string name="err_favorite_failed">Falló el cambio de estado de favorito.</string>
+ <string name="err_select_logimage_failed">No se pudo seleccionar una imagen para el registro.</string>
+ <string name="err_acquire_image_failed">No se pudo obtener una imagen.</string>
<string name="err_tb_display">\"Lo siento, c:geo no puede mostrar el rastreable que buscas. ¿Es realmente rastreable?</string>
<string name="err_tb_details_open">Lo siento, c:geo no puede abrir los detalles del rastreable.</string>
<string name="err_tb_forgot_saw">Lo siento, c:geo ha olvidado qué rastreable has visto.</string>
@@ -160,12 +172,13 @@
<string name="err_log_load_data">Lo siento, c:geo no puede cargar los datos necesarios para registrar la visita.</string>
<string name="err_log_load_data_again">Lo siento, c:geo no puede cargar los datos necesarios para registrar la visita. Intentándolo de nuevo.</string>
<string name="err_log_load_data_still">c:geo sigue cargando datos para registrar el escondite. Debes esperar un poquito mas.</string>
- <string name="err_log_failed_server">Lo siento, c:geo no ha podido enviar el registro porque el servidor no responde.</string>
<string name="err_log_post_failed">Lo siento, c:geo no ha podido enviar el registro.</string>
+ <string name="err_logimage_post_failed">Parece que su imagen de registro no se ha enviado al servidor. Compruébelo en Geocaching.com.</string>
<string name="err_search_address_forgot">Lo siento, c:geo ha olvidado la dirección que buscabas.</string>
<string name="err_parse_lat">Lo siento, c:geo no puede procesar la latitud.</string>
<string name="err_parse_lon">Lo siento, c:geo no puede procesar la longitud.</string>
<string name="err_parse_dist">Lo siento, c:geo can\'t no puede procesar la distancia.</string>
+ <string name="err_parse_lat_lon">c:geo no ha podido interpretar la latitud o la longitud.</string>
<string name="warn_save_nothing">No hay nada para guardar.</string>
<string name="warn_no_cache_coord">No hay escondite con coordenadas.</string>
<string name="warn_no_coordinates">No se han dado coordenadas.</string>
@@ -179,30 +192,43 @@
<string name="warn_search_help_tb">Escribe el código del rastreable. Por ejemplo \"TB29QMZ\".</string>
<string name="warn_log_text_fill">Escribe algún texto de registro.</string>
<string name="warn_load_images">Error al cargar las imágenes.</string>
+ <string name="warn_invalid_mapfile">El archivo de mapa seleccionado no es un archivo de mapsforge versión 0.3.0 válido.\nLos mapas sin conexión no están disponibles.</string>
+ <string name="warn_deprecated_mapfile">Está usando una versión obsoleta del fichero de mapa (0.2.4)\nConsidere cambiar a un archivo versión 0.3.0.\nc:geo no será compatible con mapas versión 0.2.4 en nuestra siguiente versión.</string>
+ <string name="warn_nonexistant_mapfile">El archivo de mapa seleccionado no existe.\nLos mapas sin conexión no están disponibles.</string>
+ <string name="warn_rendertheme_missing">No se ha encontrado el esquema de colores del mapa.</string>
+ <string name="warn_pocket_query_select">No ha seleccionado ninguna Pocket Query.</string>
+ <string name="warn_no_pocket_query_found">No se ha encontrado ninguna Pocket Query en Geocaching.com.</string>
<string name="info_log_posted">c:geo registro enviado sin problemas.</string>
<string name="info_log_saved">c:geo guardado sin problemas.</string>
<string name="info_log_cleared">Registro borrado.</string>
<string name="info_log_type_changed">¡El tipo de registro ha sido cambiado!</string>
+ <string name="info_select_logimage_cancelled">La selección de imagen o captura ha sido cancelada.</string>
+ <string name="info_stored_image">Nueva imagen guardada en:</string>
+ <string name="info_storing_static_maps">Intentando almacenar los mapas estáticos</string>
<string name="loc_last">Última conocida</string>
<string name="loc_net">Red</string>
<string name="loc_gps">GPS</string>
<string name="loc_sat">Sat</string>
<string name="loc_trying">Intentando ubicar</string>
<string name="loc_no_addr">Dirección desconocida</string>
+ <string name="loc_gps_disabled">GPS desactivado</string>
<string name="menu_about">Sobre c:geo</string>
<string name="menu_helpers">Programas útiles</string>
<string name="menu_settings">Ajustes</string>
<string name="menu_history">Historia</string>
<string name="menu_filter">Filtro</string>
+ <string name="menu_scan_geo">Escánear geocódigo</string>
<string name="live_map_button">Mapa</string>
<string name="caches_nearby_button">Cercanos</string>
<string name="advanced_search_button">Buscar</string>
<string name="stored_caches_button">Guardados</string>
<string name="any_button">Manual</string>
+ <string name="unknown_scan">No se ha encontrado ningún geocódigo en la imagen.</string>
<string name="caches_no_cache">Ningún escondite</string>
<string name="caches_more_caches">Buscar mas</string>
<string name="caches_more_caches_no">No hay mas escondites</string>
<string name="caches_more_caches_loading">Cargando escondites…</string>
+ <string name="caches_more_caches_currently">actualmente</string>
<string name="caches_downloading">Descargando escondites…\nFaltan: </string>
<string name="caches_eta_ltm">Menos de un minuto</string>
<string name="caches_store_offline">Usar sin conexión luego</string>
@@ -215,14 +241,18 @@
<string name="caches_sort_difficulty">dificultad</string>
<string name="caches_sort_terrain">terreno</string>
<string name="caches_sort_size">tamaño</string>
- <string name="caches_sort_favorites">popularidad</string>
- <string name="caches_sort_favorites_ratio">popularidad [%]</string>
+ <string name="caches_sort_favorites">Favoritos</string>
+ <string name="caches_sort_favorites_ratio">Favoritos [%]</string>
<string name="caches_sort_name">nombre</string>
<string name="caches_sort_geocode">Código</string>
<string name="caches_sort_rating">valoración</string>
<string name="caches_sort_vote">votar (valoración propia)</string>
<string name="caches_sort_inventory">recuento de inventario</string>
<string name="caches_sort_date_hidden">fecha</string>
+ <string name="caches_sort_date_logged">Fecha de registro</string>
+ <string name="caches_sort_finds">Encontrados</string>
+ <string name="caches_sort_state">Estado</string>
+ <string name="caches_sort_storage">Fecha almacenada en el dispositivo</string>
<string name="caches_select_mode">Modo selección</string>
<string name="caches_select_mode_exit">Salir de modo selección</string>
<string name="caches_select_invert">Invertir selección</string>
@@ -235,11 +265,13 @@
<string name="caches_drop_stored">Descartar guardados</string>
<string name="caches_drop_progress">Borrando escondites</string>
<string name="caches_drop_all_and_list">Descartar todos y borrar lista</string>
+ <string name="caches_delete_events">Borrar eventos pasados</string>
<string name="caches_refresh_selected">Actualizar seleccionados</string>
<string name="caches_refresh_all">Actualizar todos</string>
<string name="caches_move_selected">Mover seleccionados</string>
<string name="caches_move_all">Mover todos</string>
<string name="caches_map_locus">Locus</string>
+ <string name="caches_map_locus_export">Exportar a Locus</string>
<string name="caches_recaptcha_title">reCAPTCHA</string>
<string name="caches_recaptcha_explanation">Debes escribir el texto de la imagen. Es importante que descargues las coordenadas de los escondites. Es opcional y lo puedes desactivar en Ajustes.</string>
<string name="caches_recaptcha_hint">Texto de la imagen</string>
@@ -250,13 +282,23 @@
<string name="caches_filter_type">tipo</string>
<string name="caches_filter_track">con rastreables</string>
<string name="caches_filter_clear">limpiar filtros</string>
+ <string name="caches_filter_modified">Con las coordenadas modificadas</string>
+ <string name="caches_filter_origin">Coordenadas originales</string>
+ <string name="caches_filter_distance">Distancia</string>
+ <string name="caches_filter_personal_note">Con nota personal</string>
+ <string name="caches_filter_popularity">Favoritos</string>
+ <string name="caches_filter_popularity_ratio">Favoritos [%]</string>
<string name="caches_removing_from_history">Borrando del historial…</string>
+ <string name="caches_clear_offlinelogs">Borrar registros sin conexión</string>
+ <string name="caches_clear_offlinelogs_progress">Borrando registros sin conexión</string>
<string name="list_menu">Lista</string>
<string name="list_menu_create">Crear nueva lista</string>
<string name="list_menu_drop">Borrar lista actual</string>
<string name="list_menu_change">Cambiar lista</string>
+ <string name="list_menu_rename">Renombrar la lista actual</string>
<string name="list_title">Escoger lista</string>
<string name="list_inbox">Guardadas</string>
+ <string name="list_all_lists">Todos los caches</string>
<string name="list_dialog_create_title">Nueva lista</string>
<string name="list_dialog_create">Crear</string>
<string name="list_dialog_create_ok">Se ha creado una nueva lista</string>
@@ -266,10 +308,29 @@
<string name="list_dialog_remove">Borrar</string>
<string name="list_dialog_remove_ok">La lista ha sido borrada</string>
<string name="list_dialog_remove_err">c:geo no ha podido borrar la lista actual</string>
+ <string name="list_dialog_rename_title">Renombrar lista</string>
+ <string name="list_dialog_rename">Renombrar</string>
+ <string name="about_version">Versión</string>
<string name="about_changelog">Cambios</string>
<string name="about_donate">Donar</string>
<string name="about_donation_more">Donar\nmas</string>
<string name="about_contributors">Colaboradores</string>
+ <string name="about_license">Licencia</string>
+ <string name="about_apache_license"><a href="">Licencia Apache, Versión 2.0</a></string>
+ <string name="about_help">Ayuda</string>
+ <string name="settings_title_services">Servicios</string>
+ <string name="settings_title_appearance">Aspecto</string>
+ <string name="settings_title_cachedetails">Detalles del cache</string>
+ <string name="settings_title_offlinedata">Datos sin conexión</string>
+ <string name="settings_title_logging">Registrar</string>
+ <string name="settings_title_map">Mapa</string>
+ <string name="settings_title_map_data">Datos del mapa</string>
+ <string name="settings_title_map_content">Contenido del mapa</string>
+ <string name="settings_title_navigation">Navegación</string>
+ <string name="settings_title_system">Sistema</string>
+ <string name="settings_title_navigation_menu">Menú de navegación</string>
+ <string name="settings_category_social">Redes sociales</string>
+ <string name="settings_category_logging_other">Otras opciones de registro</string>
<string name="init_gcvote">GCvote.com</string>
<string name="init_twitter">Twitter</string>
<string name="init_username">Usuario</string>
@@ -319,6 +380,11 @@
<string name="init_backup_last">Copia guardada el</string>
<string name="init_backup_last_no">No hay ninguna copia de seguridad.</string>
<string name="init_mapsource_select">Elige proveedor de mapas</string>
+ <string name="init_gpx_exportdir">Directorio de exportación de GPX</string>
+ <string name="init_gpx_importdir">Directorio de importación de GPX</string>
+ <string name="init_maptrail">Mostrar rastro en el mapa</string>
+ <string name="init_summary_maptrail">Muestra el rastro en el mapa</string>
+ <string name="init_share_after_export">Abrir el menú de compartir tras exportar GPX</string>
<string name="init_trackautovisit">Convertir rastreables automáticamente a \"visita\"</string>
<string name="init_summary_trackautovisit">Convertir rastreables automáticamente a \"visita\"</string>
<string name="init_sigautoinsert">Insertar automáticamente</string>
diff --git a/main/res/values-fr/strings.xml b/main/res/values-fr/strings.xml
index 7b8a8d7..3c73f10 100644
--- a/main/res/values-fr/strings.xml
+++ b/main/res/values-fr/strings.xml
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">virtuelle</string>
<string name="cache_size_notchosen">non renseignée</string>
<string name="cache_size_unknown">inconnu</string>
+ <string name="cache_size_nano">nano</string>
+ <string name="cache_size_very_large">très grande</string>
<string name="wp_final">Étape finale</string>
<string name="wp_stage">Étape</string>
<string name="wp_puzzle">Énigme</string>
@@ -117,16 +119,15 @@
<string name="log_image_scale">Mise à l\'échelle</string>
<string name="log_password_title">Mot de passe du carnet :</string>
<string name="log_hint_log_password">Entrez votre mot de passe pour le carnet</string>
+ <string name="log_oc_team_comment">Commentaire de l\'équipe OC</string>
<string name="translate_to_sys_lang">Traduire en %s</string>
<string name="translate_to_english">Traduire en anglais</string>
<string name="translate_length_warning">La traduction d\'un texte trop long peut échouer.</string>
<string name="err_none">ok</string>
- <string name="err_start">Communication non démarrée</string>
<string name="err_parse">Échec login lecture page</string>
<string name="err_server">Échec de la connexion à Geocaching.com (probléme de serveur ou de connexion?)</string>
<string name="err_server_ec">Impossible de contacter Extremcaching.com. Le site web peut ne pas fonctionner ou votre connexion Internet peut être défectueuse.</string>
<string name="err_login">Pas d\'utilisateur ou de mot de passe enregistré</string>
- <string name="err_login_failed">c:geo ne peut pas se connecter.</string>
<string name="err_login_failed_toast">c:geo est en mode hors-ligne et ne peut pas se connecter. Vérifiez votre connexion Internet.</string>
<string name="err_unknown">Erreur inconnue</string>
<string name="err_comm">Erreur inconnue de communication</string>
@@ -178,7 +179,6 @@
<string name="err_log_load_data">c:geo ne peut pas charger les données pour enregistrer votre visite.</string>
<string name="err_log_load_data_again">c:geo ne peut pas charger les données pour enregistrer votre visite. Essayer plus tard.</string>
<string name="err_log_load_data_still">c:geo est en train de charger les données pour enregistrer votre visite. Veuillez patienter encore un peu.</string>
- <string name="err_log_failed_server">c:geo n\'a pas réussi à charger les données pour enregistrer votre visite car le serveur ne répond pas.</string>
<string name="err_log_post_failed">Il semble que votre visite n\'a pas été enregistrée. Veuillez vérifier sur le site Geocaching.com.</string>
<string name="err_log_post_failed_ec">Il semble que votre visite n\'a pas été enregistrée. Veuillez vérifier sur le site Extremcaching.com.</string>
<string name="err_logimage_post_failed">Il semble que l\'envoi de l\'image ait échoué. Veuillez vérifier sur le site Geocaching.com.</string>
@@ -247,22 +247,22 @@
<string name="caches_on_map">Voir sur la carte</string>
<string name="caches_sort">Trier</string>
<string name="caches_sort_title">Trier par</string>
- <string name="caches_sort_distance">distance</string>
- <string name="caches_sort_difficulty">difficulté</string>
- <string name="caches_sort_terrain">terrain</string>
- <string name="caches_sort_size">taille</string>
+ <string name="caches_sort_distance">Distance</string>
+ <string name="caches_sort_difficulty">Difficulté</string>
+ <string name="caches_sort_terrain">Terrain</string>
+ <string name="caches_sort_size">Taille</string>
<string name="caches_sort_favorites">Favoris</string>
<string name="caches_sort_favorites_ratio">Favoris [%]</string>
- <string name="caches_sort_name">nom</string>
+ <string name="caches_sort_name">Nom</string>
<string name="caches_sort_geocode">Geocode</string>
- <string name="caches_sort_rating">note</string>
- <string name="caches_sort_vote">vote (note perso)</string>
- <string name="caches_sort_inventory">nombre d\'objets dans l\'inventaire</string>
- <string name="caches_sort_date_hidden">date de création</string>
- <string name="caches_sort_date_logged">date du carnet</string>
- <string name="caches_sort_finds">trouvées</string>
- <string name="caches_sort_state">état</string>
- <string name="caches_sort_storage">date de sauvegarde dans l\'appareil</string>
+ <string name="caches_sort_rating">Note</string>
+ <string name="caches_sort_vote">Vote (note perso)</string>
+ <string name="caches_sort_inventory">Nombre d\'objets dans l\'inventaire</string>
+ <string name="caches_sort_date_hidden">Date de création</string>
+ <string name="caches_sort_date_logged">Date du carnet</string>
+ <string name="caches_sort_finds">Trouvées</string>
+ <string name="caches_sort_state">État</string>
+ <string name="caches_sort_storage">Date de sauvegarde dans l\'appareil</string>
<string name="caches_select_mode">Mode sélection</string>
<string name="caches_select_mode_exit">Sortir du mode sélection</string>
<string name="caches_select_invert">Inverser la sélection</string>
@@ -274,7 +274,7 @@
<string name="caches_drop_all_ask">Effacer les caches de la liste courante ?</string>
<string name="caches_drop_stored">Effacer les caches stockées</string>
<string name="caches_drop_progress">Suppression des caches en cours</string>
- <string name="caches_drop_all_and_list">Suppression des caches et de la liste</string>
+ <string name="caches_drop_all_and_list">Suppr. caches et liste</string>
<string name="caches_delete_events">Effacer les événements précédents</string>
<string name="caches_refresh_selected">Rafraîchir les caches sélectionnées</string>
<string name="caches_refresh_all">Tout rafraîchir</string>
@@ -288,10 +288,10 @@
<string name="caches_recaptcha_continue">Continuer</string>
<string name="caches_filter">Filtrer</string>
<string name="caches_filter_title">Filtrer selon</string>
- <string name="caches_filter_size">taille</string>
- <string name="caches_filter_type">type</string>
- <string name="caches_filter_track">avec des trackables</string>
- <string name="caches_filter_clear">effacer les filtres</string>
+ <string name="caches_filter_size">Taille</string>
+ <string name="caches_filter_type">Type</string>
+ <string name="caches_filter_track">Avec des objets voyageurs</string>
+ <string name="caches_filter_clear">Effacer les filtres</string>
<string name="caches_filter_modified">Avec les coordonnées modifiées</string>
<string name="caches_filter_origin">Avec les coordonées originales</string>
<string name="caches_filter_distance">Distance</string>
@@ -320,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo n\'a pas réussi à supprimer la liste courante</string>
<string name="list_dialog_rename_title">Renommer la liste</string>
<string name="list_dialog_rename">Renommer</string>
+ <string name="list_not_available">La liste n\'est plus disponible, basculement vers la liste standard</string>
<string name="about_version">Version</string>
<string name="about_changelog">Versions</string>
<string name="about_donate">Dons</string>
@@ -478,6 +479,9 @@
<string name="init_use_native_ua">S\'identifier comme le navigateur web Android. Peut résoudre des problèmes de connexion avec certains opérateurs mobiles.</string>
<string name="init_summary_use_native_ua">S\'identifier comme le navigateur Android. Résout les problèmes de connexion lors de l\'utilisation de certains fournisseurs d\'accès au réseau.</string>
<string name="init_rendertheme_folder">Dossier contenant les cartes hors-ligne personnelles (optionnelles).</string>
+ <string name="init_maintenance">Maintenance</string>
+ <string name="init_maintenance_directories_note">c:geo stocke les images et les autres fichiers associés à une géocache dans un dossier dédié. Dans certains cas (comme l\'importation/exportation de la base de données), ce dossier peut contenir des fichiers obsolètes, qui peuvent être supprimés ici.</string>
+ <string name="init_maintenance_directories">Supprimer les fichiers orphelins</string>
<string name="settings_open_website">Ouvrir le site dans un navigateur</string>
<string name="settings_settings">Paramètres</string>
<string name="settings_information">Information</string>
@@ -493,12 +497,12 @@
<string name="feature_log_images">Joindre des images aux entrées de journal</string>
<string name="feature_watch_list">Liste de suivi</string>
<string name="feature_own_coordinates">Stockage de coordonnées modifiées</string>
- <string name="feature_search_owner">Recherche par propriétaire</string>
- <string name="feature_search_finder">Recherche par découvreur</string>
<string name="feature_search_keyword">Recherche par mot clé</string>
<string name="feature_search_live_map">Carte active</string>
<string name="feature_search_center">Recherche par position</string>
<string name="feature_search_geocode">Recherche par géocode</string>
+ <string name="feature_search_owner">Recherche par propriétaire</string>
+ <string name="feature_search_finder">Recherche par découvreur</string>
<string name="map_source_google_map">Google Maps : plan</string>
<string name="map_source_google_satellite">Google Maps : satellite</string>
<string name="map_source_osm_mapnik">OSM : rendu Mapnik</string>
@@ -651,7 +655,6 @@
<string name="cache_coordinates">Coordonnées</string>
<string name="cache_coordinates_original">Coordonnées d\'origine</string>
<string name="cache_spoiler_images_title">Images indices</string>
- <string name="cache_images_title">Images</string>
<string name="cache_log_types">Types de visites</string>
<string name="cache_coordinates_no">Cette cache n\'a pas de coordonnées.</string>
<string name="cache_clear_history">Effacer l\'historique</string>
@@ -759,7 +762,6 @@
<string name="map_strategy_auto">En fonction du déplacement</string>
<string name="map_strategy_detailed">Détaillée</string>
<string name="live_map_notification">Lors de l\'affichage de la carte active, certaines coordonnées de géocaches peuvent être imprécises et sont indiquées par un cercle orange.\nDemander les détails d\'une géocache ou la sauver pour une utilisation hors-ligne récupérera les coordonnées exactes.\n\nVous trouverez plus d\'informations sur les changements sur la page \"À propos de c:geo\".</string>
- <string name="live_map_note_dontshow">Ne plus afficher</string>
<string name="search_bar_hint">Recherche de caches</string>
<string name="search_bar_desc">Caches (géocode, mot clé), Objets voyageurs (code TB)</string>
<string name="search_coordinates">Coordonnées</string>
@@ -837,6 +839,8 @@
<string name="helper_calendar_missing">Module supplémentaire c:geo agenda non installé</string>
<string name="helper_calendar_description">Permet d\'exporter les événements liés aux caches dans le calendrier Android.</string>
<string name="helper_sendtocgeo_title">Envoyer vers c:geo</string>
+ <string name="helper_contacts_title">c:geo - additif contacts</string>
+ <string name="helper_contacts_description">Permet d\'ouvrir une fiche de contact (depuis le carnet d\'adresses) directement depuis une entrée de journal, de manière à pouvoir plus facilement appeler des amis à l\'aide.</string>
<string name="helper_sendtocgeo_description">Envoyer à c:geo (<i>Send to c:geo</i>) est une extension pour le navigateur <strong>de votre ordinateur</strong>. Lorsque vous naviguez sur geocaching.com, vous pouvez envoyer des caches vers votre smartphone avec un clic.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Application simple affichant des cartes en ligne et hors ligne. Permet d\'enregistrer son parcours, de gérer des POI et de nombreuses autres fonctions utiles.</string>
@@ -1117,6 +1121,7 @@
<string name="tts_oclock">%s heures</string>
<string name="clipboard_copy_ok">Copié dans le presse-papiers</string>
<string name="percent_favorite_points">%\ favoris</string>
+ <string name="cgeo_shortcut">c:geo raccourci</string>
<string name="create_shortcut">Créer un raccourci</string>
<string-array name="log_image_scales">
<item>Taille originale</item>
diff --git a/main/res/values-hu/strings.xml b/main/res/values-hu/strings.xml
index f46885f..a593d2f 100644
--- a/main/res/values-hu/strings.xml
+++ b/main/res/values-hu/strings.xml
@@ -105,11 +105,9 @@
<string name="translate_to_english">Fordítás angolra</string>
<string name="translate_length_warning">A fordítás sikertelen lehet hosszú szövegeknél.</string>
<string name="err_none">Ok</string>
- <string name="err_start">A kommunikáció nem indult el</string>
<string name="err_parse">Hiba a belépőoldalon</string>
<string name="err_server">Hiba a kapcsolatban a geocaching.com-mal (a szerver vagy a kapcsolat nem működik?)</string>
<string name="err_login">Nincs mentett belépési adat</string>
- <string name="err_login_failed">Sajnos a c:geo nem tud belépni.</string>
<string name="err_login_failed_toast"> Sajnos a c:geo nem tud belépni. A c:geo hálózat nélküli módban van. Ellenőrizd a belépési adataid a bállításoknál vagy engedélyezd az internet kapcsolatot.</string>
<string name="err_unknown">Ismeretlen hiba</string>
<string name="err_comm">Ismeretlen kommunikációs hiba</string>
@@ -157,7 +155,6 @@
<string name="err_log_load_data">Sajnáljuk, a c:geo nem tudja betölteni az adatokat amik a megtalálás bejelentéséhez szükségesek.</string>
<string name="err_log_load_data_again">Sajnáljuk, a c:geo nem tudja betölteni az adatokat amik a megtalálás bejelentéséhez szükségesek. Újrapróbálkozás.</string>
<string name="err_log_load_data_still">A c:geo még tölti az adatokat amik a megtalálás bejelentéséhez szükségesek. Kérlek várj egy kicsit tovább.</string>
- <string name="err_log_failed_server">Sajnáljuk, a c:geo-nak nem sikerült hozzáadni a logot mert a szerver nem válaszol.</string>
<string name="err_log_post_failed">Úgy tűnik a logot nem került hozzáadásra. Kérlek ellenőrizd a geocaching.com-on.</string>
<string name="err_search_address_forgot">Sajnáljuk, a c:geo elfelejtette a címet amit kerestél.</string>
<string name="err_parse_lat">Sajnáljuk, a c:geo nem tudja értelmezni a szélességet.</string>
@@ -503,7 +500,6 @@
<string name="cache_coordinates">Koordináták</string>
<string name="cache_coordinates_original">Eredeti koordináták</string>
<string name="cache_spoiler_images_title">Spoiler képek</string>
- <string name="cache_images_title">Képek</string>
<string name="cache_log_types">Bejegyzés típusok</string>
<string name="cache_coordinates_no">Ennek a ládának nincsenek koordinátái.</string>
<string name="cache_clear_history">Előzmények törlése</string>
@@ -590,7 +586,6 @@
<string name="map_strategy_auto">Sebességfüggő</string>
<string name="map_strategy_detailed">Részletes</string>
<string name="live_map_notification">A koordináták az élő térképen nem mindig pontosak. A vélhetően pontatlan koordinátákat narancssárga kör jelöli.\nA geoláda részleteinek megnyitása vagy a geoláda mentése mindig pontos koordinátákkal történik.\n\nTovábbi információ az összes változásról a \"A c:georól\" oldalon található az appon belül.</string>
- <string name="live_map_note_dontshow">Ne mutasd újra</string>
<string name="search_bar_hint">Ládák keresése</string>
<string name="search_bar_desc">Ládák (GC-kód, kulcsszó), Nyomonkövethető tárgyak (TB-kód)</string>
<string name="search_coordinates">Koordináták</string>
diff --git a/main/res/values-it/strings.xml b/main/res/values-it/strings.xml
index ae86197..e0e7653 100644
--- a/main/res/values-it/strings.xml
+++ b/main/res/values-it/strings.xml
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">virtual</string>
<string name="cache_size_notchosen">non selezionato</string>
<string name="cache_size_unknown">sconosciuto</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Molto grande</string>
<string name="wp_final">Destinazione finale</string>
<string name="wp_stage">Step intermedio multi-cache</string>
<string name="wp_puzzle">Quesito da risolvere</string>
@@ -117,15 +119,15 @@
<string name="log_image_scale">Ridimensiona</string>
<string name="log_password_title">Log Password:</string>
<string name="log_hint_log_password">Inserisci la password per il log</string>
+ <string name="log_oc_team_comment">Commenti del Team OC</string>
<string name="translate_to_sys_lang">Traduci in %s</string>
<string name="translate_to_english">Traduci in inglese</string>
<string name="translate_length_warning">La traduzione può fallire quando c\'è molto testo.</string>
<string name="err_none">OK</string>
- <string name="err_start">Comunicazione non avviata</string>
<string name="err_parse">Errore analizzando la pagina di login</string>
<string name="err_server">Connessione fallita con Geocaching.com (server o connessione non disponibile?)</string>
+ <string name="err_server_ec">Impossibile contattare Extremcaching.com. Il sito Web potrebbe essere non attivoo la tua connessione internet non funziona.</string>
<string name="err_login">Informazioni di login non memorizzate</string>
- <string name="err_login_failed">c:geo non può effettuare login.</string>
<string name="err_login_failed_toast">c:geo non può effettuare login. Attivata la modalità offline. Verificare le informazioni di login nelle impostazioni o abilitare una connessione internet.</string>
<string name="err_unknown">Errore sconosciuto</string>
<string name="err_comm">Errore sconosciuto di comunicazione</string>
@@ -177,8 +179,8 @@
<string name="err_log_load_data">c:geo non riesce a caricare i dati necessari per salvare il log della tua visita.</string>
<string name="err_log_load_data_again">c:geo non riesce a caricare i dati necessari per salvare il log della tua visita. Nuovo tentativo in corso.</string>
<string name="err_log_load_data_still">c:geo sta ancora caricando i dati necessari per salvare il log. Per cortesia attendere ancora un pochino.</string>
- <string name="err_log_failed_server">c:geo non è riuscito ad inviare il log perché il server non risponde.</string>
<string name="err_log_post_failed">Sembra che il log non sia stato inviato. Prego verificare su Geocaching.com.</string>
+ <string name="err_log_post_failed_ec">Sembra che il tuo log non sia stato pubblicato. Controlla su Extremcaching.com.</string>
<string name="err_logimage_post_failed">Sembra che l\'immagine del tuo log non sia stata caricata. Si prega di controllare su Geocaching.com.</string>
<string name="err_search_address_forgot">c:geo ha dimenticato l\'indirizzo che vuoi trovare.</string>
<string name="err_parse_lat">c:geo non riesce ad interpretare la latitudine.</string>
@@ -202,6 +204,8 @@
<string name="warn_deprecated_mapfile">Stai usando una vecchia mappa 0.2.4.\nAggiornala alla 0.3.0 appena puoi.\nIl supporto alla 0.2.4 sarà rimosso nella prossima versione.</string>
<string name="warn_nonexistant_mapfile">La mappa selezionata non esiste.\nMappa offline non disponibile.</string>
<string name="warn_rendertheme_missing">Tema mappa non trovato.</string>
+ <string name="warn_pocket_query_select">Nessuna Pocket query selezionata.</string>
+ <string name="warn_no_pocket_query_found">Nessuna Pocket query trovata online.</string>
<string name="info_log_posted">c:geo ha inviato il log con successo.</string>
<string name="info_log_saved">c:geo ha salvato il log.</string>
<string name="info_log_cleared">Il log è stato azzerato.</string>
@@ -222,6 +226,8 @@
<string name="menu_history">Cronologia</string>
<string name="menu_filter">Filtri</string>
<string name="menu_scan_geo">Scansiona geocode</string>
+ <string name="menu_pocket_queries">Pocket query</string>
+ <string name="menu_scan_description">c:geo può eseguire una scansione di geocodes stampati oppure di immagini QR code. L\'applicazione necessaria non è installata. Desideri aprire Google Play per installarla?</string>
<string name="live_map_button">Mappa</string>
<string name="caches_nearby_button">Vicini</string>
<string name="advanced_search_button">Cerca</string>
@@ -245,8 +251,8 @@
<string name="caches_sort_difficulty">Difficoltà</string>
<string name="caches_sort_terrain">Terreno</string>
<string name="caches_sort_size">Dimensione</string>
- <string name="caches_sort_favorites">Popolarità</string>
- <string name="caches_sort_favorites_ratio">Popolarità [%]</string>
+ <string name="caches_sort_favorites">Preferiti</string>
+ <string name="caches_sort_favorites_ratio">Preferiti [%]</string>
<string name="caches_sort_name">Nome</string>
<string name="caches_sort_geocode">Geo Code</string>
<string name="caches_sort_rating">Voto</string>
@@ -289,6 +295,9 @@
<string name="caches_filter_modified">Con coordinate modificate</string>
<string name="caches_filter_origin">Origine</string>
<string name="caches_filter_distance">Distanza</string>
+ <string name="caches_filter_personal_note">Con una nota personale</string>
+ <string name="caches_filter_popularity">Preferiti</string>
+ <string name="caches_filter_popularity_ratio">Preferiti [%]</string>
<string name="caches_removing_from_history">Rimozione dalla cronologia…</string>
<string name="caches_clear_offlinelogs">Cancella i log offline</string>
<string name="caches_clear_offlinelogs_progress">Cancellazione logs offline</string>
@@ -311,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo non è riuscito a rimuovere la lista corrente</string>
<string name="list_dialog_rename_title">Rinomina lista</string>
<string name="list_dialog_rename">Rinomina</string>
+ <string name="list_not_available">Elenco non più disponibile, passo a elenco standard</string>
<string name="about_version">Versione</string>
<string name="about_changelog">Modifiche</string>
<string name="about_donate">Donazioni</string>
@@ -328,6 +338,7 @@
<string name="settings_title_map_data">Dati mappa</string>
<string name="settings_title_map_content">Contenuto Mappa</string>
<string name="settings_title_gpx">GPX</string>
+ <string name="settings_title_basicmembers">Opzioni per i membri di base (non Premium)</string>
<string name="settings_title_navigation">Navigazione</string>
<string name="settings_title_system">Sistema</string>
<string name="settings_title_navigation_menu">Menu \"Naviga\"</string>
@@ -337,7 +348,11 @@
<string name="settings_category_logging_other">Altre opzioni di log</string>
<string name="settings_goto_url_button">altro …</string>
<string name="settings_title_gc">Geocaching.com</string>
+ <string name="settings_title_ec">Extremcaching.com</string>
+ <string name="settings_title_ox">OpenCaching.com (Garmin)</string>
<string name="settings_activate_gc">Attiva</string>
+ <string name="settings_activate_ec">Attivare</string>
+ <string name="settings_activate_ox">Attivare</string>
<string name="settings_gc_legal_note">Per usare i servizi di Geocaching.com, si applicano i termini e le condizioni del Contratto Groundspeak che deve essere approvato dall\'utente.</string>
<string name="settings_info_facebook_login_title">Facebook Login</string>
<string name="settings_info_facebook_login">Con il tuo account di Facebook non puoi fare login su geocaching.com. Ma c\'è una soluzione semplice …</string>
@@ -361,7 +376,10 @@
<string name="init_login_popup_failed">Login fallito.</string>
<string name="init_login_popup_failed_reason">Login fallito: </string>
<string name="init_login_popup_not_authorized">Non autorizzato</string>
+ <string name="init_login_popup_invalid_timestamp">Ora locale non valida, regolare l\'orologio del dispositivo</string>
+ <string name="init_login_popup_invalid_token">Autorizzazione non valida, ri-autorizzare</string>
<string name="init_signature">Firma</string>
+ <string name="init_template_help">Stringhe segnaposto come [NAME] saranno espanse più tardi, quando verrà utilizzato questo modello.</string>
<string name="init_signature_template_button">Stringhe speciali</string>
<string name="init_signature_template_date">Data</string>
<string name="init_signature_template_time">Ora</string>
@@ -369,6 +387,9 @@
<string name="init_signature_template_user">Utente</string>
<string name="init_signature_template_number">Numero cache</string>
<string name="init_signature_template_owner">Proprietario</string>
+ <string name="init_signature_template_name">Nome</string>
+ <string name="init_signature_template_url">URL</string>
+ <string name="init_signature_template_log">Testo di Log</string>
<string name="init_ratingwanted">Rating GCvote.com</string>
<string name="init_summary_ratingwanted">Carica il rating del cache da GCvote.com</string>
<string name="init_friendlogswanted">Visualizza log dei miei amici</string>
@@ -458,9 +479,30 @@
<string name="init_use_native_ua">Browser Android</string>
<string name="init_summary_use_native_ua">Identifica come browser Android. Risolve alcuni problemi di login con alcuni provider di rete.</string>
<string name="init_rendertheme_folder">Directory per i temi mappa</string>
+ <string name="init_maintenance">Manutenzione</string>
+ <string name="init_maintenance_directories_note">c:geo memorizza immagini, immagini log e altri file (correlati a un cache) in una cartella separata. In alcuni casi (es.: dopo import/esport del database) questa cartella potrebbe contenere file obsoleti, che possono essere cancellati da qui.</string>
+ <string name="init_maintenance_directories">Elimina file orfani</string>
<string name="settings_open_website">Apri il sito</string>
<string name="settings_settings">Impostazioni</string>
<string name="settings_information">Informazioni</string>
+ <string name="settings_twitter_cache_message">Messaggio per cache trovato</string>
+ <string name="settings_twitter_trackable_message">Messaggio per Trackable trovato</string>
+ <string name="init_ec_icons">Icone Mappa</string>
+ <string name="settings_ec_icons_other">Proprio stile</string>
+ <string name="settings_ec_icons_oc">Come OC</string>
+ <string name="settings_features">Caratteristiche supportate</string>
+ <string name="feature_description">Le seguenti funzioni <b>online</b> di questo sito Web sono supportate in c:geo (oltre alle funzionalità offline):</string>
+ <string name="feature_personal_notes">Note personali</string>
+ <string name="feature_online_logging">Log online</string>
+ <string name="feature_log_images">Immagini allegate ai Log</string>
+ <string name="feature_watch_list">Watchlist</string>
+ <string name="feature_own_coordinates">Memorizzazione delle coordinate modificate</string>
+ <string name="feature_search_keyword">Ricerca per parola chiave</string>
+ <string name="feature_search_live_map">Mappa Live</string>
+ <string name="feature_search_center">Cerca per posizione</string>
+ <string name="feature_search_geocode">Cerca per geocode</string>
+ <string name="feature_search_owner">Cerca per proprietario</string>
+ <string name="feature_search_finder">Cerca per ricercatore</string>
<string name="map_source_google_map">Google: Map</string>
<string name="map_source_google_satellite">Google: Satellite</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
@@ -485,6 +527,7 @@
<string name="auth_explain_long">Premendo il pulsante \"autorizza c:geo\" avrà inizio il processo. Verrà aperto un browser web con la pagina %s. Effettuare login alla pagina e lasciare che <b>c:geo</b> acceda al tuo account.</string>
<string name="auth_dialog_completed_twitter">c:geo è ora autorizzato a postare su Twitter.</string>
<string name="auth_ocde">opencaching.de</string>
+ <string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo è ora autorizzato ad accedere a %s.</string>
<string name="cache_offline">Offline</string>
<string name="cache_offline_refresh">Aggiorna</string>
@@ -506,6 +549,8 @@
<string name="cache_log_image_default_title">Foto</string>
<string name="cache_personal_note">Note personali</string>
<string name="cache_personal_note_edit">Modifica</string>
+ <string name="cache_personal_note_limit">Limite per le note personali</string>
+ <string name="cache_personal_note_truncation">Questa nota personale verrà troncata da Geocaching.com dopo %d caratteri.</string>
<string name="cache_personal_note_upload">Carica</string>
<string name="cache_personal_note_uploading">Nota personale in caricamento</string>
<string name="cache_personal_note_upload_done">Nota personale caricata</string>
@@ -581,6 +626,8 @@
<string name="cache_menu_whereyougo">WhereYouGo</string>
<string name="cache_menu_oruxmaps">OruxMaps</string>
<string name="cache_menu_cachebeacon">Cache Beacon</string>
+ <string name="cache_menu_navigon">Navigon</string>
+ <string name="cache_menu_pebble">Pebble</string>
<string name="cache_status">Stato</string>
<string name="cache_status_offline_log">Log salvato</string>
<string name="cache_status_found">Trovato</string>
@@ -608,7 +655,6 @@
<string name="cache_coordinates">Coordinate</string>
<string name="cache_coordinates_original">Coordinate originali</string>
<string name="cache_spoiler_images_title">Immagini spoiler</string>
- <string name="cache_images_title">Immagini</string>
<string name="cache_log_types">Tipi di Log</string>
<string name="cache_coordinates_no">Questo cache non ha coordinate.</string>
<string name="cache_clear_history">Cancella cronologia</string>
@@ -627,6 +673,7 @@
<string name="file_title_searching">Ricerca in corso</string>
<string name="simple_dir_chooser_title">Scegli cartella</string>
<string name="simple_dir_chooser_current_path">Path:</string>
+ <string name="simple_dir_chooser_invalid_path">Percorso non valido</string>
<string name="gpx_import_loading_caches">Caricamento dei cache da file GPX</string>
<string name="gpx_import_loading_waypoints">Caricamento file waypoints</string>
<string name="gpx_import_store_static_maps">Salvataggio mappe statiche</string>
@@ -644,6 +691,7 @@
<string name="gpx_import_delete_title">Cancella file</string>
<string name="gpx_import_delete_message">Vuoi cancellare %s?</string>
<string name="gpx_import_select_list_title">Importa GPX nella lista</string>
+ <string name="gpx_import_android">Importazione da Android</string>
<string name="map_file_select_title">Seleziona il file mappa</string>
<string name="web_import_title">Importa dal web</string>
<string name="web_import_waiting">In attesa di nuovi cache dal web…</string>
@@ -714,7 +762,6 @@
<string name="map_strategy_auto">In base alla tua velocità di movimento</string>
<string name="map_strategy_detailed">Dettagliata</string>
<string name="live_map_notification">Nella nuova Mappa Live le coordinate potrebbero non essere sempre precise. Coordinate possibilmente imprecise sono marcate da un cerchio arancione.\nAprendo i dettagli del cache o salvando il cache per uso offline farà calcolare sempre coordinate precise.\n\nInformazioni addizionali su tutte le modifiche si possono trovare nel menu \"Info su c:geo\" sulla pagina principale di questa app.</string>
- <string name="live_map_note_dontshow">Non mostrare ancora</string>
<string name="search_bar_hint">Cerca cache</string>
<string name="search_bar_desc">Cache (geo code, parole chiave), oggetti Trackables (TB-code)</string>
<string name="search_coordinates">Coordinate</string>
@@ -740,6 +787,9 @@
<string name="search_address_started">Cerca per luoghi</string>
<string name="search_address_result">Cerca luoghi</string>
<string name="search_own_caches">Cerca i miei cache</string>
+ <string name="search_pocket_title">Pocket Query</string>
+ <string name="search_pocket_loading">Caricamento di una lista di Pocket query</string>
+ <string name="search_pocket_select">Scegli Pocket Query</string>
<string name="trackable">Oggetto Trackable</string>
<string name="trackable_details_loading">Caricamento dettagli Trackable…</string>
<string name="trackable_log_touch">Documenta il contatto</string>
@@ -772,6 +822,7 @@
<string name="user_menu_view_found">Cache trovati</string>
<string name="user_menu_open_browser">Apri profilo nel browser</string>
<string name="user_menu_send_message">Invia messaggio</string>
+ <string name="user_menu_open_contact">Aprire scheda contatto</string>
<string name="navigation">Navigazione</string>
<string name="compass_title">Bussola</string>
<string name="use_gps">Usa Nord solo da GPS</string>
@@ -787,6 +838,10 @@
<string name="helper_calendar_title">c:geo calendario add-on</string>
<string name="helper_calendar_missing">c:geo calendario add-on non installato</string>
<string name="helper_calendar_description">Permette di esportare gli eventi cache nel calendario del tuo dispositivo.</string>
+ <string name="helper_sendtocgeo_title">Send to c:geo</string>
+ <string name="helper_contacts_title">c:geo - plugin Contatti</string>
+ <string name="helper_contacts_description">Consente di aprire una scheda contatto (della tua rubrica) direttamente da un log, per permetterti di chiedere aiuto agli amici più facilmente.</string>
+ <string name="helper_sendtocgeo_description">Send to c:geo è un\'estensione del browser <strong>per il tuo PC</strong>. Durante la navigazione su geocaching.com, è possibile inviare i cache al vostro smartphone con il clic di un pulsante direttamente all\'interno del browser.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Applicazione semplice da usare che mostra mappe online permettendo di scaricarle direttamente per l\'uso offline (solo mappe raster). Supporta inoltra la registrazione di traccia, gestione dei waypoints e altre utili funzioni.</string>
<string name="helper_gpsstatus_title">GPS Status</string>
@@ -797,6 +852,8 @@
<string name="helper_barcode_description">Ci sono script Greasemonkey e siti web che consentono di visualizzare un geocode come codice a barre. Con questa app c:geo può leggere il geocode direttamente dallo schermo del tuo computer.</string>
<string name="helper_pocketquery_title">Creatore di Pocket Query</string>
<string name="helper_pocketquery_description">Consente di creare facilmente Pocket Queries centrate sulla tua posizione attuale o un punto scelto dalla mappa. Richiede un account premium su Geocaching.com.</string>
+ <string name="helper_google_translate_title">Google Traduttore</string>
+ <string name="helper_google_translate_description">Se si scaricano i pacchetti di traduzione nell\'applicazione Google Traduttore, puoi facilmente tradurre le descrizioni dei cache in c:geo toccando e tenendo premuto sul testo (senza bisogno di una connessione Internet).</string>
<string name="addon_missing_title">Add-On mancante</string>
<string name="addon_download_prompt">Scaricalo ora da Google Play.</string>
<string name="export">Esporta</string>
@@ -1004,6 +1061,38 @@
<string name="attribute_unknown_no">Senza attributo sconosciuto</string>
<string name="attribute_geotour_yes">Parte di un GeoTour</string>
<string name="attribute_geotour_no">Non fa parte di un GeoTour</string>
+ <string name="attribute_kids_2_yes">Porta i tuoi bambini</string>
+ <string name="attribute_kids_2_no">Non portare bambini</string>
+ <string name="attribute_historic_site_yes">Sito storico</string>
+ <string name="attribute_historic_site_no">Non è un sito storico</string>
+ <string name="attribute_magnetic_yes">Cache magnetico</string>
+ <string name="attribute_magnetic_no">Non è un cache magnetico</string>
+ <string name="attribute_usb_cache_yes">Cache \"Dead drop USB\"</string>
+ <string name="attribute_usb_cache_no">Non è un cache \"Dead drop USB\"</string>
+ <string name="attribute_shovel_yes">Potrebbe essere necessaria una pala</string>
+ <string name="attribute_shovel_no">Non hai bisogno di una pala</string>
+ <string name="attribute_specific_access_yes">Disponibile nelle ore specificate (l\'accesso può essere a pagamento)</string>
+ <string name="attribute_specific_access_no">Disponibile ad ogni ora del giorno</string>
+ <string name="attribute_pedestrian_only_yes">Accesso solo a piedi</string>
+ <string name="attribute_pedestrian_only_no">Accesso non solo a piedi</string>
+ <string name="attribute_nature_cache_yes">Nascosto in un ambiente naturale (boschi, montagne, ecc.)</string>
+ <string name="attribute_nature_cache_no">Non nascosto in un ambiente naturale</string>
+ <string name="attribute_byop_yes">Portati qualcosa per scrivere</string>
+ <string name="attribute_byop_no">Matita non necessaria</string>
+ <string name="attribute_safari_cache_yes">Reverse cache</string>
+ <string name="attribute_safari_cache_no">Non è un reverse cache</string>
+ <string name="attribute_quick_cache_yes">Cache veloce</string>
+ <string name="attribute_quick_cache_no">Non è un cache veloce</string>
+ <string name="attribute_wherigo_yes">Cache Wherigo</string>
+ <string name="attribute_wherigo_no">Non è un cache Wherigo</string>
+ <string name="attribute_audio_cache_yes">La descrizione contiene un file audio</string>
+ <string name="attribute_audio_cache_no">La descrizione non contiene un file audio</string>
+ <string name="attribute_geohotel_yes">Cache GeoHotel</string>
+ <string name="attribute_geohotel_no">Non è un cache GeoHotel</string>
+ <string name="attribute_survey_marker_yes">Vicino ad una targa o marcatore geodedico (Survey Marker)</string>
+ <string name="attribute_survey_marker_no">Non è vicino ad una targa o marcatore geodedico (Survey Marker)</string>
+ <string name="attribute_offset_cache_yes">Offset cache</string>
+ <string name="attribute_offset_cache_no">Non è un offset cache</string>
<string name="quote">Per rendere il geocaching più facile e gli utenti più pigri.</string>
<string name="powered_by">carnero</string>
<string name="support">Supporto: <a href="">support@cgeo.org</a></string>
@@ -1013,6 +1102,7 @@
<string name="nutshellmanual">Manuale: <a href="">c:geo in a Nutshell</a></string>
<string name="market">Android: <a href="">c:geo su Google Play</a></string>
<string name="about_twitter">Può <b>c:geo</b> pubblicare su Twitter ogni volta che logghi un cache?</string>
+ <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string>
<string name="status_new_release" tools:ignore="UnusedResources">Una nuova versione è disponibile.\nClicca per installarla.</string>
<string name="status_new_nightly" tools:ignore="UnusedResources">Una nuova versione nightly è disponibile.\nClicca per installarla.</string>
<string name="status_new_rc" tools:ignore="UnusedResources">Una nuova release candidate è disponibile.\nClicca per installarla.</string>
@@ -1030,6 +1120,9 @@
<string name="tts_one_oclock">a ore una</string>
<string name="tts_oclock">a ore %s</string>
<string name="clipboard_copy_ok">Copiato nella clipboard</string>
+ <string name="percent_favorite_points">%\ preferiti</string>
+ <string name="cgeo_shortcut">collegamento a c:geo</string>
+ <string name="create_shortcut">Crea collegamento</string>
<string-array name="log_image_scales">
<item>Dimensioni originali</item>
<item>512 px</item>
@@ -1069,4 +1162,8 @@
<item quantity="one">ieri</item>
<item quantity="other">%d giorni fa</item>
</plurals>
+ <plurals name="favorite_points">
+ <item quantity="one">%s preferito</item>
+ <item quantity="other">%s preferiti</item>
+ </plurals>
</resources>
diff --git a/main/res/values-ja/strings.xml b/main/res/values-ja/strings.xml
index d7e5287..ddf3406 100644
--- a/main/res/values-ja/strings.xml
+++ b/main/res/values-ja/strings.xml
@@ -121,11 +121,9 @@
<string name="translate_to_english">英語に翻訳</string>
<string name="translate_length_warning">文章が長すぎるので翻訳できないかもしれません。</string>
<string name="err_none">OK</string>
- <string name="err_start">通信を始めることができませんでした</string>
<string name="err_parse">ログインページの解析に失敗しました</string>
<string name="err_server">Geocaching.comに接続できません。サーバが停止中かインターネットに未接続かもしれません。</string>
<string name="err_login">ログイン情報が保存されていません</string>
- <string name="err_login_failed">ログインできません。</string>
<string name="err_login_failed_toast">ログインできません。保存済みキャッシュのみでオフラインで動作します。 ログインの設定を確認したりネット接続を有効にしてください。</string>
<string name="err_unknown">未知のエラー</string>
<string name="err_comm">未知の通信エラー</string>
@@ -177,7 +175,6 @@
<string name="err_log_load_data">ログを書くのに必要なデータをロードすることができません。</string>
<string name="err_log_load_data_again">ログを書くのに必要なデータをロードすることができません。もう一度やってみてください。</string>
<string name="err_log_load_data_still">ログを投稿するのに必要なデータをまだロード中です。もう少しお待ちください。</string>
- <string name="err_log_failed_server">サーバの反応がないのでログを投稿することができませんでした。</string>
<string name="err_log_post_failed">ログを投稿することができなかったようです。Geocaching.comで確認してください。</string>
<string name="err_logimage_post_failed">ログの添付画像がアップロードされなかったようです。Geocaching.comで確認してください。</string>
<string name="err_search_address_forgot">c:geo forgot the address you tried to find.</string>
@@ -582,7 +579,6 @@
<string name="cache_coordinates">座標</string>
<string name="cache_coordinates_original">オリジナル座標</string>
<string name="cache_spoiler_images_title">スポイラー画像</string>
- <string name="cache_images_title">画像</string>
<string name="cache_log_types">ログタイプ</string>
<string name="cache_coordinates_no">このキャッシュに座標値はありません。</string>
<string name="cache_clear_history">全履歴を削除</string>
@@ -688,7 +684,6 @@
<string name="map_strategy_auto">自動(移動速度に依存)</string>
<string name="map_strategy_detailed">詳細(「速い」+詳細)</string>
<string name="live_map_notification">現バージョンではオンライン地図の座標は正確とは限りません。不正確と思われる座標のキャッシュはオレンジ色の丸で表示されます。\nキャッシュの詳細を表示したりオフライン用に保存する際には正確な座標を取得します。\n\n詳しくはアプリ内の「c:geoについて」の変更履歴(英語)をご覧ください。</string>
- <string name="live_map_note_dontshow">再び表示しない</string>
<string name="search_bar_hint">キャッシュ検索</string>
<string name="search_bar_desc">キャッシュ(GCコード,キーワード), トラッカブル(TBコード)</string>
<string name="search_coordinates">座標</string>
diff --git a/main/res/values-nb/strings.xml b/main/res/values-nb/strings.xml
index 6eb61a2..d830b3c 100644
--- a/main/res/values-nb/strings.xml
+++ b/main/res/values-nb/strings.xml
@@ -69,11 +69,9 @@
<string name="log_new_log">Logg</string>
<string name="log_new_log_text">Logg tekst</string>
<string name="err_none">Ok</string>
- <string name="err_start">Klarte ikke å koble til</string>
<string name="err_parse">Klarte ikke å lese innloggings-siden</string>
<string name="err_server">Klarte ikke å koble til Geocaching.com (server eller tilkobling nede?)</string>
<string name="err_login">Ingen innloggings-opplysninger lagret</string>
- <string name="err_login_failed">Beklager, c:geo kan ikke logge inn.</string>
<string name="err_unknown">Ukjent feil</string>
<string name="err_comm">Ukjent tilkoblings-feil</string>
<string name="err_missing_auth">Brukernavn eller passord er ikke oppgitt.</string>
@@ -103,7 +101,6 @@
<string name="err_log_load_data">Beklager, c:geo klarte ikke å laste den nødvendige informasjonen for å logge funnet.</string>
<string name="err_log_load_data_again">Beklager, c:geo klarte ikke å laste den nødvendige informasjonen for å logge funnet. c:geo prøver på nytt.</string>
<string name="err_log_load_data_still">c:geo laster fortsatt informasjonen som er nødvendig for å logge funnet. Vennligst vent.</string>
- <string name="err_log_failed_server">Beklager, c:geo klarte ikke å logge funnet fordi serveren er nede.</string>
<string name="err_log_post_failed">Beklager, c:geo klarte ikke å logge funnet.</string>
<string name="err_search_address_forgot">Beklager, c:geo glemte adressen du prøvde å finne.</string>
<string name="err_parse_lat">Beklager, c:geo klarte ikke å lese breddegraden.</string>
diff --git a/main/res/values-nl/strings.xml b/main/res/values-nl/strings.xml
index 27081f7..6a6f165 100644
--- a/main/res/values-nl/strings.xml
+++ b/main/res/values-nl/strings.xml
@@ -5,7 +5,7 @@
<string name="cache">Cache</string>
<string name="detail">Details</string>
<string name="search">Zoeken</string>
- <string name="helpers">Wat te installeren</string>
+ <string name="helpers">Handige apps</string>
<string name="about">Over c:geo</string>
<string name="latitude">Breedtegraad</string>
<string name="longitude">Lengtegraad</string>
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">Virtual</string>
<string name="cache_size_notchosen">not chosen</string>
<string name="cache_size_unknown">Onbekend</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Erg Groot</string>
<string name="wp_final">Eindbestemming</string>
<string name="wp_stage">Multi-cache punt</string>
<string name="wp_puzzle">Vraag voor antwoord</string>
@@ -99,7 +101,7 @@
<string name="log_stars_35_description">Goed</string>
<string name="log_stars_4_description">Boven gemiddeld</string>
<string name="log_stars_45_description">Zeer goed</string>
- <string name="log_stars_5_description">geweldig</string>
+ <string name="log_stars_5_description">Geweldig</string>
<string name="log_webcam">Webcam foto gemaakt</string>
<string name="log_new_log">Log</string>
<string name="log_new_log_text">Log tekst</string>
@@ -121,11 +123,10 @@
<string name="translate_to_english">Vertaal naar engels</string>
<string name="translate_length_warning">Vertaling kan mislukken bij grote stukken tekst.</string>
<string name="err_none">Ok</string>
- <string name="err_start">Communicatie niet gestart</string>
<string name="err_parse">Login pagina verwerken mislukt</string>
<string name="err_server">Verbinding met Geocaching.com mislukt (geen verbinding of server niet bereikbaar)</string>
+ <string name="err_server_ec">Verbinding maken met Extremcaching.com is mislukt (geen verbinding of server niet bereikbaar).</string>
<string name="err_login">Geen login informatie opgeslagen</string>
- <string name="err_login_failed">Sorry, c:geo kan niet inloggen.</string>
<string name="err_login_failed_toast">Sorry, c:geo kan niet inloggen. c:geo werkt in offline modus. Controleer je gebruikersnaam en wachtwoord en/of zet de internetverbinding aan.</string>
<string name="err_unknown">Onbekende fout</string>
<string name="err_comm">Onbekende communicatiefout</string>
@@ -177,9 +178,9 @@
<string name="err_log_load_data">Sorry, c:geo kan data om bezoek te loggen niet laden.</string>
<string name="err_log_load_data_again">Sorry, c:geo kan data om bezoek te loggen niet laden. Bezig nogmaals te proberen.</string>
<string name="err_log_load_data_still">c:geo is nog steeds bezig om data te laden om bezoek te loggen. Graag nog even geduld.</string>
- <string name="err_log_failed_server">Sorry, c:geo kon bezoek niet loggen omdat de server niet reageert.</string>
<string name="err_log_post_failed">Sorry, het is c:geo niet gelukt het log te posten.</string>
- <string name="err_logimage_post_failed">Het lijkt erop dat uw log-foto is niet geüpload. Controleer het op Geocaching.com.</string>
+ <string name="err_log_post_failed_ec">Het lijkt erop dat uw log niet werd gepost. Controleer het op Extremcaching.com.</string>
+ <string name="err_logimage_post_failed">Het lijkt erop dat uw log-foto niet geüpload is. Controleer het op Geocaching.com.</string>
<string name="err_search_address_forgot">Sorry, c:geo is het adres dat je zoekt vergeten.</string>
<string name="err_parse_lat">Sorry, c:geo kan breedtegraad niet verwerken.</string>
<string name="err_parse_lon">Sorry, c:geo kan lengtegraad niet verwerken.</string>
@@ -191,7 +192,7 @@
<string name="warn_no_keyword">Geen sleutelwoord opgegeven.</string>
<string name="warn_no_username">Geem gebruikersnaam opgegeven.</string>
<string name="warn_search_help_title">Hulp nodig?</string>
- <string name="warn_search_help_address">\"Vul adres of locatienaam. Gebruik bijvoorbeeld adres \"Hoofdstraat 100, Amsterdam, Nederland\", plaatsnaam \"Utrecht\" of een naam \"Nationaal Park de Hoge Veluwe\".</string>
+ <string name="warn_search_help_address">Vul adres of locatienaam. Gebruik bijvoorbeeld adres \"Hoofdstraat 100, Amsterdam, Nederland\", plaatsnaam \"Utrecht\" of een naam \"Nationaal Park de Hoge Veluwe\".</string>
<string name="warn_search_help_gccode">Voer de cachecode in. Bijvoorbeeld \"GC1VCAZ\".</string>
<string name="warn_search_help_keyword">Voer een woord in dat een deel is van de cache naam die je zoekt.</string>
<string name="warn_search_help_user">Voer een gebruikersnaam in van een Geocaching.com gebruiker.</string>
@@ -199,9 +200,11 @@
<string name="warn_log_text_fill">Voer s.v.p. een logtekst in.</string>
<string name="warn_load_images">Sorry, c:geo kon de afbeeldingen niet laden.</string>
<string name="warn_invalid_mapfile">Het geselecteerde mapbestand is geen correct mapforge 0.3.0 mapbestand.\nOffline kaarten zijn niet beschikbaar.</string>
- <string name="warn_deprecated_mapfile">Ge gebruikt een verouderde 0.2.4 mapbestand.\nJe word aangeraden naar een 0.3.0 mapbestand over te schakelen.\nOndersteuning voor de 0.2.4 versie zal in de volgende versie verdwijnen.</string>
+ <string name="warn_deprecated_mapfile">Je gebruikt een verouderd 0.2.4 mapbestand.\nJe word aangeraden naar een 0.3.0 mapbestand over te schakelen.\nOndersteuning voor de 0.2.4 versie zal in de volgende versie verdwijnen.</string>
<string name="warn_nonexistant_mapfile">Het geselecteerde mapbestand bestaat niet.\nOffline kaarten zijn niet beschikbaar.</string>
<string name="warn_rendertheme_missing">Map thema niet gevonden.</string>
+ <string name="warn_pocket_query_select">Geen Pocket query geselecteerd.</string>
+ <string name="warn_no_pocket_query_found">Geen Pocket query online gevonden.</string>
<string name="info_log_posted">c:geo heeft log succesvol gepost.</string>
<string name="info_log_saved">c:geo heeft log succesvol opgeslagen.</string>
<string name="info_log_cleared">Log is gewist.</string>
@@ -222,6 +225,7 @@
<string name="menu_history">Geschiedenis</string>
<string name="menu_filter">Filter</string>
<string name="menu_scan_geo">Scan geocode</string>
+ <string name="menu_pocket_queries">Pocket queries</string>
<string name="live_map_button">Live kaart</string>
<string name="caches_nearby_button">Dichtbij</string>
<string name="advanced_search_button">Zoeken</string>
@@ -255,11 +259,11 @@
<string name="caches_sort_date_hidden">Datum geplaatst</string>
<string name="caches_sort_date_logged">Datum gelogd</string>
<string name="caches_sort_finds">Aantal keer gevonden</string>
- <string name="caches_sort_state">Staat</string>
+ <string name="caches_sort_state">Selectie omkeren</string>
<string name="caches_sort_storage">Datum opgeslagen op apparaat</string>
<string name="caches_select_mode">Selectie modus</string>
<string name="caches_select_mode_exit">Selectie modus beëindigen</string>
- <string name="caches_select_invert">Inverteer selectie</string>
+ <string name="caches_select_invert">Selectie omkeren</string>
<string name="caches_nearby">Nabij</string>
<string name="caches_manage">Beheer</string>
<string name="caches_drop_selected">Drop geselecteerde</string>
@@ -282,15 +286,15 @@
<string name="caches_recaptcha_continue">Doorgaan</string>
<string name="caches_filter">Filter</string>
<string name="caches_filter_title">Filter op</string>
- <string name="caches_filter_size">grootte</string>
- <string name="caches_filter_type">type</string>
- <string name="caches_filter_track">met trackables</string>
- <string name="caches_filter_clear">maak filters leeg</string>
+ <string name="caches_filter_size">Grootte</string>
+ <string name="caches_filter_type">Type</string>
+ <string name="caches_filter_track">Met trackables</string>
+ <string name="caches_filter_clear">Maak filters leeg</string>
<string name="caches_filter_modified">Met aangepaste coordinaten</string>
- <string name="caches_filter_origin">Origin</string>
+ <string name="caches_filter_origin">Oorsprong</string>
<string name="caches_filter_distance">Afstand</string>
<string name="caches_removing_from_history">Verwijderen uit geschiedenis…</string>
- <string name="caches_clear_offlinelogs">Duidelijk off line logs</string>
+ <string name="caches_clear_offlinelogs">Verwijderen offline logs</string>
<string name="caches_clear_offlinelogs_progress">Offline logs worden verwijderd</string>
<string name="list_menu">Lijst</string>
<string name="list_menu_create">Maak nieuwe lijst</string>
@@ -341,6 +345,8 @@
<string name="settings_gc_legal_note">Met het gebruik van de dienst van geocaching.com, accepteert u de gebruiksvoorwaarden van Groundspeak.</string>
<string name="settings_info_facebook_login_title">Facebook Login</string>
<string name="settings_info_facebook_login">U kunt c:geo login aanbrengen in geocaching.com met uw Facebook-account. Maar er is een eenvoudige alternatieve oplossing…</string>
+ <string name="settings_authorize">Autoriseer c:geo</string>
+ <string name="settings_reauthorize">Autoriseer c:geo nogmaals</string>
<string name="init_oc">Opencaching.de</string>
<string name="settings_activate_oc">Activeren</string>
<string name="init_oc_de_description">c:geo authoriseren met opencaching.de om naar caches te zoeken en het filteren van gevonden caches.</string>
@@ -367,21 +373,21 @@
<string name="init_signature_template_user">Gebruiker</string>
<string name="init_signature_template_number">Nummer</string>
<string name="init_signature_template_owner">Eigenaar</string>
- <string name="init_ratingwanted">Laad cachewaardering van GCvote.com</string>
+ <string name="init_ratingwanted">GCvote.com waardering</string>
<string name="init_summary_ratingwanted">Laad cachewaardering van GCvote.com</string>
- <string name="init_friendlogswanted">Laad extra logbook pagina voor logs van vrienden</string>
+ <string name="init_friendlogswanted">Lange omschrijving</string>
<string name="init_summary_friendlogswanted">Laad extra logbook pagina voor logs van vrienden</string>
<string name="init_openlastdetailspage">Laad details met laatst gebruikte pagina</string>
<string name="init_summary_openlastdetailspage">Laad details met laatst gebruikte pagina</string>
- <string name="init_autoload">Automatisch laden van lange omschrijving</string>
+ <string name="init_autoload">Lange omschrijving</string>
<string name="init_summary_autoload">Automatisch laden van lange omschrijving</string>
- <string name="init_skin">Lichte skin (c:geo herstarten)</string>
+ <string name="init_skin">Lichte skin</string>
<string name="init_summary_skin">Lichte skin (c:geo herstarten)</string>
- <string name="init_address">Toon adres in plaats van positie op hoofdscherm</string>
+ <string name="init_address">Toon adres</string>
<string name="init_summary_address">Toon adres in plaats van positie op hoofdscherm</string>
- <string name="init_captcha">Laat CAPTCHA zien indien noodzakelijk</string>
+ <string name="init_captcha">Tonen CAPTCHA</string>
<string name="init_summary_captcha">Laat CAPTCHA zien indien noodzakelijk</string>
- <string name="init_useenglish">Use English inside c:geo\n(restart needed)</string>
+ <string name="init_useenglish">Use English language</string>
<string name="init_summary_useenglish">Use English inside c:geo\n(restart needed)</string>
<string name="init_exclude">Eigen en gevonden caches uitsluiten</string>
<string name="init_summary_exclude">Eigen en gevonden caches uitsluiten</string>
@@ -422,6 +428,8 @@
<string name="settings_info_themes_title">Info over kaart thema\'s</string>
<string name="settings_info_themes">c:geo ondersteund aangepaste thema\'s voor offline kaarten. Deze kunnen worden gebruikt voor het aanpassen om kleurstijlen van de kaart (bijv. een nachtmodus) of het accentueren van bepaalde objecten zoals fietspaden of hoogtelijnen op de kaart.</string>
<string name="init_mapsource_select">Selecteer kaartbron</string>
+ <string name="settings_title_scale_map_text">Tekst op kaart schalen</string>
+ <string name="settings_summary_scale_map_text">Tekst labels op offline kaart schalen n.a.v. DPI apparaat</string>
<string name="init_map_directory_description">Directory met offline kaarten</string>
<string name="init_gpx_exportdir">GPX Export Directory</string>
<string name="init_gpx_importdir">GPX Import Directory</string>
@@ -439,21 +447,24 @@
<string name="init_default_navigation_tool_select">Selecteer tool</string>
<string name="init_default_navigation_tool_2_description">Hier kan je de tweede navigatie-tool van jouw voorkeur instellen. Je kan deze activeren door lang op de navigatie-icoon naast de titel van de cache te klikken.</string>
<string name="init_navigation_menu_description">Here kun je selecteren welke beschikbare navigatie methodes getoond worden in het navigatie menu voor een cache of waypoint. Uitgeschakelde tools zijn niet geïnstalleerd op uw apparaat.</string>
- <string name="init_debug_title">Debug informatie</string>
- <string name="init_debug_note">c:geo kan een boel debug-informatie genereren. Alhoewel deze gegevens niet nuttig zijn voor c:geo gebruikers, ontwikkelaars kunnen deze gegevens nodig hebben om een bug te analyseren. Ze zullen dan vragen om hier een vinkje te plaatsen en de logfile op te sturen.</string>
- <string name="init_debug">Activeer foutopsporing logboek</string>
+ <string name="init_debug_title">Foutopsporings informatie</string>
+ <string name="init_debug_note">c:geo kan een foutopsporings-informatie genereren. Alhoewel deze gegevens niet nuttig zijn voor c:geo gebruikers, kunnen ontwikkelaars deze nodig hebben om een bug te analyseren. Ze zullen dan vragen om hier een vinkje te plaatsen en de logfile op te sturen.</string>
+ <string name="init_debug">Activeer foutopsporings informatie</string>
<string name="init_dbonsdcard_title">Database locatie</string>
<string name="init_dbonsdcard_note">Je kan de c:geo database op een externe locatie opslaan. Dit zal intern geheugen besparen maar kan de applicatie iets trager maken en c:geo zal niet werken als het externe medium (zoals een (micro-)SD-kaart) verwijderd is.</string>
<string name="init_dbonsdcard">Op externe locatie.</string>
<string name="init_dbmove_dbmove">Verplaats database</string>
- <string name="init_dbmove_running">Verplaats database</string>
+ <string name="init_dbmove_running">Verplaatsen database…</string>
<string name="init_dbmove_success">Database succesvol verplaatst.</string>
<string name="init_dbmove_failed">Database kon niet verplaatst worden.</string>
- <string name="init_plain_logs">Laat logs zien zonder kleuren.</string>
+ <string name="init_plain_logs">Logs zonder opmaak tonen</string>
<string name="init_summary_plain_logs">Laat logs zien zonder kleuren.</string>
- <string name="init_use_native_ua">Identificeer als Android browser (lost loginproblemen bij sommige mobiele aanbieders op).</string>
+ <string name="init_use_native_ua">Identificeer als Android browser</string>
<string name="init_summary_use_native_ua">Identificeer als Android browser (lost loginproblemen bij sommige mobiele aanbieders op).</string>
<string name="init_rendertheme_folder">Kaart thema\'s directorie</string>
+ <string name="settings_open_website">Open website</string>
+ <string name="settings_settings">Instellingen</string>
+ <string name="settings_information">Informatie</string>
<string name="map_source_google_map">Google: Map</string>
<string name="map_source_google_satellite">Google: Satellite</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
@@ -462,9 +473,9 @@
<string name="init_sendToCgeo">Verstuur naar c:geo</string>
<string name="settings_info_send2cgeo_title">Informatie over send2cgeo</string>
<string name="init_sendToCgeo_name">Jouw apparaatnaam</string>
- <string name="init_sendToCgeo_description">Verstuur naar c:geo zorgt ervoor dat je caches direct vanaf de geocaching website kan ontvangen door middel van een plugin in je webbrowser (Firefox of Chrome). Lees het volgende voordat je registreert <a href="http://send2.cgeo.org/">http://send2.cgeo.org/</a>. Registratie is alleen nodig als je send2cgeo wil gebruiken. C:geo werkt ook zonder het registreren van je apparaat.</string>
+ <string name="init_sendToCgeo_description"><b>Send2c:geo</b> zorgt ervoor dat je caches direct vanaf de geocaching website kan ontvangen door middel van een plugin in je webbrowser (Chrome of Firefox). Lees het volgende voordat je registreert <a href="http://send2.cgeo.org/">http://send2.cgeo.org/</a>. Registratie is alleen nodig als je send2cgeo wil gebruiken. c:geo werkt ook zonder het registreren van je apparaat.</string>
<string name="init_sendToCgeo_register">Verstuur registratieverzoek</string>
- <string name="init_sendToCgeo_registering">Bezig met het registreren voor \"Send to c:geo\"…</string>
+ <string name="init_sendToCgeo_registering">Bezig met het registreren voor \"Send2c:geo\"…</string>
<string name="init_sendToCgeo_register_ok">Registratie gelukt. PIN code is ####. Gebruik dit op de c:geo website om dit apparaat aan je browser toe te voegen.</string>
<string name="init_sendToCgeo_register_fail">Registratie is niet gelukt.</string>
<string name="sendToCgeo_download_fail">Het is c:geo niet gelukt om de caches te downloaden. Geen internetverbinding beschikbaar of send2c:geo is niet bereikbaar.</string>
@@ -473,6 +484,10 @@
<string name="auth_authorize">c:geo Autoriseren</string>
<string name="auth_start">Start autorisatie</string>
<string name="auth_again">Nogmaals starten</string>
+ <string name="auth_dialog_waiting">Wachten op %s…</string>
+ <string name="auth_explain_short">Het volgende proces zal <b>c:geo</b> toegang geven tot %s.</string>
+ <string name="auth_explain_long">Druk op de knop \"Autoriseer c:geo\" om het proces te starten. Dit proces zal een webbrowser met een pagina voor %s. Log in op deze pagina om <b>c:geo</b> toegang te geven tot je account. Dat is alles.</string>
+ <string name="auth_dialog_completed_twitter">c:geo is nu gekoppeld met Twitter.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo is nu gekoppeld met %s.</string>
@@ -494,7 +509,7 @@
<string name="cache_log_offline">Offline log</string>
<string name="cache_log_images_title">Logafbeelding</string>
<string name="cache_log_image_default_title">Foto</string>
- <string name="cache_personal_note">Persoonlijke aantekening</string>
+ <string name="cache_personal_note">Persoonlijke notitie</string>
<string name="cache_personal_note_edit">Wijzig</string>
<string name="cache_personal_note_upload">Uploaden</string>
<string name="cache_personal_note_uploading">Uploading persoonlijke notitie</string>
@@ -514,7 +529,7 @@
<string name="cache_favpoint_add">Voeg toe</string>
<string name="cache_favpoint_remove">Verwijder</string>
<string name="cache_list_text">Lijst:</string>
- <string name="cache_list_change">Verplaats</string>
+ <string name="cache_list_change">Verplaatsen</string>
<string name="cache_list_unknown">Niet in een lijst</string>
<string name="cache_images">Afbeeldingen</string>
<string name="cache_waypoints">Waypoints</string>
@@ -536,7 +551,7 @@
<string name="cache_dialog_offline_drop_title">Offline</string>
<string name="cache_dialog_offline_drop_message">Verwijder cache uit geheugen…</string>
<string name="cache_dialog_refresh_title">Ververs</string>
- <string name="cache_dialog_refresh_message">Herlaad cachedetails…</string>
+ <string name="cache_dialog_refresh_message">Vernieuw cachedetails…</string>
<string name="cache_dialog_watchlist_add_title">Watchlist</string>
<string name="cache_dialog_watchlist_add_message">Voeg cache toe aan watchlist…</string>
<string name="cache_dialog_watchlist_remove_title">Watchlist</string>
@@ -548,7 +563,7 @@
<string name="cache_menu_navigate">Navigeer</string>
<string name="cache_menu_navigation_drive">Navigeer (rijden)</string>
<string name="cache_menu_navigation_walk">Navigeer (lopen)</string>
- <string name="cache_menu_navigation_bike">Navigeren (fiets)</string>
+ <string name="cache_menu_navigation_bike">Navigeer (fiets)</string>
<string name="cache_menu_maps_directions">Google Maps aanwijzigen</string>
<string name="cache_menu_radar">Radar</string>
<string name="cache_menu_map">Toon op kaart</string>
@@ -581,7 +596,7 @@
<string name="cache_status_not_premium">Toegang voor alle leden</string>
<string name="cache_status_stored">Opgeslagen</string>
<string name="cache_status_not_stored">Niet opgeslagen</string>
- <string name="cache_geocode">geo code</string>
+ <string name="cache_geocode">Geo code</string>
<string name="cache_name">Naam</string>
<string name="cache_type">Type</string>
<string name="cache_size">Grootte</string>
@@ -599,16 +614,15 @@
<string name="cache_coordinates">Coördinaten</string>
<string name="cache_coordinates_original">Originele coordinaten</string>
<string name="cache_spoiler_images_title">Spoiler afbeeldingen</string>
- <string name="cache_images_title">Afbeeldingen</string>
<string name="cache_log_types">Log types</string>
<string name="cache_coordinates_no">Deze cache heeft geen coördinaten.</string>
- <string name="cache_clear_history">Maak geschiedenis leeg</string>
+ <string name="cache_clear_history">Geschiedenis verwijderen</string>
<string name="cache_remove_from_history">Verwijder uit geschiedenis</string>
<string name="cache_license">Licentie</string>
<string name="cache_image">Afbeelding</string>
<string name="cache_image_open_file">Open als bestand</string>
<string name="cache_image_open_browser">Open in browser</string>
- <string name="cache_share_field">Deel</string>
+ <string name="cache_share_field">Delen</string>
<string name="cache_time_full_hours">uur</string>
<string name="cache_listed_on">Opgenomen in %s</string>
<string name="file_searching_in">Zoeken naar bestanden\nin</string>
@@ -622,23 +636,23 @@
<string name="gpx_import_loading_waypoints">Waypoints laden van .gpx bestand</string>
<string name="gpx_import_store_static_maps">Opslaan statische kaarten</string>
<string name="gpx_import_caches_imported">Caches geïmporteerd</string>
- <string name="gpx_import_static_maps_skipped">Download van statische kaarten afgebroken</string>
+ <string name="gpx_import_static_maps_skipped">Downloaden van statische kaarten afgebroken</string>
<string name="gpx_import_title_static_maps">Sla statische kaarten op</string>
<string name="gpx_import_title_reading_file">Bestand lezen</string>
<string name="gpx_import_title">Importeer GPX</string>
<string name="gpx_import_title_caches_imported">Resultaat</string>
<string name="gpx_import_title_caches_import_failed">Importeren niet gelukt</string>
<string name="gpx_import_error_io">Kan bestand niet lezen</string>
- <string name="gpx_import_error_parser">Bestandsformaat niet goed</string>
- <string name="gpx_import_error_unexpected">Onbekend probleem</string>
+ <string name="gpx_import_error_parser">Bestandsformaat onjuist</string>
+ <string name="gpx_import_error_unexpected">Onverwachte fout</string>
<string name="gpx_import_canceled">GPX import is afgebroken</string>
- <string name="gpx_import_delete_title">Verwijder file</string>
+ <string name="gpx_import_delete_title">Verwijder bestand</string>
<string name="gpx_import_delete_message">Weet je zeker dat je %s wil verwijderen?</string>
- <string name="gpx_import_select_list_title">Importeren GPX naar lijst</string>
+ <string name="gpx_import_select_list_title">Importeer GPX naar lijst</string>
<string name="map_file_select_title">Selecteer mapbestand</string>
<string name="web_import_title">Importeer van web</string>
<string name="web_import_waiting">Aan het wachten voor nieuwe caches van het web…</string>
- <string name="web_downloading">Downloading</string>
+ <string name="web_downloading">Downloaden…</string>
<string name="web_downloaded">Gedownload</string>
<string name="popup_more">Meer details</string>
<string name="waypoint">Waypoint</string>
@@ -666,24 +680,24 @@
<string name="waypoint_localy_reset_cache_coords">Herstel in c:geo</string>
<string name="waypoint_reset_local_and_remote_cache_coords">Herstel in c:geo en op de website</string>
<string name="waypoint_being_saved">Waypoint wordt opgeslagen…</string>
- <string name="waypoint_coordinates_couldnt_be_modified_on_website">Website ondersteund niet het wijzigen van de cachecoördinaten.</string>
+ <string name="waypoint_coordinates_couldnt_be_modified_on_website">Website ondersteund wijzigen van de cachecoördinaten niet.</string>
<string name="waypoint_coordinates_upload_error">Fout opgetreden tijdens het aanpassen van de coördinaten op de website.</string>
<string name="waypoint_coordinates_uploading_to_website">Bezig met uploaden van coördinaten %s naar de website.</string>
<string name="waypoint_coordinates_has_been_modified_on_website">Cachecoördinaten op de website zijn aangepast naar: %s.</string>
- <string name="waypoint_done">Klaar</string>
- <string name="waypoint_duplicate">Dubbel</string>
+ <string name="waypoint_done">Afgerond</string>
+ <string name="waypoint_duplicate">Duplicaat</string>
<string name="waypoint_copy_of">Kopie van</string>
<string name="search_history">Geschiedenis</string>
<string name="search_history_empty">Geen eerdere bestemmingen</string>
<string name="search_remove_destination">Bestemming verwijderd</string>
<string name="search_clear_history">Maak geschiedenis leeg</string>
<string name="search_history_cleared">Geschiedenis leeggemaakt</string>
- <string name="waypoint_coordinate_formats_plain">Vlak</string>
+ <string name="waypoint_coordinate_formats_plain">Plat</string>
<string name="visit_tweet">Post deze vondst op Twitter</string>
<string name="map_map">Kaart</string>
<string name="map_live">Live kaart</string>
<string name="map_view_map">Kaart weergave</string>
- <string name="map_modes">Kaartkeuzes</string>
+ <string name="map_modes">Kaartinstellingen</string>
<string name="map_trail_show">Toon spoor</string>
<string name="map_trail_hide">Verberg spoor</string>
<string name="map_circles_show">Laat cirkels zien</string>
@@ -696,16 +710,15 @@
<string name="map_live_disable">Live uitzetten</string>
<string name="map_static_title">Statische kaarten</string>
<string name="map_static_loading">Statische kaarten laden…</string>
- <string name="map_token_err">Omdat c:geo alleen gedeeltelijke gegevens kan downloaden, kunnen de coördinaten inaccuraat zijn.</string>
+ <string name="map_token_err">Omdat c:geo alleen gedeeltelijke gegevens kan downloaden, kunnen de coördinaten onnauwkeurig zijn.</string>
<string name="map_as_list">Laat zien als lijst</string>
<string name="map_strategy">Strategie</string>
- <string name="map_strategy_title">Live Map strategie</string>
+ <string name="map_strategy_title">Live kaart strategie</string>
<string name="map_strategy_fastest">Snelste</string>
<string name="map_strategy_fast">Snel</string>
<string name="map_strategy_auto">Afhankelijk van snelheid</string>
<string name="map_strategy_detailed">Gedetailleerd</string>
<string name="live_map_notification">Op de nieuwe live-kaart zullen coördinaten niet altijd exact zijn. Mogelijke onnauwkeurige coördinaten zijn aangegeven met een oranje cirkel.\nHet openen of opslaan van de cache zorgt ervoor dat de exacte coördinaten gebruikt worden.\n\nMeer informatie over de wijzigingen kan gevonden worden op de \"Over c:geo\" pagina in de app.</string>
- <string name="live_map_note_dontshow">Laat niet nogmaals zien</string>
<string name="search_bar_hint">Zoek naar caches</string>
<string name="search_bar_desc">Caches (geo code, trefwoord), Trackables (TB-code)</string>
<string name="search_coordinates">Coördinaten</string>
@@ -769,14 +782,16 @@
<string name="use_compass">Gebruik GPS en kompas</string>
<string name="destination_select">Selecteer bestemming</string>
<string name="destination_set">Zet bestemming</string>
- <string name="navigation_direct_navigation">Directe Navigatie</string>
+ <string name="navigation_direct_navigation">Directe navigatie</string>
<string name="navigation_target">Doel</string>
+ <string name="err_nav_no_coordinates">Kan navigatie niet starten zonder coördinaten</string>
<string name="license">Licentie</string>
<string name="license_show">Toon licentie</string>
<string name="license_dismiss">Afwijzen</string>
<string name="helper_calendar_title">c:geo kalender add-on</string>
- <string name="helper_calendar_missing">c:geo kalender add-on niet geinstalleerd.</string>
+ <string name="helper_calendar_missing">c:geo kalender add-on niet geïnstalleerd.</string>
<string name="helper_calendar_description">Maakt het mogelijk om Geocaching events in je kalender op te slaan.</string>
+ <string name="helper_contacts_title">c:geo contacten-plug-in</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Simpele bruikbare applicatie om online kaarten weer te geven en deze voor offline gebruik te downloaden (alleen rasterkarten). Ook ondersteuning voor track recording, poi afhandeling en vele andere handige functies.</string>
<string name="helper_gpsstatus_title">GPS Status</string>
@@ -786,22 +801,22 @@
<string name="helper_barcode_title">Barcode Scanner</string>
<string name="helper_barcode_description">Er zijn Greasemonkey scripts en websites beschikbaar die een geocode als barcode weergeven. Met deze applicatie kan c:geo deze geocode direct van het computerscherm lezen.</string>
<string name="helper_pocketquery_title">Pocket Query Creator</string>
- <string name="helper_pocketquery_description">Kunnen gemakkelijk maken en downloaden van Pocket query\'s gericht op uw huidige positie of een punt is geselecteerd van een kaart. Vereist een account premie Geocaching.com.</string>
+ <string name="helper_pocketquery_description">Makkelijk Pocket Query\'s maken en downloaden gericht op uw huidige positie of een punt geselecteerd van een kaart. Vereist een Premium account van Geocaching.com.</string>
<string name="addon_missing_title">Add-On ontbreekt</string>
<string name="addon_download_prompt">Haal de add-on nu op van Google Play.</string>
<string name="export">Export</string>
<string name="export_exportedto">Geexporteerd naar</string>
<string name="export_failed">Exporteren mislukt</string>
<string name="export_fieldnotes">Veld-notities</string>
- <string name="export_fieldnotes_info">Veld-notities worden geexporteerd naar /sdcard/field-notes met huidige datum en tijd als bestandsnaam.</string>
+ <string name="export_fieldnotes_info">Veld-notities worden geëxporteerd naar /sdcard/field-notes met huidige datum en tijd als bestandsnaam.</string>
<string name="export_fieldnotes_upload">Upload naar geocaching.com</string>
- <string name="export_fieldnotes_uploading">Uploading…</string>
- <string name="export_fieldnotes_upload_success">Upload naar geocaching.com succesvol</string>
- <string name="export_fieldnotes_onlynew">Alleen sinds laatste export</string>
- <string name="export_fieldnotes_creating">Veld-Notities worden gemaakt…</string>
+ <string name="export_fieldnotes_uploading">Uploaden…</string>
+ <string name="export_fieldnotes_upload_success">Uploaden naar geocaching.com succesvol</string>
+ <string name="export_fieldnotes_onlynew">Alles sinds laatste export</string>
+ <string name="export_fieldnotes_creating">Veld-notities worden gemaakt…</string>
<string name="export_gpx">GPX</string>
- <string name="export_gpx_info">Het GPX bestand word geexporteerd naar %1$s met huidige datum en tijd als bestandsnaam.</string>
- <string name="export_gpx_to">Verstuur geexporteerde GPX naar</string>
+ <string name="export_gpx_info">Het GPX bestand word geëxporteerd naar %1$s met huidige datum en tijd als bestandsnaam.</string>
+ <string name="export_gpx_to">Verstuur geëxporteerde GPX naar</string>
<string name="attribute_dogs_yes">Honden toegestaan</string>
<string name="attribute_dogs_no">Honden niet toegestaan</string>
<string name="attribute_bicycles_yes">Fietsen toegestaan</string>
@@ -822,8 +837,8 @@
<string name="attribute_rv_no">Truck driver/RV niet toegestaan</string>
<string name="attribute_kids_yes">Aanbevolen voor kinderen</string>
<string name="attribute_kids_no">Niet aanbevolen voor kinderen</string>
- <string name="attribute_onehour_yes">Duurt minder dan 1 uur</string>
- <string name="attribute_onehour_no">Duurt meer dan 1 uur</string>
+ <string name="attribute_onehour_yes">Duurt korter dan 1 uur</string>
+ <string name="attribute_onehour_no">Duurt langer dan 1 uur</string>
<string name="attribute_scenic_yes">Uitzicht(punt)</string>
<string name="attribute_scenic_no">Geen uitzicht(punt)</string>
<string name="attribute_hiking_yes">Significante wandeling</string>
@@ -834,7 +849,7 @@
<string name="attribute_wading_no">Lopen door water niet nodig</string>
<string name="attribute_swimming_yes">Mogelijk zwemmen nodig</string>
<string name="attribute_swimming_no">Zwemmen niet nodig</string>
- <string name="attribute_available_yes">Altijd beschikbaar</string>
+ <string name="attribute_available_yes">Alle tijden beschikbaar</string>
<string name="attribute_available_no">Niet altijd beschikbaar</string>
<string name="attribute_night_yes">\'s nachts aanbevolen</string>
<string name="attribute_night_no">Niet \'s nachts aanbevolen</string>
@@ -861,7 +876,7 @@
<string name="attribute_hike_long_yes">Lange wandeling (meer dan 10 km)</string>
<string name="attribute_hike_long_no">Geen lange wandeling</string>
<string name="attribute_seasonal_yes">Seizoens toegang</string>
- <string name="attribute_seasonal_no">Geen seizoens Toegang</string>
+ <string name="attribute_seasonal_no">Geen seizoens toegang</string>
<string name="attribute_touristok_yes">Toerist-vriendelijk</string>
<string name="attribute_touristok_no">Niet toerist-vriendelijk</string>
<string name="attribute_frontyard_yes">Privé woonplaats</string>
@@ -872,8 +887,8 @@
<string name="attribute_landf_no">Geen lost and found rondleiding</string>
<string name="attribute_partnership_yes">Partnership cache</string>
<string name="attribute_partnership_no">Geen partnership cache</string>
- <string name="attribute_fee_yes">Toegang-of parkeerkosten van toepassing</string>
- <string name="attribute_fee_no">Geen toegang-of parkeerkosten van toepassing</string>
+ <string name="attribute_fee_yes">Toegang- of parkeerkosten van toepassing</string>
+ <string name="attribute_fee_no">Geen toegang- of parkeerkosten van toepassing</string>
<string name="attribute_rappelling_yes">Klimuitrusting benodigd</string>
<string name="attribute_rappelling_no">Geen klimuitrusting nodig</string>
<string name="attribute_boat_yes">Boot benodigd</string>
@@ -926,8 +941,8 @@
<string name="attribute_picnic_no">Geen picknicktafels in de buurt</string>
<string name="attribute_camping_yes">Camping beschikbaar</string>
<string name="attribute_camping_no">Geen camping beschikbaar</string>
- <string name="attribute_stroller_yes">Wandelaar toegankelijk</string>
- <string name="attribute_stroller_no">Niet wandelaar toegankelijk</string>
+ <string name="attribute_stroller_yes">Toegankelijk voor kinderwagen</string>
+ <string name="attribute_stroller_no">Niet toegankelijk voor kinderwagen</string>
<string name="attribute_fuel_yes">Brandstof in de buurt</string>
<string name="attribute_fuel_no">Geen brandstof in de buurt</string>
<string name="attribute_food_yes">Eetgelegenheid in de buurt</string>
@@ -946,7 +961,7 @@
<string name="attribute_swamp_no">Geen moeras</string>
<string name="attribute_hills_yes">Bergachtig gebied</string>
<string name="attribute_hills_no">Geen bergachtig gebied</string>
- <string name="attribute_easy_climbing_yes">gemakkelijk klimmen</string>
+ <string name="attribute_easy_climbing_yes">Gemakkelijk klimmen</string>
<string name="attribute_easy_climbing_no">Geen gemakkelijk klimmen</string>
<string name="attribute_poi_yes">Interessant punt</string>
<string name="attribute_poi_no">Geen interessant punt</string>
@@ -996,12 +1011,12 @@
<string name="attribute_geotour_no">Geen onderdeel van GeoTour</string>
<string name="quote">Om geocahing makkelijker te maken en gebruikers luier te maken.</string>
<string name="powered_by">carnero</string>
- <string name="support">support:<a href="">support@cgeo.org</a></string>
- <string name="website">website: <a href="">cgeo.org</a></string>
+ <string name="support">Support: <a href="">support@cgeo.org</a></string>
+ <string name="website">Website: <a href="">cgeo.org</a></string>
<string name="facebook">Facebook: <a href="">c:geo page</a></string>
<string name="twitter">Twitter: <a href="">@android_GC</a></string>
<string name="nutshellmanual">Handleiding: <a href="">c:geo in een notendop</a></string>
- <string name="market">Android: <a href=""> c:geo op Google Play</a></string>
+ <string name="market">Android: <a href="">c:geo op Google Play</a></string>
<string name="about_twitter">Moet <b>c:geo</b> elke cache vondst publiceren naar Twitter?</string>
<string name="faq">FAQ: <a href=""> faq.cgeo.org</a></string>
<string name="status_new_release" tools:ignore="UnusedResources">Nieuwe release beschikbaar.\nTik om te installeren.</string>
@@ -1009,14 +1024,14 @@
<string name="status_new_rc" tools:ignore="UnusedResources">Nieuwe release-candidaad beschikbaar.\nTik om te installeren.</string>
<string name="status_geocaching_change" tools:ignore="UnusedResources">Recente aanpassingen op geocaching.com zorgen dat c:geo niet meer (100%) correct werkt.\nWe werken aan het probleem, controleer binnenkort nogmaals.</string>
<string name="status_geocaching_livemap" tools:ignore="UnusedResources">Recente aanpassingen op geocaching.com zorgen dat de live-kaart niet meer werkt.\nWe werken aan het probleem, controleer binnenkort nogmaals.</string>
- <string name="status_closeout_warning" tools:ignore="UnusedResources">U lijkt te worden met behulp van een versie van Android ouder dan 2.1. Toekomstige versies van c:geo mogelijk niet meer beschikbaar voor uw apparaat.</string>
- <string name="tts_service">Praten kompas</string>
+ <string name="status_closeout_warning" tools:ignore="UnusedResources">U lijkt gebruik te maken van een versie van Android ouder dan 2.1. Toekomstige versies van c:geo zijn mogelijk niet meer beschikbaar voor uw apparaat.</string>
+ <string name="tts_service">Pratend kompas</string>
<string name="tts_start">Begin met praten</string>
- <string name="tts_stop">Stoppen met praten</string>
+ <string name="tts_stop">Stop met praten</string>
<string name="err_tts_lang_not_supported">De huidige taal wordt niet ondersteund door tekst naar spraak.</string>
- <string name="tts_one_kilometer">een kilometer</string>
+ <string name="tts_one_kilometer">één kilometer</string>
<string name="tts_one_meter">één meter</string>
- <string name="tts_one_mile">een mijl</string>
+ <string name="tts_one_mile">één mijl</string>
<string name="tts_one_foot">één voet</string>
<string name="tts_one_oclock">één uur</string>
<string name="tts_oclock">%s uur</string>
diff --git a/main/res/values-pl/strings.xml b/main/res/values-pl/strings.xml
index 3fbbda6..1a38473 100644
--- a/main/res/values-pl/strings.xml
+++ b/main/res/values-pl/strings.xml
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">Wirtualna</string>
<string name="cache_size_notchosen">Niewybrano</string>
<string name="cache_size_unknown">Nieznana</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Bardzo duża</string>
<string name="wp_final">Finał</string>
<string name="wp_stage">Etap</string>
<string name="wp_puzzle">Zagadka</string>
@@ -117,15 +119,15 @@
<string name="log_image_scale">Skalowanie obrazu</string>
<string name="log_password_title">Hasło do logu:</string>
<string name="log_hint_log_password">Wpisz hasło do logu</string>
+ <string name="log_oc_team_comment">Komentarz zespołu OC</string>
<string name="translate_to_sys_lang">Przetłumacz na %s</string>
<string name="translate_to_english">Przetłumacz na angielski</string>
<string name="translate_length_warning">Tłumaczenie może nie udać się przy dużej ilości tekstu.</string>
<string name="err_none">OK</string>
- <string name="err_start">Komunikacja nie rozpoczeła się</string>
<string name="err_parse">Nieudany odczyt strony logowania.</string>
<string name="err_server">Nieudane połączenie z Geocaching.com. Strona albo Twoje połączenie internetowe nie działa.</string>
+ <string name="err_server_ec">Nieudane połączenie z Extremcaching.com. Strona może być w tej chwili niedostępna, bądź połączenie internetowe nie działa właściwie.</string>
<string name="err_login">Brak danych do logowania.</string>
- <string name="err_login_failed">c:geo nie może zalogować się.</string>
<string name="err_login_failed_toast">c:geo nie może zalogować się. c:geo pracuje offline z zapisanymi skrzynkami. Sprawdź dane logowania i połączenie z internetem.</string>
<string name="err_unknown">Nieznany błąd</string>
<string name="err_comm">Nieznany błąd w komunikacji</string>
@@ -177,8 +179,8 @@
<string name="err_log_load_data">c:geo nie może załadować danych wymaganych do wpisania wizyty.</string>
<string name="err_log_load_data_again">c:geo nie może załadować danych wymaganych do wpisania wizyty. Próbuję ponownie.</string>
<string name="err_log_load_data_still">Nadal trwa ładowanie danych wymaganych do wpisu w dzienniku. Proszę czekać…</string>
- <string name="err_log_failed_server">c:geo nie może dokonać wpisu ponieważ serwer nie odpowiada.</string>
<string name="err_log_post_failed">Wygląda na to, że Twój wpis nie został zapisany. Proszę sprawdź na Geocaching.com.</string>
+ <string name="err_log_post_failed_ec">Wygląda na to, że wpis nie został wysłany. Proszę sprawdzić to na stronie Extremcaching.com.</string>
<string name="err_logimage_post_failed">Wygląda na to, że Twój obraz nie został dodany. Proszę sprawdź to na Geocaching.com.</string>
<string name="err_search_address_forgot">c:geo zapomniał adresu, którego szukałeś.</string>
<string name="err_parse_lat">c:geo nie może obliczyć szerokości geograficznej.</string>
@@ -202,6 +204,8 @@
<string name="warn_deprecated_mapfile">Używasz przestarzałego pliku mapy w wersji 0.2.4.\nRozważ przejście na wersję mapy 0.3.0.\nNiedługo c:geo przestanie wspierać wersję 0.2.4.</string>
<string name="warn_nonexistant_mapfile">Wybrany plik z mapą nie istnieje.\nMapy offline są niedostępne.</string>
<string name="warn_rendertheme_missing">Nie znaleziono tytułu mapy.</string>
+ <string name="warn_pocket_query_select">Nie wybrano Pocket query.</string>
+ <string name="warn_no_pocket_query_found">Nie znaleziono Pocket query online.</string>
<string name="info_log_posted">Wpis został wysłany.</string>
<string name="info_log_saved">Wpis został zapisany.</string>
<string name="info_log_cleared">Wpis został usunięty.</string>
@@ -222,11 +226,13 @@
<string name="menu_history">Historia</string>
<string name="menu_filter">Filter</string>
<string name="menu_scan_geo">Zeskanuj geokod</string>
- <string name="live_map_button">Mapa Live</string>
+ <string name="menu_pocket_queries">Pocket queries</string>
+ <string name="menu_scan_description">c:geo może skanować geokody, które są wydrukowane jako kody QR. Wymagana aplikacja nie jest zainstalowana. Czy chcesz otworzyć Google Play i ją zainstalować?</string>
+ <string name="live_map_button">Mapa online</string>
<string name="caches_nearby_button">Najbliższe</string>
<string name="advanced_search_button">Szukaj</string>
<string name="stored_caches_button">Zapisane</string>
- <string name="any_button">Gdziekolwiek</string>
+ <string name="any_button">Współrzędne</string>
<string name="unknown_scan">c:geo nie znalazł żadnego GC-kodu w wynikach skanowania.</string>
<string name="caches_no_cache">Brak skrzynki</string>
<string name="caches_more_caches">Więcej skrzynek</string>
@@ -245,8 +251,8 @@
<string name="caches_sort_difficulty">trudności</string>
<string name="caches_sort_terrain">terenu</string>
<string name="caches_sort_size">rozmiaru</string>
- <string name="caches_sort_favorites">popularności</string>
- <string name="caches_sort_favorites_ratio">popularności [%]</string>
+ <string name="caches_sort_favorites">Ulubione</string>
+ <string name="caches_sort_favorites_ratio">Ulubione [%]</string>
<string name="caches_sort_name">nazwy</string>
<string name="caches_sort_geocode">Kod skrytki</string>
<string name="caches_sort_rating">oceny</string>
@@ -289,6 +295,9 @@
<string name="caches_filter_modified">Zmiany koordynatów </string>
<string name="caches_filter_origin">Źródło</string>
<string name="caches_filter_distance">Odległość</string>
+ <string name="caches_filter_personal_note">Zawiera notatkę</string>
+ <string name="caches_filter_popularity">Ulubione</string>
+ <string name="caches_filter_popularity_ratio">Ulubione [%]</string>
<string name="caches_removing_from_history">Usuwam z Historii…</string>
<string name="caches_clear_offlinelogs">Usuń logi offline</string>
<string name="caches_clear_offlinelogs_progress">Usuwanie logów offline</string>
@@ -311,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo nie mógł usunąć aktualnej listy</string>
<string name="list_dialog_rename_title">Zmień nazwę listy</string>
<string name="list_dialog_rename">Zmień nazwę</string>
+ <string name="list_not_available">Lista nie jest już dostępna, przechodzę do standardowej listy</string>
<string name="about_version">Wersja</string>
<string name="about_changelog">Zmiany</string>
<string name="about_donate">Podaruj</string>
@@ -328,6 +338,7 @@
<string name="settings_title_map_data">Dane mapy</string>
<string name="settings_title_map_content">Zawartość mapy</string>
<string name="settings_title_gpx">GPX</string>
+ <string name="settings_title_basicmembers">Opcje dla podstawowego członkowstwa</string>
<string name="settings_title_navigation">Nawigacja</string>
<string name="settings_title_system">System</string>
<string name="settings_title_navigation_menu">Menu nawigacji</string>
@@ -337,10 +348,16 @@
<string name="settings_category_logging_other">Inne opcje logowania</string>
<string name="settings_goto_url_button">więcej …</string>
<string name="settings_title_gc">Geocaching.com</string>
+ <string name="settings_title_ec">Extremcaching.com</string>
+ <string name="settings_title_ox">Opencaching.com (Garmin)</string>
<string name="settings_activate_gc">Aktywuj</string>
+ <string name="settings_activate_ec">Aktywuj</string>
+ <string name="settings_activate_ox">Aktywuj</string>
<string name="settings_gc_legal_note">Używając serwisu geocaching.com, akceptujesz postanowienia licencyjne Groundspeak.</string>
<string name="settings_info_facebook_login_title">Facebook Login</string>
<string name="settings_info_facebook_login">Nie możesz zmusić c:geo aby zalogował się do geocaching.com przy pomocy Twojego konta Facebook. Jednakże istnieje proste rozwiązanie …</string>
+ <string name="settings_authorize">Autoryzuj c:geo</string>
+ <string name="settings_reauthorize">Autoryzuj c:geo ponownie</string>
<string name="init_oc">Opencaching.de</string>
<string name="settings_activate_oc">Aktywuj</string>
<string name="init_oc_de_description">Autoryzuj c:geo z opencaching.de aby wyszukiwać skrzynki i mieć dostęp/filtrować znalezione skrzynki.</string>
@@ -359,7 +376,10 @@
<string name="init_login_popup_failed">Logowanie nie powiodło się</string>
<string name="init_login_popup_failed_reason">Logowanie nie powiodło się, ponieważ </string>
<string name="init_login_popup_not_authorized">Brak autoryzacji</string>
+ <string name="init_login_popup_invalid_timestamp">Czas lokalny nieprawidłowy, ustaw właściwy czas urządzenia</string>
+ <string name="init_login_popup_invalid_token">Autoryzacja nieprawidłowa, spróbuj ponownie</string>
<string name="init_signature">Podpis</string>
+ <string name="init_template_help">Tagi jak np. [NAZWA] będą używane w przyszłości.</string>
<string name="init_signature_template_button">Wstaw szablon</string>
<string name="init_signature_template_date">Data</string>
<string name="init_signature_template_time">Czas</string>
@@ -367,6 +387,9 @@
<string name="init_signature_template_user">Użytkownik</string>
<string name="init_signature_template_number">Numer</string>
<string name="init_signature_template_owner">Właściciel</string>
+ <string name="init_signature_template_name">Nazwa</string>
+ <string name="init_signature_template_url">URL</string>
+ <string name="init_signature_template_log">Wpis</string>
<string name="init_ratingwanted">Załaduj ocenę skrzynki z GCvote.com</string>
<string name="init_summary_ratingwanted">Załaduj ocenę skrzynki z GCvote.com</string>
<string name="init_friendlogswanted">Załaduj dodatkowy dziennik dla wpisów od przyjaciół</string>
@@ -422,6 +445,8 @@
<string name="settings_info_themes_title">Informacje na temat Map Themes</string>
<string name="settings_info_themes">c:geo wspiera motywy dla map offline. Mogą być używane by zmienić kolorystykę mapy (np. aby uzyskać tryb nocny) lub by zaznaczyć wybrane obiekty jak ścieżki rowerowe lub izolinie.</string>
<string name="init_mapsource_select">Wybierz źródło mapy</string>
+ <string name="settings_title_scale_map_text">Tekst skali mapy</string>
+ <string name="settings_summary_scale_map_text">Dostosowuj tekst skali mapy offline do dpi urządzenia</string>
<string name="init_map_directory_description">Katalog z mapami offline</string>
<string name="init_gpx_exportdir">Katalog do eksportu plików GPX</string>
<string name="init_gpx_importdir">Katalog do importu plików GPX</string>
@@ -454,6 +479,30 @@
<string name="init_use_native_ua">Identyfikuj jako przeglądarka Android. Rozwiązuje problemy z logowaniem w niektórych sieciach.</string>
<string name="init_summary_use_native_ua">Identyfikuj jako przeglądarka Android. Rozwiązuje problemy z logowaniem w niektórych sieciach.</string>
<string name="init_rendertheme_folder">Katalog z motywami map</string>
+ <string name="init_maintenance">Konserwacja</string>
+ <string name="init_maintenance_directories_note">c:geo przechowuje zdjęcia, zdjęcia do logów i inne pliki związane ze skrzynką w oddzielnym katalogu. W niektórych przypadkach (np. import/eksport bazy danych) ten katalog może zawierać nieaktualne pliki, które mogą być usunięte tutaj.</string>
+ <string name="init_maintenance_directories">Usuń nieaktualne pliki</string>
+ <string name="settings_open_website">Otwórz stronę</string>
+ <string name="settings_settings">Ustawienia</string>
+ <string name="settings_information">Informacje</string>
+ <string name="settings_twitter_cache_message">Wiadomość o znalezieniu skrzynki</string>
+ <string name="settings_twitter_trackable_message">Wiadomość o znalezieniu przedmiotu podróżnego</string>
+ <string name="init_ec_icons">Ikony mapy</string>
+ <string name="settings_ec_icons_other">Własny styl</string>
+ <string name="settings_ec_icons_oc">Jak na OC</string>
+ <string name="settings_features">Obsługiwane funkcje</string>
+ <string name="feature_description">Podane funkcje <b>online</b> na tej stronie są wspierane przez c:geo (w porównaniu do funkcji offline):</string>
+ <string name="feature_personal_notes">Notatka osobista</string>
+ <string name="feature_online_logging">Wpisy online</string>
+ <string name="feature_log_images">Załączanie zdjęć do logów</string>
+ <string name="feature_watch_list">Listy obserwowanych skrzynek</string>
+ <string name="feature_own_coordinates">Przechowywanie zmodyfikowanych współrzędnych</string>
+ <string name="feature_search_keyword">Szukanie po słowie kluczowym</string>
+ <string name="feature_search_live_map">Mapa skrzynek online</string>
+ <string name="feature_search_center">Szukanie po lokalizacji</string>
+ <string name="feature_search_geocode">Szukanie po numerze skrzynki</string>
+ <string name="feature_search_owner">Szukaj wg właściciela</string>
+ <string name="feature_search_finder">Szukaj wg znalazcy</string>
<string name="map_source_google_map">Google: Mapa</string>
<string name="map_source_google_satellite">Google: Satelita</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
@@ -473,6 +522,10 @@
<string name="auth_authorize">Autoryzacja c:geo</string>
<string name="auth_start">Rozpoczynam autoryzację</string>
<string name="auth_again">Rozpoczynam ponownie autoryzację</string>
+ <string name="auth_dialog_waiting">Czekanie na %s…</string>
+ <string name="auth_explain_short">Wybrany proces pozwoli na dostęp <b>c:geo</b> do %s.</string>
+ <string name="auth_explain_long">Naciśnięcie \"autoryzuj c:geo\" rozpocznie proces autoryzacji. Zostanie otwarte okno przeglądarki ze stroną %s. Zaloguj się na tej stronie i zezwól <b>c:geo</b> na dostęp do konta.</string>
+ <string name="auth_dialog_completed_twitter">c:geo jest teraz autoryzowane do zamieszczania postów na Twitterze.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo został zautoryzowany by komunikować się z %s.</string>
@@ -487,7 +540,7 @@
<string name="cache_offline_time_mins_few">przed kilkoma minutami</string>
<string name="cache_offline_time_hour">przed jedną godziną</string>
<string name="cache_offline_time_hours">przed godzinami</string>
- <string name="cache_offline_time_days">przed kilkoma dniami</string>
+ <string name="cache_offline_time_days">dni temu</string>
<string name="cache_premium">Premium</string>
<string name="cache_attributes">Atrybuty</string>
<string name="cache_inventory">Inwentarz</string>
@@ -496,6 +549,8 @@
<string name="cache_log_image_default_title">Zdjęcie</string>
<string name="cache_personal_note">Notatka osobista</string>
<string name="cache_personal_note_edit">Edytuj</string>
+ <string name="cache_personal_note_limit">Limit znaków notatki osobistej</string>
+ <string name="cache_personal_note_truncation">Osobista notatka będzie ucięta po przekroczeniu %d znaków na Geocaching.com.</string>
<string name="cache_personal_note_upload">Wyślij</string>
<string name="cache_personal_note_uploading">Wysyłam osobistą notatkę</string>
<string name="cache_personal_note_upload_done">Notatka osobista wysłana</string>
@@ -561,7 +616,7 @@
<string name="cache_menu_visit">Wpisz wizytę</string>
<string name="cache_menu_visit_offline">Wpisz wizytę offline</string>
<string name="cache_menu_spoilers">Zdjęcia spoiler</string>
- <string name="cache_menu_around">Skrzynki w okręgu</string>
+ <string name="cache_menu_around">Skrzynki w pobliżu</string>
<string name="cache_menu_event">Dodaj do kalendarza</string>
<string name="cache_menu_details">Szczegóły</string>
<string name="cache_menu_refresh">Odśwież</string>
@@ -572,6 +627,7 @@
<string name="cache_menu_oruxmaps">OruxMaps</string>
<string name="cache_menu_cachebeacon">Cache Beacon</string>
<string name="cache_menu_navigon">Navigon</string>
+ <string name="cache_menu_pebble">Zegarek Pebble</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Zapamiętany wpis</string>
<string name="cache_status_found">Znaleziona</string>
@@ -599,7 +655,6 @@
<string name="cache_coordinates">Współrzędne</string>
<string name="cache_coordinates_original">Oryginalne współrzędne</string>
<string name="cache_spoiler_images_title">Zdjęcia spoiler</string>
- <string name="cache_images_title">Zdjęcia</string>
<string name="cache_log_types">Rodzaj wpisu</string>
<string name="cache_coordinates_no">Ta skrzynka nie ma współrzędnych GPS.</string>
<string name="cache_clear_history">Usuń historię</string>
@@ -618,6 +673,7 @@
<string name="file_title_searching">Szukam</string>
<string name="simple_dir_chooser_title">Wybierz katalog</string>
<string name="simple_dir_chooser_current_path">Ścieżka:</string>
+ <string name="simple_dir_chooser_invalid_path">Nieprawidłowa ścieżka</string>
<string name="gpx_import_loading_caches">Ładuję skrzynki z pliku GPX</string>
<string name="gpx_import_loading_waypoints">Ładuję plik z punktami nawigacji</string>
<string name="gpx_import_store_static_maps">Zapisuję mapy statyczne</string>
@@ -635,6 +691,7 @@
<string name="gpx_import_delete_title">Usuń plik</string>
<string name="gpx_import_delete_message">Czy na pewno chcesz usunąć %s?</string>
<string name="gpx_import_select_list_title">Importuj GPX do listy</string>
+ <string name="gpx_import_android">Import z Androida</string>
<string name="map_file_select_title">Wybierz plik z mapą</string>
<string name="web_import_title">Import z internetu</string>
<string name="web_import_waiting">Czekam na nowe skrzynki z internetu…</string>
@@ -645,7 +702,7 @@
<string name="waypoint_cache_coordinates">Współrzędne skrzynki</string>
<string name="waypoint_custom">Zdefiniowane przez użytkownika</string>
<string name="waypoint_my_coordinates">Moje współrzędne</string>
- <string name="waypoint_bearing">Kierunek w °</string>
+ <string name="waypoint_bearing">Kierunek w stopniach</string>
<string name="waypoint_distance">Odległość</string>
<string name="waypoint_name">Nazwa</string>
<string name="waypoint_edit">Edytuj</string>
@@ -681,7 +738,7 @@
<string name="waypoint_coordinate_formats_plain">zwykłe</string>
<string name="visit_tweet">Wyślij informację do Twitter</string>
<string name="map_map">Mapa</string>
- <string name="map_live">Mapa Live</string>
+ <string name="map_live">Mapa online</string>
<string name="map_view_map">Widok mapy</string>
<string name="map_modes">Tryb mapy</string>
<string name="map_trail_show">Pokaż szlak</string>
@@ -692,20 +749,19 @@
<string name="map_mycaches_hide">Ukryj własne/znalezione skrzynki</string>
<string name="map_theme_builtin">Domyślny</string>
<string name="map_theme_select">Wybierz motyw mapy</string>
- <string name="map_live_enable">Włącz live</string>
- <string name="map_live_disable">Wyłącz live</string>
+ <string name="map_live_enable">Włącz online</string>
+ <string name="map_live_disable">Wyłącz online</string>
<string name="map_static_title">Mapa statyczna</string>
<string name="map_static_loading">Ładuję mapę statyczną…</string>
<string name="map_token_err">W związku z tym, że c:geo ma możliwość pobrania tylko częściowych danych, współrzędne GPS mogą być niedokładne.</string>
<string name="map_as_list">Pokaż w postaci listy</string>
<string name="map_strategy">Strategia</string>
- <string name="map_strategy_title">Strategia mapy Live</string>
+ <string name="map_strategy_title">Strategia mapy online</string>
<string name="map_strategy_fastest">Najszybsza</string>
<string name="map_strategy_fast">Szybka</string>
<string name="map_strategy_auto">Zależna od prędkości</string>
<string name="map_strategy_detailed">Szczegółowa</string>
<string name="live_map_notification">Na nowej mapie live, współrzędnie nie zawsze muszą być dokładne. Prawdopodobne niedokładne współrzędne są zaznaczane za pomocą pomarańczowych okręgów.\nOtworzenie współrzędnych skrzynki lub zapisanie skrzynki do użytku offline zawsze używa precyzyjnych współrzędnych.\n\nWięcej informacji na temat wszystkich zmian można odnaleźć na stronie \"O c:geo\" wewnątrz programu.</string>
- <string name="live_map_note_dontshow">Nie pokazuj ponownie</string>
<string name="search_bar_hint">Szukaj skrzynek</string>
<string name="search_bar_desc">Skrzynki (GC-kod, słowo kluczowe), przedmioty podróżne (TB-kod)</string>
<string name="search_coordinates">Współrzędne</string>
@@ -731,6 +787,9 @@
<string name="search_address_started">Wyszukiwanie miejsc</string>
<string name="search_address_result">Znalezione miejsca</string>
<string name="search_own_caches">Szukaj moich skrzynek</string>
+ <string name="search_pocket_title">Pocket Query</string>
+ <string name="search_pocket_loading">Wczytywanie listy Pocket Queries</string>
+ <string name="search_pocket_select">Wybierz Pocket Queries</string>
<string name="trackable">Przedmiot podróżny</string>
<string name="trackable_details_loading">Ładuje szczegóły przedmiotu podróżnego…</string>
<string name="trackable_log_touch">Wpisz odkrycie</string>
@@ -763,6 +822,7 @@
<string name="user_menu_view_found">Znalezione skrzynki</string>
<string name="user_menu_open_browser">Otwórz profil w przeglądarce</string>
<string name="user_menu_send_message">Wyślij wiadomość</string>
+ <string name="user_menu_open_contact">Otwórz wizytówkę kontaktu</string>
<string name="navigation">Nawigacja</string>
<string name="compass_title">Kompas</string>
<string name="use_gps">Użyj tylko GPS</string>
@@ -771,12 +831,17 @@
<string name="destination_set">Ustaw cel</string>
<string name="navigation_direct_navigation">Bezpośrednia nawigacja</string>
<string name="navigation_target">Cel</string>
+ <string name="err_nav_no_coordinates">Nie można rozpocząć nawigacji - brak współrzędnych</string>
<string name="license">Licencja</string>
<string name="license_show">Pokaż licencję</string>
<string name="license_dismiss">Odmów</string>
<string name="helper_calendar_title">Dodatek Kalendarz c:geo</string>
<string name="helper_calendar_missing">Dodatek Kalendarz c:geo nie jest zainstalowany.</string>
<string name="helper_calendar_description">Umożliwia Tobie eksport skrzynek Wydarzenie do kalendarza w Twoim urządzeniu.</string>
+ <string name="helper_sendtocgeo_title">Wyślij do c:geo</string>
+ <string name="helper_contacts_title">c:geo - dodatek Kontakty</string>
+ <string name="helper_contacts_description">Umożliwia Tobie otwarcie kontaktu (z Twojej książki adresowej) bezpośrednio z wpisu do dziennika, więc możesz łatwiej poprosić przyjaciół o pomoc.</string>
+ <string name="helper_sendtocgeo_description">Wyślij do c:geo jest rozszerzeniem do przeglądarki <strong>na komputer</strong>. Podczas przeglądania Geocaching.com pozwala na wysłanie skrzynek bezpośrednio do telefonu, za pomocą jednego przycisku w przeglądarce.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Bardzo dobra aplikacja do oglądania map online, która pozwala na pobieranie ich bezpośrednio do trybu offline (tylko mapy rastrowe). Pozwala także na zapisywanie ścieżek, obsługę POI oraz ma wiele innych przydatnych funkcji.</string>
<string name="helper_gpsstatus_title">GPS Status</string>
@@ -787,6 +852,8 @@
<string name="helper_barcode_description">Istnieją skrypty i strony WWW, które umożliwiają wyświetlanie GC-kodu jako kodu kreskowego. Z tym programem c:geo może czytać te GC-kody bezpośrednio z ekranu Twojego komputera.</string>
<string name="helper_pocketquery_title">Kreator Pocket Query</string>
<string name="helper_pocketquery_description">Pozwala na łatwe tworzenie i pobieranie Pocket Queries wyśrodkowanych w Twoim aktualnym położeniu lub wybranym punkcie mapy. Wymaga konta Premium w Geocaching.com.</string>
+ <string name="helper_google_translate_title">Tłumacz Google</string>
+ <string name="helper_google_translate_description">Jeśli pobierzesz paczki tłumaczeń w aplikacji Google Tłumacz, będziesz mógł łatwo tłumaczyć opisy skrzynek przytrzymując na nich palcem chwilę dłużej (bez połączenia z internetem).</string>
<string name="addon_missing_title">Brakujący dodatek</string>
<string name="addon_download_prompt">Pobierz teraz z Google Play.</string>
<string name="export">Eksport</string>
@@ -994,6 +1061,38 @@
<string name="attribute_unknown_no">Nie ma żadnego nieznanego atrybutu</string>
<string name="attribute_geotour_yes">Część GeoTour</string>
<string name="attribute_geotour_no">Nie jest częścią GeoTour</string>
+ <string name="attribute_kids_2_yes">Można zabrać dzieci</string>
+ <string name="attribute_kids_2_no">Nie zabieraj dzieci</string>
+ <string name="attribute_historic_site_yes">Miejsce historyczne</string>
+ <string name="attribute_historic_site_no">To nie jest miejsce historyczne</string>
+ <string name="attribute_magnetic_yes">Skrzynka magnetyczna</string>
+ <string name="attribute_magnetic_no">To nie jest skrzynka magnetyczna</string>
+ <string name="attribute_usb_cache_yes">Skrzynka Dead Drop</string>
+ <string name="attribute_usb_cache_no">To nie jest skrzynka Dead Drop</string>
+ <string name="attribute_shovel_yes">Zakopana</string>
+ <string name="attribute_shovel_no">Nie potrzebna łopatka</string>
+ <string name="attribute_specific_access_yes">Dostępna o określonych godzinach (może wymagać opłaty)</string>
+ <string name="attribute_specific_access_no">Dostępna zawsze</string>
+ <string name="attribute_pedestrian_only_yes">Dostępna tylko pieszo</string>
+ <string name="attribute_pedestrian_only_no">Dostępna różnymi środkami lokomocji</string>
+ <string name="attribute_nature_cache_yes">Umiejscowiona na łonie natury (góry, lasy, rzeki itp.)</string>
+ <string name="attribute_nature_cache_no">Nie jest ukryta na łonie natury</string>
+ <string name="attribute_byop_yes">Weź coś do pisania</string>
+ <string name="attribute_byop_no">Własny długopis niewymagany</string>
+ <string name="attribute_safari_cache_yes">Skrzynka bez lokalizacji</string>
+ <string name="attribute_safari_cache_no">To nie jest skrzynka bez lokalizacji</string>
+ <string name="attribute_quick_cache_yes">Szybka skrzynka</string>
+ <string name="attribute_quick_cache_no">Zajmuje więcej czasu</string>
+ <string name="attribute_wherigo_yes">Skrzynka Wherigo</string>
+ <string name="attribute_wherigo_no">Nie jest skrzynką Wherigo</string>
+ <string name="attribute_audio_cache_yes">Opis skrzynki zawiera plik audio</string>
+ <string name="attribute_audio_cache_no">Opis skrzynki nie zawiera pliku audio</string>
+ <string name="attribute_geohotel_yes">Hotel Geokretów</string>
+ <string name="attribute_geohotel_no">Nie jest hotelem Geokretów</string>
+ <string name="attribute_survey_marker_yes">W pobliżu punkt geodezyjny</string>
+ <string name="attribute_survey_marker_no">W pobliżu nie ma punktu geodezyjnego</string>
+ <string name="attribute_offset_cache_yes">Skrzynka Offset</string>
+ <string name="attribute_offset_cache_no">Nie jest to skrzynka Offset</string>
<string name="quote">Aby uczynić geocaching prostszym, a użytkowników bardziej leniwymi.</string>
<string name="powered_by">carnero</string>
<string name="support">Support: <a href="">support@cgeo.org</a></string>
@@ -1021,6 +1120,9 @@
<string name="tts_one_oclock">pierwsza</string>
<string name="tts_oclock">%s</string>
<string name="clipboard_copy_ok">Skopiowano do schowka</string>
+ <string name="percent_favorite_points">%\ ulubionych</string>
+ <string name="cgeo_shortcut">skrót do c:geo</string>
+ <string name="create_shortcut">Utwórz skrót</string>
<string-array name="log_image_scales">
<item>Brak skalowania</item>
<item>512 px</item>
@@ -1068,4 +1170,9 @@
<item quantity="few">%d dni temu</item>
<item quantity="other">%d dni temu</item>
</plurals>
+ <plurals name="favorite_points">
+ <item quantity="one">%s ulubiony</item>
+ <item quantity="few">%s ulubione</item>
+ <item quantity="other">%s ulubionych</item>
+ </plurals>
</resources>
diff --git a/main/res/values-pt/strings.xml b/main/res/values-pt/strings.xml
index 5cb824c..f06482e 100644
--- a/main/res/values-pt/strings.xml
+++ b/main/res/values-pt/strings.xml
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">Virtual</string>
<string name="cache_size_notchosen">Não especificado</string>
<string name="cache_size_unknown">Desconhecido</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Muito grande</string>
<string name="wp_final">Localização final</string>
<string name="wp_stage">Estado da multi-cache</string>
<string name="wp_puzzle">Pergunta para a resposta</string>
@@ -121,11 +123,10 @@
<string name="translate_to_english">Traduzir para inglês</string>
<string name="translate_length_warning">A tradução pode falhar se o texto fôr muito grande.</string>
<string name="err_none">Ok</string>
- <string name="err_start">Comunicação não iniciada</string>
<string name="err_parse">Falha na análise da página de login</string>
<string name="err_server">Falha na ligação a Geocaching.com (servidor ou ligação em baixo?)</string>
+ <string name="err_server_ec">Não é possível entrar em contato com Extremcaching.com. O site pode estar em baixo ou sua conexão de internet não está a funcionar.</string>
<string name="err_login">Informação de login não gravada</string>
- <string name="err_login_failed">O c:geo não consegue fazer login.</string>
<string name="err_login_failed_toast">O c:geo não consegue fazer login. O c:geo funciona offline com as caches Arquivadas. Verifique as definições de login ou habilite a ligação de dados.</string>
<string name="err_unknown">Erro desconhecido</string>
<string name="err_comm">Erro de comunicação desconhecido</string>
@@ -177,8 +178,8 @@
<string name="err_log_load_data">O c:geo não consegue carregar os dados necessários para registar a sua visita.</string>
<string name="err_log_load_data_again">O c:geo não consegue carregar os dados necessários para registar a sua visita. A tentar de novo.</string>
<string name="err_log_load_data_still">O c:geo ainda está a carregar dados necessários para publicar o registo. Por favor espere mais um pouco.</string>
- <string name="err_log_failed_server">O c:geo falhou a publicação do registo porque o servidor não responde.</string>
<string name="err_log_post_failed">O c:geo falhou a publicação do registo.</string>
+ <string name="err_log_post_failed_ec">Parece que o seu log não foi publicado. Por favor verifique-o em Extremcaching.com.</string>
<string name="err_logimage_post_failed">Parece que a sua imagem de registo não foi enviada. Por favor verifique em Geocaching.com.</string>
<string name="err_search_address_forgot">O c:geo esqueceu o endereço que procura.</string>
<string name="err_parse_lat">O c:geo não consegue analisar a latitue.</string>
@@ -202,6 +203,8 @@
<string name="warn_deprecated_mapfile">Está a utilizar um ficheiro de mapa de uma versão obsoleta.\nConsidere mudar o mapa para a versão 0.3.0.\nNa próxima versão vamos deixar de suportar a 0.2.4.</string>
<string name="warn_nonexistant_mapfile">O ficheiro de mapa selecionado não existe.\nMapas offline não estão disponíveis.</string>
<string name="warn_rendertheme_missing">Tema de mapa não encontrado.</string>
+ <string name="warn_pocket_query_select">Nenhuma pocket query selecionada.</string>
+ <string name="warn_no_pocket_query_found">Nenhuma pocket query encontrada on-line.</string>
<string name="info_log_posted">O c:geo publicou o registo com sucesso.</string>
<string name="info_log_saved">O c:geo gravou o registo com sucesso.</string>
<string name="info_log_cleared">O registo foi limpo.</string>
@@ -222,6 +225,7 @@
<string name="menu_history">Histórico</string>
<string name="menu_filter">Filtro</string>
<string name="menu_scan_geo">Scan geocode</string>
+ <string name="menu_pocket_queries">Pocket queries</string>
<string name="live_map_button">Ao vivo</string>
<string name="caches_nearby_button">Por perto</string>
<string name="advanced_search_button">Pesquisar</string>
@@ -606,7 +610,6 @@
<string name="cache_coordinates">Coordenadas</string>
<string name="cache_coordinates_original">Coordenadas originais</string>
<string name="cache_spoiler_images_title">Imagens spoiler</string>
- <string name="cache_images_title">Imagens</string>
<string name="cache_log_types">Tipos de log</string>
<string name="cache_coordinates_no">Esta cache não tem coordenadas.</string>
<string name="cache_clear_history">Apagar histórico</string>
@@ -712,7 +715,6 @@
<string name="map_strategy_auto">Dependente da velocidade</string>
<string name="map_strategy_detailed">Detalhado</string>
<string name="live_map_notification">No novo mapa ao vivo as coordenadas podem nem sempre ser precisas. As coordenadas possivelmente imprecisas são marcadas com um círculo cor de laranja.\nAbrindo os detalhes da cache or gravando a cache para utilização offline fará com que obtenha as coordenadas precisas.\n\nMais informações em todas as alterações podem ser encontradas na página \"Sobre c:geo\" na aplicação.</string>
- <string name="live_map_note_dontshow">Não mostrar novamente</string>
<string name="search_bar_hint">Procurar caches</string>
<string name="search_bar_desc">Caches (código-GC, palavra-chave), Trackables (código-TB)</string>
<string name="search_coordinates">Coordenadas</string>
@@ -785,6 +787,7 @@
<string name="helper_calendar_title">Add on calendário para c:geo </string>
<string name="helper_calendar_missing">Add on calendário para o c:geo não está instalado.</string>
<string name="helper_calendar_description">Permite exportar caches evento para o calendário do seu dispositivo.</string>
+ <string name="helper_contacts_title">c:geo - plugin contactos</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Aplicação simples e útil, que mostra mapas online e permite transferi-los directamente para o modo offline (apenas mapas raster). Também suporta a gravação de caminhos, gestão de PDI e muitas outras funções úteis.</string>
<string name="helper_gpsstatus_title">Estado do GPS</string>
diff --git a/main/res/values-sk/strings.xml b/main/res/values-sk/strings.xml
index 615a630..ac7446d 100644
--- a/main/res/values-sk/strings.xml
+++ b/main/res/values-sk/strings.xml
@@ -105,11 +105,9 @@
<string name="translate_to_english">Preložiť do angličtiny</string>
<string name="translate_length_warning">Pre veľké texty môže preklad zlyhať.</string>
<string name="err_none">Ok</string>
- <string name="err_start">Komunikácia nezačala.</string>
<string name="err_parse">Zlyhalo čítanie prihlasovacej stránky.</string>
<string name="err_server">Zlyhalo pripojenie k serveru Geocaching.com (pripojenie, alebo server nefunkčný?)</string>
<string name="err_login">Nie sú uložené žiadne prihlasovacie údaje.</string>
- <string name="err_login_failed">prepáčte, ale c:geo sa nemôže prihlásiť.</string>
<string name="err_login_failed_toast">Prepáčte, c:geo sa nepodarilo prihlásiť. c:geo funguje v offline režime. Skontrolujte vaše prihlasovacie údaje v nastaveniach, alebo povoľte pripojenie k Internetu.</string>
<string name="err_unknown">Neznáma chyba</string>
<string name="err_comm">Neznáma chyba pri komunikácii</string>
@@ -157,7 +155,6 @@
<string name="err_log_load_data">c:geo nemôže načítať dáta potrebné pre zalogovanie návštevy.</string>
<string name="err_log_load_data_again">c:geo nemôže načítať dáta potrebné pre zalogovanie návštevy. Skúša to znovu.</string>
<string name="err_log_load_data_still">c:geo stále načítava dáta potrebné pre zalogovanie návštevy. Prosím, počkajte chvíľu.</string>
- <string name="err_log_failed_server">c:geo nemohlo odoslať log, pretože server neodpovedá.</string>
<string name="err_log_post_failed">c:geo nemohlo odoslať log.</string>
<string name="err_search_address_forgot">c:geo zabudlo adresu, ktorú sa pokúšate nájsť.</string>
<string name="err_parse_lat">c:geo nemôže dopočítať šírku.</string>
@@ -504,7 +501,6 @@
<string name="cache_coordinates">Súradnice</string>
<string name="cache_coordinates_original">Pôvodné súradnice</string>
<string name="cache_spoiler_images_title">Spoilerové obrázky</string>
- <string name="cache_images_title">Obrázky</string>
<string name="cache_log_types">Typy záznamov</string>
<string name="cache_coordinates_no">Táto skrýša nemá žiadne súradnice.</string>
<string name="cache_clear_history">Vymazať históriu</string>
@@ -591,7 +587,6 @@
<string name="map_strategy_auto">Podľa rýchlosti</string>
<string name="map_strategy_detailed">Podrobná</string>
<string name="live_map_notification">Na novej aktívnej mape nemusia byť súradnice vždy presné. Súradnice, ktoré môžu byť nepresné, sú označené oranžovým krúžkom.\nPo otvorení detailu skrýše, alebo po jej uložení pre použitie offline, sú získané vždy presné súradnice.\n\nViac informácií ku všetkým zmenám sa nachádzajú na stránke „O c:geo“ v aplikácii.</string>
- <string name="live_map_note_dontshow">Nabudúce nezobrazovať</string>
<string name="search_bar_hint">Hľadanie skrýš</string>
<string name="search_bar_desc">Skrýše (GC kód, kľúčové slovo), trasovateľné predmety (TB-kód)</string>
<string name="search_coordinates">Súradnice</string>
@@ -679,8 +674,8 @@
<string name="export_gpx">GPX</string>
<string name="export_gpx_info">Súbor GPX bude exportovaný do %1$s s názvom súboru podľa aktuálneho dátumu a času.</string>
<string name="export_gpx_to">Odoslať exportovaný GPS do</string>
- <string name="attribute_dogs_yes">Psy povolené</string>
- <string name="attribute_dogs_no">Psy nepovolené</string>
+ <string name="attribute_dogs_yes">Psi povolené</string>
+ <string name="attribute_dogs_no">Psi nepovolené</string>
<string name="attribute_bicycles_yes">Bicykle povolené</string>
<string name="attribute_bicycles_no">Bicykle nepovolené</string>
<string name="attribute_motorcycles_yes">Motorky povolené</string>
diff --git a/main/res/values-sl/strings.xml b/main/res/values-sl/strings.xml
index 86e7ce7..e1c6784 100644
--- a/main/res/values-sl/strings.xml
+++ b/main/res/values-sl/strings.xml
@@ -121,11 +121,9 @@
<string name="translate_to_english">Prevedi v: angleščino</string>
<string name="translate_length_warning">Prevod lahko spodleti zaradi velike količine besedila.</string>
<string name="err_none">OK</string>
- <string name="err_start">Komunikacija se ni začela</string>
<string name="err_parse">Razčlenjevanje prijavne strani ni uspelo</string>
<string name="err_server">Ni bilo mogoče vzpostaviti povezave z Geocaching.com. Spletna stran ali vaša povezava z internetom je lahko nedosegljiva.</string>
<string name="err_login">Prijavni podatki niso shranjeni</string>
- <string name="err_login_failed">c:geo se ne more prijaviti.</string>
<string name="err_login_failed_toast">c:geo se ne more prijaviti. c:geo lahko deluje v načinu brez povezave s shranjenimi zakladi. Preverite vaše prijavne podatke in internetno povezavo.</string>
<string name="err_unknown">Neznana napaka</string>
<string name="err_comm">Neznana napaka v komunikaciji</string>
@@ -177,7 +175,6 @@
<string name="err_log_load_data">c:geo ni mogel naložiti podatkov za zapis obiska.</string>
<string name="err_log_load_data_again">c:geo ne more naložiti podatkov za zapis obiska. Ponovni poskus…</string>
<string name="err_log_load_data_still">c:geo še vedno nalaga podatke za zapis obiska. Prosimo počakajte še trenutek.</string>
- <string name="err_log_failed_server">c:geo ni mogel objaviti zapisa, ker se strežnik ne odziva.</string>
<string name="err_log_post_failed">Izgleda, kot da zapis ni bil objavljen. Preverite na Geocaching.com.</string>
<string name="err_logimage_post_failed">Izgleda, kot da slika ni bila naložena. Preverite na Geocaching.com.</string>
<string name="err_search_address_forgot">c:geo je pozabil naslov, ki ste ga hoteli najti.</string>
@@ -341,6 +338,8 @@
<string name="settings_gc_legal_note">Za uporabo storitev Geocaching.com se morate strinjati s pogoji uporabe podjetja Groundspeak.</string>
<string name="settings_info_facebook_login_title">Prijava s Facebookom</string>
<string name="settings_info_facebook_login">V c:geo se ne morete prijaviti s Facebook računom, obstaja pa druga enostavna rešitev…</string>
+ <string name="settings_authorize">Poveži c:geo</string>
+ <string name="settings_reauthorize">Ponovno poveži c:geo</string>
<string name="init_oc">Opencaching.de</string>
<string name="settings_activate_oc">Aktiviraj</string>
<string name="init_oc_de_description">Poveži c:geo z opencaching.de za iskanje zakladov in dostop in filter najdenih zakladov.</string>
@@ -418,9 +417,12 @@
<string name="init_backup_last">Varnostna kopija je na voljo iz</string>
<string name="init_backup_last_no">Varnostna kopija ne obstaja.</string>
<string name="settings_info_offline_maps_title">Zemljevidi brez povezave</string>
+ <string name="settings_info_offline_maps">c:geo podpira uporabo zemljevidov brez povezave. Zemljevide lahko prenesete iz Mapsforge-ove strani ali si jih naredite sami iz OSM podatkov. Če želite uporabljati zemljevide brez povezave morate najprej izbrati imenik, kjer se zemljevidi nahajajo.</string>
<string name="settings_info_themes_title">Teme zemljevidov</string>
<string name="settings_info_themes">c:geo omogoča prikaz različnih tem zemljevidov brez povezave. Teme so uporabljene za spremembo barvnih shem (npr. temni nočni zemljevid) ali za poudarek objektov, kot na primer kolesarske poti ali plastnice na zemljevidu.</string>
<string name="init_mapsource_select">Izberi vir zemljevidov</string>
+ <string name="settings_title_scale_map_text">Prilagodi velikost pisave na zemljevidu</string>
+ <string name="settings_summary_scale_map_text">Prilagodi velikost pisave na zemljevidu glede na ločljivost zaslona vaše naprave</string>
<string name="init_map_directory_description">Mapa z zemljevidi</string>
<string name="init_gpx_exportdir">Mapa za izvoz GPX datotek</string>
<string name="init_gpx_importdir">Mapa za uvoz GPX datotek</string>
@@ -453,6 +455,9 @@
<string name="init_use_native_ua">Android brskalnik</string>
<string name="init_summary_use_native_ua">c:geo naj se strežniku predstavi kot Android brskalnik. Ta možnost reši problem prijave pri nekaterih ponudnikih omrežja.</string>
<string name="init_rendertheme_folder">Mapa s temami zemljevidov</string>
+ <string name="settings_open_website">Odpri spletno stran</string>
+ <string name="settings_settings">Nastavitve</string>
+ <string name="settings_information">Informacije</string>
<string name="map_source_google_map">Google: Cestni zemljevid</string>
<string name="map_source_google_satellite">Google: Satelitska slika</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
@@ -472,6 +477,10 @@
<string name="auth_authorize">Poveži c:geo s Twitterjem</string>
<string name="auth_start">Začni z avtorizacijo</string>
<string name="auth_again">Ponovno začni</string>
+ <string name="auth_dialog_waiting">Čakam na %s…</string>
+ <string name="auth_explain_short">Naslednji postopek bo omogočil <b>c:geo</b>tu dostop do %s.</string>
+ <string name="auth_explain_long">S pritiskom na gumb \"poveži c:geo\" se bo začel postopek. Postopek bo najprej odprl spletno stran %s. Prijavite se na to spletno stran in dovolite <b>c:geo</b>tu dostop do vašega računa. To je vse.</string>
+ <string name="auth_dialog_completed_twitter">c:geo je sedaj povezan s Twitterjem za objavo sporočil.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_ocpl">opencaching.pl</string>
<string name="auth_dialog_completed_oc">c:geo je sedaj povezan z %s.</string>
@@ -598,7 +607,6 @@
<string name="cache_coordinates">Koordinate</string>
<string name="cache_coordinates_original">Originalne koordiante</string>
<string name="cache_spoiler_images_title">Spoiler slike</string>
- <string name="cache_images_title">Slike</string>
<string name="cache_log_types">Tipi zapisov</string>
<string name="cache_coordinates_no">Zaklad nima koordinat.</string>
<string name="cache_clear_history">Počisti zgodovino</string>
@@ -704,7 +712,6 @@
<string name="map_strategy_auto">Odvisna od moje hitrosti</string>
<string name="map_strategy_detailed">Podrobna</string>
<string name="live_map_notification">Na zemljevidu s podatki v živo koordinate niso nujno točne. Nenatančne koordinate so označene z oranžnim krogom.\nČe odprete podrobnosti zaklada se bodo vedno naložile natančne koordinate\n\nVeč informacij o teh spremembah lahko dobite na strani \"O c:geo\" v aplikaciji.</string>
- <string name="live_map_note_dontshow">Ne pokaži tega ponovno</string>
<string name="search_bar_hint">Iskanje zakladov</string>
<string name="search_bar_desc">Zakladi (geo koda, ključne besede), Sledljivčki (TB koda)</string>
<string name="search_coordinates">Koordinate</string>
@@ -770,6 +777,7 @@
<string name="destination_set">Nastavi destinacijo</string>
<string name="navigation_direct_navigation">Direktna navigacija</string>
<string name="navigation_target">Cilj</string>
+ <string name="err_nav_no_coordinates">Ne morem začeti navigacije brez koordinat</string>
<string name="license">Licenca</string>
<string name="license_show">Pokaži licenco</string>
<string name="license_dismiss">Zapri</string>
diff --git a/main/res/values-sv/strings.xml b/main/res/values-sv/strings.xml
index 463730e..37f853e 100644
--- a/main/res/values-sv/strings.xml
+++ b/main/res/values-sv/strings.xml
@@ -5,12 +5,12 @@
<string name="cache">Cache</string>
<string name="detail">Detaljer</string>
<string name="search">Sök</string>
- <string name="helpers">Bra program att installera</string>
+ <string name="helpers">Användbara appar</string>
<string name="about">Om c:geo</string>
<string name="latitude">Latitud</string>
<string name="longitude">Longitud</string>
<string name="action_bar_share_title">Skicka cachens länk via</string>
- <string name="settings_titlebar">c:geo Inställningar</string>
+ <string name="settings_titlebar">Inställningar för c:geo</string>
<string name="all_types">Alla typer av cacher</string>
<string name="traditional">Traditionell cache</string>
<string name="multi">Multi-cache</string>
@@ -37,6 +37,8 @@
<string name="cache_size_virtual">virtual</string>
<string name="cache_size_notchosen">not chosen</string>
<string name="cache_size_unknown">Okänd</string>
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Extra large</string>
<string name="wp_final">Slutlig plats</string>
<string name="wp_stage">Delsteg för multi-cache</string>
<string name="wp_puzzle">Fråga att besvara</string>
@@ -117,15 +119,15 @@
<string name="log_image_scale">Skalning</string>
<string name="log_password_title">Logglösenord:</string>
<string name="log_hint_log_password">Ange ditt lösenord för loggning</string>
+ <string name="log_oc_team_comment">Meddelande från OC Team</string>
<string name="translate_to_sys_lang">Översätt till %s</string>
<string name="translate_to_english">Översätt till engelska</string>
<string name="translate_length_warning">Översättningen kan misslyckas med långa texter.</string>
<string name="err_none">Ok</string>
- <string name="err_start">Kommunikationen har inte påbörjats</string>
<string name="err_parse">Misslyckades att analysera inloggningssidan</string>
<string name="err_server">Misslyckades att ansluta till Geocaching.com. Hemsidan kan vara ur funktion eller så är det problem med din anslutning till Internet.</string>
+ <string name="err_server_ec">Det gick inte att kontakta Extremcaching.com. Webbplatsen kan ha problem eller så fungerar inte din internet-anslutning.</string>
<string name="err_login">Inloggningsinformationen ej sparad</string>
- <string name="err_login_failed">Tyvärr kan c:geo inte logga in.</string>
<string name="err_login_failed_toast">Tyvärr kan c:geo inte logga in. c:geo kommer att köra i offline läge med sparade cacher. Kontrollera dina inloggningsuppgifter och aktivera din internetanslutning.</string>
<string name="err_unknown">Okänt fel</string>
<string name="err_comm">Okänt kommunikationsfel</string>
@@ -177,8 +179,8 @@
<string name="err_log_load_data">Tyvärr kan c:geo inte ladda information som krävs för att logga ditt besök.</string>
<string name="err_log_load_data_again">Tyvärr kan c:geo inte ladda information som krävs för att logga ditt besök. Försöker igen.</string>
<string name="err_log_load_data_still">c:geo laddar fortfarande data för att kunna posta loggen. Vänligen vänta en stund till.</string>
- <string name="err_log_failed_server">Tyvärr misslyckades c:geo att posta loggen eftersom servern inte svarade.</string>
<string name="err_log_post_failed">Tyvärr misslyckades c:geo att posta loggen.</string>
+ <string name="err_log_post_failed_ec">Det verkar som att din logg inte kunde laddas upp. Kontrollera loggen på Extremcaching.com.</string>
<string name="err_logimage_post_failed">Det verkar som om din bild till loggen inte kunde laddas upp. Vänligen kontrollera den på Geocaching.com.</string>
<string name="err_search_address_forgot">Tyvärr glömde c:geo adressen du sökte efter.</string>
<string name="err_parse_lat">Tyvärr kan c:geo inte tolka latitud.</string>
@@ -202,6 +204,8 @@
<string name="warn_deprecated_mapfile">Den kartfil du använder är av en gammal version (0.2.4).\nVi rekommenderar att byta till en kartfil med version 0.3.0.\nNästa version av c:geo kommer inte hantera version 0.2.4.</string>
<string name="warn_nonexistant_mapfile">Den angivna kartfilen finns inte.\nOffline-kartor kommer inte att vara tillgängliga.</string>
<string name="warn_rendertheme_missing">Karttema kunde inte hittas.</string>
+ <string name="warn_pocket_query_select">Ingen Pocket query vald.</string>
+ <string name="warn_no_pocket_query_found">Ingen Pocket query hittades på nätet.</string>
<string name="info_log_posted">c:geo har postat din logg.</string>
<string name="info_log_saved">c:geo har sparat din logg.</string>
<string name="info_log_cleared">Loggen har rensats.</string>
@@ -222,6 +226,8 @@
<string name="menu_history">Hittade cacher</string>
<string name="menu_filter">Filter</string>
<string name="menu_scan_geo">Scanna geokod</string>
+ <string name="menu_pocket_queries">Pocket queries</string>
+ <string name="menu_scan_description">c:geo kan skanna geocoder som skrivits som QR-koder. Den nödvändiga appen är inte installerad. Vill du öppna Google Play för att installera den?</string>
<string name="live_map_button">Live karta</string>
<string name="caches_nearby_button">Nära</string>
<string name="advanced_search_button">Sök</string>
@@ -289,6 +295,9 @@
<string name="caches_filter_modified">Med tillagda koordinater</string>
<string name="caches_filter_origin">Ursprung</string>
<string name="caches_filter_distance">Avstånd</string>
+ <string name="caches_filter_personal_note">Med personlig anteckning</string>
+ <string name="caches_filter_popularity">Favoriter</string>
+ <string name="caches_filter_popularity_ratio">Favoriter [%]</string>
<string name="caches_removing_from_history">Tar bort från historik…</string>
<string name="caches_clear_offlinelogs">Rensa offline loggar</string>
<string name="caches_clear_offlinelogs_progress">Rensar offline loggar</string>
@@ -311,6 +320,7 @@
<string name="list_dialog_remove_err">c:geo misslyckades med att ta bort listan</string>
<string name="list_dialog_rename_title">Byt namn på listan</string>
<string name="list_dialog_rename">Byt namn</string>
+ <string name="list_not_available">Listan är inte längre tillgänglig, byter till standardlistan</string>
<string name="about_version">Version</string>
<string name="about_changelog">Historik</string>
<string name="about_donate">Stöd c:geo</string>
@@ -327,6 +337,7 @@
<string name="settings_title_map">Karta</string>
<string name="settings_title_map_data">Kartdata</string>
<string name="settings_title_map_content">Kartinnehåll</string>
+ <string name="settings_title_basicmembers">Inställningar för Basic Members</string>
<string name="settings_title_navigation">Navigering</string>
<string name="settings_title_system">System</string>
<string name="settings_title_navigation_menu">Navigeringsmeny</string>
@@ -334,10 +345,16 @@
<string name="settings_category_social">Sociala media</string>
<string name="settings_category_logging_other">Andra loggningsinställningar</string>
<string name="settings_goto_url_button">mer …</string>
+ <string name="settings_title_ec">Extremcaching.com</string>
+ <string name="settings_title_ox">Opencaching.com (Garmin)</string>
<string name="settings_activate_gc">Aktivera</string>
+ <string name="settings_activate_ec">Aktivera</string>
+ <string name="settings_activate_ox">Aktivera</string>
<string name="settings_gc_legal_note">Genom att använda tjänster hos geocaching.com godkänner du Groundspeaks användarvillkor.</string>
<string name="settings_info_facebook_login_title">Facebook inloggning</string>
<string name="settings_info_facebook_login">c:geo kan inte logga inte logga in på geocaching.com med ditt Facebook konto. Men det finns en enkel lösning …</string>
+ <string name="settings_authorize">Tillåt c:geo</string>
+ <string name="settings_reauthorize">Tillåt c:geo igen</string>
<string name="init_oc">Opencaching.de</string>
<string name="settings_activate_oc">Aktivera</string>
<string name="init_oc_de_description">Använd c:geo med opencaching.de för att söka efter cacher samt för att filtrera dina funna cacher.</string>
@@ -355,14 +372,20 @@
<string name="init_login_popup_failed">Inloggning misslyckades</string>
<string name="init_login_popup_failed_reason">Inloggning misslyckades:</string>
<string name="init_login_popup_not_authorized">Ej godkänd</string>
+ <string name="init_login_popup_invalid_timestamp">Lokal tid ogiltig, justera enhetens tid</string>
+ <string name="init_login_popup_invalid_token">Tillstånd misslyckades, försök igen</string>
<string name="init_signature">Signatur</string>
+ <string name="init_template_help">Markörer som [NAME] kommer att utvidgas senare när mallen används.</string>
<string name="init_signature_template_button">Infoga makro</string>
<string name="init_signature_template_date">Datum</string>
<string name="init_signature_template_time">Tid</string>
<string name="init_signature_template_datetime">Datum &amp; Tid</string>
- <string name="init_signature_template_user">Namn</string>
+ <string name="init_signature_template_user">Ditt namn</string>
<string name="init_signature_template_number">Nummer</string>
<string name="init_signature_template_owner">Ägare</string>
+ <string name="init_signature_template_name">Namn</string>
+ <string name="init_signature_template_url">URL</string>
+ <string name="init_signature_template_log">Loggtext</string>
<string name="init_ratingwanted">GCvote.com</string>
<string name="init_summary_ratingwanted">Ladda cache betyg från GCvote.com</string>
<string name="init_friendlogswanted">Vänners loggar</string>
@@ -418,6 +441,8 @@
<string name="settings_info_themes_title">Info om kartteman</string>
<string name="settings_info_themes">c:geo har stöd för anpassade teman för offline-kartor. Dessa kan användas för färgerna på kartan (t.ex. för nattläge) eller för att tydliggöra vissa objekt såsom cykelvägar eller höjdkurvor.</string>
<string name="init_mapsource_select">Välj kartkälla</string>
+ <string name="settings_title_scale_map_text">Skala karttext</string>
+ <string name="settings_summary_scale_map_text">Skala textetiketter på offlinekartor mot enhetens upplösning</string>
<string name="init_map_directory_description">Katalog med offline-kartor</string>
<string name="init_gpx_exportdir">GPX-exportkatalog</string>
<string name="init_gpx_importdir">GPX-importkatalog</string>
@@ -450,9 +475,30 @@
<string name="init_use_native_ua">Identifiering</string>
<string name="init_summary_use_native_ua">Identifiera som en Android webbläsare. Löser problem med inloggning vid uppkoppling via vissa operatörer.</string>
<string name="init_rendertheme_folder">Katalog för kartteman</string>
+ <string name="init_maintenance">Underhåll</string>
+ <string name="init_maintenance_directories_note">c:geo lagrar bilder, loggbilder och andra filer relaterade till en cache i en separat katalog. I vissa fall (som vid importering/exportering av databasen) kan denna katalog innehålla inaktuella filer, som kan tas bort här.</string>
+ <string name="init_maintenance_directories">Ta bort överblivna filer</string>
<string name="settings_open_website">Öppna hemsida</string>
<string name="settings_settings">Inställningar</string>
<string name="settings_information">Information</string>
+ <string name="settings_twitter_cache_message">Meddelande för hittad cache</string>
+ <string name="settings_twitter_trackable_message">Meddelande för hittad trackable</string>
+ <string name="init_ec_icons">Kartikoner</string>
+ <string name="settings_ec_icons_other">Egen stil</string>
+ <string name="settings_ec_icons_oc">Som OC</string>
+ <string name="settings_features">Funktioner som stöds</string>
+ <string name="feature_description">Följande <b>online</b> funktioner på denna webbplats stöds i c:geo (förutom offline funktionerna):</string>
+ <string name="feature_personal_notes">Personlig anteckning</string>
+ <string name="feature_online_logging">Online loggning</string>
+ <string name="feature_log_images">Bifoga bilder till loggar</string>
+ <string name="feature_watch_list">Watchlist</string>
+ <string name="feature_own_coordinates">Lagring av modifierade koordinater</string>
+ <string name="feature_search_keyword">Sök med nyckelord</string>
+ <string name="feature_search_live_map">Live karta</string>
+ <string name="feature_search_center">Sök efter position</string>
+ <string name="feature_search_geocode">Sök med geo-kod</string>
+ <string name="feature_search_owner">Sök baserat på ägare</string>
+ <string name="feature_search_finder">Sök baserat på hittare</string>
<string name="map_source_google_map">Google: Map</string>
<string name="map_source_google_satellite">Google: Satellit</string>
<string name="map_source_osm_mapnik">OSM: Mapnik</string>
@@ -472,6 +518,10 @@
<string name="auth_authorize">Koppla c:geo mot Twitter</string>
<string name="auth_start">Påbörja koppling mot Twitter</string>
<string name="auth_again">Koppla mot Twitter igen</string>
+ <string name="auth_dialog_waiting">Väntar på %s…</string>
+ <string name="auth_explain_short">Följande process kommer att tillåta <b>c:geo</b> att få tillgång till %s.</string>
+ <string name="auth_explain_long">Genom att trycka på knappen \"tillåt c:geo\" kommer processen att startas. Denna process kommer att öppna en webbläsare med %s sida. Logga in på den här sidan och låt <b>c:geo</b> komma åt ditt konto. Det är allt.</string>
+ <string name="auth_dialog_completed_twitter">c:geo är nu godkänd att posta på Twitter.</string>
<string name="auth_ocde">opencaching.de</string>
<string name="auth_dialog_completed_oc">c:geo är nu godkänd för att kommunicera med %s.</string>
<string name="cache_offline">Offline</string>
@@ -494,6 +544,8 @@
<string name="cache_log_image_default_title">Foto</string>
<string name="cache_personal_note">Personlig anteckning</string>
<string name="cache_personal_note_edit">Redigera</string>
+ <string name="cache_personal_note_limit">Begränsning av personlig kommentar</string>
+ <string name="cache_personal_note_truncation">Denna personliga kommentar kommer att trunkeras efter %d tecken av Geocaching.com.</string>
<string name="cache_personal_note_upload">Ladda upp</string>
<string name="cache_personal_note_uploading">Laddar upp personlig anteckning</string>
<string name="cache_personal_note_upload_done">Den personliga anteckning har laddats upp</string>
@@ -569,6 +621,7 @@
<string name="cache_menu_whereyougo">WhereYouGo</string>
<string name="cache_menu_oruxmaps">OruxMaps</string>
<string name="cache_menu_cachebeacon">Cache Beacon</string>
+ <string name="cache_menu_pebble">Pebble</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Sparad logg</string>
<string name="cache_status_found">Hittad</string>
@@ -596,7 +649,6 @@
<string name="cache_coordinates">Koordinater</string>
<string name="cache_coordinates_original">Ursprungliga koordinater</string>
<string name="cache_spoiler_images_title">Spoiler bilder</string>
- <string name="cache_images_title">Bilder</string>
<string name="cache_log_types">Loggtyper</string>
<string name="cache_coordinates_no">Cachen saknar koordinater.</string>
<string name="cache_clear_history">Rensa historik</string>
@@ -615,6 +667,7 @@
<string name="file_title_searching">Söker</string>
<string name="simple_dir_chooser_title">Välj katalog</string>
<string name="simple_dir_chooser_current_path">Sökväg:</string>
+ <string name="simple_dir_chooser_invalid_path">Ogiltig sökväg</string>
<string name="gpx_import_loading_caches">Läser in cacher från .gpx filen</string>
<string name="gpx_import_loading_waypoints">Läser in punkter från .gpx file</string>
<string name="gpx_import_store_static_maps">Sparar kartor</string>
@@ -632,6 +685,7 @@
<string name="gpx_import_delete_title">Ta bort fil</string>
<string name="gpx_import_delete_message">Vill du radera %s?</string>
<string name="gpx_import_select_list_title">Importera GPX till lista</string>
+ <string name="gpx_import_android">Importera från Android</string>
<string name="map_file_select_title">Välj kartfil</string>
<string name="web_import_title">Importerar från webben</string>
<string name="web_import_waiting">Väntar på nya cacher från webben…</string>
@@ -702,7 +756,6 @@
<string name="map_strategy_auto">Hastighetsberoende (gps)</string>
<string name="map_strategy_detailed">Exakta positioner</string>
<string name="live_map_notification">I den nya Live kartan så är koordinaterna inte alltid exakta. En cache med potentiellt oexakta koordinater är markerad med en orange cirkel.\nGenom att visa detaljer för cachen eller genom att spara cachen för offline kommer alltid exakta koordinater att hämtas.\n\nMer information om alla förändringar finns på \"Om c:geo\" sidan, som kan nås från c:geo\'s startsida.</string>
- <string name="live_map_note_dontshow">Visa inte mer</string>
<string name="search_bar_hint">Sök cache/TB</string>
<string name="search_bar_desc">Cache (GC-kod, nyckelord), Trackable (TB-kod)</string>
<string name="search_coordinates">Koordinater</string>
@@ -728,6 +781,9 @@
<string name="search_address_started">Söker efter platser</string>
<string name="search_address_result">Hittade platser</string>
<string name="search_own_caches">Sök egna cacher</string>
+ <string name="search_pocket_title">Pocket query</string>
+ <string name="search_pocket_loading">Laddar en lista med Pocket queries</string>
+ <string name="search_pocket_select">Välj Pocket query</string>
<string name="trackable">Trackable</string>
<string name="trackable_details_loading">Laddar detaljer om trackable…</string>
<string name="trackable_log_touch">Logga</string>
@@ -760,6 +816,7 @@
<string name="user_menu_view_found">Hittade cacher</string>
<string name="user_menu_open_browser">Öppna profil i webbläsaren</string>
<string name="user_menu_send_message">Skicka meddelande</string>
+ <string name="user_menu_open_contact">Öppna kontakt</string>
<string name="navigation">Navigering</string>
<string name="compass_title">Kompass</string>
<string name="use_gps">Använd enbart GPS</string>
@@ -768,12 +825,17 @@
<string name="destination_set">Sätt målpunkt</string>
<string name="navigation_direct_navigation">Direkt navigering</string>
<string name="navigation_target">Mål</string>
+ <string name="err_nav_no_coordinates">Kan inte starta navigering utan koordinater</string>
<string name="license">Licens</string>
<string name="license_show">Visa licens</string>
<string name="license_dismiss">Avbryt</string>
<string name="helper_calendar_title">c:geo kalendertillägg</string>
<string name="helper_calendar_missing">c:geo kalendertillägg är inte installerat</string>
<string name="helper_calendar_description">Gör det möjligt att exportera event till din kalender.</string>
+ <string name="helper_sendtocgeo_title">Skicka till c:geo (Send2cgeo)</string>
+ <string name="helper_contacts_title">c:geo - Kontakttillägg</string>
+ <string name="helper_contacts_description">Gör det möjligt att öppna en kontakt (i telefonens adressbok) direkt från en logg, så att du enkelt kan kontakta vänner för att få hjälp.</string>
+ <string name="helper_sendtocgeo_description">Skicka till c:geo är ett tillägg till webbläsaren <strong>för din PC</strong>. När du bläddrar geocaching.com, kan du skicka cacher till din telefon med en knapptryckning i webbläsaren.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Ett enkelt program för att visa Online kartor men som också medger nedladdning av raster kartor för användning i Offline läge. Stödjer även inspelning av väg (track recording), POI hantering och många andra användbara funktioner.</string>
<string name="helper_gpsstatus_title">GPS Status</string>
@@ -784,6 +846,8 @@
<string name="helper_barcode_description">Det finns Greasemonkey-script och hemsidor som visar GC-koder som streckkoder/QR-koder. Med den här appen kan c:geo scanna in GC-koden direkt från skärmen på din dator.</string>
<string name="helper_pocketquery_title">Pocket Query Creator</string>
<string name="helper_pocketquery_description">Gör det enkelt att skapa och ladda ner Pocket Queries baserade på din position eller plats som väljs på kartan. Kräver Premium konto hos Geocaching.com.</string>
+ <string name="helper_google_translate_title">Google Översätt</string>
+ <string name="helper_google_translate_description">Om du hämtar översättningspaket i Google Translate appen, kan du enkelt översätta cachebeskrivningar i c:geo med en lång tryckning på cache-beskrivningstexten (även utan Internet-anslutning).</string>
<string name="addon_missing_title">Tillägg saknas</string>
<string name="addon_download_prompt">Hämta det nu från Google Play.</string>
<string name="export">Exportera</string>
@@ -799,6 +863,230 @@
<string name="export_gpx">GPX</string>
<string name="export_gpx_info">GPX filen kommer att exporteras till %1$s med datum och tid i filnamnet.</string>
<string name="export_gpx_to">Skicka exporterad GPX till</string>
+ <string name="attribute_dogs_yes">Hundar tillåtna</string>
+ <string name="attribute_dogs_no">Hundar är inte tillåtna</string>
+ <string name="attribute_bicycles_yes">Cyklar tillåtna</string>
+ <string name="attribute_bicycles_no">Cyklar inte tillåtna</string>
+ <string name="attribute_motorcycles_yes">Motorcyklar tillåtna</string>
+ <string name="attribute_motorcycles_no">Motorcyklar inte tillåtna</string>
+ <string name="attribute_quads_yes">Fyrhjulingar tillåtna</string>
+ <string name="attribute_quads_no">Fyrhjulingar inte tillåtna</string>
+ <string name="attribute_jeeps_yes">Terränggående fordon tillåtna</string>
+ <string name="attribute_jeeps_no">Terränggående fordon inte tillåtna</string>
+ <string name="attribute_snowmobiles_yes">Snöskotrar tillåtna</string>
+ <string name="attribute_snowmobiles_no">Snöskotrar inte tillåtna</string>
+ <string name="attribute_horses_yes">Hästar tillåtna</string>
+ <string name="attribute_horses_no">Hästar inte tillåtna</string>
+ <string name="attribute_campfires_yes">Lägereldar tillåtna</string>
+ <string name="attribute_campfires_no">Lägereldar inte tillåtna</string>
+ <string name="attribute_rv_yes">Lastbil/husbil tillåtna</string>
+ <string name="attribute_rv_no">Lastbil/husbil inte tillåtna</string>
+ <string name="attribute_kids_yes">Rekommenderas för barn</string>
+ <string name="attribute_kids_no">Rekommenderas inte för barn</string>
+ <string name="attribute_onehour_yes">Tar mindre än en timme</string>
+ <string name="attribute_onehour_no">Tar mer än en timme</string>
+ <string name="attribute_scenic_yes">Vacker utsikt</string>
+ <string name="attribute_scenic_no">Ingen vacker utsikt</string>
+ <string name="attribute_hiking_yes">Väsentlig vandring</string>
+ <string name="attribute_hiking_no">Obetydlig vandring</string>
+ <string name="attribute_climbing_yes">Svår klättring</string>
+ <string name="attribute_climbing_no">Ingen svår klättring</string>
+ <string name="attribute_wading_yes">Kan kräva vadning</string>
+ <string name="attribute_wading_no">Kräver inte vadning</string>
+ <string name="attribute_swimming_yes">Kan kräva simning</string>
+ <string name="attribute_swimming_no">Ingen simning</string>
+ <string name="attribute_available_yes">Alltid tillgänglig</string>
+ <string name="attribute_available_no">Inte alltid tillgänglig</string>
+ <string name="attribute_night_yes">Rekommenderas på natten</string>
+ <string name="attribute_night_no">Rekommenderas inte på natten</string>
+ <string name="attribute_winter_yes">Tillgänglig under vintern</string>
+ <string name="attribute_winter_no">Inte tillgänglig under vintern</string>
+ <string name="attribute_stealth_yes">Stealth krävs</string>
+ <string name="attribute_stealth_no">Stealth krävs inte</string>
+ <string name="attribute_firstaid_yes">Behöver underhåll</string>
+ <string name="attribute_firstaid_no">Behöver inget underhåll</string>
+ <string name="attribute_cow_yes">Se för boskap</string>
+ <string name="attribute_cow_no">Ingen boskap</string>
+ <string name="attribute_field_puzzle_yes">Fältpussel</string>
+ <string name="attribute_field_puzzle_no">Inget fältpussel</string>
+ <string name="attribute_nightcache_yes">Nattcache</string>
+ <string name="attribute_nightcache_no">Ingen nattcache</string>
+ <string name="attribute_parkngrab_yes">Parkera och logga</string>
+ <string name="attribute_parkngrab_no">Ingen parkera och logga</string>
+ <string name="attribute_abandonedbuilding_yes">Övergivna byggnader</string>
+ <string name="attribute_abandonedbuilding_no">Inga övergivna byggnader</string>
+ <string name="attribute_hike_short_yes">Kort vandring (mindre än 1 km)</string>
+ <string name="attribute_hike_short_no">Ingen kort vandring</string>
+ <string name="attribute_hike_med_yes">Medellång vandring (1 km till 10 km)</string>
+ <string name="attribute_hike_med_no">Ingen medellång vandring</string>
+ <string name="attribute_hike_long_yes">Lång vandringen (mer än 10 km)</string>
+ <string name="attribute_hike_long_no">Ingen lång vandring</string>
+ <string name="attribute_seasonal_yes">Tillgänglig beroende på säsong</string>
+ <string name="attribute_seasonal_no">Inte tillgänglig beroende på säsong</string>
+ <string name="attribute_touristok_yes">Turistvänlig</string>
+ <string name="attribute_touristok_no">Inte turistvänlig</string>
+ <string name="attribute_frontyard_yes">Privat bostad</string>
+ <string name="attribute_frontyard_no">Inte en privat bostad</string>
+ <string name="attribute_teamwork_yes">Lagarbete krävs</string>
+ <string name="attribute_teamwork_no">Inget lagarbete krävs</string>
+ <string name="attribute_landf_yes">Lost and found tour</string>
+ <string name="attribute_landf_no">Inte en Lost and found tour</string>
+ <string name="attribute_partnership_yes">Partnerskapscache</string>
+ <string name="attribute_partnership_no">Inte en partnerskapscache</string>
+ <string name="attribute_fee_yes">Entré- eller parkeringavgift krävs</string>
+ <string name="attribute_fee_no">Entré- eller parkeringavgift krävs inte</string>
+ <string name="attribute_rappelling_yes">Klätterutrustning krävs</string>
+ <string name="attribute_rappelling_no">Klätterutrustning krävs inte</string>
+ <string name="attribute_boat_yes">Båt krävs</string>
+ <string name="attribute_boat_no">Båt krävs inte</string>
+ <string name="attribute_scuba_yes">Dykutrustning krävs</string>
+ <string name="attribute_scuba_no">Dykutrustning krävs inte</string>
+ <string name="attribute_flashlight_yes">Ficklampa krävs</string>
+ <string name="attribute_flashlight_no">Ficklampa krävs inte</string>
+ <string name="attribute_uv_yes">UV-ljus krävs</string>
+ <string name="attribute_uv_no">UV-ljus krävs inte</string>
+ <string name="attribute_snowshoes_yes">Snöskor krävs</string>
+ <string name="attribute_snowshoes_no">Snöskor krävs inte</string>
+ <string name="attribute_skiis_yes">Längdskidor krävs</string>
+ <string name="attribute_skiis_no">Längdskidor krävs inte</string>
+ <string name="attribute_s_tool_yes">Specialverktyg krävs</string>
+ <string name="attribute_s_tool_no">Specialverktyg krävs inte</string>
+ <string name="attribute_wirelessbeacon_yes">Trådlös beacon</string>
+ <string name="attribute_wirelessbeacon_no">Ingen trådlös beacon</string>
+ <string name="attribute_treeclimbing_yes">Trädklättring krävs</string>
+ <string name="attribute_treeclimbing_no">Trädklättring krävs inte</string>
+ <string name="attribute_poisonoak_yes">Giftiga växter</string>
+ <string name="attribute_poisonoak_no">Inga giftiga växter</string>
+ <string name="attribute_dangerousanimals_yes">Farliga djur</string>
+ <string name="attribute_dangerousanimals_no">Inga farliga djur</string>
+ <string name="attribute_ticks_yes">Fästingar</string>
+ <string name="attribute_ticks_no">Inga fästingar</string>
+ <string name="attribute_mine_yes">Övergivna gruvor</string>
+ <string name="attribute_mine_no">Inga övergivna gruvor</string>
+ <string name="attribute_cliff_yes">Klippor / fallande stenar</string>
+ <string name="attribute_cliff_no">Inga klippor / fallande stenar</string>
+ <string name="attribute_hunting_yes">Jakt</string>
+ <string name="attribute_hunting_no">Ingen jakt</string>
+ <string name="attribute_danger_yes">Farligt område</string>
+ <string name="attribute_danger_no">Inte ett farligt område</string>
+ <string name="attribute_thorn_yes">Taggar</string>
+ <string name="attribute_thorn_no">Inga taggar</string>
+ <string name="attribute_wheelchair_yes">Tillgänglig med rullstol</string>
+ <string name="attribute_wheelchair_no">Inte tillgänglig med rullstol</string>
+ <string name="attribute_parking_yes">Parkering</string>
+ <string name="attribute_parking_no">Ingen parkering</string>
+ <string name="attribute_public_yes">Kollektivtrafik</string>
+ <string name="attribute_public_no">Ingen kollektivtrafik</string>
+ <string name="attribute_water_yes">Dricksvatten i närheten</string>
+ <string name="attribute_water_no">Inget dricksvatten i närheten</string>
+ <string name="attribute_restrooms_yes">Offentliga toaletter i närheten</string>
+ <string name="attribute_restrooms_no">Inga offentliga toaletter i närheten</string>
+ <string name="attribute_phone_yes">Telefon i närheten</string>
+ <string name="attribute_phone_no">Ingen telefon i närheten</string>
+ <string name="attribute_picnic_yes">Picknickbord i närheten</string>
+ <string name="attribute_picnic_no">Inga picknickbord i närheten</string>
+ <string name="attribute_camping_yes">Camping finns</string>
+ <string name="attribute_camping_no">Ingen camping finns</string>
+ <string name="attribute_stroller_yes">Tillgänglig med barnvagn</string>
+ <string name="attribute_stroller_no">Inte tillgänglig med barnvagn</string>
+ <string name="attribute_fuel_yes">Mack i närheten</string>
+ <string name="attribute_fuel_no">Ingen mack i närheten</string>
+ <string name="attribute_food_yes">Mat i närheten</string>
+ <string name="attribute_food_no">Ingen mat i närheten</string>
+ <string name="attribute_oc_only_yes">Endast loggbar på Opencaching</string>
+ <string name="attribute_oc_only_no">Inte loggbar endast på Opencaching</string>
+ <string name="attribute_link_only_yes">Enbart länk till en annan cacheportal</string>
+ <string name="attribute_link_only_no">Inte enbart länk till en annan cacheportal</string>
+ <string name="attribute_letterbox_yes">Letterbox (behöver stämpel)</string>
+ <string name="attribute_letterbox_no">Ingen letterbox (ingen stämpel krävs)</string>
+ <string name="attribute_railway_yes">Aktiv järnväg i närheten</string>
+ <string name="attribute_railway_no">Inga aktiva järnvägar i närheten</string>
+ <string name="attribute_syringe_yes">Första hjälpen tillgänglig</string>
+ <string name="attribute_syringe_no">Ingen första hjälpen tillgänglig</string>
+ <string name="attribute_swamp_yes">Träsk eller kärr</string>
+ <string name="attribute_swamp_no">Inget träsk eller kärr</string>
+ <string name="attribute_hills_yes">Kuperat område</string>
+ <string name="attribute_hills_no">Inte ett kuperat område</string>
+ <string name="attribute_easy_climbing_yes">Lätt klättring</string>
+ <string name="attribute_easy_climbing_no">Ingen lätt klättring</string>
+ <string name="attribute_poi_yes">Punkt av intresse</string>
+ <string name="attribute_poi_no">Ingen punkt av intresse</string>
+ <string name="attribute_moving_target_yes">Rörligt mål</string>
+ <string name="attribute_moving_target_no">Inget rörligt mål</string>
+ <string name="attribute_webcam_yes">Webbkamera</string>
+ <string name="attribute_webcam_no">Ingen webbkamera</string>
+ <string name="attribute_inside_yes">Inom slutna rum (grottor, byggnader etc.)</string>
+ <string name="attribute_inside_no">Inte inom slutna rum</string>
+ <string name="attribute_in_water_yes">I vattnet</string>
+ <string name="attribute_in_water_no">Inte i vattnet</string>
+ <string name="attribute_no_gps_yes">Utan GPS (letterbox, kompass jonglering,…)</string>
+ <string name="attribute_no_gps_no">Med GPS</string>
+ <string name="attribute_overnight_yes">Övernattning krävs</string>
+ <string name="attribute_overnight_no">Ingen övernattning krävs</string>
+ <string name="attribute_specific_times_yes">Endast tillgänglig på angivna tider</string>
+ <string name="attribute_specific_times_no">Inte bara tillgänglig på angivna tider</string>
+ <string name="attribute_day_yes">Enbart dagtid</string>
+ <string name="attribute_day_no">Inte bara dagtid</string>
+ <string name="attribute_tide_yes">Tidvatten</string>
+ <string name="attribute_tide_no">Inget tidvatten</string>
+ <string name="attribute_all_seasons_yes">Alla årstider</string>
+ <string name="attribute_all_seasons_no">Inte alla årstider</string>
+ <string name="attribute_breeding_yes">Häckningssäsong / skyddad natur</string>
+ <string name="attribute_breeding_no">Ingen häckningssäsong / skyddad natur</string>
+ <string name="attribute_snow_proof_yes">Snösäkert gömställe</string>
+ <string name="attribute_snow_proof_no">Ingen snösäkert gömställe</string>
+ <string name="attribute_compass_yes">Kompass</string>
+ <string name="attribute_compass_no">Ingen kompass</string>
+ <string name="attribute_cave_yes">Grottutrustning</string>
+ <string name="attribute_cave_no">Ingen grottutrustning</string>
+ <string name="attribute_aircraft_yes">Flygplan</string>
+ <string name="attribute_aircraft_no">Inga flygplan</string>
+ <string name="attribute_investigation_yes">Undersökning</string>
+ <string name="attribute_investigation_no">Ingen undersökning</string>
+ <string name="attribute_puzzle_yes">Pussel / mysterie</string>
+ <string name="attribute_puzzle_no">Inget pussel / mysterie</string>
+ <string name="attribute_arithmetic_yes">Aritmetiskt problem</string>
+ <string name="attribute_arithmetic_no">Inga aritmetiska problem</string>
+ <string name="attribute_other_cache_yes">Annan cachetyp</string>
+ <string name="attribute_other_cache_no">Ingen annan cachetyp</string>
+ <string name="attribute_ask_owner_yes">Kontakta ägaren för start villkor</string>
+ <string name="attribute_ask_owner_no">Ägaren behöver inte kontaktas för start villkor</string>
+ <string name="attribute_unknown_yes">Okänt attribut hittat</string>
+ <string name="attribute_unknown_no">Inget okänt attribut hittat</string>
+ <string name="attribute_geotour_yes">Del av GeoTour</string>
+ <string name="attribute_geotour_no">Inte en del av GeoTour</string>
+ <string name="attribute_kids_2_yes">Ta med dina barn</string>
+ <string name="attribute_kids_2_no">Ta inte med dina barn</string>
+ <string name="attribute_historic_site_yes">Historisk plats</string>
+ <string name="attribute_historic_site_no">Ingen historisk plats</string>
+ <string name="attribute_magnetic_yes">Magnetisk cache</string>
+ <string name="attribute_magnetic_no">Inte en magnetisk cache</string>
+ <string name="attribute_usb_cache_yes">Dead drop USB cache</string>
+ <string name="attribute_usb_cache_no">Inte dead drop USB cache</string>
+ <string name="attribute_shovel_yes">Du kan behöva en spade</string>
+ <string name="attribute_shovel_no">Du behöver ingen spade</string>
+ <string name="attribute_specific_access_yes">Tillgänglig på angivna klockslag (kan kräva avgift)</string>
+ <string name="attribute_specific_access_no">Tillgänglig hela tiden</string>
+ <string name="attribute_pedestrian_only_yes">Tillgänglig endast till fots</string>
+ <string name="attribute_pedestrian_only_no">Inte tillgänglig endast till fots</string>
+ <string name="attribute_nature_cache_yes">Gömd i naturliga omgivningar (skogar, berg, etc.)</string>
+ <string name="attribute_nature_cache_no">Inte gömd i naturliga omgivningar</string>
+ <string name="attribute_byop_yes">Ta med något att skriva med</string>
+ <string name="attribute_byop_no">Egen penna behövs ej</string>
+ <string name="attribute_safari_cache_yes">Reverse cache</string>
+ <string name="attribute_safari_cache_no">Inte en reverse cache</string>
+ <string name="attribute_quick_cache_yes">Snabb cache</string>
+ <string name="attribute_quick_cache_no">Inte en snabb cache</string>
+ <string name="attribute_wherigo_yes">Wherigo cache</string>
+ <string name="attribute_wherigo_no">Ingen Wherigo cache</string>
+ <string name="attribute_audio_cache_yes">Beskrivningen innehåller en ljudfil</string>
+ <string name="attribute_audio_cache_no">Beskrivningen innehåller inte en ljudfil</string>
+ <string name="attribute_geohotel_yes">GeoHotel cache</string>
+ <string name="attribute_geohotel_no">Inte en GeoHotel cache</string>
+ <string name="attribute_survey_marker_yes">Nära en Survey Marker</string>
+ <string name="attribute_survey_marker_no">Inte nära en Survey Marker</string>
+ <string name="attribute_offset_cache_yes">Offset cache</string>
+ <string name="attribute_offset_cache_no">Ingen offset cache</string>
<string name="quote">To make geocaching easier, to make users lazier.</string>
<string name="powered_by">carnero</string>
<string name="support">Support: <a href="">support@cgeo.org</a></string>
@@ -825,6 +1113,9 @@
<string name="tts_one_oclock">Klockan ett</string>
<string name="tts_oclock">Klockan %s</string>
<string name="clipboard_copy_ok">Kopierat till urklipp</string>
+ <string name="percent_favorite_points">%\ favoriter</string>
+ <string name="cgeo_shortcut">c:geo genväg</string>
+ <string name="create_shortcut">Skapa genväg</string>
<string-array name="log_image_scales">
<item>Ingen skalning</item>
<item>512 px</item>
diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml
index 1e3c3d4..7d733ab 100644
--- a/main/res/values/changelog_master.xml
+++ b/main/res/values/changelog_master.xml
@@ -2,5 +2,19 @@
<resources>
<!-- changelog for the master branch -->
<string name="changelog_master" translatable="false">
+ <b>Next feature release</b>\n
+ <b>New Features:</b>\n
+ · Parallel loading from different platforms to speed up live map\n
+ · All GCVote related settings moved to Menu-Services-GCVote\n
+ · Support of some GSAK specific GPX contents\n
+ · Create waypoint from personal note also for OC caches\n
+ <b>Bugfixing:</b>\n
+ · Corrected wrong field note progress indication\n
+ · When using "external map" sometimes the position marker was not shown\m
+ · Circles on map now also shown for caches with final coords defined\n
+ · Adding event caches to calendar corrected for events without starting time\n
+ · Logging of OC caches was not possible if no GC login data was stored\n
+ \n
+ \n
</string>
</resources>
diff --git a/main/res/values/preference_keys.xml b/main/res/values/preference_keys.xml
index 0e4675d..d231795 100644
--- a/main/res/values/preference_keys.xml
+++ b/main/res/values/preference_keys.xml
@@ -6,13 +6,18 @@
and in the Java code as constants and avoid code duplication.
-->
- <string name="pref_fakekey_main_screen">fakekey_main_screen</string>
- <string name="pref_fakekey_services_screen">fakekey_services_screen</string>
- <string name="pref_fakekey_basicmembers_screen">fakekey_basicmembers_screen</string>
+ <string name="preference_screen_main">fakekey_main_screen</string>
+ <string name="preference_screen_services">fakekey_services_screen</string>
+ <string name="preference_screen_gc">preference_screen_gc</string>
+ <string name="preference_screen_basicmembers">fakekey_basicmembers_screen</string>
+ <string name="preference_screen_ocde">preference_screen_ocde</string>
+ <string name="preference_screen_ocpl">preference_screen_ocpl</string>
+ <string name="preference_screen_ec">preference_screen_ec</string>
+ <string name="preference_screen_twitter">preference_screen_twitter</string>
+ <string name="preference_screen_navigation_menu">fakekey_navigation_menu_screen</string>
<string name="pref_fakekey_ocde_authorization">fakekey_ocde_authorization</string>
<string name="pref_fakekey_ocpl_authorization">fakekey_ocpl_authorization</string>
<string name="pref_fakekey_twitter_authorization">fakekey_twitter_authorization</string>
- <string name="pref_fakekey_navigation_menu_screen">fakekey_navigation_menu_screen</string>
<string name="pref_connectorGCActive">connectorGCActive</string>
<string name="pref_username">username</string>
<string name="pref_password">password</string>
@@ -60,6 +65,7 @@
<string name="pref_fakekey_preference_backup_info">fakekey_preference_backup_info</string>
<string name="pref_fakekey_preference_backup">fakekey_preference_backup</string>
<string name="pref_fakekey_preference_restore">fakekey_preference_restore</string>
+ <string name="pref_fakekey_preference_maintenance_directories">pref_fakekey_preference_maintenance_directories</string>
<string name="pref_dbonsdcard">dbonsdcard</string>
<string name="pref_debug">debug</string>
<!-- preferences used internally -->
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml
index 7b40811..c4e3fae 100644
--- a/main/res/values/strings.xml
+++ b/main/res/values/strings.xml
@@ -45,7 +45,9 @@
<string name="cache_size_virtual">Virtual</string>
<string name="cache_size_notchosen">Not chosen</string>
<string name="cache_size_unknown">Unknown</string>
-
+ <string name="cache_size_nano">Nano</string>
+ <string name="cache_size_very_large">Very large</string>
+
<!-- waypoints -->
<string name="wp_final">Final Location</string>
<string name="wp_stage">Stage of a Multicache</string>
@@ -129,6 +131,7 @@
<string name="log_image_scale">Scaling</string>
<string name="log_password_title">Log Password:</string>
<string name="log_hint_log_password">Enter your log password</string>
+ <string name="log_oc_team_comment">OC Team comment</string>
<string-array name="log_image_scales">
<item>No scaling</item>
@@ -145,12 +148,10 @@
<!-- errors, warnings, info toasts -->
<string name="err_none">OK</string>
- <string name="err_start">Communication not started</string>
<string name="err_parse">Failed Login page parsing</string>
<string name="err_server">Unable to contact Geocaching.com. The website may be down or your internet connection not working.</string>
<string name="err_server_ec">Unable to contact Extremcaching.com. The website may be down or your internet connection not working.</string>
<string name="err_login">No Login information stored</string>
- <string name="err_login_failed">c:geo can\'t log in.</string>
<string name="err_login_failed_toast">c:geo can\'t log in. c:geo works offline with Stored caches. Check Login settings or enable your internet connection.</string>
<string name="err_unknown">Unknown error</string>
<string name="err_comm">Unknown communication error</string>
@@ -202,7 +203,6 @@
<string name="err_log_load_data">c:geo can\'t load data required to log visit.</string>
<string name="err_log_load_data_again">c:geo can\'t load data required to log visit. Trying again.</string>
<string name="err_log_load_data_still">c:geo is still loading data required to post log. Please wait a little while longer.</string>
- <string name="err_log_failed_server">c:geo failed to post log because server is not responding.</string>
<string name="err_log_post_failed">It seems that your log was not posted. Please check it on Geocaching.com.</string>
<string name="err_log_post_failed_ec">It seems that your log was not posted. Please check it on Extremcaching.com.</string>
<string name="err_logimage_post_failed">It seems that your log image was not uploaded. Please check it on Geocaching.com.</string>
@@ -360,7 +360,8 @@
<string name="list_dialog_remove_err">c:geo failed to remove the current list</string>
<string name="list_dialog_rename_title">Rename list</string>
<string name="list_dialog_rename">Rename</string>
-
+ <string name="list_not_available">List no longer available, switching to standard list</string>
+
<!-- about -->
<string name="about_version">Version</string>
<string name="about_changelog">Changelog</string>
@@ -525,6 +526,9 @@
<string name="init_use_native_ua">Android browser</string>
<string name="init_summary_use_native_ua">Identify as Android browser. Solves login problems when using certain network providers.</string>
<string name="init_rendertheme_folder">Map Themes Directory</string>
+ <string name="init_maintenance">Maintenance</string>
+ <string name="init_maintenance_directories_note">c:geo stores images, log images and other files related to a cache in a separate directory. In some cases (like importing/exporting the database) this directory may contain outdated files, which can be deleted here.</string>
+ <string name="init_maintenance_directories">Delete orphaned files</string>
<string name="settings_open_website">Open website</string>
<string name="settings_settings">Settings</string>
<string name="settings_information">Information</string>
@@ -535,7 +539,7 @@
<string name="settings_ec_icons_oc">Like OC</string>
<string name="settings_features">Supported Features</string>
<string name="feature_description">The following <b>online</b> features of this website are supported in c:geo (in addition to the offline features):</string>
- <string name="feature_personal_notes">Personal notes</string>
+ <string name="feature_personal_notes">Personal note</string>
<string name="feature_online_logging">Online logging</string>
<string name="feature_log_images">Attach images to logs</string>
<string name="feature_watch_list">Watch list</string>
@@ -614,7 +618,7 @@
<string name="cache_personal_note_upload_done">Personal note uploaded</string>
<string name="cache_personal_note_upload_cancelled">Personal note upload cancelled</string>
<string name="cache_personal_note_unstored">Cache not stored</string>
- <string name="cache_personal_note_store">The cache will be stored first to enable personal notes.</string>
+ <string name="cache_personal_note_store">The cache will be stored first to allow a personal note.</string>
<string name="cache_description">Description</string>
<string name="cache_description_long">Long Description</string>
<string name="cache_description_table_note">Description contains table formatting which may need to be viewed at %s to be seen correctly.</string>
@@ -719,7 +723,6 @@
<string name="cache_coordinates">Coordinates</string>
<string name="cache_coordinates_original">Original Coordinates</string>
<string name="cache_spoiler_images_title">Spoiler images</string>
- <string name="cache_images_title">Images</string>
<string name="cache_log_types">Log types</string>
<string name="cache_coordinates_no">This cache has no coordinates.</string>
<string name="cache_clear_history">Clear history</string>
@@ -848,7 +851,6 @@
<string name="map_strategy_auto">Speed dependent</string>
<string name="map_strategy_detailed">Detailed</string>
<string name="live_map_notification">Coordinates on the live map may not always be precise. Possibly imprecise coordinates are marked by an orange circle.\nOpening the cache details or saving the cache for offline use will always obtain precise coordinates.\n\nMore information can be found on the \"About c:geo\" page inside the app.</string>
- <string name="live_map_note_dontshow">Do not show again</string>
<!-- search -->
<string name="search_bar_hint">Search for caches</string>
@@ -939,6 +941,8 @@
<string name="helper_calendar_missing">c:geo calendar add-on not installed.</string>
<string name="helper_calendar_description">Enables you to export event caches to the calendar on your device.</string>
<string name="helper_sendtocgeo_title">Send to c:geo</string>
+ <string name="helper_contacts_title">c:geo contacts add-on</string>
+ <string name="helper_contacts_description">Enables you to open a contact card (of your address book) directly from a log entry, so you can more easily ask friends for help.</string>
<string name="helper_sendtocgeo_description">Send to c:geo is a browser extension <strong>for your PC</strong>. When browsing geocaching.com, you can send caches to your smartphone with the click of a button directly inside the browser.</string>
<string name="helper_locus_title">Locus</string>
<string name="helper_locus_description">Simple, usable application which shows online maps and allows you to download them directly into Offline mode (raster maps only). Also supports track recording, POI handling and many other useful functions.</string>
@@ -1262,5 +1266,6 @@
<string name="percent_favorite_points">%\ favorites</string>
<!-- shortcuts -->
+ <string name="cgeo_shortcut">c:geo shortcut</string>
<string name="create_shortcut">Create shortcut</string>
</resources>
diff --git a/main/res/xml/preferences.xml b/main/res/xml/preferences.xml
index de0914e..454574e 100644
--- a/main/res/xml/preferences.xml
+++ b/main/res/xml/preferences.xml
@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cgeo="http://schemas.android.com/apk/res/cgeo.geocaching"
- android:key="@string/pref_fakekey_main_screen" >
+ android:key="@string/preference_screen_main" >
<PreferenceScreen
android:icon="?attr/settings_cloud"
- android:key="@string/pref_fakekey_services_screen"
+ android:key="@string/preference_screen_services"
android:title="@string/settings_title_services" >
<PreferenceCategory android:title="@string/settings_category_geocaching" >
- <PreferenceScreen android:title="@string/settings_title_gc" >
+ <PreferenceScreen
+ android:key="@string/preference_screen_gc"
+ android:title="@string/settings_title_gc" >
<PreferenceCategory android:title="@string/settings_settings" >
<cgeo.geocaching.settings.CheckBoxWithPopupPreference
android:defaultValue="true"
@@ -44,7 +46,7 @@
<PreferenceScreen
android:dependency="@string/pref_connectorGCActive"
- android:key="@string/pref_fakekey_basicmembers_screen"
+ android:key="@string/preference_screen_basicmembers"
android:title="@string/settings_title_basicmembers" >
<CheckBoxPreference
android:defaultValue="false"
@@ -74,7 +76,9 @@
android:title="@string/settings_open_website" />
</PreferenceCategory>
</PreferenceScreen>
- <PreferenceScreen android:title="@string/init_oc" >
+ <PreferenceScreen
+ android:key="@string/preference_screen_ocde"
+ android:title="@string/init_oc" >
<PreferenceCategory android:title="@string/settings_settings" >
<CheckBoxPreference
android:defaultValue="false"
@@ -94,12 +98,15 @@
<cgeo.geocaching.settings.CapabilitiesPreference
android:title="@string/settings_features"
cgeo:connector="OC" />
+
<Preference
android:key="@string/pref_fakekey_ocde_website"
android:title="@string/settings_open_website" />
</PreferenceCategory>
</PreferenceScreen>
- <PreferenceScreen android:title="@string/init_oc_pl" >
+ <PreferenceScreen
+ android:key="@string/preference_screen_ocpl"
+ android:title="@string/init_oc_pl" >
<PreferenceCategory android:title="@string/settings_settings" >
<CheckBoxPreference
android:defaultValue="false"
@@ -119,13 +126,13 @@
<cgeo.geocaching.settings.CapabilitiesPreference
android:title="@string/settings_features"
cgeo:connector="OP" />
+
<Preference
android:key="@string/pref_fakekey_ocpl_website"
android:title="@string/settings_open_website" />
</PreferenceCategory>
</PreferenceScreen>
-
- <PreferenceScreen android:title="@string/settings_title_ec" >
+ <PreferenceScreen android:title="@string/settings_title_ec" android:key="@string/preference_screen_ec">
<PreferenceCategory android:title="@string/settings_settings" >
<CheckBoxPreference
android:defaultValue="false"
@@ -150,30 +157,31 @@
android:key="@string/pref_ecpassword"
android:singleLine="true"
android:title="@string/init_password" />
+
<cgeo.geocaching.settings.CheckECCredentialsPreference
android:dependency="@string/pref_connectorECActive"
android:title="@string/init_login" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_title_appearance" >
- <ListPreference
- android:dependency="@string/pref_connectorECActive"
- android:defaultValue="1"
- android:dialogTitle="@string/init_ec_icons"
- android:key="@string/pref_ec_icons"
- android:title="@string/init_ec_icons"
- android:entries="@array/ECIcons"
- android:entryValues="@array/ECIconsValues" />
+ <ListPreference
+ android:defaultValue="1"
+ android:dependency="@string/pref_connectorECActive"
+ android:dialogTitle="@string/init_ec_icons"
+ android:entries="@array/ECIcons"
+ android:entryValues="@array/ECIconsValues"
+ android:key="@string/pref_ec_icons"
+ android:title="@string/init_ec_icons" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_information" >
<cgeo.geocaching.settings.CapabilitiesPreference
android:title="@string/settings_features"
cgeo:connector="EC" />
+
<Preference
android:key="@string/pref_fakekey_ec_website"
android:title="@string/settings_open_website" />
</PreferenceCategory>
</PreferenceScreen>
-
<PreferenceScreen android:title="@string/settings_title_ox" >
<PreferenceCategory android:title="@string/settings_settings" >
<CheckBoxPreference
@@ -185,14 +193,19 @@
<cgeo.geocaching.settings.CapabilitiesPreference
android:title="@string/settings_features"
cgeo:connector="OX" />
+
<Preference
android:key="@string/pref_fakekey_ox_website"
android:title="@string/settings_open_website" />
</PreferenceCategory>
</PreferenceScreen>
-
<PreferenceScreen android:title="@string/init_gcvote" >
<PreferenceCategory android:title="@string/settings_settings" >
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:key="@string/pref_ratingwanted"
+ android:summary="@string/init_summary_ratingwanted"
+ android:title="@string/init_ratingwanted" />
<cgeo.geocaching.settings.EditPasswordPreference
android:dialogTitle="@string/init_password"
android:hint="@string/init_password"
@@ -233,7 +246,9 @@
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_category_social" >
- <PreferenceScreen android:title="@string/init_twitter" >
+ <PreferenceScreen
+ android:key="@string/preference_screen_twitter"
+ android:title="@string/init_twitter" >
<CheckBoxPreference
android:defaultValue="false"
android:key="@string/pref_twitter"
@@ -307,11 +322,6 @@
android:title="@string/init_autoload" />
<CheckBoxPreference
android:defaultValue="true"
- android:key="@string/pref_ratingwanted"
- android:summary="@string/init_summary_ratingwanted"
- android:title="@string/init_ratingwanted" />
- <CheckBoxPreference
- android:defaultValue="true"
android:key="@string/pref_friendlogswanted"
android:summary="@string/init_summary_friendlogswanted"
android:title="@string/init_friendlogswanted" />
@@ -470,7 +480,7 @@
android:text="@string/init_navigation_menu_description" />
<PreferenceScreen
- android:key="@string/pref_fakekey_navigation_menu_screen"
+ android:key="@string/preference_screen_navigation_menu"
android:title="@string/settings_title_navigation_menu" >
<CheckBoxPreference
android:defaultValue="true"
@@ -609,6 +619,15 @@
android:key="@string/pref_dbonsdcard"
android:title="@string/init_dbonsdcard" />
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/init_maintenance" >
+ <cgeo.geocaching.settings.TextPreference
+ android:layout="@layout/text_preference"
+ android:text="@string/init_maintenance_directories_note" />
+
+ <Preference
+ android:key="@string/pref_fakekey_preference_maintenance_directories"
+ android:title="@string/init_maintenance_directories" />
+ </PreferenceCategory>
<PreferenceCategory android:title="@string/init_debug_title" >
<cgeo.geocaching.settings.TextPreference
android:layout="@layout/text_preference"
diff --git a/main/res/xml/searchable.xml b/main/res/xml/searchable.xml
index 13e34c5..a3844cf 100644
--- a/main/res/xml/searchable.xml
+++ b/main/res/xml/searchable.xml
@@ -6,6 +6,7 @@
android:inputType="textNoSuggestions"
android:label="@string/app_name"
android:searchSettingsDescription="@string/search_bar_desc"
+ android:searchSuggestAuthority="cgeo.geocaching.search.SuggestionProvider"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable> \ No newline at end of file
diff --git a/main/src/cgeo/calendar/CalendarAddon.java b/main/src/cgeo/calendar/CalendarAddon.java
new file mode 100644
index 0000000..117fb9a
--- /dev/null
+++ b/main/src/cgeo/calendar/CalendarAddon.java
@@ -0,0 +1,58 @@
+package cgeo.calendar;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.R;
+import cgeo.geocaching.geopoint.GeopointFormatter;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.ui.dialog.Dialogs;
+import cgeo.geocaching.utils.ProcessUtils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+
+import java.util.Date;
+
+public class CalendarAddon {
+ public static boolean isAvailable() {
+ return ProcessUtils.isIntentAvailable(ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST));
+ }
+
+ public static void addToCalendarWithIntent(final Activity activity, final Geocache cache) {
+ final Resources res = activity.getResources();
+ if (CalendarAddon.isAvailable()) {
+ final Date hiddenDate = cache.getHiddenDate();
+ final Parameters params = new Parameters(
+ ICalendar.PARAM_NAME, cache.getName(),
+ ICalendar.PARAM_NOTE, StringUtils.defaultString(cache.getPersonalNote()),
+ ICalendar.PARAM_HIDDEN_DATE, hiddenDate != null ? String.valueOf(hiddenDate.getTime()) : StringUtils.EMPTY,
+ ICalendar.PARAM_URL, StringUtils.defaultString(cache.getUrl()),
+ ICalendar.PARAM_COORDS, cache.getCoords() == null ? "" : cache.getCoords().format(GeopointFormatter.Format.LAT_LON_DECMINUTE_RAW),
+ ICalendar.PARAM_LOCATION, StringUtils.defaultString(cache.getLocation()),
+ ICalendar.PARAM_SHORT_DESC, StringUtils.defaultString(cache.getShortDescription()),
+ ICalendar.PARAM_START_TIME_MINUTES, StringUtils.defaultString(cache.guessEventTimeMinutes())
+ );
+
+ activity.startActivity(new Intent(ICalendar.INTENT,
+ Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST + "?" + params.toString())));
+ } else {
+ // Inform user the calendar add-on is not installed and let them get it from Google Play
+ Dialogs.confirmYesNo(activity, R.string.addon_missing_title, new StringBuilder(res.getString(R.string.helper_calendar_missing))
+ .append(' ')
+ .append(res.getString(R.string.addon_download_prompt))
+ .toString(), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ final Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(ICalendar.CALENDAR_ADDON_URI));
+ activity.startActivity(intent);
+ }
+ });
+ }
+ }
+
+}
diff --git a/main/src/cgeo/calendar/ICalendar.java b/main/src/cgeo/calendar/ICalendar.java
index 933d248..6ecb6d5 100644
--- a/main/src/cgeo/calendar/ICalendar.java
+++ b/main/src/cgeo/calendar/ICalendar.java
@@ -14,6 +14,6 @@ public interface ICalendar {
static final String PARAM_NOTE = "note"; // personal note
static final String PARAM_NAME = "name"; // cache name
static final String PARAM_LOCATION = "location"; // cache location, or empty string
- static final String PARAM_COORDS = "coords"; // cache coords, or empty string
+ static final String PARAM_COORDS = "coords"; // cache coordinates, or empty string
static final String PARAM_START_TIME_MINUTES = "time"; // time of start
}
diff --git a/main/src/cgeo/contacts/IContacts.java b/main/src/cgeo/contacts/IContacts.java
index d46a5a4..d68b78a 100644
--- a/main/src/cgeo/contacts/IContacts.java
+++ b/main/src/cgeo/contacts/IContacts.java
@@ -1,8 +1,6 @@
package cgeo.contacts;
public interface IContacts {
- static final String CALENDAR_ADDON_URI = "market://details?id=cgeo.contacts";
-
static final String INTENT = "cgeo.contacts.FIND";
static final String URI_SCHEME = "find";
diff --git a/main/src/cgeo/geocaching/AbstractPopupActivity.java b/main/src/cgeo/geocaching/AbstractPopupActivity.java
index 5f24030..38e37da 100644
--- a/main/src/cgeo/geocaching/AbstractPopupActivity.java
+++ b/main/src/cgeo/geocaching/AbstractPopupActivity.java
@@ -40,7 +40,7 @@ public abstract class AbstractPopupActivity extends AbstractActivity implements
private final GeoDirHandler geoUpdate = new GeoDirHandler() {
@Override
- protected void updateGeoData(final IGeoData geo) {
+ public void updateGeoData(final IGeoData geo) {
try {
if (geo.getCoords() != null && cache != null && cache.getCoords() != null) {
cacheDistance.setText(Units.getDistanceFromKilometers(geo.getCoords().distanceTo(cache.getCoords())));
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index 4068e38..7e8ab28 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -3,6 +3,7 @@ package cgeo.geocaching;
import butterknife.ButterKnife;
import butterknife.InjectView;
+import cgeo.calendar.CalendarAddon;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.activity.AbstractViewPagerActivity;
import cgeo.geocaching.activity.Progress;
@@ -38,18 +39,14 @@ import cgeo.geocaching.ui.WeakReferenceHandler;
import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.ui.logs.CacheLogsViewCreator;
import cgeo.geocaching.utils.CancellableHandler;
-import cgeo.geocaching.utils.ClipboardUtils;
import cgeo.geocaching.utils.CryptUtils;
import cgeo.geocaching.utils.GeoDirHandler;
-import cgeo.geocaching.utils.HtmlUtils;
import cgeo.geocaching.utils.ImageUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.MatcherWrapper;
-import cgeo.geocaching.utils.RunnableWithArgument;
import cgeo.geocaching.utils.SimpleCancellableHandler;
import cgeo.geocaching.utils.SimpleHandler;
import cgeo.geocaching.utils.TextUtils;
-import cgeo.geocaching.utils.TranslationUtils;
import cgeo.geocaching.utils.UnknownTagsHandler;
import org.apache.commons.collections4.CollectionUtils;
@@ -57,6 +54,14 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Observer;
+import rx.Subscriber;
+import rx.Subscription;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action1;
+import rx.schedulers.Schedulers;
import android.R.color;
import android.app.AlertDialog;
@@ -71,7 +76,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -80,7 +84,6 @@ import android.text.Editable;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned;
-import android.text.format.DateUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
@@ -109,7 +112,6 @@ import android.widget.TextView.BufferType;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
@@ -164,6 +166,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
private TextView cacheDistanceView;
protected ImagesList imagesList;
+ private Subscription imagesSubscription;
/**
* waypoint selected in context menu. This variable will be gone when the waypoint context menu is a fragment.
*/
@@ -176,24 +179,15 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
// set title in code, as the activity needs a hard coded title due to the intent filters
setTitle(res.getString(R.string.cache));
- String geocode = null;
-
- // TODO Why can it happen that search is not null? onCreate should be called only once and it is not set before.
- if (search != null) {
- cache = search.getFirstCacheFromResult(LoadFlags.LOAD_ALL_DB_ONLY);
- if (cache != null && cache.getGeocode() != null) {
- geocode = cache.getGeocode();
- }
- }
-
// get parameters
final Bundle extras = getIntent().getExtras();
final Uri uri = getIntent().getData();
// try to get data from extras
String name = null;
+ String geocode = null;
String guid = null;
- if (geocode == null && extras != null) {
+ if (extras != null) {
geocode = extras.getString(Intents.EXTRA_GEOCODE);
name = extras.getString(Intents.EXTRA_NAME);
guid = extras.getString(Intents.EXTRA_GUID);
@@ -327,6 +321,14 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
@Override
+ public void onDestroy() {
+ if (imagesList != null) {
+ imagesSubscription.unsubscribe();
+ }
+ super.onDestroy();
+ }
+
+ @Override
public void onStop() {
if (cache != null) {
cache.setChangeNotificationHandler(null);
@@ -349,12 +351,12 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
assert view instanceof TextView;
clickedItemText = ((TextView) view).getText();
final String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText();
- buildDetailsContextMenu(menu, itemTitle, true);
+ buildDetailsContextMenu(menu, clickedItemText, itemTitle, true);
break;
case R.id.shortdesc:
assert view instanceof TextView;
clickedItemText = ((TextView) view).getText();
- buildDetailsContextMenu(menu, res.getString(R.string.cache_description), false);
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_description), false);
break;
case R.id.longdesc:
assert view instanceof TextView;
@@ -365,22 +367,28 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
} else {
clickedItemText = shortDesc + "\n\n" + ((TextView) view).getText();
}
- buildDetailsContextMenu(menu, res.getString(R.string.cache_description), false);
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_description), false);
break;
case R.id.personalnote:
assert view instanceof TextView;
clickedItemText = ((TextView) view).getText();
- buildDetailsContextMenu(menu, res.getString(R.string.cache_personal_note), true);
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_personal_note), true);
break;
case R.id.hint:
assert view instanceof TextView;
clickedItemText = ((TextView) view).getText();
- buildDetailsContextMenu(menu, res.getString(R.string.cache_hint), false);
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_hint), false);
break;
case R.id.log:
assert view instanceof TextView;
clickedItemText = ((TextView) view).getText();
- buildDetailsContextMenu(menu, res.getString(R.string.cache_logs), false);
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_logs), false);
+ break;
+ case R.id.date: // event date
+ assert view instanceof TextView;
+ clickedItemText = ((TextView) view).getText();
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_event), true);
+ menu.findItem(R.id.menu_calendar).setVisible(cache.canBeAddedToCalendar());
break;
case R.id.waypoint:
menu.setHeaderTitle(selectedWaypoint.getName() + " (" + res.getString(R.string.waypoint) + ")");
@@ -406,41 +414,13 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
- private void buildDetailsContextMenu(ContextMenu menu, String fieldTitle, boolean copyOnly) {
- menu.setHeaderTitle(fieldTitle);
- getMenuInflater().inflate(R.menu.details_context, menu);
- menu.findItem(R.id.menu_translate_to_sys_lang).setVisible(!copyOnly);
- if (!copyOnly) {
- if (clickedItemText.length() > TranslationUtils.TRANSLATION_TEXT_LENGTH_WARN) {
- showToast(res.getString(R.string.translate_length_warning));
- }
- menu.findItem(R.id.menu_translate_to_sys_lang).setTitle(res.getString(R.string.translate_to_sys_lang, Locale.getDefault().getDisplayLanguage()));
- }
- final boolean localeIsEnglish = StringUtils.equals(Locale.getDefault().getLanguage(), Locale.ENGLISH.getLanguage());
- menu.findItem(R.id.menu_translate_to_english).setVisible(!copyOnly && !localeIsEnglish);
- }
-
@Override
public boolean onContextItemSelected(MenuItem item) {
+ if (onClipboardItemSelected(item, clickedItemText)) {
+ return true;
+ }
switch (item.getItemId()) {
- // detail fields
- case R.id.menu_copy:
- ClipboardUtils.copyToClipboard(clickedItemText);
- showToast(res.getString(R.string.clipboard_copy_ok));
- return true;
- case R.id.menu_translate_to_sys_lang:
- TranslationUtils.startActivityTranslate(this, Locale.getDefault().getLanguage(), HtmlUtils.extractText(clickedItemText));
- return true;
- case R.id.menu_translate_to_english:
- TranslationUtils.startActivityTranslate(this, Locale.ENGLISH.getLanguage(), HtmlUtils.extractText(clickedItemText));
- return true;
- case R.id.menu_cache_share_field:
- final Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_TEXT, clickedItemText.toString());
- startActivity(Intent.createChooser(intent, res.getText(R.string.cache_share_field)));
- return true;
- // waypoints
+ // waypoints
case R.id.menu_waypoint_edit:
if (selectedWaypoint != null) {
EditWaypointActivity.startActivityEditWaypoint(this, cache, selectedWaypoint.getId());
@@ -484,6 +464,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
new ResetCoordsThread(cache, handler, selectedWaypoint, true, false, progressDialog).start();
}
return true;
+ case R.id.menu_calendar:
+ CalendarAddon.addToCalendarWithIntent(this, cache);
+ return true;
default:
break;
}
@@ -542,20 +525,19 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
updateStatusMsg((String) msg.obj);
} else {
- CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get());
+ final CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get());
if (activity == null) {
return;
}
- SearchResult search = activity.getSearch();
- if (search == null) {
+ if (activity.search == null) {
showToast(R.string.err_dwld_details_failed);
dismissProgress();
finishActivity();
return;
}
- if (search.getError() != null) {
- activity.showToast(activity.getResources().getString(R.string.err_dwld_details_failed) + " " + search.getError().getErrorString(activity.getResources()) + ".");
+ if (activity.search.getError() != null) {
+ activity.showToast(activity.getResources().getString(R.string.err_dwld_details_failed) + " " + activity.search.getError().getErrorString(activity.getResources()) + ".");
dismissProgress();
finishActivity();
return;
@@ -691,7 +673,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return;
}
imagesList = new ImagesList(this, cache.getGeocode());
- imagesList.loadImages(imageView, cache.getImages(), false);
+ imagesSubscription = imagesList.loadImages(imageView, cache.getImages(), false);
}
public static void startActivity(final Context context, final String geocode) {
@@ -922,9 +904,17 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
view = (ScrollView) getLayoutInflater().inflate(R.layout.cachedetail_details_page, null);
// Start loading preview map
- if (Settings.isStoreOfflineMaps()) {
- new PreviewMapTask().execute((Void) null);
- }
+ AndroidObservable.fromActivity(CacheDetailActivity.this, previewMap.subscribeOn(Schedulers.io())).subscribe(new Action1<BitmapDrawable>() {
+ @Override
+ public void call(final BitmapDrawable image) {
+ final Bitmap bitmap = image.getBitmap();
+ if (bitmap != null && bitmap.getWidth() > 10) {
+ final ImageView imageView = (ImageView) view.findViewById(R.id.map_preview);
+ imageView.setImageDrawable(image);
+ view.findViewById(R.id.map_preview_box).setVisibility(View.VISIBLE);
+ }
+ }
+ });
detailsList = (LinearLayout) view.findViewById(R.id.details_list);
final CacheDetailsCreator details = new CacheDetailsCreator(CacheDetailActivity.this, detailsList);
@@ -972,17 +962,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
ownerView.setOnClickListener(new OwnerActionsClickListener(cache));
}
- // cache hidden
- final Date hiddenDate = cache.getHiddenDate();
- if (hiddenDate != null) {
- final long time = hiddenDate.getTime();
- if (time > 0) {
- String dateString = Formatter.formatFullDate(time);
- if (cache.isEventCache()) {
- dateString = DateUtils.formatDateTime(CgeoApplication.getInstance().getBaseContext(), time, DateUtils.FORMAT_SHOW_WEEKDAY) + ", " + dateString;
- }
- details.add(cache.isEventCache() ? R.string.cache_event : R.string.cache_hidden, dateString);
- }
+ // hidden or event date
+ final TextView hiddenView = details.addHiddenDate(cache);
+ if (hiddenView != null) {
+ registerForContextMenu(hiddenView);
}
// cache location
@@ -1051,9 +1034,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
if (Settings.getChooseList()) {
// let user select list to store cache in
new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title,
- new RunnableWithArgument<Integer>() {
+ new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
storeCache(selectedListId, new StoreCacheHandler(CacheDetailActivity.this, progress));
}
}, true, StoredList.TEMPORARY_LIST_ID);
@@ -1302,9 +1285,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void onClick(View view) {
new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title,
- new RunnableWithArgument<Integer>() {
+ new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
switchListById(selectedListId);
}
}, true, cache.getListId());
@@ -1368,7 +1351,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
final LinearLayout layout = (LinearLayout) view.findViewById(R.id.favpoint_box);
final boolean supportsFavoritePoints = cache.supportsFavoritePoints();
layout.setVisibility(supportsFavoritePoints ? View.VISIBLE : View.GONE);
- if (!supportsFavoritePoints || cache.isOwner() || !Settings.isPremiumMember()) {
+ if (!supportsFavoritePoints || cache.isOwner() || !Settings.isGCPremiumMember()) {
return;
}
final Button buttonAdd = (Button) view.findViewById(R.id.add_to_favpoint);
@@ -1418,58 +1401,41 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
box.setVisibility(View.GONE);
}
}
+ }
- private class PreviewMapTask extends AsyncTask<Void, Void, BitmapDrawable> {
- @Override
- protected BitmapDrawable doInBackground(Void... parameters) {
- try {
- // persistent preview from storage
- Bitmap image = decode(cache);
+ private Observable<BitmapDrawable> previewMap = Observable.create(new OnSubscribe<BitmapDrawable>() {
+ @Override
+ public void call(final Subscriber<? super BitmapDrawable> subscriber) {
+ try {
+ // persistent preview from storage
+ Bitmap image = StaticMapsProvider.getPreviewMap(cache);
- if (image == null) {
+ if (image == null) {
+ if (Settings.isStoreOfflineMaps()) {
StaticMapsProvider.storeCachePreviewMap(cache);
- image = decode(cache);
- if (image == null) {
- return null;
- }
+ image = StaticMapsProvider.getPreviewMap(cache);
}
-
- return ImageUtils.scaleBitmapToFitDisplay(image);
- } catch (final Exception e) {
- Log.w("CacheDetailActivity.PreviewMapTask", e);
- return null;
}
- }
- private Bitmap decode(final Geocache cache) {
- return StaticMapsProvider.getPreviewMap(cache.getGeocode());
- }
-
- @Override
- protected void onPostExecute(BitmapDrawable image) {
- if (image == null) {
- return;
- }
-
- try {
- final Bitmap bitmap = image.getBitmap();
- if (bitmap == null || bitmap.getWidth() <= 10) {
- return;
- }
-
- final ImageView imageView = (ImageView) view.findViewById(R.id.map_preview);
- imageView.setImageDrawable(image);
- view.findViewById(R.id.map_preview_box).setVisibility(View.VISIBLE);
- } catch (final Exception e) {
- Log.e("CacheDetailActivity.PreviewMapTask", e);
+ if (image != null) {
+ subscriber.onNext(ImageUtils.scaleBitmapToFitDisplay(image));
}
+ subscriber.onCompleted();
+ } catch (final Exception e) {
+ Log.w("CacheDetailActivity.previewMap", e);
+ subscriber.onError(e);
}
}
- }
+
+ });
protected class DescriptionViewCreator extends AbstractCachingPageViewCreator<ScrollView> {
@InjectView(R.id.personalnote) protected TextView personalNoteView;
+ @InjectView(R.id.shortdesc) protected IndexOutOfBoundsAvoidingTextView shortDescView;
+ @InjectView(R.id.longdesc) protected IndexOutOfBoundsAvoidingTextView longDescView;
+ @InjectView(R.id.show_description) protected Button showDesc;
+ @InjectView(R.id.loading) protected View loadingView;
@Override
public ScrollView getDispatchedView() {
@@ -1483,7 +1449,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
// cache short description
if (StringUtils.isNotBlank(cache.getShortDescription())) {
- new LoadDescriptionTask(cache.getShortDescription(), view.findViewById(R.id.shortdesc), null, null).execute();
+ loadDescription(cache.getShortDescription(), shortDescView, null);
}
// long description
@@ -1491,7 +1457,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
if (Settings.isAutoLoadDescription()) {
loadLongDescription();
} else {
- final Button showDesc = (Button) view.findViewById(R.id.show_description);
showDesc.setVisibility(View.VISIBLE);
showDesc.setOnClickListener(new View.OnClickListener() {
@Override
@@ -1605,12 +1570,23 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
private void loadLongDescription() {
- final Button showDesc = (Button) view.findViewById(R.id.show_description);
showDesc.setVisibility(View.GONE);
showDesc.setOnClickListener(null);
view.findViewById(R.id.loading).setVisibility(View.VISIBLE);
- new LoadDescriptionTask(cache.getDescription(), view.findViewById(R.id.longdesc), view.findViewById(R.id.loading), view.findViewById(R.id.shortdesc)).execute();
+ final String longDescription = cache.getDescription();
+ loadDescription(longDescription, longDescView, loadingView);
+
+ // Hide the short description, if it is contained somewhere at the start of the long description.
+ if (shortDescView != null) {
+ final String shortDescription = cache.getShortDescription();
+ if (StringUtils.isNotBlank(shortDescription)) {
+ final int index = longDescription.indexOf(shortDescription);
+ if (index >= 0 && index < 200) {
+ shortDescView.setVisibility(View.GONE);
+ }
+ }
+ }
}
private void warnPersonalNoteNeedsStoring() {
@@ -1641,148 +1617,118 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
- /**
- * Loads the description in background. <br />
- * <br />
- * Params:
- * <ol>
- * <li>description string (String)</li>
- * <li>target description view (TextView)</li>
- * <li>loading indicator view (View, may be null)</li>
- * </ol>
- */
- private class LoadDescriptionTask extends AsyncTask<Object, Void, Void> {
- private final View loadingIndicatorView;
- private final IndexOutOfBoundsAvoidingTextView descriptionView;
- private final String descriptionString;
- private Spanned description;
- private final View shortDescView;
+ /**
+ * Load the description in the background.
+ * @param descriptionString the HTML description as retrieved from the connector
+ * @param descriptionView the view to fill
+ * @param loadingIndicatorView the loading indicator view, will be hidden when completed
+ */
+ private void loadDescription(final String descriptionString, final IndexOutOfBoundsAvoidingTextView descriptionView, final View loadingIndicatorView) {
+ // The producer produces successives (without then with images) versions of the description.
+ final Observable<Spanned> producer = Observable.create(new OnSubscribe<Spanned>() {
+ @Override
+ public void call(final Subscriber<? super Spanned> subscriber) {
+ try {
+ // Fast preview: parse only HTML without loading any images
+ final HtmlImageCounter imageCounter = new HtmlImageCounter();
+ final UnknownTagsHandler unknownTagsHandler = new UnknownTagsHandler();
+ Spanned description = Html.fromHtml(descriptionString, imageCounter, unknownTagsHandler);
+ addWarning(unknownTagsHandler, description);
+ subscriber.onNext(description);
+
+ if (imageCounter.getImageCount() > 0) {
+ // Complete view: parse again with loading images - if necessary ! If there are any images causing problems the user can see at least the preview
+ description = Html.fromHtml(descriptionString, new HtmlImage(cache.getGeocode(), true, cache.getListId(), false), unknownTagsHandler);
+ addWarning(unknownTagsHandler, description);
+ subscriber.onNext(description);
+ }
- public LoadDescriptionTask(final String description, final View descriptionView, final View loadingIndicatorView, final View shortDescView) {
- assert descriptionView instanceof IndexOutOfBoundsAvoidingTextView;
- this.descriptionString = description;
- this.descriptionView = (IndexOutOfBoundsAvoidingTextView) descriptionView;
- this.loadingIndicatorView = loadingIndicatorView;
- this.shortDescView = shortDescView;
- }
+ subscriber.onCompleted();
+ } catch (final Exception e) {
+ Log.e("loadDescription", e);
+ subscriber.onError(e);
+ }
+ }
- @Override
- protected Void doInBackground(Object... params) {
- try {
- // Fast preview: parse only HTML without loading any images
- final HtmlImageCounter imageCounter = new HtmlImageCounter();
- final UnknownTagsHandler unknownTagsHandler = new UnknownTagsHandler();
- description = Html.fromHtml(descriptionString, imageCounter, unknownTagsHandler);
- publishProgress();
-
- boolean needsRefresh = false;
- if (imageCounter.getImageCount() > 0) {
- // Complete view: parse again with loading images - if necessary ! If there are any images causing problems the user can see at least the preview
- description = Html.fromHtml(descriptionString, new HtmlImage(cache.getGeocode(), true, cache.getListId(), false), unknownTagsHandler);
- needsRefresh = true;
- }
-
- // If description has an HTML construct which may be problematic to render, add a note at the end of the long description.
- // Technically, it may not be a table, but a pre, which has the same problems as a table, so the message is ok even though
- // sometimes technically incorrect.
- if (unknownTagsHandler.isProblematicDetected() && descriptionView != null) {
+ // If description has an HTML construct which may be problematic to render, add a note at the end of the long description.
+ // Technically, it may not be a table, but a pre, which has the same problems as a table, so the message is ok even though
+ // sometimes technically incorrect.
+ private void addWarning(final UnknownTagsHandler unknownTagsHandler, final Spanned description) {
+ if (unknownTagsHandler.isProblematicDetected()) {
final int startPos = description.length();
final IConnector connector = ConnectorFactory.getConnector(cache);
final Spanned tableNote = Html.fromHtml(res.getString(R.string.cache_description_table_note, "<a href=\"" + cache.getUrl() + "\">" + connector.getName() + "</a>"));
((Editable) description).append("\n\n").append(tableNote);
((Editable) description).setSpan(new StyleSpan(Typeface.ITALIC), startPos, description.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- needsRefresh = true;
- }
-
- if (needsRefresh) {
- publishProgress();
- }
- } catch (final Exception e) {
- Log.e("LoadDescriptionTask: ", e);
- }
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Void... values) {
- if (description == null) {
- showToast(res.getString(R.string.err_load_descr_failed));
- return;
- }
- if (StringUtils.isNotBlank(descriptionString)) {
- try {
- descriptionView.setText(description, TextView.BufferType.SPANNABLE);
- } catch (final Exception e) {
- // On 4.1, there is sometimes a crash on measuring the layout: https://code.google.com/p/android/issues/detail?id=35412
- Log.e("Android bug setting text: ", e);
- // remove the formatting by converting to a simple string
- descriptionView.setText(description.toString());
}
- descriptionView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
- fixTextColor(descriptionView, descriptionString);
- descriptionView.setVisibility(View.VISIBLE);
- registerForContextMenu(descriptionView);
-
- hideDuplicatedShortDescription();
}
- }
+ });
- /**
- * Hide the short description, if it is contained somewhere at the start of the long description.
- */
- private void hideDuplicatedShortDescription() {
- if (shortDescView != null) {
- final String shortDescription = cache.getShortDescription();
- if (StringUtils.isNotBlank(shortDescription)) {
- final int index = descriptionString.indexOf(shortDescription);
- if (index >= 0 && index < 200) {
- shortDescView.setVisibility(View.GONE);
+ AndroidObservable.fromActivity(this, producer.subscribeOn(Schedulers.io()))
+ .subscribe(new Observer<Spanned>() {
+ @Override
+ public void onCompleted() {
+ if (null != loadingIndicatorView) {
+ loadingIndicatorView.setVisibility(View.GONE);
+ }
}
- }
- }
- }
- @Override
- protected void onPostExecute(Void result) {
- if (null != loadingIndicatorView) {
- loadingIndicatorView.setVisibility(View.GONE);
- }
- }
+ @Override
+ public void onError(final Throwable throwable) {
+ showToast(res.getString(R.string.err_load_descr_failed));
+ }
- /**
- * Handle caches with black font color in dark skin and white font color in light skin
- * by changing background color of the view
- *
- * @param view
- * containing the text
- * @param text
- * to be checked
- */
- private void fixTextColor(final TextView view, final String text) {
- int backcolor;
- if (Settings.isLightSkin()) {
- backcolor = color.white;
-
- for (final Pattern pattern : LIGHT_COLOR_PATTERNS) {
- final MatcherWrapper matcher = new MatcherWrapper(pattern, text);
- if (matcher.find()) {
- view.setBackgroundResource(color.darker_gray);
- return;
+ @Override
+ public void onNext(final Spanned description) {
+ if (StringUtils.isNotBlank(descriptionString)) {
+ try {
+ descriptionView.setText(description, TextView.BufferType.SPANNABLE);
+ } catch (final Exception e) {
+ // On 4.1, there is sometimes a crash on measuring the layout: https://code.google.com/p/android/issues/detail?id=35412
+ Log.e("Android bug setting text: ", e);
+ // remove the formatting by converting to a simple string
+ descriptionView.setText(description.toString());
+ }
+ descriptionView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
+ fixTextColor(descriptionString);
+ descriptionView.setVisibility(View.VISIBLE);
+ registerForContextMenu(descriptionView);
+ }
}
- }
- } else {
- backcolor = color.black;
- for (final Pattern pattern : DARK_COLOR_PATTERNS) {
- final MatcherWrapper matcher = new MatcherWrapper(pattern, text);
- if (matcher.find()) {
- view.setBackgroundResource(color.darker_gray);
- return;
+ /**
+ * Handle caches with black font color in dark skin and white font color in light skin
+ * by changing background color of the view
+ *
+ * @param text
+ * to be checked
+ */
+ private void fixTextColor(final String text) {
+ int backcolor;
+ if (Settings.isLightSkin()) {
+ backcolor = color.white;
+
+ for (final Pattern pattern : LIGHT_COLOR_PATTERNS) {
+ final MatcherWrapper matcher = new MatcherWrapper(pattern, text);
+ if (matcher.find()) {
+ descriptionView.setBackgroundResource(color.darker_gray);
+ return;
+ }
+ }
+ } else {
+ backcolor = color.black;
+
+ for (final Pattern pattern : DARK_COLOR_PATTERNS) {
+ final MatcherWrapper matcher = new MatcherWrapper(pattern, text);
+ if (matcher.find()) {
+ descriptionView.setBackgroundResource(color.darker_gray);
+ return;
+ }
+ }
+ }
+ descriptionView.setBackgroundResource(backcolor);
}
- }
- }
- view.setBackgroundResource(backcolor);
- }
+ });
}
private class WaypointsViewCreator extends AbstractCachingPageViewCreator<ListView> {
@@ -2255,10 +2201,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return cache;
}
- public SearchResult getSearch() {
- return search;
- }
-
private static class StoreCacheHandler extends SimpleCancellableHandler {
public StoreCacheHandler(CacheDetailActivity activity, Progress progress) {
diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java
index cc8b178..fa84ac6 100644
--- a/main/src/cgeo/geocaching/CacheListActivity.java
+++ b/main/src/cgeo/geocaching/CacheListActivity.java
@@ -8,7 +8,7 @@ import cgeo.geocaching.activity.Progress;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cachelist.CacheListAppFactory;
import cgeo.geocaching.compatibility.Compatibility;
-import cgeo.geocaching.connector.gc.SearchHandler;
+import cgeo.geocaching.connector.gc.RecaptchaHandler;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -18,11 +18,13 @@ import cgeo.geocaching.files.GPXImporter;
import cgeo.geocaching.filter.FilterUserInterface;
import cgeo.geocaching.filter.IFilter;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.loaders.AbstractSearchLoader;
import cgeo.geocaching.loaders.AbstractSearchLoader.CacheListLoaderType;
import cgeo.geocaching.loaders.AddressGeocacheListLoader;
import cgeo.geocaching.loaders.CoordsGeocacheListLoader;
+import cgeo.geocaching.loaders.FinderGeocacheListLoader;
import cgeo.geocaching.loaders.HistoryGeocacheListLoader;
import cgeo.geocaching.loaders.KeywordGeocacheListLoader;
import cgeo.geocaching.loaders.NextPageGeocacheListLoader;
@@ -30,7 +32,6 @@ import cgeo.geocaching.loaders.OfflineGeocacheListLoader;
import cgeo.geocaching.loaders.OwnerGeocacheListLoader;
import cgeo.geocaching.loaders.PocketGeocacheListLoader;
import cgeo.geocaching.loaders.RemoveFromHistoryLoader;
-import cgeo.geocaching.loaders.FinderGeocacheListLoader;
import cgeo.geocaching.maps.CGeoMap;
import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.network.Network;
@@ -43,10 +44,10 @@ import cgeo.geocaching.ui.LoggingUI;
import cgeo.geocaching.ui.WeakReferenceHandler;
import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
+import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.DateUtils;
import cgeo.geocaching.utils.GeoDirHandler;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
import ch.boye.httpclientandroidlib.HttpResponse;
@@ -55,6 +56,8 @@ import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import rx.functions.Action1;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@@ -93,7 +96,11 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
private static final int MAX_LIST_ITEMS = 1000;
private static final int MSG_DONE = -1;
- private static final int MSG_CANCEL = -99;
+ private static final int MSG_SERVER_FAIL = -2;
+ private static final int MSG_NO_REGISTRATION = -3;
+ private static final int MSG_WAITING = 0;
+ private static final int MSG_LOADING = 1;
+ private static final int MSG_LOADED = 2;
private static final int REQUEST_CODE_IMPORT_GPX = 1;
@@ -111,8 +118,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
private int detailTotal = 0;
private int detailProgress = 0;
private long detailProgressTime = 0L;
- private LoadDetailsThread threadDetails = null;
- private LoadFromWebThread threadWeb = null;
private int listId = StoredList.TEMPORARY_LIST_ID; // Only meaningful for the OFFLINE type
private final GeoDirHandler geoDirHandler = new GeoDirHandler() {
@@ -267,10 +272,10 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
}
- private final Handler loadDetailsHandler = new Handler() {
+ private final CancellableHandler loadDetailsHandler = new CancellableHandler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
setAdapter();
if (msg.what > -1) {
@@ -287,10 +292,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
} else {
progress.setMessage(res.getString(R.string.caches_downloading) + " " + minutesRemaining + " " + res.getQuantityString(R.plurals.caches_eta_mins, minutesRemaining));
}
- } else if (msg.what == MSG_CANCEL) {
- if (threadDetails != null) {
- threadDetails.kill();
- }
} else {
if (search != null) {
final Set<Geocache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
@@ -304,13 +305,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
showProgress(false);
progress.dismiss();
-
- if (!isPaused()) {
- // If the current activity has been paused, then we do not want to fiddle with the
- // GPS and direction states. If the activity later gets resumed, its onResume()
- // function will take care of turning the GPS back on.
- startGeoAndDir();
- }
}
}
};
@@ -318,54 +312,53 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
/**
* TODO Possibly parts should be a Thread not a Handler
*/
- private final Handler downloadFromWebHandler = new Handler() {
+ private final CancellableHandler downloadFromWebHandler = new CancellableHandler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
setAdapter();
adapter.notifyDataSetChanged();
- if (msg.what == 0) { //no caches
- progress.setMessage(res.getString(R.string.web_import_waiting));
- } else if (msg.what == 1) { //cache downloading
- progress.setMessage(res.getString(R.string.web_downloading) + " " + msg.obj + '…');
- } else if (msg.what == 2) { //Cache downloaded
- progress.setMessage(res.getString(R.string.web_downloaded) + " " + msg.obj + '…');
- refreshCurrentList();
- } else if (msg.what == -2) {
- progress.dismiss();
- showToast(res.getString(R.string.sendToCgeo_download_fail));
- finish();
- } else if (msg.what == -3) {
- progress.dismiss();
- showToast(res.getString(R.string.sendToCgeo_no_registration));
- finish();
- } else if (msg.what == MSG_CANCEL) {
- if (threadWeb != null) {
- threadWeb.kill();
- }
- } else {
- adapter.setSelectMode(false);
-
- replaceCacheListFromSearch();
-
- progress.dismiss();
+ switch (msg.what) {
+ case MSG_WAITING: //no caches
+ progress.setMessage(res.getString(R.string.web_import_waiting));
+ break;
+ case MSG_LOADING: //cache downloading
+ progress.setMessage(res.getString(R.string.web_downloading) + " " + msg.obj + '…');
+ break;
+ case MSG_LOADED: //Cache downloaded
+ progress.setMessage(res.getString(R.string.web_downloaded) + " " + msg.obj + '…');
+ refreshCurrentList();
+ break;
+ case MSG_SERVER_FAIL:
+ progress.dismiss();
+ showToast(res.getString(R.string.sendToCgeo_download_fail));
+ finish();
+ break;
+ case MSG_NO_REGISTRATION:
+ progress.dismiss();
+ showToast(res.getString(R.string.sendToCgeo_no_registration));
+ finish();
+ break;
+ default: // MSG_DONE
+ adapter.setSelectMode(false);
+ replaceCacheListFromSearch();
+ progress.dismiss();
+ break;
}
}
};
- private final Handler clearOfflineLogsHandler = new Handler() {
+ private final CancellableHandler clearOfflineLogsHandler = new CancellableHandler() {
@Override
- public void handleMessage(Message msg) {
- if (msg.what != MSG_CANCEL) {
- adapter.setSelectMode(false);
+ public void handleRegularMessage(Message msg) {
+ adapter.setSelectMode(false);
- refreshCurrentList();
+ refreshCurrentList();
- replaceCacheListFromSearch();
+ replaceCacheListFromSearch();
- progress.dismiss();
- }
+ progress.dismiss();
}
};
@@ -402,7 +395,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
if (isInvokedFromAttachment()) {
type = CacheListType.OFFLINE;
if (coords == null) {
- coords = new Geopoint(0.0, 0.0);
+ coords = Geopoint.ZERO;
}
}
@@ -422,7 +415,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
prepareFilterBar();
- currentLoader = (AbstractSearchLoader) getSupportLoaderManager().initLoader(type.ordinal(), extras, this);
+ currentLoader = (AbstractSearchLoader) getSupportLoaderManager().initLoader(type.getLoaderId(), extras, this);
// init
if (CollectionUtils.isNotEmpty(cacheList)) {
@@ -458,10 +451,10 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
private void importGpxAttachement() {
- new StoredList.UserInterface(this).promptForListSelection(R.string.gpx_import_select_list_title, new RunnableWithArgument<Integer>() {
+ new StoredList.UserInterface(this).promptForListSelection(R.string.gpx_import_select_list_title, new Action1<Integer>() {
@Override
- public void run(Integer listId) {
+ public void call(Integer listId) {
new GPXImporter(CacheListActivity.this, listId, importGpxAttachementFinishedHandler).importGPX();
switchListById(listId);
}
@@ -472,12 +465,15 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
public void onResume() {
super.onResume();
- startGeoAndDir();
+ geoDirHandler.startGeo();
+ if (Settings.isLiveMap()) {
+ geoDirHandler.startDir();
+ }
adapter.setSelectMode(false);
setAdapterCurrentCoordinates(true);
- if (loadCachesHandler != null && search != null) {
+ if (search != null) {
replaceCacheListFromSearch();
loadCachesHandler.sendEmptyMessage(0);
}
@@ -503,8 +499,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
@Override
public void onPause() {
- removeGeoAndDir();
-
+ geoDirHandler.stopGeoAndDir();
super.onPause();
}
@@ -675,9 +670,9 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
return true;
case R.id.menu_sort:
final CacheComparator oldComparator = adapter.getCacheComparator();
- new ComparatorUserInterface(this).selectComparator(oldComparator, new RunnableWithArgument<CacheComparator>() {
+ new ComparatorUserInterface(this).selectComparator(oldComparator, new Action1<CacheComparator>() {
@Override
- public void run(CacheComparator selectedComparator) {
+ public void call(CacheComparator selectedComparator) {
// selecting the same sorting twice will toggle the order
if (selectedComparator != null && oldComparator != null && selectedComparator.getClass().equals(oldComparator.getClass())) {
adapter.toggleInverseSort();
@@ -728,7 +723,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
public void clearOfflineLogs() {
- progress.show(this, null, res.getString(R.string.caches_clear_offlinelogs_progress), true, clearOfflineLogsHandler.obtainMessage(MSG_CANCEL));
+ progress.show(this, null, res.getString(R.string.caches_clear_offlinelogs_progress), true, clearOfflineLogsHandler.cancelMessage());
new ClearOfflineLogsThread(clearOfflineLogsHandler).start();
}
@@ -737,13 +732,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
*/
@Override
public void showFilterMenu(final View view) {
- new FilterUserInterface(this).selectFilter(new RunnableWithArgument<IFilter>() {
+ new FilterUserInterface(this).selectFilter(new Action1<IFilter>() {
@Override
- public void run(IFilter selectedFilter) {
+ public void call(IFilter selectedFilter) {
if (selectedFilter != null) {
setFilter(selectedFilter);
- }
- else {
+ } else {
// clear filter
setFilter(null);
}
@@ -793,10 +787,10 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
private void moveCachesToOtherList() {
- new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new RunnableWithArgument<Integer>() {
+ new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new Action1<Integer>() {
@Override
- public void run(Integer newListId) {
+ public void call(Integer newListId) {
DataStore.moveToList(adapter.getCheckedOrAllCaches(), newListId);
adapter.setSelectMode(false);
@@ -850,10 +844,10 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
});
break;
case R.id.menu_move_to_list:
- new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new RunnableWithArgument<Integer>() {
+ new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new Action1<Integer>() {
@Override
- public void run(Integer newListId) {
+ public void call(Integer newListId) {
DataStore.moveToList(Collections.singletonList(cache), newListId);
adapter.setSelectMode(false);
refreshCurrentList();
@@ -960,7 +954,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
boolean enableMore = (type != CacheListType.OFFLINE && cacheList.size() < MAX_LIST_ITEMS);
if (enableMore && search != null) {
final int count = search.getTotalCountGC();
- enableMore = enableMore && count > 0 && cacheList.size() < count;
+ enableMore = count > 0 && cacheList.size() < count;
}
if (enableMore) {
@@ -973,17 +967,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
listFooter.setClickable(enableMore);
}
- private void startGeoAndDir() {
- geoDirHandler.startGeo();
- if (Settings.isLiveMap()) {
- geoDirHandler.startDir();
- }
- }
-
- private void removeGeoAndDir() {
- geoDirHandler.stopGeoAndDir();
- }
-
private void importGpx() {
GpxFileListActivity.startSubActivity(this, listId);
}
@@ -1002,7 +985,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
// provided to this method as a parameter. Pull that uri using "resultData.getData()"
if (data != null) {
final Uri uri = data.getData();
- new GPXImporter(CacheListActivity.this, listId, importGpxAttachementFinishedHandler).importGPX(uri, null, getDisplayName(uri));
+ new GPXImporter(this, listId, importGpxAttachementFinishedHandler).importGPX(uri, null, getDisplayName(uri));
}
}
@@ -1038,9 +1021,9 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
if (Settings.getChooseList() && type != CacheListType.OFFLINE) {
// let user select list to store cache in
new StoredList.UserInterface(this).promptForListSelection(R.string.list_title,
- new RunnableWithArgument<Integer>() {
+ new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
refreshStored(caches, selectedListId);
}
}, true, StoredList.TEMPORARY_LIST_ID, newListName);
@@ -1062,12 +1045,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
message = res.getString(R.string.caches_downloading) + " " + etaTime + " " + res.getQuantityString(R.plurals.caches_eta_mins, etaTime);
}
- progress.show(this, null, message, ProgressDialog.STYLE_HORIZONTAL, loadDetailsHandler.obtainMessage(MSG_CANCEL));
+ progress.show(this, null, message, ProgressDialog.STYLE_HORIZONTAL, loadDetailsHandler.cancelMessage());
progress.setMaxProgressAndReset(detailTotal);
detailProgressTime = System.currentTimeMillis();
- threadDetails = new LoadDetailsThread(loadDetailsHandler, caches, storeListId);
+ final LoadDetailsThread threadDetails = new LoadDetailsThread(loadDetailsHandler, caches, storeListId);
threadDetails.start();
}
@@ -1091,16 +1074,16 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
final Bundle b = new Bundle();
b.putStringArray(Intents.EXTRA_CACHELIST, geocodes);
- getSupportLoaderManager().initLoader(CacheListLoaderType.REMOVE_FROM_HISTORY.ordinal(), b, this);
+ getSupportLoaderManager().initLoader(CacheListLoaderType.REMOVE_FROM_HISTORY.getLoaderId(), b, this);
}
public void importWeb() {
detailProgress = 0;
showProgress(false);
- progress.show(this, null, res.getString(R.string.web_import_waiting), true, downloadFromWebHandler.obtainMessage(MSG_CANCEL));
+ progress.show(this, null, res.getString(R.string.web_import_waiting), true, downloadFromWebHandler.cancelMessage());
- threadWeb = new LoadFromWebThread(downloadFromWebHandler, listId);
+ final LoadFromWebThread threadWeb = new LoadFromWebThread(downloadFromWebHandler, listId);
threadWeb.start();
}
@@ -1127,26 +1110,20 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
private class LoadDetailsThread extends Thread {
- final private Handler handler;
+ final private CancellableHandler handler;
final private int listIdLD;
- private volatile boolean needToStop = false;
final private List<Geocache> caches;
- public LoadDetailsThread(Handler handlerIn, List<Geocache> caches, int listId) {
- handler = handlerIn;
+ public LoadDetailsThread(CancellableHandler handler, List<Geocache> caches, int listId) {
+ this.handler = handler;
this.caches = caches;
// in case of online lists, set the list id to the standard list
this.listIdLD = Math.max(listId, StoredList.STANDARD_LIST_ID);
}
- public void kill() {
- needToStop = true;
- }
-
@Override
public void run() {
- removeGeoAndDir();
// First refresh caches that do not yet have static maps to get them a chance to get a copy
// before the limit expires, unless we do not want to store offline maps.
final List<Geocache> allCaches = Settings.isStoreOfflineMaps() ?
@@ -1173,7 +1150,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
*/
private boolean refreshCache(Geocache cache) {
try {
- if (needToStop) {
+ if (handler.isCancelled()) {
throw new InterruptedException("Stopped storing process.");
}
detailProgress++;
@@ -1190,85 +1167,55 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
}
- private class LoadFromWebThread extends Thread {
+ private static class LoadFromWebThread extends Thread {
- final private Handler handler;
+ final private CancellableHandler handler;
final private int listIdLFW;
- private volatile boolean needToStop = false;
- public LoadFromWebThread(Handler handlerIn, int listId) {
- handler = handlerIn;
+ public LoadFromWebThread(CancellableHandler handler, int listId) {
+ this.handler = handler;
listIdLFW = StoredList.getConcreteList(listId);
}
- public void kill() {
- needToStop = true;
- }
-
@Override
public void run() {
+ final long startTime = System.currentTimeMillis();
- removeGeoAndDir();
-
- int delay = -1;
- int times = 0;
-
- int ret = MSG_DONE;
- while (!needToStop && times < 3 * 60 / 5) { // maximum: 3 minutes, every 5 seconds
- //download new code
- String deviceCode = Settings.getWebDeviceCode();
- if (deviceCode == null) {
- deviceCode = "";
- }
- final Parameters params = new Parameters("code", deviceCode);
+ final String deviceCode = StringUtils.defaultString(Settings.getWebDeviceCode());
+ final Parameters params = new Parameters("code", deviceCode);
+ while (!handler.isCancelled() && System.currentTimeMillis() - startTime < 3 * 60000) { // maximum: 3 minutes
+ // Download new code
final HttpResponse responseFromWeb = Network.getRequest("http://send2.cgeo.org/read.html", params);
if (responseFromWeb != null && responseFromWeb.getStatusLine().getStatusCode() == 200) {
final String response = Network.getResponseData(responseFromWeb);
if (response != null && response.length() > 2) {
- delay = 1;
- handler.sendMessage(handler.obtainMessage(1, response));
- yield();
+ handler.sendMessage(handler.obtainMessage(MSG_LOADING, response));
Geocache.storeCache(null, response, listIdLFW, false, null);
- handler.sendMessage(handler.obtainMessage(2, response));
- yield();
+ handler.sendMessage(handler.obtainMessage(MSG_LOADED, response));
} else if ("RG".equals(response)) {
//Server returned RG (registration) and this device no longer registered.
Settings.setWebNameCode(null, null);
- ret = -3;
- needToStop = true;
+ handler.sendEmptyMessage(MSG_NO_REGISTRATION);
+ handler.cancel();
break;
} else {
- delay = 0;
- handler.sendEmptyMessage(0);
- yield();
+ try {
+ sleep(5000); // Wait for 5s if no cache found
+ } catch (final InterruptedException e) {
+ }
+ handler.sendEmptyMessage(MSG_WAITING);
}
- }
- if (responseFromWeb == null || responseFromWeb.getStatusLine().getStatusCode() != 200) {
- ret = -2;
- needToStop = true;
+ } else {
+ handler.sendEmptyMessage(MSG_SERVER_FAIL);
+ handler.cancel();
break;
}
-
- try {
- yield();
- if (delay == 0) {
- sleep(5000); //No caches 5s
- times++;
- } else {
- sleep(500); //Cache was loaded 0.5s
- times = 0;
- }
- } catch (final InterruptedException e) {
- Log.e("CacheListActivity.LoadFromWebThread.sleep", e);
- }
}
- handler.sendEmptyMessage(ret);
-
- startGeoAndDir();
+ handler.sendEmptyMessage(MSG_DONE);
}
}
@@ -1283,9 +1230,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
@Override
protected Void doInBackgroundInternal(Geocache[] caches) {
- removeGeoAndDir();
DataStore.markDropped(Arrays.asList(caches));
- startGeoAndDir();
return null;
}
@@ -1328,7 +1273,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
showFooterLoadingCaches();
listFooter.setOnClickListener(null);
- getSupportLoaderManager().restartLoader(CacheListLoaderType.NEXT_PAGE.ordinal(), null, CacheListActivity.this);
+ getSupportLoaderManager().restartLoader(CacheListLoaderType.NEXT_PAGE.getLoaderId(), null, CacheListActivity.this);
}
}
@@ -1349,11 +1294,11 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
@NonNull
- private RunnableWithArgument<Integer> getListSwitchingRunnable() {
- return new RunnableWithArgument<Integer>() {
+ private Action1<Integer> getListSwitchingRunnable() {
+ return new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
switchListById(selectedListId);
}
};
@@ -1364,6 +1309,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
return;
}
+ if (id == PseudoList.HISTORY_LIST.id) {
+ CacheListActivity.startActivityHistory(this);
+ finish();
+ return;
+ }
+
final StoredList list = DataStore.getList(id);
if (list == null) {
return;
@@ -1378,7 +1329,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
showFooterLoadingCaches();
DataStore.moveToList(adapter.getCheckedCaches(), listId);
- currentLoader = (OfflineGeocacheListLoader) getSupportLoaderManager().initLoader(CacheListType.OFFLINE.ordinal(), new Bundle(), this);
+ currentLoader = (OfflineGeocacheListLoader) getSupportLoaderManager().initLoader(CacheListType.OFFLINE.getLoaderId(), new Bundle(), this);
currentLoader.reset();
((OfflineGeocacheListLoader) currentLoader).setListId(listId);
((OfflineGeocacheListLoader) currentLoader).setSearchCenter(coords);
@@ -1433,7 +1384,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
* @param view
* unused here but needed since this method is referenced from XML layout
*/
- public void goMap(View view) {
+ public void goMap(@SuppressWarnings("unused") View view) {
if (search == null || CollectionUtils.isEmpty(cacheList)) {
showToast(res.getString(R.string.warn_no_cache_coord));
@@ -1483,12 +1434,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
return true;
}
- public static void startActivityUserName(final Activity context, final String userName) {
+ public static void startActivityFinder(final Activity context, final String userName) {
if (!isValidUsername(context, userName)) {
return;
}
final Intent cachesIntent = new Intent(context, CacheListActivity.class);
- cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.USERNAME);
+ cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.FINDER);
cachesIntent.putExtra(Intents.EXTRA_USERNAME, userName);
context.startActivity(cachesIntent);
}
@@ -1606,6 +1557,9 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
} else {
final StoredList list = DataStore.getList(listId);
// list.id may be different if listId was not valid
+ if (list.id != listId) {
+ showToast(getString(R.string.list_not_available));
+ }
listId = list.id;
title = list.title;
}
@@ -1670,8 +1624,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
break;
case POCKET:
final String guid = extras.getString(Intents.EXTRA_POCKET_GUID);
- final String pocket_name = extras.getString(Intents.EXTRA_NAME);
- title = pocket_name;
+ title = extras.getString(Intents.EXTRA_NAME);
loader = new PocketGeocacheListLoader(app, guid);
break;
}
@@ -1680,7 +1633,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
showFooterLoadingCaches();
if (loader != null) {
- loader.setRecaptchaHandler(new SearchHandler(this, res, loader));
+ loader.setRecaptchaHandler(new RecaptchaHandler(this, loader));
}
return loader;
}
diff --git a/main/src/cgeo/geocaching/CacheMenuHandler.java b/main/src/cgeo/geocaching/CacheMenuHandler.java
index d0f1005..cfe9eeb 100644
--- a/main/src/cgeo/geocaching/CacheMenuHandler.java
+++ b/main/src/cgeo/geocaching/CacheMenuHandler.java
@@ -1,27 +1,17 @@
package cgeo.geocaching;
-import cgeo.calendar.ICalendar;
+import cgeo.calendar.CalendarAddon;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
-import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.AbstractUIFactory;
-import cgeo.geocaching.ui.dialog.Dialogs;
-import cgeo.geocaching.utils.ProcessUtils;
-
-import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
import android.view.Menu;
import android.view.MenuItem;
-import java.util.Date;
-
/**
- * Shared menu handling for all activities having menu items related to a cache.
- *
+ * Shared menu handling for all activities having menu items related to a cache. <br>
+ * TODO: replace by a fragment
+ *
*/
public class CacheMenuHandler extends AbstractUIFactory {
@@ -58,7 +48,7 @@ public class CacheMenuHandler extends AbstractUIFactory {
cache.shareCache(activity, res);
return true;
case R.id.menu_calendar:
- addToCalendarWithIntent(activity, cache);
+ CalendarAddon.addToCalendarWithIntent(activity, cache);
return true;
default:
return false;
@@ -84,39 +74,4 @@ public class CacheMenuHandler extends AbstractUIFactory {
activity.getMenuInflater().inflate(R.menu.cache_options, menu);
onPrepareOptionsMenu(menu, cache);
}
-
- private static void addToCalendarWithIntent(final Activity activity, final Geocache cache) {
- final boolean calendarAddOnAvailable = ProcessUtils.isIntentAvailable(ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST));
-
- if (calendarAddOnAvailable) {
- final Date hiddenDate = cache.getHiddenDate();
- final Parameters params = new Parameters(
- ICalendar.PARAM_NAME, cache.getName(),
- ICalendar.PARAM_NOTE, StringUtils.defaultString(cache.getPersonalNote()),
- ICalendar.PARAM_HIDDEN_DATE, hiddenDate != null ? String.valueOf(hiddenDate.getTime()) : StringUtils.EMPTY,
- ICalendar.PARAM_URL, StringUtils.defaultString(cache.getUrl()),
- ICalendar.PARAM_COORDS, cache.getCoords() == null ? "" : cache.getCoords().format(GeopointFormatter.Format.LAT_LON_DECMINUTE_RAW),
- ICalendar.PARAM_LOCATION, StringUtils.defaultString(cache.getLocation()),
- ICalendar.PARAM_SHORT_DESC, StringUtils.defaultString(cache.getShortDescription()),
- ICalendar.PARAM_START_TIME_MINUTES, StringUtils.defaultString(cache.guessEventTimeMinutes())
- );
-
- activity.startActivity(new Intent(ICalendar.INTENT,
- Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST + "?" + params.toString())));
- } else {
- // Inform user the calendar add-on is not installed and let them get it from Google Play
- Dialogs.confirmYesNo(activity, R.string.addon_missing_title, new StringBuilder(res.getString(R.string.helper_calendar_missing))
- .append(' ')
- .append(res.getString(R.string.addon_download_prompt))
- .toString(), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(ICalendar.CALENDAR_ADDON_URI));
- activity.startActivity(intent);
- }
- });
- }
- }
-
}
diff --git a/main/src/cgeo/geocaching/CachePopup.java b/main/src/cgeo/geocaching/CachePopup.java
index 9186497..c6c7c1c 100644
--- a/main/src/cgeo/geocaching/CachePopup.java
+++ b/main/src/cgeo/geocaching/CachePopup.java
@@ -9,9 +9,9 @@ import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.ui.CacheDetailsCreator;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.lang3.StringUtils;
+import rx.functions.Action1;
import android.content.Context;
import android.content.Intent;
@@ -110,9 +110,9 @@ public class CachePopup extends AbstractPopupActivity {
if (Settings.getChooseList()) {
// let user select list to store cache in
new StoredList.UserInterface(CachePopup.this).promptForListSelection(R.string.list_title,
- new RunnableWithArgument<Integer>() {
+ new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
storeCache(selectedListId);
}
}, true, StoredList.TEMPORARY_LIST_ID);
diff --git a/main/src/cgeo/geocaching/CgeoApplication.java b/main/src/cgeo/geocaching/CgeoApplication.java
index 2500d10..7bee97e 100644
--- a/main/src/cgeo/geocaching/CgeoApplication.java
+++ b/main/src/cgeo/geocaching/CgeoApplication.java
@@ -1,10 +1,10 @@
package cgeo.geocaching;
-import cgeo.geocaching.network.StatusUpdater;
import cgeo.geocaching.ui.dialog.Dialogs;
-import cgeo.geocaching.utils.IObserver;
import cgeo.geocaching.utils.Log;
+import rx.Observable;
+
import android.app.Activity;
import android.app.Application;
import android.app.ProgressDialog;
@@ -14,12 +14,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class CgeoApplication extends Application {
- private volatile GeoDataProvider geo;
- private volatile DirectionProvider dir;
+ private volatile Observable<IGeoData> geo;
+ private volatile Observable<Float> dir;
private boolean forceRelog = false; // c:geo needs to log into cache providers
public boolean showLoginToast = true; //login toast shown just once.
- private boolean liveMapHintShown = false; // livemap hint has been shown
- final private StatusUpdater statusUpdater = new StatusUpdater();
+ private boolean liveMapHintShownInThisSession = false; // livemap hint has been shown
private static CgeoApplication instance;
public CgeoApplication() {
@@ -35,26 +34,11 @@ public class CgeoApplication extends Application {
}
@Override
- public void onCreate() {
- new Thread(statusUpdater).start();
- }
-
- @Override
public void onLowMemory() {
Log.i("Cleaning applications cache.");
DataStore.removeAllFromCache();
}
- @Override
- public void onTerminate() {
- Log.d("Terminating c:geo…");
-
- DataStore.clean();
- DataStore.closeDb();
-
- super.onTerminate();
- }
-
/**
* Move the database to/from external cgdata in a new thread,
* showing a progress window
@@ -82,29 +66,11 @@ public class CgeoApplication extends Application {
}.start();
}
- /**
- * Register an observer to receive GeoData information.
- * <br/>
- * If there is a chance that no observers are registered before this
- * method is called, it is necessary to call it from a task implementing
- * a looper interface as the data provider will use listeners that
- * require a looper thread to run.
- *
- * @param observer a geodata observer
- */
- public void addGeoObserver(final IObserver<? super IGeoData> observer) {
- currentGeoObject().addObserver(observer);
- }
-
- public void deleteGeoObserver(final IObserver<? super IGeoData> observer) {
- currentGeoObject().deleteObserver(observer);
- }
-
- private GeoDataProvider currentGeoObject() {
+ public Observable<IGeoData> currentGeoObject() {
if (geo == null) {
synchronized(this) {
if (geo == null) {
- geo = new GeoDataProvider(this);
+ geo = GeoDataProvider.create(this);
}
}
}
@@ -112,22 +78,14 @@ public class CgeoApplication extends Application {
}
public IGeoData currentGeo() {
- return currentGeoObject().getMemory();
+ return currentGeoObject().first().toBlockingObservable().single();
}
- public void addDirectionObserver(final IObserver<? super Float> observer) {
- currentDirObject().addObserver(observer);
- }
-
- public void deleteDirectionObserver(final IObserver<? super Float> observer) {
- currentDirObject().deleteObserver(observer);
- }
-
- private DirectionProvider currentDirObject() {
+ public Observable<Float> currentDirObject() {
if (dir == null) {
synchronized(this) {
if (dir == null) {
- dir = new DirectionProvider(this);
+ dir = DirectionProvider.create(this);
}
}
}
@@ -135,19 +93,15 @@ public class CgeoApplication extends Application {
}
public Float currentDirection() {
- return currentDirObject().getMemory();
- }
-
- public StatusUpdater getStatusUpdater() {
- return statusUpdater;
+ return currentDirObject().first().toBlockingObservable().single();
}
- public boolean isLiveMapHintShown() {
- return liveMapHintShown;
+ public boolean isLiveMapHintShownInThisSession() {
+ return liveMapHintShownInThisSession;
}
- public void setLiveMapHintShown() {
- liveMapHintShown = true;
+ public void setLiveMapHintShownInThisSession() {
+ liveMapHintShownInThisSession = true;
}
/**
diff --git a/main/src/cgeo/geocaching/CompassActivity.java b/main/src/cgeo/geocaching/CompassActivity.java
index 8955afd..6fc2de1 100644
--- a/main/src/cgeo/geocaching/CompassActivity.java
+++ b/main/src/cgeo/geocaching/CompassActivity.java
@@ -150,12 +150,13 @@ public class CompassActivity extends AbstractActivity {
final CgeoApplication app = CgeoApplication.getInstance();
final IGeoData geo = app.currentGeo();
if (geo != null) {
- geoDirHandler.update(geo);
+ geoDirHandler.updateGeoData(geo);
}
final Float dir = app.currentDirection();
if (dir != null) {
- geoDirHandler.update(dir);
+ geoDirHandler.updateDirection(dir);
}
+
}
@Override
diff --git a/main/src/cgeo/geocaching/CreateShortcutActivity.java b/main/src/cgeo/geocaching/CreateShortcutActivity.java
index 7b91ba1..b6ea4f6 100644
--- a/main/src/cgeo/geocaching/CreateShortcutActivity.java
+++ b/main/src/cgeo/geocaching/CreateShortcutActivity.java
@@ -1,8 +1,10 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.list.StoredList;
-import cgeo.geocaching.utils.RunnableWithArgument;
+
+import rx.functions.Action1;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
@@ -21,17 +23,17 @@ public class CreateShortcutActivity extends AbstractActivity {
}
private void promptForShortcut() {
- new StoredList.UserInterface(this).promptForListSelection(R.string.create_shortcut, new RunnableWithArgument<Integer>() {
+ new StoredList.UserInterface(this).promptForListSelection(R.string.create_shortcut, new Action1<Integer>() {
@Override
- public void run(final Integer listId) {
+ public void call(final Integer listId) {
final Intent shortcut = createShortcut(listId.intValue());
setResult(RESULT_OK, shortcut);
// finish activity to return the shortcut
finish();
}
- });
+ }, false, PseudoList.HISTORY_LIST.id);
}
protected Intent createShortcut(int listId) {
diff --git a/main/src/cgeo/geocaching/DataStore.java b/main/src/cgeo/geocaching/DataStore.java
index 6da1af8..5cc77dc 100644
--- a/main/src/cgeo/geocaching/DataStore.java
+++ b/main/src/cgeo/geocaching/DataStore.java
@@ -25,17 +25,20 @@ import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils;
+import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
+import android.provider.BaseColumns;
import java.io.File;
import java.io.FilenameFilter;
@@ -811,12 +814,19 @@ public class DataStore {
/**
* Remove obsolete cache directories in c:geo private storage.
+ */
+ public static void removeObsoleteCacheDirectories() {
+ removeObsoleteCacheDirectories(database);
+ }
+
+ /**
+ * Remove obsolete cache directories in c:geo private storage.
*
* @param db
* the read-write database to use
*/
private static void removeObsoleteCacheDirectories(final SQLiteDatabase db) {
- final Pattern oldFilePattern = Pattern.compile("^[GC|TB|O][A-Z0-9]{4,7}$");
+ final Pattern oldFilePattern = Pattern.compile("^[GC|TB|EC|GK|O][A-Z0-9]{4,7}$");
final SQLiteStatement select = db.compileStatement("select count(*) from " + dbTableCaches + " where geocode = ?");
final File[] files = LocalStorage.getStorage().listFiles();
final ArrayList<File> toRemove = new ArrayList<File>(files.length);
@@ -868,28 +878,6 @@ public class DataStore {
db.execSQL("drop table if exists " + dbTableTrackables);
}
- public static String[] getRecentGeocodesForSearch() {
- init();
-
- try {
- long timestamp = System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED;
- final Cursor cursor = database.query(
- dbTableCaches,
- new String[]{"geocode"},
- "(detailed = 1 and detailedupdate > ?) or reason > 0",
- new String[]{Long.toString(timestamp)},
- null,
- null,
- "detailedupdate desc",
- "100");
-
- return getFirstColumn(cursor);
- } catch (final Exception e) {
- Log.e("DataStore.allDetailedThere", e);
- return new String[0];
- }
- }
-
public static boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) {
init();
@@ -2302,11 +2290,6 @@ public class DataStore {
return new SearchResult(geocodes);
}
- /** delete caches from the DB store 3 days or more before */
- public static void clean() {
- clean(false);
- }
-
/**
* Remove caches with listId = 0
*
@@ -2355,6 +2338,8 @@ public class DataStore {
cursor.close();
+ geocodes = exceptCachesWithOfflineLog(geocodes);
+
if (!geocodes.isEmpty()) {
Log.d("Database clean: removing " + geocodes.size() + " geocaches from listId=0");
removeCaches(geocodes, LoadFlags.REMOVE_ALL);
@@ -2367,6 +2352,33 @@ public class DataStore {
databaseCleaned = true;
}
+ /**
+ * remove all geocodes from the given list of geocodes where an offline log exists
+ *
+ * @param geocodes
+ * @return
+ */
+ private static Set<String> exceptCachesWithOfflineLog(Set<String> geocodes) {
+ if (geocodes.isEmpty()) {
+ return geocodes;
+ }
+
+ init();
+ final Cursor cursor = database.query(
+ dbTableLogsOffline,
+ new String[] { "geocode" },
+ null,
+ null,
+ null,
+ null,
+ null);
+
+ final List<String> geocodesWithOfflineLog = Arrays.asList(getFirstColumn(cursor));
+
+ geocodes.removeAll(geocodesWithOfflineLog);
+ return geocodes;
+ }
+
public static void removeAllFromCache() {
// clean up CacheCache
cacheCache.removeAllFromCache();
@@ -2897,21 +2909,6 @@ public class DataStore {
return waypoints;
}
- public static String[] getTrackableCodes() {
- init();
-
- final Cursor cursor = database.query(
- dbTableTrackables,
- new String[] { "tbcode" },
- null,
- null,
- null,
- null,
- "updated DESC",
- "100");
- return getFirstColumn(cursor);
- }
-
/**
* Extract the first column of the cursor rows and close the cursor.
*
@@ -3098,4 +3095,103 @@ public class DataStore {
return missingFromSearch;
}
+ public static Cursor findSuggestions(final String searchTerm) {
+ // require 3 characters, otherwise there are to many results
+ if (StringUtils.length(searchTerm) < 3) {
+ return null;
+ }
+ init();
+ final MatrixCursor resultCursor = new MatrixCursor(new String[] {
+ BaseColumns._ID,
+ SearchManager.SUGGEST_COLUMN_TEXT_1,
+ SearchManager.SUGGEST_COLUMN_TEXT_2,
+ SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+ SearchManager.SUGGEST_COLUMN_QUERY
+ });
+ try {
+ final String selectionArg = getSuggestionArgument(searchTerm);
+ findCaches(resultCursor, selectionArg);
+ findTrackables(resultCursor, selectionArg);
+ } catch (final Exception e) {
+ Log.e("DataStore.loadBatchOfStoredGeocodes", e);
+ }
+ return resultCursor;
+ }
+
+ private static void findCaches(final MatrixCursor resultCursor, final String selectionArg) {
+ Cursor cursor = database.query(
+ dbTableCaches,
+ new String[] { "geocode", "name" },
+ "geocode IS NOT NULL AND geocode != '' AND (geocode LIKE ? OR name LIKE ? OR owner LIKE ?)",
+ new String[] { selectionArg, selectionArg, selectionArg },
+ null,
+ null,
+ "name");
+ while (cursor.moveToNext()) {
+ final String geocode = cursor.getString(0);
+ resultCursor.addRow(new String[] {
+ String.valueOf(resultCursor.getCount()),
+ cursor.getString(1),
+ geocode,
+ Intents.ACTION_GEOCACHE,
+ geocode
+ });
+ }
+ cursor.close();
+ }
+
+ private static String getSuggestionArgument(String input) {
+ return "%" + StringUtils.trim(input) + "%";
+ }
+
+ private static void findTrackables(final MatrixCursor resultCursor, final String selectionArg) {
+ Cursor cursor = database.query(
+ dbTableTrackables,
+ new String[] { "tbcode", "title" },
+ "tbcode IS NOT NULL AND tbcode != '' AND (tbcode LIKE ? OR title LIKE ?)",
+ new String[] { selectionArg, selectionArg },
+ null,
+ null,
+ "title");
+ while (cursor.moveToNext()) {
+ final String tbcode = cursor.getString(0);
+ resultCursor.addRow(new String[] {
+ String.valueOf(resultCursor.getCount()),
+ cursor.getString(1),
+ tbcode,
+ Intents.ACTION_TRACKABLE,
+ tbcode
+ });
+ }
+ cursor.close();
+ }
+
+ public static String[] getSuggestions(final String table, final String column, final String input) {
+ Cursor cursor = database.rawQuery("SELECT DISTINCT " + column
+ + " FROM " + table
+ + " WHERE " + column + " LIKE ?"
+ + " ORDER BY " + column + " COLLATE NOCASE ASC;", new String[] { getSuggestionArgument(input) });
+ return getFirstColumn(cursor);
+ }
+
+ public static String[] getSuggestionsOwnerName(String input) {
+ return getSuggestions(dbTableCaches, "owner", input);
+ }
+
+ public static String[] getSuggestionsTrackableCode(String input) {
+ return getSuggestions(dbTableTrackables, "tbcode", input);
+ }
+
+ public static String[] getSuggestionsFinderName(String input) {
+ return getSuggestions(dbTableLogs, "author", input);
+ }
+
+ public static String[] getSuggestionsGeocode(String input) {
+ return getSuggestions(dbTableCaches, "geocode", input);
+ }
+
+ public static String[] getSuggestionsKeyword(String input) {
+ return getSuggestions(dbTableCaches, "name", input);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/DirectionProvider.java b/main/src/cgeo/geocaching/DirectionProvider.java
index ae58fed..49a433e 100644
--- a/main/src/cgeo/geocaching/DirectionProvider.java
+++ b/main/src/cgeo/geocaching/DirectionProvider.java
@@ -1,9 +1,15 @@
package cgeo.geocaching;
import cgeo.geocaching.compatibility.Compatibility;
-import cgeo.geocaching.utils.MemorySubject;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.Subscription;
+import rx.observables.ConnectableObservable;
+import rx.subjects.BehaviorSubject;
+import rx.subscriptions.Subscriptions;
+import rx.functions.Action0;
import android.app.Activity;
import android.content.Context;
@@ -12,58 +18,61 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-public class DirectionProvider extends MemorySubject<Float> implements SensorEventListener {
+public class DirectionProvider implements OnSubscribe<Float> {
private final SensorManager sensorManager;
+ private final BehaviorSubject<Float> subject = BehaviorSubject.create(0.0f);
- // Previous values signaled to observers to avoid re-sending the same value when the
- // device doesn't change orientation. The orientation is usually given with a 1 degree
- // precision by Android, so it is not uncommon to obtain exactly the same value several
- // times.
- private float previous = -1;
-
- public DirectionProvider(final Context context) {
- sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
-
+ static public Observable<Float> create(final Context context) {
+ return new DirectionProvider((SensorManager) context.getSystemService(Context.SENSOR_SERVICE)).worker.refCount();
}
- @Override
- protected void onFirstObserver() {
- @SuppressWarnings("deprecation")
- // This will be removed when using a new location service. Until then, it is okay to be used.
- final Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
- sensorManager.registerListener(this, defaultSensor, SensorManager.SENSOR_DELAY_NORMAL);
+ private DirectionProvider(final SensorManager sensorManager) {
+ this.sensorManager = sensorManager;
}
@Override
- protected void onLastObserver() {
- sensorManager.unregisterListener(this);
+ public void call(final Subscriber<? super Float> subscriber) {
+ subject.distinctUntilChanged().subscribe(subscriber);
}
- @Override
- public void onAccuracyChanged(final Sensor sensor, int accuracy) {
- /*
- * There is a bug in Android, which apparently causes this method to be called every
- * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging
- * this event leads to the log being flooded with multiple entries _per second_,
- * which I experienced when running cgeo in a building (with GPS and network being
- * unreliable).
- *
- * See for example https://code.google.com/p/android/issues/detail?id=14792
- */
+ private final ConnectableObservable<Float> worker = new ConnectableObservable<Float>(this) {
+ @Override
+ public Subscription connect() {
+ @SuppressWarnings("deprecation")
+ // This will be removed when using a new location service. Until then, it is okay to be used.
+ final Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
+ final SensorEventListener listener = new SensorEventListener() {
+ @Override
+ public void onSensorChanged(final SensorEvent event) {
+ subject.onNext(event.values[0]);
+ }
- //Log.i(Settings.tag, "Compass' accuracy is low (" + accuracy + ")");
- }
+ @Override
+ public void onAccuracyChanged(final Sensor sensor, final int accuracy) {
+ /*
+ * There is a bug in Android, which apparently causes this method to be called every
+ * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging
+ * this event leads to the log being flooded with multiple entries _per second_,
+ * which I experienced when running cgeo in a building (with GPS and network being
+ * unreliable).
+ *
+ * See for example https://code.google.com/p/android/issues/detail?id=14792
+ */
- @Override
- @SuppressFBWarnings("FE_FLOATING_POINT_EQUALITY")
- public void onSensorChanged(final SensorEvent event) {
- final float direction = event.values[0];
- if (direction != previous) {
- notifyObservers(direction);
- previous = direction;
+ //Log.i(Settings.tag, "Compass' accuracy is low (" + accuracy + ")");
+ }
+ };
+
+ sensorManager.registerListener(listener, defaultSensor, SensorManager.SENSOR_DELAY_NORMAL);
+ return Subscriptions.create(new Action0() {
+ @Override
+ public void call() {
+ sensorManager.unregisterListener(listener);
+ }
+ });
}
- }
+ };
/**
* Take the phone rotation (through a given activity) in account and adjust the direction.
@@ -72,6 +81,7 @@ public class DirectionProvider extends MemorySubject<Float> implements SensorEve
* @param direction the unadjusted direction in degrees, in the [0, 360[ range
* @return the adjusted direction in degrees, in the [0, 360[ range
*/
+
public static float getDirectionNow(final Activity activity, final float direction) {
return Compatibility.getDirectionNow(direction, activity);
}
diff --git a/main/src/cgeo/geocaching/EditWaypointActivity.java b/main/src/cgeo/geocaching/EditWaypointActivity.java
index 6d0f822..9010d3a 100644
--- a/main/src/cgeo/geocaching/EditWaypointActivity.java
+++ b/main/src/cgeo/geocaching/EditWaypointActivity.java
@@ -17,10 +17,10 @@ import cgeo.geocaching.utils.GeoDirHandler;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.TextUtils;
-import com.googlecode.androidannotations.annotations.EActivity;
-import com.googlecode.androidannotations.annotations.Extra;
-import com.googlecode.androidannotations.annotations.InstanceState;
-import com.googlecode.androidannotations.annotations.ViewById;
+import org.androidannotations.annotations.EActivity;
+import org.androidannotations.annotations.Extra;
+import org.androidannotations.annotations.InstanceState;
+import org.androidannotations.annotations.ViewById;
import org.apache.commons.lang3.StringUtils;
@@ -110,12 +110,14 @@ public class EditWaypointActivity extends AbstractActivity {
buttonLon.setText(waypoint.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE));
}
waypointName.setText(Html.fromHtml(StringUtils.trimToEmpty(waypoint.getName())).toString());
+ Dialogs.moveCursorToEnd(waypointName);
if (TextUtils.containsHtml(waypoint.getNote())) {
note.setText(Html.fromHtml(StringUtils.trimToEmpty(waypoint.getNote())).toString());
}
else {
note.setText(StringUtils.trimToEmpty(waypoint.getNote()));
}
+ Dialogs.moveCursorToEnd(note);
}
final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_ONLY);
setCoordsModificationVisibility(ConnectorFactory.getConnector(geocode), cache);
diff --git a/main/src/cgeo/geocaching/GeoDataProvider.java b/main/src/cgeo/geocaching/GeoDataProvider.java
index 73aefce..e18f735 100644
--- a/main/src/cgeo/geocaching/GeoDataProvider.java
+++ b/main/src/cgeo/geocaching/GeoDataProvider.java
@@ -3,9 +3,16 @@ package cgeo.geocaching;
import cgeo.geocaching.enumerations.LocationProviderType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.MemorySubject;
import org.apache.commons.lang3.StringUtils;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.Subscription;
+import rx.observables.ConnectableObservable;
+import rx.subjects.BehaviorSubject;
+import rx.subscriptions.Subscriptions;
+import rx.functions.Action0;
import android.content.Context;
import android.location.GpsSatellite;
@@ -15,22 +22,14 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provide information about the user location. This class should be instantiated only once per application.
- */
-class GeoDataProvider extends MemorySubject<IGeoData> {
+class GeoDataProvider implements OnSubscribe<IGeoData> {
private static final String LAST_LOCATION_PSEUDO_PROVIDER = "last";
private final LocationManager geoManager;
- private final GpsStatus.Listener gpsStatusListener = new GpsStatusListener();
private final LocationData gpsLocation = new LocationData();
private final LocationData netLocation = new LocationData();
- private final Listener networkListener = new Listener(LocationManager.NETWORK_PROVIDER, netLocation);
- private final Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation);
- private final Unregisterer unregisterer = new Unregisterer();
+ private final BehaviorSubject<IGeoData> subject;
+
public boolean gpsEnabled = false;
public int satellitesVisible = 0;
public int satellitesFixed = 0;
@@ -111,51 +110,6 @@ class GeoDataProvider extends MemorySubject<IGeoData> {
}
}
- private class Unregisterer extends Thread {
-
- private boolean unregisterRequested = false;
- private final ArrayBlockingQueue<Boolean> queue = new ArrayBlockingQueue<Boolean>(1);
-
- public void cancelUnregister() {
- try {
- queue.put(false);
- } catch (final InterruptedException e) {
- // Do nothing
- }
- }
-
- public void lateUnregister() {
- try {
- queue.put(true);
- } catch (final InterruptedException e) {
- // Do nothing
- }
- }
-
- @Override
- public void run() {
- try {
- while (true) {
- if (unregisterRequested) {
- final Boolean element = queue.poll(2500, TimeUnit.MILLISECONDS);
- if (element == null) {
- // Timeout
- unregisterListeners();
- unregisterRequested = false;
- } else {
- unregisterRequested = element;
- }
- } else {
- unregisterRequested = queue.take();
- }
- }
- } catch (final InterruptedException e) {
- // Do nothing
- }
- }
-
- }
-
/**
* Build a new geo data provider object.
* <p/>
@@ -164,10 +118,50 @@ class GeoDataProvider extends MemorySubject<IGeoData> {
*
* @param context the context used to retrieve the system services
*/
- GeoDataProvider(final Context context) {
+ protected GeoDataProvider(final Context context) {
geoManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
- unregisterer.start();
+ subject = BehaviorSubject.create(findInitialLocation());
+ }
+
+ public static Observable<IGeoData> create(final Context context) {
+ final GeoDataProvider provider = new GeoDataProvider(context);
+ return provider.worker.refCount();
+ }
+ @Override
+ public void call(final Subscriber<? super IGeoData> subscriber) {
+ subject.subscribe(subscriber);
+ }
+
+ final ConnectableObservable<IGeoData> worker = new ConnectableObservable<IGeoData>(this) {
+ @Override
+ public Subscription connect() {
+ final GpsStatus.Listener gpsStatusListener = new GpsStatusListener();
+ geoManager.addGpsStatusListener(gpsStatusListener);
+
+ final Listener networkListener = new Listener(LocationManager.NETWORK_PROVIDER, netLocation);
+ final Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation);
+
+ for (final Listener listener : new Listener[] { networkListener, gpsListener }) {
+ try {
+ geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
+ } catch (final Exception e) {
+ Log.w("There is no location provider " + listener.locationProvider);
+ }
+ }
+
+ return Subscriptions.create(new Action0() {
+ @Override
+ public void call() {
+ geoManager.removeUpdates(networkListener);
+ geoManager.removeUpdates(gpsListener);
+ geoManager.removeGpsStatusListener(gpsStatusListener);
+ }
+ });
+ }
+ };
+
+ private IGeoData findInitialLocation() {
final Location initialLocation = new Location(LAST_LOCATION_PSEUDO_PROVIDER);
try {
// Try to find a sensible initial location from the last locations known to Android.
@@ -195,45 +189,13 @@ class GeoDataProvider extends MemorySubject<IGeoData> {
}
// Start with an historical GeoData just in case someone queries it before we get
// a chance to get any information.
- notifyObservers(new GeoData(initialLocation, false, 0, 0));
+ return new GeoData(initialLocation, false, 0, 0);
}
private static void copyCoords(final Location target, final Location source) {
target.setLatitude(source.getLatitude());
target.setLongitude(source.getLongitude());
}
- private void registerListeners() {
- geoManager.addGpsStatusListener(gpsStatusListener);
-
- for (final Listener listener : new Listener[] { networkListener, gpsListener }) {
- try {
- geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
- } catch (final Exception e) {
- Log.w("There is no location provider " + listener.locationProvider);
- }
- }
- }
-
- private synchronized void unregisterListeners() {
- // This method must be synchronized because it will be called asynchronously from the Unregisterer thread.
- // We check that no observers have been re-added to prevent a race condition.
- if (sizeObservers() == 0) {
- geoManager.removeUpdates(networkListener);
- geoManager.removeUpdates(gpsListener);
- geoManager.removeGpsStatusListener(gpsStatusListener);
- }
- }
-
- @Override
- protected void onFirstObserver() {
- unregisterer.cancelUnregister();
- registerListeners();
- }
-
- @Override
- protected void onLastObserver() {
- unregisterer.lateUnregister();
- }
private class Listener implements LocationListener {
private final String locationProvider;
@@ -336,7 +298,7 @@ class GeoDataProvider extends MemorySubject<IGeoData> {
// We do not necessarily get signalled when satellites go to 0/0.
final int visible = gpsLocation.isRecent() ? satellitesVisible : 0;
final IGeoData current = new GeoData(locationData.location, gpsEnabled, visible, satellitesFixed);
- notifyObservers(current);
+ subject.onNext(current);
}
}
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index 156c4b6..bac4600 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -165,7 +165,7 @@ public class Geocache implements ICache, IWaypoint {
*
* @param gpxParser
*/
- public Geocache(GPXParser gpxParser) {
+ public Geocache(@SuppressWarnings("unused") GPXParser gpxParser) {
setReliableLatLon(true);
setAttributes(Collections.<String> emptyList());
setWaypoints(Collections.<Waypoint> emptyList(), false);
@@ -370,6 +370,7 @@ public class Geocache implements ICache, IWaypoint {
* the other cache to compare this one to
* @return true if both caches have the same content
*/
+ @SuppressWarnings("deprecation")
@SuppressFBWarnings("FE_FLOATING_POINT_EQUALITY")
private boolean isEqualTo(final Geocache other) {
return detailed == other.detailed &&
@@ -438,22 +439,6 @@ public class Geocache implements ICache, IWaypoint {
return hidden.compareTo(cal.getTime()) >= 0;
}
- /**
- * Checks if a page contains the guid of a cache
- *
- * @param page
- * the page to search in, may be null
- * @return true if the page contains the guid of the cache, false otherwise
- */
- public boolean isGuidContainedInPage(final String page) {
- if (StringUtils.isBlank(page) || StringUtils.isBlank(guid)) {
- return false;
- }
- final Boolean found = Pattern.compile(guid, Pattern.CASE_INSENSITIVE).matcher(page).find();
- Log.i("Geocache.isGuidContainedInPage: guid '" + guid + "' " + (found ? "" : "not ") + "found");
- return found;
- }
-
public boolean isEventCache() {
return cacheType.getValue().isEvent();
}
@@ -817,13 +802,7 @@ public class Geocache implements ICache, IWaypoint {
}
public boolean showSize() {
- if (size == CacheSize.NOT_CHOSEN) {
- return false;
- }
- if (isEventCache() || isVirtual()) {
- return false;
- }
- return true;
+ return !(size == CacheSize.NOT_CHOSEN || isEventCache() || isVirtual());
}
public long getUpdated() {
@@ -1373,17 +1352,6 @@ public class Geocache implements ICache, IWaypoint {
}
/**
- * Retrieve a given waypoint.
- *
- * @param index
- * the index of the waypoint
- * @return waypoint or <code>null</code> if index is out of range
- */
- public Waypoint getWaypoint(final int index) {
- return index >= 0 && index < waypoints.size() ? waypoints.get(index) : null;
- }
-
- /**
* Lookup a waypoint by its id.
*
* @param id
@@ -1660,6 +1628,8 @@ public class Geocache implements ICache, IWaypoint {
StaticMapsProvider.downloadMaps(cache);
+ imgGetter.waitForBackgroundLoading(handler);
+
if (handler != null) {
handler.sendMessage(Message.obtain());
}
@@ -1719,8 +1689,9 @@ public class Geocache implements ICache, IWaypoint {
patterns.add(Pattern.compile("\\b(\\d{1,2})(?:\\.00)?\\s+" + Pattern.quote(hourLocalized), Pattern.CASE_INSENSITIVE));
}
+ final String searchText = getShortDescription() + ' ' + getDescription();
for (Pattern pattern : patterns) {
- final MatcherWrapper matcher = new MatcherWrapper(pattern, getDescription());
+ final MatcherWrapper matcher = new MatcherWrapper(pattern, searchText);
while (matcher.find()) {
try {
final int hours = Integer.parseInt(matcher.group(1));
@@ -1831,4 +1802,8 @@ public class Geocache implements ICache, IWaypoint {
return 0;
}
+ public boolean applyDistanceRule() {
+ return (getType().applyDistanceRule() || hasUserModifiedCoords()) && getConnector() == GCConnector.getInstance();
+ }
+
}
diff --git a/main/src/cgeo/geocaching/ImageSelectActivity.java b/main/src/cgeo/geocaching/ImageSelectActivity.java
index 12d1e84..766149c 100644
--- a/main/src/cgeo/geocaching/ImageSelectActivity.java
+++ b/main/src/cgeo/geocaching/ImageSelectActivity.java
@@ -6,6 +6,7 @@ import butterknife.InjectView;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.ImageUtils;
import cgeo.geocaching.utils.Log;
@@ -111,10 +112,12 @@ public class ImageSelectActivity extends AbstractActivity {
if (StringUtils.isNotBlank(imageCaption)) {
captionView.setText(imageCaption);
+ Dialogs.moveCursorToEnd(captionView);
}
if (StringUtils.isNotBlank(imageDescription)) {
descriptionView.setText(imageDescription);
+ Dialogs.moveCursorToEnd(captionView);
}
scaleView.setSelection(scaleChoiceIndex);
diff --git a/main/src/cgeo/geocaching/ImagesActivity.java b/main/src/cgeo/geocaching/ImagesActivity.java
index 29bc8c7..3da1ade 100644
--- a/main/src/cgeo/geocaching/ImagesActivity.java
+++ b/main/src/cgeo/geocaching/ImagesActivity.java
@@ -6,6 +6,7 @@ import cgeo.geocaching.ui.ImagesList;
import cgeo.geocaching.ui.ImagesList.ImageType;
import org.apache.commons.collections4.CollectionUtils;
+import rx.Subscription;
import android.content.Context;
import android.content.Intent;
@@ -22,8 +23,9 @@ public class ImagesActivity extends AbstractActivity {
private boolean offline;
private ArrayList<Image> imageNames;
- private ImagesList imagesList;
private ImageType imgType = ImageType.SpoilerImages;
+ private ImagesList imagesList;
+ private Subscription subscription;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -60,18 +62,19 @@ public class ImagesActivity extends AbstractActivity {
offline = DataStore.isOffline(geocode, null) && (imgType == ImageType.SpoilerImages
|| Settings.isStoreLogImages());
+
}
@Override
public void onStart() {
super.onStart();
- imagesList.loadImages(findViewById(R.id.spoiler_list), imageNames, offline);
+ subscription = imagesList.loadImages(findViewById(R.id.spoiler_list), imageNames, offline);
}
@Override
public void onStop() {
// Reclaim native memory faster than the finalizers would
- imagesList.removeAllViews();
+ subscription.unsubscribe();
super.onStop();
}
diff --git a/main/src/cgeo/geocaching/Intents.java b/main/src/cgeo/geocaching/Intents.java
index d9d9829..5c969a1 100644
--- a/main/src/cgeo/geocaching/Intents.java
+++ b/main/src/cgeo/geocaching/Intents.java
@@ -29,4 +29,8 @@ public class Intents {
public static final String EXTRA_WAYPOINT_ID = PREFIX + "waypoint_id";
public static final String EXTRA_CACHELIST = PREFIX + "cache_list";
public static final String EXTRA_POCKET_GUID = PREFIX + "pocket_guid";
+
+ private static final String PREFIX_ACTION = "cgeo.geocaching.intent.action.";
+ public static final String ACTION_GEOCACHE = PREFIX_ACTION + "GEOCACHE";
+ public static final String ACTION_TRACKABLE = PREFIX_ACTION + "TRACKABLE";
}
diff --git a/main/src/cgeo/geocaching/LogCacheActivity.java b/main/src/cgeo/geocaching/LogCacheActivity.java
index 301de01..4d2815b 100644
--- a/main/src/cgeo/geocaching/LogCacheActivity.java
+++ b/main/src/cgeo/geocaching/LogCacheActivity.java
@@ -13,6 +13,7 @@ import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.ui.dialog.DateDialog;
+import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
import cgeo.geocaching.utils.DateUtils;
import cgeo.geocaching.utils.Log;
@@ -151,7 +152,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia
final TextView actionButton = (TextView) inventoryItem.findViewById(R.id.action);
actionButton.setId(tb.id);
actionButtons.put(actionButton.getId(), tb);
- actionButton.setText(res.getString(tb.action.resourceId) + " ▼");
+ actionButton.setText(tb.action.getLabel() + " ▼");
actionButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -301,6 +302,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia
final EditText logView = (EditText) findViewById(R.id.log);
if (StringUtils.isBlank(currentLogText()) && StringUtils.isNotBlank(text)) {
logView.setText(text);
+ Dialogs.moveCursorToEnd(logView);
}
tweetCheck.setChecked(true);
@@ -633,11 +635,11 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia
alert.create().show();
}
- private String[] getTBLogTypes() {
+ private static String[] getTBLogTypes() {
final LogTypeTrackable[] logTypeValues = LogTypeTrackable.values();
String[] logTypes = new String[logTypeValues.length];
for (int i = 0; i < logTypes.length; i++) {
- logTypes[i] = res.getString(logTypeValues[i].resourceId);
+ logTypes[i] = logTypeValues[i].getLabel();
}
return logTypes;
}
diff --git a/main/src/cgeo/geocaching/LogTrackableActivity.java b/main/src/cgeo/geocaching/LogTrackableActivity.java
index 5246fa9..fabe391 100644
--- a/main/src/cgeo/geocaching/LogTrackableActivity.java
+++ b/main/src/cgeo/geocaching/LogTrackableActivity.java
@@ -3,8 +3,8 @@ package cgeo.geocaching;
import butterknife.ButterKnife;
import butterknife.InjectView;
-import cgeo.geocaching.connector.gc.GCParser;
import cgeo.geocaching.connector.gc.GCLogin;
+import cgeo.geocaching.connector.gc.GCParser;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.network.Network;
@@ -13,6 +13,7 @@ import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.ui.dialog.DateDialog;
+import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
@@ -127,6 +128,7 @@ public class LogTrackableActivity extends AbstractLoggingActivity implements Dat
if (StringUtils.isNotBlank(extras.getString(Intents.EXTRA_TRACKING_CODE))) {
trackingEditText.setText(extras.getString(Intents.EXTRA_TRACKING_CODE));
+ Dialogs.moveCursorToEnd(trackingEditText);
}
}
diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java
index 924c66d..6d89991 100644
--- a/main/src/cgeo/geocaching/MainActivity.java
+++ b/main/src/cgeo/geocaching/MainActivity.java
@@ -10,6 +10,7 @@ import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Units;
+import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.maps.CGeoMap;
import cgeo.geocaching.settings.Settings;
@@ -19,14 +20,17 @@ import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.DatabaseBackupUtils;
import cgeo.geocaching.utils.GeoDirHandler;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
import cgeo.geocaching.utils.Version;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
-
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.android.observables.AndroidObservable;
+import rx.schedulers.Schedulers;
+import rx.functions.Action1;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@@ -48,7 +52,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -77,8 +80,6 @@ public class MainActivity extends AbstractActivity {
private boolean cleanupRunning = false;
private int countBubbleCnt = 0;
private Geopoint addCoords = null;
- private List<Address> addresses = null;
- private boolean addressObtaining = false;
private boolean initialized = false;
private final UpdateLocation locationUpdater = new UpdateLocation();
@@ -104,7 +105,7 @@ public class MainActivity extends AbstractActivity {
if (conn.isLoggedIn()) {
userInfo.append(conn.getUserName());
if (conn.getCachesFound() >= 0) {
- userInfo.append(" (").append(String.valueOf(conn.getCachesFound())).append(')');
+ userInfo.append(" (").append(conn.getCachesFound()).append(')');
}
userInfo.append(Formatter.SEPARATOR);
}
@@ -115,40 +116,24 @@ public class MainActivity extends AbstractActivity {
}
};
- private Handler obtainAddressHandler = new Handler() {
-
- @Override
- public void handleMessage(final Message msg) {
- try {
- if (CollectionUtils.isNotEmpty(addresses)) {
- final Address address = addresses.get(0);
- final ArrayList<String> addressParts = new ArrayList<String>();
-
- final String countryName = address.getCountryName();
- if (countryName != null) {
- addressParts.add(countryName);
- }
- final String locality = address.getLocality();
- if (locality != null) {
- addressParts.add(locality);
- } else {
- final String adminArea = address.getAdminArea();
- if (adminArea != null) {
- addressParts.add(adminArea);
- }
- }
-
- addCoords = app.currentGeo().getCoords();
+ private static String formatAddress(final Address address) {
+ final ArrayList<String> addressParts = new ArrayList<String>();
- navLocation.setText(StringUtils.join(addressParts, ", "));
- }
- } catch (RuntimeException e) {
- // nothing
+ final String countryName = address.getCountryName();
+ if (countryName != null) {
+ addressParts.add(countryName);
+ }
+ final String locality = address.getLocality();
+ if (locality != null) {
+ addressParts.add(locality);
+ } else {
+ final String adminArea = address.getAdminArea();
+ if (adminArea != null) {
+ addressParts.add(adminArea);
}
-
- addresses = null;
}
- };
+ return StringUtils.join(addressParts, ", ");
+ }
private class SatellitesHandler extends GeoDirHandler {
@@ -285,7 +270,7 @@ public class MainActivity extends AbstractActivity {
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.menu_pocket_queries).setVisible(Settings.isPremiumMember());
+ menu.findItem(R.id.menu_pocket_queries).setVisible(Settings.isGCPremiumMember());
return true;
}
@@ -309,13 +294,13 @@ public class MainActivity extends AbstractActivity {
startScannerApplication();
return true;
case R.id.menu_pocket_queries:
- if (!Settings.isPremiumMember()) {
+ if (!Settings.isGCPremiumMember()) {
return true;
}
- new PocketQueryList.UserInterface(MainActivity.this).promptForListSelection(new RunnableWithArgument<PocketQueryList>() {
+ PocketQueryList.promptForListSelection(this, new Action1<PocketQueryList>() {
@Override
- public void run(final PocketQueryList pql) {
+ public void call(final PocketQueryList pql) {
CacheListActivity.startActivityPocket(MainActivity.this, pql);
}
});
@@ -388,14 +373,14 @@ public class MainActivity extends AbstractActivity {
@Override
public boolean onLongClick(final View v) {
- new StoredList.UserInterface(MainActivity.this).promptForListSelection(R.string.list_title, new RunnableWithArgument<Integer>() {
+ new StoredList.UserInterface(MainActivity.this).promptForListSelection(R.string.list_title, new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
Settings.saveLastList(selectedListId);
CacheListActivity.startActivityOffline(MainActivity.this);
}
- });
+ }, false, PseudoList.HISTORY_LIST.id);
return true;
}
});
@@ -525,52 +510,60 @@ public class MainActivity extends AbstractActivity {
@Override
public void updateGeoData(final IGeoData geo) {
- try {
- if (geo.getCoords() != null) {
- if (!nearestView.isClickable()) {
- nearestView.setFocusable(true);
- nearestView.setClickable(true);
- nearestView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View v) {
- cgeoFindNearest(v);
- }
- });
- nearestView.setBackgroundResource(R.drawable.main_nearby);
+ if (!nearestView.isClickable()) {
+ nearestView.setFocusable(true);
+ nearestView.setClickable(true);
+ nearestView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ cgeoFindNearest(v);
}
+ });
+ nearestView.setBackgroundResource(R.drawable.main_nearby);
+ }
- navType.setText(res.getString(geo.getLocationProvider().resourceId));
+ navType.setText(res.getString(geo.getLocationProvider().resourceId));
- if (geo.getAccuracy() >= 0) {
- int speed = Math.round(geo.getSpeed()) * 60 * 60 / 1000;
- navAccuracy.setText("±" + Units.getDistanceFromMeters(geo.getAccuracy()) + Formatter.SEPARATOR + Units.getSpeed(speed));
- } else {
- navAccuracy.setText(null);
- }
+ if (geo.getAccuracy() >= 0) {
+ int speed = Math.round(geo.getSpeed()) * 60 * 60 / 1000;
+ navAccuracy.setText("±" + Units.getDistanceFromMeters(geo.getAccuracy()) + Formatter.SEPARATOR + Units.getSpeed(speed));
+ } else {
+ navAccuracy.setText(null);
+ }
- if (Settings.isShowAddress()) {
- if (addCoords == null) {
- navLocation.setText(res.getString(R.string.loc_no_addr));
- }
- if (addCoords == null || (geo.getCoords().distanceTo(addCoords) > 0.5 && !addressObtaining)) {
- (new ObtainAddressThread()).start();
+ if (Settings.isShowAddress()) {
+ if (addCoords == null) {
+ navLocation.setText(R.string.loc_no_addr);
+ }
+ if (addCoords == null || (geo.getCoords().distanceTo(addCoords) > 0.5)) {
+ final Observable<String> address = Observable.create(new OnSubscribe<String>() {
+ @Override
+ public void call(final Subscriber<? super String> subscriber) {
+ try {
+ addCoords = geo.getCoords();
+ final Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
+ final Geopoint coords = app.currentGeo().getCoords();
+ final List<Address> addresses = geocoder.getFromLocation(coords.getLatitude(), coords.getLongitude(), 1);
+ if (!addresses.isEmpty()) {
+ subscriber.onNext(formatAddress(addresses.get(0)));
+ }
+ subscriber.onCompleted();
+ } catch (final Exception e) {
+ subscriber.onError(e);
+ }
}
- } else {
- navLocation.setText(geo.getCoords().toString());
- }
- } else {
- if (nearestView.isClickable()) {
- nearestView.setFocusable(false);
- nearestView.setClickable(false);
- nearestView.setOnClickListener(null);
- nearestView.setBackgroundResource(R.drawable.main_nearby_disabled);
- }
- navType.setText(null);
- navAccuracy.setText(null);
- navLocation.setText(res.getString(R.string.loc_trying));
+ }).subscribeOn(Schedulers.io());
+ AndroidObservable.fromActivity(MainActivity.this, address)
+ .onErrorResumeNext(Observable.from(geo.getCoords().toString()))
+ .subscribe(new Action1<String>() {
+ @Override
+ public void call(final String address) {
+ navLocation.setText(address);
+ }
+ });
}
- } catch (RuntimeException e) {
- Log.w("Failed to update location.");
+ } else {
+ navLocation.setText(geo.getCoords().toString());
}
}
}
@@ -579,7 +572,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoFindOnMap(final View v) {
+ public void cgeoFindOnMap(@SuppressWarnings("unused") final View v) {
findOnMap.setPressed(true);
CGeoMap.startActivityLiveMap(this);
}
@@ -588,7 +581,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoFindNearest(final View v) {
+ public void cgeoFindNearest(@SuppressWarnings("unused") final View v) {
if (app.currentGeo().getCoords() == null) {
return;
}
@@ -601,7 +594,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoFindByOffline(final View v) {
+ public void cgeoFindByOffline(@SuppressWarnings("unused") final View v) {
findByOffline.setPressed(true);
CacheListActivity.startActivityOffline(this);
}
@@ -610,7 +603,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoSearch(final View v) {
+ public void cgeoSearch(@SuppressWarnings("unused") final View v) {
advanced.setPressed(true);
startActivity(new Intent(this, SearchActivity.class));
}
@@ -619,7 +612,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoPoint(final View v) {
+ public void cgeoPoint(@SuppressWarnings("unused") final View v) {
any.setPressed(true);
startActivity(new Intent(this, NavigateAnyPointActivity.class));
}
@@ -628,7 +621,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoFilter(final View v) {
+ public void cgeoFilter(@SuppressWarnings("unused") final View v) {
filter.setPressed(true);
filter.performClick();
}
@@ -637,7 +630,7 @@ public class MainActivity extends AbstractActivity {
* @param v
* unused here but needed since this method is referenced from XML layout
*/
- public void cgeoNavSettings(final View v) {
+ public void cgeoNavSettings(@SuppressWarnings("unused") final View v) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
@@ -714,40 +707,11 @@ public class MainActivity extends AbstractActivity {
}
}
- private class ObtainAddressThread extends Thread {
-
- public ObtainAddressThread() {
- setPriority(Thread.MIN_PRIORITY);
- }
-
- @Override
- public void run() {
- if (addressObtaining) {
- return;
- }
- addressObtaining = true;
-
- try {
- final Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
- final Geopoint coords = app.currentGeo().getCoords();
- addresses = geocoder.getFromLocation(coords.getLatitude(), coords.getLongitude(), 1);
- } catch (final IOException e) {
- Log.i("Failed to obtain address");
- } catch (final IllegalArgumentException e) {
- Log.w("ObtainAddressThread.run", e);
- }
-
- obtainAddressHandler.sendEmptyMessage(0);
-
- addressObtaining = false;
- }
- }
-
/**
* @param view
* unused here but needed since this method is referenced from XML layout
*/
- public void showAbout(final View view) {
+ public void showAbout(@SuppressWarnings("unused") final View view) {
startActivity(new Intent(this, AboutActivity.class));
}
@@ -755,7 +719,7 @@ public class MainActivity extends AbstractActivity {
* @param view
* unused here but needed since this method is referenced from XML layout
*/
- public void goSearch(final View view) {
+ public void goSearch(@SuppressWarnings("unused") final View view) {
onSearchRequested();
}
diff --git a/main/src/cgeo/geocaching/PocketQueryList.java b/main/src/cgeo/geocaching/PocketQueryList.java
index 9d1110d..9b48f92 100644
--- a/main/src/cgeo/geocaching/PocketQueryList.java
+++ b/main/src/cgeo/geocaching/PocketQueryList.java
@@ -2,15 +2,20 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.connector.gc.GCParser;
-import cgeo.geocaching.utils.RunnableWithArgument;
+
+import org.apache.commons.collections4.CollectionUtils;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.android.observables.AndroidObservable;
+import rx.schedulers.Schedulers;
+import rx.functions.Action1;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Message;
import java.util.List;
@@ -20,105 +25,62 @@ public final class PocketQueryList {
private final int maxCaches;
private final String name;
- public PocketQueryList(String guid, String name, int maxCaches) {
+ public PocketQueryList(final String guid, final String name, final int maxCaches) {
this.guid = guid;
this.name = name;
this.maxCaches = maxCaches;
}
- public static class UserInterface {
-
- List<PocketQueryList> pocketQueryList = null;
- RunnableWithArgument<PocketQueryList> runAfterwards;
-
- private Handler loadPocketQueryHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- if ((pocketQueryList == null) || (pocketQueryList.size() == 0)) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
-
- ActivityMixin.showToast(activity, res.getString(R.string.warn_no_pocket_query_found));
-
- return;
- }
-
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
-
- final CharSequence[] items = new CharSequence[pocketQueryList.size()];
-
- for (int i = 0; i < pocketQueryList.size(); i++) {
- PocketQueryList pq = pocketQueryList.get(i);
- items[i] = pq.name;
- }
+ public String getGuid() {
+ return guid;
+ }
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setTitle(res.getString(R.string.search_pocket_select));
- builder.setItems(items, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int itemId) {
- final PocketQueryList query = pocketQueryList.get(itemId);
- dialogInterface.dismiss();
- runAfterwards.run(query);
- }
- });
- builder.create().show();
+ public int getMaxCaches() {
+ return maxCaches;
+ }
- }
- };
+ public String getName() {
+ return name;
+ }
- private class LoadPocketQueryListThread extends Thread {
- final private Handler handler;
+ public static void promptForListSelection(final Activity activity, final Action1<PocketQueryList> runAfterwards) {
+ final Dialog waitDialog = ProgressDialog.show(activity, activity.getString(R.string.search_pocket_title), activity.getString(R.string.search_pocket_loading), true, true);
- public LoadPocketQueryListThread(Handler handlerIn) {
- handler = handlerIn;
+ AndroidObservable.fromActivity(activity, Observable.create(new OnSubscribe<List<PocketQueryList>>() {
+ @Override
+ public void call(final Subscriber<? super List<PocketQueryList>> subscriber) {
+ subscriber.onNext(GCParser.searchPocketQueryList());
+ subscriber.onCompleted();
}
-
+ }).subscribeOn(Schedulers.io())).subscribe(new Action1<List<PocketQueryList>>() {
@Override
- public void run() {
- pocketQueryList = GCParser.searchPocketQueryList();
- handler.sendMessage(Message.obtain());
+ public void call(final List<PocketQueryList> pocketQueryLists) {
+ waitDialog.dismiss();
+ selectFromPocketQueries(activity, pocketQueryLists, runAfterwards);
}
+ });
+ }
+ private static void selectFromPocketQueries(final Activity activity, final List<PocketQueryList> pocketQueryList, final Action1<PocketQueryList> runAfterwards) {
+ if (CollectionUtils.isEmpty(pocketQueryList)) {
+ ActivityMixin.showToast(activity, activity.getString(R.string.warn_no_pocket_query_found));
+ return;
}
- private final Activity activity;
- private final CgeoApplication app;
- private final Resources res;
- private ProgressDialog waitDialog = null;
-
- public UserInterface(final Activity activity) {
- this.activity = activity;
- app = CgeoApplication.getInstance();
- res = app.getResources();
- }
-
- public void promptForListSelection(final RunnableWithArgument<PocketQueryList> runAfterwards) {
+ final CharSequence[] items = new CharSequence[pocketQueryList.size()];
- this.runAfterwards = runAfterwards;
-
- waitDialog = ProgressDialog.show(activity, res.getString(R.string.search_pocket_title), res.getString(R.string.search_pocket_loading), true, true);
-
- LoadPocketQueryListThread thread = new LoadPocketQueryListThread(loadPocketQueryHandler);
- thread.start();
+ for (int i = 0; i < pocketQueryList.size(); i++) {
+ items[i] = pocketQueryList.get(i).name;
}
-
- }
-
- public String getGuid() {
- return guid;
- }
-
- public int getMaxCaches() {
- return maxCaches;
- }
-
- public String getName() {
- return name;
+ new AlertDialog.Builder(activity)
+ .setTitle(activity.getString(R.string.search_pocket_select))
+ .setItems(items, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(final DialogInterface dialogInterface, final int itemId) {
+ dialogInterface.dismiss();
+ runAfterwards.call(pocketQueryList.get(itemId));
+ }
+ }).create().show();
}
}
diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java
index 4e1777d..8a89e5f 100644
--- a/main/src/cgeo/geocaching/SearchActivity.java
+++ b/main/src/cgeo/geocaching/SearchActivity.java
@@ -10,12 +10,17 @@ import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.trackable.TrackableConnector;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
+import cgeo.geocaching.search.AutoCompleteAdapter;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.ui.dialog.CoordinatesInputDialog;
import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.EditUtils;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+import rx.functions.Func1;
import android.app.Activity;
import android.app.SearchManager;
@@ -26,10 +31,8 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
-import android.widget.EditText;
import java.util.Locale;
@@ -39,19 +42,19 @@ public class SearchActivity extends AbstractActivity {
@InjectView(R.id.buttonLongitude) protected Button buttonLongitude;
@InjectView(R.id.search_coordinates) protected Button buttonSearchCoords;
- @InjectView(R.id.address) protected EditText addressEditText;
+ @InjectView(R.id.address) protected AutoCompleteTextView addressEditText;
@InjectView(R.id.search_address) protected Button buttonSearchAddress;
@InjectView(R.id.geocode) protected AutoCompleteTextView geocodeEditText;
@InjectView(R.id.display_geocode) protected Button buttonSearchGeocode;
- @InjectView(R.id.keyword) protected EditText keywordEditText;
+ @InjectView(R.id.keyword) protected AutoCompleteTextView keywordEditText;
@InjectView(R.id.search_keyword) protected Button buttonSearchKeyword;
- @InjectView(R.id.finder) protected EditText finderNameEditText;
+ @InjectView(R.id.finder) protected AutoCompleteTextView finderNameEditText;
@InjectView(R.id.search_finder) protected Button buttonSearchFinder;
- @InjectView(R.id.owner) protected EditText ownerNameEditText;
+ @InjectView(R.id.owner) protected AutoCompleteTextView ownerNameEditText;
@InjectView(R.id.search_owner) protected Button buttonSearchOwner;
@InjectView(R.id.trackable) protected AutoCompleteTextView trackableEditText;
@@ -60,9 +63,23 @@ public class SearchActivity extends AbstractActivity {
@Override
public final void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final Intent intent = getIntent();
+
+ // search suggestion for a cache
+ if (Intents.ACTION_GEOCACHE.equals(intent.getAction())) {
+ CacheDetailActivity.startActivity(this, intent.getStringExtra(SearchManager.QUERY));
+ finish();
+ return;
+ }
+
+ // search suggestion for a trackable
+ if (Intents.ACTION_TRACKABLE.equals(intent.getAction())) {
+ TrackableActivity.startActivity(this, null, intent.getStringExtra(SearchManager.QUERY), null);
+ finish();
+ return;
+ }
// search query
- final Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
hideKeyboard();
final String query = intent.getStringExtra(SearchManager.QUERY);
@@ -173,7 +190,7 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findByAddressFn();
}
- });
+ }, null);
setSearchAction(geocodeEditText, buttonSearchGeocode, new Runnable() {
@@ -181,8 +198,13 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findByGeocodeFn();
}
+ }, new Func1<String, String[]>() {
+
+ @Override
+ public String[] call(final String input) {
+ return DataStore.getSuggestionsGeocode(input);
+ }
});
- addHistoryEntries(geocodeEditText, DataStore.getRecentGeocodesForSearch());
setSearchAction(keywordEditText, buttonSearchKeyword, new Runnable() {
@@ -190,6 +212,12 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findByKeywordFn();
}
+ }, new Func1<String, String[]>() {
+
+ @Override
+ public String[] call(final String input) {
+ return DataStore.getSuggestionsKeyword(input);
+ }
});
setSearchAction(finderNameEditText, buttonSearchFinder, new Runnable() {
@@ -198,6 +226,12 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findByFinderFn();
}
+ }, new Func1<String, String[]>() {
+
+ @Override
+ public String[] call(final String input) {
+ return DataStore.getSuggestionsFinderName(input);
+ }
});
setSearchAction(ownerNameEditText, buttonSearchOwner, new Runnable() {
@@ -206,6 +240,12 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findByOwnerFn();
}
+ }, new Func1<String, String[]>() {
+
+ @Override
+ public String[] call(final String input) {
+ return DataStore.getSuggestionsOwnerName(input);
+ }
});
setSearchAction(trackableEditText, buttonSearchTrackable, new Runnable() {
@@ -214,12 +254,16 @@ public class SearchActivity extends AbstractActivity {
public void run() {
findTrackableFn();
}
+ }, new Func1<String, String[]>() {
+
+ @Override
+ public String[] call(final String input) {
+ return DataStore.getSuggestionsTrackableCode(input);
+ }
});
- addHistoryEntries(trackableEditText, DataStore.getTrackableCodes());
- disableSuggestions(trackableEditText);
}
- private static void setSearchAction(final EditText editText, final Button button, final Runnable runnable) {
+ private static void setSearchAction(final AutoCompleteTextView editText, final Button button, final @NonNull Runnable runnable, final @Nullable Func1<String, String[]> suggestionFunction) {
EditUtils.setActionListener(editText, runnable);
button.setOnClickListener(new View.OnClickListener() {
@Override
@@ -227,12 +271,8 @@ public class SearchActivity extends AbstractActivity {
runnable.run();
}
});
- }
-
- private void addHistoryEntries(final AutoCompleteTextView textView, final String[] entries) {
- if (entries != null) {
- final ArrayAdapter<String> historyAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, entries);
- textView.setAdapter(historyAdapter);
+ if (suggestionFunction != null) {
+ editText.setAdapter(new AutoCompleteAdapter(editText.getContext(), android.R.layout.simple_dropdown_item_1line, suggestionFunction));
}
}
@@ -305,7 +345,7 @@ public class SearchActivity extends AbstractActivity {
return;
}
- CacheListActivity.startActivityUserName(this, usernameText);
+ CacheListActivity.startActivityFinder(this, usernameText);
}
private void findByOwnerFn() {
@@ -331,7 +371,7 @@ public class SearchActivity extends AbstractActivity {
return;
}
- CacheDetailActivity.startActivity(this, geocodeText.toUpperCase());
+ CacheDetailActivity.startActivity(this, geocodeText.toUpperCase(Locale.US));
}
private void findTrackableFn() {
diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java
index 131a01c..46ac38e 100644
--- a/main/src/cgeo/geocaching/SearchResult.java
+++ b/main/src/cgeo/geocaching/SearchResult.java
@@ -10,6 +10,7 @@ import cgeo.geocaching.gcvote.GCVote;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -228,6 +229,7 @@ public class SearchResult implements Parcelable {
return result;
}
+ @Nullable
public Geocache getFirstCacheFromResult(final EnumSet<LoadFlag> loadFlags) {
return CollectionUtils.isNotEmpty(geocodes) ? DataStore.loadCache(geocodes.iterator().next(), loadFlags) : null;
}
diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java
index 7811da5..16fce37 100644
--- a/main/src/cgeo/geocaching/StaticMapsActivity.java
+++ b/main/src/cgeo/geocaching/StaticMapsActivity.java
@@ -4,11 +4,10 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.utils.Log;
-import com.googlecode.androidannotations.annotations.EActivity;
-import com.googlecode.androidannotations.annotations.Extra;
-import com.googlecode.androidannotations.annotations.OptionsItem;
-import com.googlecode.androidannotations.annotations.OptionsMenu;
-
+import org.androidannotations.annotations.EActivity;
+import org.androidannotations.annotations.Extra;
+import org.androidannotations.annotations.OptionsItem;
+import org.androidannotations.annotations.OptionsMenu;
import org.apache.commons.collections4.CollectionUtils;
import android.app.ProgressDialog;
diff --git a/main/src/cgeo/geocaching/StaticMapsProvider.java b/main/src/cgeo/geocaching/StaticMapsProvider.java
index d5cbb13..eaab159 100644
--- a/main/src/cgeo/geocaching/StaticMapsProvider.java
+++ b/main/src/cgeo/geocaching/StaticMapsProvider.java
@@ -298,8 +298,8 @@ public final class StaticMapsProvider {
return true;
}
- public static Bitmap getPreviewMap(final String geocode) {
- return decodeFile(StaticMapsProvider.getMapFile(geocode, PREFIX_PREVIEW, false));
+ public static Bitmap getPreviewMap(final Geocache cache) {
+ return decodeFile(StaticMapsProvider.getMapFile(cache.getGeocode(), PREFIX_PREVIEW, false));
}
public static Bitmap getWaypointMap(final String geocode, final Waypoint waypoint, final int level) {
diff --git a/main/src/cgeo/geocaching/StatusFragment.java b/main/src/cgeo/geocaching/StatusFragment.java
index 4f70f0e..3672a3b 100644
--- a/main/src/cgeo/geocaching/StatusFragment.java
+++ b/main/src/cgeo/geocaching/StatusFragment.java
@@ -1,15 +1,17 @@
package cgeo.geocaching;
+import cgeo.geocaching.network.StatusUpdater;
import cgeo.geocaching.network.StatusUpdater.Status;
-import cgeo.geocaching.utils.IObserver;
import cgeo.geocaching.utils.Log;
+import rx.Subscription;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action1;
+
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@@ -20,91 +22,68 @@ import android.widget.TextView;
public class StatusFragment extends Fragment {
- private ViewGroup status;
- private ImageView statusIcon;
- private TextView statusMessage;
-
- final private StatusHandler statusHandler = new StatusHandler();
+ private Subscription statusSubscription;
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- status = (ViewGroup) inflater.inflate(R.layout.status, container, false);
- statusIcon = (ImageView) status.findViewById(R.id.status_icon);
- statusMessage = (TextView) status.findViewById(R.id.status_message);
- return status;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- CgeoApplication.getInstance().getStatusUpdater().addObserver(statusHandler);
- }
-
- @Override
- public void onPause() {
- CgeoApplication.getInstance().getStatusUpdater().deleteObserver(statusHandler);
- super.onPause();
- }
-
- private class StatusHandler extends Handler implements IObserver<Status> {
-
- @Override
- public void update(final Status data) {
- obtainMessage(0, data).sendToTarget();
- }
-
- @Override
- public void handleMessage(final Message msg) {
- final Status data = (Status) msg.obj;
- updateDisplay(data != null && data.message != null ? data : Status.defaultStatus());
- }
-
- private void updateDisplay(final Status data) {
-
- if (data == null) {
- status.setVisibility(View.INVISIBLE);
- return;
- }
-
- final Resources res = getResources();
- final String packageName = getActivity().getPackageName();
+ final ViewGroup statusGroup = (ViewGroup) inflater.inflate(R.layout.status, container, false);
+ final ImageView statusIcon = (ImageView) statusGroup.findViewById(R.id.status_icon);
+ final TextView statusMessage = (TextView) statusGroup.findViewById(R.id.status_message);
+ statusSubscription = AndroidObservable.fromFragment(this, StatusUpdater.latestStatus).subscribe(new Action1<Status>() {
+ @Override
+ public void call(final Status status) {
+ if (status == null) {
+ statusGroup.setVisibility(View.INVISIBLE);
+ return;
+ }
- if (data.icon != null) {
- final int iconId = res.getIdentifier(data.icon, "drawable", packageName);
- if (iconId != 0) {
- statusIcon.setImageResource(iconId);
- statusIcon.setVisibility(View.VISIBLE);
+ final Resources res = getResources();
+ final String packageName = getActivity().getPackageName();
+
+ if (status.icon != null) {
+ final int iconId = res.getIdentifier(status.icon, "drawable", packageName);
+ if (iconId != 0) {
+ statusIcon.setImageResource(iconId);
+ statusIcon.setVisibility(View.VISIBLE);
+ } else {
+ Log.w("StatusHandler: could not find icon corresponding to @drawable/" + status.icon);
+ statusIcon.setVisibility(View.GONE);
+ }
} else {
- Log.w("StatusHandler: could not find icon corresponding to @drawable/" + data.icon);
statusIcon.setVisibility(View.GONE);
}
- } else {
- statusIcon.setVisibility(View.GONE);
- }
- String message = data.message;
- if (data.messageId != null) {
- final int messageId = res.getIdentifier(data.messageId, "string", packageName);
- if (messageId != 0) {
- message = res.getString(messageId);
+ String message = status.message;
+ if (status.messageId != null) {
+ final int messageId = res.getIdentifier(status.messageId, "string", packageName);
+ if (messageId != 0) {
+ message = res.getString(messageId);
+ }
}
- }
- statusMessage.setText(message);
- status.setVisibility(View.VISIBLE);
+ statusMessage.setText(message);
+ statusGroup.setVisibility(View.VISIBLE);
- if (data.url != null) {
- status.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View v) {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(data.url)));
- }
- });
- } else {
- status.setClickable(false);
+ if (status.url != null) {
+ statusGroup.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(status.url)));
+ }
+ });
+ } else {
+ statusGroup.setClickable(false);
+ }
}
- }
+ });
+ return statusGroup;
+ }
+ @Override
+ public void onDestroy() {
+ statusSubscription.unsubscribe();
+ super.onDestroy();
}
+
}
diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java
index dcfd80a..948e668 100644
--- a/main/src/cgeo/geocaching/TrackableActivity.java
+++ b/main/src/cgeo/geocaching/TrackableActivity.java
@@ -34,6 +34,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
+import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -109,6 +110,8 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
};
+ private CharSequence clickedItemText = null;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.viewpager_activity);
@@ -130,6 +133,8 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
// try to get data from URI
if (geocode == null && guid == null && id == null && uri != null) {
+ geocode = ConnectorFactory.getTrackableFromURL(uri.toString());
+
final String uriHost = uri.getHost().toLowerCase(Locale.US);
if (uriHost.contains("geocaching.com")) {
geocode = uri.getQueryParameter("tracker");
@@ -190,6 +195,36 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
@Override
+ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
+ super.onCreateContextMenu(menu, view, info);
+ final int viewId = view.getId();
+ assert view instanceof TextView;
+ clickedItemText = ((TextView) view).getText();
+ switch (viewId) {
+ case R.id.value: // name, TB-code, origin, released, distance
+ final String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText();
+ buildDetailsContextMenu(menu, clickedItemText, itemTitle, true);
+ break;
+ case R.id.goal:
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_goal), false);
+ break;
+ case R.id.details:
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_details), false);
+ break;
+ case R.id.log:
+ buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_logs), false);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ return onClipboardItemSelected(item, clickedItemText) || onOptionsItemSelected(item);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.trackable_activity, menu);
return true;
@@ -360,7 +395,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
// trackable name
- details.add(R.string.trackable_name, StringUtils.isNotBlank(trackable.getName()) ? Html.fromHtml(trackable.getName()).toString() : res.getString(R.string.trackable_unknown));
+ registerForContextMenu(details.add(R.string.trackable_name, StringUtils.isNotBlank(trackable.getName()) ? Html.fromHtml(trackable.getName()).toString() : res.getString(R.string.trackable_unknown)));
// trackable type
String tbType;
@@ -372,7 +407,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
details.add(R.string.trackable_type, tbType);
// trackable geocode
- details.add(R.string.trackable_code, trackable.getGeocode());
+ registerForContextMenu(details.add(R.string.trackable_code, trackable.getGeocode()));
// trackable owner
final TextView owner = details.add(R.string.trackable_owner, res.getString(R.string.trackable_unknown));
@@ -441,16 +476,17 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
if (StringUtils.isNotBlank(trackable.getOrigin())) {
final TextView origin = details.add(R.string.trackable_origin, "");
origin.setText(Html.fromHtml(trackable.getOrigin()), TextView.BufferType.SPANNABLE);
+ registerForContextMenu(origin);
}
// trackable released
if (trackable.getReleased() != null) {
- details.add(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime()));
+ registerForContextMenu(details.add(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime())));
}
// trackable distance
if (trackable.getDistance() >= 0) {
- details.add(R.string.trackable_distance, Units.getDistanceFromKilometers(trackable.getDistance()));
+ registerForContextMenu(details.add(R.string.trackable_distance, Units.getDistanceFromKilometers(trackable.getDistance())));
}
// trackable goal
@@ -459,6 +495,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
goalTextView.setVisibility(View.VISIBLE);
goalTextView.setText(Html.fromHtml(trackable.getGoal(), new HtmlImage(geocode, true, 0, false), null), TextView.BufferType.SPANNABLE);
goalTextView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
+ registerForContextMenu(goalTextView);
}
// trackable details
@@ -467,6 +504,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
detailsTextView.setVisibility(View.VISIBLE);
detailsTextView.setText(Html.fromHtml(trackable.getDetails(), new HtmlImage(geocode, true, 0, false), new UnknownTagsHandler()), TextView.BufferType.SPANNABLE);
detailsTextView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
+ registerForContextMenu(detailsTextView);
}
// trackable image
diff --git a/main/src/cgeo/geocaching/UsefulAppsActivity.java b/main/src/cgeo/geocaching/UsefulAppsActivity.java
index c70143f..39c527d 100644
--- a/main/src/cgeo/geocaching/UsefulAppsActivity.java
+++ b/main/src/cgeo/geocaching/UsefulAppsActivity.java
@@ -62,6 +62,7 @@ public class UsefulAppsActivity extends AbstractActivity {
private static final HelperApp[] HELPER_APPS = {
new HelperApp(R.string.helper_calendar_title, R.string.helper_calendar_description, R.drawable.cgeo, "cgeo.calendar"),
new HelperApp(R.string.helper_sendtocgeo_title, R.string.helper_sendtocgeo_description, R.drawable.cgeo, "http://send2.cgeo.org"),
+ new HelperApp(R.string.helper_contacts_title, R.string.helper_contacts_description, R.drawable.cgeo, "cgeo.contacts"),
new HelperApp(R.string.helper_pocketquery_title, R.string.helper_pocketquery_description, R.drawable.helper_pocketquery, "org.pquery"),
new HelperApp(R.string.helper_locus_title, R.string.helper_locus_description, R.drawable.helper_locus, "menion.android.locus"),
new HelperApp(R.string.helper_google_translate_title, R.string.helper_google_translate_description, R.drawable.helper_google_translate, "com.google.android.apps.translate"),
diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java
index 36b6d01..7127de4 100644
--- a/main/src/cgeo/geocaching/activity/AbstractActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java
@@ -3,18 +3,27 @@ package cgeo.geocaching.activity;
import butterknife.ButterKnife;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.R;
import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.ClipboardUtils;
+import cgeo.geocaching.utils.HtmlUtils;
+import cgeo.geocaching.utils.TranslationUtils;
-import android.content.Context;
+import org.apache.commons.lang3.StringUtils;
+
+import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
+import android.view.ContextMenu;
+import android.view.MenuItem;
import android.view.View;
-import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import java.util.Locale;
+
public abstract class AbstractActivity extends FragmentActivity implements IAbstractActivity {
protected CgeoApplication app = null;
@@ -96,7 +105,7 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst
// create view variables
ButterKnife.inject(this);
}
-
+
private void initializeCommonFields() {
// initialize commonly used members
res = this.getResources();
@@ -116,6 +125,48 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst
}
protected void hideKeyboard() {
- ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
+ new Keyboard(this).hide();
+ }
+
+ public void showKeyboard(final View view) {
+ new Keyboard(this).show(view);
+ }
+
+ protected void buildDetailsContextMenu(final ContextMenu menu, final CharSequence clickedItemText, final String fieldTitle, final boolean copyOnly) {
+ menu.setHeaderTitle(fieldTitle);
+ getMenuInflater().inflate(R.menu.details_context, menu);
+ menu.findItem(R.id.menu_translate_to_sys_lang).setVisible(!copyOnly);
+ if (!copyOnly) {
+ if (clickedItemText.length() > TranslationUtils.TRANSLATION_TEXT_LENGTH_WARN) {
+ showToast(res.getString(R.string.translate_length_warning));
+ }
+ menu.findItem(R.id.menu_translate_to_sys_lang).setTitle(res.getString(R.string.translate_to_sys_lang, Locale.getDefault().getDisplayLanguage()));
+ }
+ final boolean localeIsEnglish = StringUtils.equals(Locale.getDefault().getLanguage(), Locale.ENGLISH.getLanguage());
+ menu.findItem(R.id.menu_translate_to_english).setVisible(!copyOnly && !localeIsEnglish);
+ }
+
+ protected boolean onClipboardItemSelected(final MenuItem item, final CharSequence clickedItemText) {
+ switch (item.getItemId()) {
+ // detail fields
+ case R.id.menu_copy:
+ ClipboardUtils.copyToClipboard(clickedItemText);
+ showToast(res.getString(R.string.clipboard_copy_ok));
+ return true;
+ case R.id.menu_translate_to_sys_lang:
+ TranslationUtils.startActivityTranslate(this, Locale.getDefault().getLanguage(), HtmlUtils.extractText(clickedItemText));
+ return true;
+ case R.id.menu_translate_to_english:
+ TranslationUtils.startActivityTranslate(this, Locale.ENGLISH.getLanguage(), HtmlUtils.extractText(clickedItemText));
+ return true;
+ case R.id.menu_cache_share_field:
+ final Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_TEXT, clickedItemText.toString());
+ startActivity(Intent.createChooser(intent, res.getText(R.string.cache_share_field)));
+ return true;
+ default:
+ return false;
+ }
}
}
diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java
index 2adae7a..a5d5c14 100644
--- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java
@@ -11,7 +11,6 @@ public abstract class AbstractListActivity extends FragmentListActivity implemen
IAbstractActivity {
private boolean keepScreenOn = false;
- private boolean paused = true;
protected CgeoApplication app = null;
protected Resources res = null;
@@ -85,26 +84,4 @@ public abstract class AbstractListActivity extends FragmentListActivity implemen
// initialize action bar title with activity title
ActivityMixin.setTitle(this, getTitle());
}
-
- @Override
- public void onResume() {
- paused = false;
- super.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- paused = true;
- }
-
- /**
- * Check if the current activity is paused. This must be called and acted
- * upon only from the UI thread.
- *
- * @return <code>true</code> if the current activity is paused
- */
- protected boolean isPaused() {
- return paused;
- }
}
diff --git a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java
index c7d4507..6e2900d 100644
--- a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java
@@ -5,7 +5,6 @@ import cgeo.geocaching.utils.Log;
import com.viewpagerindicator.TitlePageIndicator;
import com.viewpagerindicator.TitleProvider;
-
import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java
index c1a2678..bfd45da 100644
--- a/main/src/cgeo/geocaching/activity/ActivityMixin.java
+++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java
@@ -125,6 +125,6 @@ public final class ActivityMixin {
editText.getText().replace(start, end, completeText);
int newCursor = moveCursor ? start + completeText.length() : start;
- editText.setSelection(newCursor, newCursor);
+ editText.setSelection(newCursor);
}
}
diff --git a/main/src/cgeo/geocaching/activity/Keyboard.java b/main/src/cgeo/geocaching/activity/Keyboard.java
new file mode 100644
index 0000000..9bae7be
--- /dev/null
+++ b/main/src/cgeo/geocaching/activity/Keyboard.java
@@ -0,0 +1,40 @@
+package cgeo.geocaching.activity;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+
+/**
+ * Class for hiding/showing the soft keyboard on Android.
+ *
+ */
+public class Keyboard {
+ private final Activity activity;
+
+ public Keyboard(final @NonNull Activity activity) {
+ this.activity = activity;
+ }
+
+ public void hide() {
+ ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
+ }
+
+ public void show(final View view) {
+ view.requestFocus();
+ ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(view, 0);
+ }
+
+ public void showDelayed(final View view) {
+ view.postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ final InputMethodManager keyboard = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ keyboard.showSoftInput(view, 0);
+ }
+ }, 50);
+ }
+}
diff --git a/main/src/cgeo/geocaching/activity/Progress.java b/main/src/cgeo/geocaching/activity/Progress.java
index 2710023..8ee88a7 100644
--- a/main/src/cgeo/geocaching/activity/Progress.java
+++ b/main/src/cgeo/geocaching/activity/Progress.java
@@ -17,7 +17,7 @@ public class Progress {
private ProgressDialog dialog;
private int progress = 0;
private int progressDivider = 1;
- private boolean hideAbsolute = false;
+ final private boolean hideAbsolute;
public Progress(boolean hideAbsolute) {
this.hideAbsolute = hideAbsolute;
@@ -28,7 +28,7 @@ public class Progress {
}
public synchronized void dismiss() {
- if (dialog != null && dialog.isShowing()) {
+ if (isShowing()) {
try {
dialog.dismiss();
} catch (final Exception e) {
@@ -54,13 +54,8 @@ public class Progress {
}
}
- private void createProgressDialog(Context context, String title, String message, Message cancelMessage) {
- if (hideAbsolute) {
- dialog = new CustomProgressDialog(context);
- }
- else {
- dialog = new ProgressDialog(context);
- }
+ private void createProgressDialog(final Context context, final String title, final String message, final Message cancelMessage) {
+ dialog = hideAbsolute ? new CustomProgressDialog(context) : new ProgressDialog(context);
dialog.setTitle(title);
dialog.setMessage(message);
if (cancelMessage != null) {
@@ -87,7 +82,7 @@ public class Progress {
}
public synchronized void setMaxProgressAndReset(final int max) {
- if (dialog != null && dialog.isShowing()) {
+ if (isShowing()) {
final int modMax = max / this.progressDivider;
dialog.setMax(modMax);
dialog.setProgress(0);
@@ -97,7 +92,7 @@ public class Progress {
public synchronized void setProgress(final int progress) {
final int modProgress = progress / this.progressDivider;
- if (dialog != null && dialog.isShowing()) {
+ if (isShowing()) {
dialog.setProgress(modProgress);
}
this.progress = modProgress;
diff --git a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
index d6c2fe6..8e9181d 100644
--- a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
+++ b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
@@ -6,6 +6,7 @@ import cgeo.geocaching.Waypoint;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.WaypointType;
+import cgeo.geocaching.utils.SynchronizedDateFormat;
import menion.android.locus.addon.publiclib.DisplayData;
import menion.android.locus.addon.publiclib.LocusUtils;
@@ -14,8 +15,6 @@ import menion.android.locus.addon.publiclib.geoData.PointGeocachingData;
import menion.android.locus.addon.publiclib.geoData.PointGeocachingDataWaypoint;
import menion.android.locus.addon.publiclib.geoData.PointsData;
-import org.apache.commons.lang3.time.FastDateFormat;
-
import android.app.Activity;
import android.location.Location;
@@ -30,7 +29,7 @@ import java.util.Locale;
* @see <a href="http://forum.asamm.cz/viewtopic.php?f=29&t=767">Locus forum</a>
*/
public abstract class AbstractLocusApp extends AbstractApp {
- private static final FastDateFormat ISO8601DATE = FastDateFormat.getInstance("yyyy-MM-dd'T'", Locale.US);
+ private static final SynchronizedDateFormat ISO8601DATE = new SynchronizedDateFormat("yyyy-MM-dd'T'", Locale.US);
protected AbstractLocusApp(final String text, int id, final String intent) {
super(text, id, intent);
@@ -122,7 +121,7 @@ public abstract class AbstractLocusApp extends AbstractApp {
pg.placedBy = cache.getOwnerDisplayName();
final Date hiddenDate = cache.getHiddenDate();
if (hiddenDate != null) {
- pg.hidden = ISO8601DATE.format(hiddenDate.getTime());
+ pg.hidden = ISO8601DATE.format(hiddenDate);
}
int locusId = toLocusType(cache.getType());
if (locusId != NO_LOCUS_ID) {
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
index a1c752c..ec9705c 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
@@ -8,6 +8,7 @@ import cgeo.geocaching.apps.AbstractApp;
import cgeo.geocaching.geopoint.Geopoint;
import android.app.Activity;
+import android.content.Intent;
/**
* navigation app for simple point navigation (no differentiation between cache/waypoint/point)
@@ -49,4 +50,17 @@ abstract class AbstractPointNavigationApp extends AbstractApp implements CacheNa
public boolean isEnabled(Waypoint waypoint) {
return waypoint.getCoords() != null;
}
+
+ protected static void addIntentExtras(final Intent intent, final Waypoint waypoint) {
+ intent.putExtra("name", waypoint.getName());
+ intent.putExtra("code", waypoint.getGeocode());
+ }
+
+ protected static void addIntentExtras(final Intent intent, final Geocache cache) {
+ intent.putExtra("difficulty", cache.getDifficulty());
+ intent.putExtra("terrain", cache.getTerrain());
+ intent.putExtra("name", cache.getName());
+ intent.putExtra("code", cache.getGeocode());
+ intent.putExtra("size", cache.getSize().getL10n());
+ }
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractRadarApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractRadarApp.java
new file mode 100644
index 0000000..6c6ffda
--- /dev/null
+++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractRadarApp.java
@@ -0,0 +1,45 @@
+package cgeo.geocaching.apps.cache.navi;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.Waypoint;
+import cgeo.geocaching.geopoint.Geopoint;
+
+import android.app.Activity;
+import android.content.Intent;
+
+public abstract class AbstractRadarApp extends AbstractPointNavigationApp {
+
+ private final String intentAction;
+
+ protected AbstractRadarApp(final String name, final int id, final String intent, final String packageName) {
+ super(name, id, intent, packageName);
+ this.intentAction = intent;
+ }
+
+ private Intent createIntent(final Geopoint point) {
+ final Intent intent = new Intent(intentAction);
+ addCoordinates(intent, point);
+ return intent;
+ }
+
+ @Override
+ public void navigate(final Activity activity, final Geopoint point) {
+ activity.startActivity(createIntent(point));
+ }
+
+ @Override
+ public void navigate(final Activity activity, final Geocache cache) {
+ final Intent intent = createIntent(cache.getCoords());
+ addIntentExtras(intent, cache);
+ activity.startActivity(intent);
+ }
+
+ @Override
+ public void navigate(final Activity activity, final Waypoint waypoint) {
+ final Intent intent = createIntent(waypoint.getCoords());
+ addIntentExtras(intent, waypoint);
+ activity.startActivity(intent);
+ }
+
+ protected abstract void addCoordinates(final Intent intent, final Geopoint point);
+}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
index 60d6e31..819638c 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
@@ -1,6 +1,8 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
+import cgeo.geocaching.Waypoint;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.Log;
@@ -22,10 +24,15 @@ class GoogleMapsApp extends AbstractPointNavigationApp {
@Override
public void navigate(Activity activity, Geopoint point) {
- // INFO: q parameter works with Google Maps, but breaks cooperation with all other apps
+ navigate(activity, point, activity.getString(R.string.waypoint));
+ }
+
+ private static void navigate(Activity activity, Geopoint point, String label) {
try {
- activity.startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse("geo:" + point.getLatitude() + "," + point.getLongitude())));
+ final String geoLocation = "geo:" + point.getLatitude() + "," + point.getLongitude();
+ final String query = point.getLatitude() + "," + point.getLongitude() + "(" + label + ")";
+ final String uriString = geoLocation + "?q=" + Uri.encode(query);
+ activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(uriString)));
return;
} catch (RuntimeException e) {
// nothing
@@ -35,4 +42,13 @@ class GoogleMapsApp extends AbstractPointNavigationApp {
ActivityMixin.showToast(activity, getString(R.string.err_application_no));
}
+ @Override
+ public void navigate(Activity activity, Geocache cache) {
+ navigate(activity, cache.getCoords(), cache.getName());
+ }
+
+ @Override
+ public void navigate(Activity activity, Waypoint waypoint) {
+ navigate(activity, waypoint.getCoords(), waypoint.getName());
+ }
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java b/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
index 8ba3bef..ac83085 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
@@ -1,17 +1,15 @@
package cgeo.geocaching.apps.cache.navi;
-import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
import cgeo.geocaching.geopoint.Geopoint;
-import android.app.Activity;
import android.content.Intent;
/**
* Application for communication with the Pebble watch.
- *
+ *
*/
-class PebbleApp extends AbstractPointNavigationApp {
+class PebbleApp extends AbstractRadarApp {
private static final String INTENT = "com.webmajstr.pebble_gc.NAVIGATE_TO";
private static final String PACKAGE_NAME = "com.webmajstr.pebble_gc";
@@ -21,24 +19,8 @@ class PebbleApp extends AbstractPointNavigationApp {
}
@Override
- public void navigate(Activity activity, Geopoint point) {
- final Intent pebbleIntent = new Intent(INTENT);
- pebbleIntent.putExtra("latitude", point.getLatitude());
- pebbleIntent.putExtra("longitude", point.getLongitude());
- activity.startActivity(pebbleIntent);
+ protected void addCoordinates(final Intent intent, final Geopoint coords) {
+ intent.putExtra("latitude", coords.getLatitude());
+ intent.putExtra("longitude", coords.getLongitude());
}
-
- @Override
- public void navigate(Activity activity, Geocache cache) {
- final Intent pebbleIntent = new Intent(INTENT);
- pebbleIntent.putExtra("latitude", cache.getCoords().getLatitude());
- pebbleIntent.putExtra("longitude", cache.getCoords().getLongitude());
- pebbleIntent.putExtra("difficulty", cache.getDifficulty());
- pebbleIntent.putExtra("terrain", cache.getTerrain());
- pebbleIntent.putExtra("name", cache.getName());
- pebbleIntent.putExtra("code", cache.getGeocode());
- pebbleIntent.putExtra("size", cache.getSize().getL10n());
- activity.startActivity(pebbleIntent);
- }
-
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/RadarApp.java b/main/src/cgeo/geocaching/apps/cache/navi/RadarApp.java
index ffa6650..41cf2d8 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/RadarApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/RadarApp.java
@@ -3,10 +3,9 @@ package cgeo.geocaching.apps.cache.navi;
import cgeo.geocaching.R;
import cgeo.geocaching.geopoint.Geopoint;
-import android.app.Activity;
import android.content.Intent;
-class RadarApp extends AbstractPointNavigationApp {
+class RadarApp extends AbstractRadarApp {
private static final String INTENT = "com.google.android.radar.SHOW_RADAR";
private static final String PACKAGE_NAME = "com.eclipsim.gpsstatus2";
@@ -16,10 +15,9 @@ class RadarApp extends AbstractPointNavigationApp {
}
@Override
- public void navigate(Activity activity, Geopoint point) {
- final Intent radarIntent = new Intent(INTENT);
- radarIntent.putExtra("latitude", (float) point.getLatitude());
- radarIntent.putExtra("longitude", (float) point.getLongitude());
- activity.startActivity(radarIntent);
+ protected void addCoordinates(final Intent intent, final Geopoint coords) {
+ intent.putExtra("latitude", (float) coords.getLatitude());
+ intent.putExtra("longitude", (float) coords.getLongitude());
}
+
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
index ac5809e..40c4d92 100644
--- a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
+++ b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.apps.cachelist;
-import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Geocache;
+import cgeo.geocaching.SearchResult;
import cgeo.geocaching.apps.App;
import android.app.Activity;
diff --git a/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java b/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java
index 76379de..0da198b 100644
--- a/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java
+++ b/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.concurrent;
+import org.eclipse.jdt.annotation.NonNull;
+
import java.util.concurrent.ThreadFactory;
/**
@@ -12,6 +14,7 @@ public class PriorityThreadFactory implements ThreadFactory {
this.priority = priority;
}
+ @NonNull
@Override
public Thread newThread(Runnable r) {
Thread result = new Thread(r);
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 53a3bcb..6d8d79e 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -16,10 +16,10 @@ import cgeo.geocaching.connector.capability.ISearchByViewPort;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import rx.functions.Action1;
import java.util.ArrayList;
import java.util.Collection;
@@ -255,21 +255,21 @@ public abstract class AbstractConnector implements IConnector {
List<UserAction> actions = getDefaultUserActions();
if (this instanceof ISearchByOwner) {
- actions.add(new UserAction(R.string.user_menu_view_hidden, new RunnableWithArgument<UserAction.Context>() {
+ actions.add(new UserAction(R.string.user_menu_view_hidden, new Action1<Context>() {
@Override
- public void run(Context context) {
+ public void call(Context context) {
CacheListActivity.startActivityOwner(context.activity, context.userName);
}
}));
}
if (this instanceof ISearchByFinder) {
- actions.add(new UserAction(R.string.user_menu_view_found, new RunnableWithArgument<UserAction.Context>() {
+ actions.add(new UserAction(R.string.user_menu_view_found, new Action1<UserAction.Context>() {
@Override
- public void run(Context context) {
- CacheListActivity.startActivityUserName(context.activity, context.userName);
+ public void call(Context context) {
+ CacheListActivity.startActivityFinder(context.activity, context.userName);
}
}));
}
@@ -283,10 +283,10 @@ public abstract class AbstractConnector implements IConnector {
public List<UserAction> getDefaultUserActions() {
final ArrayList<UserAction> actions = new ArrayList<UserAction>();
if (ContactsAddon.isAvailable()) {
- actions.add(new UserAction(R.string.user_menu_open_contact, new RunnableWithArgument<UserAction.Context>() {
+ actions.add(new UserAction(R.string.user_menu_open_contact, new Action1<UserAction.Context>() {
@Override
- public void run(Context context) {
+ public void call(Context context) {
ContactsAddon.openContactCard(context.activity, context.userName);
}
}));
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index 0081951..18344f5 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -28,6 +28,11 @@ import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import rx.Observable;
+import rx.schedulers.Schedulers;
+import rx.functions.Func1;
+import rx.functions.Func2;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -176,14 +181,30 @@ public final class ConnectorFactory {
}
/** @see ISearchByViewPort#searchByViewport */
- public static SearchResult searchByViewport(final @NonNull Viewport viewport, final MapTokens tokens) {
- final SearchResult result = new SearchResult();
- for (final ISearchByViewPort connector : searchByViewPortConns) {
- if (connector.isActive()) {
- result.addSearchResult(connector.searchByViewport(viewport, tokens));
+ public static Observable<SearchResult> searchByViewport(final @NonNull Viewport viewport, final MapTokens tokens) {
+ return Observable.from(searchByViewPortConns).filter(new Func1<ISearchByViewPort, Boolean>() {
+ @Override
+ public Boolean call(final ISearchByViewPort connector) {
+ return connector.isActive();
}
- }
- return result;
+ }).parallel(new Func1<Observable<ISearchByViewPort>, Observable<SearchResult>>() {
+ @Override
+ public Observable<SearchResult> call(final Observable<ISearchByViewPort> connector) {
+ return connector.map(new Func1<ISearchByViewPort, SearchResult>() {
+ @Override
+ public SearchResult call(final ISearchByViewPort connector) {
+ return connector.searchByViewport(viewport, tokens);
+ }
+ });
+ }
+ }, Schedulers.io()).reduce(new SearchResult(), new Func2<SearchResult, SearchResult, SearchResult>() {
+
+ @Override
+ public SearchResult call(final SearchResult result, final SearchResult searchResult) {
+ result.addSearchResult(searchResult);
+ return result;
+ }
+ });
}
public static String getGeocodeFromURL(final String url) {
@@ -200,6 +221,12 @@ public final class ConnectorFactory {
return TRACKABLE_CONNECTORS;
}
+ /**
+ * Get the geocode of a trackable from a URL.
+ *
+ * @param url
+ * @return {@code null} if the URL cannot be decoded
+ */
public static String getTrackableFromURL(final String url) {
if (url == null) {
return null;
diff --git a/main/src/cgeo/geocaching/connector/UserAction.java b/main/src/cgeo/geocaching/connector/UserAction.java
index d0c97bb..e9ee4a3 100644
--- a/main/src/cgeo/geocaching/connector/UserAction.java
+++ b/main/src/cgeo/geocaching/connector/UserAction.java
@@ -1,8 +1,7 @@
package cgeo.geocaching.connector;
-import cgeo.geocaching.utils.RunnableWithArgument;
-
import org.eclipse.jdt.annotation.NonNull;
+import rx.functions.Action1;
import android.app.Activity;
@@ -19,14 +18,15 @@ public class UserAction {
}
public final int displayResourceId;
- private final @NonNull RunnableWithArgument<Context> runnable;
+ private final @NonNull
+ Action1<Context> runnable;
- public UserAction(int displayResourceId, final @NonNull RunnableWithArgument<UserAction.Context> runnable) {
+ public UserAction(int displayResourceId, final @NonNull Action1<Context> runnable) {
this.displayResourceId = displayResourceId;
this.runnable = runnable;
}
public void run(Context context) {
- runnable.run(context);
+ runnable.call(context);
}
}
diff --git a/main/src/cgeo/geocaching/connector/capability/FieldNotesCapability.java b/main/src/cgeo/geocaching/connector/capability/FieldNotesCapability.java
new file mode 100644
index 0000000..4da9705
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/FieldNotesCapability.java
@@ -0,0 +1,13 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.connector.IConnector;
+
+import java.io.File;
+
+/**
+ * Connector interface to implement an upload of (already exported) field notes
+ *
+ */
+public interface FieldNotesCapability extends IConnector {
+ public boolean uploadFieldNotes(final File exportFile);
+}
diff --git a/main/src/cgeo/geocaching/connector/ec/ECApi.java b/main/src/cgeo/geocaching/connector/ec/ECApi.java
index 03fce4d..702e557 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECApi.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECApi.java
@@ -15,12 +15,12 @@ import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.SynchronizedDateFormat;
import ch.boye.httpclientandroidlib.HttpResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -39,7 +39,7 @@ public class ECApi {
private static final String API_HOST = "https://extremcaching.com/exports/";
private static final ECLogin ecLogin = ECLogin.getInstance();
- private static final FastDateFormat LOG_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US);
+ private static final SynchronizedDateFormat LOG_DATE_FORMAT = new SynchronizedDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US);
public static String getIdFromGeocode(final String geocode) {
return StringUtils.removeStartIgnoreCase(geocode, "EC");
diff --git a/main/src/cgeo/geocaching/connector/ec/ECConnector.java b/main/src/cgeo/geocaching/connector/ec/ECConnector.java
index 6da076b..71716fe 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECConnector.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECConnector.java
@@ -140,7 +140,7 @@ public class ECConnector extends AbstractConnector implements ISearchByGeocode,
// invoke settings activity to insert login details
if (status == StatusCode.NO_LOGIN_INFO_STORED && fromActivity != null) {
- SettingsActivity.jumpToServicesPage(fromActivity);
+ SettingsActivity.openForScreen(R.string.preference_screen_ec, fromActivity);
}
}
return status == StatusCode.NO_ERROR;
diff --git a/main/src/cgeo/geocaching/connector/ec/ECLogin.java b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
index 52bd423..012bdc9 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECLogin.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
@@ -10,7 +10,6 @@ import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.Nullable;
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index e946748..925f6f0 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -10,6 +10,7 @@ import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.AbstractConnector;
import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.UserAction;
+import cgeo.geocaching.connector.capability.FieldNotesCapability;
import cgeo.geocaching.connector.capability.ICredentials;
import cgeo.geocaching.connector.capability.ILogin;
import cgeo.geocaching.connector.capability.ISearchByCenter;
@@ -23,26 +24,29 @@ import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.loaders.RecaptchaReceiver;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.settings.SettingsActivity;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import rx.functions.Action1;
+
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
+import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
-public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder {
+public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder, FieldNotesCapability {
private static final String CACHE_URL_SHORT = "http://coord.info/";
// Double slash is used to force open in browser
@@ -91,7 +95,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
@Override
public boolean supportsPersonalNote() {
- return Settings.isPremiumMember();
+ return Settings.isGCPremiumMember();
}
@Override
@@ -285,7 +289,22 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
@Override
protected String getCacheUrlPrefix() {
- return CACHE_URL_SHORT;
+ return null; // UNUSED
+ }
+
+ @Override
+ public String getGeocodeFromUrl(String url) {
+ // coord.info URLs
+ String code = StringUtils.substringAfterLast(url, "coord.info/");
+ if (code != null && canHandle(code)) {
+ return code;
+ }
+ // expanded geocaching.com URLs
+ code = StringUtils.substringBetween(url, "/geocache/", "_");
+ if (code != null && canHandle(code)) {
+ return code;
+ }
+ return null;
}
@Override
@@ -316,7 +335,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
// invoke settings activity to insert login details
if (status == StatusCode.NO_LOGIN_INFO_STORED && fromActivity != null) {
- SettingsActivity.jumpToServicesPage(fromActivity);
+ SettingsActivity.openForScreen(R.string.preference_screen_gc, fromActivity);
}
}
return status == StatusCode.NO_ERROR;
@@ -379,17 +398,17 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
public @NonNull
List<UserAction> getUserActions() {
List<UserAction> actions = super.getUserActions();
- actions.add(new UserAction(R.string.user_menu_open_browser, new RunnableWithArgument<UserAction.Context>() {
+ actions.add(new UserAction(R.string.user_menu_open_browser, new Action1<UserAction.Context>() {
@Override
- public void run(cgeo.geocaching.connector.UserAction.Context context) {
+ public void call(cgeo.geocaching.connector.UserAction.Context context) {
context.activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + Network.encode(context.userName))));
}
}));
- actions.add(new UserAction(R.string.user_menu_send_message, new RunnableWithArgument<UserAction.Context>() {
+ actions.add(new UserAction(R.string.user_menu_send_message, new Action1<UserAction.Context>() {
@Override
- public void run(cgeo.geocaching.connector.UserAction.Context context) {
+ public void call(cgeo.geocaching.connector.UserAction.Context context) {
context.activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/email/?u=" + Network.encode(context.userName))));
}
}));
@@ -406,4 +425,40 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
return GCParser.searchByUsername(username, Settings.getCacheType(), Settings.isShowCaptcha(), recaptchaReceiver);
}
+ @Override
+ public boolean uploadFieldNotes(final File exportFile) {
+ if (!GCLogin.getInstance().isActualLoginStatus()) {
+ // no need to upload (possibly large file) if we're not logged in
+ final StatusCode loginState = GCLogin.getInstance().login();
+ if (loginState != StatusCode.NO_ERROR) {
+ Log.e("FieldnoteExport.ExportTask upload: Login failed");
+ }
+ }
+
+ final String uri = "http://www.geocaching.com/my/uploadfieldnotes.aspx";
+ final String page = GCLogin.getInstance().getRequestLogged(uri, null);
+
+ if (StringUtils.isBlank(page)) {
+ Log.e("FieldnoteExport.ExportTask get page: No data from server");
+ return false;
+ }
+
+ final String[] viewstates = GCLogin.getViewstates(page);
+
+ final Parameters uploadParams = new Parameters(
+ "__EVENTTARGET", "",
+ "__EVENTARGUMENT", "",
+ "ctl00$ContentBody$btnUpload", "Upload Field Note");
+
+ GCLogin.putViewstates(uploadParams, viewstates);
+
+ Network.getResponseData(Network.postRequest(uri, uploadParams, "ctl00$ContentBody$FieldNoteLoader", "text/plain", exportFile));
+
+ if (StringUtils.isBlank(page)) {
+ Log.e("FieldnoteExport.ExportTask upload: No data from server");
+ return false;
+ }
+ return true;
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
index 3900a95..cfc369d 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.connector.gc;
+import org.eclipse.jdt.annotation.NonNull;
+
import java.util.Locale;
import java.util.regex.Pattern;
@@ -15,13 +17,13 @@ public final class GCConstants {
static final String GC_URL = "http://www.geocaching.com/";
static final String GC_TILE_URL = "http://tiles.geocaching.com/";
/** Live Map */
- public final static String URL_LIVE_MAP = GC_URL + "map/default.aspx";
+ public final static @NonNull String URL_LIVE_MAP = GC_URL + "map/default.aspx";
/** Live Map pop-up */
- public final static String URL_LIVE_MAP_DETAILS = GC_TILE_URL + "map.details";
+ public final static @NonNull String URL_LIVE_MAP_DETAILS = GC_TILE_URL + "map.details";
/** Caches in a tile */
- public final static String URL_MAP_INFO = GC_TILE_URL + "map.info";
+ public final static @NonNull String URL_MAP_INFO = GC_TILE_URL + "map.info";
/** Tile itself */
- public final static String URL_MAP_TILE = GC_TILE_URL + "map.png";
+ public final static @NonNull String URL_MAP_TILE = GC_TILE_URL + "map.png";
/**
* Patterns for parsing the result of a (detailed) search
diff --git a/main/src/cgeo/geocaching/connector/gc/GCLogin.java b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
index a7cf6cf..250b0b2 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCLogin.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
@@ -14,7 +14,6 @@ import cgeo.geocaching.utils.MatcherWrapper;
import cgeo.geocaching.utils.TextUtils;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -97,7 +96,7 @@ public class GCLogin extends AbstractLogin {
}
if (getLoginStatus(loginData)) {
- Log.i("Already logged in Geocaching.com as " + username + " (" + Settings.getMemberStatus() + ')');
+ Log.i("Already logged in Geocaching.com as " + username + " (" + Settings.getGCMemberStatus() + ')');
if (switchToEnglish(loginData) && retry) {
return login(false);
}
@@ -132,7 +131,7 @@ public class GCLogin extends AbstractLogin {
assert loginData != null; // Caught above
if (getLoginStatus(loginData)) {
- Log.i("Successfully logged in Geocaching.com as " + username + " (" + Settings.getMemberStatus() + ')');
+ Log.i("Successfully logged in Geocaching.com as " + username + " (" + Settings.getGCMemberStatus() + ')');
if (switchToEnglish(loginData) && retry) {
return login(false);
@@ -204,9 +203,9 @@ public class GCLogin extends AbstractLogin {
Log.e("getLoginStatus: bad cache count", e);
}
setActualCachesFound(cachesCount);
- Settings.setMemberStatus(TextUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null));
- if ( page.contains(GCConstants.MEMBER_STATUS_RENEW) ) {
- Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM);
+ Settings.setGCMemberStatus(TextUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null));
+ if (page.contains(GCConstants.MEMBER_STATUS_RENEW)) {
+ Settings.setGCMemberStatus(GCConstants.MEMBER_STATUS_PM);
}
return true;
}
@@ -259,9 +258,9 @@ public class GCLogin extends AbstractLogin {
final String responseData = StringUtils.defaultString(Network.getResponseData(Network.getRequest("http://www.geocaching.com/my/")));
final String profile = TextUtils.replaceWhitespace(responseData);
- Settings.setMemberStatus(TextUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
+ Settings.setGCMemberStatus(TextUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
if (profile.contains(GCConstants.MEMBER_STATUS_RENEW)) {
- Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM);
+ Settings.setGCMemberStatus(GCConstants.MEMBER_STATUS_PM);
}
setActualCachesFound(Integer.parseInt(TextUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")));
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 6c94150..2782b64 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -368,7 +368,7 @@ public class GCMap {
}
}
- if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isPremiumMember()) {
+ if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
final Geopoint center = viewport.getCenter();
if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
//FIXME We don't have a RecaptchaReceiver!?
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 219adc8..8e59e5e 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -36,7 +36,6 @@ import cgeo.geocaching.utils.SynchronizedDateFormat;
import cgeo.geocaching.utils.TextUtils;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringEscapeUtils;
@@ -63,12 +62,13 @@ import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Set;
+import java.util.regex.Pattern;
public abstract class GCParser {
private final static SynchronizedDateFormat dateTbIn1 = new SynchronizedDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009
private final static SynchronizedDateFormat dateTbIn2 = new SynchronizedDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009
- private static SearchResult parseSearch(final String url, final String pageContent, final boolean showCaptcha, RecaptchaReceiver thread) {
+ private static SearchResult parseSearch(final String url, final String pageContent, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(pageContent)) {
Log.e("GCParser.parseSearch: No page given");
return null;
@@ -86,12 +86,12 @@ public abstract class GCParser {
final String recaptchaJsParam = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null);
if (recaptchaJsParam != null) {
- thread.setKey(recaptchaJsParam.trim());
+ recaptchaReceiver.setKey(recaptchaJsParam.trim());
- thread.fetchChallenge();
+ recaptchaReceiver.fetchChallenge();
}
- if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) {
- thread.notifyNeed();
+ if (recaptchaReceiver != null && StringUtils.isNotBlank(recaptchaReceiver.getChallenge())) {
+ recaptchaReceiver.notifyNeed();
}
}
@@ -277,12 +277,12 @@ public abstract class GCParser {
}
String recaptchaText = null;
- if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) {
- thread.waitForUser();
- recaptchaText = thread.getText();
+ if (recaptchaReceiver != null && StringUtils.isNotBlank(recaptchaReceiver.getChallenge())) {
+ recaptchaReceiver.waitForUser();
+ recaptchaText = recaptchaReceiver.getText();
}
- if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && ((thread == null || StringUtils.isBlank(thread.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) {
+ if (!cids.isEmpty() && (Settings.isGCPremiumMember() || showCaptcha) && ((recaptchaReceiver == null || StringUtils.isBlank(recaptchaReceiver.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) {
Log.i("Trying to get .loc for " + cids.size() + " caches");
try {
@@ -303,8 +303,8 @@ public abstract class GCParser {
params.put("CID", cid);
}
- if (thread != null && StringUtils.isNotBlank(thread.getChallenge()) && StringUtils.isNotBlank(recaptchaText)) {
- params.put("recaptcha_challenge_field", thread.getChallenge());
+ if (StringUtils.isNotBlank(recaptchaText) && recaptchaReceiver != null) {
+ params.put("recaptcha_challenge_field", recaptchaReceiver.getChallenge());
params.put("recaptcha_response_field", recaptchaText);
}
params.put("ctl00$ContentBody$uxDownloadLoc", "Download Waypoints");
@@ -347,6 +347,9 @@ public abstract class GCParser {
// attention: parseCacheFromText already stores implicitly through searchResult.addCache
if (searchResult != null && !searchResult.getGeocodes().isEmpty()) {
final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
+ if (cache == null) {
+ return null;
+ }
getExtraOnlineInfo(cache, page, handler);
// too late: it is already stored through parseCacheFromText
cache.setDetailedUpdatedNow();
@@ -741,7 +744,7 @@ public abstract class GCParser {
cache.parseWaypointsFromNote();
// logs
- cache.setLogs(loadLogsFromDetails(page, cache, false, true));
+ cache.setLogs(getLogsFromDetails(page, false));
// last check for necessary cache conditions
if (StringUtils.isBlank(cache.getGeocode())) {
@@ -1308,7 +1311,7 @@ public abstract class GCParser {
return false; // error
}
- final boolean guidOnPage = cache.isGuidContainedInPage(page);
+ final boolean guidOnPage = isGuidContainedInPage(cache, page);
if (guidOnPage) {
Log.i("GCParser.addToWatchlist: cache is on watchlist");
cache.setOnWatchlist(true);
@@ -1342,7 +1345,7 @@ public abstract class GCParser {
GCLogin.transferViewstates(page, params);
page = Network.getResponseData(Network.postRequest(uri, params));
- final boolean guidOnPage = cache.isGuidContainedInPage(page);
+ final boolean guidOnPage = isGuidContainedInPage(cache, page);
if (!guidOnPage) {
Log.i("GCParser.removeFromWatchlist: cache removed from watchlist");
cache.setOnWatchlist(false);
@@ -1352,6 +1355,21 @@ public abstract class GCParser {
return !guidOnPage; // on watch list (=error) / not on watch list
}
+ /**
+ * Checks if a page contains the guid of a cache
+ *
+ * @param cache the geocache
+ * @param page
+ * the page to search in, may be null
+ * @return true if the page contains the guid of the cache, false otherwise
+ */
+ private static boolean isGuidContainedInPage(final Geocache cache, final String page) {
+ if (StringUtils.isBlank(page) || StringUtils.isBlank(cache.getGuid())) {
+ return false;
+ }
+ return Pattern.compile(cache.getGuid(), Pattern.CASE_INSENSITIVE).matcher(page).find();
+ }
+
@Nullable
static String requestHtmlPage(@Nullable final String geocode, @Nullable final String guid, final String log, final String numlogs) {
final Parameters params = new Parameters("decrypt", "y");
@@ -1380,8 +1398,7 @@ public abstract class GCParser {
}
private static boolean changeFavorite(final Geocache cache, final boolean add) {
- final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = getUserToken(cache);
if (StringUtils.isEmpty(userToken)) {
return false;
}
@@ -1400,6 +1417,11 @@ public abstract class GCParser {
return false;
}
+ private static String getUserToken(final Geocache cache) {
+ final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
+ return TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ }
+
/**
* Removes the cache from the favorites.
*
@@ -1617,19 +1639,20 @@ public abstract class GCParser {
}
/**
- * Load logs from a cache details page.
+ * Extract logs from a cache details page.
*
* @param page
* the text of the details page
- * @param cache
- * the cache object to put the logs in
* @param friends
- * retrieve friend logs
+ * return friends logs only (will require a network request)
+ * @return a list of log entries or <code>null</code> if the logs could not be retrieved
+ *
*/
- private static List<LogEntry> loadLogsFromDetails(final String page, final Geocache cache, final boolean friends, final boolean getDataFromPage) {
+ @Nullable
+ private static List<LogEntry> getLogsFromDetails(final String page, final boolean friends) {
String rawResponse;
- if (!getDataFromPage) {
+ if (friends) {
final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page);
if (!userTokenMatcher.find()) {
Log.e("GCParser.loadLogsFromDetails: unable to extract userToken");
@@ -1716,7 +1739,7 @@ public abstract class GCParser {
final JSONArray images = entry.getJSONArray("Images");
for (int i = 0; i < images.length(); i++) {
final JSONObject image = images.getJSONObject(i);
- final String url = "http://img.geocaching.com/cache/log/large/" + image.getString("FileName");
+ final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName");
final String title = TextUtils.removeControlCharacters(image.getString("Name"));
final Image logImage = new Image(url, title);
logDone.addLogImage(logImage);
@@ -1829,7 +1852,7 @@ public abstract class GCParser {
if (Settings.isFriendLogsWanted()) {
CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
final List<LogEntry> allLogs = cache.getLogs();
- final List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false);
+ final List<LogEntry> friendLogs = getLogsFromDetails(page, true);
if (friendLogs != null) {
for (final LogEntry log : friendLogs) {
if (allLogs.contains(log)) {
@@ -1864,8 +1887,7 @@ public abstract class GCParser {
}
public static boolean editModifiedCoordinates(Geocache cache, Geopoint wpt) {
- final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = getUserToken(cache);
if (StringUtils.isEmpty(userToken)) {
return false;
}
@@ -1900,8 +1922,7 @@ public abstract class GCParser {
}
public static boolean uploadPersonalNote(Geocache cache) {
- final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = getUserToken(cache);
if (StringUtils.isEmpty(userToken)) {
return false;
}
diff --git a/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java b/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java
new file mode 100644
index 0000000..ff3f5ef
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java
@@ -0,0 +1,114 @@
+package cgeo.geocaching.connector.gc;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.loaders.RecaptchaReceiver;
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.io.IOUtils;
+
+import rx.Observable;
+import rx.android.observables.AndroidObservable;
+import rx.schedulers.Schedulers;
+import rx.functions.Action1;
+import rx.functions.Func0;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+
+import java.io.InputStream;
+
+public class RecaptchaHandler extends Handler {
+ final public static int SHOW_CAPTCHA = 1;
+
+ final private Activity activity;
+ final private RecaptchaReceiver recaptchaReceiver;
+
+ public RecaptchaHandler(final Activity activity, final RecaptchaReceiver recaptchaReceiver) {
+ this.activity = activity;
+ this.recaptchaReceiver = recaptchaReceiver;
+ }
+
+ private void loadChallenge(final ImageView imageView, final View reloadButton) {
+ getCaptcha().subscribe(new Action1<Bitmap>() {
+ @Override
+ public void call(final Bitmap bitmap) {
+ imageView.setImageBitmap(bitmap);
+ }
+ }, new Action1<Throwable>() {
+ @Override
+ public void call(final Throwable throwable) {
+ // Do nothing
+ }
+ });
+ reloadButton.setEnabled(true);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == SHOW_CAPTCHA) {
+ final AlertDialog.Builder dlg = new AlertDialog.Builder(activity);
+ final View view = activity.getLayoutInflater().inflate(R.layout.recaptcha_dialog, null);
+
+ final ImageView imageView = (ImageView) view.findViewById(R.id.image);
+
+ final ImageButton reloadButton = (ImageButton) view.findViewById(R.id.button_recaptcha_refresh);
+ reloadButton.setEnabled(false);
+ reloadButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ recaptchaReceiver.fetchChallenge();
+ loadChallenge(imageView, reloadButton);
+ }
+ });
+
+ loadChallenge(imageView, reloadButton);
+
+ dlg.setTitle(activity.getString(R.string.caches_recaptcha_title));
+ dlg.setView(view);
+ dlg.setNeutralButton(activity.getString(R.string.caches_recaptcha_continue), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ final String text = ((EditText) view.findViewById(R.id.text)).getText().toString();
+ recaptchaReceiver.setText(text);
+ dialog.cancel();
+ }
+ });
+
+ dlg.create().show();
+ }
+ }
+
+ private Observable<Bitmap> getCaptcha() {
+ return AndroidObservable.fromActivity(activity,
+ Observable.defer(new Func0<Observable<? extends Bitmap>>() {
+ @Override
+ public Observable<? extends Bitmap> call() {
+ final String url = "http://www.google.com/recaptcha/api/image?c=" + recaptchaReceiver.getChallenge();
+ final InputStream is = Network.getResponseStream(Network.getRequest(url));
+ if (is != null) {
+ try {
+ final Bitmap img = BitmapFactory.decodeStream(is);
+ return Observable.from(img);
+ } catch (final Exception e) {
+ Log.e("RecaptchaHandler.getCaptcha", e);
+ return Observable.error(e);
+ } finally {
+ IOUtils.closeQuietly(is);
+ }
+ }
+ return Observable.empty();
+ }
+ }).subscribeOn(Schedulers.io()));
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/gc/SearchHandler.java b/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
deleted file mode 100644
index 795ed2f..0000000
--- a/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package cgeo.geocaching.connector.gc;
-
-import cgeo.geocaching.R;
-import cgeo.geocaching.loaders.RecaptchaReceiver;
-import cgeo.geocaching.utils.Log;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Handler;
-import android.os.Message;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-public class SearchHandler extends Handler {
- private Activity activity = null;
- private Resources res = null;
- private RecaptchaReceiver recaptchaThread = null;
- private ImageView imageView = null;
- private Bitmap img = null;
-
- private Handler imgHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- try {
- if (img != null && imageView != null) {
- imageView.setImageBitmap(img);
- }
- } catch (Exception e) {
- Log.e("Error setting reCAPTCHA image", e);
- }
- }
- };
-
- public SearchHandler(Activity activityIn, Resources resIn, RecaptchaReceiver recaptchaThreadIn) {
- activity = activityIn;
- res = resIn;
- recaptchaThread = recaptchaThreadIn;
- }
-
- @Override
- public void handleMessage(Message msg) {
- try {
- if (msg.what == 1) {
- final AlertDialog.Builder dlg = new AlertDialog.Builder(activity);
- final LayoutInflater inflater = activity.getLayoutInflater();
- final View view = inflater.inflate(R.layout.recaptcha_dialog, null);
-
- imageView = (ImageView) view.findViewById(R.id.image);
-
- ImageButton reloadButton = (ImageButton) view.findViewById(R.id.button_recaptcha_refresh);
- reloadButton.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- recaptchaThread.fetchChallenge();
- try {
- (new GetCaptchaThread(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start();
- } catch (MalformedURLException e) {
- Log.e("Bad reCAPTCHA image url", e);
- }
- }
- });
-
- (new GetCaptchaThread(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start();
-
- dlg.setTitle(res.getString(R.string.caches_recaptcha_title));
- dlg.setView(view);
- dlg.setNeutralButton(res.getString(R.string.caches_recaptcha_continue), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- final String text = ((EditText) view.findViewById(R.id.text)).getText().toString();
-
- recaptchaThread.setText(text);
-
- dialog.cancel();
- }
- });
-
- dlg.create().show();
- }
- } catch (MalformedURLException e) {
- Log.e("Error in reCAPTCHA handler", e);
- }
- }
-
- private class GetCaptchaThread extends Thread {
- private URL uri = null;
-
- public GetCaptchaThread(URL uriIn) {
- uri = uriIn;
- }
-
- @Override
- public void run() {
- try {
- Log.d("Getting reCAPTCHA image from: " + uri.toString());
- HttpURLConnection connection = (HttpURLConnection) uri.openConnection();
- connection.setDoInput(true);
- connection.connect();
-
- InputStream is = connection.getInputStream();
-
- img = BitmapFactory.decodeStream(is);
-
- is.close();
-
- imgHandler.sendEmptyMessage(0);
- } catch (IOException e) {
- Log.e("Failed to download reCAPTCHA image", e);
- }
- }
- }
-}
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 623730a..6a257cd 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -10,6 +10,8 @@ import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
+import org.eclipse.jdt.annotation.NonNull;
+
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -110,6 +112,7 @@ public class Tile {
* @see <a
* href="http://developers.cloudmade.com/projects/tiles/examples/convert-coordinates-to-tile-numbers">Cloudmade</a>
*/
+ @NonNull
public Geopoint getCoord(UTFGridPosition pos) {
double pixX = tileX * TILE_SIZE + pos.x * 4;
@@ -244,7 +247,7 @@ public class Tile {
return null;
}
- public boolean containsPoint(final ICoordinates point) {
+ public boolean containsPoint(final @NonNull ICoordinates point) {
return viewPort.contains(point);
}
diff --git a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
index dacb626..acf7b48 100644
--- a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
+++ b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.connector.oc;
+import org.eclipse.jdt.annotation.NonNull;
+
public interface IOCAuthParams {
/**
@@ -7,6 +9,7 @@ public interface IOCAuthParams {
*
* @return
*/
+ @NonNull
String getSite();
/**
@@ -63,5 +66,6 @@ public interface IOCAuthParams {
*
* @return
*/
+ @NonNull
String getCallbackUri();
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
index 46e4c96..284234e 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
@@ -90,4 +90,16 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
public int getTokenSecretPrefKeyId() {
return 0;
}
+
+ /**
+ * Checks if a search based on a user name targets the current user
+ *
+ * @param username
+ * Name of the user the query is searching after
+ * @return True - search target and current is same, False - current user not known or not the same as username
+ */
+ @SuppressWarnings("static-method")
+ public boolean isSearchForMyCaches(String username) {
+ return false;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
index 0b7493c..049c633 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
@@ -173,4 +173,10 @@ public class OCApiLiveConnector extends OCApiConnector implements ISearchByCente
final Geopoint currentPos = CgeoApplication.getInstance().currentGeo().getCoords();
return new SearchResult(OkapiClient.getCachesNamed(currentPos, name, this));
}
+
+ @Override
+ public boolean isSearchForMyCaches(String username) {
+ return StringUtils.equalsIgnoreCase(username, getUserName());
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java b/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java
index c082bac..19f4447 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java
@@ -2,9 +2,13 @@ package cgeo.geocaching.connector.oc;
import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;
+import cgeo.geocaching.connector.oc.OkapiError.OkapiErrors;
import cgeo.geocaching.network.OAuthAuthorizationActivity;
import cgeo.geocaching.settings.Settings;
+import ch.boye.httpclientandroidlib.HttpResponse;
+
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.Nullable;
@@ -52,4 +56,16 @@ public abstract class OCAuthorizationActivity extends OAuthAuthorizationActivity
return res.getString(R.string.auth_dialog_completed_oc, getAuthTitle());
}
+ /**
+ * Return an extended error in case of an invalid time stamp
+ */
+ @Override
+ protected String getExtendedErrorMsg(HttpResponse response) {
+ OkapiError error = OkapiClient.decodeErrorResponse(response);
+ if (error.getResult() == OkapiErrors.INVALID_TIMESTAMP) {
+ return res.getString(R.string.init_login_popup_invalid_timestamp);
+ }
+ return StringUtils.EMPTY;
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 2175935..712bb26 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -34,7 +34,6 @@ import cgeo.geocaching.utils.SynchronizedDateFormat;
import ch.boye.httpclientandroidlib.HttpResponse;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@@ -61,7 +60,7 @@ final class OkapiClient {
private static final char SEPARATOR = '|';
private static final String SEPARATOR_STRING = Character.toString(SEPARATOR);
- private static final FastDateFormat LOG_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US);
+ private static final SynchronizedDateFormat LOG_DATE_FORMAT = new SynchronizedDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US);
private static final SynchronizedDateFormat ISO8601DATEFORMAT = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
private static final String CACHE_ATTRNAMES = "attrnames";
@@ -75,7 +74,8 @@ final class OkapiClient {
private static final String CACHE_STATUS_ARCHIVED = "Archived";
private static final String CACHE_STATUS_DISABLED = "Temporarily unavailable";
private static final String CACHE_IS_FOUND = "is_found";
- private static final String CACHE_SIZE = "size";
+ private static final String CACHE_SIZE_DEPRECATED = "size";
+ private static final String CACHE_SIZE2 = "size2";
private static final String CACHE_VOTES = "rating_votes";
private static final String CACHE_NOTFOUNDS = "notfounds";
private static final String CACHE_FOUNDS = "founds";
@@ -112,7 +112,7 @@ final class OkapiClient {
// the several realms of possible fields for cache retrieval:
// Core: for livemap requests (L3 - only with level 3 auth)
// Additional: additional fields for full cache (L3 - only for level 3 auth, current - only for connectors with current api)
- private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size|date_hidden";
+ private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size|size2|date_hidden";
private static final String SERVICE_CACHE_CORE_L3_FIELDS = "is_found";
private static final String SERVICE_CACHE_ADDITIONAL_FIELDS = "owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|alt_wpts|attrnames|req_passwd";
private static final String SERVICE_CACHE_ADDITIONAL_CURRENT_FIELDS = "gc_code|attribution_note|attr_acodes";
@@ -148,23 +148,18 @@ final class OkapiClient {
valueMap.put("limit", "20");
valueMap.put("radius", "200");
- return requestCaches(connector, params, valueMap);
+ return requestCaches(connector, params, valueMap, false);
}
public static List<Geocache> getCachesByOwner(final String username, final OCApiConnector connector) {
- final Parameters params = new Parameters("search_method", METHOD_SEARCH_ALL);
- final Map<String, String> valueMap = new LinkedHashMap<String, String>();
- final @Nullable
- String uuid = getUserUUID(connector, username);
- if (StringUtils.isEmpty(uuid)) {
- return Collections.emptyList();
- }
- valueMap.put("owner_uuid", uuid);
-
- return requestCaches(connector, params, valueMap);
+ return getCachesByUser(username, connector, "owner_uuid");
}
public static List<Geocache> getCachesByFinder(final String username, final OCApiConnector connector) {
+ return getCachesByUser(username, connector, "found_by");
+ }
+
+ private static List<Geocache> getCachesByUser(final String username, final OCApiConnector connector, final String userRequestParam) {
final Parameters params = new Parameters("search_method", METHOD_SEARCH_ALL);
final Map<String, String> valueMap = new LinkedHashMap<String, String>();
final @Nullable
@@ -172,9 +167,9 @@ final class OkapiClient {
if (StringUtils.isEmpty(uuid)) {
return Collections.emptyList();
}
- valueMap.put("found_by", uuid);
+ valueMap.put(userRequestParam, uuid);
- return requestCaches(connector, params, valueMap);
+ return requestCaches(connector, params, valueMap, connector.isSearchForMyCaches(username));
}
public static List<Geocache> getCachesNamed(final Geopoint center, final String namePart, final OCApiConnector connector) {
@@ -195,16 +190,16 @@ final class OkapiClient {
// full wildcard search, maybe we need to change this after some testing and evaluation
valueMap.put("name", "*" + namePart + "*");
- return requestCaches(connector, params, valueMap);
+ return requestCaches(connector, params, valueMap, false);
}
- private static List<Geocache> requestCaches(final OCApiConnector connector, final Parameters params, final Map<String, String> valueMap) {
+ private static List<Geocache> requestCaches(final OCApiConnector connector, final Parameters params, final Map<String, String> valueMap, final boolean my) {
// if a global type filter is set, and OKAPI does not know that type, then return an empty list instead of all caches
if (Settings.getCacheType() != CacheType.ALL && StringUtils.isBlank(getFilterFromType())) {
return Collections.emptyList();
}
- addFilterParams(valueMap, connector);
+ addFilterParams(valueMap, connector, my);
params.add("search_params", new JSONObject(valueMap).toString());
addRetrieveParams(params, connector);
@@ -234,7 +229,7 @@ final class OkapiClient {
final Map<String, String> valueMap = new LinkedHashMap<String, String>();
valueMap.put("bbox", bboxString);
- return requestCaches(connector, params, valueMap);
+ return requestCaches(connector, params, valueMap, false);
}
public static boolean setWatchState(final Geocache cache, final boolean watched, final OCApiConnector connector) {
@@ -386,6 +381,7 @@ final class OkapiClient {
}
if (!response.isNull(CACHE_MY_NOTES)) {
cache.setPersonalNote(response.getString(CACHE_MY_NOTES));
+ cache.parseWaypointsFromNote();
}
cache.setLogPasswordRequired(response.getBoolean(CACHE_REQ_PASSWORD));
@@ -489,6 +485,30 @@ final class OkapiClient {
if ("Didn't find it".equalsIgnoreCase(logType)) {
return LogType.DIDNT_FIND_IT;
}
+ if ("Will attend".equalsIgnoreCase(logType)) {
+ return LogType.WILL_ATTEND;
+ }
+ if ("Attended".equalsIgnoreCase(logType)) {
+ return LogType.ATTENDED;
+ }
+ if ("Temporarily unavailable".equalsIgnoreCase(logType)) {
+ return LogType.TEMP_DISABLE_LISTING;
+ }
+ if ("Ready to search".equalsIgnoreCase(logType)) {
+ return LogType.ENABLE_LISTING;
+ }
+ if ("Archived".equalsIgnoreCase(logType)) {
+ return LogType.ARCHIVE;
+ }
+ if ("Needs maintenance".equalsIgnoreCase(logType)) {
+ return LogType.NEEDS_MAINTENANCE;
+ }
+ if ("Moved".equalsIgnoreCase(logType)) {
+ return LogType.UPDATE_COORDINATES;
+ }
+ if ("OC Team comment".equalsIgnoreCase(logType)) {
+ return LogType.POST_REVIEWER_NOTE;
+ }
return LogType.NOTE;
}
@@ -567,12 +587,25 @@ final class OkapiClient {
}
private static CacheSize getCacheSize(final JSONObject response) {
- if (response.isNull(CACHE_SIZE)) {
+ if (response.isNull(CACHE_SIZE2)) {
+ return getCacheSizeDeprecated(response);
+ }
+ try {
+ final String size = response.getString(CACHE_SIZE2);
+ return CacheSize.getById(size);
+ } catch (JSONException e) {
+ Log.e("OkapiClient.getCacheSize", e);
+ return getCacheSizeDeprecated(response);
+ }
+ }
+
+ private static CacheSize getCacheSizeDeprecated(final JSONObject response) {
+ if (response.isNull(CACHE_SIZE_DEPRECATED)) {
return CacheSize.NOT_CHOSEN;
}
double size = 0;
try {
- size = response.getDouble(CACHE_SIZE);
+ size = response.getDouble(CACHE_SIZE_DEPRECATED);
} catch (final JSONException e) {
Log.e("OkapiClient.getCacheSize", e);
}
@@ -586,7 +619,7 @@ final class OkapiClient {
case 4:
return CacheSize.LARGE;
case 5:
- return CacheSize.LARGE;
+ return CacheSize.VERY_LARGE;
default:
break;
}
@@ -687,11 +720,11 @@ final class OkapiClient {
return "en";
}
- private static void addFilterParams(final Map<String, String> valueMap, final OCApiConnector connector) {
+ private static void addFilterParams(final Map<String, String> valueMap, final OCApiConnector connector, final boolean my) {
if (!Settings.isExcludeDisabledCaches()) {
valueMap.put("status", "Available|Temporarily unavailable");
}
- if (Settings.isExcludeMyCaches() && connector.getSupportedAuthLevel() == OAuthLevel.Level3) {
+ if (!my && Settings.isExcludeMyCaches() && connector.getSupportedAuthLevel() == OAuthLevel.Level3) {
valueMap.put("exclude_my_own", "true");
valueMap.put("found_status", "notfound_only");
}
@@ -789,6 +822,21 @@ final class OkapiClient {
}
/**
+ * Retrieves error information from an unsuccessful Okapi-response
+ *
+ * @param response
+ * response containing an error object
+ * @return OkapiError object with detailed information
+ */
+ public static OkapiError decodeErrorResponse(HttpResponse response) {
+ final JSONResult result = new JSONResult(response);
+ if (!result.isSuccess) {
+ return new OkapiError(result.data);
+ }
+ return new OkapiError(new JSONObject());
+ }
+
+ /**
* Encapsulates response state and content of an HTTP-request that expects a JSON result. <code>isSuccess</code> is
* only true, if the response state was success and <code>data</code> is not null.
*/
diff --git a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
index f72b698..5f11a11 100644
--- a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
+++ b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
@@ -28,10 +28,10 @@ public class OXGPXParser extends GPX10Parser {
/**
* The short description of OX caches contains "title by owner, type(T/D/Awesomeness)". That is a lot of
* duplication.
- *
+ *
* @param cache
*/
private static void removeTitleFromShortDescription(final @NonNull Geocache cache) {
- cache.setShortDescription(StringUtils.substringAfterLast(cache.getShortDescription(), ","));
+ cache.setShortDescription(StringUtils.trim(StringUtils.substringAfterLast(cache.getShortDescription(), ",")));
}
}
diff --git a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
index 2defc52..0137af4 100644
--- a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
+++ b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
@@ -11,7 +11,6 @@ import cgeo.geocaching.utils.CryptUtils;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.jdt.annotation.NonNull;
diff --git a/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java
index 69efddc..fb554b9 100644
--- a/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.connector.AbstractConnector;
import cgeo.geocaching.connector.UserAction;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import java.util.List;
@@ -15,7 +16,8 @@ public abstract class AbstractTrackableConnector implements TrackableConnector {
}
@Override
- public String getTrackableCodeFromUrl(@NonNull String url) {
+ public @Nullable
+ String getTrackableCodeFromUrl(@NonNull String url) {
return null;
}
diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
index 8387076..03052f9 100644
--- a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
@@ -4,6 +4,10 @@ import cgeo.geocaching.Trackable;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.utils.Log;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
import java.util.regex.Pattern;
public class GeokretyConnector extends AbstractTrackableConnector {
@@ -29,7 +33,7 @@ public class GeokretyConnector extends AbstractTrackableConnector {
return GeokretyParser.parse(page);
}
- private static int getId(String geocode) {
+ protected static int getId(String geocode) {
try {
final String hex = geocode.substring(2);
return Integer.parseInt(hex, 16);
@@ -39,4 +43,25 @@ public class GeokretyConnector extends AbstractTrackableConnector {
return -1;
}
+ @Override
+ public @Nullable
+ String getTrackableCodeFromUrl(@NonNull String url) {
+ // http://geokrety.org/konkret.php?id=38545
+ String id = StringUtils.substringAfterLast(url, "konkret.php?id=");
+ if (StringUtils.isNumeric(id)) {
+ return geocode(Integer.parseInt(id));
+ }
+ return null;
+ }
+
+ /**
+ * Get geocode from geokrety id
+ *
+ * @param id
+ * @return
+ */
+ public static String geocode(final int id) {
+ return String.format("GK%04X", id);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java
index ee8c8c0..0e64abd 100644
--- a/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java
+++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java
@@ -37,8 +37,8 @@ public class GeokretyParser {
public void start(Attributes attributes) {
try {
final String kretyId = attributes.getValue("id");
- if (StringUtils.isNotBlank(kretyId)) {
- trackable.setGeocode(geocode(Integer.parseInt(kretyId)));
+ if (StringUtils.isNumeric(kretyId)) {
+ trackable.setGeocode(GeokretyConnector.geocode(Integer.parseInt(kretyId)));
}
final String distance = attributes.getValue("dist");
if (StringUtils.isNotBlank(distance)) {
@@ -88,8 +88,4 @@ public class GeokretyParser {
}
return null;
}
-
- protected static String geocode(final int id) {
- return String.format("GK%04X", id);
- }
}
diff --git a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
index 0990d96..6071b5f 100644
--- a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.Trackable;
import cgeo.geocaching.connector.UserAction;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import java.util.List;
@@ -21,7 +22,8 @@ public interface TrackableConnector {
public Trackable searchTrackable(String geocode, String guid, String id);
- public String getTrackableCodeFromUrl(final @NonNull String url);
+ public @Nullable
+ String getTrackableCodeFromUrl(final @NonNull String url);
public @NonNull
List<UserAction> getUserActions();
diff --git a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
index dad285c..77848d7 100644
--- a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
@@ -7,6 +7,7 @@ import cgeo.geocaching.connector.gc.GCParser;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import java.util.List;
import java.util.regex.Pattern;
@@ -20,7 +21,7 @@ public class TravelBugConnector extends AbstractTrackableConnector {
@Override
public boolean canHandleTrackable(String geocode) {
- return TravelBugConnector.PATTERN_TB_CODE.matcher(geocode).matches();
+ return TravelBugConnector.PATTERN_TB_CODE.matcher(geocode).matches() && !StringUtils.startsWithIgnoreCase(geocode, "GC");
}
@Override
@@ -54,8 +55,18 @@ public class TravelBugConnector extends AbstractTrackableConnector {
}
@Override
- public String getTrackableCodeFromUrl(@NonNull String url) {
- return StringUtils.substringAfterLast(url, "?tracker=");
+ public @Nullable
+ String getTrackableCodeFromUrl(@NonNull String url) {
+ // coord.info URLs
+ String code = StringUtils.substringAfterLast(url, "coord.info/");
+ if (code != null && canHandleTrackable(code)) {
+ return code;
+ }
+ code = StringUtils.substringAfterLast(url, "?tracker=");
+ if (code != null && canHandleTrackable(code)) {
+ return code;
+ }
+ return null;
}
@Override
diff --git a/main/src/cgeo/geocaching/enumerations/CacheAttribute.java b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java
index 472bad5..0703c3c 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheAttribute.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java
@@ -164,15 +164,11 @@ public enum CacheAttribute {
}
private final static Map<String, CacheAttribute> FIND_BY_GCRAWNAME;
- private final static SparseArray<CacheAttribute> FIND_BY_GCID = new SparseArray<CacheAttribute>();
private final static SparseArray<CacheAttribute> FIND_BY_OCACODE = new SparseArray<CacheAttribute>();
static {
final HashMap<String, CacheAttribute> mapGcRawNames = new HashMap<String, CacheAttribute>();
for (CacheAttribute attr : values()) {
mapGcRawNames.put(attr.rawName, attr);
- if (attr.gcid != NO_ID) {
- FIND_BY_GCID.put(attr.gcid, attr);
- }
if (attr.ocacode != NO_ID) {
FIND_BY_OCACODE.put(attr.ocacode, attr);
}
@@ -184,10 +180,6 @@ public enum CacheAttribute {
return rawName != null ? FIND_BY_GCRAWNAME.get(rawName) : null;
}
- public static CacheAttribute getByGcId(final int gcid) {
- return FIND_BY_GCID.get(gcid);
- }
-
public static CacheAttribute getByOcACode(final int ocAcode) {
return FIND_BY_OCACODE.get(ocAcode);
}
diff --git a/main/src/cgeo/geocaching/enumerations/CacheListType.java b/main/src/cgeo/geocaching/enumerations/CacheListType.java
index f482d5b..1fce282 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheListType.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheListType.java
@@ -1,23 +1,32 @@
package cgeo.geocaching.enumerations;
+import cgeo.geocaching.loaders.AbstractSearchLoader.CacheListLoaderType;
+
public enum CacheListType {
- OFFLINE(true),
- POCKET(false),
- HISTORY(true),
- NEAREST(false),
- COORDINATE(false),
- KEYWORD(false),
- ADDRESS(false),
- USERNAME(false),
- OWNER(false),
- MAP(false);
+ OFFLINE(true, CacheListLoaderType.OFFLINE),
+ POCKET(false, CacheListLoaderType.POCKET),
+ HISTORY(true, CacheListLoaderType.HISTORY),
+ NEAREST(false, CacheListLoaderType.NEAREST),
+ COORDINATE(false, CacheListLoaderType.COORDINATE),
+ KEYWORD(false, CacheListLoaderType.KEYWORD),
+ ADDRESS(false, CacheListLoaderType.ADDRESS),
+ FINDER(false, CacheListLoaderType.FINDER),
+ OWNER(false, CacheListLoaderType.OWNER),
+ MAP(false, CacheListLoaderType.MAP);
/**
* whether or not this list allows switching to another list
*/
public final boolean canSwitch;
- private CacheListType(final boolean canSwitch) {
+ public final CacheListLoaderType loaderType;
+
+ CacheListType(final boolean canSwitch, final CacheListLoaderType loaderType) {
this.canSwitch = canSwitch;
+ this.loaderType = loaderType;
+ }
+
+ public int getLoaderId() {
+ return loaderType.getLoaderId();
}
}
diff --git a/main/src/cgeo/geocaching/enumerations/CacheSize.java b/main/src/cgeo/geocaching/enumerations/CacheSize.java
index ee42c66..1255455 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheSize.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheSize.java
@@ -12,30 +12,38 @@ import java.util.Map;
* Enum listing cache sizes
*/
public enum CacheSize {
- MICRO("Micro", 1, R.string.cache_size_micro),
- SMALL("Small", 2, R.string.cache_size_small),
- REGULAR("Regular", 3, R.string.cache_size_regular),
- LARGE("Large", 4, R.string.cache_size_large),
- VIRTUAL("Virtual", 0, R.string.cache_size_virtual),
- NOT_CHOSEN("Not chosen", 0, R.string.cache_size_notchosen),
- OTHER("Other", 0, R.string.cache_size_other),
- UNKNOWN("Unknown", 0, R.string.cache_size_unknown); // CacheSize not init. yet
+ NANO("Nano", 0, R.string.cache_size_nano, "nano"), // used by OC only
+ MICRO("Micro", 1, R.string.cache_size_micro, "micro"),
+ SMALL("Small", 2, R.string.cache_size_small, "small"),
+ REGULAR("Regular", 3, R.string.cache_size_regular, "regular"),
+ LARGE("Large", 4, R.string.cache_size_large, "large"),
+ VERY_LARGE("Very large", 5, R.string.cache_size_very_large, "xlarge"), // used by OC only
+ NOT_CHOSEN("Not chosen", 6, R.string.cache_size_notchosen, ""),
+ VIRTUAL("Virtual", 7, R.string.cache_size_virtual, "none"),
+ OTHER("Other", 8, R.string.cache_size_other, "other"),
+ UNKNOWN("Unknown", -1, R.string.cache_size_unknown, ""); // CacheSize not init. yet
public final String id;
public final int comparable;
private final int stringId;
+ /**
+ * lookup for OC JSON requests (the numeric size is deprecated for OC)
+ */
+ private final String ocSize2;
- CacheSize(String id, int comparable, int stringId) {
+ CacheSize(final String id, final int comparable, final int stringId, final String ocSize2) {
this.id = id;
this.comparable = comparable;
this.stringId = stringId;
+ this.ocSize2 = ocSize2;
}
final private static Map<String, CacheSize> FIND_BY_ID;
static {
final HashMap<String, CacheSize> mapping = new HashMap<String, CacheSize>();
- for (CacheSize cs : values()) {
+ for (final CacheSize cs : values()) {
mapping.put(cs.id.toLowerCase(Locale.US), cs);
+ mapping.put(cs.ocSize2.toLowerCase(Locale.US), cs);
}
// add medium as additional string for Regular
mapping.put("medium", CacheSize.REGULAR);
@@ -61,21 +69,21 @@ public enum CacheSize {
/**
* Bad GPX files can contain the container size encoded as number.
- *
+ *
* @param id
* @return
*/
private static CacheSize getByNumber(final String id) {
try {
- int numerical = Integer.parseInt(id);
+ final int numerical = Integer.parseInt(id);
if (numerical != 0) {
- for (CacheSize size : CacheSize.values()) {
+ for (final CacheSize size : CacheSize.values()) {
if (size.comparable == numerical) {
return size;
}
}
}
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
// ignore, as this might be a number or not
}
return UNKNOWN;
@@ -85,4 +93,3 @@ public enum CacheSize {
return CgeoApplication.getInstance().getBaseContext().getResources().getString(stringId);
}
}
-
diff --git a/main/src/cgeo/geocaching/enumerations/CacheType.java b/main/src/cgeo/geocaching/enumerations/CacheType.java
index c952ba0..35fe7a1 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheType.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheType.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.enumerations;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.ICache;
import cgeo.geocaching.R;
-import cgeo.geocaching.CgeoApplication;
import java.util.Collections;
import java.util.HashMap;
diff --git a/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java b/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
index 710c3ba..5bcaf4a 100644
--- a/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
+++ b/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.enumerations;
-import cgeo.geocaching.R;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.R;
import java.util.EnumSet;
diff --git a/main/src/cgeo/geocaching/enumerations/LogType.java b/main/src/cgeo/geocaching/enumerations/LogType.java
index 543f83d..a63ef4e 100644
--- a/main/src/cgeo/geocaching/enumerations/LogType.java
+++ b/main/src/cgeo/geocaching/enumerations/LogType.java
@@ -19,19 +19,19 @@ public enum LogType {
DIDNT_FIND_IT(3, "3", "didn't find it", "Didn't find it", R.string.log_dnf, R.drawable.mark_red),
NOTE(4, "4", "write note", "Comment", R.string.log_note),
PUBLISH_LISTING(1003, "24", "publish listing", "", R.string.log_published, R.drawable.mark_green_more),
- ENABLE_LISTING(23, "23", "enable listing", "", R.string.log_enabled, R.drawable.mark_green_more),
- ARCHIVE(5, "5", "archive", "", R.string.log_archived, R.drawable.mark_red_more),
+ ENABLE_LISTING(23, "23", "enable listing", "Ready to search", R.string.log_enabled, R.drawable.mark_green_more),
+ ARCHIVE(5, "5", "archive", "Archived", R.string.log_archived, R.drawable.mark_red_more),
UNARCHIVE(12, "12", "unarchive", "", R.string.log_unarchived, R.drawable.mark_green_more),
- TEMP_DISABLE_LISTING(22, "22", "temporarily disable listing", "", R.string.log_disabled, R.drawable.mark_red_more),
+ TEMP_DISABLE_LISTING(22, "22", "temporarily disable listing", "Temporarily unavailable", R.string.log_disabled, R.drawable.mark_red_more),
NEEDS_ARCHIVE(7, "7", "needs archived", "", R.string.log_needs_archived, R.drawable.mark_red),
WILL_ATTEND(9, "9", "will attend", "Will attend", R.string.log_attend),
ATTENDED(10, "10", "attended", "Attended", R.string.log_attended, R.drawable.mark_green),
RETRIEVED_IT(13, "13", "retrieved it", "", R.string.log_retrieved, R.drawable.mark_green_more),
PLACED_IT(14, "14", "placed it", "", R.string.log_placed, R.drawable.mark_green_more),
GRABBED_IT(19, "19", "grabbed it", "", R.string.log_grabbed, R.drawable.mark_green_more),
- NEEDS_MAINTENANCE(45, "45", "needs maintenance", "Comment", R.string.log_maintenance_needed, R.drawable.mark_red),
+ NEEDS_MAINTENANCE(45, "45", "needs maintenance", "Needs maintenance", R.string.log_maintenance_needed, R.drawable.mark_red),
OWNER_MAINTENANCE(46, "46", "owner maintenance", "", R.string.log_maintained, R.drawable.mark_green_more),
- UPDATE_COORDINATES(47, "47", "update coordinates", "", R.string.log_update),
+ UPDATE_COORDINATES(47, "47", "update coordinates", "Moved", R.string.log_update),
DISCOVERED_IT(48, "48", "discovered it", "", R.string.log_discovered, R.drawable.mark_green),
POST_REVIEWER_NOTE(18, "68", "post reviewer note", "", R.string.log_reviewer),
VISIT(1001, "75", "visit", "", R.string.log_tb_visit, R.drawable.mark_green),
@@ -41,6 +41,7 @@ public enum LogType {
MOVE_INVENTORY(70, "70", "unused_inventory", "", R.string.log_moveinventory),
RETRACT(25, "25", "retract listing", "", R.string.log_retractlisting),
MARKED_MISSING(16, "16", "marked missing", "", R.string.log_marked_missing, R.drawable.mark_red),
+ OC_TEAM_COMMENT(83, null, "X1", "OC Team comment", R.string.log_oc_team_comment),
UNKNOWN(0, "unknown", "", "", R.string.err_unknown, R.drawable.mark_red); // LogType not init. yet
public final int id;
@@ -69,7 +70,9 @@ public enum LogType {
final HashMap<String, LogType> mappingPattern = new HashMap<String, LogType>();
final HashMap<String, LogType> mappingType = new HashMap<String, LogType>();
for (LogType lt : values()) {
- mappingPattern.put(lt.iconName, lt);
+ if (lt.iconName != null) {
+ mappingPattern.put(lt.iconName, lt);
+ }
mappingType.put(lt.type, lt);
}
FIND_BY_ICONNAME = Collections.unmodifiableMap(mappingPattern);
diff --git a/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java b/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java
index 68a17a5..e008294 100644
--- a/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java
+++ b/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java
@@ -1,29 +1,22 @@
package cgeo.geocaching.enumerations;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;
public enum LogTypeTrackable {
- DO_NOTHING(0, "", R.string.log_tb_nothing),
- VISITED(1, "_Visited", R.string.log_tb_visit),
- DROPPED_OFF(2, "_DroppedOff", R.string.log_tb_drop);
+ DO_NOTHING("", R.string.log_tb_nothing),
+ VISITED("_Visited", R.string.log_tb_visit),
+ DROPPED_OFF("_DroppedOff", R.string.log_tb_drop);
- final public int id;
final public String action;
- final public int resourceId;
+ final private int resourceId;
- LogTypeTrackable(int id, String action, int resourceId) {
- this.id = id;
+ LogTypeTrackable(String action, int resourceId) {
this.action = action;
this.resourceId = resourceId;
}
- public static LogTypeTrackable findById(int id) {
- for (LogTypeTrackable logType : values()) {
- if (logType.id == id) {
- return logType;
- }
- }
- return DO_NOTHING;
+ public String getLabel() {
+ return CgeoApplication.getInstance().getString(resourceId);
}
-
}
diff --git a/main/src/cgeo/geocaching/enumerations/StatusCode.java b/main/src/cgeo/geocaching/enumerations/StatusCode.java
index e1a1aaa..8bda371 100644
--- a/main/src/cgeo/geocaching/enumerations/StatusCode.java
+++ b/main/src/cgeo/geocaching/enumerations/StatusCode.java
@@ -6,7 +6,6 @@ import android.content.res.Resources;
public enum StatusCode {
- COMMUNICATION_NOT_STARTED(R.string.err_start),
NO_ERROR(R.string.err_none),
LOG_SAVED(R.string.info_log_saved),
LOGIN_PARSE_ERROR(R.string.err_parse),
@@ -24,7 +23,6 @@ public enum StatusCode {
LOG_POST_ERROR(R.string.err_log_post_failed),
LOG_POST_ERROR_EC(R.string.err_log_post_failed_ec),
NO_LOG_TEXT(R.string.warn_log_text_fill),
- NO_DATA_FROM_SERVER(R.string.err_log_failed_server),
NOT_LOGGED_IN(R.string.init_login_popup_failed),
LOGIMAGE_POST_ERROR(R.string.err_logimage_post_failed);
diff --git a/main/src/cgeo/geocaching/export/FieldNotes.java b/main/src/cgeo/geocaching/export/FieldNotes.java
new file mode 100644
index 0000000..11d725a
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/FieldNotes.java
@@ -0,0 +1,65 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.files.LocalStorage;
+import cgeo.geocaching.utils.FileUtils;
+import cgeo.geocaching.utils.SynchronizedDateFormat;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Field Notes are simple plain text files, but poorly documented. Syntax:<br>
+ * <code>GCxxxxx,yyyy-mm-ddThh:mm:ssZ,Found it,"logtext"</code>
+ */
+class FieldNotes {
+
+ private static final SynchronizedDateFormat FIELD_NOTE_DATE_FORMAT = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"), Locale.US);
+
+ private int size = 0;
+ private final StringBuilder buffer = new StringBuilder();
+
+ void add(final Geocache cache, final LogEntry log) {
+ size++;
+ buffer.append(cache.getGeocode())
+ .append(',')
+ .append(FIELD_NOTE_DATE_FORMAT.format(new Date(log.date)))
+ .append(',')
+ .append(StringUtils.capitalize(log.type.type))
+ .append(",\"")
+ .append(StringUtils.replaceChars(log.log, '"', '\''))
+ .append("\"\n");
+ }
+
+ public String getContent() {
+ return buffer.toString();
+ }
+
+ File writeToDirectory(File exportLocation) {
+ if (!LocalStorage.isExternalStorageAvailable()) {
+ return null;
+ }
+
+ FileUtils.mkdirs(exportLocation);
+
+ final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
+ final File exportFile = new File(exportLocation.toString() + '/' + fileNameDateFormat.format(new Date()) + ".txt");
+
+ if (!FileUtils.writeFileUTF16(exportFile, getContent())) {
+ return null;
+ }
+
+ return exportFile;
+ }
+
+ public int size() {
+ return size;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/export/FieldnoteExport.java b/main/src/cgeo/geocaching/export/FieldnoteExport.java
index 4da480a..7d3e07e 100644
--- a/main/src/cgeo/geocaching/export/FieldnoteExport.java
+++ b/main/src/cgeo/geocaching/export/FieldnoteExport.java
@@ -5,21 +5,14 @@ import cgeo.geocaching.Geocache;
import cgeo.geocaching.LogEntry;
import cgeo.geocaching.R;
import cgeo.geocaching.activity.ActivityMixin;
-import cgeo.geocaching.connector.gc.GCLogin;
-import cgeo.geocaching.enumerations.StatusCode;
-import cgeo.geocaching.network.Network;
-import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.connector.ConnectorFactory;
+import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.capability.FieldNotesCapability;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
-import cgeo.geocaching.utils.FileUtils;
import cgeo.geocaching.utils.Log;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -29,29 +22,16 @@ import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.CheckBox;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
/**
- * Exports offline logs in the Groundspeak Field Note format.<br>
- * <br>
+ * Exports offline logs in the Groundspeak Field Note format.
*
- * Field Notes are simple plain text files, but poorly documented. Syntax:<br>
- * <code>GCxxxxx,yyyy-mm-ddThh:mm:ssZ,Found it,"logtext"</code>
*/
class FieldnoteExport extends AbstractExport {
private static final File exportLocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/field-notes");
- private static final FastDateFormat fieldNoteDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"), Locale.US);
+ private static int fieldNotesCount = 0;
protected FieldnoteExport() {
super(getString(R.string.export_fieldnotes));
@@ -89,7 +69,7 @@ class FieldnoteExport extends AbstractExport {
builder.setPositiveButton(R.string.export, new DialogInterface.OnClickListener() {
@Override
- public void onClick(DialogInterface dialog, int which) {
+ public void onClick(final DialogInterface dialog, final int which) {
final boolean upload = uploadOption.isChecked();
final boolean onlyNew = onlyNewOption.isChecked();
Settings.setFieldNoteExportUpload(upload);
@@ -121,22 +101,32 @@ class FieldnoteExport extends AbstractExport {
* Upload/export only new logs since last export
*/
public ExportTask(final Activity activity, final boolean upload, final boolean onlyNew) {
- super(activity, getProgressTitle(), getString(R.string.export_fieldnotes_creating));
+ super(activity, getProgressTitle(), getString(R.string.export_fieldnotes_creating), true);
this.activity = activity;
this.upload = upload;
this.onlyNew = onlyNew;
}
@Override
- protected Boolean doInBackgroundInternal(Geocache[] caches) {
- final StringBuilder fieldNoteBuffer = new StringBuilder();
+ protected Boolean doInBackgroundInternal(final Geocache[] caches) {
+ // export field notes separately for each connector, so the file can be uploaded to the respective site afterwards
+ for (IConnector connector : ConnectorFactory.getConnectors()) {
+ if (connector instanceof FieldNotesCapability) {
+ exportFieldNotes((FieldNotesCapability) connector, caches);
+ }
+ }
+ return true;
+ }
+
+ private boolean exportFieldNotes(final FieldNotesCapability connector, Geocache[] caches) {
+ final FieldNotes fieldNotes = new FieldNotes();
try {
int i = 0;
for (final Geocache cache : caches) {
- if (cache.isLogOffline()) {
+ if (ConnectorFactory.getConnector(cache).equals(connector) && cache.isLogOffline()) {
final LogEntry log = DataStore.loadLogOffline(cache.getGeocode());
if (!onlyNew || log.date > Settings.getFieldnoteExportDate()) {
- appendFieldNote(fieldNoteBuffer, cache, log);
+ fieldNotes.add(cache, log);
}
}
publishProgress(++i);
@@ -145,65 +135,16 @@ class FieldnoteExport extends AbstractExport {
Log.e("FieldnoteExport.ExportTask generation", e);
return false;
}
+ fieldNotesCount += fieldNotes.size();
- fieldNoteBuffer.append('\n');
-
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- return false;
- }
-
- FileUtils.mkdirs(exportLocation);
-
- final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
- exportFile = new File(exportLocation.toString() + '/' + fileNameDateFormat.format(new Date()) + ".txt");
-
- Writer fileWriter = null;
- BufferedOutputStream buffer = null;
- try {
- final OutputStream os = new FileOutputStream(exportFile);
- buffer = new BufferedOutputStream(os);
- fileWriter = new OutputStreamWriter(buffer, CharEncoding.UTF_16);
- fileWriter.write(fieldNoteBuffer.toString());
- } catch (final IOException e) {
- Log.e("FieldnoteExport.ExportTask export", e);
+ exportFile = fieldNotes.writeToDirectory(exportLocation);
+ if (exportFile == null) {
return false;
- } finally {
- IOUtils.closeQuietly(fileWriter);
- IOUtils.closeQuietly(buffer);
}
if (upload) {
publishProgress(STATUS_UPLOAD);
-
- if (!GCLogin.getInstance().isActualLoginStatus()) {
- // no need to upload (possibly large file) if we're not logged in
- final StatusCode loginState = GCLogin.getInstance().login();
- if (loginState != StatusCode.NO_ERROR) {
- Log.e("FieldnoteExport.ExportTask upload: Login failed");
- }
- }
-
- final String uri = "http://www.geocaching.com/my/uploadfieldnotes.aspx";
- final String page = GCLogin.getInstance().getRequestLogged(uri, null);
-
- if (StringUtils.isBlank(page)) {
- Log.e("FieldnoteExport.ExportTask get page: No data from server");
- return false;
- }
-
- final String[] viewstates = GCLogin.getViewstates(page);
-
- final Parameters uploadParams = new Parameters(
- "__EVENTTARGET", "",
- "__EVENTARGUMENT", "",
- "ctl00$ContentBody$btnUpload", "Upload Field Note");
-
- GCLogin.putViewstates(uploadParams, viewstates);
-
- Network.getResponseData(Network.postRequest(uri, uploadParams, "ctl00$ContentBody$FieldNoteLoader", "text/plain", exportFile));
-
- if (StringUtils.isBlank(page)) {
- Log.e("FieldnoteExport.ExportTask upload: No data from server");
+ if (!connector.uploadFieldNotes(exportFile)) {
return false;
}
}
@@ -212,7 +153,7 @@ class FieldnoteExport extends AbstractExport {
}
@Override
- protected void onPostExecuteInternal(Boolean result) {
+ protected void onPostExecuteInternal(final Boolean result) {
if (null != activity) {
if (result) {
Settings.setFieldnoteExportDate(System.currentTimeMillis());
@@ -229,25 +170,11 @@ class FieldnoteExport extends AbstractExport {
}
@Override
- protected void onProgressUpdateInternal(int status) {
+ protected void onProgressUpdateInternal(final int status) {
if (null != activity) {
- if (STATUS_UPLOAD == status) {
- setMessage(getString(R.string.export_fieldnotes_uploading));
- } else {
- setMessage(getString(R.string.export_fieldnotes_creating) + " (" + status + ')');
- }
+ setMessage(getString(STATUS_UPLOAD == status ? R.string.export_fieldnotes_uploading : R.string.export_fieldnotes_creating) + " (" + fieldNotesCount + ')');
}
}
}
- static void appendFieldNote(final StringBuilder fieldNoteBuffer, final Geocache cache, final LogEntry log) {
- fieldNoteBuffer.append(cache.getGeocode())
- .append(',')
- .append(fieldNoteDateFormat.format(new Date(log.date)))
- .append(',')
- .append(StringUtils.capitalize(log.type.type))
- .append(",\"")
- .append(StringUtils.replaceChars(log.log, '"', '\''))
- .append("\"\n");
- }
}
diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java
index a2e0f93..08fca0b 100644
--- a/main/src/cgeo/geocaching/export/GpxExport.java
+++ b/main/src/cgeo/geocaching/export/GpxExport.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.export;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
-import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
diff --git a/main/src/cgeo/geocaching/export/GpxSerializer.java b/main/src/cgeo/geocaching/export/GpxSerializer.java
index df07f17..962f0d3 100644
--- a/main/src/cgeo/geocaching/export/GpxSerializer.java
+++ b/main/src/cgeo/geocaching/export/GpxSerializer.java
@@ -8,6 +8,7 @@ import cgeo.geocaching.Waypoint;
import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.utils.SynchronizedDateFormat;
import cgeo.geocaching.utils.TextUtils;
import cgeo.geocaching.utils.XmlUtils;
import cgeo.org.kxml2.io.KXmlSerializer;
@@ -15,7 +16,6 @@ import cgeo.org.kxml2.io.KXmlSerializer;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
@@ -29,7 +29,7 @@ import java.util.Set;
public final class GpxSerializer {
- private static final FastDateFormat dateFormatZ = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+ private static final SynchronizedDateFormat dateFormatZ = new SynchronizedDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
public static final String PREFIX_XSI = "http://www.w3.org/2001/XMLSchema-instance";
public static final String PREFIX_GPX = "http://www.topografix.com/GPX/1/0";
public static final String PREFIX_GROUNDSPEAK = "http://www.groundspeak.com/cache/1/0";
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java
index 157ea9d..f5380be 100644
--- a/main/src/cgeo/geocaching/files/GPXParser.java
+++ b/main/src/cgeo/geocaching/files/GPXParser.java
@@ -500,52 +500,9 @@ public abstract class GPXParser extends FileParser {
// for GPX 1.1 from extensions node
final Element cacheParent = getCacheParent(waypoint);
- // GSAK extensions
- for (final String gsakNamespace : GSAK_NS) {
- final Element gsak = cacheParent.getChild(gsakNamespace, "wptExtension");
- gsak.getChild(gsakNamespace, "Watch").setEndTextElementListener(new EndTextElementListener() {
+ registerGsakExtensions(cacheParent);
- @Override
- public void end(String watchList) {
- cache.setOnWatchlist(Boolean.valueOf(watchList.trim()));
- }
- });
-
- gsak.getChild(gsakNamespace, "UserData").setEndTextElementListener(new UserDataListener(1));
-
- for (int i = 2; i <= 4; i++) {
- gsak.getChild(gsakNamespace, "User" + i).setEndTextElementListener(new UserDataListener(i));
- }
-
- gsak.getChild(gsakNamespace, "Parent").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- parentCacheCode = body;
- }
- });
- }
-
- // c:geo extensions
- final Element cgeoVisited = cacheParent.getChild(CGEO_NS, "visited");
-
- cgeoVisited.setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String visited) {
- wptVisited = Boolean.valueOf(visited.trim());
- }
- });
-
- final Element cgeoUserDefined = cacheParent.getChild(CGEO_NS, "userdefined");
-
- cgeoUserDefined.setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String userDefined) {
- wptUserDefined = Boolean.valueOf(userDefined.trim());
- }
- });
+ registerCgeoExtensions(cacheParent);
// 3 different versions of the GC schema
for (final String nsGC : GROUNDSPEAK_NAMESPACE) {
@@ -857,6 +814,94 @@ public abstract class GPXParser extends FileParser {
}
/**
+ * Add listeners for GSAK extensions
+ *
+ * @param cacheParent
+ */
+ private void registerGsakExtensions(final Element cacheParent) {
+ for (final String gsakNamespace : GSAK_NS) {
+ final Element gsak = cacheParent.getChild(gsakNamespace, "wptExtension");
+ gsak.getChild(gsakNamespace, "Watch").setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String watchList) {
+ cache.setOnWatchlist(Boolean.valueOf(watchList.trim()));
+ }
+ });
+
+ gsak.getChild(gsakNamespace, "UserData").setEndTextElementListener(new UserDataListener(1));
+
+ for (int i = 2; i <= 4; i++) {
+ gsak.getChild(gsakNamespace, "User" + i).setEndTextElementListener(new UserDataListener(i));
+ }
+
+ gsak.getChild(gsakNamespace, "Parent").setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String body) {
+ parentCacheCode = body;
+ }
+ });
+
+ gsak.getChild(gsakNamespace, "FavPoints").setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String favoritePoints) {
+ try {
+ cache.setFavoritePoints(Integer.parseInt(favoritePoints));
+ }
+ catch (final NumberFormatException e) {
+ Log.w("Failed to parse favorite points", e);
+ }
+ }
+ });
+
+ gsak.getChild(gsakNamespace, "GcNote").setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(final String personalNote) {
+ cache.setPersonalNote(StringUtils.trim(personalNote));
+ }
+ });
+
+ gsak.getChild(gsakNamespace, "IsPremium").setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(final String premium) {
+ cache.setPremiumMembersOnly(Boolean.parseBoolean(premium));
+ }
+ });
+ }
+ }
+
+ /**
+ * Add listeners for c:geo extensions
+ *
+ * @param cacheParent
+ */
+ private void registerCgeoExtensions(final Element cacheParent) {
+ final Element cgeoVisited = cacheParent.getChild(CGEO_NS, "visited");
+
+ cgeoVisited.setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String visited) {
+ wptVisited = Boolean.valueOf(visited.trim());
+ }
+ });
+
+ final Element cgeoUserDefined = cacheParent.getChild(CGEO_NS, "userdefined");
+
+ cgeoUserDefined.setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String userDefined) {
+ wptUserDefined = Boolean.valueOf(userDefined.trim());
+ }
+ });
+ }
+
+ /**
* Overwrite this method in a GPX parser sub class to modify the {@link Geocache}, after it has been fully parsed
* from the GPX file and before it gets stored.
*
diff --git a/main/src/cgeo/geocaching/files/LocalStorage.java b/main/src/cgeo/geocaching/files/LocalStorage.java
index d57c247..626f6e6 100644
--- a/main/src/cgeo/geocaching/files/LocalStorage.java
+++ b/main/src/cgeo/geocaching/files/LocalStorage.java
@@ -7,7 +7,6 @@ import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
@@ -122,7 +121,7 @@ public final class LocalStorage {
* the geocode
* @return the cache directory
*/
- public static File getStorageDir(final String geocode) {
+ public static File getStorageDir(@Nullable final String geocode) {
return storageDir(getStorage(), geocode);
}
@@ -134,11 +133,11 @@ public final class LocalStorage {
* the geocode
* @return the cache directory
*/
- private static File getStorageSecDir(final String geocode) {
+ private static File getStorageSecDir(@Nullable final String geocode) {
return storageDir(getStorageSec(), geocode);
}
- private static File storageDir(final File base, final String geocode) {
+ private static File storageDir(final File base, @Nullable final String geocode) {
return new File(base, StringUtils.defaultIfEmpty(geocode, "_others"));
}
@@ -155,7 +154,7 @@ public final class LocalStorage {
* true if an url was given, false if a file name was given
* @return the file
*/
- public static File getStorageFile(final String geocode, final String fileNameOrUrl, final boolean isUrl, final boolean createDirs) {
+ public static File getStorageFile(@Nullable final String geocode, final String fileNameOrUrl, final boolean isUrl, final boolean createDirs) {
return buildFile(getStorageDir(geocode), fileNameOrUrl, isUrl, createDirs);
}
@@ -276,15 +275,18 @@ public final class LocalStorage {
return false;
}
+
try {
try {
- final FileOutputStream fos = new FileOutputStream(targetFile);
+ final File tempFile = File.createTempFile("download", null, targetFile.getParentFile());
+ final FileOutputStream fos = new FileOutputStream(tempFile);
final boolean written = copy(inputStream, fos);
fos.close();
- if (!written) {
- FileUtils.deleteIgnoringFailure(targetFile);
+ if (written) {
+ return tempFile.renameTo(targetFile);
}
- return written;
+ FileUtils.deleteIgnoringFailure(tempFile);
+ return false;
} finally {
IOUtils.closeQuietly(inputStream);
}
diff --git a/main/src/cgeo/geocaching/files/SimpleDirChooser.java b/main/src/cgeo/geocaching/files/SimpleDirChooser.java
index 67cbb34..1e1296a 100644
--- a/main/src/cgeo/geocaching/files/SimpleDirChooser.java
+++ b/main/src/cgeo/geocaching/files/SimpleDirChooser.java
@@ -88,9 +88,9 @@ public class SimpleDirChooser extends AbstractListActivity {
}
public void editPath() {
- AlertDialog.Builder builder = new AlertDialog.Builder(SimpleDirChooser.this);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.simple_dir_chooser_current_path);
- final EditText input = new EditText(SimpleDirChooser.this);
+ final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
input.setText(currentDir.getPath());
builder.setView(input);
diff --git a/main/src/cgeo/geocaching/filter/DistanceFilter.java b/main/src/cgeo/geocaching/filter/DistanceFilter.java
index 54225d2..cddcf72 100644
--- a/main/src/cgeo/geocaching/filter/DistanceFilter.java
+++ b/main/src/cgeo/geocaching/filter/DistanceFilter.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.filter;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
-import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.geopoint.Geopoint;
import java.util.ArrayList;
diff --git a/main/src/cgeo/geocaching/filter/FilterUserInterface.java b/main/src/cgeo/geocaching/filter/FilterUserInterface.java
index d77341b..b6eaa78 100644
--- a/main/src/cgeo/geocaching/filter/FilterUserInterface.java
+++ b/main/src/cgeo/geocaching/filter/FilterUserInterface.java
@@ -5,7 +5,8 @@ import cgeo.geocaching.R;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
+
+import rx.functions.Action1;
import android.app.Activity;
import android.app.AlertDialog;
@@ -77,7 +78,7 @@ public final class FilterUserInterface {
registry.add(new FactoryEntry(res.getString(resourceId), factoryClass));
}
- public void selectFilter(final RunnableWithArgument<IFilter> runAfterwards) {
+ public void selectFilter(final Action1<IFilter> runAfterwards) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.caches_filter_title);
@@ -89,7 +90,7 @@ public final class FilterUserInterface {
FactoryEntry entry = adapter.getItem(itemIndex);
// reset?
if (entry.filterFactory == null) {
- runAfterwards.run(null);
+ runAfterwards.call(null);
}
else {
try {
@@ -105,10 +106,10 @@ public final class FilterUserInterface {
builder.create().show();
}
- private void selectFromFactory(final IFilterFactory factory, final String menuTitle, final RunnableWithArgument<IFilter> runAfterwards) {
+ private void selectFromFactory(final IFilterFactory factory, final String menuTitle, final Action1<IFilter> runAfterwards) {
final List<IFilter> filters = Collections.unmodifiableList(factory.getFilters());
if (filters.size() == 1) {
- runAfterwards.run(filters.get(0));
+ runAfterwards.call(filters.get(0));
return;
}
@@ -119,7 +120,7 @@ public final class FilterUserInterface {
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int item) {
- runAfterwards.run(filters.get(item));
+ runAfterwards.call(filters.get(item));
}
});
diff --git a/main/src/cgeo/geocaching/filter/ModifiedFilter.java b/main/src/cgeo/geocaching/filter/ModifiedFilter.java
index d976b69..2ac088a 100644
--- a/main/src/cgeo/geocaching/filter/ModifiedFilter.java
+++ b/main/src/cgeo/geocaching/filter/ModifiedFilter.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.filter;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
-import cgeo.geocaching.CgeoApplication;
import java.util.Collections;
import java.util.List;
diff --git a/main/src/cgeo/geocaching/geopoint/Geopoint.java b/main/src/cgeo/geocaching/geopoint/Geopoint.java
index f21df01..e91a93d 100644
--- a/main/src/cgeo/geocaching/geopoint/Geopoint.java
+++ b/main/src/cgeo/geocaching/geopoint/Geopoint.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.ICoordinates;
import cgeo.geocaching.R;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
import android.location.Location;
import android.os.Build;
@@ -11,10 +12,13 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Abstraction of geographic point.
+ * Abstraction of geographic point. This class is immutable.
*/
public final class Geopoint implements ICoordinates, Parcelable {
- public static final Geopoint ZERO = new Geopoint(0.0, 0.0);
+ /**
+ * Reusable default object
+ */
+ public static final @NonNull Geopoint ZERO = new Geopoint(0.0, 0.0);
private static final double DEG_TO_RAD = Math.PI / 180;
private static final double RAD_TO_DEG = 180 / Math.PI;
@@ -64,7 +68,6 @@ public final class Geopoint implements ICoordinates, Parcelable {
* longitude string to parse
* @throws Geopoint.ParseException
* if any argument string cannot be parsed
- * @see GeopointParser#parse(String, String)
*/
public Geopoint(final String latText, final String lonText) {
this(GeopointParser.parseLatitude(latText), GeopointParser.parseLongitude(lonText));
@@ -273,19 +276,6 @@ public final class Geopoint implements ICoordinates, Parcelable {
}
/**
- * Checks if given Geopoint is similar to this Geopoint with tolerance.
- *
- * @param gp
- * Geopoint to check
- * @param tolerance
- * tolerance in km
- * @return true if similar, false otherwise
- */
- public boolean isEqualTo(Geopoint gp, double tolerance) {
- return null != gp && distanceTo(gp) <= tolerance;
- }
-
- /**
* Returns formatted coordinates.
*
* @param format
@@ -300,7 +290,7 @@ public final class Geopoint implements ICoordinates, Parcelable {
/**
* Returns formatted coordinates with default format.
* Default format is decimalminutes, e.g. N 52° 36.123 E 010° 03.456
- *
+ *
* @return formatted coordinates
*/
@Override
@@ -365,7 +355,7 @@ public final class Geopoint implements ICoordinates, Parcelable {
/**
* Get longitude character (E or W).
- *
+ *
* @return
*/
public char getLonDir() {
diff --git a/main/src/cgeo/geocaching/geopoint/GeopointParser.java b/main/src/cgeo/geocaching/geopoint/GeopointParser.java
index c043d6f..120e02e 100644
--- a/main/src/cgeo/geocaching/geopoint/GeopointParser.java
+++ b/main/src/cgeo/geocaching/geopoint/GeopointParser.java
@@ -70,37 +70,11 @@ class GeopointParser {
}
/**
- * Parses a pair of coordinates (latitude and longitude) out of a String.
- * Accepts following formats and combinations of it:
- * X DD
- * X DD°
- * X DD° MM
- * X DD° MM.MMM
- * X DD° MM SS
- *
- * as well as:
- * DD.DDDDDDD
- *
- * Both . and , are accepted, also variable count of spaces (also 0)
- *
- * @param latitude
- * the latitude string to parse
- * @param longitude
- * the longitude string to parse
- * @return an Geopoint with parsed latitude and longitude
- * @throws Geopoint.ParseException
- * if lat or lon could not be parsed
- */
- public static Geopoint parse(final String latitude, final String longitude) {
- final double lat = parseLatitude(latitude);
- final double lon = parseLongitude(longitude);
-
- return new Geopoint(lat, lon);
- }
-
- /*
- * (non JavaDoc)
- * Helper for coordinates-parsing.
+ * Helper for coordinates-parsing
+ *
+ * @param text
+ * @param latlon
+ * @return
*/
private static ResultWrapper parseHelper(final String text, final LatLon latlon) {
diff --git a/main/src/cgeo/geocaching/geopoint/Viewport.java b/main/src/cgeo/geocaching/geopoint/Viewport.java
index 9d55f69..ba0e040 100644
--- a/main/src/cgeo/geocaching/geopoint/Viewport.java
+++ b/main/src/cgeo/geocaching/geopoint/Viewport.java
@@ -5,16 +5,15 @@ import cgeo.geocaching.ICoordinates;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import java.util.Set;
+import java.util.Collection;
-
-public class Viewport {
+public final class Viewport {
public final @NonNull Geopoint center;
public final @NonNull Geopoint bottomLeft;
public final @NonNull Geopoint topRight;
- public Viewport(final ICoordinates point1, final ICoordinates point2) {
+ public Viewport(final @NonNull ICoordinates point1, final @NonNull ICoordinates point2) {
final Geopoint gp1 = point1.getCoords();
final Geopoint gp2 = point2.getCoords();
this.bottomLeft = new Geopoint(Math.min(gp1.getLatitude(), gp2.getLatitude()),
@@ -25,7 +24,7 @@ public class Viewport {
(gp1.getLongitude() + gp2.getLongitude()) / 2);
}
- public Viewport(final ICoordinates center, final double latSpan, final double lonSpan) {
+ public Viewport(final @NonNull ICoordinates center, final double latSpan, final double lonSpan) {
this.center = center.getCoords();
final double centerLat = this.center.getLatitude();
final double centerLon = this.center.getLongitude();
@@ -71,7 +70,7 @@ public class Viewport {
* the coordinates to check
* @return true if the point is contained in this viewport, false otherwise or if the point contains no coordinates
*/
- public boolean contains(final ICoordinates point) {
+ public boolean contains(final @NonNull ICoordinates point) {
final Geopoint coords = point.getCoords();
return coords != null
&& coords.getLongitudeE6() >= bottomLeft.getLongitudeE6()
@@ -87,12 +86,12 @@ public class Viewport {
/**
* Check whether another viewport is fully included into the current one.
- *
+ *
* @param vp
* the other viewport
- * @return true if the vp is fully included into this one, false otherwise
+ * @return true if the viewport is fully included into this one, false otherwise
*/
- public boolean includes(final Viewport vp) {
+ public boolean includes(final @NonNull Viewport vp) {
return contains(vp.bottomLeft) && contains(vp.topRight);
}
@@ -124,46 +123,37 @@ public class Viewport {
}
/**
- * Return a viewport that contains the current viewport as well as another point.
- *
- * @param point
- * the point we want in the viewport
- * @return either the same or an expanded viewport
- */
- public Viewport expand(final ICoordinates point) {
- if (contains(point)) {
- return this;
- }
-
- final Geopoint coords = point.getCoords();
- final double latitude = coords.getLatitude();
- final double longitude = coords.getLongitude();
- final double latMin = Math.min(getLatitudeMin(), latitude);
- final double latMax = Math.max(getLatitudeMax(), latitude);
- final double lonMin = Math.min(getLongitudeMin(), longitude);
- final double lonMax = Math.max(getLongitudeMax(), longitude);
- return new Viewport(new Geopoint(latMin, lonMin), new Geopoint(latMax, lonMax));
- }
-
- /**
* Return the smallest viewport containing all the given points.
*
* @param points
* a set of points. Point with null coordinates (or null themselves) will be ignored
* @return the smallest viewport containing the non-null coordinates, or null if no coordinates are non-null
*/
- static public Viewport containing(final Set<? extends ICoordinates> points) {
- Viewport viewport = null;
+ static public @Nullable
+ Viewport containing(final Collection<? extends ICoordinates> points) {
+ boolean valid = false;
+ double latMin = Double.MAX_VALUE;
+ double latMax = -Double.MAX_VALUE;
+ double lonMin = Double.MAX_VALUE;
+ double lonMax = -Double.MAX_VALUE;
for (final ICoordinates point : points) {
- if (point != null && point.getCoords() != null) {
- if (viewport == null) {
- viewport = new Viewport(point, point);
- } else {
- viewport = viewport.expand(point);
+ if (point != null) {
+ final Geopoint coords = point.getCoords();
+ if (coords != null) {
+ valid = true;
+ final double latitude = coords.getLatitude();
+ final double longitude = coords.getLongitude();
+ latMin = Math.min(latMin, latitude);
+ latMax = Math.max(latMax, latitude);
+ lonMin = Math.min(lonMin, longitude);
+ lonMax = Math.max(lonMax, longitude);
}
}
}
- return viewport;
+ if (!valid) {
+ return null;
+ }
+ return new Viewport(new Geopoint(latMin, lonMin), new Geopoint(latMax, lonMax));
}
@Override
diff --git a/main/src/cgeo/geocaching/list/PseudoList.java b/main/src/cgeo/geocaching/list/PseudoList.java
index 365d6fd..f2cc7ed 100644
--- a/main/src/cgeo/geocaching/list/PseudoList.java
+++ b/main/src/cgeo/geocaching/list/PseudoList.java
@@ -17,6 +17,12 @@ public class PseudoList extends AbstractList {
*/
public static final AbstractList NEW_LIST = new PseudoList(NEW_LIST_ID, R.string.list_menu_create);
+ private static final int HISTORY_LIST_ID = 4;
+ /**
+ * list entry to create a new list
+ */
+ public static final AbstractList HISTORY_LIST = new PseudoList(HISTORY_LIST_ID, R.string.menu_history);
+
/**
* private constructor to have all instances as constants in the class
*/
diff --git a/main/src/cgeo/geocaching/list/StoredList.java b/main/src/cgeo/geocaching/list/StoredList.java
index 8106073..7e2a83c 100644
--- a/main/src/cgeo/geocaching/list/StoredList.java
+++ b/main/src/cgeo/geocaching/list/StoredList.java
@@ -5,11 +5,12 @@ import cgeo.geocaching.DataStore;
import cgeo.geocaching.R;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.ui.dialog.Dialogs;
-import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import rx.functions.Action1;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
@@ -67,15 +68,15 @@ public final class StoredList extends AbstractList {
res = app.getResources();
}
- public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards) {
+ public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards) {
promptForListSelection(titleId, runAfterwards, false, -1);
}
- public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId) {
+ public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId) {
promptForListSelection(titleId, runAfterwards, onlyConcreteLists, exceptListId, StringUtils.EMPTY);
}
- public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId, final String newListName) {
+ public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId, final String newListName) {
final List<AbstractList> lists = new ArrayList<AbstractList>();
lists.addAll(getSortedLists());
@@ -87,7 +88,12 @@ public final class StoredList extends AbstractList {
}
if (!onlyConcreteLists) {
- lists.add(PseudoList.ALL_LIST);
+ if (exceptListId != PseudoList.ALL_LIST.id) {
+ lists.add(PseudoList.ALL_LIST);
+ }
+ if (exceptListId != PseudoList.HISTORY_LIST.id) {
+ lists.add(PseudoList.HISTORY_LIST);
+ }
}
lists.add(PseudoList.NEW_LIST);
@@ -109,7 +115,7 @@ public final class StoredList extends AbstractList {
promptForListCreation(runAfterwards, newListName);
}
else {
- runAfterwards.run(lists.get(itemId).id);
+ runAfterwards.call(lists.get(itemId).id);
}
}
});
@@ -138,17 +144,17 @@ public final class StoredList extends AbstractList {
return lists;
}
- public void promptForListCreation(@NonNull final RunnableWithArgument<Integer> runAfterwards, String newListName) {
- handleListNameInput(newListName, R.string.list_dialog_create_title, R.string.list_dialog_create, new RunnableWithArgument<String>() {
+ public void promptForListCreation(@NonNull final Action1<Integer> runAfterwards, String newListName) {
+ handleListNameInput(newListName, R.string.list_dialog_create_title, R.string.list_dialog_create, new Action1<String>() {
@Override
- public void run(final String listName) {
+ public void call(final String listName) {
final int newId = DataStore.createList(listName);
new StoredList(newId, listName, 0);
if (newId >= DataStore.customListIdOffset) {
ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_ok));
- runAfterwards.run(newId);
+ runAfterwards.call(newId);
} else {
ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_err));
}
@@ -156,15 +162,15 @@ public final class StoredList extends AbstractList {
});
}
- private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final RunnableWithArgument<String> runnable) {
- Dialogs.input(activity, dialogTitle, defaultValue, buttonTitle, new RunnableWithArgument<String>() {
+ private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final Action1<String> runnable) {
+ Dialogs.input(activity, dialogTitle, defaultValue, buttonTitle, new Action1<String>() {
@Override
- public void run(final String input) {
+ public void call(final String input) {
// remove whitespaces added by autocompletion of Android keyboard
String listName = StringUtils.trim(input);
if (StringUtils.isNotBlank(listName)) {
- runnable.run(listName);
+ runnable.call(listName);
}
}
});
@@ -172,10 +178,10 @@ public final class StoredList extends AbstractList {
public void promptForListRename(final int listId, @NonNull final Runnable runAfterRename) {
final StoredList list = DataStore.getList(listId);
- handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new RunnableWithArgument<String>() {
+ handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new Action1<String>() {
@Override
- public void run(final String listName) {
+ public void call(final String listName) {
DataStore.renameList(listId, listName);
runAfterRename.run();
}
@@ -197,7 +203,7 @@ public final class StoredList extends AbstractList {
* Return the given list, if it is a concrete list. Return the default list otherwise.
*/
public static int getConcreteList(int listId) {
- if (listId == PseudoList.ALL_LIST.id || listId == TEMPORARY_LIST_ID) {
+ if (listId == PseudoList.ALL_LIST.id || listId == TEMPORARY_LIST_ID || listId == PseudoList.HISTORY_LIST.id) {
return STANDARD_LIST_ID;
}
return listId;
diff --git a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
index 7524b76..b2cb0b2 100644
--- a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
+++ b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.loaders;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.gc.GCConstants;
+import cgeo.geocaching.connector.gc.RecaptchaHandler;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
@@ -13,6 +14,8 @@ import android.content.Context;
import android.os.Handler;
import android.support.v4.content.AsyncTaskLoader;
+import java.util.concurrent.CountDownLatch;
+
public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult> implements RecaptchaReceiver {
public enum CacheListLoaderType {
@@ -28,6 +31,10 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
MAP,
REMOVE_FROM_HISTORY,
NEXT_PAGE;
+
+ public int getLoaderId() {
+ return ordinal();
+ }
}
private Handler recaptchaHandler = null;
@@ -36,6 +43,7 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
private String recaptchaText = null;
private SearchResult search;
private boolean loading;
+ private CountDownLatch latch = new CountDownLatch(1);
public AbstractSearchLoader(Context context) {
super(context);
@@ -72,23 +80,21 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
forceLoad();
}
- public void setRecaptchaHandler(Handler recaptchaHandlerIn) {
- recaptchaHandler = recaptchaHandlerIn;
+ public void setRecaptchaHandler(final Handler recaptchaHandler) {
+ this.recaptchaHandler = recaptchaHandler;
}
@Override
public void notifyNeed() {
if (recaptchaHandler != null) {
- recaptchaHandler.sendEmptyMessage(1);
+ recaptchaHandler.sendEmptyMessage(RecaptchaHandler.SHOW_CAPTCHA);
}
}
@Override
- public synchronized void waitForUser() {
+ public void waitForUser() {
try {
- while (getText() == null) {
- wait();
- }
+ latch.await();
} catch (InterruptedException e) {
Log.w("searchThread is not waiting for user…");
}
@@ -100,16 +106,11 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
}
@Override
- public String getKey() {
- return recaptchaKey;
- }
-
- @Override
public void fetchChallenge() {
recaptchaChallenge = null;
if (StringUtils.isNotEmpty(recaptchaKey)) {
- final Parameters params = new Parameters("k", getKey());
+ final Parameters params = new Parameters("k", recaptchaKey);
final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));
if (StringUtils.isNotBlank(recaptchaJs)) {
@@ -124,18 +125,16 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
}
@Override
- public synchronized void setText(String text) {
+ public void setText(String text) {
recaptchaText = text;
-
- notify();
+ latch.countDown();
}
@Override
- public synchronized String getText() {
+ public String getText() {
return recaptchaText;
}
-
@Override
public void reset() {
super.reset();
diff --git a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java
index dd7c7a6..e1573c9 100644
--- a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java
+++ b/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.loaders;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.settings.Settings;
import android.content.Context;
diff --git a/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java
index 605f461..fdb35f2 100644
--- a/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java
+++ b/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java
@@ -2,9 +2,9 @@ package cgeo.geocaching.loaders;
import cgeo.geocaching.DataStore;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.settings.Settings;
import android.content.Context;
diff --git a/main/src/cgeo/geocaching/loaders/NextPageGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/NextPageGeocacheListLoader.java
index 1104f83..05eac18 100644
--- a/main/src/cgeo/geocaching/loaders/NextPageGeocacheListLoader.java
+++ b/main/src/cgeo/geocaching/loaders/NextPageGeocacheListLoader.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.loaders;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.settings.Settings;
import android.content.Context;
diff --git a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java
index 5088484..b80a1b8 100644
--- a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java
+++ b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.loaders;
-import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.DataStore;
+import cgeo.geocaching.SearchResult;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.settings.Settings;
import android.content.Context;
diff --git a/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java b/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
index fd5189c..881e048 100644
--- a/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
+++ b/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
@@ -10,8 +10,6 @@ public interface RecaptchaReceiver {
public void fetchChallenge();
- public String getKey();
-
public void setKey(String key);
public void notifyNeed();
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index c98ba72..6730ba9 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -38,12 +38,13 @@ import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.GeoDirHandler;
import cgeo.geocaching.utils.LeastRecentlyUsedSet;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
+import rx.functions.Action1;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@@ -289,8 +290,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
waitDialog.dismiss();
waitDialog.setOnCancelListener(null);
}
-
- geoDirUpdate.startDir();
}
}
@@ -299,8 +298,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (loadDetailsThread != null) {
loadDetailsThread.stopIt();
}
-
- geoDirUpdate.startDir();
}
}
@@ -466,7 +463,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
prepareFilterBar();
- if (!app.isLiveMapHintShown() && !Settings.getHideLiveMapHint()) {
+ if (!app.isLiveMapHintShownInThisSession() && !Settings.getHideLiveMapHint() && Settings.getLiveMapHintShowCount() <= 3) {
LiveMapInfoDialogBuilder.create(activity).show();
}
}
@@ -495,7 +492,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
public void onResume() {
super.onResume();
- addGeoDirObservers();
+ geoDirUpdate.startGeoAndDir();
if (!CollectionUtils.isEmpty(dirtyCaches)) {
for (String geocode : dirtyCaches) {
@@ -515,18 +512,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
startTimer();
}
- private void addGeoDirObservers() {
- geoDirUpdate.startGeoAndDir();
- }
-
- private void deleteGeoDirObservers() {
- geoDirUpdate.stopGeoAndDir();
- }
-
@Override
public void onPause() {
stopTimer();
- deleteGeoDirObservers();
+ geoDirUpdate.stopGeoAndDir();
savePrefs();
if (mapView != null) {
@@ -661,9 +650,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (Settings.getChooseList()) {
// let user select list to store cache in
new StoredList.UserInterface(activity).promptForListSelection(R.string.list_title,
- new RunnableWithArgument<Integer>() {
+ new Action1<Integer>() {
@Override
- public void run(final Integer selectedListId) {
+ public void call(final Integer selectedListId) {
storeCaches(geocodes, selectedListId);
}
}, true, StoredList.TEMPORARY_LIST_ID);
@@ -800,7 +789,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
* @return true if a restart is needed, false otherwise
*/
private boolean changeMapSource(final MapSource mapSource) {
- final boolean restartRequired = !MapProviderFactory.isSameActivity(Settings.getMapSource(), mapSource);
+ final boolean restartRequired = !MapProviderFactory.isSameActivity(MapProviderFactory.getMapSource(currentSourceId), mapSource);
Settings.setMapSource(mapSource);
currentSourceId = mapSource.getNumericalId();
@@ -898,7 +887,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private long timeLastPositionOverlayCalculation = 0;
@Override
- protected void updateGeoData(final IGeoData geo) {
+ public void updateGeoData(final IGeoData geo) {
if (geo.isPseudoLocation()) {
locationValid = false;
} else {
@@ -994,7 +983,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
public synchronized void startTimer() {
if (coordsIntent != null) {
// display just one point
- (new DisplayPointThread()).start();
+ displayPoint(coordsIntent);
} else {
// start timer
stopTimer();
@@ -1063,7 +1052,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
}
- yield();
} catch (Exception e) {
Log.w("CGeoMap.LoadTimer.run", e);
}
@@ -1182,7 +1170,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
}
}
- final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens);
+ final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens).toBlockingObservable().single();
downloaded = true;
Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
@@ -1271,32 +1259,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
}
- /**
- * Thread to display one point. Started on opening if in single mode.
- */
- private class DisplayPointThread extends Thread {
-
- @Override
- public void run() {
- if (mapView == null || caches == null) {
- return;
- }
-
- if (coordsIntent != null) {
- final Waypoint waypoint = new Waypoint("some place", waypointTypeIntent != null ? waypointTypeIntent : WaypointType.WAYPOINT, false);
- waypoint.setCoords(coordsIntent);
+ private void displayPoint(final Geopoint coords) {
+ final Waypoint waypoint = new Waypoint("some place", waypointTypeIntent != null ? waypointTypeIntent : WaypointType.WAYPOINT, false);
+ waypoint.setCoords(coords);
- final CachesOverlayItemImpl item = getWaypointItem(waypoint);
- overlayCaches.updateItems(item);
- displayHandler.sendEmptyMessage(INVALIDATE_MAP);
+ final CachesOverlayItemImpl item = getWaypointItem(waypoint);
+ overlayCaches.updateItems(item);
+ displayHandler.sendEmptyMessage(INVALIDATE_MAP);
+ displayHandler.sendEmptyMessage(UPDATE_TITLE);
- cachesCnt = 1;
- } else {
- cachesCnt = 0;
- }
-
- displayHandler.sendEmptyMessage(UPDATE_TITLE);
- }
+ cachesCnt = 1;
}
private static abstract class DoRunnable implements Runnable {
@@ -1343,8 +1315,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (loadDetailsThread != null) {
loadDetailsThread.stopIt();
}
-
- geoDirUpdate.startDir();
} catch (Exception e) {
Log.e("CGeoMap.storeCaches.onCancel", e);
}
@@ -1392,8 +1362,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
return;
}
- deleteGeoDirObservers();
-
for (final String geocode : geocodes) {
try {
if (handler.isCancelled()) {
@@ -1410,14 +1378,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
detailProgress++;
handler.sendEmptyMessage(UPDATE_PROGRESS);
}
-
- // FIXME: what does this yield() do here?
- yield();
}
// we're done
handler.sendEmptyMessage(FINISHED_LOADING_DETAILS);
- addGeoDirObservers();
}
}
@@ -1609,7 +1573,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
private CachesOverlayItemImpl getCacheItem(final Geocache cache) {
- final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(cache, cache.getType().applyDistanceRule());
+ final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(cache, cache.applyDistanceRule());
final int hashcode = new HashCodeBuilder()
.append(cache.isReliableLatLon())
diff --git a/main/src/cgeo/geocaching/maps/MapProviderFactory.java b/main/src/cgeo/geocaching/maps/MapProviderFactory.java
index 2e43e19..b928a1e 100644
--- a/main/src/cgeo/geocaching/maps/MapProviderFactory.java
+++ b/main/src/cgeo/geocaching/maps/MapProviderFactory.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.maps;
-import cgeo.geocaching.R;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.R;
import cgeo.geocaching.maps.google.GoogleMapProvider;
import cgeo.geocaching.maps.interfaces.MapProvider;
import cgeo.geocaching.maps.interfaces.MapSource;
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlay.java b/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlay.java
index 3339650..d14c687 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlay.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlay.java
@@ -77,11 +77,6 @@ public class GoogleCacheOverlay extends ItemizedOverlay<GoogleCacheOverlayItem>
}
@Override
- public Drawable superBoundCenter(Drawable markerIn) {
- return ItemizedOverlay.boundCenter(markerIn);
- }
-
- @Override
public Drawable superBoundCenterBottom(Drawable marker) {
return ItemizedOverlay.boundCenterBottom(marker);
}
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java b/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
index cb95b2c..38d7d96 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.maps.google;
-import cgeo.geocaching.R;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.R;
import cgeo.geocaching.maps.AbstractMapProvider;
import cgeo.geocaching.maps.AbstractMapSource;
import cgeo.geocaching.maps.interfaces.MapItemFactory;
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
index d02e3c2..610dbe1 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
@@ -11,15 +11,14 @@ import cgeo.geocaching.maps.interfaces.MapControllerImpl;
import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
-import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
-import com.google.android.maps.Overlay;
import org.apache.commons.lang3.reflect.MethodUtils;
+import org.eclipse.jdt.annotation.NonNull;
import android.app.Activity;
import android.content.Context;
@@ -54,7 +53,7 @@ public class GoogleMapView extends MapView implements MapViewImpl {
}
@Override
- public void draw(Canvas canvas) {
+ public void draw(final Canvas canvas) {
try {
if (getMapZoomLevel() > 22) { // to avoid too close zoom level (mostly on Samsung Galaxy S series)
getController().setZoom(22);
@@ -91,6 +90,7 @@ public class GoogleMapView extends MapView implements MapViewImpl {
}
@Override
+ @NonNull
public GeoPointImpl getMapViewCenter() {
GeoPoint point = getMapCenter();
return new GoogleGeoPoint(point.getLatitudeE6(), point.getLongitudeE6());
@@ -102,11 +102,6 @@ public class GoogleMapView extends MapView implements MapViewImpl {
}
@Override
- public void addOverlay(OverlayImpl ovl) {
- getOverlays().add((Overlay) ovl);
- }
-
- @Override
public void clearOverlays() {
getOverlays().clear();
}
diff --git a/main/src/cgeo/geocaching/maps/interfaces/ItemizedOverlayImpl.java b/main/src/cgeo/geocaching/maps/interfaces/ItemizedOverlayImpl.java
index 90c5b31..ee61f12 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/ItemizedOverlayImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/ItemizedOverlayImpl.java
@@ -18,8 +18,6 @@ public interface ItemizedOverlayImpl extends OverlayImpl {
void superSetLastFocusedItemIndex(int i);
- Drawable superBoundCenter(Drawable markerIn);
-
Drawable superBoundCenterBottom(Drawable marker);
boolean superOnTap(int index);
diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
index cb7ddc6..5ae8e15 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
@@ -4,6 +4,8 @@ import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.maps.CachesOverlay;
import cgeo.geocaching.maps.PositionAndScaleOverlay;
+import org.eclipse.jdt.annotation.NonNull;
+
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -22,12 +24,11 @@ public interface MapViewImpl {
void clearOverlays();
- void addOverlay(OverlayImpl ovl);
-
MapControllerImpl getMapController();
void destroyDrawingCache();
+ @NonNull
GeoPointImpl getMapViewCenter();
int getLatitudeSpan();
@@ -75,7 +76,7 @@ public interface MapViewImpl {
/**
* Indicates if the current map view supports different themes
* for map rendering
- *
+ *
* @return true - supports custom themes, false - does not support custom themes
*/
boolean hasMapThemes();
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlay.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlay.java
index 9e14e36..b9e40d7 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlay.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlay.java
@@ -70,11 +70,6 @@ public class MapsforgeCacheOverlay extends ItemizedOverlay<MapsforgeCacheOverlay
}
@Override
- public Drawable superBoundCenter(Drawable markerIn) {
- return ItemizedOverlay.boundCenter(markerIn);
- }
-
- @Override
public Drawable superBoundCenterBottom(Drawable marker) {
return ItemizedOverlay.boundCenterBottom(marker);
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
index 78aa47d..e993548 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
@@ -11,7 +11,6 @@ import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
import cgeo.geocaching.maps.interfaces.MapSource;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
-import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
@@ -86,11 +85,6 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
}
@Override
- public void addOverlay(OverlayImpl ovl) {
- getOverlays().add((Overlay) ovl);
- }
-
- @Override
public void clearOverlays() {
getOverlays().clear();
}
@@ -229,7 +223,7 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
@Override
public void setMapTheme() {
String customRenderTheme = Settings.getCustomRenderThemeFilePath();
- if (!StringUtils.isEmpty(customRenderTheme)) {
+ if (StringUtils.isNotEmpty(customRenderTheme)) {
try {
setRenderTheme(new File(customRenderTheme));
} catch (FileNotFoundException e) {
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeCacheOverlay.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeCacheOverlay.java
index 30355fd..a8111ed 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeCacheOverlay.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeCacheOverlay.java
@@ -70,11 +70,6 @@ public class MapsforgeCacheOverlay extends ItemizedOverlay<MapsforgeCacheOverlay
}
@Override
- public Drawable superBoundCenter(Drawable markerIn) {
- return ItemizedOverlay.boundCenter(markerIn);
- }
-
- @Override
public Drawable superBoundCenterBottom(Drawable marker) {
return ItemizedOverlay.boundCenterBottom(marker);
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
index c741a31..30caed5 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java
@@ -10,10 +10,10 @@ import cgeo.geocaching.maps.interfaces.MapControllerImpl;
import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
-import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
+import org.eclipse.jdt.annotation.NonNull;
import org.mapsforge.android.mapsold.GeoPoint;
import org.mapsforge.android.mapsold.MapDatabase;
import org.mapsforge.android.mapsold.MapView;
@@ -66,6 +66,7 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl {
}
@Override
+ @NonNull
public GeoPointImpl getMapViewCenter() {
GeoPoint point = getMapCenter();
return new MapsforgeGeoPoint(point.getLatitudeE6(), point.getLongitudeE6());
@@ -77,11 +78,6 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl {
}
@Override
- public void addOverlay(OverlayImpl ovl) {
- getOverlays().add((Overlay) ovl);
- }
-
- @Override
public void clearOverlays() {
getOverlays().clear();
}
diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java
index 0daa588..524617c 100644
--- a/main/src/cgeo/geocaching/network/HtmlImage.java
+++ b/main/src/cgeo/geocaching/network/HtmlImage.java
@@ -6,14 +6,31 @@ import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.list.StoredList;
+import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.FileUtils;
import cgeo.geocaching.utils.ImageUtils;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.androidextra.Base64;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Scheduler;
+import rx.Scheduler.Inner;
+import rx.Subscriber;
+import rx.functions.Action1;
+import rx.functions.Func1;
+import rx.schedulers.Schedulers;
+import rx.subjects.PublishSubject;
+import rx.subscriptions.CompositeSubscription;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -31,9 +48,23 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class HtmlImage implements Html.ImageGetter {
+ // This class implements an all-purpose image getter that can also be used as a ImageGetter interface
+ // when displaying caches. An instance mainly has three possible use cases:
+ // - If onlySave is true, getDrawable() will return null immediately and will queue the image retrieval
+ // and saving in the loading subject. Downloads will start in parallel when the blocking
+ // waitForBackgroundLoading() method is called, and they can be cancelled through the given handler.
+ // - If onlySave is false and the instance is called through fetchDrawable(), then an observable for the
+ // given URL will be returned. This observable will emit the local copy of the image if it is present,
+ // regardless of its freshness, then if needed an updated fresher copy after retrieving it from the network.
+ // - If onlySave is false and the instance is used as an ImageGetter, only the final version of the
+ // image will be returned.
+
private static final String[] BLOCKED = new String[] {
"gccounter.de",
"gccounter.com",
@@ -59,105 +90,183 @@ public class HtmlImage implements Html.ImageGetter {
final private boolean returnErrorImage;
final private int listId;
final private boolean onlySave;
- final private BitmapFactory.Options bfOptions;
final private int maxWidth;
final private int maxHeight;
final private Resources resources;
+ // Background loading
+ final private PublishSubject<Observable<String>> loading = PublishSubject.create();
+ final Observable<String> waitForEnd = Observable.merge(loading).publish().refCount();
+ final CompositeSubscription subscription = new CompositeSubscription(waitForEnd.subscribe());
+ final private Scheduler downloadScheduler = Schedulers.executor(new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>()));
+
public HtmlImage(final String geocode, final boolean returnErrorImage, final int listId, final boolean onlySave) {
this.geocode = geocode;
this.returnErrorImage = returnErrorImage;
this.listId = listId;
this.onlySave = onlySave;
- bfOptions = new BitmapFactory.Options();
- bfOptions.inTempStorage = new byte[16 * 1024];
- bfOptions.inPreferredConfig = Bitmap.Config.RGB_565;
-
Point displaySize = Compatibility.getDisplaySize();
this.maxWidth = displaySize.x - 25;
this.maxHeight = displaySize.y - 25;
this.resources = CgeoApplication.getInstance().getResources();
}
+ @Nullable
@Override
public BitmapDrawable getDrawable(final String url) {
- // Reject empty and counter images URL
+ final Observable<BitmapDrawable> drawable = fetchDrawable(url);
+ if (onlySave) {
+ loading.onNext(drawable.map(new Func1<BitmapDrawable, String>() {
+ @Override
+ public String call(final BitmapDrawable bitmapDrawable) {
+ return url;
+ }
+ }));
+ return null;
+ }
+ return drawable.toBlockingObservable().lastOrDefault(null);
+ }
+
+ // Caches are loaded from disk on Schedulers.computation() to avoid using more threads than processors
+ // on the phone while decoding the image. Downloads happen on downloadScheduler, in parallel with image
+ // decoding.
+ public Observable<BitmapDrawable> fetchDrawable(final String url) {
+
if (StringUtils.isBlank(url) || isCounter(url)) {
- return new BitmapDrawable(resources, getTransparent1x1Image());
+ return Observable.from(getTransparent1x1Image(resources));
}
final boolean shared = url.contains("/images/icons/icon_");
final String pseudoGeocode = shared ? SHARED : geocode;
- Bitmap imagePre = loadImageFromStorage(url, pseudoGeocode, shared);
-
- // Download image and save it to the cache
- if (imagePre == null) {
- final File file = LocalStorage.getStorageFile(pseudoGeocode, url, true, true);
- if (url.startsWith("data:image/")) {
- if (url.contains(";base64,")) {
- // TODO: when we use SDK level 8 or above, we can use the streaming version of the base64
- // Android utilities.
- byte[] decoded = Base64.decode(StringUtils.substringAfter(url, ";base64,"), Base64.DEFAULT);
- OutputStream out = null;
- try {
- out = new FileOutputStream(file);
- out.write(decoded);
- } catch (final IOException e) {
- Log.e("HtmlImage.getDrawable: cannot write file for decoded inline image", e);
- return null;
- } finally {
- IOUtils.closeQuietly(out);
+ return Observable.create(new OnSubscribe<BitmapDrawable>() {
+ @Override
+ public void call(final Subscriber<? super BitmapDrawable> subscriber) {
+ Schedulers.computation().schedule(new Action1<Inner>() {
+ @Override
+ public void call(final Inner inner) {
+ final Pair<BitmapDrawable, Boolean> loaded = loadFromDisk();
+ final BitmapDrawable bitmap = loaded.getLeft();
+ if (loaded.getRight()) {
+ subscriber.onNext(bitmap);
+ subscriber.onCompleted();
+ return;
+ }
+ if (bitmap != null && !onlySave) {
+ subscriber.onNext(bitmap);
+ }
+ downloadScheduler.schedule(new Action1<Inner>() {
+ @Override
+ public void call(final Inner inner) {
+ downloadAndSave(subscriber);
+ }
+ });
+ }
+ });
+ }
+
+ private Pair<BitmapDrawable, Boolean> loadFromDisk() {
+ final Pair<Bitmap, Boolean> loadResult = loadImageFromStorage(url, pseudoGeocode, shared);
+ final Bitmap bitmap = loadResult.getLeft();
+ return new ImmutablePair<BitmapDrawable, Boolean>(bitmap != null ?
+ ImageUtils.scaleBitmapToFitDisplay(bitmap) :
+ null,
+ loadResult.getRight());
+ }
+
+ private void downloadAndSave(final Subscriber<? super BitmapDrawable> subscriber) {
+ final File file = LocalStorage.getStorageFile(pseudoGeocode, url, true, true);
+ if (url.startsWith("data:image/")) {
+ if (url.contains(";base64,")) {
+ saveBase64ToFile(url, file);
+ } else {
+ Log.e("HtmlImage.getDrawable: unable to decode non-base64 inline image");
+ subscriber.onCompleted();
+ return;
}
} else {
- Log.e("HtmlImage.getDrawable: unable to decode non-base64 inline image");
- return null;
+ if (subscription.isUnsubscribed() || downloadOrRefreshCopy(url, file)) {
+ // The existing copy was fresh enough or we were unsubscribed earlier.
+ subscriber.onCompleted();
+ return;
+ }
}
- } else {
- final String absoluteURL = makeAbsoluteURL(url);
-
- if (absoluteURL != null) {
- try {
- final HttpResponse httpResponse = Network.getRequest(absoluteURL, null, file);
- if (httpResponse != null) {
- final int statusCode = httpResponse.getStatusLine().getStatusCode();
- if (statusCode == 200) {
- LocalStorage.saveEntityToFile(httpResponse, file);
- } else if (statusCode == 304) {
- if (!file.setLastModified(System.currentTimeMillis())) {
- makeFreshCopy(file);
- }
+ if (onlySave) {
+ subscriber.onCompleted();
+ } else {
+ Schedulers.computation().schedule(new Action1<Inner>() {
+ @Override
+ public void call(final Inner inner) {
+ final Pair<BitmapDrawable, Boolean> loaded = loadFromDisk();
+ final BitmapDrawable image = loaded.getLeft();
+ if (image != null) {
+ subscriber.onNext(image);
+ } else {
+ subscriber.onNext(returnErrorImage ?
+ new BitmapDrawable(resources, BitmapFactory.decodeResource(resources, R.drawable.image_not_loaded)) :
+ getTransparent1x1Image(resources));
}
+ subscriber.onCompleted();
}
- } catch (Exception e) {
- Log.e("HtmlImage.getDrawable (downloading from web)", e);
- }
+ });
}
}
- }
-
- if (onlySave) {
- return null;
- }
+ });
+ }
- // now load the newly downloaded image
- if (imagePre == null) {
- imagePre = loadImageFromStorage(url, pseudoGeocode, shared);
+ public void waitForBackgroundLoading(@Nullable final CancellableHandler handler) {
+ if (handler != null) {
+ handler.unsubscribeIfCancelled(subscription);
}
+ loading.onCompleted();
+ waitForEnd.toBlockingObservable().lastOrDefault(null);
+ }
- // get image and return
- if (imagePre == null) {
- Log.d("HtmlImage.getDrawable: Failed to obtain image");
+ /**
+ * Download or refresh the copy of <code>url</code> in <code>file</code>.
+ *
+ * @param url the url of the document
+ * @param file the file to save the document in
+ * @return <code>true</code> if the existing file was up-to-date, <code>false</code> otherwise
+ */
+ private boolean downloadOrRefreshCopy(final String url, final File file) {
+ final String absoluteURL = makeAbsoluteURL(url);
- if (returnErrorImage) {
- imagePre = BitmapFactory.decodeResource(resources, R.drawable.image_not_loaded);
- } else {
- imagePre = getTransparent1x1Image();
+ if (absoluteURL != null) {
+ try {
+ final HttpResponse httpResponse = Network.getRequest(absoluteURL, null, file);
+ if (httpResponse != null) {
+ final int statusCode = httpResponse.getStatusLine().getStatusCode();
+ if (statusCode == 200) {
+ LocalStorage.saveEntityToFile(httpResponse, file);
+ } else if (statusCode == 304) {
+ if (!file.setLastModified(System.currentTimeMillis())) {
+ makeFreshCopy(file);
+ }
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ Log.e("HtmlImage.downloadOrRefreshCopy", e);
}
}
+ return false;
+ }
- return imagePre != null ? ImageUtils.scaleBitmapToFitDisplay(imagePre) : null;
+ private static void saveBase64ToFile(final String url, final File file) {
+ // TODO: when we use SDK level 8 or above, we can use the streaming version of the base64
+ // Android utilities.
+ OutputStream out = null;
+ try {
+ out = new FileOutputStream(file);
+ out.write(Base64.decode(StringUtils.substringAfter(url, ";base64,"), Base64.DEFAULT));
+ } catch (final IOException e) {
+ Log.e("HtmlImage.saveBase64ToFile: cannot write file for decoded inline image", e);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
}
/**
@@ -180,25 +289,35 @@ public class HtmlImage implements Html.ImageGetter {
}
}
- private Bitmap getTransparent1x1Image() {
- return BitmapFactory.decodeResource(resources, R.drawable.image_no_placement);
+ private BitmapDrawable getTransparent1x1Image(final Resources res) {
+ return new BitmapDrawable(res, BitmapFactory.decodeResource(resources, R.drawable.image_no_placement));
}
- private Bitmap loadImageFromStorage(final String url, final String pseudoGeocode, final boolean forceKeep) {
+ /**
+ * Load an image from primary or secondary storage.
+ *
+ * @param url the image URL
+ * @param pseudoGeocode the geocode or the shared name
+ * @param forceKeep keep the image if it is there, without checking its freshness
+ * @return <code>true</code> if the image was there and is fresh enough, <code>false</code> otherwise
+ */
+ @NonNull
+ private Pair<Bitmap, Boolean> loadImageFromStorage(final String url, final String pseudoGeocode, final boolean forceKeep) {
try {
final File file = LocalStorage.getStorageFile(pseudoGeocode, url, true, false);
- final Bitmap image = loadCachedImage(file, forceKeep);
- if (image != null) {
+ final Pair<Bitmap, Boolean> image = loadCachedImage(file, forceKeep);
+ if (image.getRight() || image.getLeft() != null) {
return image;
}
final File fileSec = LocalStorage.getStorageSecFile(pseudoGeocode, url, true);
return loadCachedImage(fileSec, forceKeep);
} catch (Exception e) {
- Log.w("HtmlImage.getDrawable (reading cache)", e);
+ Log.w("HtmlImage.loadImageFromStorage", e);
}
- return null;
+ return new ImmutablePair<Bitmap, Boolean>(null, false);
}
+ @Nullable
private String makeAbsoluteURL(final String url) {
// Check if uri is absolute or not, if not attach the connector hostname
// FIXME: that should also include the scheme
@@ -222,21 +341,39 @@ public class HtmlImage implements Html.ImageGetter {
return null;
}
- private Bitmap loadCachedImage(final File file, final boolean forceKeep) {
+ /**
+ * Load a previously saved image.
+ *
+ * @param file the file on disk
+ * @param forceKeep keep the image if it is there, without checking its freshness
+ * @return a pair with <code>true</code> if the image was there and is fresh enough or <code>false</code> otherwise,
+ * and the image (possibly <code>null</code> if the first component is <code>false</code> and the image
+ * could not be loaded, or if the first component is <code>true</code> and <code>onlySave</code> is also
+ * <code>true</code>)
+ */
+ @NonNull
+ private Pair<Bitmap, Boolean> loadCachedImage(final File file, final boolean forceKeep) {
if (file.exists()) {
- if (listId >= StoredList.STANDARD_LIST_ID || file.lastModified() > (new Date().getTime() - (24 * 60 * 60 * 1000)) || forceKeep) {
- setSampleSize(file);
- final Bitmap image = BitmapFactory.decodeFile(file.getPath(), bfOptions);
- if (image == null) {
- Log.e("Cannot decode bitmap from " + file.getPath());
- }
- return image;
+ final boolean freshEnough = listId >= StoredList.STANDARD_LIST_ID || file.lastModified() > (new Date().getTime() - (24 * 60 * 60 * 1000)) || forceKeep;
+ if (onlySave) {
+ return new ImmutablePair<Bitmap, Boolean>(null, true);
+ }
+ final BitmapFactory.Options bfOptions = new BitmapFactory.Options();
+ bfOptions.inTempStorage = new byte[16 * 1024];
+ bfOptions.inPreferredConfig = Bitmap.Config.RGB_565;
+ setSampleSize(file, bfOptions);
+ final Bitmap image = BitmapFactory.decodeFile(file.getPath(), bfOptions);
+ if (image == null) {
+ Log.e("Cannot decode bitmap from " + file.getPath());
+ return new ImmutablePair<Bitmap, Boolean>(null, false);
}
+ return new ImmutablePair<Bitmap, Boolean>(image,
+ freshEnough);
}
- return null;
+ return new ImmutablePair<Bitmap, Boolean>(null, false);
}
- private void setSampleSize(final File file) {
+ private void setSampleSize(final File file, final BitmapFactory.Options bfOptions) {
//Decode image size only
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java
index e891d3b..d8638db 100644
--- a/main/src/cgeo/geocaching/network/Network.java
+++ b/main/src/cgeo/geocaching/network/Network.java
@@ -5,18 +5,10 @@ import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.TextUtils;
-import ch.boye.httpclientandroidlib.Header;
-import ch.boye.httpclientandroidlib.HeaderElement;
import ch.boye.httpclientandroidlib.HttpEntity;
-import ch.boye.httpclientandroidlib.HttpException;
-import ch.boye.httpclientandroidlib.HttpRequest;
-import ch.boye.httpclientandroidlib.HttpRequestInterceptor;
import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.HttpResponseInterceptor;
import ch.boye.httpclientandroidlib.NameValuePair;
-import ch.boye.httpclientandroidlib.ProtocolException;
import ch.boye.httpclientandroidlib.client.HttpClient;
-import ch.boye.httpclientandroidlib.client.entity.GzipDecompressingEntity;
import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity;
import ch.boye.httpclientandroidlib.client.methods.HttpGet;
import ch.boye.httpclientandroidlib.client.methods.HttpPost;
@@ -26,15 +18,14 @@ import ch.boye.httpclientandroidlib.entity.StringEntity;
import ch.boye.httpclientandroidlib.entity.mime.MultipartEntity;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
+import ch.boye.httpclientandroidlib.impl.client.DecompressingHttpClient;
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.impl.client.DefaultRedirectStrategy;
+import ch.boye.httpclientandroidlib.impl.client.LaxRedirectStrategy;
import ch.boye.httpclientandroidlib.params.BasicHttpParams;
import ch.boye.httpclientandroidlib.params.CoreConnectionPNames;
import ch.boye.httpclientandroidlib.params.CoreProtocolPNames;
import ch.boye.httpclientandroidlib.params.HttpParams;
-import ch.boye.httpclientandroidlib.protocol.HttpContext;
import ch.boye.httpclientandroidlib.util.EntityUtils;
-
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
@@ -48,6 +39,7 @@ import android.net.Uri;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@@ -86,60 +78,8 @@ public abstract class Network {
final DefaultHttpClient client = new DefaultHttpClient();
client.setCookieStore(Cookies.cookieStore);
client.setParams(clientParams);
-
- client.setRedirectStrategy(new DefaultRedirectStrategy() {
- @Override
- public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
- boolean isRedirect = false;
- try {
- isRedirect = super.isRedirected(request, response, context);
- } catch (final ProtocolException e) {
- Log.e("httpclient.isRedirected: unable to check for redirection", e);
- }
- if (!isRedirect) {
- final int responseCode = response.getStatusLine().getStatusCode();
- if (responseCode == 301 || responseCode == 302) {
- return true;
- }
- }
- return isRedirect;
- }
- });
-
- client.addRequestInterceptor(new HttpRequestInterceptor() {
-
- @Override
- public void process(
- final HttpRequest request,
- final HttpContext context) throws HttpException, IOException {
- if (!request.containsHeader("Accept-Encoding")) {
- request.addHeader("Accept-Encoding", "gzip");
- }
- }
- });
- client.addResponseInterceptor(new HttpResponseInterceptor() {
-
- @Override
- public void process(
- final HttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- final HttpEntity entity = response.getEntity();
- if (entity != null) {
- final Header contentEncoding = entity.getContentEncoding();
- if (contentEncoding != null) {
- for (final HeaderElement codec : contentEncoding.getElements()) {
- if (codec.getName().equalsIgnoreCase("gzip")) {
- response.setEntity(new GzipDecompressingEntity(response.getEntity()));
- return;
- }
- }
- }
- }
- }
-
- });
-
- return client;
+ client.setRedirectStrategy(new LaxRedirectStrategy());
+ return new DecompressingHttpClient(client);
}
/**
@@ -426,6 +366,30 @@ public abstract class Network {
return null;
}
+ /**
+ * Get the input stream corresponding to a HTTP response if it exists.
+ *
+ * @param response a HTTP response, which can be null
+ * @return the input stream if the HTTP request is successful, <code>null</code> otherwise
+ */
+ @Nullable
+ public static InputStream getResponseStream(@Nullable final HttpResponse response) {
+ if (!isSuccess(response)) {
+ return null;
+ }
+ assert(response != null);
+ final HttpEntity entity = response.getEntity();
+ if (entity == null) {
+ return null;
+ }
+ try {
+ return entity.getContent();
+ } catch (final IOException e) {
+ Log.e("Network.getResponseStream", e);
+ return null;
+ }
+ }
+
@Nullable
private static String getResponseDataNoError(final HttpResponse response, boolean replaceWhitespace) {
try {
diff --git a/main/src/cgeo/geocaching/network/OAuth.java b/main/src/cgeo/geocaching/network/OAuth.java
index c033660..fa376af 100644
--- a/main/src/cgeo/geocaching/network/OAuth.java
+++ b/main/src/cgeo/geocaching/network/OAuth.java
@@ -37,13 +37,14 @@ public class OAuth {
}
final String keysPacked = consumerSecret + "&" + StringUtils.defaultString(tokenSecret); // both even if empty some of them!
- final String requestPacked = method + "&" + OAuth.percentEncode((https ? "https" : "http") + "://" + host + path) + "&" + OAuth.percentEncode(StringUtils.join(paramsEncoded.toArray(), '&'));
+ final @NonNull String joinedParams = StringUtils.join(paramsEncoded.toArray(), '&');
+ final String requestPacked = method + "&" + OAuth.percentEncode((https ? "https" : "http") + "://" + host + path) + "&" + OAuth.percentEncode(joinedParams);
params.put("oauth_signature", CryptUtils.base64Encode(CryptUtils.hashHmac(requestPacked, keysPacked)));
}
/**
* percent encode following http://tools.ietf.org/html/rfc5849#section-3.6
- *
+ *
* @param url
* @return
*/
diff --git a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
index 888cf77..a5a2383 100644
--- a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
+++ b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
@@ -7,6 +7,7 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.MatcherWrapper;
+import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.ParseException;
import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity;
import ch.boye.httpclientandroidlib.util.EntityUtils;
@@ -34,6 +35,10 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
public static final int NOT_AUTHENTICATED = 0;
public static final int AUTHENTICATED = 1;
+ private static final int STATUS_ERROR = 0;
+ private static final int STATUS_SUCCESS = 1;
+ private static final int STATUS_ERROR_EXT_MSG = 2;
+
@NonNull final private String host;
@NonNull final private String pathRequest;
@NonNull final private String pathAuthorize;
@@ -62,8 +67,13 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
startButton.setOnClickListener(new StartListener());
startButton.setEnabled(true);
- if (msg.what == 1) {
+ if (msg.what == STATUS_SUCCESS) {
startButton.setText(getAuthAgain());
+ } else if (msg.what == STATUS_ERROR_EXT_MSG) {
+ String errMsg = getErrAuthInitialize();
+ errMsg += msg.obj != null ? "\n" + msg.obj.toString() : "";
+ showToast(errMsg);
+ startButton.setText(getAuthStart());
} else {
showToast(getErrAuthInitialize());
startButton.setText(getAuthStart());
@@ -161,37 +171,49 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
params.put("oauth_callback", callback);
final String method = "GET";
OAuth.signOAuth(host, pathRequest, method, https, params, null, null, consumerKey, consumerSecret);
- final String line = Network.getResponseData(Network.getRequest(getUrlPrefix() + host + pathRequest, params));
+ final HttpResponse response = Network.getRequest(getUrlPrefix() + host + pathRequest, params);
- int status = 0;
- if (StringUtils.isNotBlank(line)) {
- assert line != null;
- final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
- if (paramsMatcher1.find()) {
- OAtoken = paramsMatcher1.group(1);
- }
- final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
- if (paramsMatcher2.find()) {
- OAtokenSecret = paramsMatcher2.group(1);
- }
+ if (Network.isSuccess(response)) {
+ final String line = Network.getResponseData(response);
- if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) {
- setTempTokens(OAtoken, OAtokenSecret);
- try {
- final Parameters paramsBrowser = new Parameters();
- paramsBrowser.put("oauth_token", OAtoken);
- final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser));
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getUrlPrefix() + host + pathAuthorize + "?" + encodedParams)));
- status = 1;
- } catch (ParseException e) {
- Log.e("OAuthAuthorizationActivity.requestToken", e);
- } catch (IOException e) {
- Log.e("OAuthAuthorizationActivity.requestToken", e);
+ int status = STATUS_ERROR;
+ if (StringUtils.isNotBlank(line)) {
+ assert line != null;
+ final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
+ if (paramsMatcher1.find()) {
+ OAtoken = paramsMatcher1.group(1);
+ }
+ final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
+ if (paramsMatcher2.find()) {
+ OAtokenSecret = paramsMatcher2.group(1);
+ }
+
+ if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) {
+ setTempTokens(OAtoken, OAtokenSecret);
+ try {
+ final Parameters paramsBrowser = new Parameters();
+ paramsBrowser.put("oauth_token", OAtoken);
+ final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser));
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getUrlPrefix() + host + pathAuthorize + "?" + encodedParams)));
+ status = STATUS_SUCCESS;
+ } catch (ParseException e) {
+ Log.e("OAuthAuthorizationActivity.requestToken", e);
+ } catch (IOException e) {
+ Log.e("OAuthAuthorizationActivity.requestToken", e);
+ }
}
}
- }
- requestTokenHandler.sendEmptyMessage(status);
+ requestTokenHandler.sendEmptyMessage(status);
+ } else {
+ final String extErrMsg = getExtendedErrorMsg(response);
+ if (StringUtils.isNotBlank(extErrMsg)) {
+ final Message msg = requestTokenHandler.obtainMessage(STATUS_ERROR_EXT_MSG, extErrMsg);
+ requestTokenHandler.sendMessage(msg);
+ } else {
+ requestTokenHandler.sendEmptyMessage(STATUS_ERROR);
+ }
+ }
}
private void changeToken(final String verifier) {
@@ -306,6 +328,18 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
return res.getString(R.string.err_auth_process);
}
+ /**
+ * Allows deriving classes to check the response for error messages specific to their OAuth implementation
+ *
+ * @param response
+ * The error response of the token request
+ * @return String with a more detailed error message (user-facing, localized), can be empty
+ */
+ @SuppressWarnings("static-method")
+ protected String getExtendedErrorMsg(HttpResponse response) {
+ return StringUtils.EMPTY;
+ }
+
protected String getAuthDialogWait() {
return res.getString(R.string.auth_dialog_waiting, getAuthTitle());
}
diff --git a/main/src/cgeo/geocaching/network/StatusUpdater.java b/main/src/cgeo/geocaching/network/StatusUpdater.java
index cb4c7f4..4055f01 100644
--- a/main/src/cgeo/geocaching/network/StatusUpdater.java
+++ b/main/src/cgeo/geocaching/network/StatusUpdater.java
@@ -1,21 +1,22 @@
package cgeo.geocaching.network;
import cgeo.geocaching.CgeoApplication;
-import cgeo.geocaching.utils.MemorySubject;
-import cgeo.geocaching.utils.PeriodicHandler;
-import cgeo.geocaching.utils.PeriodicHandler.PeriodicHandlerListener;
import cgeo.geocaching.utils.Version;
import org.json.JSONException;
import org.json.JSONObject;
+import rx.Scheduler;
+import rx.schedulers.Schedulers;
+import rx.subjects.BehaviorSubject;
+import rx.functions.Action1;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
-import android.os.Looper;
import java.util.Locale;
+import java.util.concurrent.TimeUnit;
-public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implements Runnable, PeriodicHandlerListener {
+public class StatusUpdater {
static public class Status {
final public String message;
@@ -30,24 +31,40 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement
this.url = url;
}
+ Status(final JSONObject response) {
+ message = get(response, "message");
+ messageId = get(response, "message_id");
+ icon = get(response, "icon");
+ url = get(response, "url");
+ }
+
final static public Status closeoutStatus =
new Status("", "status_closeout_warning", "attribute_abandonedbuilding", "http://faq.cgeo.org/#7_69");
- final static public Status defaultStatus() {
+ final static public Status defaultStatus(final Status upToDate) {
+ if (upToDate != null && upToDate.message != null) {
+ return upToDate;
+ }
return VERSION.SDK_INT < VERSION_CODES.ECLAIR_MR1 ? closeoutStatus : null;
}
}
- @Override
- public void onPeriodic() {
- final JSONObject response =
- Network.requestJSON("http://status.cgeo.org/api/status.json",
- new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())),
- "version_name", Version.getVersionName(CgeoApplication.getInstance()),
- "locale", Locale.getDefault().toString()));
- if (response != null) {
- notifyObservers(new Status(get(response, "message"), get(response, "message_id"), get(response, "icon"), get(response, "url")));
- }
+ final static public BehaviorSubject<Status> latestStatus = BehaviorSubject.create(Status.defaultStatus(null));
+
+ static {
+ Schedulers.io().schedulePeriodically(new Action1<Scheduler.Inner>() {
+ @Override
+ public void call(final Scheduler.Inner inner) {
+ final JSONObject response =
+ Network.requestJSON("http://status.cgeo.org/api/status.json",
+ new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())),
+ "version_name", Version.getVersionName(CgeoApplication.getInstance()),
+ "locale", Locale.getDefault().toString()));
+ if (response != null) {
+ latestStatus.onNext(Status.defaultStatus(new Status(response)));
+ }
+ }
+ }, 0, 1800, TimeUnit.SECONDS);
}
private static String get(final JSONObject json, final String key) {
@@ -58,11 +75,4 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement
}
}
- @Override
- public void run() {
- Looper.prepare();
- new PeriodicHandler(1800000L, this).start();
- Looper.loop();
- }
-
}
diff --git a/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java b/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java
new file mode 100644
index 0000000..15a45c6
--- /dev/null
+++ b/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java
@@ -0,0 +1,71 @@
+package cgeo.geocaching.search;
+
+import org.apache.commons.lang3.StringUtils;
+
+import rx.functions.Func1;
+
+import android.content.Context;
+import android.widget.ArrayAdapter;
+import android.widget.Filter;
+
+/**
+ * The standard auto completion only matches user input at word boundaries. Therefore searching "est" will not match
+ * "test". This adapter matches everywhere.
+ *
+ */
+public class AutoCompleteAdapter extends ArrayAdapter<String> {
+
+ private String[] suggestions;
+ private final Func1<String, String[]> suggestionFunction;
+
+ public AutoCompleteAdapter(Context context, int textViewResourceId, final Func1<String, String[]> suggestionFunction) {
+ super(context, textViewResourceId);
+ this.suggestionFunction = suggestionFunction;
+ }
+
+ @Override
+ public int getCount() {
+ return suggestions.length;
+ }
+
+ @Override
+ public String getItem(int index) {
+ return suggestions[index];
+ }
+
+ @Override
+ public Filter getFilter() {
+ Filter filter = new Filter() {
+
+ @Override
+ protected FilterResults performFiltering(CharSequence constraint) {
+ FilterResults filterResults = new FilterResults();
+ if (constraint == null) {
+ return filterResults;
+ }
+ String trimmed = StringUtils.trim(constraint.toString());
+ if (StringUtils.length(trimmed) >= 2) {
+ String[] newResults = suggestionFunction.call(trimmed);
+
+ // Assign the data to the FilterResults, but do not yet store in the global member.
+ // Otherwise we might invalidate the adapter and cause an IllegalStateException.
+ filterResults.values = newResults;
+ filterResults.count = newResults.length;
+ }
+ return filterResults;
+ }
+
+ @Override
+ protected void publishResults(CharSequence constraint, FilterResults filterResults) {
+ if (filterResults != null && filterResults.count > 0) {
+ suggestions = (String[]) filterResults.values;
+ notifyDataSetChanged();
+ }
+ else {
+ notifyDataSetInvalidated();
+ }
+ }
+ };
+ return filter;
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/search/SuggestionProvider.java b/main/src/cgeo/geocaching/search/SuggestionProvider.java
new file mode 100644
index 0000000..c0a7728
--- /dev/null
+++ b/main/src/cgeo/geocaching/search/SuggestionProvider.java
@@ -0,0 +1,57 @@
+package cgeo.geocaching.search;
+
+import cgeo.geocaching.DataStore;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class SuggestionProvider extends ContentProvider {
+
+ private static Cursor lastCursor;
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public String getType(final Uri arg0) {
+ return SearchManager.SUGGEST_MIME_TYPE;
+ }
+
+ @Override
+ public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
+ final String searchTerm = uri.getLastPathSegment();
+ // can be empty when deleting the query
+ if (StringUtils.equals(searchTerm, SearchManager.SUGGEST_URI_PATH_QUERY)) {
+ return lastCursor;
+ }
+ return getSuggestions(searchTerm);
+ }
+
+ private static Cursor getSuggestions(final String searchTerm) {
+ lastCursor = DataStore.findSuggestions(searchTerm);
+ return lastCursor;
+ }
+
+ @Override
+ public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Uri insert(final Uri uri, final ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java b/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java
index d3aae5c..1efbc96 100644
--- a/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java
+++ b/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java
@@ -5,28 +5,23 @@ import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.ui.dialog.Dialogs;
-import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
+import rx.Observable;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action1;
+import rx.functions.Func0;
+import rx.schedulers.Schedulers;
-import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
import android.preference.Preference;
import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-public abstract class AbstractCheckCredentialsPreference extends Preference {
-
- public AbstractCheckCredentialsPreference(Context context) {
- super(context);
- }
+public abstract class AbstractCheckCredentialsPreference extends AbstractClickablePreference {
public AbstractCheckCredentialsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -37,57 +32,25 @@ public abstract class AbstractCheckCredentialsPreference extends Preference {
}
@Override
- protected View onCreateView(ViewGroup parent) {
- setOnPreferenceClickListener(new LoginCheckClickListener());
- return super.onCreateView(parent);
+ protected OnPreferenceClickListener getOnPreferenceClickListener(final SettingsActivity activity) {
+ return new LoginCheckClickListener(activity);
}
protected abstract ImmutablePair<String, String> getCredentials();
- protected abstract Object login();
+ protected abstract ImmutablePair<StatusCode, Drawable> login();
private class LoginCheckClickListener implements OnPreferenceClickListener {
- private Resources res;
- private SettingsActivity activity;
-
- private ProgressDialog loginDialog;
- @SuppressLint("HandlerLeak")
- private Handler logInHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- try {
- if (loginDialog != null && loginDialog.isShowing()) {
- loginDialog.dismiss();
- }
+ final private SettingsActivity activity;
- if (msg.obj == null || (msg.obj instanceof Drawable)) {
- Dialogs.message(activity, R.string.init_login_popup, R.string.init_login_popup_ok, (Drawable) msg.obj);
- } else {
- Dialogs.message(activity, R.string.init_login_popup,
- res.getString(R.string.init_login_popup_failed_reason)
- + " "
- + ((StatusCode) msg.obj).getErrorString(res)
- + ".");
- }
- } catch (Exception e) {
- ActivityMixin.showToast(activity, R.string.err_login_failed);
- Log.e("SettingsActivity.logInHandler", e);
- } finally {
- if (loginDialog != null && loginDialog.isShowing()) {
- loginDialog.dismiss();
- }
- // enable/disable basic member preferences
- activity.initBasicMemberPreferences();
- }
- }
- };
+ LoginCheckClickListener(final SettingsActivity activity) {
+ this.activity = activity;
+ }
@Override
public boolean onPreferenceClick(Preference preference) {
- this.activity = (SettingsActivity) AbstractCheckCredentialsPreference.this.getContext();
- this.res = activity.getResources();
-
- ImmutablePair<String, String> credentials = getCredentials();
+ final Resources res = activity.getResources();
+ final ImmutablePair<String, String> credentials = getCredentials();
// check credentials for validity
if (StringUtils.isBlank(credentials.getLeft())
@@ -96,19 +59,33 @@ public abstract class AbstractCheckCredentialsPreference extends Preference {
return false;
}
- loginDialog = ProgressDialog.show(activity,
+ final ProgressDialog loginDialog = ProgressDialog.show(activity,
res.getString(R.string.init_login_popup),
res.getString(R.string.init_login_popup_working), true);
loginDialog.setCancelable(false);
Cookies.clearCookies();
- (new Thread() {
+ AndroidObservable.fromActivity(activity, Observable.defer(new Func0<Observable<ImmutablePair<StatusCode, Drawable>>>() {
@Override
- public void run() {
- Object payload = login();
- logInHandler.obtainMessage(0, payload).sendToTarget();
+ public Observable<ImmutablePair<StatusCode, Drawable>> call() {
+ return Observable.from(login());
+ }
+ }).subscribeOn(Schedulers.io())).subscribe(new Action1<ImmutablePair<StatusCode, Drawable>>() {
+ @Override
+ public void call(final ImmutablePair<StatusCode, Drawable> loginInfo) {
+ loginDialog.dismiss();
+ if (loginInfo.getLeft() == StatusCode.NO_ERROR) {
+ Dialogs.message(activity, R.string.init_login_popup, R.string.init_login_popup_ok, loginInfo.getRight());
+ } else {
+ Dialogs.message(activity, R.string.init_login_popup,
+ res.getString(R.string.init_login_popup_failed_reason)
+ + " "
+ + loginInfo.getLeft().getErrorString(res)
+ + ".");
+ }
+ activity.initBasicMemberPreferences();
}
- }).start();
+ });
return false; // no shared preference has to be changed
}
diff --git a/main/src/cgeo/geocaching/settings/AbstractClickablePreference.java b/main/src/cgeo/geocaching/settings/AbstractClickablePreference.java
new file mode 100644
index 0000000..f4080cd
--- /dev/null
+++ b/main/src/cgeo/geocaching/settings/AbstractClickablePreference.java
@@ -0,0 +1,30 @@
+package cgeo.geocaching.settings;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+abstract class AbstractClickablePreference extends Preference {
+
+ final SettingsActivity activity;
+
+ public AbstractClickablePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ activity = (SettingsActivity) context;
+ }
+
+ public AbstractClickablePreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ activity = (SettingsActivity) context;
+ }
+
+ @Override
+ protected View onCreateView(ViewGroup parent) {
+ setOnPreferenceClickListener(getOnPreferenceClickListener(activity));
+ return super.onCreateView(parent);
+ }
+
+ abstract protected OnPreferenceClickListener getOnPreferenceClickListener(final SettingsActivity activity);
+}
diff --git a/main/src/cgeo/geocaching/settings/CheckECCredentialsPreference.java b/main/src/cgeo/geocaching/settings/CheckECCredentialsPreference.java
index 46a3661..c1cf740 100644
--- a/main/src/cgeo/geocaching/settings/CheckECCredentialsPreference.java
+++ b/main/src/cgeo/geocaching/settings/CheckECCredentialsPreference.java
@@ -7,14 +7,11 @@ import cgeo.geocaching.enumerations.StatusCode;
import org.apache.commons.lang3.tuple.ImmutablePair;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
public class CheckECCredentialsPreference extends AbstractCheckCredentialsPreference {
- public CheckECCredentialsPreference(Context context) {
- super(context);
- }
-
public CheckECCredentialsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -29,12 +26,7 @@ public class CheckECCredentialsPreference extends AbstractCheckCredentialsPrefer
}
@Override
- protected Object login() {
- final StatusCode loginResult = ECLogin.getInstance().login();
- Object payload = loginResult;
- if (loginResult == StatusCode.NO_ERROR) {
- payload = null;
- }
- return payload;
+ protected ImmutablePair<StatusCode, Drawable> login() {
+ return new ImmutablePair<StatusCode, Drawable>(ECLogin.getInstance().login(), null);
}
}
diff --git a/main/src/cgeo/geocaching/settings/CheckGcCredentialsPreference.java b/main/src/cgeo/geocaching/settings/CheckGcCredentialsPreference.java
index 12c8b24..8257fdd 100644
--- a/main/src/cgeo/geocaching/settings/CheckGcCredentialsPreference.java
+++ b/main/src/cgeo/geocaching/settings/CheckGcCredentialsPreference.java
@@ -6,14 +6,11 @@ import cgeo.geocaching.enumerations.StatusCode;
import org.apache.commons.lang3.tuple.ImmutablePair;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
public class CheckGcCredentialsPreference extends AbstractCheckCredentialsPreference {
- public CheckGcCredentialsPreference(Context context) {
- super(context);
- }
-
public CheckGcCredentialsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -28,13 +25,14 @@ public class CheckGcCredentialsPreference extends AbstractCheckCredentialsPrefer
}
@Override
- protected Object login() {
+ protected ImmutablePair<StatusCode, Drawable> login() {
final StatusCode loginResult = GCLogin.getInstance().login();
- Object payload = loginResult;
- if (loginResult == StatusCode.NO_ERROR) {
- GCLogin.detectGcCustomDate();
- payload = GCLogin.getInstance().downloadAvatarAndGetMemberStatus();
+ switch (loginResult) {
+ case NO_ERROR:
+ GCLogin.detectGcCustomDate();
+ return new ImmutablePair<StatusCode, Drawable>(StatusCode.NO_ERROR, GCLogin.getInstance().downloadAvatarAndGetMemberStatus());
+ default:
+ return new ImmutablePair<StatusCode, Drawable>(loginResult, null);
}
- return payload;
}
}
diff --git a/main/src/cgeo/geocaching/settings/OAuthPreference.java b/main/src/cgeo/geocaching/settings/OAuthPreference.java
index 3550947..df77197 100644
--- a/main/src/cgeo/geocaching/settings/OAuthPreference.java
+++ b/main/src/cgeo/geocaching/settings/OAuthPreference.java
@@ -10,10 +10,8 @@ import android.content.Context;
import android.content.Intent;
import android.preference.Preference;
import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-public class OAuthPreference extends Preference {
+public class OAuthPreference extends AbstractClickablePreference {
private static final int NO_KEY = -1;
@@ -23,8 +21,8 @@ public class OAuthPreference extends Preference {
OCPL(R.string.pref_fakekey_ocpl_authorization, OCPLAuthorizationActivity.class),
TWITTER(R.string.pref_fakekey_twitter_authorization, TwitterAuthorizationActivity.class);
- public int prefKeyId;
- public Class<?> authActivity;
+ public final int prefKeyId;
+ public final Class<?> authActivity;
OAuthActivityMapping(int prefKeyId, Class<?> clazz) {
this.prefKeyId = prefKeyId;
@@ -44,11 +42,6 @@ public class OAuthPreference extends Preference {
return OAuthActivityMapping.NONE;
}
- public OAuthPreference(Context context) {
- super(context);
- this.oAuthMapping = getAuthorization();
- }
-
public OAuthPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.oAuthMapping = getAuthorization();
@@ -60,10 +53,9 @@ public class OAuthPreference extends Preference {
}
@Override
- protected View onCreateView(ViewGroup parent) {
- final SettingsActivity activity = (SettingsActivity) getContext();
-
- setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ protected OnPreferenceClickListener getOnPreferenceClickListener(final SettingsActivity activity) {
+ activity.setOcAuthTitle(oAuthMapping.prefKeyId);
+ return new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (oAuthMapping.authActivity != null) {
@@ -74,9 +66,7 @@ public class OAuthPreference extends Preference {
}
return false; // no shared preference has to be changed
}
- });
+ };
- activity.setOcAuthTitle(oAuthMapping.prefKeyId);
- return super.onCreateView(parent);
}
}
diff --git a/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java b/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java
index 3e838ab..a1ab215 100644
--- a/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java
+++ b/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java
@@ -8,26 +8,19 @@ import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.lang3.StringUtils;
+import rx.Observable;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action1;
+import rx.functions.Func0;
+import rx.schedulers.Schedulers;
import android.app.ProgressDialog;
import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
import android.preference.Preference;
import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-public class RegisterSend2CgeoPreference extends Preference {
- ProgressDialog progressDialog;
- SettingsActivity activity;
-
- public RegisterSend2CgeoPreference(Context context) {
- super(context);
- }
+public class RegisterSend2CgeoPreference extends AbstractClickablePreference {
public RegisterSend2CgeoPreference(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -37,42 +30,9 @@ public class RegisterSend2CgeoPreference extends Preference {
super(context, attrs, defStyle);
}
- private Handler webAuthHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // satisfy static code analysis
- if (activity == null) {
- return;
- }
-
- try {
- if (progressDialog != null && progressDialog.isShowing()) {
- progressDialog.dismiss();
- }
-
- if (msg.what > 0) {
- Dialogs.message(activity, R.string.init_sendToCgeo,
- activity.getString(R.string.init_sendToCgeo_register_ok)
- .replace("####", String.valueOf(msg.what)));
- } else {
- Dialogs.message(activity, R.string.init_sendToCgeo, R.string.init_sendToCgeo_register_fail);
- }
- } catch (Exception e) {
- ActivityMixin.showToast(activity, R.string.init_sendToCgeo_register_fail);
- Log.e("SettingsActivity.webHandler", e);
- }
-
- if (progressDialog != null && progressDialog.isShowing()) {
- progressDialog.dismiss();
- }
- }
- };
-
@Override
- protected View onCreateView(ViewGroup parent) {
- activity = (SettingsActivity) getContext();
-
- setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ protected OnPreferenceClickListener getOnPreferenceClickListener(final SettingsActivity activity) {
+ return new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// satisfy static code analysis
@@ -88,43 +48,51 @@ public class RegisterSend2CgeoPreference extends Preference {
return false;
}
- progressDialog = ProgressDialog.show(activity,
+ final ProgressDialog progressDialog = ProgressDialog.show(activity,
activity.getString(R.string.init_sendToCgeo),
activity.getString(R.string.init_sendToCgeo_registering), true);
progressDialog.setCancelable(false);
- (new Thread() {
-
- @Override
- public void run() {
- int pin = 0;
-
- final String nam = StringUtils.defaultString(deviceName);
- final String cod = StringUtils.defaultString(deviceCode);
-
- final Parameters params = new Parameters("name", nam, "code", cod);
- HttpResponse response = Network.getRequest("http://send2.cgeo.org/auth.html", params);
-
- if (response != null && response.getStatusLine().getStatusCode() == 200) {
- //response was OK
- String[] strings = StringUtils.split(Network.getResponseData(response), ',');
- try {
- pin = Integer.parseInt(strings[1].trim());
- } catch (Exception e) {
- Log.e("webDialog", e);
+ AndroidObservable.fromActivity(activity,
+ Observable.defer(new Func0<Observable<Integer>>() {
+ @Override
+ public Observable<Integer> call() {
+ final String nam = StringUtils.defaultString(deviceName);
+ final String cod = StringUtils.defaultString(deviceCode);
+
+ final Parameters params = new Parameters("name", nam, "code", cod);
+ HttpResponse response = Network.getRequest("http://send2.cgeo.org/auth.html", params);
+
+ if (response != null && response.getStatusLine().getStatusCode() == 200) {
+ //response was OK
+ final String[] strings = StringUtils.split(Network.getResponseData(response), ',');
+ Settings.setWebNameCode(nam, strings[0]);
+ try {
+ return Observable.from(Integer.parseInt(strings[1].trim()));
+ } catch (final Exception e) {
+ Log.e("RegisterSend2CgeoPreference", e);
+ }
+ }
+
+ return Observable.empty();
}
- String code = strings[0];
- Settings.setWebNameCode(nam, code);
+ }).firstOrDefault(0).subscribeOn(Schedulers.io())).subscribe(new Action1<Integer>() {
+ @Override
+ public void call(final Integer pin) {
+ progressDialog.dismiss();
+ if (pin > 0) {
+ Dialogs.message(activity, R.string.init_sendToCgeo,
+ activity.getString(R.string.init_sendToCgeo_register_ok)
+ .replace("####", String.valueOf(pin)));
+ } else {
+ Dialogs.message(activity, R.string.init_sendToCgeo, R.string.init_sendToCgeo_register_fail);
}
-
- webAuthHandler.sendEmptyMessage(pin);
}
- }).start();
+ });
return true;
}
- });
- return super.onCreateView(parent);
+ };
}
}
diff --git a/main/src/cgeo/geocaching/settings/Settings.java b/main/src/cgeo/geocaching/settings/Settings.java
index 0732866..6c3c984 100644
--- a/main/src/cgeo/geocaching/settings/Settings.java
+++ b/main/src/cgeo/geocaching/settings/Settings.java
@@ -54,8 +54,8 @@ public class Settings {
private final static int unitsMetric = 1;
// twitter api keys
- private final static String keyConsumerPublic = CryptUtils.rot13("ESnsCvAv3kEupF1GCR3jGj");
- private final static String keyConsumerSecret = CryptUtils.rot13("7vQWceACV9umEjJucmlpFe9FCMZSeqIqfkQ2BnhV9x");
+ private final static @NonNull String keyConsumerPublic = CryptUtils.rot13("ESnsCvAv3kEupF1GCR3jGj");
+ private final static @NonNull String keyConsumerSecret = CryptUtils.rot13("7vQWceACV9umEjJucmlpFe9FCMZSeqIqfkQ2BnhV9x");
public enum CoordInputFormatEnum {
Plain,
@@ -313,16 +313,16 @@ public class Settings {
return getBoolean(R.string.pref_connectorOXActive, false);
}
- public static boolean isPremiumMember() {
+ public static boolean isGCPremiumMember() {
// Basic Member, Premium Member, ???
- return GCConstants.MEMBER_STATUS_PM.equalsIgnoreCase(Settings.getMemberStatus());
+ return GCConstants.MEMBER_STATUS_PM.equalsIgnoreCase(Settings.getGCMemberStatus());
}
- public static String getMemberStatus() {
+ public static String getGCMemberStatus() {
return getString(R.string.pref_memberstatus, "");
}
- public static boolean setMemberStatus(final String memberStatus) {
+ public static boolean setGCMemberStatus(final String memberStatus) {
if (StringUtils.isBlank(memberStatus)) {
return remove(R.string.pref_memberstatus);
}
@@ -478,7 +478,7 @@ public class Settings {
}
public static boolean getLoadDirImg() {
- return !isPremiumMember() && getBoolean(R.string.pref_loaddirectionimg, true);
+ return !isGCPremiumMember() && getBoolean(R.string.pref_loaddirectionimg, true);
}
public static void setGcCustomDate(final String format) {
@@ -506,7 +506,7 @@ public class Settings {
}
public static boolean isShowCaptcha() {
- return !isPremiumMember() && getBoolean(R.string.pref_showcaptcha, false);
+ return !isGCPremiumMember() && getBoolean(R.string.pref_showcaptcha, false);
}
public static boolean isExcludeDisabledCaches() {
@@ -694,10 +694,12 @@ public class Settings {
return getBoolean(R.string.pref_skin, false);
}
+ @NonNull
public static String getKeyConsumerPublic() {
return keyConsumerPublic;
}
+ @NonNull
public static String getKeyConsumerSecret() {
return keyConsumerSecret;
}
diff --git a/main/src/cgeo/geocaching/settings/SettingsActivity.java b/main/src/cgeo/geocaching/settings/SettingsActivity.java
index 58acfc1..bcf6715 100644
--- a/main/src/cgeo/geocaching/settings/SettingsActivity.java
+++ b/main/src/cgeo/geocaching/settings/SettingsActivity.java
@@ -1,6 +1,7 @@
package cgeo.geocaching.settings;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.DataStore;
import cgeo.geocaching.Intents;
import cgeo.geocaching.R;
import cgeo.geocaching.SelectMapfileActivity;
@@ -19,8 +20,10 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.openintents.intents.FileManagerIntents;
+import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -52,8 +55,7 @@ import java.util.Locale;
*/
public class SettingsActivity extends PreferenceActivity {
- private static final String INTENT_GOTO = "GOTO";
- private static final int INTENT_GOTO_SERVICES = 1;
+ private static final String INTENT_OPEN_SCREEN = "OPEN_SCREEN";
/**
* Enumeration for directory choosers. This is how we can retrieve information about the
@@ -89,18 +91,21 @@ public class SettingsActivity extends PreferenceActivity {
initPreferences();
Intent intent = getIntent();
- int gotoPage = intent.getIntExtra(INTENT_GOTO, 0);
- if (gotoPage == INTENT_GOTO_SERVICES) {
- // start with services screen
- PreferenceScreen main = (PreferenceScreen) getPreference(R.string.pref_fakekey_main_screen);
- try {
- if (main != null) {
- int index = getPreference(R.string.pref_fakekey_services_screen).getOrder();
- main.onItemClick(null, null, index, 0);
- }
- } catch (RuntimeException e) {
- Log.e("could not open services preferences", e);
- }
+ openInitialScreen(intent.getIntExtra(INTENT_OPEN_SCREEN, 0));
+ }
+
+ private void openInitialScreen(int initialScreen) {
+ if (initialScreen == 0) {
+ return;
+ }
+ PreferenceScreen screen = (PreferenceScreen) getPreference(initialScreen);
+ if (screen == null) {
+ return;
+ }
+ try {
+ setPreferenceScreen(screen);
+ } catch (RuntimeException e) {
+ Log.e("could not open preferences " + initialScreen, e);
}
}
@@ -121,6 +126,7 @@ public class SettingsActivity extends PreferenceActivity {
initSend2CgeoPreferences();
initServicePreferences();
initNavigationMenuPreferences();
+ initMaintenanceButtons();
for (int k : new int[] { R.string.pref_username, R.string.pref_password,
R.string.pref_pass_vote, R.string.pref_signature,
@@ -141,9 +147,9 @@ public class SettingsActivity extends PreferenceActivity {
getPreference(appEnum.preferenceKey).setEnabled(true);
}
}
- getPreference(R.string.pref_fakekey_basicmembers_screen)
- .setEnabled(!Settings.isPremiumMember());
- redrawScreen(R.string.pref_fakekey_navigation_menu_screen);
+ getPreference(R.string.preference_screen_basicmembers)
+ .setEnabled(!Settings.isGCPremiumMember());
+ redrawScreen(R.string.preference_screen_navigation_menu);
}
private void initServicePreferences() {
@@ -310,6 +316,35 @@ public class SettingsActivity extends PreferenceActivity {
});
}
+ public void initMaintenanceButtons() {
+ Preference dirMaintenance = getPreference(R.string.pref_fakekey_preference_maintenance_directories);
+ dirMaintenance.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ // disable the button, as the cleanup runs in background and should not be invoked a second time
+ preference.setEnabled(false);
+
+ Resources res = getResources();
+ final SettingsActivity activity = SettingsActivity.this;
+ final ProgressDialog dialog = ProgressDialog.show(activity, res.getString(R.string.init_maintenance), res.getString(R.string.init_maintenance_directories), true, false);
+ new Thread() {
+ @Override
+ public void run() {
+ DataStore.removeObsoleteCacheDirectories();
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ dialog.dismiss();
+ }
+ });
+ }
+ }.start();
+
+ return true;
+ }
+ });
+ }
+
private void initDbLocationPreference() {
Preference p = getPreference(R.string.pref_dbonsdcard);
p.setPersistent(false);
@@ -336,21 +371,29 @@ public class SettingsActivity extends PreferenceActivity {
}
void initBasicMemberPreferences() {
- getPreference(R.string.pref_fakekey_basicmembers_screen)
- .setEnabled(!Settings.isPremiumMember());
+ getPreference(R.string.preference_screen_basicmembers)
+ .setEnabled(!Settings.isGCPremiumMember());
getPreference(R.string.pref_loaddirectionimg)
- .setEnabled(!Settings.isPremiumMember());
+ .setEnabled(!Settings.isGCPremiumMember());
getPreference(R.string.pref_showcaptcha)
- .setEnabled(!Settings.isPremiumMember());
+ .setEnabled(!Settings.isGCPremiumMember());
- redrawScreen(R.string.pref_fakekey_services_screen);
+ redrawScreen(R.string.preference_screen_services);
}
- void redrawScreen(int key) {
- PreferenceScreen screen = (PreferenceScreen) getPreference(key);
- if (screen == null) {
+ /**
+ * Refresh a preference screen. Has no effect when called for a preference, that is not actually a preference
+ * screen.
+ *
+ * @param key
+ * Key of a preference screen.
+ */
+ void redrawScreen(final int key) {
+ final Preference preference = getPreference(key);
+ if (!(preference instanceof PreferenceScreen)) {
return;
}
+ final PreferenceScreen screen = (PreferenceScreen) preference;
ListAdapter adapter = screen.getRootAdapter();
if (adapter instanceof BaseAdapter) {
((BaseAdapter) adapter).notifyDataSetChanged();
@@ -399,9 +442,9 @@ public class SettingsActivity extends PreferenceActivity {
: R.string.settings_authorize));
}
- public static void jumpToServicesPage(final Context fromActivity) {
+ public static void openForScreen(final int preferenceScreenKey, final Context fromActivity) {
final Intent intent = new Intent(fromActivity, SettingsActivity.class);
- intent.putExtra(INTENT_GOTO, INTENT_GOTO_SERVICES);
+ intent.putExtra(INTENT_OPEN_SCREEN, preferenceScreenKey);
fromActivity.startActivity(intent);
}
@@ -445,15 +488,15 @@ public class SettingsActivity extends PreferenceActivity {
break;
case R.string.pref_fakekey_ocde_authorization:
setOCDEAuthTitle();
- redrawScreen(R.string.pref_fakekey_services_screen);
+ redrawScreen(R.string.preference_screen_ocde);
break;
case R.string.pref_fakekey_ocpl_authorization:
setOCPLAuthTitle();
- redrawScreen(R.string.pref_fakekey_services_screen);
+ redrawScreen(R.string.preference_screen_ocpl);
break;
case R.string.pref_fakekey_twitter_authorization:
setTwitterAuthTitle();
- redrawScreen(R.string.pref_fakekey_services_screen);
+ redrawScreen(R.string.preference_screen_twitter);
break;
default:
throw new IllegalArgumentException();
@@ -582,6 +625,13 @@ public class SettingsActivity extends PreferenceActivity {
preferenceActivity.addPreferencesFromResource(preferencesResId);
}
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ // TODO replace with fragment based code
+ super.setPreferenceScreen(preferenceScreen);
+ }
+
private static boolean isPreference(final Preference preference, int preferenceKeyId) {
return getKey(preferenceKeyId).equals(preference.getKey());
}
diff --git a/main/src/cgeo/geocaching/settings/TemplateTextPreference.java b/main/src/cgeo/geocaching/settings/TemplateTextPreference.java
index a703231..667b02b 100644
--- a/main/src/cgeo/geocaching/settings/TemplateTextPreference.java
+++ b/main/src/cgeo/geocaching/settings/TemplateTextPreference.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.settings;
import cgeo.geocaching.R;
import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.ui.dialog.Dialogs;
import cgeo.geocaching.utils.LogTemplateProvider;
import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate;
@@ -49,6 +50,7 @@ public class TemplateTextPreference extends DialogPreference {
editText = (EditText) view.findViewById(R.id.signature_dialog_text);
editText.setText(getPersistedString(initialValue != null ? initialValue : StringUtils.EMPTY));
+ Dialogs.moveCursorToEnd(editText);
Button button = (Button) view.findViewById(R.id.signature_templates);
button.setOnClickListener(new View.OnClickListener() {
diff --git a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
index a1c04a4..2b171b4 100644
--- a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
+++ b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.sorting;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.utils.Log;
+import org.apache.commons.lang3.StringUtils;
/**
* abstract super implementation for all cache comparators
@@ -13,25 +14,35 @@ public abstract class AbstractCacheComparator implements CacheComparator {
@Override
public final int compare(final Geocache cache1, final Geocache cache2) {
try {
- // first check that we have all necessary data for the comparison
- if (!canCompare(cache1, cache2)) {
- return 0;
+ final boolean canCompare1 = canCompare(cache1);
+ final boolean canCompare2 = canCompare(cache2);
+ if (!canCompare1) {
+ return canCompare2 ? 1 : fallbackToGeocode(cache1, cache2);
}
- return compareCaches(cache1, cache2);
- } catch (Exception e) {
+ return canCompare2 ? compareCaches(cache1, cache2) : -1;
+ } catch (final Exception e) {
Log.e("AbstractCacheComparator.compare", e);
+ // This may violate the Comparator interface if the exception is not systematic.
+ return fallbackToGeocode(cache1, cache2);
}
- return 0;
+ }
+
+ private static int fallbackToGeocode(final Geocache cache1, final Geocache cache2) {
+ return StringUtils.defaultString(cache1.getGeocode()).compareToIgnoreCase(StringUtils.defaultString(cache2.getGeocode()));
}
/**
- * Check necessary preconditions (like missing fields) before running the comparison itself
- *
- * @param cache1
- * @param cache2
- * @return
+ * Check necessary preconditions (like missing fields) before running the comparison itself.
+ * Caches not filling the conditions will be placed last, sorted by Geocode.
+ *
+ * The default returns <code>true</code> and can be overridden if needed in child classes.
+ *
+ * @param cache
+ * @return <code>true</code> if the cache holds the necessary data to be compared meaningfully
*/
- protected abstract boolean canCompare(final Geocache cache1, final Geocache cache2);
+ protected boolean canCompare(final Geocache cache) {
+ return true;
+ }
/**
* Compares two caches. Logging and exception handling is implemented outside this method already.
diff --git a/main/src/cgeo/geocaching/sorting/CacheComparator.java b/main/src/cgeo/geocaching/sorting/CacheComparator.java
index 7932729..b06a4b0 100644
--- a/main/src/cgeo/geocaching/sorting/CacheComparator.java
+++ b/main/src/cgeo/geocaching/sorting/CacheComparator.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.sorting;
-import java.util.Comparator;
-
import cgeo.geocaching.Geocache;
+import java.util.Comparator;
+
public interface CacheComparator extends Comparator<Geocache> {
}
diff --git a/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java b/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java
index 99a535a..7f10353 100644
--- a/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java
+++ b/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java
@@ -2,7 +2,8 @@ package cgeo.geocaching.sorting;
import cgeo.geocaching.R;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.RunnableWithArgument;
+
+import rx.functions.Action1;
import android.app.Activity;
import android.app.AlertDialog;
@@ -70,7 +71,7 @@ public class ComparatorUserInterface {
registry.add(new ComparatorEntry(res.getString(resourceId), comparatorClass));
}
- public void selectComparator(final CacheComparator current, final RunnableWithArgument<CacheComparator> runAfterwards) {
+ public void selectComparator(final CacheComparator current, final Action1<CacheComparator> runAfterwards) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.caches_sort_title);
@@ -85,11 +86,11 @@ public class ComparatorUserInterface {
ComparatorEntry entry = registry.get(itemIndex);
try {
if (entry.cacheComparator == null) {
- runAfterwards.run(null);
+ runAfterwards.call(null);
}
else {
CacheComparator comparator = entry.cacheComparator.newInstance();
- runAfterwards.run(comparator);
+ runAfterwards.call(comparator);
}
} catch (InstantiationException e) {
Log.e("selectComparator", e);
diff --git a/main/src/cgeo/geocaching/sorting/DateComparator.java b/main/src/cgeo/geocaching/sorting/DateComparator.java
index 091f6a4..9df70f9 100644
--- a/main/src/cgeo/geocaching/sorting/DateComparator.java
+++ b/main/src/cgeo/geocaching/sorting/DateComparator.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.sorting;
-import cgeo.geocaching.Geocache;
import cgeo.geocaching.CgeoApplication;
+import cgeo.geocaching.Geocache;
import java.util.ArrayList;
import java.util.Date;
@@ -12,11 +12,6 @@ import java.util.Date;
public class DateComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(Geocache cache1, Geocache cache2) {
final Date date1 = cache1.getHiddenDate();
final Date date2 = cache2.getHiddenDate();
diff --git a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
index 73d12fa..459f38d 100644
--- a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
+++ b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
@@ -9,8 +9,8 @@ import cgeo.geocaching.Geocache;
public class DifficultyComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return cache1.getDifficulty() != 0.0 && cache2.getDifficulty() != 0.0;
+ protected boolean canCompare(Geocache cache) {
+ return cache.getDifficulty() != 0.0;
}
@Override
diff --git a/main/src/cgeo/geocaching/sorting/DistanceComparator.java b/main/src/cgeo/geocaching/sorting/DistanceComparator.java
index 731e356..541ce48 100644
--- a/main/src/cgeo/geocaching/sorting/DistanceComparator.java
+++ b/main/src/cgeo/geocaching/sorting/DistanceComparator.java
@@ -36,11 +36,6 @@ public class DistanceComparator extends AbstractCacheComparator {
}
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
calculateAllDistances();
final Float distance1 = cache1.getDistance();
diff --git a/main/src/cgeo/geocaching/sorting/FindsComparator.java b/main/src/cgeo/geocaching/sorting/FindsComparator.java
index c889776..7f2ef50 100644
--- a/main/src/cgeo/geocaching/sorting/FindsComparator.java
+++ b/main/src/cgeo/geocaching/sorting/FindsComparator.java
@@ -5,8 +5,8 @@ import cgeo.geocaching.Geocache;
public class FindsComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return cache1.getLogCounts() != null && cache2.getLogCounts() != null;
+ protected boolean canCompare(Geocache cache) {
+ return cache.getLogCounts() != null;
}
@Override
diff --git a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
index fff26c6..e700f13 100644
--- a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
+++ b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
@@ -2,23 +2,20 @@ package cgeo.geocaching.sorting;
import cgeo.geocaching.Geocache;
-import org.apache.commons.lang3.StringUtils;
-
/**
* sorts caches by geo code, therefore effectively sorting by cache age
- *
+ *
*/
public class GeocodeComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return StringUtils.isNotBlank(cache1.getGeocode())
- && StringUtils.isNotBlank(cache2.getGeocode());
+ protected boolean canCompare(final Geocache cache) {
+ // This will fall back to geocode comparisons.
+ return false;
}
@Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
- final int lengthDiff = cache1.getGeocode().length() - cache2.getGeocode().length();
- return lengthDiff != 0 ? lengthDiff : cache1.getGeocode().compareToIgnoreCase(cache2.getGeocode());
+ throw new RuntimeException("should never be called");
}
}
diff --git a/main/src/cgeo/geocaching/sorting/InventoryComparator.java b/main/src/cgeo/geocaching/sorting/InventoryComparator.java
index 73ea2c5..9d19b64 100644
--- a/main/src/cgeo/geocaching/sorting/InventoryComparator.java
+++ b/main/src/cgeo/geocaching/sorting/InventoryComparator.java
@@ -8,11 +8,6 @@ import cgeo.geocaching.Geocache;
public class InventoryComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
return cache2.getInventoryItems() - cache1.getInventoryItems();
}
diff --git a/main/src/cgeo/geocaching/sorting/NameComparator.java b/main/src/cgeo/geocaching/sorting/NameComparator.java
index b432ad0..2941b1c 100644
--- a/main/src/cgeo/geocaching/sorting/NameComparator.java
+++ b/main/src/cgeo/geocaching/sorting/NameComparator.java
@@ -11,8 +11,8 @@ import org.apache.commons.lang3.StringUtils;
public class NameComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return StringUtils.isNotBlank(cache1.getName()) && StringUtils.isNotBlank(cache2.getName());
+ protected boolean canCompare(Geocache cache) {
+ return StringUtils.isNotBlank(cache.getName());
}
@Override
diff --git a/main/src/cgeo/geocaching/sorting/PopularityComparator.java b/main/src/cgeo/geocaching/sorting/PopularityComparator.java
index e256654..2dbee68 100644
--- a/main/src/cgeo/geocaching/sorting/PopularityComparator.java
+++ b/main/src/cgeo/geocaching/sorting/PopularityComparator.java
@@ -9,11 +9,6 @@ import cgeo.geocaching.Geocache;
public class PopularityComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
return cache2.getFavoritePoints() - cache1.getFavoritePoints();
}
diff --git a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
index f438762..1ed8e68 100644
--- a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
+++ b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
@@ -11,11 +11,6 @@ import cgeo.geocaching.Geocache;
public class PopularityRatioComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
float ratio1 = 0.0f;
diff --git a/main/src/cgeo/geocaching/sorting/RatingComparator.java b/main/src/cgeo/geocaching/sorting/RatingComparator.java
index 72cf6c8..6f2c615 100644
--- a/main/src/cgeo/geocaching/sorting/RatingComparator.java
+++ b/main/src/cgeo/geocaching/sorting/RatingComparator.java
@@ -9,11 +9,6 @@ import cgeo.geocaching.Geocache;
public class RatingComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
final float rating1 = cache1.getRating();
final float rating2 = cache2.getRating();
diff --git a/main/src/cgeo/geocaching/sorting/SizeComparator.java b/main/src/cgeo/geocaching/sorting/SizeComparator.java
index d128822..c8de586 100644
--- a/main/src/cgeo/geocaching/sorting/SizeComparator.java
+++ b/main/src/cgeo/geocaching/sorting/SizeComparator.java
@@ -9,8 +9,8 @@ import cgeo.geocaching.Geocache;
public class SizeComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return cache1.getSize() != null && cache2.getSize() != null;
+ protected boolean canCompare(Geocache cache) {
+ return cache.getSize() != null;
}
@Override
diff --git a/main/src/cgeo/geocaching/sorting/StateComparator.java b/main/src/cgeo/geocaching/sorting/StateComparator.java
index b99c3c0..9488bd9 100644
--- a/main/src/cgeo/geocaching/sorting/StateComparator.java
+++ b/main/src/cgeo/geocaching/sorting/StateComparator.java
@@ -9,11 +9,6 @@ import cgeo.geocaching.Geocache;
public class StateComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
return getState(cache1) - getState(cache2);
}
diff --git a/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java b/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java
index 78ba742..b718d3b 100644
--- a/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java
+++ b/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java
@@ -5,11 +5,6 @@ import cgeo.geocaching.Geocache;
public class StorageTimeComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(Geocache cache1, Geocache cache2) {
if (cache1.getUpdated() < cache2.getUpdated()) {
return -1;
diff --git a/main/src/cgeo/geocaching/sorting/TerrainComparator.java b/main/src/cgeo/geocaching/sorting/TerrainComparator.java
index be1e9bb..9bbb5f7 100644
--- a/main/src/cgeo/geocaching/sorting/TerrainComparator.java
+++ b/main/src/cgeo/geocaching/sorting/TerrainComparator.java
@@ -9,8 +9,8 @@ import cgeo.geocaching.Geocache;
public class TerrainComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return cache1.getTerrain() != 0.0 && cache2.getTerrain() != 0.0;
+ protected boolean canCompare(final Geocache cache) {
+ return cache.getTerrain() != 0.0;
}
@Override
diff --git a/main/src/cgeo/geocaching/sorting/VisitComparator.java b/main/src/cgeo/geocaching/sorting/VisitComparator.java
index 27d3170..1589a4c 100644
--- a/main/src/cgeo/geocaching/sorting/VisitComparator.java
+++ b/main/src/cgeo/geocaching/sorting/VisitComparator.java
@@ -9,11 +9,6 @@ import cgeo.geocaching.Geocache;
public class VisitComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(final Geocache cache1, final Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(final Geocache cache1, final Geocache cache2) {
return Long.valueOf(cache2.getVisitedDate()).compareTo(cache1.getVisitedDate());
}
diff --git a/main/src/cgeo/geocaching/sorting/VoteComparator.java b/main/src/cgeo/geocaching/sorting/VoteComparator.java
index dc0304b..cd4ad7e 100644
--- a/main/src/cgeo/geocaching/sorting/VoteComparator.java
+++ b/main/src/cgeo/geocaching/sorting/VoteComparator.java
@@ -8,11 +8,6 @@ import cgeo.geocaching.Geocache;
public class VoteComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(Geocache cache1, Geocache cache2) {
- return true;
- }
-
- @Override
protected int compareCaches(Geocache cache1, Geocache cache2) {
// if there is no vote available, put that cache at the end of the list
return Float.compare(cache2.getMyVote(), cache1.getMyVote());
diff --git a/main/src/cgeo/geocaching/speech/SpeechService.java b/main/src/cgeo/geocaching/speech/SpeechService.java
index 2a72bbf..8c650c3 100644
--- a/main/src/cgeo/geocaching/speech/SpeechService.java
+++ b/main/src/cgeo/geocaching/speech/SpeechService.java
@@ -47,7 +47,7 @@ public class SpeechService extends Service implements OnInitListener {
GeoDirHandler geoHandler = new GeoDirHandler() {
@Override
- protected void updateDirection(float newDirection) {
+ public void updateDirection(float newDirection) {
if (CgeoApplication.getInstance().currentGeo().getSpeed() <= 5) {
direction = DirectionProvider.getDirectionNow(startingActivity, newDirection);
directionInitialized = true;
@@ -56,7 +56,7 @@ public class SpeechService extends Service implements OnInitListener {
}
@Override
- protected void updateGeoData(cgeo.geocaching.IGeoData newGeo) {
+ public void updateGeoData(cgeo.geocaching.IGeoData newGeo) {
position = newGeo.getCoords();
positionInitialized = true;
if (!Settings.isUseCompass() || newGeo.getSpeed() > 5) {
diff --git a/main/src/cgeo/geocaching/speech/TextFactory.java b/main/src/cgeo/geocaching/speech/TextFactory.java
index 2a3b6d7..eb780c6 100644
--- a/main/src/cgeo/geocaching/speech/TextFactory.java
+++ b/main/src/cgeo/geocaching/speech/TextFactory.java
@@ -2,9 +2,9 @@ package cgeo.geocaching.speech;
import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.IConversion;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.AngleUtils;
import java.util.Locale;
diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java
index 51cf6e2..c89c0b6 100644
--- a/main/src/cgeo/geocaching/twitter/Twitter.java
+++ b/main/src/cgeo/geocaching/twitter/Twitter.java
@@ -17,7 +17,6 @@ import cgeo.geocaching.utils.LogTemplateProvider;
import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
import ch.boye.httpclientandroidlib.HttpResponse;
-
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
diff --git a/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java b/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java
index ed5d182..0c67384 100644
--- a/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java
+++ b/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java
@@ -3,7 +3,6 @@ package cgeo.geocaching.ui;
import cgeo.geocaching.activity.AbstractViewPagerActivity.PageViewCreator;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
diff --git a/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java b/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java
index db82e5c..d4c2e10 100644
--- a/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java
+++ b/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java
@@ -8,7 +8,7 @@ import android.widget.TextView;
/**
* <code>LinkMovementMethod</code> with built-in suppression of errors for links, where the URL cannot be handled
* correctly by Android.
- *
+ *
*/
public class AnchorAwareLinkMovementMethod extends LinkMovementMethod {
diff --git a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
index 7fe77c4..5d8ebef 100644
--- a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
+++ b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
@@ -39,6 +39,11 @@ public final class CacheDetailsCreator {
parentView.removeAllViews();
}
+ /**
+ * @param nameId
+ * @param value
+ * @return the view containing the displayed string (i.e. the right side one from the pair of "label": "value")
+ */
public TextView add(final int nameId, final CharSequence value) {
final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_information_item, null);
final TextView nameView = (TextView) layout.findViewById(R.id.name);
@@ -188,14 +193,24 @@ public final class CacheDetailsCreator {
if (!cache.isEventCache()) {
return;
}
+ addHiddenDate(cache);
+ }
+
+ public TextView addHiddenDate(final @NonNull Geocache cache) {
final Date hiddenDate = cache.getHiddenDate();
if (hiddenDate == null) {
- return;
+ return null;
}
final long time = hiddenDate.getTime();
if (time > 0) {
- final String dateString = DateUtils.formatDateTime(CgeoApplication.getInstance().getBaseContext(), time, DateUtils.FORMAT_SHOW_WEEKDAY) + ", " + Formatter.formatFullDate(time);
- add(R.string.cache_event, dateString);
+ String dateString = Formatter.formatFullDate(time);
+ if (cache.isEventCache()) {
+ dateString = DateUtils.formatDateTime(CgeoApplication.getInstance().getBaseContext(), time, DateUtils.FORMAT_SHOW_WEEKDAY) + ", " + dateString;
+ }
+ final TextView view = add(cache.isEventCache() ? R.string.cache_event : R.string.cache_hidden, dateString);
+ view.setId(R.id.date);
+ return view;
}
+ return null;
}
}
diff --git a/main/src/cgeo/geocaching/ui/EditNoteDialog.java b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
index 2af1cb8..63f06fc 100644
--- a/main/src/cgeo/geocaching/ui/EditNoteDialog.java
+++ b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
@@ -1,12 +1,17 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
+import cgeo.geocaching.activity.Keyboard;
+import cgeo.geocaching.ui.dialog.Dialogs;
+
+import org.eclipse.jdt.annotation.NonNull;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.EditText;
@@ -35,15 +40,17 @@ public class EditNoteDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- View view = View.inflate(new ContextThemeWrapper(getActivity(), R.style.dark), R.layout.fragment_edit_note, null);
+ final @NonNull FragmentActivity activity = getActivity();
+ View view = View.inflate(new ContextThemeWrapper(activity, R.style.dark), R.layout.fragment_edit_note, null);
mEditText = (EditText) view.findViewById(R.id.note);
String initialNote = getArguments().getString(ARGUMENT_INITIAL_NOTE);
if (initialNote != null) {
mEditText.setText(initialNote);
+ Dialogs.moveCursorToEnd(mEditText);
getArguments().remove(ARGUMENT_INITIAL_NOTE);
}
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.cache_personal_note);
builder.setView(view);
builder.setPositiveButton(android.R.string.ok,
@@ -61,6 +68,8 @@ public class EditNoteDialog extends DialogFragment {
dialog.dismiss();
}
});
- return builder.create();
+ final AlertDialog dialog = builder.create();
+ new Keyboard(activity).showDelayed(mEditText);
+ return dialog;
}
}
diff --git a/main/src/cgeo/geocaching/ui/ImagesList.java b/main/src/cgeo/geocaching/ui/ImagesList.java
index 4eaf06d..dcce969 100644
--- a/main/src/cgeo/geocaching/ui/ImagesList.java
+++ b/main/src/cgeo/geocaching/ui/ImagesList.java
@@ -9,6 +9,12 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import rx.Subscription;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action0;
+import rx.functions.Action1;
+import rx.subscriptions.CompositeSubscription;
+import rx.subscriptions.Subscriptions;
import android.app.Activity;
import android.content.Intent;
@@ -18,14 +24,12 @@ import android.graphics.Bitmap.CompressFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
-import android.os.AsyncTask;
import android.text.Html;
import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -44,8 +48,7 @@ public class ImagesList {
public enum ImageType {
LogImages(R.string.cache_log_images_title),
- SpoilerImages(R.string.cache_spoiler_images_title),
- AllImages(R.string.cache_images_title);
+ SpoilerImages(R.string.cache_spoiler_images_title);
private final int titleResId;
@@ -75,12 +78,31 @@ public class ImagesList {
inflater = activity.getLayoutInflater();
}
- public void loadImages(final View parentView, final List<Image> images, final boolean offline) {
+ /**
+ * Load images into a view.
+ *
+ * @param parentView a view to load the images into
+ * @param images the images to load
+ * @param offline <tt>true</tt> if the images must be stored for offline use
+ * @return a subscription which, when unsubscribed, interrupts the loading and clears up resources
+ */
+ public Subscription loadImages(final View parentView, final List<Image> images, final boolean offline) {
+ // Start with a fresh subscription because of this method can be called several times if the
+ // englobing activity is stopped/restarted.
+ final CompositeSubscription subscriptions = new CompositeSubscription(Subscriptions.create(new Action0() {
+ @Override
+ public void call() {
+ removeAllViews();
+ }
+ }));
imagesView = (LinearLayout) parentView.findViewById(R.id.spoiler_list);
+ final HtmlImage imgGetter = new HtmlImage(geocode, true, offline ? StoredList.STANDARD_LIST_ID : StoredList.TEMPORARY_LIST_ID, false);
+
for (final Image img : images) {
- LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null);
+ final LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null);
+ assert(rowView != null);
if (StringUtils.isNotBlank(img.getTitle())) {
((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.getTitle()));
@@ -93,66 +115,58 @@ public class ImagesList {
descView.setVisibility(View.VISIBLE);
}
- new AsyncImgLoader(rowView, img, offline).execute();
+ final ImageView imageView = (ImageView) inflater.inflate(R.layout.image_item, null);
+ assert(imageView != null);
+ subscriptions.add(AndroidObservable.fromActivity(activity, imgGetter.fetchDrawable(img.getUrl()))
+ .subscribe(new Action1<BitmapDrawable>() {
+ @Override
+ public void call(final BitmapDrawable image) {
+ display(imageView, image, img, rowView);
+ }
+ }));
+ rowView.addView(imageView);
imagesView.addView(rowView);
}
+
+ return subscriptions;
}
- private class AsyncImgLoader extends AsyncTask<Void, Void, BitmapDrawable> {
+ private void display(final ImageView imageView, final BitmapDrawable image, final Image img, final LinearLayout view) {
+ if (image != null) {
+ bitmaps.add(image.getBitmap());
- final private LinearLayout view;
- final private Image img;
- final boolean offline;
+ final Rect bounds = image.getBounds();
- public AsyncImgLoader(final LinearLayout view, final Image img, final boolean offline) {
- this.view = view;
- this.img = img;
- this.offline = offline;
- }
+ imageView.setImageResource(R.drawable.image_not_loaded);
+ imageView.setClickable(true);
+ imageView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ viewImageInStandardApp(image);
+ }
+ });
+ activity.registerForContextMenu(imageView);
+ imageView.setImageDrawable(image);
+ imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+ imageView.setLayoutParams(new LinearLayout.LayoutParams(bounds.width(), bounds.height()));
- @Override
- protected BitmapDrawable doInBackground(Void... params) {
- final HtmlImage imgGetter = new HtmlImage(geocode, true, offline ? StoredList.STANDARD_LIST_ID : StoredList.TEMPORARY_LIST_ID, false);
- return imgGetter.getDrawable(img.getUrl());
- }
+ view.findViewById(R.id.progress_bar).setVisibility(View.GONE);
- @Override
- protected void onPostExecute(final BitmapDrawable image) {
- if (image != null) {
- bitmaps.add(image.getBitmap());
- final ImageView imageView = (ImageView) inflater.inflate(R.layout.image_item, null);
-
- final Rect bounds = image.getBounds();
-
- imageView.setImageResource(R.drawable.image_not_loaded);
- imageView.setClickable(true);
- imageView.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View arg0) {
- viewImageInStandardApp(image);
- }
- });
- activity.registerForContextMenu(imageView);
- imageView.setImageDrawable(image);
- imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
- imageView.setLayoutParams(new LayoutParams(bounds.width(), bounds.height()));
-
- view.findViewById(R.id.progress_bar).setVisibility(View.GONE);
- view.addView(imageView);
-
- imageView.setId(image.hashCode());
- images.put(imageView.getId(), img);
- }
+ imageView.setId(image.hashCode());
+ images.put(imageView.getId(), img);
+
+ view.invalidate();
}
}
- public void removeAllViews() {
- imagesView.removeAllViews();
+ private void removeAllViews() {
for (final Bitmap b : bitmaps) {
b.recycle();
}
bitmaps.clear();
+ images.clear();
+
+ imagesView.removeAllViews();
}
public void onCreateContextMenu(ContextMenu menu, View v) {
diff --git a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
index 93f50e1..651ff6e 100644
--- a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
+++ b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
@@ -54,7 +54,7 @@ public class CoordinatesInputDialog extends NoTitleDialog {
} else if (geo != null && geo.getCoords() != null) {
this.gp = geo.getCoords();
} else {
- this.gp = new Geopoint(0.0, 0.0);
+ this.gp = Geopoint.ZERO;
}
}
@@ -396,7 +396,7 @@ public class CoordinatesInputDialog extends NoTitleDialog {
if (geo != null && geo.getCoords() != null) {
gp = geo.getCoords();
} else {
- gp = new Geopoint(0.0, 0.0);
+ gp = Geopoint.ZERO;
}
}
}
diff --git a/main/src/cgeo/geocaching/ui/dialog/Dialogs.java b/main/src/cgeo/geocaching/ui/dialog/Dialogs.java
index 865ba70..cb8926a 100644
--- a/main/src/cgeo/geocaching/ui/dialog/Dialogs.java
+++ b/main/src/cgeo/geocaching/ui/dialog/Dialogs.java
@@ -1,20 +1,24 @@
package cgeo.geocaching.ui.dialog;
import cgeo.geocaching.CgeoApplication;
-import cgeo.geocaching.utils.RunnableWithArgument;
+import cgeo.geocaching.R;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
+import rx.functions.Action1;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
+import android.view.ContextThemeWrapper;
import android.view.WindowManager;
import android.widget.EditText;
@@ -298,7 +302,7 @@ public final class Dialogs {
/**
* Show a message dialog for input from the user. The okay button is only enabled on non empty input.
- *
+ *
* @param context
* activity owning the dialog
* @param title
@@ -310,19 +314,20 @@ public final class Dialogs {
* @param okayListener
* listener to be run on okay
*/
- public static void input(final Activity context, final int title, final String defaultValue, final int buttonTitle, final RunnableWithArgument<String> okayListener) {
- final EditText input = new EditText(context);
+ public static void input(final Activity context, final int title, final String defaultValue, final int buttonTitle, final Action1<String> okayListener) {
+ final Context themedContext = new ContextThemeWrapper(context, R.style.dark);
+ final EditText input = new EditText(themedContext);
input.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_CLASS_TEXT);
input.setText(defaultValue);
- final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
builder.setTitle(title);
builder.setView(input);
builder.setPositiveButton(buttonTitle, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- okayListener.run(input.getText().toString());
+ okayListener.call(input.getText().toString());
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@@ -357,8 +362,16 @@ public final class Dialogs {
dialog.show();
enableDialogButtonIfNotEmpty(dialog, defaultValue);
- // position cursor after text
- input.setSelection(input.getText().length());
+ moveCursorToEnd(input);
+ }
+
+ /**
+ * Move the cursor to the end of the input field.
+ *
+ * @param input
+ */
+ public static void moveCursorToEnd(final EditText input) {
+ input.setSelection(input.getText().length(), input.getText().length());
}
private static void enableDialogButtonIfNotEmpty(final AlertDialog dialog, final String input) {
diff --git a/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
index 6ad59ec..c29f549 100644
--- a/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
+++ b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
@@ -1,15 +1,14 @@
package cgeo.geocaching.ui.dialog;
+import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.R;
import cgeo.geocaching.settings.Settings;
-import cgeo.geocaching.CgeoApplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.ContextThemeWrapper;
import android.view.View;
-import android.widget.CheckBox;
public class LiveMapInfoDialogBuilder {
@@ -20,12 +19,7 @@ public class LiveMapInfoDialogBuilder {
final View layout = View.inflate(new ContextThemeWrapper(activity, R.style.dark), R.layout.livemapinfo, null);
builder.setView(layout);
- final CheckBox checkBoxHide = (CheckBox) layout.findViewById(R.id.live_map_hint_hide);
-
final int showCount = Settings.getLiveMapHintShowCount();
- if (showCount > 2) {
- checkBoxHide.setVisibility(View.VISIBLE);
- }
Settings.setLiveMapHintShowCount(showCount + 1);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@@ -33,10 +27,7 @@ public class LiveMapInfoDialogBuilder {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- CgeoApplication.getInstance().setLiveMapHintShown();
- if (checkBoxHide.getVisibility() == View.VISIBLE && checkBoxHide.isChecked()) {
- Settings.setHideLiveHint(true);
- }
+ CgeoApplication.getInstance().setLiveMapHintShownInThisSession();
}
});
return builder.create();
diff --git a/main/src/cgeo/geocaching/utils/CancellableHandler.java b/main/src/cgeo/geocaching/utils/CancellableHandler.java
index cb4b9db..01fb568 100644
--- a/main/src/cgeo/geocaching/utils/CancellableHandler.java
+++ b/main/src/cgeo/geocaching/utils/CancellableHandler.java
@@ -2,6 +2,9 @@ package cgeo.geocaching.utils;
import cgeo.geocaching.CgeoApplication;
+import rx.Subscription;
+import rx.subscriptions.CompositeSubscription;
+
import android.os.Handler;
import android.os.Message;
@@ -13,6 +16,7 @@ public abstract class CancellableHandler extends Handler {
protected static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186;
private volatile boolean cancelled = false;
+ private static CompositeSubscription subscriptions = new CompositeSubscription();
private static class CancelHolder {
final Object payload;
@@ -30,6 +34,7 @@ public abstract class CancellableHandler extends Handler {
if (message.obj instanceof CancelHolder) {
cancelled = true;
+ subscriptions.unsubscribe();
handleCancel(((CancelHolder) message.obj).payload);
} else {
handleRegularMessage(message);
@@ -37,6 +42,17 @@ public abstract class CancellableHandler extends Handler {
}
/**
+ * Add a subscription to the list of subscriptions to be subscribed at cancellation time.
+ */
+ final public void unsubscribeIfCancelled(final Subscription subscription) {
+ subscriptions.add(subscription);
+ if (cancelled) {
+ // Protect against race conditions
+ subscriptions.unsubscribe();
+ }
+ }
+
+ /**
* Handle a non-cancel message.<br>
* Subclasses must implement this to handle messages.
*
diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java
index 5273fa5..80d841f 100644
--- a/main/src/cgeo/geocaching/utils/CryptUtils.java
+++ b/main/src/cgeo/geocaching/utils/CryptUtils.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.utils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
@@ -66,6 +67,8 @@ public final class CryptUtils {
}
}
+ @SuppressWarnings("null")
+ @NonNull
public static String rot13(String text) {
if (text == null) {
return StringUtils.EMPTY;
diff --git a/main/src/cgeo/geocaching/utils/FileUtils.java b/main/src/cgeo/geocaching/utils/FileUtils.java
index f650216..54553c2 100644
--- a/main/src/cgeo/geocaching/utils/FileUtils.java
+++ b/main/src/cgeo/geocaching/utils/FileUtils.java
@@ -1,12 +1,20 @@
package cgeo.geocaching.utils;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import android.os.Handler;
import android.os.Message;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
import java.util.List;
/**
@@ -126,4 +134,23 @@ public final class FileUtils {
}
return success;
}
+
+ public static boolean writeFileUTF16(File file, String content) {
+ // TODO: replace by some apache.commons IOUtils or FileUtils code
+ Writer fileWriter = null;
+ BufferedOutputStream buffer = null;
+ try {
+ final OutputStream os = new FileOutputStream(file);
+ buffer = new BufferedOutputStream(os);
+ fileWriter = new OutputStreamWriter(buffer, CharEncoding.UTF_16);
+ fileWriter.write(content.toString());
+ } catch (final IOException e) {
+ Log.e("FieldnoteExport.ExportTask export", e);
+ return false;
+ } finally {
+ IOUtils.closeQuietly(fileWriter);
+ IOUtils.closeQuietly(buffer);
+ }
+ return true;
+ }
}
diff --git a/main/src/cgeo/geocaching/utils/GeoDirHandler.java b/main/src/cgeo/geocaching/utils/GeoDirHandler.java
index c85648b..7050e61 100644
--- a/main/src/cgeo/geocaching/utils/GeoDirHandler.java
+++ b/main/src/cgeo/geocaching/utils/GeoDirHandler.java
@@ -4,12 +4,16 @@ import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.IGeoData;
import cgeo.geocaching.settings.Settings;
-import android.os.Handler;
-import android.os.Message;
+import rx.Scheduler;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+import rx.functions.Action1;
+
+import java.util.concurrent.TimeUnit;
/**
- * GeoData and Direction handler. Manipulating geodata and direction information
- * through a GeoDirHandler ensures that all listeners are registered from a {@link android.os.Looper} thread.
+ * GeoData and Direction handler.
* <p>
* To use this class, override at least one of {@link #updateDirection(float)} or {@link #updateGeoData(IGeoData)}. You
* need to start the handler using one of
@@ -21,47 +25,11 @@ import android.os.Message;
* A good place might be the {@code onResume} method of the Activity. Stop the Handler accordingly in {@code onPause}.
* </p>
*/
-public abstract class GeoDirHandler extends Handler implements IObserver<Object> {
-
- private static final int OBSERVABLE = 1 << 1;
- private static final int START_GEO = 1 << 2;
- private static final int START_DIR = 1 << 3;
- private static final int STOP_GEO = 1 << 4;
- private static final int STOP_DIR = 1 << 5;
-
+public abstract class GeoDirHandler {
private static final CgeoApplication app = CgeoApplication.getInstance();
- @Override
- final public void handleMessage(final Message message) {
- if ((message.what & START_GEO) != 0) {
- app.addGeoObserver(this);
- }
-
- if ((message.what & START_DIR) != 0) {
- app.addDirectionObserver(this);
- }
-
- if ((message.what & STOP_GEO) != 0) {
- app.deleteGeoObserver(this);
- }
-
- if ((message.what & STOP_DIR) != 0) {
- app.deleteDirectionObserver(this);
- }
-
- if ((message.what & OBSERVABLE) != 0) {
- if (message.obj instanceof IGeoData) {
- updateGeoData((IGeoData) message.obj);
- } else {
- updateDirection((Float) message.obj);
- }
- }
- }
-
- @Override
- final public void update(final Object o) {
- obtainMessage(OBSERVABLE, o).sendToTarget();
- }
+ private Subscription dirSubscription = null;
+ private Subscription geoSubscription = null;
/**
* Update method called when new IGeoData is available.
@@ -69,7 +37,7 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object>
* @param data
* the new data
*/
- protected void updateGeoData(final IGeoData data) {
+ public void updateGeoData(final IGeoData data) {
// Override this in children
}
@@ -79,24 +47,38 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object>
* @param direction
* the new direction
*/
- protected void updateDirection(final float direction) {
+ public void updateDirection(final float direction) {
// Override this in children
}
/**
* Register the current GeoDirHandler for GeoData information.
*/
- public void startGeo() {
- sendEmptyMessage(START_GEO);
+ public synchronized void startGeo() {
+ geoSubscription = app.currentGeoObject()
+ .subscribeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Action1<IGeoData>() {
+ @Override
+ public void call(final IGeoData geoData) {
+ updateGeoData(geoData);
+ }
+ });
}
/**
* Register the current GeoDirHandler for direction information if the preferences
* allow it.
*/
- public void startDir() {
+ public synchronized void startDir() {
if (Settings.isUseCompass()) {
- sendEmptyMessage(START_DIR);
+ dirSubscription = app.currentDirObject()
+ .subscribeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Action1<Float>() {
+ @Override
+ public void call(final Float direction) {
+ updateDirection(direction);
+ }
+ });
}
}
@@ -105,27 +87,43 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object>
* preferences allow it).
*/
public void startGeoAndDir() {
- sendEmptyMessage(START_GEO | (Settings.isUseCompass() ? START_DIR : 0));
+ startGeo();
+ startDir();
}
/**
* Unregister the current GeoDirHandler for GeoData information.
*/
- public void stopGeo() {
- sendEmptyMessage(STOP_GEO);
+ public synchronized void stopGeo() {
+ // Delay the unsubscription by 2.5 seconds, so that another activity has
+ // the time to subscribe and the GPS receiver will not be turned down.
+ if (geoSubscription != null) {
+ final Subscription subscription = geoSubscription;
+ geoSubscription = null;
+ Schedulers.newThread().schedule(new Action1<Scheduler.Inner>() {
+ @Override
+ public void call(final Scheduler.Inner inner) {
+ subscription.unsubscribe();
+ }
+ }, 2500, TimeUnit.MILLISECONDS);
+ }
}
/**
* Unregister the current GeoDirHandler for direction information.
*/
- public void stopDir() {
- sendEmptyMessage(STOP_DIR);
+ public synchronized void stopDir() {
+ if (dirSubscription != null) {
+ dirSubscription.unsubscribe();
+ dirSubscription = null;
+ }
}
/**
* Unregister the current GeoDirHandler for GeoData and direction information.
*/
public void stopGeoAndDir() {
- sendEmptyMessage(STOP_GEO | STOP_DIR);
+ stopGeo();
+ stopDir();
}
}
diff --git a/main/src/cgeo/geocaching/utils/IObserver.java b/main/src/cgeo/geocaching/utils/IObserver.java
deleted file mode 100644
index bfcc798..0000000
--- a/main/src/cgeo/geocaching/utils/IObserver.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package cgeo.geocaching.utils;
-
-/**
- * Observer interface.
- * <p/>
- * An observer will receive updates about the observed object (implementing the {@link ISubject} interface) through its
- * {@link #update(Object)} method.
- *
- * @param <T>
- * the kind of data to observe
- */
-public interface IObserver<T> {
-
- /**
- * Called when an observed object has updated its data.
- *
- * @param data
- * the updated data
- */
- void update(final T data);
-
-}
diff --git a/main/src/cgeo/geocaching/utils/ISubject.java b/main/src/cgeo/geocaching/utils/ISubject.java
deleted file mode 100644
index c325db0..0000000
--- a/main/src/cgeo/geocaching/utils/ISubject.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package cgeo.geocaching.utils;
-
-/**
- * Interface for subjects objects. Those can be observed by objects implementing the {@link IObserver} interface.
- *
- * @param <T>
- * the kind of data to observe
- */
-
-public interface ISubject<T> {
-
- /**
- * Add an observer to the observers list.
- * <p/>
- * Observers will be notified with no particular order.
- *
- * @param observer
- * the observer to add
- * @return true if the observer has been added, false if it was present already
- */
- public boolean addObserver(final IObserver<? super T> observer);
-
- /**
- * Delete an observer from the observers list.
- *
- * @param observer
- * the observer to remove
- * @return true if the observer has been removed, false if it was not in the list of observers
- */
- public boolean deleteObserver(final IObserver<? super T> observer);
-
- /**
- * Number of observers currently observing the object.
- *
- * @return the number of observers
- */
- public int sizeObservers();
-
- /**
- * Notify all the observers that new data is available.
- * <p/>
- * The {@link IObserver#update(Object)} method of each observer will be called with no particular order.
- *
- * @param data
- * the updated data
- * @return true if at least one observer was notified, false if there were no observers
- */
- public boolean notifyObservers(final T data);
-
- /**
- * Clear the observers list.
- *
- * @return true if there were observers before calling this method, false if the observers list was empty
- */
- public boolean clearObservers();
-
-}
diff --git a/main/src/cgeo/geocaching/utils/ImageUtils.java b/main/src/cgeo/geocaching/utils/ImageUtils.java
index 73f322c..9f47ead 100644
--- a/main/src/cgeo/geocaching/utils/ImageUtils.java
+++ b/main/src/cgeo/geocaching/utils/ImageUtils.java
@@ -78,7 +78,7 @@ public final class ImageUtils {
* @return BitmapDrawable The scaled image
*/
@NonNull
- public static BitmapDrawable scaleBitmapTo(@NonNull final Bitmap image, final int maxWidth, final int maxHeight) {
+ private static BitmapDrawable scaleBitmapTo(@NonNull final Bitmap image, final int maxWidth, final int maxHeight) {
final CgeoApplication app = CgeoApplication.getInstance();
Bitmap result = image;
int width = image.getWidth();
diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
index 708dff0..0c83076 100644
--- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
+++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.utils;
+import org.eclipse.jdt.annotation.NonNull;
+
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
@@ -42,6 +44,8 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E>
*
* @see HashSet
*/
+ @SuppressWarnings("null")
+ @NonNull
@Override
public Iterator<E> iterator() {
return map.keySet().iterator();
diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
index 76fa0f7..5fa0982 100644
--- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
+++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
@@ -47,10 +47,6 @@ public final class LogTemplateProvider {
this.logEntry = logEntry;
}
- public LogContext(final boolean offline) {
- this(null, null, offline);
- }
-
public LogContext(final Geocache cache, LogEntry logEntry, final boolean offline) {
this.cache = cache;
this.offline = offline;
diff --git a/main/src/cgeo/geocaching/utils/MemorySubject.java b/main/src/cgeo/geocaching/utils/MemorySubject.java
deleted file mode 100644
index c424528..0000000
--- a/main/src/cgeo/geocaching/utils/MemorySubject.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cgeo.geocaching.utils;
-
-/**
- * Synchronized implementation of the {@link ISubject} interface with an added pull interface.
- *
- * @param <T>
- * the kind of data to observe
- */
-public class MemorySubject<T> extends Subject<T> {
-
- /**
- * The latest version of the observed data.
- * <p/>
- * A child class implementation may want to set this field from its constructors, in case early observers request
- * the data before it got a chance to get updated. Otherwise, <code>null</code> will be returned until updated
- * data is available.
- */
- private T memory;
-
- @Override
- public synchronized boolean addObserver(final IObserver<? super T> observer) {
- final boolean added = super.addObserver(observer);
- if (added && memory != null) {
- observer.update(memory);
- }
- return added;
- }
-
- @Override
- public synchronized boolean notifyObservers(final T data) {
- memory = data;
- return super.notifyObservers(data);
- }
-
- /**
- * Get the memorized version of the data.
- *
- * @return the initial data set by the subject (which may be <code>null</code>),
- * or the updated data if it is available
- */
- public synchronized T getMemory() {
- return memory;
- }
-
-}
diff --git a/main/src/cgeo/geocaching/utils/RunnableWithArgument.java b/main/src/cgeo/geocaching/utils/RunnableWithArgument.java
deleted file mode 100644
index 6137efd..0000000
--- a/main/src/cgeo/geocaching/utils/RunnableWithArgument.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package cgeo.geocaching.utils;
-
-public interface RunnableWithArgument<T> {
-
- abstract void run(final T argument);
-
-}
diff --git a/main/src/cgeo/geocaching/utils/Subject.java b/main/src/cgeo/geocaching/utils/Subject.java
deleted file mode 100644
index b1754cc..0000000
--- a/main/src/cgeo/geocaching/utils/Subject.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package cgeo.geocaching.utils;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-/**
- * Synchronized implementation of the {@link ISubject} interface.
- *
- * @param <T>
- * the kind of data to observe
- */
-public class Subject<T> implements ISubject<T> {
-
- /**
- * Collection of observers.
- */
- protected final Set<IObserver<? super T>> observers = new LinkedHashSet<IObserver<? super T>>();
-
- @Override
- public synchronized boolean addObserver(final IObserver<? super T> observer) {
- final boolean added = observers.add(observer);
- if (added && observers.size() == 1) {
- onFirstObserver();
- }
- return added;
- }
-
- @Override
- public synchronized boolean deleteObserver(final IObserver<? super T> observer) {
- final boolean removed = observers.remove(observer);
- if (removed && observers.isEmpty()) {
- onLastObserver();
- }
- return removed;
- }
-
- @Override
- public synchronized boolean notifyObservers(final T arg) {
- final boolean nonEmpty = !observers.isEmpty();
- for (final IObserver<? super T> observer : observers) {
- observer.update(arg);
- }
- return nonEmpty;
- }
-
- @Override
- public synchronized int sizeObservers() {
- return observers.size();
- }
-
- @Override
- public synchronized boolean clearObservers() {
- final boolean nonEmpty = !observers.isEmpty();
- for (final IObserver<? super T> observer : observers) {
- deleteObserver(observer);
- }
- return nonEmpty;
- }
-
- /**
- * Method called when the collection of observers goes from empty to non-empty.
- * <p/>
- * The default implementation does nothing and may be overwritten by child classes.
- */
- protected void onFirstObserver() {
- }
-
- /**
- * Method called when the collection of observers goes from non-empty to empty.
- * <p/>
- * The default implementation does nothing and may be overwritten by child classes.
- */
- protected void onLastObserver() {
- }
-
-}
diff --git a/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java b/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java
index 2368469..7848d1a 100644
--- a/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java
+++ b/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java
@@ -4,6 +4,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
+import java.util.TimeZone;
public class SynchronizedDateFormat {
private final SimpleDateFormat format;
@@ -12,7 +13,17 @@ public class SynchronizedDateFormat {
format = new SimpleDateFormat(pattern, locale);
}
+ public SynchronizedDateFormat(String pattern, TimeZone timeZone, Locale locale) {
+ format = new SimpleDateFormat(pattern, locale);
+ format.setTimeZone(timeZone);
+ }
+
public synchronized Date parse(final String input) throws ParseException {
return format.parse(input);
}
+
+ public synchronized String format(final Date date) {
+ return format.format(date);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/utils/TextUtils.java b/main/src/cgeo/geocaching/utils/TextUtils.java
index efbb2d7..c4e1128 100644
--- a/main/src/cgeo/geocaching/utils/TextUtils.java
+++ b/main/src/cgeo/geocaching/utils/TextUtils.java
@@ -4,7 +4,6 @@
package cgeo.geocaching.utils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
import org.eclipse.jdt.annotation.Nullable;
import java.util.regex.Matcher;
diff --git a/main/thirdparty/android/support/v4/app/FragmentListActivity.java b/main/thirdparty/android/support/v4/app/FragmentListActivity.java
index e3ed42c..fa425ab 100644
--- a/main/thirdparty/android/support/v4/app/FragmentListActivity.java
+++ b/main/thirdparty/android/support/v4/app/FragmentListActivity.java
@@ -16,6 +16,8 @@
package android.support.v4.app;
+import org.eclipse.jdt.annotation.NonNull;
+
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
@@ -215,7 +217,7 @@ public class FragmentListActivity extends FragmentActivity {
*@see Activity#onRestoreInstanceState(Bundle)
*/
@Override
- protected void onRestoreInstanceState(Bundle state) {
+ protected void onRestoreInstanceState(@NonNull Bundle state) {
ensureList();
super.onRestoreInstanceState(state);
}
diff --git a/main/thirdparty/com/viewpagerindicator/TitlePageIndicator.java b/main/thirdparty/com/viewpagerindicator/TitlePageIndicator.java
index 94ac962..0f922c5 100644
--- a/main/thirdparty/com/viewpagerindicator/TitlePageIndicator.java
+++ b/main/thirdparty/com/viewpagerindicator/TitlePageIndicator.java
@@ -19,6 +19,8 @@ package com.viewpagerindicator;
import cgeo.geocaching.R;
+import org.eclipse.jdt.annotation.NonNull;
+
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -445,7 +447,7 @@ public class TitlePageIndicator extends View implements PageIndicator {
}
@Override
- public boolean onTouchEvent(android.view.MotionEvent ev) {
+ public boolean onTouchEvent(@NonNull android.view.MotionEvent ev) {
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
@@ -751,7 +753,7 @@ public class TitlePageIndicator extends View implements PageIndicator {
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
diff --git a/tests/.settings/org.eclipse.jdt.core.prefs b/tests/.settings/org.eclipse.jdt.core.prefs
index 5385520..6ba1bbd 100644
--- a/tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tests/.settings/org.eclipse.jdt.core.prefs
@@ -1,9 +1,10 @@
eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
@@ -11,7 +12,7 @@ org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=ignore
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
@@ -20,13 +21,13 @@ org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
@@ -47,37 +48,39 @@ org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warni
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=warning
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
@@ -90,6 +93,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tests/libs/org.eclipse.jdt.annotation_1.1.0.v20130513-1648.jar b/tests/libs/org.eclipse.jdt.annotation_1.1.0.v20130513-1648.jar
new file mode 100644
index 0000000..daca164
--- /dev/null
+++ b/tests/libs/org.eclipse.jdt.annotation_1.1.0.v20130513-1648.jar
Binary files differ
diff --git a/tests/res/raw/gc3t1xg_gsak.gpx b/tests/res/raw/gc3t1xg_gsak.gpx
new file mode 100644
index 0000000..ebb5ca5
--- /dev/null
+++ b/tests/res/raw/gc3t1xg_gsak.gpx
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<gpx xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+version="1.0" creator="GSAK"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd http://www.gsak.net/xmlv1/6 http://www.gsak.net/xmlv1/6/gsak.xsd"
+xmlns="http://www.topografix.com/GPX/1/0">
+ <desc>Geocache file generated by GSAK (HasChildren)</desc>
+ <author>GSAK</author>
+ <email>support@gsak.net</email>
+ <time>2014-01-26T19:54:13Z</time>
+ <keywords>cache, geocache, groundspeak</keywords>
+ <bounds minlat="50.1075" minlon="8.65885" maxlat="50.1075" maxlon="8.65885"/>
+ <wpt lat="50.1075" lon="8.65885">
+ <time>2012-08-13T08:00:00Z</time>
+ <name>GC3T1XG</name>
+ <desc>Help by TheGreenTool (3/1)</desc>
+ <url>http://www.geocaching.com/seek/cache_details.aspx?guid=d09416d5-dba9-4347-86a6-12f7b5ef2fff</url>
+ <urlname>Help by TheGreenTool</urlname>
+ <sym>Geocache</sym>
+ <type>Geocache|Traditional Cache</type>
+ <gsak:wptExtension xmlns:gsak="http://www.gsak.net/xmlv1/6">
+ <gsak:UserFlag>true</gsak:UserFlag>
+ <gsak:Lock>false</gsak:Lock>
+ <gsak:DNF>false</gsak:DNF>
+ <gsak:Watch>false</gsak:Watch>
+ <gsak:UserData></gsak:UserData>
+ <gsak:FirstToFind>false</gsak:FirstToFind>
+ <gsak:User2></gsak:User2>
+ <gsak:User3></gsak:User3>
+ <gsak:User4></gsak:User4>
+ <gsak:County></gsak:County>
+ <gsak:UserSort>0</gsak:UserSort>
+ <gsak:SmartName>Help</gsak:SmartName>
+ <gsak:LastGpxDate>2014-01-26</gsak:LastGpxDate>
+ <gsak:Code>GC3T1XG</gsak:Code>
+ <gsak:Resolution></gsak:Resolution>
+ <gsak:IsPremium>true</gsak:IsPremium>
+ <gsak:FavPoints>258</gsak:FavPoints>
+ <gsak:GcNote>Personal Note Test</gsak:GcNote>
+ <gsak:Guid>d09416d5-dba9-4347-86a6-12f7b5ef2fff</gsak:Guid>
+ <gsak:CacheImages>
+ </gsak:CacheImages>
+ <gsak:LogImages>
+ </gsak:LogImages>
+ <gsak:CustomData>
+Custom_Start:cCode:Custom_Data:GC3T1XG:Custom_End
+
+ </gsak:CustomData>
+ </gsak:wptExtension>
+ <groundspeak:cache id="3106063" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0/1">
+ <groundspeak:name>Help</groundspeak:name>
+ <groundspeak:placed_by>TheGreenTool</groundspeak:placed_by>
+ <groundspeak:owner id="2072379">TheGreenTool</groundspeak:owner>
+ <groundspeak:type>Traditional Cache</groundspeak:type>
+ <groundspeak:container>Small</groundspeak:container>
+ <groundspeak:attributes>
+ <groundspeak:attribute id="1" inc="1">Dogs</groundspeak:attribute>
+ <groundspeak:attribute id="7" inc="1">Takes less than an hour</groundspeak:attribute>
+ <groundspeak:attribute id="13" inc="1">Available at all times</groundspeak:attribute>
+ <groundspeak:attribute id="15" inc="1">Available during winter</groundspeak:attribute>
+ <groundspeak:attribute id="24" inc="1">Wheelchair accessible</groundspeak:attribute>
+ <groundspeak:attribute id="32" inc="1">Bicycles</groundspeak:attribute>
+ <groundspeak:attribute id="33" inc="1">Motorcycles</groundspeak:attribute>
+ <groundspeak:attribute id="34" inc="1">Quads</groundspeak:attribute>
+ <groundspeak:attribute id="35" inc="1">Off-road vehicles</groundspeak:attribute>
+ <groundspeak:attribute id="47" inc="1">Field Puzzle</groundspeak:attribute>
+ <groundspeak:attribute id="63" inc="1">Tourist Friendly</groundspeak:attribute>
+ </groundspeak:attributes>
+ <groundspeak:difficulty>3</groundspeak:difficulty>
+ <groundspeak:terrain>1</groundspeak:terrain>
+ <groundspeak:country>Germany</groundspeak:country>
+ <groundspeak:state>Hessen</groundspeak:state>
+ <groundspeak:short_description html="True"> </groundspeak:short_description>
+ <groundspeak:long_description html="True">Ein Cache für Leute, die keine langen Listingtexte lesen wollen.&lt;br /&gt;
+Dieses Listing beinhaltet alle Informationen, die ihr benötigt.&lt;br /&gt;
+Die Notrufsäule hat absolut NICHTS mit dem Cache zu tun. Lasst sie bitte in Ruhe!&lt;br /&gt;
+&lt;br /&gt;
+A cache for people who don't like reading long listing texts.&lt;br /&gt;
+This listing contains all information you need.&lt;br /&gt;
+Please DO NOT use the emergency telephone! It has absolutely NOTHING to do with the cache.&lt;br /&gt;
+&lt;br /&gt;</groundspeak:long_description>
+ <groundspeak:encoded_hints></groundspeak:encoded_hints>
+ <groundspeak:logs>
+ <groundspeak:log id="378435354">
+ <groundspeak:date>2014-01-24T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="4685592">Holleradhiho</groundspeak:finder>
+ <groundspeak:text encoded="False">Nachdem ich im letzten Jahr den Code nicht rausbekommen habe hat mir meine Freundin den entscheidenden Tipp gegeben. Heute mit den richtigen vorbei gegangen und schnell eingetragen. Vielen Dank für den Cache. Holleradhiho</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378281233">
+ <groundspeak:date>2014-01-22T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="6585656">leontheleon</groundspeak:finder>
+ <groundspeak:text encoded="False">In Francfurt for a business trip, I quickly loaded in the GPS a few caches around my hotel and the station,
+That s awesome to see how much cache there are in Germany.
+
+After the failure yesterday, i have this in my mind....
+
+and suddenly after dinner,
+i tried to found information translating the others log... but I didn't need this HELP,
+before I start to translate it appears clear and loud : I got the key !!!
+
+Wait tomorrow to try this,
+hopefully the taxi droped me 30 min beore my train leave,
+i go
+try
+and open it !
+
+Thanks for this good idea,
+I was so sorry if I can t found this one before to leave !
+
+Come with me little geocoin, you will visite France.
+
+
+362 ème cache trouvée par leontheleon
+Merci à TheGreenTool pour cette cache
+
+362 geocache found by LeontheLeon
+Thanks to TheGreenTool for this cache.
+
+J'ai donné 4 à cette cache grâce à [url=http://www.gcvote.com]GCVote[/url]</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378261404">
+ <groundspeak:date>2014-01-22T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2969623">bravo1999</groundspeak:finder>
+ <groundspeak:text encoded="False">#2881
+Auf der Dienstreise einen Boxenstopp am Frankfurter Hbf eingelegt und die Zwischenzeit natürlich sinnvoll genutzt.
+Unweit des Hbf diesen Cache erspäht und nach kurzer Andacht dann auch geloggt.
+Klasse Ding, tolle Umsetzung - hat mir sehr gut gefallen - ich liebe Stadtcache, trotz oder vielleicht wg der Muggelei.
+Dafür gibt´s auch von mir einen FavPkt und
+TFTC sagt bravo1999</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378231850">
+ <groundspeak:date>2014-01-22T16:44:49Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="4950075">DovasTeam</groundspeak:finder>
+ <groundspeak:text encoded="False">Sehr gut.
+MfG aus Griechenland.
+Dfdc</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378194961">
+ <groundspeak:date>2014-01-22T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="4005684">Klaye</groundspeak:finder>
+ <groundspeak:text encoded="False">TFTC! #815
+Quickly located, but it took me another while to log. TBs exchanged. Favourite point.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378280964">
+ <groundspeak:date>2014-01-21T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Didn't find it</groundspeak:type>
+ <groundspeak:finder id="6585656">leontheleon</groundspeak:finder>
+ <groundspeak:text encoded="False">In Francfurt for a business trip, I quickly loaded in the GPS a few caches around my hotel and the station,
+That s awesome to see how much cache there are in Germany.
+
+may be a bit of time during my trip to try my first German cache...
+
+I arrived at 5 pm and before looking for a taxi, I will go for a few ones
+
+______________________________________
+After the faiulure on "Cafe Metropolitan", I quickly tried this one,
+
+After a quick inspection, I see the difficulty level and decided to go direct to the next one because not too much time and this is dark now.
+
+On return walk, I check and see the attributes, quickly see if I can find
+
+I can imagine what could be the container, but not possible to find the solution...
+
+Go for hotel... my mind is boiling to be so close
+
+may be on return tomorrow if I have 15 min free</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378195032">
+ <groundspeak:date>2014-01-21T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2106220">LouisCyphre</groundspeak:finder>
+ <groundspeak:text encoded="False">Nach einem kleinen Nachtcache in der Nähe sind muffinstarbucks und ich auch noch mal "schnell" hier vorbei. Am schwierigsten war allerdings das Parkplatz finden und Einparken[:D].
+An der Dose hatte ich dann ein kleines Deja-Vu, genau die Dose hatte ich vom gleichen Owner schon vor ein paar Wochen an einer anderen Stelle gemacht[8D].
+TFTC
+#8552</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378187240">
+ <groundspeak:date>2014-01-21T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1624740">muffinstarbucks</groundspeak:finder>
+ <groundspeak:text encoded="False">[:D]
+
+Ein wirklich cooles Versteck. Nach unserem NC kamen LouisCyphre und ich auch noch hier vorbei. Das Cachemobil am Strassenrand abzustellen war genauso schwierig, wie das Auffinden der Dose. Beides
+klappte zum Glück am Ende aber gut.[^]
+
+Einen Favoritenpunkt hierfür.
+
+TFTC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="377942548">
+ <groundspeak:date>2014-01-20T16:29:02Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1366147">FlashCool</groundspeak:finder>
+ <groundspeak:text encoded="False">Schick, schick. Clevere Versteckidee. Heute im 2. Anlauf gut und im Schutze der Dunkelheit finden und heben können.
+
+Danke fürs Aushecken und Verstecken.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="377136980">
+ <groundspeak:date>2014-01-17T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="2849267">dl1ely</groundspeak:finder>
+ <groundspeak:text encoded="False">Keine Ahnung, wo die Dose sich verbergen soll, so ganz ohne Hint. Nachdem 2 Polizisten begannen, mir interessiert beim Rumlungern zuzusehen, trat ich lieber den Rückweg zum Bahnhof an. Vielleicht habe ich beim nächsten Umstieg am HBf mehr Glück.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376948874">
+ <groundspeak:date>2014-01-15T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="613426">Kassabeckabua</groundspeak:finder>
+ <groundspeak:text encoded="False">Nach einem Abendessen und Zwischenstopp heute im zweiten Anlauf. TFTC KBB</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376946408">
+ <groundspeak:date>2014-01-15T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2040005">Bembelboy</groundspeak:finder>
+ <groundspeak:text encoded="False">Ich war ja schon mal bei der Dose als sie noch am vorigen Platz versteckt war. Seinerzeit fehlte mir die Idee und die Muggeldichte war einfach zu hoch. Zwischenzeitlich hatte ich das neue Versteck auch ausfindig gemacht, doch die Muggeldichte war wieder zu hoch und es war hell. Heute Abend im Dunkeln konnte sie sich meinem Zugriff dann nicht mehr entziehen. Ich hatte ca. 2 Stunden vorher in Hamburg eine ahnliche Dose zu öffnen gehabt. Lustig.
+
+This entry was edited by Bembelboy on Friday, 17 January 2014 at 19:54:02 UTC.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376892811">
+ <groundspeak:date>2014-01-14T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="7675187">KuWu80</groundspeak:finder>
+ <groundspeak:text encoded="False">Gesucht, gefunden und geloggt. :-)
+
+TFTC !!!!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376793802">
+ <groundspeak:date>2014-01-14T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="6306622">Kaiserwurst86</groundspeak:finder>
+ <groundspeak:text encoded="False">TB abgelegt. Da es aber nur eine Kopie ist, kann ich ihn hier online nicht ablegen.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376766889">
+ <groundspeak:date>2014-01-14T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="7169608">Tom Ato</groundspeak:finder>
+ <groundspeak:text encoded="False">Nach einer kleinen Hilfestellung (DANKE DAFÜR) im zweiten Anlauf gut gelöst.
+Sehr schöne Idee, dafür von mir ein FP!!!
+TB: out
+T4TC!!!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376741584">
+ <groundspeak:date>2014-01-14T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="5385835">lietuvis28</groundspeak:finder>
+ <groundspeak:text encoded="False">Vor dem dienstlichen Termin noch schnell diese "Dose" gefunden, geöffnet und geloggt.
+
+Ich gebe zu, es bracuht auch bei mir einen 2. Anlauf. Bei meiner letzten Dienstreise nach Frankfurt hatte ich noch die Notrufsäule vor Augen. Diese wollte ich aber nicht ausprobieren.
+Daher ein wenig nachgedacht, nochmal geschaut, etwas "neues" entdeckt und schon lag das Logbuch in meinen Händen.
+
+Für die Idee lasse ich gerne ein Schleifchen hier.
+
+TFTC!
+
+Gruß aus Windeck</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="378209899">
+ <groundspeak:date>2014-01-12T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2057810">Nerre</groundspeak:finder>
+ <groundspeak:text encoded="False">Mit TurtleSA und Neonfly ging auf große Tour Richtung Frankfurt. Danke für's Verstecken!
+
+Zum Abschluß der Tour ging es nochmal durch die Innenstadt.
+Ein toller Cache! Hier suchten wir lange weil wir es erst übersahen, dann konnten wir aber direkt loggen. Super! Dafür gibt es einen FP. :)</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="377753263">
+ <groundspeak:date>2014-01-12T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2098778">neonfly</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute bei gutem Wetter eine Tagestour zusammen mit TurtleSA und Nerre nach Frankfurt unternommen.
+Auf dem Weg dorthin haben wir bei Darmstadt auch noch ein paar Dosen geloggt.
+
+Im wesentlichen waren wir östlich in direkter Flugphafennähe unterwegs, sowie anschliessend in Niederrad und FFM Innenstadt.
+
+Dies ist ein Sammellog für alle Caches, manche bekommen auch ein Schleifchen. :=)
+
+Bei der Europatour sind wir nicht alle angegangen und bei einem Cache dieser Serie (Stockholm) hat Nerre ein Ersatzlogbuch gebastelt, da anscheinend die Muggel zugeschlagen hatten. An der richtigen Laterne waren wir.
+
+Der Portier am Café Metropolitan hat uns durch subtile Hinweise weiter geholfen den Kleinen doch noch zu finden. :)
+War eine nette Begegnung. :)
+
+Ansonsten hat sich Frankfurt ganz schön gemacht in den letzten Jahren (war lange nicht mehr dort gewesen).
+
+Grüße an alle Owner sowie unsere spontanen Begleiter im Wald südlich Niederrad und natürlich auch an Nerre und TurtleSA.
+War eine schöne Runde. :)</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376878775">
+ <groundspeak:date>2014-01-12T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2518165">friendscout</groundspeak:finder>
+ <groundspeak:text encoded="False">Schönes Versteck mit Finger-Abzähl-Übung, dafür einen FP. Merci!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="376250428">
+ <groundspeak:date>2014-01-12T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="6167340">eifelmuggel</groundspeak:finder>
+ <groundspeak:text encoded="False">Schön gemacht. Die Dose hatten wir sofort gefunden, aber wie auf bekommen!? Ich kann bestätigen, dass im Listing alles steht, was man braucht. Genau genommen steht da noch etwas zu viel ;-)!
+
+Danke!</groundspeak:text>
+ </groundspeak:log>
+ </groundspeak:logs>
+ <groundspeak:travelbugs>
+ </groundspeak:travelbugs>
+</groundspeak:cache>
+</wpt>
+</gpx>
diff --git a/tests/src/cgeo/geocaching/CgeoApplicationTest.java b/tests/src/cgeo/geocaching/CgeoApplicationTest.java
index b9c03a4..af6bcaa 100644
--- a/tests/src/cgeo/geocaching/CgeoApplicationTest.java
+++ b/tests/src/cgeo/geocaching/CgeoApplicationTest.java
@@ -114,7 +114,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
public static Geocache testSearchByGeocode(final String geocode) {
final SearchResult search = Geocache.searchByGeocode(geocode, null, 0, true, null);
assertNotNull(search);
- if (Settings.isPremiumMember() || search.getError() == null) {
+ if (Settings.isGCPremiumMember() || search.getError() == null) {
assertEquals(1, search.getGeocodes().size());
assertTrue(search.getGeocodes().contains(geocode));
return DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
@@ -140,14 +140,14 @@ public class CgeoApplicationTest extends CGeoTestCase {
*/
private static void withMockedLoginDo(final Runnable runnable) {
final ImmutablePair<String, String> login = Settings.getGcCredentials();
- final String memberStatus = Settings.getMemberStatus();
+ final String memberStatus = Settings.getGCMemberStatus();
try {
runnable.run();
} finally {
// restore user and password
TestSettings.setLogin(login.left, login.right);
- Settings.setMemberStatus(memberStatus);
+ Settings.setGCMemberStatus(memberStatus);
GCLogin.getInstance().login();
}
}
@@ -171,6 +171,8 @@ public class CgeoApplicationTest extends CGeoTestCase {
assertTrue(search.getGeocodes().contains(cache.getGeocode()));
final Geocache searchedCache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
// coords must be null if the user is not logged in
+ assertNotNull(searchedCache);
+ assert (searchedCache != null); // eclipse bug
assertNull(searchedCache.getCoords());
// premium cache. Not visible to guests
@@ -237,10 +239,10 @@ public class CgeoApplicationTest extends CGeoTestCase {
@Override
public void run() {
- final SearchResult search = GCParser.searchByCoords(new Geopoint("N 52° 24.972 E 009° 35.647"), CacheType.MYSTERY, false, null);
+ final SearchResult search = GCParser.searchByCoords(new Geopoint("N 50° 06.654 E 008° 39.777"), CacheType.MYSTERY, false, null);
assertNotNull(search);
assertTrue(20 <= search.getGeocodes().size());
- assertTrue(search.getGeocodes().contains("GC1RMM2"));
+ assertTrue(search.getGeocodes().contains("GC1HBMY"));
}
});
}
@@ -305,25 +307,25 @@ public class CgeoApplicationTest extends CGeoTestCase {
// check coords for DETAILED
Settings.setLiveMapStrategy(Strategy.DETAILED);
- SearchResult search = ConnectorFactory.searchByViewport(viewport, tokens);
+ SearchResult search = ConnectorFactory.searchByViewport(viewport, tokens).toBlockingObservable().single();
assertNotNull(search);
assertTrue(search.getGeocodes().contains(mockedCache.getGeocode()));
Geocache parsedCache = DataStore.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB);
- assertEquals(Settings.isPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords()));
- assertEquals(Settings.isPremiumMember(), parsedCache.isReliableLatLon());
+ assertEquals(Settings.isGCPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords()));
+ assertEquals(Settings.isGCPremiumMember(), parsedCache.isReliableLatLon());
// check update after switch strategy to FAST
Settings.setLiveMapStrategy(Strategy.FAST);
Tile.Cache.removeFromTileCache(mockedCache);
- search = ConnectorFactory.searchByViewport(viewport, tokens);
+ search = ConnectorFactory.searchByViewport(viewport, tokens).toBlockingObservable().single();
assertNotNull(search);
assertTrue(search.getGeocodes().contains(mockedCache.getGeocode()));
parsedCache = DataStore.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB);
- assertEquals(Settings.isPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords()));
- assertEquals(Settings.isPremiumMember(), parsedCache.isReliableLatLon());
+ assertEquals(Settings.isGCPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords()));
+ assertEquals(Settings.isGCPremiumMember(), parsedCache.isReliableLatLon());
} finally {
// restore user settings
@@ -356,7 +358,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
Settings.setCacheType(CacheType.ALL);
Viewport viewport = new Viewport(cache, 0.003, 0.003);
- SearchResult search = ConnectorFactory.searchByViewport(viewport, INVALID_TOKEN);
+ SearchResult search = ConnectorFactory.searchByViewport(viewport, INVALID_TOKEN).toBlockingObservable().single();
assertNotNull(search);
assertTrue(search.getGeocodes().contains(cache.getGeocode()));
@@ -364,7 +366,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
final Geocache cacheFromViewport = DataStore.loadCache(cache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB);
Log.d("cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords expected = " + cache.getCoords());
Log.d("cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords actual = " + cacheFromViewport.getCoords());
- assertFalse(cache.getCoords().isEqualTo(cacheFromViewport.getCoords(), 1e-3));
+ assertFalse(cache.getCoords().distanceTo(cacheFromViewport.getCoords()) <= 1e-3);
// depending on the chosen strategy the coords can be reliable or not
assertEquals(testStrategy == Strategy.DETAILED, cacheFromViewport.isReliableLatLon());
@@ -373,11 +375,11 @@ public class CgeoApplicationTest extends CGeoTestCase {
deleteCacheFromDBAndLogout(cache.getGeocode());
viewport = new Viewport(cache, 0.003, 0.003);
- search = ConnectorFactory.searchByViewport(viewport, INVALID_TOKEN);
+ search = ConnectorFactory.searchByViewport(viewport, INVALID_TOKEN).toBlockingObservable().single();
assertNotNull(search);
- // depending on the chosen strategy the cache is part of the search or not
- assertEquals(testStrategy == Strategy.DETAILED, search.getGeocodes().contains(cache.getGeocode()));
+ // In the meantime, premium-member caches are also shown on map when not logged in
+ assertTrue(search.getGeocodes().contains(cache.getGeocode()));
} finally {
Settings.setLiveMapStrategy(strategy);
@@ -423,7 +425,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
GCLogin.getInstance().logout();
// Modify login data to avoid an automatic login again
TestSettings.setLogin("c:geo", "c:geo");
- Settings.setMemberStatus("Basic member");
+ Settings.setGCMemberStatus("Basic member");
}
}
diff --git a/tests/src/cgeo/geocaching/GeocacheTest.java b/tests/src/cgeo/geocaching/GeocacheTest.java
index cdca9b7..b49048b 100644
--- a/tests/src/cgeo/geocaching/GeocacheTest.java
+++ b/tests/src/cgeo/geocaching/GeocacheTest.java
@@ -249,6 +249,14 @@ public class GeocacheTest extends CGeoTestCase {
assertTime("from 11 to 13 " + timeHours, 11, 00);
}
+ public static void testGuessEventTimeShortDescription() {
+ Geocache cache = new Geocache();
+ cache.setType(CacheType.EVENT);
+ cache.setDescription(StringUtils.EMPTY);
+ cache.setShortDescription("text 14:20 text");
+ assertEquals(String.valueOf(14 * 60 + 20), cache.guessEventTimeMinutes());
+ }
+
private static void assertTime(final String description, final int hours, final int minutes) {
final Geocache cache = new Geocache();
cache.setDescription(description);
diff --git a/tests/src/cgeo/geocaching/SettingsTest.java b/tests/src/cgeo/geocaching/SettingsTest.java
index c58db08..90a0209 100644
--- a/tests/src/cgeo/geocaching/SettingsTest.java
+++ b/tests/src/cgeo/geocaching/SettingsTest.java
@@ -27,7 +27,7 @@ public class SettingsTest extends ActivityInstrumentationTestCase2<MainActivity>
public static void testSettings() {
// unfortunately, several other tests depend on being a premium member and will fail if run by a basic member
- assertEquals(GCConstants.MEMBER_STATUS_PM, Settings.getMemberStatus());
+ assertEquals(GCConstants.MEMBER_STATUS_PM, Settings.getGCMemberStatus());
}
public static void testDeviceHasNormalLogin() {
diff --git a/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java b/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java
index e41e316..725f718 100644
--- a/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java
+++ b/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java
@@ -63,8 +63,32 @@ public class ConnectorFactoryTest extends AbstractResourceInstrumentationTestCas
public static void testGetGeocodeFromUrl() {
assertEquals("GC34PLO", ConnectorFactory.getGeocodeFromURL("http://coord.info/GC34PLO"));
+ assertEquals("GC34PLO", ConnectorFactory.getGeocodeFromURL("http://www.coord.info/GC34PLO"));
assertEquals("OX1234", ConnectorFactory.getGeocodeFromURL("http://www.opencaching.com/#!geocache/OX1234"));
+
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://coord.info/GC12ABC"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://www.coord.info/GC12ABC"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://www.geocaching.com/geocache/GC12ABC_die-muhlen-im-schondratal-muhle-munchau"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://geocaching.com/geocache/GC12ABC_die-muhlen-im-schondratal-muhle-munchau"));
+
+ // trackable URLs
+ assertNull(GCConnector.getInstance().getGeocodeFromUrl("http://coord.info/TB1234"));
+ assertNull(GCConnector.getInstance().getGeocodeFromUrl("http://www.coord.info/TB1234"));
+
// make sure that a mixture of different connector and geocode is recognized as invalid
assertNull(ConnectorFactory.getGeocodeFromURL("http://www.opencaching.com/#!geocache/" + "GC12345"));
}
+
+ public static void testGetTrackableFromURL() throws Exception {
+ assertEquals("GK78FA", ConnectorFactory.getTrackableFromURL("http://www.geokrety.org/konkret.php?id=30970"));
+ assertEquals("GK78FA", ConnectorFactory.getTrackableFromURL("http://geokrety.org/konkret.php?id=30970"));
+ assertEquals("TB1234", ConnectorFactory.getTrackableFromURL("http://coord.info/TB1234"));
+ assertEquals("TB1234", ConnectorFactory.getTrackableFromURL("http://www.coord.info/TB1234"));
+ assertEquals("TB1234", ConnectorFactory.getTrackableFromURL("http://geocaching.com/track/details.aspx?tracker=TB1234"));
+ assertEquals("TB1234", ConnectorFactory.getTrackableFromURL("http://www.geocaching.com/track/details.aspx?tracker=TB1234"));
+
+ // cache URLs
+ assertNull(ConnectorFactory.getTrackableFromURL("http://coord.info/GC1234"));
+ assertNull(ConnectorFactory.getTrackableFromURL("http://www.coord.info/GC1234"));
+ }
}
diff --git a/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java b/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
index a5b9a44..47c3f6f 100644
--- a/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
+++ b/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
@@ -26,7 +26,7 @@ public class GCConnectorTest extends AbstractResourceInstrumentationTestCase {
{
final Viewport viewport = new Viewport(new Geopoint("N 52° 25.369 E 9° 35.499"), new Geopoint("N 52° 25.600 E 9° 36.200"));
- final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport, tokens);
+ final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport, tokens).toBlockingObservable().single();
assertNotNull(searchResult);
assertFalse(searchResult.isEmpty());
assertTrue(searchResult.getGeocodes().contains("GC4ER5H"));
@@ -35,7 +35,7 @@ public class GCConnectorTest extends AbstractResourceInstrumentationTestCase {
{
final Viewport viewport = new Viewport(new Geopoint("N 52° 24.000 E 9° 34.500"), new Geopoint("N 52° 26.000 E 9° 38.500"));
- final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport, tokens);
+ final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport, tokens).toBlockingObservable().single();
assertNotNull(searchResult);
assertTrue(searchResult.getGeocodes().contains("GC4ER5H"));
}
@@ -88,5 +88,11 @@ public class GCConnectorTest extends AbstractResourceInstrumentationTestCase {
public static void testGetGeocodeFromUrl() {
assertNull(GCConnector.getInstance().getGeocodeFromUrl("some string"));
assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://coord.info/GC12ABC"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://www.coord.info/GC12ABC"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://www.geocaching.com/geocache/GC12ABC_die-muhlen-im-schondratal-muhle-munchau"));
+ assertEquals("GC12ABC", GCConnector.getInstance().getGeocodeFromUrl("http://geocaching.com/geocache/GC12ABC_die-muhlen-im-schondratal-muhle-munchau"));
+
+ assertNull(GCConnector.getInstance().getGeocodeFromUrl("http://coord.info/TB1234"));
+ assertNull(GCConnector.getInstance().getGeocodeFromUrl("http://www.coord.info/TB1234"));
}
}
diff --git a/tests/src/cgeo/geocaching/connector/gc/GCParserTest.java b/tests/src/cgeo/geocaching/connector/gc/GCParserTest.java
index 43b6d01..1509563 100644
--- a/tests/src/cgeo/geocaching/connector/gc/GCParserTest.java
+++ b/tests/src/cgeo/geocaching/connector/gc/GCParserTest.java
@@ -56,6 +56,8 @@ public class GCParserTest extends AbstractResourceInstrumentationTestCase {
assertNotNull(result);
assertEquals(1, result.getCount());
final Geocache cache = result.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
+ assertNotNull(cache);
+ assert (cache != null); // eclipse bug
assertEquals(cacheName, cache.getName());
}
@@ -158,6 +160,8 @@ public class GCParserTest extends AbstractResourceInstrumentationTestCase {
cache.drop(new Handler());
final String page = GCParser.requestHtmlPage(cache.getGeocode(), null, "n", "0");
final Geocache cache2 = GCParser.parseCacheFromText(page, null).getFirstCacheFromResult(LoadFlags.LOAD_CACHE_ONLY);
+ assertNotNull(cache2);
+ assert (cache2 != null); // eclipse bug
assertTrue(cache2.hasUserModifiedCoords());
assertEquals(new Geopoint("N51 21.544", "E07 02.566"), cache2.getCoords());
// delete coordinates
@@ -165,6 +169,8 @@ public class GCParserTest extends AbstractResourceInstrumentationTestCase {
cache2.drop(new Handler());
final String page2 = GCParser.requestHtmlPage(cache.getGeocode(), null, "n", "0");
final Geocache cache3 = GCParser.parseCacheFromText(page2, null).getFirstCacheFromResult(LoadFlags.LOAD_CACHE_ONLY);
+ assertNotNull(cache3);
+ assert (cache3 != null); // eclipse bug
assertFalse(cache3.hasUserModifiedCoords());
}
@@ -172,9 +178,10 @@ public class GCParserTest extends AbstractResourceInstrumentationTestCase {
cache.setPersonalNote(note);
cache.setWaypoints(new ArrayList<Waypoint>(), false);
cache.parseWaypointsFromNote();
- assertEquals(expected.length, cache.getWaypoints().size());
+ final List<Waypoint> waypoints = cache.getWaypoints();
+ assertEquals(expected.length, waypoints.size());
for (int i = 0; i < expected.length; i++) {
- assertTrue(expected[i].equals(cache.getWaypoint(i).getCoords()));
+ assertTrue(expected[i].equals(waypoints.get(i).getCoords()));
}
}
diff --git a/tests/src/cgeo/geocaching/connector/trackable/GeokretyConnectorTest.java b/tests/src/cgeo/geocaching/connector/trackable/GeokretyConnectorTest.java
index f08fb6b..d3633cb 100644
--- a/tests/src/cgeo/geocaching/connector/trackable/GeokretyConnectorTest.java
+++ b/tests/src/cgeo/geocaching/connector/trackable/GeokretyConnectorTest.java
@@ -11,4 +11,17 @@ public class GeokretyConnectorTest extends TestCase {
assertFalse(new GeokretyConnector().canHandleTrackable("UNKNOWN"));
}
+ public static void testGetTrackableCodeFromUrl() throws Exception {
+ assertEquals("GK78FA", new GeokretyConnector().getTrackableCodeFromUrl("http://www.geokrety.org/konkret.php?id=30970"));
+ assertEquals("GK78FA", new GeokretyConnector().getTrackableCodeFromUrl("http://geokrety.org/konkret.php?id=30970"));
+ }
+
+ public static void testGeocode() throws Exception {
+ assertEquals("GK97C1", GeokretyConnector.geocode(38849));
+ }
+
+ public static void testGetId() throws Exception {
+ assertEquals(38849, GeokretyConnector.getId("GK97C1"));
+ }
+
}
diff --git a/tests/src/cgeo/geocaching/connector/trackable/TravelBugConnectorTest.java b/tests/src/cgeo/geocaching/connector/trackable/TravelBugConnectorTest.java
index ef2821d..7e85b71 100644
--- a/tests/src/cgeo/geocaching/connector/trackable/TravelBugConnectorTest.java
+++ b/tests/src/cgeo/geocaching/connector/trackable/TravelBugConnectorTest.java
@@ -38,4 +38,15 @@ public class TravelBugConnectorTest extends TestCase {
private static TravelBugConnector getConnector() {
return TravelBugConnector.getInstance();
}
+
+ public static void testGetTrackableCodeFromUrl() throws Exception {
+ assertEquals("TB1234", TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://coord.info/TB1234"));
+ assertEquals("TB1234", TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://www.coord.info/TB1234"));
+ assertEquals("TB1234", TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://geocaching.com/track/details.aspx?tracker=TB1234"));
+ assertEquals("TB1234", TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://www.geocaching.com/track/details.aspx?tracker=TB1234"));
+
+ // do not match coord.info URLs of caches
+ assertNull(TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://coord.info/GC1234"));
+ assertNull(TravelBugConnector.getInstance().getTrackableCodeFromUrl("http://www.coord.info/GC1234"));
+ }
}
diff --git a/tests/src/cgeo/geocaching/enumerations/CacheAttributeTest.java b/tests/src/cgeo/geocaching/enumerations/CacheAttributeTest.java
index 54db279..d126c0b 100644
--- a/tests/src/cgeo/geocaching/enumerations/CacheAttributeTest.java
+++ b/tests/src/cgeo/geocaching/enumerations/CacheAttributeTest.java
@@ -25,7 +25,7 @@ public class CacheAttributeTest extends AndroidTestCase {
public static void testGetL10n() {
final CacheAttribute attribute = CacheAttribute.HIKING;
- // This test is language dependend. It does not make sense to test it
+ // This test is language dependent. It does not make sense to test it
// with every attribute. We just want to know if getL10n works
// correctly
assertFalse("_yes and _no must not have the same translation",
@@ -37,7 +37,6 @@ public class CacheAttributeTest extends AndroidTestCase {
assertTrue("Test cannot be run with this attribute", attribute.gcid >= 0);
assertTrue("Test cannot be run with this attribute", attribute.ocacode >= 0);
assertSame(CacheAttribute.getByRawName(attribute.rawName), attribute);
- assertSame(CacheAttribute.getByGcId(attribute.gcid), attribute);
assertSame(CacheAttribute.getByOcACode(attribute.ocacode), attribute);
}
diff --git a/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java b/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java
index 2f11dfc..26a1953 100644
--- a/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java
+++ b/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java
@@ -30,8 +30,6 @@ public class CacheSizeTest extends AndroidTestCase {
public static void testGetByIdNumeric() {
assertEquals(CacheSize.REGULAR, CacheSize.getById("3"));
- assertEquals(CacheSize.UNKNOWN, CacheSize.getById("0"));
- assertEquals(CacheSize.UNKNOWN, CacheSize.getById("9"));
assertEquals(CacheSize.UNKNOWN, CacheSize.getById("-1"));
}
}
diff --git a/tests/src/cgeo/geocaching/enumerations/LogTypeTest.java b/tests/src/cgeo/geocaching/enumerations/LogTypeTest.java
index 81ca33b..47879a0 100644
--- a/tests/src/cgeo/geocaching/enumerations/LogTypeTest.java
+++ b/tests/src/cgeo/geocaching/enumerations/LogTypeTest.java
@@ -17,8 +17,7 @@ public class LogTypeTest extends AndroidTestCase {
}
public static void testGetByType() {
- assertEquals(LogType.UNKNOWN, LogType.getByIconName(""));
- assertEquals(LogType.UNKNOWN, LogType.getByIconName(null));
+ assertEquals(LogType.UNKNOWN, LogType.getByType("obviously unknown type"));
assertEquals(LogType.GRABBED_IT, LogType.getByType("grabbed it"));
assertEquals(LogType.GRABBED_IT, LogType.getByType(" gRAbbed IT "));
}
diff --git a/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java b/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java
index 667eefb..d6b7d33 100644
--- a/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java
+++ b/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java
@@ -1,11 +1,15 @@
package cgeo.geocaching.enumerations;
+import org.apache.commons.lang3.StringUtils;
+
import android.test.AndroidTestCase;
public class LogTypeTrackableTest extends AndroidTestCase {
public static void testFindById() {
- assertEquals(LogTypeTrackable.DO_NOTHING, LogTypeTrackable.findById(12345));
+ for (LogTypeTrackable logTypeTrackable : LogTypeTrackable.values()) {
+ assertTrue(StringUtils.isNotEmpty(logTypeTrackable.getLabel()));
+ }
}
}
diff --git a/tests/src/cgeo/geocaching/export/ExportTest.java b/tests/src/cgeo/geocaching/export/ExportTest.java
index b8f1ffd..b03c9bb 100644
--- a/tests/src/cgeo/geocaching/export/ExportTest.java
+++ b/tests/src/cgeo/geocaching/export/ExportTest.java
@@ -20,9 +20,9 @@ public class ExportTest extends CGeoTestCase {
final Geocache cache = new Geocache();
cache.setGeocode("GCX1234");
final LogEntry log = new LogEntry(1353244820000L, LogType.FOUND_IT, "Hidden in a tree");
- final StringBuilder logStr = new StringBuilder();
- FieldnoteExport.appendFieldNote(logStr, cache, log);
- assertEquals("Non matching export " + logStr.toString(), "GCX1234,2012-11-18T13:20:20Z,Found it,\"Hidden in a tree\"\n", logStr.toString());
+ FieldNotes fieldNotes = new FieldNotes();
+ fieldNotes.add(cache, log);
+ assertEquals("Non matching export " + fieldNotes.getContent(), "GCX1234,2012-11-18T13:20:20Z,Found it,\"Hidden in a tree\"\n", fieldNotes.getContent());
}
public static void testGpxExportSmilies() throws InterruptedException, ExecutionException {
diff --git a/tests/src/cgeo/geocaching/files/GPXParserTest.java b/tests/src/cgeo/geocaching/files/GPXParserTest.java
index dcaad22..9297819 100644
--- a/tests/src/cgeo/geocaching/files/GPXParserTest.java
+++ b/tests/src/cgeo/geocaching/files/GPXParserTest.java
@@ -325,4 +325,27 @@ public class GPXParserTest extends AbstractResourceInstrumentationTestCase {
assertEquals("Wasserleitung", cache.getHint());
}
+ private Geocache getFirstCache(int gpxResourceId) throws IOException, ParserException {
+ final List<Geocache> caches = readGPX10(gpxResourceId);
+ assertNotNull(caches);
+ assertEquals(1, caches.size());
+ final Geocache cache = caches.get(0);
+ return cache;
+ }
+
+ public void testGsakFavPoints() throws IOException, ParserException {
+ final Geocache cache = getFirstCache(R.raw.gc3t1xg_gsak);
+ assertEquals(258, cache.getFavoritePoints());
+ }
+
+ public void testGsakPersonalNote() throws IOException, ParserException {
+ final Geocache cache = getFirstCache(R.raw.gc3t1xg_gsak);
+ assertEquals("Personal Note Test", cache.getPersonalNote());
+ }
+
+ public void testGsakPremium() throws IOException, ParserException {
+ final Geocache cache = getFirstCache(R.raw.gc3t1xg_gsak);
+ assertTrue(cache.isPremiumMembersOnly());
+ }
+
}
diff --git a/tests/src/cgeo/geocaching/geopoint/GeoPointParserTest.java b/tests/src/cgeo/geocaching/geopoint/GeoPointParserTest.java
index 1de2e26..28dbe77 100644
--- a/tests/src/cgeo/geocaching/geopoint/GeoPointParserTest.java
+++ b/tests/src/cgeo/geocaching/geopoint/GeoPointParserTest.java
@@ -19,7 +19,13 @@ public class GeoPointParserTest extends AndroidTestCase {
public static void testFullCoordinates() {
final Geopoint goal = new Geopoint(refLatitude, refLongitude);
- assertTrue(goal.isEqualTo(GeopointParser.parse("N 49° 56.031 | E 8° 38.564"), 1e-6));
+ assertEquals(goal, GeopointParser.parse("N 49° 56.031 | E 8° 38.564"), 1e-6);
+ }
+
+ private static void assertEquals(final Geopoint expected, Geopoint actual, double tolerance) {
+ assertNotNull(expected);
+ assertNotNull(actual);
+ assertTrue(expected.distanceTo(actual) <= tolerance);
}
public static void testCoordinateMissingPart() {
@@ -48,18 +54,18 @@ public class GeoPointParserTest extends AndroidTestCase {
public static void testVariousFormats() {
final Geopoint goal1 = GeopointParser.parse("N 49° 43' 57\" | E 2 12' 35");
final Geopoint goal2 = GeopointParser.parse("N 49 43.95 E2°12.5833333333");
- assertTrue(goal1.isEqualTo(goal2, 1e-6));
+ assertEquals(goal1, goal2, 1e-6);
}
public static void testParseOurOwnSeparator() {
final Geopoint separator = GeopointParser.parse("N 49° 43' 57\"" + Formatter.SEPARATOR + "E 2 12' 35");
final Geopoint noSeparator = GeopointParser.parse("N 49 43.95 E2°12.5833333333");
- assertTrue(separator.isEqualTo(noSeparator, 1e-6));
+ assertEquals(separator, noSeparator, 1e-6);
}
public static void testInSentence() {
final Geopoint p1 = GeopointParser.parse("Station3: N51 21.523 / E07 02.680");
- final Geopoint p2 = GeopointParser.parse("N51 21.523", "E07 02.680");
+ final Geopoint p2 = GeopointParser.parse("N51 21.523 E07 02.680");
assertNotNull(p1);
assertNotNull(p2);
assertEquals(p1, p2);
@@ -106,6 +112,6 @@ public class GeoPointParserTest extends AndroidTestCase {
}
public static void testEquatorMeridian() {
- assertEquals(new Geopoint(0, 0), GeopointParser.parse("00° 00.000 00° 00.000"));
+ assertEquals(Geopoint.ZERO, GeopointParser.parse("00° 00.000 00° 00.000"));
}
}
diff --git a/tests/src/cgeo/geocaching/geopoint/ViewportTest.java b/tests/src/cgeo/geocaching/geopoint/ViewportTest.java
index 60766b4..11f78ad 100644
--- a/tests/src/cgeo/geocaching/geopoint/ViewportTest.java
+++ b/tests/src/cgeo/geocaching/geopoint/ViewportTest.java
@@ -2,6 +2,8 @@ package cgeo.geocaching.geopoint;
import cgeo.geocaching.ICoordinates;
+import org.eclipse.jdt.annotation.NonNull;
+
import android.test.AndroidTestCase;
import java.util.Collections;
@@ -11,7 +13,8 @@ import java.util.Set;
public class ViewportTest extends AndroidTestCase {
- final private static Viewport vpRef = new Viewport(new Geopoint(-1.0, -2.0), new Geopoint(3.0, 4.0));
+ final private static @NonNull
+ Viewport vpRef = new Viewport(new Geopoint(-1.0, -2.0), new Geopoint(3.0, 4.0));
public static void assertBounds(final Viewport vp) {
assertEquals(new Geopoint(1.0, 1.0), vp.center);
@@ -49,7 +52,7 @@ public class ViewportTest extends AndroidTestCase {
public static void testInViewport() {
assertFalse(vpRef.contains(new Geopoint(-2.0, -2.0)));
assertFalse(vpRef.contains(new Geopoint(4.0, 4.0)));
- assertTrue(vpRef.contains(new Geopoint(0.0, 0.0)));
+ assertTrue(vpRef.contains(Geopoint.ZERO));
assertTrue(vpRef.contains(new Geopoint(-1.0, -2.0)));
assertTrue(vpRef.contains(new Geopoint(3.0, 4.0)));
}
@@ -86,16 +89,6 @@ public class ViewportTest extends AndroidTestCase {
assertFalse(vpRef.includes(vpRef.resize(2.0)));
}
- public static void testExpands() {
- assertEquals(vpRef, vpRef.expand(new Geopoint(0, 0)));
- final Viewport vp1 = vpRef.expand(new Geopoint(-4.0, 0.0));
- assertEquals(new Geopoint(-4.0, -2.0), vp1.bottomLeft);
- assertEquals(new Geopoint(3.0, 4.0), vp1.topRight);
- final Viewport vp2 = vpRef.expand(new Geopoint(-10.0, 10.0));
- assertEquals(new Geopoint(-10.0, -2.0), vp2.bottomLeft);
- assertEquals(new Geopoint(3.0, 10.0), vp2.topRight);
- }
-
public static void testContaining() {
assertNull(Viewport.containing(Collections.singleton((ICoordinates) null)));
final Set<Geopoint> points = new HashSet<Geopoint>();
diff --git a/tests/src/cgeo/geocaching/network/OAuthTest.java b/tests/src/cgeo/geocaching/network/OAuthTest.java
index fa0104f..6888cec 100644
--- a/tests/src/cgeo/geocaching/network/OAuthTest.java
+++ b/tests/src/cgeo/geocaching/network/OAuthTest.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.network;
+import org.eclipse.jdt.annotation.NonNull;
+
import java.util.ArrayList;
import java.util.List;
@@ -26,7 +28,8 @@ public class OAuthTest extends TestCase {
public static void testUnreservedCharactersMustNotBeEncoded() {
for (Character c : UNRESERVED) {
- final String charAsString = String.valueOf(c);
+ final @NonNull
+ String charAsString = String.valueOf(c);
assertEquals("wrong OAuth encoding for " + c, charAsString, OAuth.percentEncode(charAsString));
}
}
@@ -35,7 +38,8 @@ public class OAuthTest extends TestCase {
for (int i = 32; i < 127; i++) {
final Character c = (char) i;
if (!UNRESERVED.contains(c)) {
- final String charAsString = String.valueOf(c);
+ final @NonNull
+ String charAsString = String.valueOf(c);
final String encoded = OAuth.percentEncode(charAsString);
assertFalse("Character '" + charAsString + "' not encoded", charAsString.equals(encoded));
assertTrue(encoded.startsWith("%"));
diff --git a/tests/src/cgeo/geocaching/sorting/DistanceComparatorTest.java b/tests/src/cgeo/geocaching/sorting/DistanceComparatorTest.java
index 2db3f59..0cfee49 100644
--- a/tests/src/cgeo/geocaching/sorting/DistanceComparatorTest.java
+++ b/tests/src/cgeo/geocaching/sorting/DistanceComparatorTest.java
@@ -20,7 +20,7 @@ public class DistanceComparatorTest extends AndroidTestCase {
}
caches.add(cache);
}
- Collections.sort(caches, new DistanceComparator(new Geopoint(0, 0), caches));
+ Collections.sort(caches, new DistanceComparator(Geopoint.ZERO, caches));
}
}
diff --git a/tests/src/cgeo/geocaching/utils/LogTemplateProviderTest.java b/tests/src/cgeo/geocaching/utils/LogTemplateProviderTest.java
index 5911218..249cbb1 100644
--- a/tests/src/cgeo/geocaching/utils/LogTemplateProviderTest.java
+++ b/tests/src/cgeo/geocaching/utils/LogTemplateProviderTest.java
@@ -10,11 +10,11 @@ public class LogTemplateProviderTest extends TestCase {
public static void testApplyTemplates() {
final String noTemplates = " no templates ";
- assertEquals(noTemplates, LogTemplateProvider.applyTemplates(noTemplates, new LogContext(true)));
+ assertEquals(noTemplates, LogTemplateProvider.applyTemplates(noTemplates, new LogContext(null, null, true)));
// This test can occasionally fail if the current year changes right after the next line.
final String currentYear = Integer.toString(Calendar.YEAR);
- assertTrue(LogTemplateProvider.applyTemplates("[DATE]", new LogContext(true)).contains(currentYear));
+ assertTrue(LogTemplateProvider.applyTemplates("[DATE]", new LogContext(null, null, true)).contains(currentYear));
}
}
diff --git a/tests/src/cgeo/geocaching/utils/MemorySubjectTest.java b/tests/src/cgeo/geocaching/utils/MemorySubjectTest.java
deleted file mode 100644
index ee46950..0000000
--- a/tests/src/cgeo/geocaching/utils/MemorySubjectTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package cgeo.geocaching.utils;
-
-import android.test.AndroidTestCase;
-
-public class MemorySubjectTest extends AndroidTestCase {
-
- private static class Observer implements IObserver<Integer> {
- private int times = 0;
- private Integer value;
-
- @Override
- public void update(final Integer data) {
- value = data;
- times++;
- }
- }
-
- private Observer observer;
- private MemorySubject<Integer> memorySubject;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- observer = new Observer();
- memorySubject = new MemorySubject<Integer>();
- }
-
- public void testInitial() {
- assertNull(observer.value);
- assertEquals(0, observer.times);
- assertNull(memorySubject.getMemory());
- }
-
- public void testMemory() {
- memorySubject.addObserver(observer);
- memorySubject.notifyObservers(10);
- assertEquals(Integer.valueOf(10), observer.value);
- assertEquals(1, observer.times);
- assertEquals(Integer.valueOf(10), memorySubject.getMemory());
- memorySubject.notifyObservers(20);
- assertEquals(Integer.valueOf(20), observer.value);
- assertEquals(2, observer.times);
- assertEquals(Integer.valueOf(20), memorySubject.getMemory());
- }
-
- public void testAttach() {
- memorySubject.notifyObservers(10);
- assertNull(observer.value);
- assertEquals(0, observer.times);
- memorySubject.addObserver(observer);
- assertEquals(Integer.valueOf(10), observer.value);
- assertEquals(1, observer.times);
- memorySubject.notifyObservers(20);
- assertEquals(Integer.valueOf(20), observer.value);
- assertEquals(2, observer.times);
- }
-
- public void testDetach() {
- memorySubject.addObserver(observer);
- memorySubject.notifyObservers(10);
- assertEquals(Integer.valueOf(10), observer.value);
- assertEquals(1, observer.times);
- assertEquals(Integer.valueOf(10), memorySubject.getMemory());
- memorySubject.deleteObserver(observer);
- memorySubject.notifyObservers(20);
- assertEquals(Integer.valueOf(10), observer.value);
- assertEquals(1, observer.times);
- assertEquals(Integer.valueOf(20), memorySubject.getMemory());
- }
-
- public void testMultiple() {
- final Observer otherObserver = new Observer();
- memorySubject.addObserver(otherObserver);
- testDetach();
- assertEquals(Integer.valueOf(20), otherObserver.value);
- assertEquals(2, otherObserver.times);
- }
-
-}