aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/AndroidManifest.xml7
-rw-r--r--main/res/layout/popup.xml3
-rw-r--r--main/res/layout/visit.xml3
-rw-r--r--main/res/layout/visit_image.xml123
-rw-r--r--main/res/layout/waypoint_popup.xml3
-rw-r--r--main/res/values-da/strings.xml2
-rw-r--r--main/res/values-de/strings.xml8
-rw-r--r--main/res/values-it/strings.xml4
-rw-r--r--main/res/values-nl/strings.xml247
-rw-r--r--main/res/values/strings.xml19
-rw-r--r--main/res/values/strings_not_translatable.xml3
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java61
-rw-r--r--main/src/cgeo/geocaching/ImageSelectActivity.java253
-rw-r--r--main/src/cgeo/geocaching/VisitCacheActivity.java88
-rw-r--r--main/src/cgeo/geocaching/compatibility/AndroidLevel8.java9
-rw-r--r--main/src/cgeo/geocaching/compatibility/AndroidLevel8Emulation.java9
-rw-r--r--main/src/cgeo/geocaching/compatibility/AndroidLevel8Interface.java4
-rw-r--r--main/src/cgeo/geocaching/compatibility/Compatibility.java6
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java7
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java95
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java7
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java12
-rw-r--r--main/src/cgeo/geocaching/enumerations/StatusCode.java3
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java4
-rw-r--r--main/src/cgeo/geocaching/network/Network.java4
-rw-r--r--main/src/cgeo/geocaching/network/Parameters.java4
-rw-r--r--main/src/cgeo/geocaching/sorting/GeocodeComparator.java4
-rw-r--r--main/src/cgeo/geocaching/utils/HtmlUtils.java25
-rw-r--r--tests/src/cgeo/geocaching/SettingsTest.java5
-rw-r--r--tests/src/cgeo/geocaching/utils/HtmlUtilsTest.java11
30 files changed, 936 insertions, 97 deletions
diff --git a/main/AndroidManifest.xml b/main/AndroidManifest.xml
index f764462..35cac8a 100644
--- a/main/AndroidManifest.xml
+++ b/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+ <uses-feature android:name="android.hardware.camera" android:required="false"/>
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
@@ -56,6 +57,7 @@
<activity
android:name=".CachePopup"
android:label="@string/app_name"
+ android:theme="@style/popup_dark"
android:windowSoftInputMode="stateHidden"
android:configChanges="keyboardHidden|orientation" >
</activity>
@@ -219,10 +221,15 @@
<activity android:name="WaypointPopup"
android:label="@string/app_name"
android:windowSoftInputMode="stateHidden"
+ android:theme="@style/popup_dark"
android:configChanges="keyboardHidden|orientation" >
</activity>
<activity android:name=".files.SimpleDirChooser"
android:label="@string/app_name">
</activity>
+ <activity
+ android:name=".ImageSelectActivity"
+ android:label="@string/app_name">
+ </activity>
</application>
</manifest>
diff --git a/main/res/layout/popup.xml b/main/res/layout/popup.xml
index 1e4c762..9e66517 100644
--- a/main/res/layout/popup.xml
+++ b/main/res/layout/popup.xml
@@ -2,7 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:orientation="vertical" >
+ android:orientation="vertical"
+ android:background="?background_color_transparent">
<LinearLayout style="@style/action_bar" >
diff --git a/main/res/layout/visit.xml b/main/res/layout/visit.xml
index 54f4f4b..fde4cd3 100644
--- a/main/res/layout/visit.xml
+++ b/main/res/layout/visit.xml
@@ -76,6 +76,9 @@
android:text="@string/visit_tweet" />
</LinearLayout>
<Button style="@style/button_full"
+ android:id="@+id/image_btn"
+ android:text="@string/log_image_attach" />
+ <Button style="@style/button_full"
android:id="@+id/post"
android:text="@string/log_post" />
<RelativeLayout style="@style/separator_horizontal_layout" >
diff --git a/main/res/layout/visit_image.xml b/main/res/layout/visit_image.xml
new file mode 100644
index 0000000..0b18f8f
--- /dev/null
+++ b/main/res/layout/visit_image.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout style="@style/action_bar" >
+
+ <ImageView
+ style="@style/action_bar_action"
+ android:onClick="goHome" />
+
+ <View style="@style/action_bar_separator" />
+
+ <TextView style="@style/action_bar_title" />
+
+ <View style="@style/action_bar_separator" />
+
+ <ProgressBar
+ style="@style/action_bar_progress"
+ android:visibility="gone" />
+
+ <ImageView
+ style="@style/action_bar_action"
+ android:onClick="goManual"
+ android:src="@drawable/actionbar_manual" />
+ </LinearLayout>
+
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:padding="4dip" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dip"
+ android:orientation="vertical" >
+
+ <RelativeLayout style="@style/separator_horizontal_layout" >
+
+ <View style="@style/separator_horizontal" />
+
+ <TextView
+ style="@style/separator_horizontal_headline"
+ android:text="@string/log_image" />
+ </RelativeLayout>
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dip"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/stored"
+ style="@style/button_full"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:text="@string/log_image_stored" />
+
+ <Button
+ android:id="@+id/camera"
+ style="@style/button_full"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:text="@string/log_image_camera" />
+ </LinearLayout>
+
+ <ImageView
+ android:id="@+id/image_preview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="5dip"
+ android:layout_marginTop="5dip"
+ android:background="#000000"
+ android:padding="1dp"
+ android:visibility="gone" />
+
+ <EditText
+ android:id="@+id/caption"
+ style="@style/edittext_full"
+ android:layout_height="wrap_content"
+ android:hint="@string/log_image_caption"
+ android:inputType="textCapSentences"
+ android:maxLength="50"
+ android:minLines="1"
+ android:singleLine="false" />
+
+ <EditText
+ android:id="@+id/description"
+ style="@style/edittext_full"
+ android:layout_height="wrap_content"
+ android:hint="@string/log_image_description"
+ android:inputType="textMultiLine|textCapSentences"
+ android:maxLength="250"
+ android:minLines="5"
+ android:singleLine="false" />
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/save"
+ style="@style/button_full"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:text="@android:string/yes" />
+
+ <Button
+ android:id="@+id/cancel"
+ style="@style/button_full"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:text="@android:string/no" />
+ </LinearLayout>
+ </LinearLayout>
+ </ScrollView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/main/res/layout/waypoint_popup.xml b/main/res/layout/waypoint_popup.xml
index 5feec43..3dfcd66 100644
--- a/main/res/layout/waypoint_popup.xml
+++ b/main/res/layout/waypoint_popup.xml
@@ -2,7 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:background="?background_color_transparent">
<LinearLayout style="@style/action_bar">
<TextView style="@style/action_bar_title" />
<View style="@style/action_bar_separator" />
diff --git a/main/res/values-da/strings.xml b/main/res/values-da/strings.xml
index cfe5b17..9332b9f 100644
--- a/main/res/values-da/strings.xml
+++ b/main/res/values-da/strings.xml
@@ -214,7 +214,7 @@
<string name="cache_status_archived">Arkiveret</string>
<string name="cache_status_disabled">Deaktiveret</string>
<string name="cache_status_premium">Kun premium-medlemmer</string>
- <string name="cache_geocode">GC-code</string>
+ <string name="cache_geocode">geo code</string>
<string name="cache_type">Type</string>
<string name="cache_distance">Distance</string>
<string name="cache_difficulty">Sværhed</string>
diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml
index ca2af61..51288fc 100644
--- a/main/res/values-de/strings.xml
+++ b/main/res/values-de/strings.xml
@@ -200,7 +200,7 @@
<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">GC-Code eingeben. z.B. \"GC1VCAZ\".</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>
@@ -241,7 +241,7 @@
<string name="advanced_search_button">Suche</string>
<string name="stored_caches_button">Gespeichert</string>
<string name="any_button">Überall</string>
- <string name="unknown_scan">Konnte keinen GC-Code im Scan finden.</string>
+ <string name="unknown_scan">Konnte keinen Geocode im Scan finden.</string>
<!-- caches -->
<string name="caches_no_cache">Kein Cache</string>
@@ -575,7 +575,7 @@
<string name="cache_status_disabled">Deaktiviert</string>
<string name="cache_status_premium">Nur für Premium-Mitglieder</string>
<string name="cache_status_not_premium">Für alle Mitglieder</string>
- <string name="cache_geocode">GC-Code</string>
+ <string name="cache_geocode">Geocode</string>
<string name="cache_name">Name</string>
<string name="cache_type">Typ</string>
<string name="cache_size">Größe</string>
@@ -731,7 +731,7 @@
<!-- search -->
<string name="search_bar_hint">Suche nach Caches</string>
- <string name="search_bar_desc">Caches (GC-Code, Stichwort), Trackables (TB-Code)</string>
+ <string name="search_bar_desc">Caches (Geocode, Stichwort), Trackables (TB-Code)</string>
<string name="search_coordinates">Koordinaten</string>
<string name="search_coordinates_button">Suche mit Koordinaten</string>
<string name="search_address">Adresse</string>
diff --git a/main/res/values-it/strings.xml b/main/res/values-it/strings.xml
index e9883e9..f7d29cb 100644
--- a/main/res/values-it/strings.xml
+++ b/main/res/values-it/strings.xml
@@ -565,7 +565,7 @@
<string name="cache_status_disabled">Non attivo</string>
<string name="cache_status_premium">Solo per utenti Premium</string>
<string name="cache_status_not_premium">Per tutti gli utenti</string>
- <string name="cache_geocode">GC-code</string>
+ <string name="cache_geocode">geo code</string>
<string name="cache_name">Nome</string>
<string name="cache_type">Tipo</string>
<string name="cache_size">Dimensione</string>
@@ -721,7 +721,7 @@
<!-- search -->
<string name="search_bar_hint">Cerca caches</string>
- <string name="search_bar_desc">Cache (GC-code, parole chiave), Oggetti trackables (TB-code)</string>
+ <string name="search_bar_desc">Cache (geo code, parole chiave), Oggetti trackables (TB-code)</string>
<string name="search_coordinates">Coordinate</string>
<string name="search_coordinates_button">Cerca per coordinate</string>
<string name="search_address">Indirizzo</string>
diff --git a/main/res/values-nl/strings.xml b/main/res/values-nl/strings.xml
index cb1b78e..9797012 100644
--- a/main/res/values-nl/strings.xml
+++ b/main/res/values-nl/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">c:geo</string>
<string name="app_name_compass">c:geo compass</string>
@@ -53,6 +53,7 @@
<string name="wp_pkg">Parkeer gelegenheid</string>
<string name="wp_trailhead">Trailhead</string>
<string name="wp_waypoint">Referentie punt</string>
+ <string name="wp_original">Originele coördinaten</string>
<!-- logs -->
<string name="log_found">Gevonden</string>
@@ -63,18 +64,21 @@
<string name="log_disabled">Uitgeschakeld</string>
<string name="log_attend">Zal aanwezig zijn</string>
<string name="log_attended">Was aanwezig</string>
- <string name="log_retrieved">Teruggevonden</string>
+ <string name="log_retrieved">Meegenomen</string>
<string name="log_placed">Geplaatst</string>
- <string name="log_grabbed">Gepakt</string>
+ <string name="log_grabbed">Ergens gepakt</string>
<string name="log_movecollection">Verplaats naar collectie</string>
<string name="log_moveinventory">Verplaats naar inventaris</string>
<string name="log_maintained">Onderhoud uitgevoerd</string>
<string name="log_maintenance_needed">Onderhoud nodig</string>
<string name="log_update">Bijgewerkte coördinaten</string>
<string name="log_archived">Gearchiveerd</string>
+ <string name="log_unarchived">Gedearchiveerd</string>
<string name="log_needs_archived">Dient te worden gearchiveerd</string>
<string name="log_discovered">Ontdekt</string>
<string name="log_reviewer">Recensent notitie</string>
+ <string name="log_retractlisting">Plaatsing teruggetrokken</string>
+ <string name="log_marked_missing">Als ontbrekend gemarkeerd</string>
<string name="log_tb_nothing">Niets doen</string>
<string name="log_tb_visit">Bezoek</string>
<string name="log_tb_drop">Hier droppen</string>
@@ -111,6 +115,9 @@
<string name="log_new_log">Log</string>
<string name="log_new_log_text">Log tekst</string>
<string name="log_announcement">Aankondiging</string>
+ <string name="log_today">Vandaag</string>
+ <string name="log_yesterday">Gisteren</string>
+ <string name="log_smilies">Smilies</string>
<!-- translation -->
<string name="translate_to_sys_lang">Vertaal naar %s</string>
@@ -131,6 +138,7 @@
<string name="err_wrong">Foutieve login informatie</string>
<string name="err_maintenance">Geocaching.com is offline voor onderhoud. c:geo werkt offline met opgeslagen caches.</string>
<string name="err_license">Gebruiker heeft de gebruikersvoorwaarden van Geocaching.com niet geaccepteerd.</string>
+ <string name="err_unvalidated_account">Je dient je account eerst te valideren op de Geocaching.com website.</string>
<string name="err_unpublished">De cache is nog niet gepubliceerd</string>
<string name="err_premium_only">Deze cache is alleen beschikbaar voor Geocaching.com premium leden.</string>
<string name="err_detail_open">Sorry, c:geo kan de geocache details niet openen.</string>
@@ -140,6 +148,7 @@
<string name="err_detail_cache_find_any">Sorry, c:geo kan geen enkele geocache vinden.</string>
<string name="err_detail_cache_find_next">Sorry, c:geo kan de volgende cache niet vinden.</string>
<string name="err_detail_cache_forgot">Sorry, c:geo is kwijt welke geocache je wilde openen.</string>
+ <string name="err_detail_google_maps_limit_reached">c:geo kon de statische kaarten niet downloaden. Wellicht dat de Google Maps limiet is bereikt.</string>
<string name="err_detail_no_spoiler">c:geo Heeft geen spoiler images gevonden voor deze cache.</string>
<string name="err_detail_no_map_static">c:geo Heeft geen statische kaarten gevonden voor deze cache.</string>
<string name="err_detail_not_load_map_static">Sorry, c:geo kon de statische kaart niet laden.</string>
@@ -156,6 +165,7 @@
<string name="err_load_descr_failed">Sorry, c:geo kan de omschrijving niet laden.</string>
<string name="err_location_unknown">c:geo kent de locatie van de cache niet.</string>
<string name="err_missing_device_name">Voer een apparaatnaam in voor registratie.</string>
+ <string name="err_favorite_failed">Wijzigen favorieten status is mislukt.</string>
<string name="err_tb_display">Sorry, c:geo kan de gezochte trackable niet weergeven. Is het wel een trackable?</string>
<string name="err_tb_details_open">Sorry, c:geo kan de trackable details niet laden.</string>
@@ -198,6 +208,10 @@
<string name="warn_search_help_tb">Voer de trackable code in. Bijvoorbeeld \"TB29QMZ\".</string>
<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_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="info_log_posted">c:geo heeft log succesvol gepost.</string>
@@ -214,6 +228,7 @@
<string name="loc_sat">Sat</string>
<string name="loc_trying">Proberen te lokaliseren</string>
<string name="loc_no_addr">Adres onbekend</string>
+ <string name="loc_gps_disabled">GPS uitgeschakeld</string>
<!-- standard menu -->
<string name="menu_about">Over c:geo</string>
@@ -249,19 +264,21 @@
<string name="caches_on_map">Toon op kaart</string>
<string name="caches_sort">Sorteer</string>
<string name="caches_sort_title">Sorteer op</string>
- <string name="caches_sort_distance">afstand</string>
- <string name="caches_sort_difficulty">moeilijkheid</string>
- <string name="caches_sort_terrain">terrein</string>
- <string name="caches_sort_size">formaat</string>
- <string name="caches_sort_favorites">populariteit</string>
- <string name="caches_sort_name">naam</string>
- <string name="caches_sort_geocode">geocode</string>
- <string name="caches_sort_rating">waardering</string>
- <string name="caches_sort_vote">stemmen (eigen waardering)</string>
- <string name="caches_sort_inventory">aantal items</string>
- <string name="caches_sort_date_hidden">datum</string>
+ <string name="caches_sort_distance">Afstand</string>
+ <string name="caches_sort_difficulty">Moeilijkheid</string>
+ <string name="caches_sort_terrain">Terrein</string>
+ <string name="caches_sort_size">Formaat</string>
+ <string name="caches_sort_favorites">Populariteit</string>
+ <string name="caches_sort_name">Naam</string>
+ <string name="caches_sort_geocode">Geocode</string>
+ <string name="caches_sort_rating">Waardering</string>
+ <string name="caches_sort_vote">Stemmen (eigen waardering)</string>
+ <string name="caches_sort_inventory">Aantal items</string>
+ <string name="caches_sort_date_hidden">Datum</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">Staat</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>
@@ -274,11 +291,13 @@
<string name="caches_drop_stored">Verwijder opgeslagen</string>
<string name="caches_drop_progress">Caches worden verwijderd</string>
<string name="caches_drop_all_and_list">Alle verwijderen en lijst verwijderen</string>
+ <string name="caches_delete_events">Verwijder afgelopen evenementen</string>
<string name="caches_refresh_selected">Ververs geselecteerden</string>
<string name="caches_refresh_all">Ververs alle</string>
<string name="caches_move_selected">Verplaats geselecteerden</string>
<string name="caches_move_all">Verplaats alle</string>
<string name="caches_map_locus">Locus</string>
+ <string name="caches_map_locus_export">Exporteer naar Locus</string>
<string name="caches_recaptcha_title">reCAPTCHA</string>
<string name="caches_recaptcha_explanation">Vul de tekst uit de afbeelding in. Dit is nodig voor het downloaden van de coördinaten van de caches. Dit is optioneel en kan in de instellingen uitgeschakeld worden.</string>
<string name="caches_recaptcha_hint">Tekst uit de afbeelding</string>
@@ -290,16 +309,19 @@
<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_removing_from_history">Verwijderen uit geschiedenis…</string>
<!-- caches lists -->
<string name="list_menu">Lijst</string>
<string name="list_menu_create">Maak nieuwe lijst</string>
+ <string name="list_menu_all_lists">Alle caches</string>
<string name="list_menu_drop">Verwijder huidige lijst</string>
<string name="list_menu_change">Pas lijst aan</string>
<string name="list_menu_rename">Hernoem huidige lijst</string>
<string name="list_title">Selecteer een lijst</string>
<string name="list_inbox">Opgeslagen</string>
+ <string name="list_all_lists">Alle caches</string>
<string name="list_dialog_create_title">Nieuwe lijst</string>
<string name="list_dialog_create">Maak</string>
<string name="list_dialog_cancel">Annuleer</string>
@@ -314,6 +336,7 @@
<string name="list_dialog_rename">Hernoem</string>
<!-- about -->
+ <string name="about_version">Versie</string>
<string name="about_changelog">Changelog</string>
<string name="about_donate">Doneren</string>
<string name="about_detail">Details</string>
@@ -322,6 +345,10 @@
<!-- init -->
<string name="init_geocaching">Geocaching.com</string>
+ <string name="init_oc">opencaching.de</string>
+ <string name="init_oc_activate">Activeer opencaching.de op live-kaart en in zoekopdrachten.</string>
+ <string name="init_oc_username_description">Vul je opencaching.de gebruikersnaam in op caches als gevonden te markeren.</string>
+ <string name="init_oc_username">Vul gebruikersnaam in</string>
<string name="init_gcvote">GCvote.com</string>
<string name="init_twitter">Twitter</string>
<string name="init_username">Gebruikersnaam</string>
@@ -345,6 +372,7 @@
<string name="init_signature_template_datetime">Datum &amp; tijd</string>
<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_details">Cache details</string>
<string name="init_ratingwanted">Laad cachewaardering van GCvote.com</string>
<string name="init_elevationwanted">Laad cache hoogte gegevens</string>
@@ -365,6 +393,7 @@
<string name="init_save_log_img">Sla afbeeldingen van logs op</string>
<string name="init_units">Gebruik imperiale stelsel voor afstanden</string>
<string name="init_log_offline">Als er gelogd word, doe dit altijd offline (Laat het online log scherm niet zien en verzend de log niet)</string>
+ <string name="init_choose_list">Vraag naar lijst voor opslaan caches.</string>
<string name="init_livelist">Toon afstand tot cache in lijst</string>
<string name="init_altitude">Hoogte correctie</string>
<string name="init_altitude_description">Als de GPS een verkeerde hoogte aangeeft, kan dit gecorrigeerd worden met een positief of negatief nummer. De correctie is in meters.</string>
@@ -387,7 +416,13 @@
<string name="init_mapsources">Kaartbron</string>
<string name="init_mapsources_description">Hier kan een kaartenbron geselecteerd worden. Als alternatief voor Google maps zijn verschillende OpenStreetMap varianten en ook offline kaarten-files beschikbaar (Zie <a href="http://code.google.com/p/mapsforge/">http://code.google.com/p/mapsforge/</a> voor meer info).</string>
<string name="init_mapsource_select">Selecteer kaartbron</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>
+ <string name="init_gpx_exportdir_description">Hier kan je de directory voor GPX exports selecteren.</string>
+ <string name="init_gpx_importdir_description">Hier kan je de directory voor GPX imports selecteren.</string>
<string name="init_maptrail">Laat pad op kaart zien</string>
+ <string name="init_share_after_export">Open deel-menu na GPX export.</string>
<string name="init_trackautovisit">Zet trackables automatisch op \'bezocht\'</string>
<string name="init_sigautoinsert">Voeg handtekening automatisch toe</string>
<string name="init_loaddirectionimg">Laad de richting-afbeelding in, indien nodig (alleen basis-leden)</string>
@@ -395,6 +430,19 @@
<string name="init_default_navigation_tool_description">Hier kan je de navigatie-tool van jouw voorkeur instellen.</string>
<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_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">Genereer debug 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">Database op externe locatie.</string>
+ <string name="init_dbmove_dbmove">Verplaats database</string>
+ <string name="init_dbmove_running">Verplaats 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_use_native_ua">Identificeer als Android browser (lost loginproblemen bij sommige mobiele aanbieders op).</string>
+ <string name="init_rendertheme_folder">Directory met aangepaste offline mapthema\'s (optioneel).</string>
<!-- map sources -->
<string name="map_source_google_map">Google: Map</string>
@@ -453,6 +501,7 @@
<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_edit">Wijzig</string>
<string name="cache_description">Omschrijving</string>
<string name="cache_description_long">Lange omschrijving</string>
<string name="cache_description_table_note">Omschrijving bevat een tabel-layout welke misschien op %s bekeken moet worden.</string>
@@ -460,6 +509,15 @@
<string name="cache_watchlist_not_on">Deze cache komt niet voor op je watchlist.</string>
<string name="cache_watchlist_add">Voeg aan watchlist toe</string>
<string name="cache_watchlist_remove">Verwijder van watchlist</string>
+ <string name="cache_favpoint_on">Deze cache staat op jouw favorieten-lijst.</string>
+ <string name="cache_favpoint_not_on">Deze cache staat niet op jouw favorieten-lijst.</string>
+ <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_unknown">Niet in een lijst</string>
+ <string name="cache_images">Afbeeldingen</string>
+
<string name="cache_waypoints">Waypoints</string>
<plurals name="waypoints">
<item quantity="one">1 Waypoint</item>
@@ -477,6 +535,7 @@
<string name="cache_dialog_loading_details_status_waypoints">Verwerken waypoints</string>
<string name="cache_dialog_loading_details_status_gcvote">Laden GCVote</string>
<string name="cache_dialog_loading_details_status_elevation">Laden van hoogte gegevens</string>
+ <string name="cache_dialog_loading_details_status_cache">Caching Gegevens</string>
<string name="cache_dialog_loading_details_status_render">Weergave genereren</string>
<string name="cache_dialog_offline_save_title">Offline</string>
<string name="cache_dialog_offline_save_message">Cache opslaan voor offline gebruik…</string>
@@ -488,10 +547,18 @@
<string name="cache_dialog_watchlist_add_message">Voeg cache toe aan watchlist…</string>
<string name="cache_dialog_watchlist_remove_title">Watchlist</string>
<string name="cache_dialog_watchlist_remove_message">Verwijder cache van watchlist…</string>
+ <string name="cache_dialog_favourite_add_title">Favoriet</string>
+ <string name="cache_dialog_favourite_add_message">Voeg cache toe aan favorieten…</string>
+ <string name="cache_dialog_favourite_remove_title">Favoriet</string>
+ <string name="cache_dialog_favourite_remove_message">Verwijder cache van je favorieten…</string>
<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_maps_directions">Google Maps aanwijzigen</string>
<string name="cache_menu_radar">Radar</string>
<string name="cache_menu_map">Toon op kaart</string>
<string name="cache_menu_map_static">Statische kaarten</string>
+ <string name="cache_menu_download_map_static">Download statische kaarten</string>
<string name="cache_menu_rmaps">Rmaps</string>
<string name="cache_menu_map_ext">Toon op ext. kaart</string>
<string name="cache_menu_streetview">Street View</string>
@@ -507,13 +574,15 @@
<string name="cache_menu_gcc">GCC</string>
<string name="cache_menu_whereyougo">WhereYouGo</string>
<string name="cache_menu_oruxmaps">OruxMaps</string>
+ <string name="cache_menu_cachebeacon">Cache baken</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Log opgeslagen</string>
<string name="cache_status_found">Gevonden</string>
<string name="cache_status_archived">Gearchiveerd</string>
<string name="cache_status_disabled">Uitgeschakeld</string>
<string name="cache_status_premium">Alleen voor premium leden</string>
- <string name="cache_geocode">gc-code</string>
+ <string name="cache_status_not_premium">Toegang voor alle leden</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>
@@ -532,6 +601,8 @@
<string name="cache_coordinates_original">Originele coordinaten</string>
<string name="cache_spoiler_images_title">Spoiler afbeeldingen</string>
<string name="cache_spoiler_images_loading">Spoiler afbeeldingen laden…</string>
+ <string name="cache_images_title">Afbeeldingen</string>
+ <string name="cache_images_loading">Afbeeldingen laden…</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>
@@ -541,7 +612,12 @@
<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_time_full_hours">uur</string>
+ <string name="cache_listed_on">Opgenomen in %s</string>
+
+ <!-- editor dialog -->
+ <string name="editor_save">Opslaan</string>
+
<!-- file list base -->
<string name="file_searching_in">Zoeken naar bestanden\nin</string>
<string name="file_searching_sdcard_in">Geen bestanden in de standaard mappen gevonden:\n%1$s\n\nDe rest van de SD kaart word doorzocht voor bestanden:\n</string>
@@ -549,6 +625,10 @@
<string name="file_searching">Zoeken naar overeenkomende bestanden</string>
<string name="file_title_searching">Bezig met zoeken</string>
+ <!-- simple_dir_chooser -->
+ <string name="simple_dir_chooser_title">Kies directory</string>
+ <string name="simple_dir_chooser_current_path">Pad:</string>
+
<!-- gpx -->
<string name="gpx_import_loading_caches">Caches laden van .gpx bestand</string>
<string name="gpx_import_loading_waypoints">Waypoints laden van .gpx bestand</string>
@@ -565,10 +645,13 @@
<string name="gpx_import_error_unexpected">Onbekend probleem</string>
<string name="gpx_import_confirm">Wil je de GPX gegevens in c:geo laden?</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_message">Weet je zeker dat je %s wil verwijderen?</string>
<!-- map file select -->
<string name="map_file_select_title">Selecteer mapbestand</string>
+ <!-- theme file select -->
<!-- import -->
<string name="web_import_title">Importeer van web</string>
<string name="web_import_waiting">Aan het wachten voor nieuwe caches van het web…</string>
@@ -593,6 +676,20 @@
<string name="waypoint_note">Notitie</string>
<string name="waypoint_save">Opslaan</string>
<string name="waypoint_loading">Waypoint laden…</string>
+ <string name="waypoint_do_not_touch_cache_coordinates">Wijzig cachecoördinaten niet</string>
+ <string name="waypoint_set_as_cache_coords">Zet als cachecoördinaten in c:geo</string>
+ <string name="waypoint_save_and_modify_on_website">Zet als cachecoördinaten in c:geo en op de website</string>
+ <string name="waypoint_reset_cache_coords">Herstel cachecoördinaten</string>
+ <string name="waypoint_coordinates_has_been_reset_on_website">Cachecoördinaten zijn gereset op de website.</string>
+ <string name="waypoint_coordinates_being_reset_on_website">Cachecoördinaten herstellen op de website…</string>
+ <string name="waypoint_reset">Herstel</string>
+ <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_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_copy_of">Kopie van</string>
@@ -602,6 +699,15 @@
<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>
+
+ <!-- distance units -->
+ <string name="unit_m">m</string>
+ <string name="unit_km">km</string>
+ <string name="unit_ft">ft</string>
+ <string name="unit_yd">yd</string>
+ <string name="unit_mi">mi</string>
+
<!-- visit -->
<string name="visit_tweet">Post deze vondst op Twitter</string>
@@ -609,10 +715,13 @@
<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_trail_show">Toon spoor</string>
<string name="map_trail_hide">Verberg spoor</string>
<string name="map_circles_show">Laat cirkels zien</string>
<string name="map_circles_hide">Verberg cirkels</string>
+ <string name="map_theme_builtin">Standaard</string>
+ <string name="map_theme_select">Selecteer mapthema</string>
<string name="map_live_enable">Live aanzetten</string>
<string name="map_live_disable">Live uitzetten</string>
<string name="map_static_title">Statische kaarten</string>
@@ -625,10 +734,13 @@
<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>
+
<!-- search -->
<string name="search_bar_hint">Zoek naar caches</string>
- <string name="search_bar_desc">Caches (GC-code, trefwoord), Trackables (TB-code)</string>
+ <string name="search_bar_desc">Caches (geo code, trefwoord), Trackables (TB-code)</string>
<string name="search_coordinates">Coördinaten</string>
<string name="search_coordinates_button">Zoeken op coördinaten</string>
<string name="search_address">Adres</string>
@@ -681,6 +793,7 @@
<string name="user_menu_view_hidden">Caches verstopt</string>
<string name="user_menu_view_found">Caches gevonden</string>
<string name="user_menu_open_browser">Open profiel in browser</string>
+ <string name="user_menu_send_message">Verstuur bericht</string>
<!-- navigation -->
<string name="navigation">Navigatie</string>
@@ -716,6 +829,21 @@
<string name="addon_missing_title">Add-On ontbreekt</string>
<string name="addon_download_prompt">Haal de add-on nu op van Google Play.</string>
+ <!-- export -->
+ <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_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_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>
+
<!-- attributes (permissions -> allowed, not allowed) -->
<string name="attribute_dogs_yes">Honden toegestaan</string>
<string name="attribute_dogs_no">Honden niet toegestaan</string>
@@ -735,8 +863,6 @@
<string name="attribute_campfires_no">Kampvuren niet toegestaan</string>
<string name="attribute_rv_yes">Truck driver/RV toegestaan</string>
<string name="attribute_rv_no">Truck driver/RV niet toegestaan</string>
-
- <!-- attributes (conditions -> yes, no) -->
<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>
@@ -789,8 +915,6 @@
<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>
-
- <!-- attributes (equipment -> required, not required) -->
<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>
@@ -809,12 +933,10 @@
<string name="attribute_skiis_no">Langlaufski\'s niet nodig</string>
<string name="attribute_s_tool_yes">Speciate gereedschappen nodig</string>
<string name="attribute_s_tool_no">Geen speciale gereedschappen nodig</string>
- <string name="attribute_wirelessbeacon_yes">Wireless beacon</string>
- <string name="attribute_wirelessbeacon_no">No wireless beacon</string>
+ <string name="attribute_wirelessbeacon_yes">Draadloos baken</string>
+ <string name="attribute_wirelessbeacon_no">Geen draadloos baken</string>
<string name="attribute_treeclimbing_yes">Boomklimmen noodzakelijk</string>
<string name="attribute_treeclimbing_no">Boomklimmen niet nodig</string>
-
- <!-- attributes (hazards -> present, not present) -->
<string name="attribute_poisonoak_yes">Giftige planten</string>
<string name="attribute_poisonoak_no">Geen giftige planten</string>
<string name="attribute_dangerousanimals_yes">Gevaarlijke dieren</string>
@@ -831,8 +953,6 @@
<string name="attribute_danger_no">Geen gevaarlijk gebied</string>
<string name="attribute_thorn_yes">Doornen</string>
<string name="attribute_thorn_no">Geen doornen</string>
-
- <!-- attributes (facilities -> yes, no) -->
<string name="attribute_wheelchair_yes">Rolstoel toegankelijk</string>
<string name="attribute_wheelchair_no">Niet rolstoel toegankelijk</string>
<string name="attribute_parking_yes">Parkeerplaats beschikbaar</string>
@@ -855,6 +975,64 @@
<string name="attribute_fuel_no">Geen brandstof in de buurt</string>
<string name="attribute_food_yes">Eetgelegenheid in de buurt</string>
<string name="attribute_food_no">Geen eetgelegenheid in de buurt</string>
+ <string name="attribute_oc_only_yes">Alleen te loggen op Opencaching</string>
+ <string name="attribute_oc_only_no">Niet alleen te loggen op Opencaching</string>
+ <string name="attribute_link_only_yes">Alleen een link naar een ander caching-portaal</string>
+ <string name="attribute_link_only_no">Niet alleen een link naar een ander caching-portaal</string>
+ <string name="attribute_letterbox_yes">Brievenbus (stempel benodigd)</string>
+ <string name="attribute_letterbox_no">Geen Brievenbus (geen stempel benodigd)</string>
+ <string name="attribute_railway_yes">In gebruik zijnde treinrails in de buurt</string>
+ <string name="attribute_railway_no">Geen in gebruik zijnde treinrails in de buurt</string>
+ <string name="attribute_syringe_yes">Eerste hulp beschikbaar</string>
+ <string name="attribute_syringe_no">Geen eerste hulp beschikbaar</string>
+ <string name="attribute_swamp_yes">Moeras</string>
+ <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_poi_yes">Interessant punt</string>
+ <string name="attribute_poi_no">Geen interessant punt</string>
+ <string name="attribute_moving_target_yes">Bewegend doel</string>
+ <string name="attribute_moving_target_no">Geen bewegend doel</string>
+ <string name="attribute_webcam_yes">Webcam</string>
+ <string name="attribute_webcam_no">Geen webcam</string>
+ <string name="attribute_inside_yes">Met gesloten ruimten (grotten, gebouwen e.d.)</string>
+ <string name="attribute_inside_no">Niet met gesloten ruimten</string>
+ <string name="attribute_in_water_yes">In het water</string>
+ <string name="attribute_in_water_no">Niet in het water</string>
+ <string name="attribute_no_gps_yes">Zonder GPS (Brievenbus, cistes, compass juggling ...)</string>
+ <string name="attribute_no_gps_no">Met GPS</string>
+ <string name="attribute_overnight_yes">Overnachting noodzakelijk</string>
+ <string name="attribute_overnight_no">Geen overnachting noodzakelijk</string>
+ <string name="attribute_specific_times_yes">Alleen beschikbaar binnen aangegeven uren</string>
+ <string name="attribute_specific_times_no">Niet alleen beschikbaar binnen aangegeven uren</string>
+ <string name="attribute_day_yes">Alleen overdag</string>
+ <string name="attribute_day_no">Niet alleen overdag</string>
+ <string name="attribute_tide_yes">Vloed</string>
+ <string name="attribute_tide_no">Geen vloed</string>
+ <string name="attribute_all_seasons_yes">Alle seizoenen</string>
+ <string name="attribute_all_seasons_no">Niet alle seizoenen</string>
+ <string name="attribute_breeding_yes">Broedseizoen / beschermd gebied</string>
+ <string name="attribute_breeding_no">Geen broedseizoen / beschermd gebied</string>
+ <string name="attribute_snow_proof_yes">Schuilplaats voor de sneeuw</string>
+ <string name="attribute_snow_proof_no">Geen schuilplaats voor de sneeuw</string>
+ <string name="attribute_compass_yes">Kompas</string>
+ <string name="attribute_compass_no">Geen kompas</string>
+ <string name="attribute_cave_yes">Grot-uitrusting</string>
+ <string name="attribute_cave_no">Geen grot-uitrusting</string>
+ <string name="attribute_aircraft_yes">Vliegtuig</string>
+ <string name="attribute_aircraft_no">Geen vliegtuig</string>
+ <string name="attribute_investigation_yes">Onderzoek</string>
+ <string name="attribute_investigation_no">Geen onderzoek</string>
+ <string name="attribute_puzzle_yes">Puzzel / Mysterie</string>
+ <string name="attribute_puzzle_no">Geen Puzzel / Mysterie</string>
+ <string name="attribute_arithmetic_yes">Wiskundig probleem</string>
+ <string name="attribute_arithmetic_no">Geen wiskundig probleem</string>
+ <string name="attribute_other_cache_yes">Ander cachetype</string>
+ <string name="attribute_other_cache_no">Geen ander cachetype</string>
+ <string name="attribute_ask_owner_yes">Vraag eigenaar om startvoorwaarden</string>
+ <string name="attribute_ask_owner_no">Vraag eigenaar niet om startvoorwaarden</string>
+ <string name="attribute_unknown_yes">Onbekend attribuut aanwezig</string>
+ <string name="attribute_unknown_no">Geen onbekend attribuut aanwezig</string>
<!-- next things -->
<string name="legal_note">Voor het gebruik van de diensten van Geocaching.com, dient akkoord te worden gegaan met de <a href="http://www.geocaching.com/about/termsofuse.aspx">Groundspeak voorwaarden</a>.</string>
@@ -868,4 +1046,17 @@
<string name="about_twitter">Moet <b>c:geo</b> elke cache vondst publiceren naar Twitter?</string>
<string name="about_auth_1">Het volgende proces staat <b>c:geo</b> toe om Twitter toegang te verkrijgen bij goedkeuring.</string>
<string name="about_auth_2">Klik op de \"autoriseer c:geo\" knop om het proces te starten. Dit proces zal een browser openen met een Twitter pagina. Login op deze pagina en sta <b>c:geo</b> toegang tot je account toe. Bij goedkeuring laat Twitter een numerieke PIN code zien. Deze PIN dien je te plakken en te bevestigen in <b>c:geo</b>.</string>
+
+ <!-- status (used via string based resource loading) -->
+ <string name="status_new_release" tools:ignore="UnusedResources">Nieuwe release beschikbaar.\nTik om te installeren.</string>
+ <string name="status_new_nightly" tools:ignore="UnusedResources">Nieuwe nightly-release beschikbaar.\nTik om te installeren.</string>
+ <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="clipboard_copy_ok">Gekopieerd naar klembord</string>
+ <plurals name="days_ago">
+ <item quantity="one">Gisteren</item>
+ <item quantity="other">%d dagen geleden</item>
+ </plurals>
</resources>
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml
index 5b273ca..0382071 100644
--- a/main/res/values/strings.xml
+++ b/main/res/values/strings.xml
@@ -85,6 +85,7 @@
<string name="log_tb_changeall">Change All</string>
<string name="log_save">Save</string>
<string name="log_saving">Sending log…</string>
+ <string name="log_saving_and_uploading">Sending log and uploading image…</string>
<string name="log_clear">Clear</string>
<string name="log_post">Submit Log</string>
<string name="log_post_rate">Submit Log &amp; Rate</string>
@@ -118,6 +119,13 @@
<string name="log_today">Today</string>
<string name="log_yesterday">Yesterday</string>
<string name="log_smilies">Smilies</string>
+ <string name="log_image">Image</string>
+ <string name="log_image_attach">Attach Image</string>
+ <string name="log_image_edit">Edit Image</string>
+ <string name="log_image_stored">Existing</string>
+ <string name="log_image_camera">New</string>
+ <string name="log_image_caption">Caption</string>
+ <string name="log_image_description">Description</string>
<!-- translation -->
<string name="translate_to_sys_lang">Translate to %s</string>
@@ -166,6 +174,8 @@
<string name="err_location_unknown">c:geo doesn\'t know location of cache.</string>
<string name="err_missing_device_name">Please enter a device name before registering.</string>
<string name="err_favorite_failed">Changing favorite status failed.</string>
+ <string name="err_select_logimage_failed">Selecting an image for the log failed.</string>
+ <string name="err_aquire_image_failed">Acquiring an image failed.</string>
<string name="err_tb_display">c:geo can\'t display trackable you want. Is it really a trackable?</string>
<string name="err_tb_details_open">c:geo can\'t open trackable details.</string>
@@ -188,6 +198,7 @@
<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_logimage_post_failed">It seems that your log image was not uploaded. Please check it on Geocaching.com.</string>
<string name="err_search_address_forgot">c:geo forgot the address you tried to find.</string>
<string name="err_parse_lat">c:geo can\'t parse latitude.</string>
@@ -213,11 +224,12 @@
<string name="warn_nonexistant_mapfile">The selected map file does not exist.\nOffline maps are not available.</string>
<string name="warn_rendertheme_missing">Map theme not found.</string>
-
<string name="info_log_posted">c:geo successfully submitted the log.</string>
<string name="info_log_saved">c:geo successfully saved the log.</string>
<string name="info_log_cleared">Log was cleared.</string>
<string name="info_log_type_changed">Type of log has been changed!</string>
+ <string name="info_select_logimage_cancelled">Image selection or capture was cancelled.</string>
+ <string name="info_stored_image">New image saved to:</string>
<string name="info_storing_static_maps">Trying to store static maps</string>
@@ -574,8 +586,7 @@
<string name="cache_menu_gcc">GCC</string>
<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_sygic" translatable="false">Sygic</string>
+ <string name="cache_menu_cachebeacon">Cache Beacon</string>
<string name="cache_status">Status</string>
<string name="cache_status_offline_log">Saved Log</string>
<string name="cache_status_found">Found</string>
@@ -741,7 +752,7 @@
<!-- search -->
<string name="search_bar_hint">Search for caches</string>
- <string name="search_bar_desc">Caches (GC-code, keyword), Trackables (TB-code)</string>
+ <string name="search_bar_desc">Caches (geo code, keyword), Trackables (TB code)</string>
<string name="search_coordinates">Coordinates</string>
<string name="search_coordinates_button">Search by coordinates</string>
<string name="search_address">Address</string>
diff --git a/main/res/values/strings_not_translatable.xml b/main/res/values/strings_not_translatable.xml
index 1853fac..ec330ad 100644
--- a/main/res/values/strings_not_translatable.xml
+++ b/main/res/values/strings_not_translatable.xml
@@ -74,6 +74,9 @@
· <a href="http://androidicons.com/">Android Icons</a> (<a href="https://creativecommons.org/licenses/by/3.0/">CC-BY 3.0</a>)\n
· <a href="http://rrze-icon-set.berlios.de/index.html">RRZE Icon set</a> (<a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA 3.0</a>)\n
</string>
+
+ <!-- cache menu -->
+ <string name="cache_menu_sygic" translatable="false">Sygic</string>
<!-- changelog -->
<string name="changelog" translatable="false">\n
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index f35d599..0cf016d 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -1883,6 +1883,21 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
+ private class HtmlImageCounter implements Html.ImageGetter {
+
+ private int imageCount = 0;
+
+ @Override
+ public Drawable getDrawable(String url) {
+ imageCount++;
+ return null;
+ }
+
+ public int getImageCount() {
+ return imageCount;
+ }
+ }
+
/**
* Loads the description in background. <br />
* <br />
@@ -1899,20 +1914,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
private String descriptionString;
private Spanned description;
- private class HtmlImageCounter implements Html.ImageGetter {
-
- private int imageCount = 0;
-
- @Override
- public Drawable getDrawable(String url) {
- imageCount++;
- return null;
- }
-
- public int getImageCount() {
- return imageCount;
- }
- }
@Override
protected Void doInBackground(Object... params) {
@@ -2086,7 +2087,15 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
String logText = log.log;
if (BaseUtils.containsHtml(logText)) {
logText = log.getDisplayText();
- holder.text.setText(Html.fromHtml(logText, new HtmlImage(cache.getGeocode(), false, cache.getListId(), false), null), TextView.BufferType.SPANNABLE);
+ // Fast preview: parse only HTML without loading any images
+ HtmlImageCounter imageCounter = new HtmlImageCounter();
+ final UnknownTagsHandler unknownTagsHandler = new UnknownTagsHandler();
+ holder.text.setText(Html.fromHtml(logText, imageCounter, unknownTagsHandler));
+ 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
+ LogImageLoader loader = new LogImageLoader(holder);
+ loader.execute(new String[] { logText });
+ }
}
else {
holder.text.setText(logText);
@@ -2131,6 +2140,28 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return view;
}
+ /** Loads the Log Images outside the ui thread. */
+
+ private class LogImageLoader extends AsyncTask<String, Progress, Spanned>
+ {
+ private LogViewHolder holder;
+
+ public LogImageLoader(LogViewHolder holder) {
+ this.holder = holder;
+ }
+
+ @Override
+ protected Spanned doInBackground(String... logtext) {
+ return Html.fromHtml(logtext[0], new HtmlImage(cache.getGeocode(), false, cache.getListId(), false), null); //, TextView.BufferType.SPANNABLE)
+ }
+
+ @Override
+ protected void onPostExecute(Spanned result) {
+ holder.text.setText(result);
+ }
+
+ }
+
private class LogViewHolder {
final TextView date;
final TextView type;
diff --git a/main/src/cgeo/geocaching/ImageSelectActivity.java b/main/src/cgeo/geocaching/ImageSelectActivity.java
new file mode 100644
index 0000000..9b29c38
--- /dev/null
+++ b/main/src/cgeo/geocaching/ImageSelectActivity.java
@@ -0,0 +1,253 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.compatibility.Compatibility;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class ImageSelectActivity extends AbstractActivity {
+ static final String EXTRAS_CAPTION = "caption";
+ static final String EXTRAS_DESCRIPTION = "description";
+ static final String EXTRAS_URI_AS_STRING = "uri";
+
+ private static final String SAVED_STATE_IMAGE_CAPTION = "cgeo.geocaching.saved_state_image_caption";
+ private static final String SAVED_STATE_IMAGE_DESCRIPTION = "cgeo.geocaching.saved_state_image_description";
+ private static final String SAVED_STATE_IMAGE_URI = "cgeo.geocaching.saved_state_image_uri";
+
+ private static final int SELECT_NEW_IMAGE = 1;
+ private static final int SELECT_STORED_IMAGE = 2;
+
+ private EditText captionView;
+ private EditText descriptionView;
+
+ // Data to be saved while reconfiguring
+ private String imageCaption;
+ private String imageDescription;
+ private Uri imageUri;
+
+ public ImageSelectActivity() {
+ super("c:geo-selectimage");
+ }
+
+ @Override
+ public void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setTheme();
+ setContentView(R.layout.visit_image);
+ setTitle(res.getString(R.string.log_image));
+
+ imageCaption = "";
+ imageDescription = "";
+ imageUri = Uri.EMPTY;
+
+ // Get parameters from intent and basic cache information from database
+ final Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ imageCaption = extras.getString(EXTRAS_CAPTION);
+ imageDescription = extras.getString(EXTRAS_DESCRIPTION);
+ imageUri = Uri.parse(extras.getString(EXTRAS_URI_AS_STRING));
+ }
+
+ // Restore previous state
+ if (savedInstanceState != null) {
+ imageCaption = savedInstanceState.getString(SAVED_STATE_IMAGE_CAPTION);
+ imageDescription = savedInstanceState.getString(SAVED_STATE_IMAGE_DESCRIPTION);
+ imageUri = Uri.parse(savedInstanceState.getString(SAVED_STATE_IMAGE_URI));
+ }
+
+ final Button cameraButton = (Button) findViewById(R.id.camera);
+ cameraButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ selectImageFromCamera();
+ }
+ });
+
+ final Button storedButton = (Button) findViewById(R.id.stored);
+ storedButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ selectImageFromStorage();
+ }
+ });
+
+ captionView = (EditText) findViewById(R.id.caption);
+ if (StringUtils.isNotBlank(imageCaption)) {
+ captionView.setText(imageCaption);
+ }
+
+ descriptionView = (EditText) findViewById(R.id.description);
+ if (StringUtils.isNotBlank(imageDescription)) {
+ descriptionView.setText(imageDescription);
+ }
+
+ final Button saveButton = (Button) findViewById(R.id.save);
+ saveButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ saveImageInfo(true);
+ }
+ });
+
+ final Button clearButton = (Button) findViewById(R.id.cancel);
+ clearButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ saveImageInfo(false);
+ }
+ });
+
+ loadImagePreview();
+ }
+
+ @Override
+ protected void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ syncEditTexts();
+ outState.putString(SAVED_STATE_IMAGE_CAPTION, imageCaption);
+ outState.putString(SAVED_STATE_IMAGE_DESCRIPTION, imageDescription);
+ outState.putString(SAVED_STATE_IMAGE_URI, imageUri != null ? imageUri.getPath() : StringUtils.EMPTY);
+ }
+
+ public void saveImageInfo(boolean saveInfo) {
+ if (saveInfo) {
+ Intent intent = new Intent();
+ syncEditTexts();
+ intent.putExtra(EXTRAS_CAPTION, imageCaption);
+ intent.putExtra(EXTRAS_DESCRIPTION, imageDescription);
+ intent.putExtra(EXTRAS_URI_AS_STRING, imageUri.toString());
+
+ setResult(RESULT_OK, intent);
+ } else {
+ setResult(RESULT_CANCELED);
+ }
+
+ finish();
+ }
+
+ private void syncEditTexts() {
+ imageCaption = captionView.getText().toString();
+ imageDescription = descriptionView.getText().toString();
+ }
+
+ private void selectImageFromCamera() {
+ // create Intent to take a picture and return control to the calling application
+ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ imageUri = getOutputImageFileUri(); // create a file to save the image
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); // set the image file name
+
+ // start the image capture Intent
+ startActivityForResult(intent, SELECT_NEW_IMAGE);
+ }
+
+ private void selectImageFromStorage() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("image/jpeg");
+
+ startActivityForResult(Intent.createChooser(intent, "Select Image"), SELECT_STORED_IMAGE);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_CANCELED) {
+ // User cancelled the image capture
+ showToast(getResources().getString(R.string.info_select_logimage_cancelled));
+ return;
+ }
+
+ if (resultCode == RESULT_OK) {
+ if (data != null) {
+ Uri selectedImage = data.getData();
+ String[] filePathColumn = { MediaColumns.DATA };
+
+ Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
+ cursor.moveToFirst();
+
+ int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
+ String filePath = cursor.getString(columnIndex);
+ imageUri = Uri.parse(filePath);
+ cursor.close();
+
+ Log.d("SELECT IMAGE data = " + data.toString());
+ } else {
+ Log.d("SELECT IMAGE data is null");
+ }
+
+ if (requestCode == SELECT_NEW_IMAGE) {
+ showToast(getResources().getString(R.string.info_stored_image) + "\n" + imageUri);
+ }
+ } else {
+ // Image capture failed, advise user
+ showToast(getResources().getString(R.string.err_aquire_image_failed));
+ return;
+ }
+
+ loadImagePreview();
+ }
+
+ private void loadImagePreview()
+ {
+ if (!new File(imageUri.getPath()).exists()) {
+ Log.i("Image does not exist");
+ return;
+ }
+
+ final ImageView imagePreview = (ImageView) findViewById(R.id.image_preview);
+ BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
+ bitmapOptions.inSampleSize = 8;
+ final Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath(), bitmapOptions);
+ imagePreview.setImageBitmap(bitmap);
+ imagePreview.setVisibility(View.VISIBLE);
+ }
+
+ private static Uri getOutputImageFileUri() {
+ return Uri.fromFile(getOutputImageFile());
+ }
+
+ /** Create a File for saving an image or video */
+ private static File getOutputImageFile() {
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+
+ File mediaStorageDir = new File(Compatibility.getExternalPictureDir(), "cgeo");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (!mediaStorageDir.exists()) {
+ if (!mediaStorageDir.mkdirs()) {
+ Log.w("Failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
+ return new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
+ }
+}
diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java
index d77be5f..43c439b 100644
--- a/main/src/cgeo/geocaching/VisitCacheActivity.java
+++ b/main/src/cgeo/geocaching/VisitCacheActivity.java
@@ -18,6 +18,7 @@ import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@@ -26,6 +27,7 @@ import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -57,6 +59,11 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private static final String SAVED_STATE_RATING = "cgeo.geocaching.saved_state_rating";
private static final String SAVED_STATE_TYPE = "cgeo.geocaching.saved_state_type";
private static final String SAVED_STATE_DATE = "cgeo.geocaching.saved_state_date";
+ private static final String SAVED_STATE_IMAGE_CAPTION = "cgeo.geocaching.saved_state_image_caption";
+ private static final String SAVED_STATE_IMAGE_DESCRIPTION = "cgeo.geocaching.saved_state_image_description";
+ private static final String SAVED_STATE_IMAGE_URI = "cgeo.geocaching.saved_state_image_uri";
+
+ private static final int SELECT_IMAGE = 101;
private LayoutInflater inflater = null;
private Geocache cache = null;
@@ -77,6 +84,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private double rating;
private LogType typeSelected;
private Calendar date;
+ private String imageCaption;
+ private String imageDescription;
+ private Uri imageUri;
@Override
public Loader<String> onCreateLoader(final int id, final Bundle args) {
@@ -297,6 +307,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
rating = savedInstanceState.getDouble(SAVED_STATE_RATING);
typeSelected = LogType.getById(savedInstanceState.getInt(SAVED_STATE_TYPE));
date.setTimeInMillis(savedInstanceState.getLong(SAVED_STATE_DATE));
+ imageCaption = savedInstanceState.getString(SAVED_STATE_IMAGE_CAPTION);
+ imageDescription = savedInstanceState.getString(SAVED_STATE_IMAGE_DESCRIPTION);
+ imageUri = Uri.parse(savedInstanceState.getString(SAVED_STATE_IMAGE_URI));
} else {
// If log had been previously saved, load it now, otherwise initialize signature as needed
final LogEntry log = cgData.loadLogOffline(geocode);
@@ -311,6 +324,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
}
updatePostButtonText();
+ setImageButtonText();
enablePostButton(false);
final Button typeButton = (Button) findViewById(R.id.type);
@@ -334,6 +348,15 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
tweetCheck.setChecked(true);
+ final Button imageButton = (Button) findViewById(R.id.image_btn);
+ imageButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ selectImage();
+ }
+ });
+
final Button saveButton = (Button) findViewById(R.id.save);
saveButton.setOnClickListener(new View.OnClickListener() {
@@ -374,6 +397,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
}
text = null;
+ imageCaption = "";
+ imageDescription = "";
+ imageUri = Uri.EMPTY;
}
private void clearLog() {
@@ -387,6 +413,8 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
final EditText logView = (EditText) findViewById(R.id.log);
logView.setText(StringUtils.EMPTY);
+ setImageButtonText();
+
showToast(res.getString(R.string.info_log_cleared));
}
@@ -454,6 +482,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
outState.putDouble(SAVED_STATE_RATING, rating);
outState.putInt(SAVED_STATE_TYPE, typeSelected.id);
outState.putLong(SAVED_STATE_DATE, date.getTimeInMillis());
+ outState.putString(SAVED_STATE_IMAGE_URI, imageUri.getPath());
+ outState.putString(SAVED_STATE_IMAGE_CAPTION, imageCaption);
+ outState.putString(SAVED_STATE_IMAGE_DESCRIPTION, imageDescription);
}
@Override
@@ -497,7 +528,8 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private class PostListener implements View.OnClickListener {
@Override
public void onClick(View arg0) {
- waitDialog = ProgressDialog.show(VisitCacheActivity.this, null, res.getString(R.string.log_saving), true);
+ waitDialog = ProgressDialog.show(VisitCacheActivity.this, null,
+ res.getString(StringUtils.isBlank(imageUri.getPath()) ? R.string.log_saving : R.string.log_saving_and_uploading), true);
waitDialog.setCancelable(true);
final Thread thread = new PostLogThread(postLogHandler, currentLogText());
@@ -524,38 +556,48 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
public StatusCode postLogFn(String log) {
+
+ StatusCode result = StatusCode.LOG_POST_ERROR;
+
try {
- final StatusCode status = GCParser.postLog(geocode, cacheid, viewstates, typeSelected,
+
+ final ImmutablePair<StatusCode, String> logResult = GCParser.postLog(geocode, cacheid, viewstates, typeSelected,
date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE),
log, trackables);
- if (status == StatusCode.NO_ERROR) {
+ result = logResult.left;
+
+ if (logResult.left == StatusCode.NO_ERROR) {
final LogEntry logNow = new LogEntry(date, typeSelected, log);
cache.getLogs().add(0, logNow);
- if (typeSelected == LogType.FOUND_IT) {
+ if (typeSelected == LogType.FOUND_IT || typeSelected == LogType.ATTENDED) {
cache.setFound(true);
}
cgData.saveChangedCache(cache);
}
- if (status == StatusCode.NO_ERROR) {
+ if (logResult.left == StatusCode.NO_ERROR) {
cgData.clearLogOffline(geocode);
}
- if (status == StatusCode.NO_ERROR && typeSelected == LogType.FOUND_IT && Settings.isUseTwitter()
+ if (logResult.left == StatusCode.NO_ERROR && typeSelected == LogType.FOUND_IT && Settings.isUseTwitter()
&& Settings.isTwitterLoginValid()
&& tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE) {
Twitter.postTweetCache(geocode);
}
- if (status == StatusCode.NO_ERROR && typeSelected == LogType.FOUND_IT && Settings.isGCvoteLogin()) {
+ if (logResult.left == StatusCode.NO_ERROR && typeSelected == LogType.FOUND_IT && Settings.isGCvoteLogin()) {
GCVote.setRating(cache, rating);
}
- return status;
+ if (logResult.left == StatusCode.NO_ERROR && StringUtils.isNotBlank(imageUri.getPath())) {
+ result = GCParser.uploadLogImage(logResult.right, imageCaption, imageDescription, imageUri);
+ }
+
+ return result;
} catch (Exception e) {
Log.e("cgeovisit.postLogFn", e);
}
@@ -651,4 +693,34 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
alert.create().show();
}
+ private void selectImage() {
+ Intent selectImageIntent = new Intent(this, ImageSelectActivity.class);
+ selectImageIntent.putExtra(ImageSelectActivity.EXTRAS_CAPTION, imageCaption);
+ selectImageIntent.putExtra(ImageSelectActivity.EXTRAS_DESCRIPTION, imageDescription);
+ selectImageIntent.putExtra(ImageSelectActivity.EXTRAS_URI_AS_STRING, imageUri.toString());
+
+ startActivityForResult(selectImageIntent, SELECT_IMAGE);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == SELECT_IMAGE) {
+ if (resultCode == RESULT_OK) {
+ imageCaption = data.getStringExtra(ImageSelectActivity.EXTRAS_CAPTION);
+ imageDescription = data.getStringExtra(ImageSelectActivity.EXTRAS_DESCRIPTION);
+ imageUri = Uri.parse(data.getStringExtra(ImageSelectActivity.EXTRAS_URI_AS_STRING));
+ } else if (resultCode != RESULT_CANCELED) {
+ // Image capture failed, advise user
+ showToast(getResources().getString(R.string.err_select_logimage_failed));
+ }
+ setImageButtonText();
+
+ }
+ }
+
+ private void setImageButtonText() {
+ final Button imageButton = (Button) findViewById(R.id.image_btn);
+ imageButton.setText(StringUtils.isNotBlank(imageUri.getPath()) ?
+ res.getString(R.string.log_image_edit) : res.getString(R.string.log_image_attach));
+ }
}
diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
index a388adb..e250934 100644
--- a/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
+++ b/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
@@ -5,9 +5,12 @@ import cgeo.geocaching.utils.Log;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.backup.BackupManager;
+import android.os.Environment;
import android.view.Display;
import android.view.Surface;
+import java.io.File;
+
@TargetApi(8)
public class AndroidLevel8 implements AndroidLevel8Interface {
@@ -41,4 +44,10 @@ public class AndroidLevel8 implements AndroidLevel8Interface {
return 0;
}
+
+ @Override
+ public File getExternalPictureDir() {
+ return Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES);
+ }
}
diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel8Emulation.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel8Emulation.java
index 197993d..996c527 100644
--- a/main/src/cgeo/geocaching/compatibility/AndroidLevel8Emulation.java
+++ b/main/src/cgeo/geocaching/compatibility/AndroidLevel8Emulation.java
@@ -3,8 +3,11 @@ package cgeo.geocaching.compatibility;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.Configuration;
+import android.os.Environment;
import android.view.Display;
+import java.io.File;
+
@TargetApi(value = 7)
public class AndroidLevel8Emulation implements AndroidLevel8Interface {
@@ -27,4 +30,10 @@ public class AndroidLevel8Emulation implements AndroidLevel8Interface {
}
return 0;
}
+
+ @Override
+ public File getExternalPictureDir() {
+ // Use externalStorage/Pictures as default
+ return new File(Environment.getExternalStorageDirectory(), "Pictures");
+ }
}
diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel8Interface.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel8Interface.java
index 761c23a..75998aa 100644
--- a/main/src/cgeo/geocaching/compatibility/AndroidLevel8Interface.java
+++ b/main/src/cgeo/geocaching/compatibility/AndroidLevel8Interface.java
@@ -2,9 +2,13 @@ package cgeo.geocaching.compatibility;
import android.app.Activity;
+import java.io.File;
+
public interface AndroidLevel8Interface {
public int getRotation(final Activity activity);
public void dataChanged(final String name);
public int getRotationOffset(final Activity activity);
+
+ public File getExternalPictureDir();
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/compatibility/Compatibility.java b/main/src/cgeo/geocaching/compatibility/Compatibility.java
index 05a3331..d846bda 100644
--- a/main/src/cgeo/geocaching/compatibility/Compatibility.java
+++ b/main/src/cgeo/geocaching/compatibility/Compatibility.java
@@ -13,6 +13,8 @@ import android.os.Build;
import android.text.InputType;
import android.widget.EditText;
+import java.io.File;
+
public final class Compatibility {
private final static int sdkVersion = Build.VERSION.SDK_INT;
@@ -108,4 +110,8 @@ public final class Compatibility {
return level13.getDisplaySize();
}
+ public static File getExternalPictureDir() {
+ return level8.getExternalPictureDir();
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
index 8a4a741..f678797 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
@@ -32,7 +32,7 @@ public final class GCConstants {
public final static Pattern PATTERN_CACHEID = Pattern.compile("/seek/log\\.aspx\\?ID=(\\d+)");
public final static Pattern PATTERN_GUID = Pattern.compile(Pattern.quote("&wid=") + "([0-9a-z\\-]+)" + Pattern.quote("&"));
public final static Pattern PATTERN_SIZE = Pattern.compile("<div id=\"ctl00_ContentBody_size\" class=\"CacheSize[^\"]*\">[^<]*<p[^>]*>[^S]*Size[^:]*:[^<]*<span[^>]*>[^<]*<img src=\"[^\"]*/icons/container/[a-z_]+\\.gif\" alt=\"\\w+: ([^\"]+)\"[^>]*>[^<]*<small>[^<]*</small>[^<]*</span>[^<]*</p>");
- public final static Pattern PATTERN_LATLON = Pattern.compile("<span id=\"uxLatLon\" style=\"font-weight:bold;\"[^>]*>(.*?)</span>");
+ public final static Pattern PATTERN_LATLON = Pattern.compile("<span id=\"uxLatLon\"[^>]*>(.*?)</span>");
public final static Pattern PATTERN_LATLON_ORIG = Pattern.compile("\\{\"isUserDefined\":true[^}]+?\"oldLatLngDisplay\":\"([^\"]+)\"\\}");
public final static Pattern PATTERN_LOCATION = Pattern.compile(Pattern.quote("<span id=\"ctl00_ContentBody_Location\">In ") + "(?:<a href=[^>]*>)?(.*?)<");
public final static Pattern PATTERN_PERSONALNOTE = Pattern.compile("<p id=\"cache_note\"[^>]*>(.*?)</p>");
@@ -70,7 +70,7 @@ public final class GCConstants {
/** Use replaceAll("[,.]","") on the resulting string before converting to an int */
public static final Pattern PATTERN_CACHES_FOUND = Pattern.compile("<strong[^>]*>.*?([\\d,.]+) Caches Found");
public static final Pattern PATTERN_AVATAR_IMAGE_PROFILE_PAGE = Pattern.compile("<img src=\"(http://img.geocaching.com/user/avatar/[0-9a-f-]+\\.jpg)\"[^>]*\\salt=\"Avatar\"");
- public static final Pattern PATTERN_LOGIN_NAME_LOGIN_PAGE = Pattern.compile("<h4>Success:</h4> <p>You are logged in as[^<]*<strong><span id=\"ctl00_ContentBody_lbUsername\"[^>]*>([^<]+)[^<]*</span>");
+ public static final Pattern PATTERN_LOGIN_NAME_LOGIN_PAGE = Pattern.compile("ctl00_ContentBody_lbUsername\">.*<strong>(.*)</strong>");
public static final Pattern PATTERN_CUSTOMDATE = Pattern.compile("<option selected=\"selected\" value=\"([ /Mdy-]+)\">");
/**
@@ -149,6 +149,7 @@ public final class GCConstants {
public final static Pattern PATTERN_MAINTENANCE = Pattern.compile("<span id=\"ctl00_ContentBody_LogBookPanel1_lbConfirm\"[^>]*>([^<]*<font[^>]*>)?([^<]+)(</font>[^<]*)?</span>", Pattern.CASE_INSENSITIVE);
public final static Pattern PATTERN_OK1 = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_lbHeading\"[^>]*>[^<]*</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_OK2 = Pattern.compile("<div id=[\"|']ctl00_ContentBody_LogBookPanel1_ViewLogPanel[\"|']>", Pattern.CASE_INSENSITIVE);
+ public final static Pattern PATTERN_OK_IMAGEUPLOAD = Pattern.compile("<div id=[\"|']ctl00_ContentBody_ImageUploadControl1_uxUploadDonePanel[\"|']>", Pattern.CASE_INSENSITIVE);
public final static Pattern PATTERN_VIEWSTATEFIELDCOUNT = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_VIEWSTATES = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_USERTOKEN = Pattern.compile("userToken\\s*=\\s*'([^']+)'");
@@ -163,6 +164,8 @@ public final class GCConstants {
public final static Pattern PATTERN_USERSESSION = Pattern.compile("UserSession\\('([^']+)'");
public final static Pattern PATTERN_SESSIONTOKEN = Pattern.compile("sessionToken:'([^']+)'");
+ public final static Pattern PATTERN_LOG_IMAGE_UPLOAD = Pattern.compile("/seek/upload\\.aspx\\?LID=(\\d+)", Pattern.CASE_INSENSITIVE);
+
public final static String STRING_PREMIUMONLY_2 = "Sorry, the owner of this listing has made it viewable to Premium Members only.";
public final static String STRING_PREMIUMONLY_1 = "has chosen to make this cache listing visible to Premium Members only.";
public final static String STRING_UNPUBLISHED_OWNER = "cache has not been published yet";
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 5481b0c..494e040 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -29,6 +29,7 @@ import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.DirectionImage;
import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.HtmlUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.MatcherWrapper;
@@ -38,6 +39,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -45,6 +47,7 @@ import org.json.JSONObject;
import android.net.Uri;
import android.text.Html;
+import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -912,36 +915,20 @@ public abstract class GCParser {
return trackable;
}
- public static StatusCode postLog(final String geocode, final String cacheid, final String[] viewstates,
+ public static ImmutablePair<StatusCode, String> postLog(final String geocode, final String cacheid, final String[] viewstates,
final LogType logType, final int year, final int month, final int day,
final String log, final List<TrackableLog> trackables) {
if (Login.isEmpty(viewstates)) {
Log.e("GCParser.postLog: No viewstate given");
- return StatusCode.LOG_POST_ERROR;
+ return new ImmutablePair<StatusCode, String>(StatusCode.LOG_POST_ERROR, "");
}
if (StringUtils.isBlank(log)) {
Log.e("GCParser.postLog: No log text given");
- return StatusCode.NO_LOG_TEXT;
+ return new ImmutablePair<StatusCode, String>(StatusCode.NO_LOG_TEXT, "");
}
- // fix log (non-Latin characters converted to HTML entities)
- final int logLen = log.length();
- final StringBuilder logUpdated = new StringBuilder();
-
- for (int i = 0; i < logLen; i++) {
- char c = log.charAt(i);
-
- if (c > 300) {
- logUpdated.append("&#");
- logUpdated.append(Integer.toString(c));
- logUpdated.append(';');
- } else {
- logUpdated.append(c);
- }
- }
-
- final String logInfo = logUpdated.toString().replace("\n", "\r\n").trim(); // windows' eol and remove leading and trailing whitespaces
+ final String logInfo = HtmlUtils.convertNonLatinCharactersToHTML(log).replace("\n", "\r\n").trim(); // windows' eol and remove leading and trailing whitespaces
if (trackables != null) {
Log.i("Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + logInfo + "; trackables: " + trackables.size());
@@ -981,7 +968,7 @@ public abstract class GCParser {
String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
Log.e("GCParser.postLogTrackable: Can not log in geocaching");
- return StatusCode.NOT_LOGGED_IN;
+ return new ImmutablePair<StatusCode, String>(StatusCode.NOT_LOGGED_IN, "");
}
// maintenance, archived needs to be confirmed
@@ -994,7 +981,7 @@ public abstract class GCParser {
if (Login.isEmpty(viewstatesConfirm)) {
Log.e("GCParser.postLog: No viewstate for confirm log");
- return StatusCode.LOG_POST_ERROR;
+ return new ImmutablePair<StatusCode, String>(StatusCode.LOG_POST_ERROR, "");
}
params.clear();
@@ -1048,14 +1035,72 @@ public abstract class GCParser {
if (Login.getActualCachesFound() >= 0) {
Login.setActualCachesFound(Login.getActualCachesFound() + 1);
}
- return StatusCode.NO_ERROR;
+
+ final String logID = BaseUtils.getMatch(page, GCConstants.PATTERN_LOG_IMAGE_UPLOAD, "");
+
+ return new ImmutablePair<StatusCode, String>(StatusCode.NO_ERROR, logID);
}
} catch (Exception e) {
Log.e("GCParser.postLog.check", e);
}
Log.e("GCParser.postLog: Failed to post log because of unknown error");
- return StatusCode.LOG_POST_ERROR;
+ return new ImmutablePair<StatusCode, String>(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ /**
+ * Upload an image to a log that has already been posted
+ *
+ * @param logId
+ * the ID of the log to upload the image to. Found on page returned when log is uploaded
+ * @param caption
+ * of the image; max 50 chars
+ * @param description
+ * of the image; max 250 chars
+ * @param imageUri
+ * the URI for the image to be uploaded
+ * @return status code to indicate success or failure
+ */
+ public static StatusCode uploadLogImage(final String logId, final String caption, final String description, final Uri imageUri)
+ {
+ final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/upload.aspx").encodedQuery("LID=" + logId).build().toString();
+
+ String page = Network.getResponseData(Network.getRequest(uri));
+
+ if (!Login.getLoginStatus(page)) {
+ // Login.isActualLoginStatus() was wrong, we are not logged in
+ final StatusCode loginState = Login.login();
+ if (loginState == StatusCode.NO_ERROR) {
+ page = Network.getResponseData(Network.getRequest(uri));
+ } else {
+ Log.e("Image upload: No login (error: " + loginState + ')');
+ return StatusCode.NOT_LOGGED_IN;
+ }
+ }
+
+ final String[] viewstates = Login.getViewstates(page);
+
+ final Parameters uploadParams = new Parameters(
+ "__EVENTTARGET", "",
+ "__EVENTARGUMENT", "",
+ "ctl00$ContentBody$ImageUploadControl1$uxFileCaption", HtmlUtils.convertNonLatinCharactersToHTML(caption),
+ "ctl00$ContentBody$ImageUploadControl1$uxFileDesc", HtmlUtils.convertNonLatinCharactersToHTML(description),
+ "ctl00$ContentBody$ImageUploadControl1$uxUpload", "Upload");
+ Login.putViewstates(uploadParams, viewstates);
+
+ final File image = new File(imageUri.getPath());
+ final String response = Network.getResponseData(Network.postRequest(uri, uploadParams, "ctl00$ContentBody$ImageUploadControl1$uxFileUpload", "image/jpeg", image));
+
+ MatcherWrapper matcherOK = new MatcherWrapper(GCConstants.PATTERN_OK_IMAGEUPLOAD, response);
+
+ if (matcherOK.find()) {
+ Log.i("Logimage successfully uploaded.");
+
+ return StatusCode.NO_ERROR;
+ }
+ Log.e("GCParser.uploadLogIMage: Failed to upload image because of unknown error");
+
+ return StatusCode.LOGIMAGE_POST_ERROR;
}
public static StatusCode postLogTrackable(final String tbid, final String trackingCode, final String[] viewstates,
@@ -1072,7 +1117,7 @@ public abstract class GCParser {
Log.i("Trying to post log for trackable #" + trackingCode + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log);
- final String logInfo = log.replace("\n", "\r\n"); // windows' eol
+ final String logInfo = HtmlUtils.convertNonLatinCharactersToHTML(log).replace("\n", "\r\n"); // windows' eol
final Calendar currentDate = Calendar.getInstance();
final Parameters params = new Parameters(
diff --git a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java
index 678654f..43fdcfc 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java
@@ -9,6 +9,7 @@ import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.lang3.StringUtils;
@@ -57,4 +58,10 @@ public class OCXMLApiConnector extends OCConnector implements ISearchByGeocode,
return StringUtils.equalsIgnoreCase(cache.getOwnerDisplayName(), Settings.getOCConnectorUserName());
}
+ @Override
+ public String getLicenseText(Geocache cache) {
+ // not to be translated
+ return "© " + cache.getOwnerDisplayName() + ", " + "<a href=\"" + getCacheUrl(cache) + "\">www.opencaching.de</a>, CC-BY-NC-ND, Stand: " + Formatter.formatFullDate(cache.getUpdated());
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index dbcfea5..0673605 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -297,8 +297,18 @@ final public class OkapiClient {
return null;
}
- final String uri = "http://" + host + service;
((OCApiConnector) connector).addAuthentication(params);
+ params.add("langpref", getPreferredLanguage());
+
+ final String uri = "http://" + host + service;
return Network.requestJSON(uri, params);
}
+
+ private static String getPreferredLanguage() {
+ final String code = Locale.getDefault().getCountry();
+ if (StringUtils.isNotBlank(code)) {
+ return StringUtils.lowerCase(code) + "|en";
+ }
+ return "en";
+ }
}
diff --git a/main/src/cgeo/geocaching/enumerations/StatusCode.java b/main/src/cgeo/geocaching/enumerations/StatusCode.java
index dc62225..102b9e9 100644
--- a/main/src/cgeo/geocaching/enumerations/StatusCode.java
+++ b/main/src/cgeo/geocaching/enumerations/StatusCode.java
@@ -23,7 +23,8 @@ public enum StatusCode {
LOG_POST_ERROR(R.string.err_log_post_failed),
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);
+ NOT_LOGGED_IN(R.string.init_login_popup_failed),
+ LOGIMAGE_POST_ERROR(R.string.err_logimage_post_failed);
final private int error_string;
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 476d523..7a59e5b 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -1101,6 +1101,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
downloaded = true;
Set<Geocache> cachesFromSearchResult = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS);
// update the caches
+ // new collection type needs to remove first
+ caches.removeAll(cachesFromSearchResult);
caches.addAll(cachesFromSearchResult);
final boolean excludeMine = Settings.isExcludeMyCaches();
@@ -1195,6 +1197,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (searchResult != null) {
Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
// update the caches
+ // new collection type needs to remove first
+ caches.removeAll(result);
caches.addAll(result);
lastSearchResult = searchResult;
}
diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java
index 5c4148f..a4155be 100644
--- a/main/src/cgeo/geocaching/network/Network.java
+++ b/main/src/cgeo/geocaching/network/Network.java
@@ -291,9 +291,9 @@ public abstract class Network {
final String timeSpan = Network.formatTimeSpan(before);
final String tries = (i + 1) + "/" + (Network.NB_DOWNLOAD_RETRIES + 1);
if (i == Network.NB_DOWNLOAD_RETRIES) {
- Log.e("Failure " + tries + timeSpan + reqLogStr, e);
+ Log.w("Failure " + tries + timeSpan + reqLogStr + " (" + e.toString() + ")");
} else {
- Log.e("Failure " + tries + " (" + e.toString() + ")" + timeSpan + "- retrying " + reqLogStr);
+ Log.w("Failure " + tries + " (" + e.toString() + ")" + timeSpan + "- retrying " + reqLogStr);
}
}
}
diff --git a/main/src/cgeo/geocaching/network/Parameters.java b/main/src/cgeo/geocaching/network/Parameters.java
index 74f5531..f035c4a 100644
--- a/main/src/cgeo/geocaching/network/Parameters.java
+++ b/main/src/cgeo/geocaching/network/Parameters.java
@@ -104,4 +104,8 @@ public class Parameters extends ArrayList<NameValuePair> {
return params;
}
+ public void add(final String key, final String value) {
+ put(key, value);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
index 412649a..fff26c6 100644
--- a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
+++ b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
@@ -5,8 +5,8 @@ import cgeo.geocaching.Geocache;
import org.apache.commons.lang3.StringUtils;
/**
- * sorts caches by GC code, therefore effectively sorting by cache age
- *
+ * sorts caches by geo code, therefore effectively sorting by cache age
+ *
*/
public class GeocodeComparator extends AbstractCacheComparator {
diff --git a/main/src/cgeo/geocaching/utils/HtmlUtils.java b/main/src/cgeo/geocaching/utils/HtmlUtils.java
index a54ba57..30aa19b 100644
--- a/main/src/cgeo/geocaching/utils/HtmlUtils.java
+++ b/main/src/cgeo/geocaching/utils/HtmlUtils.java
@@ -53,4 +53,29 @@ public class HtmlUtils {
return StringUtils.replace(result, "<br />", "\n").trim();
}
+ /**
+ * Convert any non-Latin characters into HTML unicode entities
+ *
+ * @param input
+ * String
+ * @return output String
+ */
+ public static String convertNonLatinCharactersToHTML(final String input) {
+ final int inputLen = input.length();
+ final StringBuilder output = new StringBuilder();
+
+ for (int i = 0; i < inputLen; i++) {
+ char c = input.charAt(i);
+
+ if (c > 300) {
+ output.append("&#");
+ output.append(Integer.toString(c));
+ output.append(';');
+ } else {
+ output.append(c);
+ }
+ }
+
+ return output.toString();
+ }
}
diff --git a/tests/src/cgeo/geocaching/SettingsTest.java b/tests/src/cgeo/geocaching/SettingsTest.java
index f113180..cedf777 100644
--- a/tests/src/cgeo/geocaching/SettingsTest.java
+++ b/tests/src/cgeo/geocaching/SettingsTest.java
@@ -32,4 +32,9 @@ public class SettingsTest extends ActivityInstrumentationTestCase2<cgeo> {
public static void testSettings() {
assertEquals(GCConstants.MEMBER_STATUS_PM, Settings.getMemberStatus());
}
+
+ public static void testDeviceHasNormalLogin() {
+ // if the unit tests were interrupted in a previous run, the device might still have the "temporary" login data from the last tests
+ assertFalse("c:geo".equals(Settings.getUsername()));
+ }
}
diff --git a/tests/src/cgeo/geocaching/utils/HtmlUtilsTest.java b/tests/src/cgeo/geocaching/utils/HtmlUtilsTest.java
new file mode 100644
index 0000000..092e45e
--- /dev/null
+++ b/tests/src/cgeo/geocaching/utils/HtmlUtilsTest.java
@@ -0,0 +1,11 @@
+package cgeo.geocaching.utils;
+
+import junit.framework.TestCase;
+
+public class HtmlUtilsTest extends TestCase {
+
+ public static void testNonLatinCharConv() {
+ String res = HtmlUtils.convertNonLatinCharactersToHTML("abcΦςቡぢれ");
+ assertEquals("abc&#934;&#962;&#4705;&#12386;&#12428;", res);
+ }
+}