diff options
Diffstat (limited to 'main')
352 files changed, 6708 insertions, 5258 deletions
diff --git a/main/.factorypath b/main/.factorypath index 0ba9bff..d19855f 100644 --- a/main/.factorypath +++ b/main/.factorypath @@ -1,4 +1,4 @@ <factorypath> - <factorypathentry kind="WKSPJAR" id="/cgeo/libs/butterknife-5.0.0.jar" enabled="true" runInBatchMode="false"/> + <factorypathentry kind="WKSPJAR" id="/cgeo/libs/butterknife-5.1.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="WKSPJAR" id="/cgeo/compile-libs/androidannotations-3.0.1.jar" enabled="true" runInBatchMode="false"/> </factorypath> diff --git a/main/.settings/org.eclipse.jdt.ui.prefs b/main/.settings/org.eclipse.jdt.ui.prefs index a80d8c1..5c339b3 100644 --- a/main/.settings/org.eclipse.jdt.ui.prefs +++ b/main/.settings/org.eclipse.jdt.ui.prefs @@ -27,11 +27,11 @@ sp_cleanup.convert_to_enhanced_for_loop=false sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=true -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=true +sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false +sp_cleanup.make_variable_declarations_final=true sp_cleanup.never_use_blocks=false sp_cleanup.never_use_parentheses_in_expressions=true sp_cleanup.on_save_use_additional_actions=true diff --git a/main/AndroidManifest.xml b/main/AndroidManifest.xml index 7836d07..2cdbc2c 100644 --- a/main/AndroidManifest.xml +++ b/main/AndroidManifest.xml @@ -7,13 +7,14 @@ <uses-sdk android:minSdkVersion="9" - android:targetSdkVersion="9" /> + android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <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-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.camera" @@ -21,6 +22,9 @@ <uses-feature android:name="android.hardware.screen.portrait" android:required="false" /> + <uses-feature + android:name="android.hardware.nfc" + android:required="false" /> <supports-screens android:anyDensity="true" @@ -79,12 +83,16 @@ android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:launchMode="singleTop" + android:parentActivityName="cgeo.geocaching.MainActivity" android:windowSoftInputMode="stateHidden" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> + <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> @@ -99,13 +107,21 @@ android:name=".AboutActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/about" + android:parentActivityName="cgeo.geocaching.MainActivity" android:windowSoftInputMode="stateHidden" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> </activity> <activity android:name=".UsefulAppsActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/helpers" + android:parentActivityName="cgeo.geocaching.MainActivity" android:windowSoftInputMode="stateHidden" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> </activity> <activity android:name=".twitter.TwitterAuthorizationActivity" @@ -134,24 +150,40 @@ android:name=".NavigateAnyPointActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/search_destination" + android:parentActivityName="cgeo.geocaching.MainActivity" android:windowSoftInputMode="stateHidden" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> </activity> <activity android:name=".AddressListActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/search_address_result" + android:parentActivityName="cgeo.geocaching.SearchActivity" android:windowSoftInputMode="stateHidden" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.SearchActivity" /> </activity> <activity android:name=".settings.SettingsActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/settings_titlebar" + android:parentActivityName="cgeo.geocaching.MainActivity" android:theme="@style/settings" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> </activity> <activity android:name=".CacheListActivity" android:configChanges="keyboardHidden|orientation|screenSize" - android:label="@string/app_name" > + android:label="@string/app_name" + android:parentActivityName="cgeo.geocaching.MainActivity" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.MainActivity" /> <!-- intent filter for local gpx files --> <intent-filter> @@ -420,9 +452,12 @@ <activity android:name=".SelectMapfileActivity" android:configChanges="keyboardHidden|orientation" - android:label="@string/map_file_select_title" > + android:label="@string/map_file_select_title" + android:parentActivityName="cgeo.geocaching.settings.SettingsActivity" > + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="cgeo.geocaching.settings.SettingsActivity" /> </activity> - <activity android:name="WaypointPopup" android:configChanges="keyboardHidden|orientation" @@ -464,7 +499,8 @@ </activity> <activity android:name=".CreateShortcutActivity" - android:label="@string/cgeo_shortcut" > + android:label="@string/cgeo_shortcut" + android:parentActivityName="cgeo.geocaching.MainActivity" > <intent-filter> <action android:name="android.intent.action.CREATE_SHORTCUT" /> @@ -472,6 +508,12 @@ </intent-filter> </activity> + <activity android:name=".activity.SimpleWebviewActivity" + android:label="c:geo internal browser" + android:icon="@drawable/ic_launcher_browser"> + + </activity> + <!-- provide enhanced meta data for caches (and waypoints) when invoking Locus from c:geo --> <provider android:name=".apps.LocusDataStorageProvider" diff --git a/main/build.gradle b/main/build.gradle new file mode 100644 index 0000000..ae8877b --- /dev/null +++ b/main/build.gradle @@ -0,0 +1,355 @@ +apply plugin: 'android' +apply plugin: 'android-apt' +apply plugin: 'findbugs' + +/* +Before use unit test : +Replace all custom namepace with xmlns:cgeo="http://schemas.android.com/apk/res-auto" + + +Usage : + +check dependencies : +gradle dependencies main:dependencies + +build & test: +gradle clean assembleDebug connectedAndroidTest + +debug: +gradle connectedAndroidTest --debug --stacktrace + +for CI? : +gradle deviceCheck +gradle connectedCheck + + */ +//Testing guide : http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Testing +//https://github.com/stephanenicolas/Quality-Tools-for-Android + +def AAVersion = '3.0.1' +def RXVersion = '0.19.0' +group = 'cgeo.geocaching' +version = '0.0.1' + +android { + compileSdkVersion "Google Inc.:Google APIs:19" + //compileSdkVersion 19 + buildToolsVersion "19.1.0" + + def Properties versionProps = new Properties() + versionProps.load(new FileInputStream(file('version.properties'))) + + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + } + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 19 + versionName versionProps['name'] + versionCode versionProps['code'].toInteger() + + // NOTE: must match the package in the test directory and must be different from the app package + testApplicationId "cgeo.geocaching.test" + + // standard android test runner + //testInstrumentationRunner "android.test.InstrumentationTestRunner" + testInstrumentationRunner "com.zutubi.android.junitreport.JUnitReportTestRunner" + + //testHandlingProfiling true + testFunctionalTest true + } + + //Conditional signing + //Uncomment and set the 4 key properties (#key.store, ...) in gradle.properties + signingConfigs { + release + } + + + buildTypes { + debug { + //packageNameSuffix ".debug" + //zipAlign = true + debuggable true + runProguard false + proguardFiles getDefaultProguardFile('proguard-android.txt'), '../tests/proguard.cfg' + versionNameSuffix " Debug " + versionProps['betaNumber'] + } + release { + debuggable true + runProguard true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' + signingConfig signingConfigs.release + } + } + + testBuildType "debug" //the default BuildType + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + //java.srcDirs = ['src', 'thirdparty', 'annotation_gen'] + java.srcDirs = ['src', 'thirdparty'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + } + //new instrumentTest name + androidTest.setRoot('../tests') + androidTest{ + manifest.srcFile '../tests/AndroidManifest.xml' + java.srcDirs = ['../tests/java'] + res.srcDirs = ['../tests/res', 'res'] + resources.srcDirs = ['../tests/res', 'res'] + } + } + testOptions { + resultsDir = "$project.buildDir/build/test-results" + } + + lintOptions { + //checkReleaseBuilds false + // Or, if you prefer, you can continue to check for errors in release builds, + // but continue the build even when errors are found: + abortOnError false + } + +} + +if (project.hasProperty('key.store') && + project.hasProperty('key.store.password') && + project.hasProperty('key.alias.password')) { + android.signingConfigs.release.storeFile = file(project.property('key.store')) + android.signingConfigs.release.storePassword = property('key.store.password') + android.signingConfigs.release.keyPassword = property('key.alias.password') + android.signingConfigs.release.keyAlias = property('key.alias') +} else { + android.buildTypes.release.signingConfig = null +} + +dependencies { + apt( "org.androidannotations:androidannotations:$AAVersion"){ + exclude module:'androidannotations-api' + } + compile "org.androidannotations:androidannotations-api:$AAVersion" + + compile project(":mapswithme-api") + + compile files('libs/httpclientandroidlib-1.1.2.jar') + compile files('libs/locus-api-4.0.jar') + //https://mapsforge.googlecode.com/files/mapsforge-map-0.2.4.jar + compile files('libs/mapsforge-map-0.2.4.jar') + compile files('libs/mapsforge-map-0.3.0-jar-with-dependencies.jar') + + compile 'com.android.support:appcompat-v7:19.1.0' + + compile 'com.jakewharton:butterknife:5.0.0' + compile 'org.apache.commons:commons-collections4:4.0' + compile 'org.apache.commons:commons-lang3:3.2.1' + compile 'commons-io:commons-io:2.4' + compile 'com.google.code.findbugs:annotations:2.0.3' + + compile "com.netflix.rxjava:rxjava-core:$RXVersion" + compile "com.netflix.rxjava:rxjava-android:$RXVersion" + compile "com.netflix.rxjava:rxjava-async-util:$RXVersion" + + //TEST + //compile files('compile-libs/androidannotations-3.0.1.jar') + //compile files('compile-libs/findbugs-ant.jar') + //compile files('compile-libs/findbugs-jsr305.jar') //CheckForNull conflict with com.google.code.findbugs:annotations + compile files('compile-libs/org.eclipse.jdt.annotation_1.1.0.v20130513-1648.jar') + + //Robotium / Robolectric?? + androidTestCompile files('../tests/libs/android-junit-report-1.5.8.jar') + androidTestCompile files('../tests/libs/robotium-solo-3.6.jar') + //androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.0.1' +} + +/* + ANDROID ANNOTATIONS + */ + +apt { + arguments { + androidManifestFile variant.processResources.manifestFile + resourcePackageName 'cgeo.geocaching' + + // If you're using Android NBS flavors you should use the following line instead of hard-coded packageName + // resourcePackageName android.defaultConfig.packageName + + // You can set optional annotation processing options here, like these commented options: + // logLevel 'INFO' + // logFile '/var/log/aa.log' + } +} + +/* + FINDBUGS + + Usage : gradle check + + */ + +//http://www.gradle.org/docs/current/dsl/org.gradle.api.plugins.quality.FindBugsExtension.html +findbugs { + toolVersion = "2.0.1" + //sourceSets = [sourceSets.main] + ignoreFailures = true + reportsDir = file("$project.buildDir/reports") + effort = "max" + reportLevel = "high" + //visitors = ["FindSqlInjection", "SwitchFallthrough"] + //omitVisitors = ["FindNonShortCircuit"] + //includeFilter = file("$rootProject.projectDir/project/findbugs/inclusions.xml") + excludeFilter = file("$rootProject.projectDir/project/findbugs/exclusions.xml") + +} + +/* +* +* +* END of useful build +* Following task are for samples +* + */ + +task logInfo { + logging.captureStandardOutput LogLevel.INFO + doFirst { + println 'A task message which is logged at INFO level' + } +} + +/* + UNIT TEST + */ +/* +sourceSets { + unitTest { + java.srcDir file('../tests/src') + //java.srcDirs = ['src', 'thirdparty', 'annotation_gen', '../tests'] + resources.srcDir file('../tests/res') + //manifest.srcFile '../tests/AndroidManifest.xml' + } +} +dependencies { + //unitTestCompile files("$project.buildDir/classes/release") + unitTestCompile files("$project.buildDir/classes/debug") + unitTestCompile 'junit:junit:4.8.2' + unitTestCompile 'com.google.android:android-test:4.1.1.4' + + unitTestCompile 'com.googlecode.androidannotations:androidannotations-api:2.7.1' + unitTestCompile 'com.jakewharton:butterknife:4.0.1' + unitTestCompile 'org.apache.commons:commons-collections4:4.0' + unitTestCompile 'commons-io:commons-io:2.4' + unitTestCompile 'org.apache.commons:commons-lang3:3.2.1' + unitTestCompile 'com.google.code.findbugs:annotations:2.0.3' + unitTestCompile 'com.netflix.rxjava:rxjava-core:0.17.0-RC6' + unitTestCompile 'com.netflix.rxjava:rxjava-android:0.17.0-RC6' +} + +// extend the runtime +configurations { + unitTestCompile.extendsFrom runtime + unitTestRuntime.extendsFrom unitTestCompile +} + +// add the unitTest task +//task unitTest(type:Test, dependsOn: assemble) { +task unitTest(type:Test, dependsOn: assembleDebug) { + description = "run unit tests" + testClassesDir = project.sourceSets.unitTest.output.classesDir + classpath = project.sourceSets.unitTest.runtimeClasspath +} +// bind to check +check.dependsOn unitTest +//build.dependsOn unitTest +*/ + +//run gradle compileTest + +/* + PLACEHOLDER + */ + +//Not working...copy templates/keys.xml in res/values for the moment +task prep() { + /* + requiredProperties "maps.api.key", "maps.api.key.market", "ocde.okapi.consumer.key", "ocde.okapi.consumer.secret", "ocpl.okapi.consumer.key", "ocpl.okapi.consumer.secret" + doFirst { + logger.info("prep... ") + + copy { + from "templates" + include "*.xml" + into "res/values" + filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: project.ext.filterTokens) + } + } + */ +} +task prep2() { +/* + //http://goo.gl/bqnwjJ + copy{ + from("${buildDir}/manifests"){ + include "${variant.dirName}/AndroidManifest.xml" + } + into("${buildDir}/manifests/$variant.name") + + // define a variable for your key: + def gmaps_key = "<your-key>" + + filter{ + String line -> line.replaceAll("<meta-data android:name=\"com.google.android.maps.v2.API_KEY\" android:value=\"\"/>", + "<meta-data android:name=\"com.google.android.maps.v2.API_KEY\" android:value=\"" + gmaps_key + "\"/>") + } + + // set the path to the modified Manifest: + variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml") + } + + + */ +} + +android.applicationVariants.all{ variant -> + variant.mergeResources.doLast{ + logger.info("rootProject.projectDir="+rootProject.projectDir) + prep{} + } +} + +//http://blog.futurice.com/android_unit_testing_in_ides_and_ci_environments +task addTest { + def src = ['tests/java'] + def file = file("app.iml") + + doLast { + try { + def parsedXml = (new XmlParser()).parse(file) + def node = parsedXml.component[1].content[0] + src.each { + def path = 'file://$MODULE_DIR$/' + "${it}" + def set = node.find { it.@url == path } + if (set == null) { + new Node(node, 'sourceFolder', ['url': 'file://$MODULE_DIR$/' + "${it}", 'isTestSource': "true"]) + def writer = new StringWriter() + new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml) + file.text = writer.toString() + } + } + } catch (FileNotFoundException e) { + // nop, iml not found + } + } +} +/* +// always do the addtest on prebuild +gradle.projectsEvaluated { + preBuild.dependsOn(addTest) +}*/
\ No newline at end of file diff --git a/main/cgeo.iml b/main/cgeo.iml index 5781d97..c662ceb 100644 --- a/main/cgeo.iml +++ b/main/cgeo.iml @@ -55,6 +55,7 @@ </library> </orderEntry> <orderEntry type="module" module-name="mapswithme-api" exported="" /> + <orderEntry type="module" module-name="android-support-v7-appcompat" exported="" /> </component> </module> diff --git a/main/libs/android-support-v4.jar b/main/libs/android-support-v4.jar Binary files differdeleted file mode 100644 index 96644ed..0000000 --- a/main/libs/android-support-v4.jar +++ /dev/null diff --git a/main/libs/butterknife-5.0.0.jar b/main/libs/butterknife-5.0.0.jar Binary files differdeleted file mode 100644 index a08482d..0000000 --- a/main/libs/butterknife-5.0.0.jar +++ /dev/null diff --git a/main/libs/butterknife-5.1.0.jar b/main/libs/butterknife-5.1.0.jar Binary files differnew file mode 100644 index 0000000..0f2da31 --- /dev/null +++ b/main/libs/butterknife-5.1.0.jar diff --git a/main/libs/rxjava-android-0.17.6.jar b/main/libs/rxjava-android-0.19.0.jar Binary files differindex b840d42..afd9070 100644 --- a/main/libs/rxjava-android-0.17.6.jar +++ b/main/libs/rxjava-android-0.19.0.jar diff --git a/main/libs/rxjava-android-0.19.0.jar.properties b/main/libs/rxjava-android-0.19.0.jar.properties new file mode 100644 index 0000000..7d2ed5d --- /dev/null +++ b/main/libs/rxjava-android-0.19.0.jar.properties @@ -0,0 +1 @@ +src=src/rxjava-android-0.19.0-sources.jar
\ No newline at end of file diff --git a/main/libs/rxjava-async-util-0.17.6.jar b/main/libs/rxjava-async-util-0.17.6.jar Binary files differdeleted file mode 100644 index 2947fe3..0000000 --- a/main/libs/rxjava-async-util-0.17.6.jar +++ /dev/null diff --git a/main/libs/rxjava-async-util-0.19.0.jar b/main/libs/rxjava-async-util-0.19.0.jar Binary files differnew file mode 100644 index 0000000..8f60ba5 --- /dev/null +++ b/main/libs/rxjava-async-util-0.19.0.jar diff --git a/main/libs/rxjava-async-util-0.19.0.jar.properties b/main/libs/rxjava-async-util-0.19.0.jar.properties new file mode 100644 index 0000000..507f41e --- /dev/null +++ b/main/libs/rxjava-async-util-0.19.0.jar.properties @@ -0,0 +1 @@ +src=src/rxjava-async-util-0.19.0-sources.jar
\ No newline at end of file diff --git a/main/libs/rxjava-core-0.17.6.jar b/main/libs/rxjava-core-0.17.6.jar Binary files differdeleted file mode 100644 index 33d8801..0000000 --- a/main/libs/rxjava-core-0.17.6.jar +++ /dev/null diff --git a/main/libs/rxjava-core-0.19.0.jar b/main/libs/rxjava-core-0.19.0.jar Binary files differnew file mode 100644 index 0000000..898a803 --- /dev/null +++ b/main/libs/rxjava-core-0.19.0.jar diff --git a/main/libs/rxjava-core-0.19.0.jar.properties b/main/libs/rxjava-core-0.19.0.jar.properties new file mode 100644 index 0000000..4b743a0 --- /dev/null +++ b/main/libs/rxjava-core-0.19.0.jar.properties @@ -0,0 +1 @@ +src=src/rxjava-core-0.19.0-sources.jar
\ No newline at end of file diff --git a/main/libs/src/rxjava-android-0.19.0-sources.jar b/main/libs/src/rxjava-android-0.19.0-sources.jar Binary files differnew file mode 100644 index 0000000..e534b4d --- /dev/null +++ b/main/libs/src/rxjava-android-0.19.0-sources.jar diff --git a/main/libs/src/rxjava-async-util-0.19.0-sources.jar b/main/libs/src/rxjava-async-util-0.19.0-sources.jar Binary files differnew file mode 100644 index 0000000..6da23af --- /dev/null +++ b/main/libs/src/rxjava-async-util-0.19.0-sources.jar diff --git a/main/libs/src/rxjava-core-0.19.0-sources.jar b/main/libs/src/rxjava-core-0.19.0-sources.jar Binary files differnew file mode 100644 index 0000000..7e753d9 --- /dev/null +++ b/main/libs/src/rxjava-core-0.19.0-sources.jar diff --git a/main/project.properties b/main/project.properties index a761287..53ab0b1 100644 --- a/main/project.properties +++ b/main/project.properties @@ -13,3 +13,4 @@ proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project. # Project target. target=Google Inc.:Google APIs:19 android.library.reference.1=../mapswithme-api +android.library.reference.2=../android-support-v7-appcompat diff --git a/main/res/drawable-hdpi/actionbar_home.png b/main/res/drawable-hdpi/actionbar_home.png Binary files differdeleted file mode 100644 index a5a1a8c..0000000 --- a/main/res/drawable-hdpi/actionbar_home.png +++ /dev/null diff --git a/main/res/drawable-hdpi/actionbar_map.png b/main/res/drawable-hdpi/actionbar_map.png Binary files differdeleted file mode 100644 index 0daa215..0000000 --- a/main/res/drawable-hdpi/actionbar_map.png +++ /dev/null diff --git a/main/res/drawable-hdpi/actionbar_mylocation_off.png b/main/res/drawable-hdpi/actionbar_mylocation_off.png Binary files differdeleted file mode 100644 index 17d61db..0000000 --- a/main/res/drawable-hdpi/actionbar_mylocation_off.png +++ /dev/null diff --git a/main/res/drawable-hdpi/actionbar_mylocation_on.png b/main/res/drawable-hdpi/actionbar_mylocation_on.png Binary files differdeleted file mode 100644 index 1f21901..0000000 --- a/main/res/drawable-hdpi/actionbar_mylocation_on.png +++ /dev/null diff --git a/main/res/drawable-hdpi/actionbar_search.png b/main/res/drawable-hdpi/actionbar_search.png Binary files differdeleted file mode 100644 index 59de344..0000000 --- a/main/res/drawable-hdpi/actionbar_search.png +++ /dev/null diff --git a/main/res/drawable-hdpi/ic_menu_account_list.png b/main/res/drawable-hdpi/ic_menu_account_list.png Binary files differindex f858d2c..0f17170 100644 --- a/main/res/drawable-hdpi/ic_menu_account_list.png +++ b/main/res/drawable-hdpi/ic_menu_account_list.png diff --git a/main/res/drawable-hdpi/ic_menu_add.png b/main/res/drawable-hdpi/ic_menu_add.png Binary files differindex 65cc01e..444e8a5 100644 --- a/main/res/drawable-hdpi/ic_menu_add.png +++ b/main/res/drawable-hdpi/ic_menu_add.png diff --git a/main/res/drawable-hdpi/ic_menu_agenda.png b/main/res/drawable-hdpi/ic_menu_agenda.png Binary files differindex 6bb5cc8..9e08c29 100644 --- a/main/res/drawable-hdpi/ic_menu_agenda.png +++ b/main/res/drawable-hdpi/ic_menu_agenda.png diff --git a/main/res/drawable-hdpi/ic_menu_clear_playlist.png b/main/res/drawable-hdpi/ic_menu_clear_playlist.png Binary files differindex 0c3e06d..84a4a5b 100644 --- a/main/res/drawable-hdpi/ic_menu_clear_playlist.png +++ b/main/res/drawable-hdpi/ic_menu_clear_playlist.png diff --git a/main/res/drawable-hdpi/ic_menu_compass.png b/main/res/drawable-hdpi/ic_menu_compass.png Binary files differindex 104270f..39760f8 100644 --- a/main/res/drawable-hdpi/ic_menu_compass.png +++ b/main/res/drawable-hdpi/ic_menu_compass.png diff --git a/main/res/drawable-hdpi/ic_menu_delete.png b/main/res/drawable-hdpi/ic_menu_delete.png Binary files differindex 2aed26a..24d8f6a 100644 --- a/main/res/drawable-hdpi/ic_menu_delete.png +++ b/main/res/drawable-hdpi/ic_menu_delete.png diff --git a/main/res/drawable-hdpi/ic_menu_edit.png b/main/res/drawable-hdpi/ic_menu_edit.png Binary files differindex 602dd10..9bdba1b 100644 --- a/main/res/drawable-hdpi/ic_menu_edit.png +++ b/main/res/drawable-hdpi/ic_menu_edit.png diff --git a/main/res/drawable-hdpi/ic_menu_emoticons.png b/main/res/drawable-hdpi/ic_menu_emoticons.png Binary files differindex 4a1f744..16ec4e4 100644 --- a/main/res/drawable-hdpi/ic_menu_emoticons.png +++ b/main/res/drawable-hdpi/ic_menu_emoticons.png diff --git a/main/res/drawable-hdpi/ic_menu_info_details.png b/main/res/drawable-hdpi/ic_menu_info_details.png Binary files differindex 7696ceb..6a7a1e9 100644 --- a/main/res/drawable-hdpi/ic_menu_info_details.png +++ b/main/res/drawable-hdpi/ic_menu_info_details.png diff --git a/main/res/drawable-hdpi/ic_menu_mapmode.png b/main/res/drawable-hdpi/ic_menu_mapmode.png Binary files differindex c895ccb..5ac4a02 100644 --- a/main/res/drawable-hdpi/ic_menu_mapmode.png +++ b/main/res/drawable-hdpi/ic_menu_mapmode.png diff --git a/main/res/drawable-hdpi/ic_menu_mark.png b/main/res/drawable-hdpi/ic_menu_mark.png Binary files differindex 724d787..95a3217 100644 --- a/main/res/drawable-hdpi/ic_menu_mark.png +++ b/main/res/drawable-hdpi/ic_menu_mark.png diff --git a/main/res/drawable-hdpi/ic_menu_mylocation.png b/main/res/drawable-hdpi/ic_menu_mylocation.png Binary files differnew file mode 100644 index 0000000..ba82ee0 --- /dev/null +++ b/main/res/drawable-hdpi/ic_menu_mylocation.png diff --git a/main/res/drawable-hdpi/ic_menu_myplaces.png b/main/res/drawable-hdpi/ic_menu_myplaces.png Binary files differindex 5f726d8..ade7532 100644 --- a/main/res/drawable-hdpi/ic_menu_myplaces.png +++ b/main/res/drawable-hdpi/ic_menu_myplaces.png diff --git a/main/res/drawable-hdpi/ic_menu_preferences.png b/main/res/drawable-hdpi/ic_menu_preferences.png Binary files differindex 81bca4a..5321f82 100644 --- a/main/res/drawable-hdpi/ic_menu_preferences.png +++ b/main/res/drawable-hdpi/ic_menu_preferences.png diff --git a/main/res/drawable-hdpi/ic_menu_recent_history.png b/main/res/drawable-hdpi/ic_menu_recent_history.png Binary files differindex 0dd1627..4101434 100644 --- a/main/res/drawable-hdpi/ic_menu_recent_history.png +++ b/main/res/drawable-hdpi/ic_menu_recent_history.png diff --git a/main/res/drawable-hdpi/ic_menu_refresh.png b/main/res/drawable-hdpi/ic_menu_refresh.png Binary files differindex 53cacca..e13315f 100644 --- a/main/res/drawable-hdpi/ic_menu_refresh.png +++ b/main/res/drawable-hdpi/ic_menu_refresh.png diff --git a/main/res/drawable-hdpi/ic_menu_rotate.png b/main/res/drawable-hdpi/ic_menu_rotate.png Binary files differindex 85115af..09efba4 100644 --- a/main/res/drawable-hdpi/ic_menu_rotate.png +++ b/main/res/drawable-hdpi/ic_menu_rotate.png diff --git a/main/res/drawable-hdpi/ic_menu_save.png b/main/res/drawable-hdpi/ic_menu_save.png Binary files differindex fc26c5d..36fc7f4 100644 --- a/main/res/drawable-hdpi/ic_menu_save.png +++ b/main/res/drawable-hdpi/ic_menu_save.png diff --git a/main/res/drawable-hdpi/ic_menu_set_as.png b/main/res/drawable-hdpi/ic_menu_set_as.png Binary files differindex 7e79c15..41f931b 100644 --- a/main/res/drawable-hdpi/ic_menu_set_as.png +++ b/main/res/drawable-hdpi/ic_menu_set_as.png diff --git a/main/res/drawable-hdpi/ic_menu_share.png b/main/res/drawable-hdpi/ic_menu_share.png Binary files differindex b41b348..2837615 100644 --- a/main/res/drawable-hdpi/ic_menu_share.png +++ b/main/res/drawable-hdpi/ic_menu_share.png diff --git a/main/res/drawable-hdpi/ic_menu_sort_alphabetically.png b/main/res/drawable-hdpi/ic_menu_sort_alphabetically.png Binary files differindex 5d68998..74e6b83 100644 --- a/main/res/drawable-hdpi/ic_menu_sort_alphabetically.png +++ b/main/res/drawable-hdpi/ic_menu_sort_alphabetically.png diff --git a/main/res/drawable-hdpi/ic_menu_sort_by_size.png b/main/res/drawable-hdpi/ic_menu_sort_by_size.png Binary files differdeleted file mode 100644 index c9388fd..0000000 --- a/main/res/drawable-hdpi/ic_menu_sort_by_size.png +++ /dev/null diff --git a/main/res/drawable-hdpi/ic_menu_start_conversation.png b/main/res/drawable-hdpi/ic_menu_start_conversation.png Binary files differindex d63d3a7..395a5ec 100644 --- a/main/res/drawable-hdpi/ic_menu_start_conversation.png +++ b/main/res/drawable-hdpi/ic_menu_start_conversation.png diff --git a/main/res/drawable-ldpi/actionbar_home.png b/main/res/drawable-ldpi/actionbar_home.png Binary files differdeleted file mode 100644 index 2334d7d..0000000 --- a/main/res/drawable-ldpi/actionbar_home.png +++ /dev/null diff --git a/main/res/drawable-ldpi/actionbar_map.png b/main/res/drawable-ldpi/actionbar_map.png Binary files differdeleted file mode 100644 index afc108c..0000000 --- a/main/res/drawable-ldpi/actionbar_map.png +++ /dev/null diff --git a/main/res/drawable-ldpi/actionbar_mylocation_off.png b/main/res/drawable-ldpi/actionbar_mylocation_off.png Binary files differdeleted file mode 100644 index be0c923..0000000 --- a/main/res/drawable-ldpi/actionbar_mylocation_off.png +++ /dev/null diff --git a/main/res/drawable-ldpi/actionbar_mylocation_on.png b/main/res/drawable-ldpi/actionbar_mylocation_on.png Binary files differdeleted file mode 100644 index f137305..0000000 --- a/main/res/drawable-ldpi/actionbar_mylocation_on.png +++ /dev/null diff --git a/main/res/drawable-ldpi/actionbar_search.png b/main/res/drawable-ldpi/actionbar_search.png Binary files differdeleted file mode 100644 index f3ce1d9..0000000 --- a/main/res/drawable-ldpi/actionbar_search.png +++ /dev/null diff --git a/main/res/drawable-ldpi/ic_menu_account_list.png b/main/res/drawable-ldpi/ic_menu_account_list.png Binary files differdeleted file mode 100644 index 04ededd..0000000 --- a/main/res/drawable-ldpi/ic_menu_account_list.png +++ /dev/null diff --git a/main/res/drawable-ldpi/ic_menu_clear_playlist.png b/main/res/drawable-ldpi/ic_menu_clear_playlist.png Binary files differdeleted file mode 100644 index f3e6b51..0000000 --- a/main/res/drawable-ldpi/ic_menu_clear_playlist.png +++ /dev/null diff --git a/main/res/drawable-ldpi/ic_menu_mark.png b/main/res/drawable-ldpi/ic_menu_mark.png Binary files differdeleted file mode 100644 index 19bcd03..0000000 --- a/main/res/drawable-ldpi/ic_menu_mark.png +++ /dev/null diff --git a/main/res/drawable-ldpi/ic_menu_more.png b/main/res/drawable-ldpi/ic_menu_more.png Binary files differdeleted file mode 100644 index 62983c6..0000000 --- a/main/res/drawable-ldpi/ic_menu_more.png +++ /dev/null diff --git a/main/res/drawable-ldpi/ic_menu_start_conversation.png b/main/res/drawable-ldpi/ic_menu_start_conversation.png Binary files differdeleted file mode 100644 index 1e39928..0000000 --- a/main/res/drawable-ldpi/ic_menu_start_conversation.png +++ /dev/null diff --git a/main/res/drawable-mdpi/actionbar_home.png b/main/res/drawable-mdpi/actionbar_home.png Binary files differdeleted file mode 100644 index e109f0a..0000000 --- a/main/res/drawable-mdpi/actionbar_home.png +++ /dev/null diff --git a/main/res/drawable-mdpi/actionbar_map.png b/main/res/drawable-mdpi/actionbar_map.png Binary files differdeleted file mode 100644 index 80287d7..0000000 --- a/main/res/drawable-mdpi/actionbar_map.png +++ /dev/null diff --git a/main/res/drawable-mdpi/actionbar_mylocation_off.png b/main/res/drawable-mdpi/actionbar_mylocation_off.png Binary files differdeleted file mode 100644 index 1cdeeba..0000000 --- a/main/res/drawable-mdpi/actionbar_mylocation_off.png +++ /dev/null diff --git a/main/res/drawable-mdpi/actionbar_mylocation_on.png b/main/res/drawable-mdpi/actionbar_mylocation_on.png Binary files differdeleted file mode 100644 index 1d1b625..0000000 --- a/main/res/drawable-mdpi/actionbar_mylocation_on.png +++ /dev/null diff --git a/main/res/drawable-mdpi/actionbar_search.png b/main/res/drawable-mdpi/actionbar_search.png Binary files differdeleted file mode 100644 index cce7789..0000000 --- a/main/res/drawable-mdpi/actionbar_search.png +++ /dev/null diff --git a/main/res/drawable-mdpi/ic_launcher_browser.png b/main/res/drawable-mdpi/ic_launcher_browser.png Binary files differnew file mode 100644 index 0000000..9bc6817 --- /dev/null +++ b/main/res/drawable-mdpi/ic_launcher_browser.png diff --git a/main/res/drawable-mdpi/ic_menu_account_list.png b/main/res/drawable-mdpi/ic_menu_account_list.png Binary files differindex f0945b2..e4e717e 100644 --- a/main/res/drawable-mdpi/ic_menu_account_list.png +++ b/main/res/drawable-mdpi/ic_menu_account_list.png diff --git a/main/res/drawable-mdpi/ic_menu_add.png b/main/res/drawable-mdpi/ic_menu_add.png Binary files differindex 6752bfd..361c7c4 100644 --- a/main/res/drawable-mdpi/ic_menu_add.png +++ b/main/res/drawable-mdpi/ic_menu_add.png diff --git a/main/res/drawable-mdpi/ic_menu_agenda.png b/main/res/drawable-mdpi/ic_menu_agenda.png Binary files differindex 9f2c1dc..c63a12b 100644 --- a/main/res/drawable-mdpi/ic_menu_agenda.png +++ b/main/res/drawable-mdpi/ic_menu_agenda.png diff --git a/main/res/drawable-mdpi/ic_menu_attachment.png b/main/res/drawable-mdpi/ic_menu_attachment.png Binary files differnew file mode 100644 index 0000000..d3d4812 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_attachment.png diff --git a/main/res/drawable-mdpi/ic_menu_clear_playlist.png b/main/res/drawable-mdpi/ic_menu_clear_playlist.png Binary files differindex 750db62..9100a69 100644 --- a/main/res/drawable-mdpi/ic_menu_clear_playlist.png +++ b/main/res/drawable-mdpi/ic_menu_clear_playlist.png diff --git a/main/res/drawable-mdpi/ic_menu_compass.png b/main/res/drawable-mdpi/ic_menu_compass.png Binary files differindex 7717dde..25235cc 100644 --- a/main/res/drawable-mdpi/ic_menu_compass.png +++ b/main/res/drawable-mdpi/ic_menu_compass.png diff --git a/main/res/drawable-mdpi/ic_menu_copy.png b/main/res/drawable-mdpi/ic_menu_copy.png Binary files differnew file mode 100644 index 0000000..eee5540 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_copy.png diff --git a/main/res/drawable-mdpi/ic_menu_delete.png b/main/res/drawable-mdpi/ic_menu_delete.png Binary files differindex 7d95494..e2c8700 100644 --- a/main/res/drawable-mdpi/ic_menu_delete.png +++ b/main/res/drawable-mdpi/ic_menu_delete.png diff --git a/main/res/drawable-mdpi/ic_menu_edit.png b/main/res/drawable-mdpi/ic_menu_edit.png Binary files differindex 41a9c2e..d0314e9 100644 --- a/main/res/drawable-mdpi/ic_menu_edit.png +++ b/main/res/drawable-mdpi/ic_menu_edit.png diff --git a/main/res/drawable-mdpi/ic_menu_emoticons.png b/main/res/drawable-mdpi/ic_menu_emoticons.png Binary files differindex 765000b..8d1780f 100644 --- a/main/res/drawable-mdpi/ic_menu_emoticons.png +++ b/main/res/drawable-mdpi/ic_menu_emoticons.png diff --git a/main/res/drawable-mdpi/ic_menu_info_details.png b/main/res/drawable-mdpi/ic_menu_info_details.png Binary files differindex 1786d1e..18b15b5 100644 --- a/main/res/drawable-mdpi/ic_menu_info_details.png +++ b/main/res/drawable-mdpi/ic_menu_info_details.png diff --git a/main/res/drawable-mdpi/ic_menu_mapmode.png b/main/res/drawable-mdpi/ic_menu_mapmode.png Binary files differindex d85cab5..1b50b5a 100644 --- a/main/res/drawable-mdpi/ic_menu_mapmode.png +++ b/main/res/drawable-mdpi/ic_menu_mapmode.png diff --git a/main/res/drawable-mdpi/ic_menu_mark.png b/main/res/drawable-mdpi/ic_menu_mark.png Binary files differindex 5e95da7..0c55506 100644 --- a/main/res/drawable-mdpi/ic_menu_mark.png +++ b/main/res/drawable-mdpi/ic_menu_mark.png diff --git a/main/res/drawable-mdpi/ic_menu_my_calendar.png b/main/res/drawable-mdpi/ic_menu_my_calendar.png Binary files differnew file mode 100644 index 0000000..991dfb0 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_my_calendar.png diff --git a/main/res/drawable-mdpi/ic_menu_mylocation.png b/main/res/drawable-mdpi/ic_menu_mylocation.png Binary files differnew file mode 100644 index 0000000..2a61a97 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_mylocation.png diff --git a/main/res/drawable-mdpi/ic_menu_mylocation_off.png b/main/res/drawable-mdpi/ic_menu_mylocation_off.png Binary files differnew file mode 100644 index 0000000..00185b9 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_mylocation_off.png diff --git a/main/res/drawable-mdpi/ic_menu_myplaces.png b/main/res/drawable-mdpi/ic_menu_myplaces.png Binary files differindex 06f11ba..75f2c9b 100644 --- a/main/res/drawable-mdpi/ic_menu_myplaces.png +++ b/main/res/drawable-mdpi/ic_menu_myplaces.png diff --git a/main/res/drawable-mdpi/ic_menu_preferences.png b/main/res/drawable-mdpi/ic_menu_preferences.png Binary files differindex 60dbff6..ccc50e6 100644 --- a/main/res/drawable-mdpi/ic_menu_preferences.png +++ b/main/res/drawable-mdpi/ic_menu_preferences.png diff --git a/main/res/drawable-mdpi/ic_menu_recent_history.png b/main/res/drawable-mdpi/ic_menu_recent_history.png Binary files differindex 4ccae5d..e5f8e2d 100644 --- a/main/res/drawable-mdpi/ic_menu_recent_history.png +++ b/main/res/drawable-mdpi/ic_menu_recent_history.png diff --git a/main/res/drawable-mdpi/ic_menu_refresh.png b/main/res/drawable-mdpi/ic_menu_refresh.png Binary files differindex 77d70dd..30b660f 100644 --- a/main/res/drawable-mdpi/ic_menu_refresh.png +++ b/main/res/drawable-mdpi/ic_menu_refresh.png diff --git a/main/res/drawable-mdpi/ic_menu_rotate.png b/main/res/drawable-mdpi/ic_menu_rotate.png Binary files differindex 27368b2..35fa56d 100644 --- a/main/res/drawable-mdpi/ic_menu_rotate.png +++ b/main/res/drawable-mdpi/ic_menu_rotate.png diff --git a/main/res/drawable-mdpi/ic_menu_save.png b/main/res/drawable-mdpi/ic_menu_save.png Binary files differindex 36d50b3..5f66864 100644 --- a/main/res/drawable-mdpi/ic_menu_save.png +++ b/main/res/drawable-mdpi/ic_menu_save.png diff --git a/main/res/drawable-mdpi/ic_menu_send.png b/main/res/drawable-mdpi/ic_menu_send.png Binary files differnew file mode 100644 index 0000000..06b4717 --- /dev/null +++ b/main/res/drawable-mdpi/ic_menu_send.png diff --git a/main/res/drawable-mdpi/ic_menu_set_as.png b/main/res/drawable-mdpi/ic_menu_set_as.png Binary files differindex cb9dc49..98cc305 100644 --- a/main/res/drawable-mdpi/ic_menu_set_as.png +++ b/main/res/drawable-mdpi/ic_menu_set_as.png diff --git a/main/res/drawable-mdpi/ic_menu_share.png b/main/res/drawable-mdpi/ic_menu_share.png Binary files differindex 44db9b1..d89ca5f 100644 --- a/main/res/drawable-mdpi/ic_menu_share.png +++ b/main/res/drawable-mdpi/ic_menu_share.png diff --git a/main/res/drawable-mdpi/ic_menu_sort_alphabetically.png b/main/res/drawable-mdpi/ic_menu_sort_alphabetically.png Binary files differindex 2583eb8..0c5ffad 100644 --- a/main/res/drawable-mdpi/ic_menu_sort_alphabetically.png +++ b/main/res/drawable-mdpi/ic_menu_sort_alphabetically.png diff --git a/main/res/drawable-mdpi/ic_menu_sort_by_size.png b/main/res/drawable-mdpi/ic_menu_sort_by_size.png Binary files differdeleted file mode 100644 index 65e2786..0000000 --- a/main/res/drawable-mdpi/ic_menu_sort_by_size.png +++ /dev/null diff --git a/main/res/drawable-mdpi/ic_menu_start_conversation.png b/main/res/drawable-mdpi/ic_menu_start_conversation.png Binary files differindex aadcc2f..24b6540 100644 --- a/main/res/drawable-mdpi/ic_menu_start_conversation.png +++ b/main/res/drawable-mdpi/ic_menu_start_conversation.png diff --git a/main/res/drawable-xhdpi/ic_launcher_browser.png b/main/res/drawable-xhdpi/ic_launcher_browser.png Binary files differnew file mode 100644 index 0000000..9412fbe --- /dev/null +++ b/main/res/drawable-xhdpi/ic_launcher_browser.png diff --git a/main/res/drawable-xhdpi/ic_menu_account_list.png b/main/res/drawable-xhdpi/ic_menu_account_list.png Binary files differnew file mode 100644 index 0000000..ebe29b9 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_account_list.png diff --git a/main/res/drawable-xhdpi/ic_menu_add.png b/main/res/drawable-xhdpi/ic_menu_add.png Binary files differnew file mode 100644 index 0000000..7d498a9 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_add.png diff --git a/main/res/drawable-xhdpi/ic_menu_agenda.png b/main/res/drawable-xhdpi/ic_menu_agenda.png Binary files differnew file mode 100644 index 0000000..25e9f11 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_agenda.png diff --git a/main/res/drawable-xhdpi/ic_menu_clear_playlist.png b/main/res/drawable-xhdpi/ic_menu_clear_playlist.png Binary files differnew file mode 100644 index 0000000..8981d6f --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_clear_playlist.png diff --git a/main/res/drawable-xhdpi/ic_menu_compass.png b/main/res/drawable-xhdpi/ic_menu_compass.png Binary files differnew file mode 100644 index 0000000..1c2ad89 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_compass.png diff --git a/main/res/drawable-xhdpi/ic_menu_delete.png b/main/res/drawable-xhdpi/ic_menu_delete.png Binary files differnew file mode 100644 index 0000000..65b9cae --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_delete.png diff --git a/main/res/drawable-xhdpi/ic_menu_edit.png b/main/res/drawable-xhdpi/ic_menu_edit.png Binary files differnew file mode 100644 index 0000000..fcdd71e --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_edit.png diff --git a/main/res/drawable-xhdpi/ic_menu_emoticons.png b/main/res/drawable-xhdpi/ic_menu_emoticons.png Binary files differnew file mode 100644 index 0000000..af730fa --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_emoticons.png diff --git a/main/res/drawable-xhdpi/ic_menu_info_details.png b/main/res/drawable-xhdpi/ic_menu_info_details.png Binary files differnew file mode 100644 index 0000000..24ea543 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_info_details.png diff --git a/main/res/drawable-xhdpi/ic_menu_mapmode.png b/main/res/drawable-xhdpi/ic_menu_mapmode.png Binary files differnew file mode 100644 index 0000000..0b62d08 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_mapmode.png diff --git a/main/res/drawable-xhdpi/ic_menu_mark.png b/main/res/drawable-xhdpi/ic_menu_mark.png Binary files differnew file mode 100644 index 0000000..a5de6fb --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_mark.png diff --git a/main/res/drawable-xhdpi/ic_menu_mylocation.png b/main/res/drawable-xhdpi/ic_menu_mylocation.png Binary files differnew file mode 100644 index 0000000..b0a76a2 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_mylocation.png diff --git a/main/res/drawable-xhdpi/ic_menu_mylocation_off.png b/main/res/drawable-xhdpi/ic_menu_mylocation_off.png Binary files differnew file mode 100644 index 0000000..6e45c52 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_mylocation_off.png diff --git a/main/res/drawable-xhdpi/ic_menu_myplaces.png b/main/res/drawable-xhdpi/ic_menu_myplaces.png Binary files differnew file mode 100644 index 0000000..205848e --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_myplaces.png diff --git a/main/res/drawable-xhdpi/ic_menu_preferences.png b/main/res/drawable-xhdpi/ic_menu_preferences.png Binary files differnew file mode 100644 index 0000000..02cfbad --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_preferences.png diff --git a/main/res/drawable-xhdpi/ic_menu_recent_history.png b/main/res/drawable-xhdpi/ic_menu_recent_history.png Binary files differnew file mode 100644 index 0000000..fc5e1fc --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_recent_history.png diff --git a/main/res/drawable-xhdpi/ic_menu_refresh.png b/main/res/drawable-xhdpi/ic_menu_refresh.png Binary files differnew file mode 100644 index 0000000..9e9f10e --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_refresh.png diff --git a/main/res/drawable-xhdpi/ic_menu_rotate.png b/main/res/drawable-xhdpi/ic_menu_rotate.png Binary files differnew file mode 100644 index 0000000..98e19fe --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_rotate.png diff --git a/main/res/drawable-xhdpi/ic_menu_save.png b/main/res/drawable-xhdpi/ic_menu_save.png Binary files differnew file mode 100644 index 0000000..62a66d8 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_save.png diff --git a/main/res/drawable-xhdpi/ic_menu_set_as.png b/main/res/drawable-xhdpi/ic_menu_set_as.png Binary files differnew file mode 100644 index 0000000..8689766 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_set_as.png diff --git a/main/res/drawable-xhdpi/ic_menu_share.png b/main/res/drawable-xhdpi/ic_menu_share.png Binary files differnew file mode 100644 index 0000000..fce1d35 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_share.png diff --git a/main/res/drawable-xhdpi/ic_menu_sort_alphabetically.png b/main/res/drawable-xhdpi/ic_menu_sort_alphabetically.png Binary files differnew file mode 100644 index 0000000..5736ff8 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_sort_alphabetically.png diff --git a/main/res/drawable-xhdpi/ic_menu_start_conversation.png b/main/res/drawable-xhdpi/ic_menu_start_conversation.png Binary files differnew file mode 100644 index 0000000..d71ed17 --- /dev/null +++ b/main/res/drawable-xhdpi/ic_menu_start_conversation.png diff --git a/main/res/drawable-xxhdpi/ic_launcher_browser.png b/main/res/drawable-xxhdpi/ic_launcher_browser.png Binary files differnew file mode 100644 index 0000000..bd8c447 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_launcher_browser.png diff --git a/main/res/drawable-xxhdpi/ic_menu_account_list.png b/main/res/drawable-xxhdpi/ic_menu_account_list.png Binary files differnew file mode 100644 index 0000000..e072523 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_account_list.png diff --git a/main/res/drawable-xxhdpi/ic_menu_add.png b/main/res/drawable-xxhdpi/ic_menu_add.png Binary files differnew file mode 100644 index 0000000..18a83a1 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_add.png diff --git a/main/res/drawable-xxhdpi/ic_menu_agenda.png b/main/res/drawable-xxhdpi/ic_menu_agenda.png Binary files differnew file mode 100644 index 0000000..20f350b --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_agenda.png diff --git a/main/res/drawable-xxhdpi/ic_menu_clear_playlist.png b/main/res/drawable-xxhdpi/ic_menu_clear_playlist.png Binary files differnew file mode 100644 index 0000000..819e839 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_clear_playlist.png diff --git a/main/res/drawable-xxhdpi/ic_menu_compass.png b/main/res/drawable-xxhdpi/ic_menu_compass.png Binary files differnew file mode 100644 index 0000000..068678d --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_compass.png diff --git a/main/res/drawable-xxhdpi/ic_menu_delete.png b/main/res/drawable-xxhdpi/ic_menu_delete.png Binary files differnew file mode 100644 index 0000000..8e9e78d --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_delete.png diff --git a/main/res/drawable-xxhdpi/ic_menu_edit.png b/main/res/drawable-xxhdpi/ic_menu_edit.png Binary files differnew file mode 100644 index 0000000..2b6e967 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_edit.png diff --git a/main/res/drawable-xxhdpi/ic_menu_emoticons.png b/main/res/drawable-xxhdpi/ic_menu_emoticons.png Binary files differnew file mode 100644 index 0000000..eae564f --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_emoticons.png diff --git a/main/res/drawable-xxhdpi/ic_menu_info_details.png b/main/res/drawable-xxhdpi/ic_menu_info_details.png Binary files differnew file mode 100644 index 0000000..4414bea --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_info_details.png diff --git a/main/res/drawable-xxhdpi/ic_menu_mapmode.png b/main/res/drawable-xxhdpi/ic_menu_mapmode.png Binary files differnew file mode 100644 index 0000000..4d8c185 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_mapmode.png diff --git a/main/res/drawable-xxhdpi/ic_menu_mark.png b/main/res/drawable-xxhdpi/ic_menu_mark.png Binary files differnew file mode 100644 index 0000000..768aeb3 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_mark.png diff --git a/main/res/drawable-xxhdpi/ic_menu_mylocation.png b/main/res/drawable-xxhdpi/ic_menu_mylocation.png Binary files differnew file mode 100644 index 0000000..8ea61e1 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_mylocation.png diff --git a/main/res/drawable-xxhdpi/ic_menu_mylocation_off.png b/main/res/drawable-xxhdpi/ic_menu_mylocation_off.png Binary files differnew file mode 100644 index 0000000..8435579 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_mylocation_off.png diff --git a/main/res/drawable-xxhdpi/ic_menu_myplaces.png b/main/res/drawable-xxhdpi/ic_menu_myplaces.png Binary files differnew file mode 100644 index 0000000..85b3f20 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_myplaces.png diff --git a/main/res/drawable-xxhdpi/ic_menu_preferences.png b/main/res/drawable-xxhdpi/ic_menu_preferences.png Binary files differnew file mode 100644 index 0000000..b039537 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_preferences.png diff --git a/main/res/drawable-xxhdpi/ic_menu_recent_history.png b/main/res/drawable-xxhdpi/ic_menu_recent_history.png Binary files differnew file mode 100644 index 0000000..a3640a6 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_recent_history.png diff --git a/main/res/drawable-xxhdpi/ic_menu_refresh.png b/main/res/drawable-xxhdpi/ic_menu_refresh.png Binary files differnew file mode 100644 index 0000000..580f4cf --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_refresh.png diff --git a/main/res/drawable-xxhdpi/ic_menu_rotate.png b/main/res/drawable-xxhdpi/ic_menu_rotate.png Binary files differnew file mode 100644 index 0000000..fd6781f --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_rotate.png diff --git a/main/res/drawable-xxhdpi/ic_menu_save.png b/main/res/drawable-xxhdpi/ic_menu_save.png Binary files differnew file mode 100644 index 0000000..800da9a --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_save.png diff --git a/main/res/drawable-xxhdpi/ic_menu_set_as.png b/main/res/drawable-xxhdpi/ic_menu_set_as.png Binary files differnew file mode 100644 index 0000000..667d723 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_set_as.png diff --git a/main/res/drawable-xxhdpi/ic_menu_share.png b/main/res/drawable-xxhdpi/ic_menu_share.png Binary files differnew file mode 100644 index 0000000..7b90639 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_share.png diff --git a/main/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png b/main/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png Binary files differnew file mode 100644 index 0000000..bb925f2 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png diff --git a/main/res/drawable-xxhdpi/ic_menu_start_conversation.png b/main/res/drawable-xxhdpi/ic_menu_start_conversation.png Binary files differnew file mode 100644 index 0000000..bb26e49 --- /dev/null +++ b/main/res/drawable-xxhdpi/ic_menu_start_conversation.png diff --git a/main/res/drawable/ic_menu_myposition.xml b/main/res/drawable/ic_menu_myposition.xml new file mode 100644 index 0000000..b50eb1e --- /dev/null +++ b/main/res/drawable/ic_menu_myposition.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:drawable="@drawable/ic_menu_mylocation" android:state_checked="true"/> + <item android:drawable="@drawable/ic_menu_mylocation_off" android:state_checked="false" /> +</selector>
\ No newline at end of file diff --git a/main/res/layout-land/compass_activity.xml b/main/res/layout-land/compass_activity.xml index 00e12bf..738f02e 100644 --- a/main/res/layout-land/compass_activity.xml +++ b/main/res/layout-land/compass_activity.xml @@ -3,121 +3,113 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="horizontal" > - <include layout="@layout/actionbar" /> - - <LinearLayout + <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" - android:orientation="horizontal" > + android:layout_weight="1" + android:orientation="vertical" > - <RelativeLayout + <TextView + android:id="@+id/destination" android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:layout_weight="1" - android:orientation="vertical" > + android:layout_height="wrap_content" + android:layout_alignParentLeft="false" + android:layout_alignParentTop="true" + android:layout_centerHorizontal="true" + android:layout_gravity="center" + android:gravity="center_horizontal" + android:textColor="?text_color" + android:textSize="14sp" /> - <TextView - android:id="@+id/destination" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_alignParentLeft="false" - android:layout_alignParentTop="true" - android:layout_centerHorizontal="true" - android:layout_gravity="center" - android:gravity="center_horizontal" - android:textColor="?text_color" - android:textSize="14sp" /> - - <TextView - android:id="@+id/cacheinfo" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_alignParentLeft="false" - android:layout_alignParentTop="false" - android:layout_below="@+id/destination" - android:layout_centerHorizontal="true" - android:layout_gravity="center" - android:gravity="center_horizontal" - android:textColor="?text_color" - android:textSize="14sp" /> + <TextView + android:id="@+id/cacheinfo" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_alignParentLeft="false" + android:layout_alignParentTop="false" + android:layout_below="@+id/destination" + android:layout_centerHorizontal="true" + android:layout_gravity="center" + android:gravity="center_horizontal" + android:textColor="?text_color" + android:textSize="14sp" /> - <TextView - android:id="@+id/heading" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_centerVertical="true" - android:layout_gravity="left" - android:layout_marginLeft="3dip" - android:text="@null" - android:textColor="?text_color" - android:textSize="26sp" /> + <TextView + android:id="@+id/heading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:layout_gravity="left" + android:layout_marginLeft="3dip" + android:text="@null" + android:textColor="?text_color" + android:textSize="26sp" /> - <TextView - android:id="@+id/distance" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentRight="true" - android:layout_centerVertical="true" - android:layout_gravity="right" - android:layout_marginRight="3dip" - android:text="@null" - android:textColor="?text_color" - android:textSize="26sp" /> + <TextView + android:id="@+id/distance" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:layout_gravity="right" + android:layout_marginRight="3dip" + android:text="@null" + android:textColor="?text_color" + android:textSize="26sp" /> - <TextView - android:id="@+id/nav_location" - style="@style/location_current" - android:layout_above="@+id/status" - android:layout_alignParentBottom="false" - android:layout_alignParentLeft="false" - android:layout_alignParentTop="false" - android:layout_marginLeft="0dp" - android:layout_marginTop="95dp" - android:text="@string/loc_trying" /> + <TextView + android:id="@+id/nav_location" + style="@style/location_current" + android:layout_above="@+id/status" + android:layout_alignParentBottom="false" + android:layout_alignParentLeft="false" + android:layout_alignParentTop="false" + android:layout_marginLeft="0dp" + android:layout_marginTop="95dp" + android:text="@string/loc_trying" /> - <RelativeLayout - android:id="@+id/status" - android:layout_width="fill_parent" - android:layout_height="16dip" - android:layout_alignParentBottom="true" - android:layout_alignParentLeft="false" - android:layout_alignParentTop="false" - android:longClickable="true" > + <RelativeLayout + android:id="@+id/status" + android:layout_width="fill_parent" + android:layout_height="16dip" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="false" + android:layout_alignParentTop="false" + android:longClickable="true" > - <TextView - android:id="@+id/nav_type" - style="@style/location_current_type" - android:textColor="?text_color_grey" /> + <TextView + android:id="@+id/nav_type" + style="@style/location_current_type" + android:textColor="?text_color_grey" /> - <TextView - android:id="@+id/nav_accuracy" - style="@style/location_current_accuracy" - android:textColor="?text_color_grey" /> + <TextView + android:id="@+id/nav_accuracy" + style="@style/location_current_accuracy" + android:textColor="?text_color_grey" /> - <TextView - android:id="@+id/nav_satellites" - style="@style/location_current_satellites" - android:textColor="?text_color_grey" /> - </RelativeLayout> + <TextView + android:id="@+id/nav_satellites" + style="@style/location_current_satellites" + android:textColor="?text_color_grey" /> </RelativeLayout> + </RelativeLayout> - <view - android:id="@+id/rose" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:layout_gravity="center_vertical" - android:layout_marginBottom="1dip" - android:layout_marginLeft="1dip" - android:layout_marginRight="1dip" - android:layout_marginTop="6dip" - android:layout_weight="1" - class="cgeo.geocaching.ui.CompassView" - android:gravity="center" - android:keepScreenOn="true" - android:padding="4dip" /> - </LinearLayout> + <view + android:id="@+id/rose" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical" + android:layout_marginBottom="1dip" + android:layout_marginLeft="1dip" + android:layout_marginRight="1dip" + android:layout_marginTop="6dip" + android:layout_weight="1" + class="cgeo.geocaching.ui.CompassView" + android:gravity="center" + android:keepScreenOn="true" + android:padding="4dip" /> -</LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout-land/coordinatesinput_dialog.xml b/main/res/layout-land/coordinatesinput_dialog.xml index 88e5e76..202f1d3 100644 --- a/main/res/layout-land/coordinatesinput_dialog.xml +++ b/main/res/layout-land/coordinatesinput_dialog.xml @@ -1,183 +1,169 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/linearLayout1" + android:id="@+id/scroller" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical" > + android:layout_height="fill_parent" + android:fillViewport="true" > - <LinearLayout style="@style/action_bar" > + <LinearLayout + android:id="@+id/scroller_child" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > - <TextView - style="@style/action_bar_title" - android:text="@string/cache_coordinates" /> - </LinearLayout> + <Spinner + android:id="@+id/spinnerCoordinateFormats" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> - <ScrollView - android:id="@+id/scroller" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:fillViewport="true" > + <TableLayout + android:id="@+id/coordTable" + android:layout_width="fill_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:stretchColumns="0,1,3,5,7" > - <LinearLayout - android:id="@+id/scroller_child" + <TableRow android:id="@+id/tableRow1" > + + <Button + android:id="@+id/ButtonLat" + style="@style/button_full" /> + + <EditText + android:id="@+id/EditTextLatDeg" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator1" + android:text="°" + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatMin" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator2" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatSec" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator3" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatSecFrac" + style="@style/edittext_full" + android:inputType="number" + android:selectAllOnFocus="true" /> + </TableRow> + + <TableRow android:id="@+id/tableRow2" > + + <Button + android:id="@+id/ButtonLon" + style="@style/button_full" /> + + <EditText + android:id="@+id/EditTextLonDeg" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator1" + android:text="°" + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonMin" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator2" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonSec" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator3" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonSecFrac" + style="@style/edittext_full" + android:inputType="number" + android:selectAllOnFocus="true" /> + </TableRow> + </TableLayout> + + <EditText + android:id="@+id/latitude" + style="@style/edittext_full" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:orientation="vertical" > + android:hint="@string/latitude" /> - <Spinner - android:id="@+id/spinnerCoordinateFormats" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> + <EditText + android:id="@+id/longitude" + style="@style/edittext_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:hint="@string/longitude" /> - <TableLayout - android:id="@+id/coordTable" - android:layout_width="fill_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:stretchColumns="0,1,3,5,7" > - - <TableRow android:id="@+id/tableRow1" > - - <Button - android:id="@+id/ButtonLat" - style="@style/button_full" /> - - <EditText - android:id="@+id/EditTextLatDeg" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator1" - android:text="°" - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatMin" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator2" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatSec" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator3" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatSecFrac" - style="@style/edittext_full" - android:inputType="number" - android:selectAllOnFocus="true" /> - </TableRow> - - <TableRow android:id="@+id/tableRow2" > - - <Button - android:id="@+id/ButtonLon" - style="@style/button_full" /> - - <EditText - android:id="@+id/EditTextLonDeg" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator1" - android:text="°" - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonMin" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator2" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonSec" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator3" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonSecFrac" - style="@style/edittext_full" - android:inputType="number" - android:selectAllOnFocus="true" /> - </TableRow> - </TableLayout> - - <EditText - android:id="@+id/latitude" - style="@style/edittext_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:hint="@string/latitude" /> + <LinearLayout + android:id="@+id/linearLayout2" + android:layout_width="fill_parent" + android:layout_height="wrap_content" > - <EditText - android:id="@+id/longitude" - style="@style/edittext_full" + <Button + android:id="@+id/current" + style="@style/button_full" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:hint="@string/longitude" /> - - <LinearLayout - android:id="@+id/linearLayout2" - android:layout_width="fill_parent" - android:layout_height="wrap_content" > - - <Button - android:id="@+id/current" - style="@style/button_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:text="@string/waypoint_my_coordinates" /> - - <Button - android:id="@+id/cache" - style="@style/button_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:text="@string/waypoint_cache_coordinates" /> - </LinearLayout> + android:layout_weight="1" + android:text="@string/waypoint_my_coordinates" /> <Button - android:id="@+id/done" + android:id="@+id/cache" style="@style/button_full" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="@string/waypoint_done" /> + android:layout_weight="1" + android:text="@string/waypoint_cache_coordinates" /> </LinearLayout> - </ScrollView> -</LinearLayout>
\ No newline at end of file + <Button + android:id="@+id/done" + style="@style/button_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/waypoint_done" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout-v11/actionbar_maps.xml b/main/res/layout-v11/actionbar_maps.xml new file mode 100644 index 0000000..3e72717 --- /dev/null +++ b/main/res/layout-v11/actionbar_maps.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> + + <!-- Empty layout, on 11+ we have a real action bar --> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" android:layout_height="match_parent"> + +</merge>
\ No newline at end of file diff --git a/main/res/layout/about_help_page.xml b/main/res/layout/about_help_page.xml index 8444094..0439e22 100644 --- a/main/res/layout/about_help_page.xml +++ b/main/res/layout/about_help_page.xml @@ -27,22 +27,6 @@ android:textSize="14sp" /> <TextView - android:id="@+id/nutshellmanual" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left" - android:layout_marginBottom="5dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:clickable="true" - android:focusable="true" - android:linksClickable="false" - android:text="@string/nutshellmanual" - android:textColor="?text_color" - android:textColorLink="?text_color_link" - android:textSize="14sp" /> - - <TextView android:id="@+id/website" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/main/res/layout/actionbar.xml b/main/res/layout/actionbar.xml deleted file mode 100644 index 098120c..0000000 --- a/main/res/layout/actionbar.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - -</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/actionbar_button_compass.xml b/main/res/layout/actionbar_button_compass.xml deleted file mode 100644 index 932444b..0000000 --- a/main/res/layout/actionbar_button_compass.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <View style="@style/action_bar_separator" /> - - <ImageView - android:id="@+id/defaultNavigation" - style="@style/action_bar_action" - android:longClickable="true" - android:onClick="goDefaultNavigation" - android:src="@drawable/actionbar_compass_dark" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/actionbar_button_map.xml b/main/res/layout/actionbar_button_map.xml deleted file mode 100644 index 9b2138a..0000000 --- a/main/res/layout/actionbar_button_map.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <View style="@style/action_bar_separator" /> - - <ImageView - style="@style/action_bar_action" - android:onClick="goMap" - android:src="@drawable/actionbar_map" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/actionbar_button_myposition.xml b/main/res/layout/actionbar_button_myposition.xml deleted file mode 100644 index 1e91419..0000000 --- a/main/res/layout/actionbar_button_myposition.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <View style="@style/action_bar_separator" /> - - <ImageSwitcher - android:id="@+id/my_position" - style="@style/action_bar_action" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/actionbar_button_search.xml b/main/res/layout/actionbar_button_search.xml deleted file mode 100644 index 2aa1a50..0000000 --- a/main/res/layout/actionbar_button_search.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <View style="@style/action_bar_separator" /> - - <ImageView - style="@style/action_bar_action" - android:onClick="goSearch" - android:src="@drawable/actionbar_search" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/actionbar_maps.xml b/main/res/layout/actionbar_maps.xml new file mode 100644 index 0000000..0e3dc0e --- /dev/null +++ b/main/res/layout/actionbar_maps.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + style="@style/action_bar" > + + <!-- Add the up chevron to the icon --> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/abc_ic_ab_back_holo_dark" /> + + <ImageView + style="@style/action_bar_action" + android:layout_marginLeft="-13dp" + android:onClick="navigateUp" /> + + <View style="@style/action_bar_separator" /> + + <TextView + android:id="@+id/actionbar_title" + style="@style/action_bar_title" + tools:ignore="InconsistentLayout" /> + + <ProgressBar + android:id="@+id/actionbar_progress" + style="@style/action_bar_progress" + android:visibility="gone" + tools:ignore="InconsistentLayout" /> + + <View style="@style/action_bar_separator" /> + + <FrameLayout style="@style/action_bar_action" > + + <CheckBox + android:id="@+id/my_position" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right" + android:button="@drawable/ic_menu_myposition" + android:checked="false" + tools:ignore="InconsistentLayout" /> + </FrameLayout> + + <!-- + No overflow (...) button here since this menu is only shown on Gingerbread, which never + features an overflow menu + --> + +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/actionbar_popup.xml b/main/res/layout/actionbar_popup.xml new file mode 100644 index 0000000..0cab165 --- /dev/null +++ b/main/res/layout/actionbar_popup.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/action_bar"> + + <TextView + android:id="@+id/actionbar_title" + style="@style/action_bar_title" /> + + <ProgressBar + android:id="@+id/actionbar_progress" + style="@style/action_bar_progress" + android:visibility="gone" /> + + <View style="@style/action_bar_separator" /> + + + <ImageView + android:id="@+id/defaultNavigation" + style="@style/action_bar_action" + android:longClickable="true" + android:src="@drawable/actionbar_compass_dark" /> + + <View style="@style/action_bar_separator" /> + + <ImageView + android:id="@+id/overflowActionBar" + style="@style/action_bar_action" + android:longClickable="true" + android:src="@drawable/abc_ic_menu_moreoverflow_normal_holo_dark" /> + + +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/actionbar_progress.xml b/main/res/layout/actionbar_progress.xml deleted file mode 100644 index 54b5875..0000000 --- a/main/res/layout/actionbar_progress.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/actionbar_progress" - style="@style/action_bar_progress" - android:visibility="gone" /> diff --git a/main/res/layout/actionbar_title.xml b/main/res/layout/actionbar_title.xml deleted file mode 100644 index 4fa5348..0000000 --- a/main/res/layout/actionbar_title.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <ImageView - style="@style/action_bar_action" - android:onClick="goHome" /> - - <View style="@style/action_bar_separator" /> - - <TextView - android:id="@+id/actionbar_title" - style="@style/action_bar_title" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/actionbar_title_no_home.xml b/main/res/layout/actionbar_title_no_home.xml deleted file mode 100644 index 6295bdc..0000000 --- a/main/res/layout/actionbar_title_no_home.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" > - - <TextView - android:id="@+id/actionbar_title" - style="@style/action_bar_title" /> - -</merge>
\ No newline at end of file diff --git a/main/res/layout/addresslist_activity.xml b/main/res/layout/addresslist_activity.xml index c48c28f..6bcbf79 100644 --- a/main/res/layout/addresslist_activity.xml +++ b/main/res/layout/addresslist_activity.xml @@ -1,11 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - <ListView android:id="@android:id/list" android:layout_width="fill_parent" @@ -14,6 +13,7 @@ android:background="?background_color" android:cacheColorHint="?background_color" android:dividerHeight="1dip" - android:padding="0dip" /> + android:padding="0dip" + tools:listitem="@layout/addresslist_item" /> </LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/authorization_activity.xml b/main/res/layout/authorization_activity.xml index 28c1987..2907286 100644 --- a/main/res/layout/authorization_activity.xml +++ b/main/res/layout/authorization_activity.xml @@ -1,55 +1,45 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" - android:visibility="visible" > + android:padding="4dip" > - <include layout="@layout/actionbar" /> - - <ScrollView + <LinearLayout android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > + android:layout_height="wrap_content" + android:orientation="vertical" > - <LinearLayout + <TextView + android:id="@+id/auth_1" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:orientation="vertical" > - - <TextView - android:id="@+id/auth_1" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_gravity="left|center_vertical" - android:layout_marginBottom="20dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:drawableLeft="@drawable/cgeo" - android:drawablePadding="15dip" - android:gravity="left|center_vertical" - android:textColor="?text_color" - android:textSize="14sp" /> - - <TextView - android:id="@+id/auth_2" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left|center_vertical" - android:layout_marginBottom="5dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:gravity="left|center_vertical" - android:textColor="?text_color" - android:textSize="14sp" /> - - <Button - android:id="@+id/start" - style="@style/button_full" - android:layout_margin="7dip" /> - - </LinearLayout> - </ScrollView> - -</LinearLayout>
\ No newline at end of file + android:layout_gravity="left|center_vertical" + android:layout_marginBottom="20dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:drawableLeft="@drawable/cgeo" + android:drawablePadding="15dip" + android:gravity="left|center_vertical" + android:textColor="?text_color" + android:textSize="14sp" /> + + <TextView + android:id="@+id/auth_2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left|center_vertical" + android:layout_marginBottom="5dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:gravity="left|center_vertical" + android:textColor="?text_color" + android:textSize="14sp" /> + + <Button + android:id="@+id/start" + style="@style/button_full" + android:layout_margin="7dip" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/cachedetail_activity.xml b/main/res/layout/cachedetail_activity.xml index 3afe5f6..d197bcd 100644 --- a/main/res/layout/cachedetail_activity.xml +++ b/main/res/layout/cachedetail_activity.xml @@ -1,18 +1,11 @@ <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res/cgeo.geocaching"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="?background_color"
android:orientation="vertical" >
- <LinearLayout style="@style/action_bar" >
-
- <include layout="@layout/actionbar_title" />
-
- <include layout="@layout/actionbar_button_compass" />
- </LinearLayout>
-
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
diff --git a/main/res/layout/cachelist_spinneritem.xml b/main/res/layout/cachelist_spinneritem.xml new file mode 100644 index 0000000..58e070e --- /dev/null +++ b/main/res/layout/cachelist_spinneritem.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="?attr/dropdownListPreferredItemHeight" + android:minHeight="?attr/dropdownListPreferredItemHeight" + android:layout_gravity="left|center_vertical" + style="?attr/spinnerDropDownItemStyle" + > + + + <TextView + android:id="@android:id/text1" + tools:text="This is the title" + android:singleLine="true" + android:ellipsize="marquee" + android:layout_width="match_parent" + style="?attr/titleTextStyle" + android:layout_height="wrap_content" /> + + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + style="?attr/subtitleTextStyle" + tools:text="This is the subtitle" + android:id="@android:id/text2" /> + +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/cacheslist_activity.xml b/main/res/layout/cacheslist_activity.xml index c267f60..a12adad 100644 --- a/main/res/layout/cacheslist_activity.xml +++ b/main/res/layout/cacheslist_activity.xml @@ -4,15 +4,6 @@ android:layout_height="fill_parent" android:orientation="vertical" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - - <include layout="@layout/actionbar_progress" /> - - <include layout="@layout/actionbar_button_map" /> - </LinearLayout> - <include layout="@layout/filter_bar" /> <RelativeLayout diff --git a/main/res/layout/cacheslist_item.xml b/main/res/layout/cacheslist_item.xml index 744ca30..b43310e 100644 --- a/main/res/layout/cacheslist_item.xml +++ b/main/res/layout/cacheslist_item.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:cc="http://schemas.android.com/apk/res/cgeo.geocaching" + xmlns:cgeo="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/one_cache" android:layout_width="fill_parent" @@ -111,7 +111,7 @@ android:minHeight="28px" android:minWidth="28px" android:visibility="gone" - cc:skin="?compass" + cgeo:skin="?compass" tools:ignore="PxUsage" /> <ImageView diff --git a/main/res/layout/compass_activity.xml b/main/res/layout/compass_activity.xml index f0ab5ef..ca61cc3 100644 --- a/main/res/layout/compass_activity.xml +++ b/main/res/layout/compass_activity.xml @@ -1,124 +1,115 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - - <RelativeLayout + <LinearLayout + android:id="@+id/info1" android:layout_width="fill_parent" - android:layout_height="fill_parent" + android:layout_height="wrap_content" android:orientation="vertical" > - - <LinearLayout - android:id="@+id/info1" - android:layout_width="fill_parent" + + <TextView + android:id="@+id/destination" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:textColor="?text_color" + android:textSize="14sp" /> + + <TextView + android:id="@+id/cacheinfo" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical" > - + android:layout_gravity="center" + android:textColor="?text_color" + android:textSize="14sp" /> + + <RelativeLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" > + <TextView - android:id="@+id/destination" + android:id="@+id/heading" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center" + android:layout_alignParentLeft="true" + android:layout_gravity="left" + android:layout_marginLeft="3dip" + android:text="@null" android:textColor="?text_color" - android:textSize="14sp" /> - + android:textSize="26sp" /> + <TextView - android:id="@+id/cacheinfo" + android:id="@+id/distance" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center" + android:layout_alignParentRight="true" + android:layout_gravity="right" + android:layout_marginRight="3dip" + android:text="@null" android:textColor="?text_color" - android:textSize="14sp" /> - - <RelativeLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" > - - <TextView - android:id="@+id/heading" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_gravity="left" - android:layout_marginLeft="3dip" - android:text="@null" - android:textColor="?text_color" - android:textSize="26sp" /> - - <TextView - android:id="@+id/distance" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentRight="true" - android:layout_gravity="right" - android:layout_marginRight="3dip" - android:text="@null" - android:textColor="?text_color" - android:textSize="26sp" /> - </RelativeLayout> - </LinearLayout> - - <LinearLayout - android:id="@+id/info2" + android:textSize="26sp" /> + </RelativeLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/info2" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_marginLeft="6dip" + android:layout_marginRight="6dip" + android:orientation="vertical" > + + <TextView + android:id="@+id/nav_location" + style="@style/location_current" + android:text="@string/loc_trying" /> + + <RelativeLayout android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_marginLeft="6dip" - android:layout_marginRight="6dip" - android:orientation="vertical" > - + android:layout_height="16dip" > + <TextView - android:id="@+id/nav_location" - style="@style/location_current" - android:text="@string/loc_trying" /> - - <RelativeLayout - android:layout_width="fill_parent" - android:layout_height="16dip" > - - <TextView - android:id="@+id/nav_type" - style="@style/location_current_type" - android:textColor="?text_color_grey" - android:textIsSelectable="false" /> - - <TextView - android:id="@+id/nav_accuracy" - style="@style/location_current_accuracy" - android:textColor="?text_color_grey" - android:textIsSelectable="false" /> - - <TextView - android:id="@+id/nav_satellites" - style="@style/location_current_satellites" - android:textColor="?text_color_grey" - android:textIsSelectable="false" /> - </RelativeLayout> - </LinearLayout> - - <view - android:id="@+id/rose" - android:layout_width="fill_parent" - android:layout_height="295dip" - android:layout_above="@id/info2" - android:layout_below="@id/info1" - android:layout_centerInParent="true" - android:layout_gravity="center_horizontal" - android:layout_marginBottom="1dip" - android:layout_marginLeft="1dip" - android:layout_marginRight="1dip" - android:layout_marginTop="6dip" - class="cgeo.geocaching.ui.CompassView" - android:gravity="center" - android:keepScreenOn="true" - android:minHeight="289dip" - android:minWidth="289dip" - android:padding="4dip" /> - - </RelativeLayout> + android:id="@+id/nav_type" + style="@style/location_current_type" + android:textColor="?text_color_grey" + android:textIsSelectable="false" /> + + <TextView + android:id="@+id/nav_accuracy" + style="@style/location_current_accuracy" + android:textColor="?text_color_grey" + android:textIsSelectable="false" /> + + <TextView + android:id="@+id/nav_satellites" + style="@style/location_current_satellites" + android:textColor="?text_color_grey" + android:textIsSelectable="false" /> + </RelativeLayout> + </LinearLayout> + + <view + android:id="@+id/rose" + android:layout_width="fill_parent" + android:layout_height="295dip" + android:layout_above="@id/info2" + android:layout_below="@id/info1" + android:layout_centerInParent="true" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="1dip" + android:layout_marginLeft="1dip" + android:layout_marginRight="1dip" + android:layout_marginTop="6dip" + class="cgeo.geocaching.ui.CompassView" + android:gravity="center" + android:keepScreenOn="true" + android:minHeight="289dip" + android:minWidth="289dip" + android:padding="4dip" /> -</LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/main/res/layout/coordinatesinput_dialog.xml b/main/res/layout/coordinatesinput_dialog.xml index 4603360..9b5cb8d 100644 --- a/main/res/layout/coordinatesinput_dialog.xml +++ b/main/res/layout/coordinatesinput_dialog.xml @@ -1,175 +1,161 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/linearLayout1" + android:id="@+id/scroller" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical" > + android:layout_height="fill_parent" + android:fillViewport="true" > - <LinearLayout style="@style/action_bar" > + <LinearLayout + android:id="@+id/scroller_child" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > - <TextView - style="@style/action_bar_title" - android:text="@string/cache_coordinates" /> - </LinearLayout> + <Spinner + android:id="@+id/spinnerCoordinateFormats" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> - <ScrollView - android:id="@+id/scroller" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:fillViewport="true" > + <TableLayout + android:id="@+id/coordTable" + android:layout_width="fill_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:stretchColumns="0,1,3,5,7" > + + <TableRow android:id="@+id/tableRow1" > + + <Button + android:id="@+id/ButtonLat" + style="@style/button_full" /> + + <EditText + android:id="@+id/EditTextLatDeg" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator1" + android:text="°" + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatMin" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator2" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatSec" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LatSeparator3" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLatSecFrac" + style="@style/edittext_full" + android:inputType="number" + android:selectAllOnFocus="true" /> + </TableRow> + + <TableRow android:id="@+id/tableRow2" > + + <Button + android:id="@+id/ButtonLon" + style="@style/button_full" /> + + <EditText + android:id="@+id/EditTextLonDeg" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator1" + android:text="°" + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonMin" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator2" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonSec" + style="@style/edittext_full" + android:gravity="right" + android:inputType="number" + android:selectAllOnFocus="true" /> + + <TextView + android:id="@+id/LonSeparator3" + android:text="," + tools:ignore="HardcodedText" /> + + <EditText + android:id="@+id/EditTextLonSecFrac" + style="@style/edittext_full" + android:inputType="number" + android:selectAllOnFocus="true" /> + </TableRow> + </TableLayout> + + <EditText + android:id="@+id/latitude" + style="@style/edittext_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:hint="@string/latitude" /> + + <EditText + android:id="@+id/longitude" + style="@style/edittext_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:hint="@string/longitude" /> - <LinearLayout - android:id="@+id/scroller_child" + <Button + android:id="@+id/current" + style="@style/button_full" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:orientation="vertical" > - - <Spinner - android:id="@+id/spinnerCoordinateFormats" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - - <TableLayout - android:id="@+id/coordTable" - android:layout_width="fill_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:stretchColumns="0,1,3,5,7" > - - <TableRow android:id="@+id/tableRow1" > - - <Button - android:id="@+id/ButtonLat" - style="@style/button_full" /> - - <EditText - android:id="@+id/EditTextLatDeg" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator1" - android:text="°" - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatMin" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator2" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatSec" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LatSeparator3" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLatSecFrac" - style="@style/edittext_full" - android:inputType="number" - android:selectAllOnFocus="true" /> - </TableRow> - - <TableRow android:id="@+id/tableRow2" > - - <Button - android:id="@+id/ButtonLon" - style="@style/button_full" /> - - <EditText - android:id="@+id/EditTextLonDeg" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator1" - android:text="°" - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonMin" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator2" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonSec" - style="@style/edittext_full" - android:gravity="right" - android:inputType="number" - android:selectAllOnFocus="true" /> - - <TextView - android:id="@+id/LonSeparator3" - android:text="," - tools:ignore="HardcodedText" /> - - <EditText - android:id="@+id/EditTextLonSecFrac" - style="@style/edittext_full" - android:inputType="number" - android:selectAllOnFocus="true" /> - </TableRow> - </TableLayout> - - <EditText - android:id="@+id/latitude" - style="@style/edittext_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:hint="@string/latitude" /> - - <EditText - android:id="@+id/longitude" - style="@style/edittext_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:hint="@string/longitude" /> - - <Button - android:id="@+id/current" - style="@style/button_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/waypoint_my_coordinates" /> - - <Button - android:id="@+id/cache" - style="@style/button_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/waypoint_cache_coordinates" /> - - <Button - android:id="@+id/done" - style="@style/button_full" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/waypoint_done" /> - </LinearLayout> - </ScrollView> - -</LinearLayout>
\ No newline at end of file + android:text="@string/waypoint_my_coordinates" /> + + <Button + android:id="@+id/cache" + style="@style/button_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/waypoint_cache_coordinates" /> + + <Button + android:id="@+id/done" + style="@style/button_full" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/waypoint_done" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/editwaypoint_activity.xml b/main/res/layout/editwaypoint_activity.xml index cd0b46c..c21e25d 100644 --- a/main/res/layout/editwaypoint_activity.xml +++ b/main/res/layout/editwaypoint_activity.xml @@ -1,115 +1,107 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="vertical" + android:padding="4dip" > - <include layout="@layout/actionbar" /> - - <ScrollView + <LinearLayout android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > + android:layout_height="wrap_content" + android:orientation="vertical" > + + <Button + android:id="@+id/buttonLatitude" + style="@style/button_full" + android:freezesText="true" + android:hint="@string/latitude" /> + + <Button + android:id="@+id/buttonLongitude" + style="@style/button_full" + android:freezesText="true" + android:hint="@string/longitude" /> + + <EditText + android:id="@+id/bearing" + style="@style/edittext_full" + android:hint="@string/waypoint_bearing" + android:inputType="numberDecimal" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" - android:orientation="vertical" > - - <Button - android:id="@+id/buttonLatitude" - style="@style/button_full" - android:hint="@string/latitude" - android:freezesText="true" /> - - <Button - android:id="@+id/buttonLongitude" - style="@style/button_full" - android:hint="@string/longitude" - android:freezesText="true" /> + android:orientation="horizontal" > <EditText - android:id="@+id/bearing" + android:id="@+id/distance" style="@style/edittext_full" - android:hint="@string/waypoint_bearing" + android:layout_width="0dip" + android:layout_weight="1" + android:hint="@string/waypoint_distance" android:inputType="numberDecimal" /> - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > - - <EditText - android:id="@+id/distance" - style="@style/edittext_full" - android:layout_width="0dip" - android:layout_weight="1" - android:hint="@string/waypoint_distance" - android:inputType="numberDecimal" /> - - <Spinner - android:id="@+id/distanceUnit" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:entries="@array/distance_units" /> - </LinearLayout> - - <AutoCompleteTextView - android:id="@+id/name" - style="@style/edittext_full" - android:hint="@string/waypoint_name" /> - <Spinner - android:id="@+id/type" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:visibility="gone" /> - - <EditText - android:id="@+id/note" - style="@style/edittext_full" - android:layout_height="wrap_content" - android:hint="@string/waypoint_note" - android:inputType="textMultiLine|textCapSentences" - android:minLines="5" - android:singleLine="false" /> - - <CheckBox - android:id="@+id/wpt_visited_checkbox" - style="@style/checkbox_full" - android:text="@string/waypoint_visited" /> - - <RadioGroup - android:id="@+id/modify_cache_coordinates_group" + android:id="@+id/distanceUnit" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="gone" > - - <RadioButton - android:id="@+id/modify_cache_coordinates_nothing" - style="@style/radiobutton_wrap" - android:checked="true" - android:text="@string/waypoint_do_not_touch_cache_coordinates" /> - - <RadioButton - android:id="@+id/modify_cache_coordinates_local" - style="@style/radiobutton_wrap" - android:text="@string/waypoint_set_as_cache_coords" /> - - <RadioButton - android:id="@+id/modify_cache_coordinates_local_and_remote" - style="@style/radiobutton_wrap" - android:text="@string/waypoint_save_and_modify_on_website" - android:visibility="gone" /> - </RadioGroup> - - <Button - android:id="@+id/add_waypoint" - style="@style/button_full" - android:text="@string/waypoint_save" /> + android:entries="@array/distance_units" /> </LinearLayout> - </ScrollView> -</LinearLayout>
\ No newline at end of file + <AutoCompleteTextView + android:id="@+id/name" + style="@style/edittext_full" + android:hint="@string/waypoint_name" /> + + <Spinner + android:id="@+id/type" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + <EditText + android:id="@+id/note" + style="@style/edittext_full" + android:layout_height="wrap_content" + android:hint="@string/waypoint_note" + android:inputType="textMultiLine|textCapSentences" + android:minLines="5" + android:singleLine="false" /> + + <CheckBox + android:id="@+id/wpt_visited_checkbox" + style="@style/checkbox_full" + android:text="@string/waypoint_visited" /> + + <RadioGroup + android:id="@+id/modify_cache_coordinates_group" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" > + + <RadioButton + android:id="@+id/modify_cache_coordinates_nothing" + style="@style/radiobutton_wrap" + android:checked="true" + android:text="@string/waypoint_do_not_touch_cache_coordinates" /> + + <RadioButton + android:id="@+id/modify_cache_coordinates_local" + style="@style/radiobutton_wrap" + android:text="@string/waypoint_set_as_cache_coords" /> + + <RadioButton + android:id="@+id/modify_cache_coordinates_local_and_remote" + style="@style/radiobutton_wrap" + android:text="@string/waypoint_save_and_modify_on_website" + android:visibility="gone" /> + </RadioGroup> + + <Button + android:id="@+id/add_waypoint" + style="@style/button_full" + android:text="@string/waypoint_save" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/gpx.xml b/main/res/layout/gpx.xml index 948c265..368f3ae 100644 --- a/main/res/layout/gpx.xml +++ b/main/res/layout/gpx.xml @@ -4,8 +4,6 @@ android:layout_height="fill_parent" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - <Button android:id="@+id/select_dir" style="@style/button_full" diff --git a/main/res/layout/images_activity.xml b/main/res/layout/images_activity.xml index ccd8499..861fa7e 100644 --- a/main/res/layout/images_activity.xml +++ b/main/res/layout/images_activity.xml @@ -5,8 +5,6 @@ android:background="?background_color" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - <include layout="@layout/cachedetail_images_page" /> </LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/imageselect_activity.xml b/main/res/layout/imageselect_activity.xml index fd8eaea..690baa2 100644 --- a/main/res/layout/imageselect_activity.xml +++ b/main/res/layout/imageselect_activity.xml @@ -1,115 +1,102 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="vertical" + android:padding="4dip" > - <LinearLayout style="@style/action_bar" > + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > - <include layout="@layout/actionbar_title" /> + <RelativeLayout style="@style/separator_horizontal_layout" > - <include layout="@layout/actionbar_progress" /> - </LinearLayout> + <View style="@style/separator_horizontal" /> - <ScrollView - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/log_image" /> + </RelativeLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" - 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" /> - - <Spinner - android:id="@+id/logImageScale" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:entries="@array/log_image_scales" - android:prompt="@string/log_image_scale" /> - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > + 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> - <Button - android:id="@+id/save" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" - android:text="@android:string/yes" /> + <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" /> + + <Spinner + android:id="@+id/logImageScale" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:entries="@array/log_image_scales" + android:prompt="@string/log_image_scale" /> - <Button - android:id="@+id/cancel" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" - android:text="@android:string/no" /> - </LinearLayout> + <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> - </ScrollView> + </LinearLayout> -</LinearLayout>
\ No newline at end of file +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/internal_browser.xml b/main/res/layout/internal_browser.xml new file mode 100644 index 0000000..1e09ee0 --- /dev/null +++ b/main/res/layout/internal_browser.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <WebView + android:id="@+id/webview" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/logcache_activity.xml b/main/res/layout/logcache_activity.xml index 4bbb441..5445285 100644 --- a/main/res/layout/logcache_activity.xml +++ b/main/res/layout/logcache_activity.xml @@ -1,202 +1,173 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="vertical" + android:padding="4dip" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - - <include layout="@layout/actionbar_progress" /> - </LinearLayout> - - <ScrollView + <LinearLayout android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > + android:layout_height="wrap_content" + android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" + android:layout_marginTop="10dip" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" - android:layout_marginTop="10dip" - android:orientation="vertical" > - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > - - <Button - android:id="@+id/type" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" /> - - <Button - android:id="@+id/date" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" /> - </LinearLayout> - - <EditText - android:id="@+id/log" - style="@style/edittext_full" - android:layout_height="wrap_content" - android:hint="@string/log_new_log_text" - android:inputType="textMultiLine|textCapSentences" - android:maxLength="4000" - android:minLines="5" - android:singleLine="false" /> - - <LinearLayout - android:id="@+id/log_password_box" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="5dip" - android:orientation="vertical" - android:visibility="gone" > - <TextView - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:gravity="left" - android:padding="10dip" - android:text="@string/log_password_title" - android:textColor="?text_color" - android:textSize="22sp" /> - <EditText - android:id="@+id/log_password" - style="@style/edittext_full" - android:hint="@string/log_hint_log_password" - android:inputType="text" - android:singleLine="true" /> - </LinearLayout> - - <LinearLayout - android:id="@+id/tweet_box" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="5dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:orientation="horizontal" - android:visibility="gone" > - - <CheckBox - android:id="@+id/tweet" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left" - android:gravity="center" - android:padding="2sp" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:gravity="left" - android:paddingRight="3dip" - android:text="@string/visit_tweet" - android:textColor="?text_color" - android:textSize="14sp" /> - </LinearLayout> + android:orientation="horizontal" > <Button - android:id="@+id/image_btn" + android:id="@+id/type" style="@style/button_full" - android:text="@string/log_image_attach" /> + android:layout_width="0dip" + android:layout_weight="1" /> <Button - android:id="@+id/post" + android:id="@+id/date" style="@style/button_full" - android:text="@string/log_post" /> - - <RelativeLayout style="@style/separator_horizontal_layout" > + android:layout_width="0dip" + android:layout_weight="1" /> + </LinearLayout> - <View style="@style/separator_horizontal" /> + <EditText + android:id="@+id/log" + style="@style/edittext_full" + android:layout_height="wrap_content" + android:hint="@string/log_new_log_text" + android:inputType="textMultiLine|textCapSentences" + android:maxLength="4000" + android:minLines="5" + android:singleLine="false" /> - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/cache_log_offline" /> - </RelativeLayout> + <LinearLayout + android:id="@+id/log_password_box" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="5dip" + android:orientation="vertical" + android:visibility="gone" > - <LinearLayout + <TextView 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="@string/log_save" /> - - <Button - android:id="@+id/clear" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" - android:text="@string/log_clear" /> - </LinearLayout> + android:gravity="left" + android:padding="10dip" + android:text="@string/log_password_title" + android:textColor="?text_color" + android:textSize="22sp" /> + + <EditText + android:id="@+id/log_password" + style="@style/edittext_full" + android:hint="@string/log_hint_log_password" + android:inputType="text" + android:singleLine="true" /> </LinearLayout> + <RatingBar + android:id="@+id/gcvoteRating" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:max="5" + android:numStars="5" + android:stepSize="0.5" + android:visibility="gone" /> + + <TextView + android:id="@+id/gcvoteLabel" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:padding="10dip" + android:text="@string/log_no_rating" + android:textColor="?text_color" + android:textSize="12sp" + android:visibility="gone" /> + <LinearLayout - android:id="@+id/inventory_box" + android:id="@+id/tweet_box" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:layout_marginBottom="10dip" - android:layout_marginTop="10dip" - android:orientation="vertical" + android:layout_marginBottom="5dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:orientation="horizontal" android:visibility="gone" > - <RelativeLayout style="@style/separator_horizontal_layout" > + <CheckBox + android:id="@+id/tweet" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left" + android:gravity="center" + android:padding="2sp" /> - <View style="@style/separator_horizontal" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:gravity="left" + android:paddingRight="3dip" + android:text="@string/visit_tweet" + android:textColor="?text_color" + android:textSize="14sp" /> + </LinearLayout> + </LinearLayout> - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/cache_inventory" /> - </RelativeLayout> + <LinearLayout + android:id="@+id/inventory_box" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="10dip" + android:layout_marginTop="10dip" + android:orientation="vertical" + android:visibility="gone" > - <LinearLayout - android:id="@+id/inventory" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical" > - </LinearLayout> + <RelativeLayout style="@style/separator_horizontal_layout" > - <LinearLayout - android:id="@+id/inventory_changeall" - android:layout_width="fill_parent" - android:layout_height="wrap_content" + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/cache_inventory" /> + </RelativeLayout> + + <LinearLayout + android:id="@+id/inventory" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > + </LinearLayout> + + <LinearLayout + android:id="@+id/inventory_changeall" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:gravity="right" + android:orientation="vertical" + android:visibility="gone" > + + <Button + android:id="@+id/changebutton" + style="@style/button_full" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:layout_marginBottom="5dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:layout_weight="1" android:gravity="right" - android:orientation="vertical" - android:visibility="gone" > - - <Button - android:id="@+id/changebutton" - style="@style/button_full" - android:layout_width="wrap_content" - android:layout_height="0dp" - android:layout_marginBottom="5dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:layout_weight="1" - android:gravity="right" - android:text="@string/log_tb_changeall" - android:textSize="14sp" /> - </LinearLayout> + android:text="@string/log_tb_changeall" + android:textSize="14sp" /> </LinearLayout> </LinearLayout> - </ScrollView> + </LinearLayout> -</LinearLayout>
\ No newline at end of file +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/logs_page.xml b/main/res/layout/logs_page.xml index 9aafd83..f0a5d31 100644 --- a/main/res/layout/logs_page.xml +++ b/main/res/layout/logs_page.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="?background_color"
@@ -8,6 +9,7 @@ android:focusable="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
- android:listSelector="?background_color" >
+ android:listSelector="?background_color"
+ tools:listitem="@layout/logs_item" >
</ListView>
\ No newline at end of file diff --git a/main/res/layout/logtrackable_activity.xml b/main/res/layout/logtrackable_activity.xml index 7791409..a43e919 100644 --- a/main/res/layout/logtrackable_activity.xml +++ b/main/res/layout/logtrackable_activity.xml @@ -1,95 +1,82 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="vertical" + android:padding="4dip" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - - <include layout="@layout/actionbar_progress" /> - </LinearLayout> - - <ScrollView + <LinearLayout android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > + android:layout_height="wrap_content" + android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" - android:orientation="vertical" > + android:orientation="horizontal" > - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > + <Button + android:id="@+id/type" + style="@style/button_full" + android:layout_width="0dip" + android:layout_weight="1" /> - <Button - android:id="@+id/type" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" /> + <Button + android:id="@+id/date" + style="@style/button_full" + android:layout_width="0dip" + android:layout_weight="1" /> + </LinearLayout> - <Button - android:id="@+id/date" - style="@style/button_full" - android:layout_width="0dip" - android:layout_weight="1" /> - </LinearLayout> + <EditText + android:id="@+id/tracking" + style="@style/edittext_full" + android:hint="@string/trackable_code" + android:inputType="textCapCharacters" /> - <EditText - android:id="@+id/tracking" - style="@style/edittext_full" - android:hint="@string/trackable_code" - android:inputType="textCapCharacters" /> + <EditText + android:id="@+id/log" + style="@style/edittext_full" + android:hint="@string/log_new_log_text" + android:inputType="textMultiLine|textCapSentences" + android:lines="5" + android:maxLength="4000" + android:singleLine="false" /> - <EditText - android:id="@+id/log" - style="@style/edittext_full" - android:hint="@string/log_new_log_text" - android:inputType="textMultiLine|textCapSentences" - android:lines="5" - android:maxLength="4000" - android:singleLine="false" /> + <LinearLayout + android:id="@+id/tweet_box" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="5dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:orientation="horizontal" + android:visibility="gone" > - <LinearLayout - android:id="@+id/tweet_box" - android:layout_width="fill_parent" + <CheckBox + android:id="@+id/tweet" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="5dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:orientation="horizontal" - android:visibility="gone" > - - <CheckBox - android:id="@+id/tweet" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left" - android:gravity="center" - android:padding="2sp" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:gravity="left" - android:paddingRight="3dip" - android:text="@string/visit_tweet" - android:textColor="?text_color" - android:textSize="14sp" /> - </LinearLayout> + android:layout_gravity="left" + android:gravity="center" + android:padding="2sp" /> - <Button - android:id="@+id/post" - style="@style/button_full" - android:text="@string/log_post" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:gravity="left" + android:paddingRight="3dip" + android:text="@string/visit_tweet" + android:textColor="?text_color" + android:textSize="14sp" /> </LinearLayout> - </ScrollView> -</LinearLayout>
\ No newline at end of file + <Button + android:id="@+id/post" + style="@style/button_full" + android:text="@string/log_post" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/main_activity.xml b/main/res/layout/main_activity.xml index 9e124a1..d2bd025 100644 --- a/main/res/layout/main_activity.xml +++ b/main/res/layout/main_activity.xml @@ -1,21 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainscreen" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" > - <LinearLayout style="@style/action_bar" > - - <ImageView - style="@style/action_bar_icon_cgeo" - android:onClick="showAbout" /> - - <TextView style="@style/action_bar_title" /> - - <include layout="@layout/actionbar_button_search" /> - </LinearLayout> - <fragment android:id="@+id/status" android:name="cgeo.geocaching.StatusFragment" @@ -24,7 +14,8 @@ android:layout_alignParentTop="true" android:layout_marginLeft="16dip" android:layout_marginRight="16dip" - android:layout_marginTop="60dip" /> + android:layout_marginTop="60dip" + tools:layout="@layout/status" /> <!-- ** --> <LinearLayout diff --git a/main/res/layout/map_google.xml b/main/res/layout/map_google.xml index 5e4d82d..471c2b8 100644 --- a/main/res/layout/map_google.xml +++ b/main/res/layout/map_google.xml @@ -4,14 +4,9 @@ android:layout_height="fill_parent" android:orientation="vertical" > - <LinearLayout style="@style/action_bar" > - <include layout="@layout/actionbar_title" /> - <include layout="@layout/actionbar_progress" /> - - <include layout="@layout/actionbar_button_myposition" /> - </LinearLayout> + <include layout="@layout/actionbar_maps" /> <include layout="@layout/filter_bar" /> diff --git a/main/res/layout/map_mapsforge.xml b/main/res/layout/map_mapsforge.xml index f05ddb0..c44a3ee 100644 --- a/main/res/layout/map_mapsforge.xml +++ b/main/res/layout/map_mapsforge.xml @@ -4,14 +4,7 @@ android:layout_height="fill_parent" android:orientation="vertical" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - - <include layout="@layout/actionbar_progress" /> - - <include layout="@layout/actionbar_button_myposition" /> - </LinearLayout> + <include layout="@layout/actionbar_maps" /> <include layout="@layout/filter_bar" /> diff --git a/main/res/layout/map_mapsforge_old.xml b/main/res/layout/map_mapsforge_old.xml index ff2b9af..daa5f74 100644 --- a/main/res/layout/map_mapsforge_old.xml +++ b/main/res/layout/map_mapsforge_old.xml @@ -4,14 +4,7 @@ android:layout_height="fill_parent" android:orientation="vertical" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title" /> - - <include layout="@layout/actionbar_progress" /> - - <include layout="@layout/actionbar_button_myposition" /> - </LinearLayout> + <include layout="@layout/actionbar_maps" /> <include layout="@layout/filter_bar" /> diff --git a/main/res/layout/navigateanypoint_activity.xml b/main/res/layout/navigateanypoint_activity.xml index baa568c..22a29af 100644 --- a/main/res/layout/navigateanypoint_activity.xml +++ b/main/res/layout/navigateanypoint_activity.xml @@ -5,8 +5,6 @@ android:background="?background_color" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - <ListView android:id="@+id/historyList" android:layout_width="match_parent" diff --git a/main/res/layout/popup.xml b/main/res/layout/popup.xml index 584eb58..de94d18 100644 --- a/main/res/layout/popup.xml +++ b/main/res/layout/popup.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color_transparent" - android:orientation="vertical" > - - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title_no_home" /> - - <include layout="@layout/actionbar_button_compass" /> - </LinearLayout> + android:orientation="vertical" + tools:context=".CachePopup"> + <include layout="@layout/actionbar_popup" /> <ScrollView android:id="@+id/details_list_box" - android:layout_width="fill_parent" - android:layout_height="fill_parent" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:orientation="vertical" android:padding="4dip" > @@ -50,6 +46,7 @@ <TextView android:id="@+id/offline_text" + tools:text="@string/cache_offline_not_ready" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" diff --git a/main/res/layout/search_activity.xml b/main/res/layout/search_activity.xml index 28256f1..894c461 100644 --- a/main/res/layout/search_activity.xml +++ b/main/res/layout/search_activity.xml @@ -1,178 +1,170 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" - android:orientation="vertical" > + android:orientation="vertical" + android:padding="4dip" > - <include layout="@layout/actionbar" /> - - <ScrollView + <LinearLayout 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:orientation="vertical" > - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_coordinates" /> - </RelativeLayout> - - <Button - android:id="@+id/buttonLatitude" - style="@style/button_full" - android:hint="@string/latitude" /> - - <Button - android:id="@+id/buttonLongitude" - style="@style/button_full" - android:hint="@string/longitude" /> - - <Button - android:id="@+id/search_coordinates" - style="@style/button_full" - android:text="@string/search_coordinates_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_address" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/address" - style="@style/edittext_full" - android:hint="@string/search_address" - android:imeOptions="actionGo" /> - - <Button - android:id="@+id/search_address" - style="@style/button_full" - android:text="@string/search_address_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_geo" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/geocode" - style="@style/edittext_full" - android:hint="@string/search_geo" - android:imeOptions="actionGo" - android:inputType="textCapCharacters" - android:text="GC" - tools:ignore="HardcodedText" /> - - <Button - android:id="@+id/display_geocode" - style="@style/button_full" - android:text="@string/search_geo_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_kw" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/keyword" - style="@style/edittext_full" - android:hint="@string/search_kw_prefill" - android:imeOptions="actionGo" /> - - <Button - android:id="@+id/search_keyword" - style="@style/button_full" - android:text="@string/search_kw_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_fbu" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/finder" - style="@style/edittext_full" - android:hint="@string/search_fbu_prefill" - android:imeOptions="actionGo" /> - - <Button - android:id="@+id/search_finder" - style="@style/button_full" - android:text="@string/search_fbu_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_hbu" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/owner" - style="@style/edittext_full" - android:hint="@string/search_hbu_prefill" - android:imeOptions="actionGo" /> - - <Button - android:id="@+id/search_owner" - style="@style/button_full" - android:text="@string/search_hbu_button" /> - <!-- ** --> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/search_tb" /> - </RelativeLayout> - - <AutoCompleteTextView - android:id="@+id/trackable" - style="@style/edittext_full" - android:hint="@string/search_tb_hint" - android:imeOptions="actionGo" - android:inputType="textCapCharacters" /> - - <Button - android:id="@+id/display_trackable" - style="@style/button_full" - android:text="@string/search_tb_button" /> - </LinearLayout> - </ScrollView> - -</LinearLayout>
\ No newline at end of file + android:layout_height="wrap_content" + android:orientation="vertical" > + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_coordinates" /> + </RelativeLayout> + + <Button + android:id="@+id/buttonLatitude" + style="@style/button_full" + android:hint="@string/latitude" /> + + <Button + android:id="@+id/buttonLongitude" + style="@style/button_full" + android:hint="@string/longitude" /> + + <Button + android:id="@+id/search_coordinates" + style="@style/button_full" + android:text="@string/search_coordinates_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_address" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/address" + style="@style/edittext_full" + android:hint="@string/search_address" + android:imeOptions="actionGo" /> + + <Button + android:id="@+id/search_address" + style="@style/button_full" + android:text="@string/search_address_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_geo" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/geocode" + style="@style/edittext_full" + android:hint="@string/search_geo" + android:imeOptions="actionGo" + android:inputType="textCapCharacters" + android:text="GC" + tools:ignore="HardcodedText" /> + + <Button + android:id="@+id/display_geocode" + style="@style/button_full" + android:text="@string/search_geo_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_kw" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/keyword" + style="@style/edittext_full" + android:hint="@string/search_kw_prefill" + android:imeOptions="actionGo" /> + + <Button + android:id="@+id/search_keyword" + style="@style/button_full" + android:text="@string/search_kw_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_fbu" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/finder" + style="@style/edittext_full" + android:hint="@string/search_fbu_prefill" + android:imeOptions="actionGo" /> + + <Button + android:id="@+id/search_finder" + style="@style/button_full" + android:text="@string/search_fbu_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_hbu" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/owner" + style="@style/edittext_full" + android:hint="@string/search_hbu_prefill" + android:imeOptions="actionGo" /> + + <Button + android:id="@+id/search_owner" + style="@style/button_full" + android:text="@string/search_hbu_button" /> + <!-- ** --> + + <RelativeLayout style="@style/separator_horizontal_layout" > + + <View style="@style/separator_horizontal" /> + + <TextView + style="@style/separator_horizontal_headline" + android:text="@string/search_tb" /> + </RelativeLayout> + + <AutoCompleteTextView + android:id="@+id/trackable" + style="@style/edittext_full" + android:hint="@string/search_tb_hint" + android:imeOptions="actionGo" + android:inputType="textCapCharacters" /> + + <Button + android:id="@+id/display_trackable" + style="@style/button_full" + android:text="@string/search_tb_button" /> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/simple_dir_chooser.xml b/main/res/layout/simple_dir_chooser.xml index ece29c7..1bf9a2d 100644 --- a/main/res/layout/simple_dir_chooser.xml +++ b/main/res/layout/simple_dir_chooser.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" @@ -42,20 +43,20 @@ android:paddingTop="10dip" > <Button - android:id="@+id/simple_dir_chooser_ok" + android:id="@+id/simple_dir_chooser_cancel" style="@style/button_full" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" - android:text="@android:string/ok" /> + android:text="@android:string/cancel" /> <Button - android:id="@+id/simple_dir_chooser_cancel" + android:id="@+id/simple_dir_chooser_ok" style="@style/button_full" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" - android:text="@android:string/cancel" /> + android:text="@android:string/ok" /> </LinearLayout> <ListView @@ -63,6 +64,7 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_above="@id/buttonLayout" - android:layout_below="@+id/headerLayout" /> + android:layout_below="@+id/headerLayout" + tools:listitem="@layout/simple_dir_item" /> </RelativeLayout>
\ No newline at end of file diff --git a/main/res/layout/staticmaps_activity.xml b/main/res/layout/staticmaps_activity.xml index 2ffa70d..c8806b4 100644 --- a/main/res/layout/staticmaps_activity.xml +++ b/main/res/layout/staticmaps_activity.xml @@ -1,23 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView 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:padding="4dip" > - <include layout="@layout/actionbar" /> - - <ScrollView + <LinearLayout + android:id="@+id/maps_list" android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="4dip" > - - <LinearLayout - android:id="@+id/maps_list" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical" > - </LinearLayout> - </ScrollView> + android:layout_height="wrap_content" + android:orientation="vertical" > + </LinearLayout> -</LinearLayout>
\ No newline at end of file +</ScrollView>
\ No newline at end of file diff --git a/main/res/layout/text_preference.xml b/main/res/layout/text_preference.xml index 818b2f3..174a6d1 100644 --- a/main/res/layout/text_preference.xml +++ b/main/res/layout/text_preference.xml @@ -1,22 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="wrap_content" + android:orientation="vertical" android:paddingLeft="16dp" android:paddingRight="16dp" - android:orientation="vertical" > + tools:context=".settings.SettingsActivity" > - <TextView + <TextView android:id="@+id/textPreferenceText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" /> - <TextView + + <TextView android:id="@+id/textPreferenceSummary" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingTop="8dp" - android:visibility="gone" - android:textAppearance="?android:attr/textAppearanceSmall" /> + android:textAppearance="?android:attr/textAppearanceSmall" + android:visibility="gone" /> -</LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/usefulapps_activity.xml b/main/res/layout/usefulapps_activity.xml index 84bcf39..e15cd7a 100644 --- a/main/res/layout/usefulapps_activity.xml +++ b/main/res/layout/usefulapps_activity.xml @@ -1,12 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?background_color" android:orientation="vertical" > - <include layout="@layout/actionbar" /> - <ListView android:id="@+id/apps_list" android:layout_width="fill_parent" @@ -17,7 +16,8 @@ android:footerDividersEnabled="false" android:headerDividersEnabled="false" android:listSelector="?background_color" - android:padding="4dip" > + android:padding="4dip" + tools:listitem="@layout/usefulapps_item" > </ListView> </LinearLayout>
\ No newline at end of file diff --git a/main/res/layout/viewpager_activity.xml b/main/res/layout/viewpager_activity.xml index 14120e0..d197bcd 100644 --- a/main/res/layout/viewpager_activity.xml +++ b/main/res/layout/viewpager_activity.xml @@ -1,13 +1,11 @@ <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res/cgeo.geocaching"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="?background_color"
android:orientation="vertical" >
- <include layout="@layout/actionbar" />
-
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
diff --git a/main/res/layout/waypoint_popup.xml b/main/res/layout/waypoint_popup.xml index c8b257c..287fc3a 100644 --- a/main/res/layout/waypoint_popup.xml +++ b/main/res/layout/waypoint_popup.xml @@ -5,12 +5,7 @@ android:background="?background_color_transparent" android:orientation="vertical" > - <LinearLayout style="@style/action_bar" > - - <include layout="@layout/actionbar_title_no_home" /> - - <include layout="@layout/actionbar_button_compass" /> - </LinearLayout> + <include layout="@layout/actionbar_popup" /> <ScrollView android:id="@+id/details_list_box" diff --git a/main/res/layout/wp_threshold_preference.xml b/main/res/layout/wp_threshold_preference.xml index 22ffe9a..f3cbc86 100644 --- a/main/res/layout/wp_threshold_preference.xml +++ b/main/res/layout/wp_threshold_preference.xml @@ -1,26 +1,28 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingLeft="16dp" android:paddingRight="16dp" - android:paddingTop="8dp" > - + android:paddingTop="8dp" + tools:context=".settings.SettingsActivity" > + <SeekBar android:id="@+id/wp_threshold_seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:paddingRight="8dp" - android:layout_weight="1" /> + android:layout_weight="1" + android:paddingRight="8dp" /> <TextView android:id="@+id/wp_threshold_value_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:gravity="center" - android:layout_weight="5" /> + android:layout_weight="5" + android:gravity="center" /> -</LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/main/res/menu/abstract_logging_activity.xml b/main/res/menu/abstract_logging_activity.xml index b926dd1..586b93e 100644 --- a/main/res/menu/abstract_logging_activity.xml +++ b/main/res/menu/abstract_logging_activity.xml @@ -1,22 +1,49 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto" > <item - android:id="@+id/menu_signature" - android:icon="@drawable/ic_menu_edit" - android:title="@string/init_signature"> + android:id="@+id/menu_send" + android:enabled="true" + android:icon="@drawable/ic_menu_send" + android:title="@string/send" + cgeo:showAsAction="ifRoom|withText"> <!-- enabled=true, we show a message if logging is not possible --> </item> <item android:id="@+id/menu_templates" android:icon="@drawable/ic_menu_add" - android:title="@string/log_add"> + android:title="@string/log_add" + cgeo:showAsAction="ifRoom|withText"> + <menu /> <!-- filled dynamically --> + </item> + <item + android:id="@+id/menu_image" + android:icon="@drawable/ic_menu_attachment" + android:title="@string/log_image_attach" + android:visible="false" + cgeo:showAsAction="ifRoom|withText"> <menu /> <!-- filled dynamically --> </item> <item android:id="@+id/menu_smilies" android:icon="@drawable/ic_menu_emoticons" - android:title="@string/log_smilies"> + android:title="@string/log_smilies" + cgeo:showAsAction="ifRoom|withText"> <menu /> <!-- filled dynamically --> </item> + <item + android:id="@+id/save" + android:icon="@drawable/ic_menu_save" + android:title="@string/log_save" + android:visible="false" + cgeo:showAsAction="ifRoom|withText"> + </item> + <item + android:id="@+id/clear" + android:icon="@drawable/ic_menu_delete" + android:title="@string/log_clear" + android:visible="false" + cgeo:showAsAction="ifRoom|withText"> + </item> </menu>
\ No newline at end of file diff --git a/main/res/menu/cache_list_context.xml b/main/res/menu/cache_list_context.xml index 2767a2e..0c14241 100644 --- a/main/res/menu/cache_list_context.xml +++ b/main/res/menu/cache_list_context.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_default_navigation" @@ -9,40 +10,52 @@ <item android:id="@+id/menu_navigate" android:icon="@drawable/ic_menu_mapmode" - android:title="@string/cache_menu_navigate"> + android:title="@string/cache_menu_navigate" + cgeo:showAsAction="ifRoom|withText"> </item> <item android:id="@+id/menu_cache_details" - android:title="@string/cache_menu_details"> + android:title="@string/cache_menu_details" + cgeo:showAsAction="ifRoom|withText"> </item> <item android:id="@+id/menu_log_visit_offline" android:icon="@drawable/ic_menu_edit" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_menu_visit_offline"> </item> <item android:id="@+id/menu_log_visit" android:icon="@drawable/ic_menu_edit" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_menu_visit"> </item> <item android:id="@+id/menu_drop_cache" + cgeo:showAsAction="ifRoom|withText" + android:icon="@drawable/ic_menu_delete" android:title="@string/cache_offline_drop"> </item> <item android:id="@+id/menu_move_to_list" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_menu_move_list"> </item> <item android:id="@+id/menu_export" + cgeo:showAsAction="ifRoom|withText" android:title="@string/export"> </item> <item android:id="@+id/menu_refresh" + cgeo:showAsAction="ifRoom|withText" + android:icon="@drawable/ic_menu_refresh" android:title="@string/cache_menu_refresh"> </item> <item android:id="@+id/menu_store_cache" + cgeo:showAsAction="ifRoom|withText" + android:icon="@drawable/ic_menu_save" android:title="@string/cache_offline_store"> </item> diff --git a/main/res/menu/cache_list_options.xml b/main/res/menu/cache_list_options.xml index 418d2de..1ff0851 100644 --- a/main/res/menu/cache_list_options.xml +++ b/main/res/menu/cache_list_options.xml @@ -1,14 +1,23 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item + android:id="@+id/menu_show_on_map" + android:icon="@drawable/ic_menu_mapmode" + cgeo:showAsAction="ifRoom" + android:title="@string/caches_on_map"> + </item> + <item android:id="@+id/menu_filter" android:icon="@drawable/ic_menu_filter" + cgeo:showAsAction="ifRoom|withText" android:title="@string/caches_filter"> </item> <item android:id="@+id/menu_sort" android:icon="@drawable/ic_menu_sort_alphabetically" + cgeo:showAsAction="ifRoom|withText" android:title="@string/caches_sort"> </item> <item @@ -92,27 +101,15 @@ </menu> </item> <item - android:id="@+id/submenu_manage_lists" - android:icon="@drawable/ic_menu_more" - android:title="@string/list_menu"> - <menu> - <item - android:id="@+id/menu_create_list" - android:title="@string/list_menu_create"> - </item> - <item - android:id="@+id/menu_drop_list" - android:title="@string/list_menu_drop"> - </item> - <item - android:id="@+id/menu_rename_list" - android:title="@string/list_menu_rename"> - </item> - <item - android:id="@+id/menu_switch_list" - android:title="@string/list_menu_change"> - </item> - </menu> + android:id="@+id/menu_create_list" + android:title="@string/list_menu_create"> + </item> + <item + android:id="@+id/menu_drop_list" + android:title="@string/list_menu_drop"> + </item> + <item + android:id="@+id/menu_rename_list" + android:title="@string/list_menu_rename"> </item> - </menu>
\ No newline at end of file diff --git a/main/res/menu/cache_options.xml b/main/res/menu/cache_options.xml index d2951f4..9610836 100644 --- a/main/res/menu/cache_options.xml +++ b/main/res/menu/cache_options.xml @@ -1,45 +1,76 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/menu_default_navigation" android:icon="@drawable/ic_menu_compass" - android:title="@string/cache_menu_navigate"> <!-- will be replaced --> + android:title="@string/cache_menu_navigate" + cgeo:showAsAction="ifRoom"> <!-- will be replaced --> </item> <item android:id="@+id/menu_navigate" android:icon="@drawable/ic_menu_mapmode" - android:title="@string/cache_menu_navigate"> - </item> - <item - android:id="@+id/menu_calendar" - android:icon="@drawable/ic_menu_agenda" - android:title="@string/cache_menu_event"> + android:title="@string/cache_menu_navigate" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_log_visit_offline" android:icon="@drawable/ic_menu_edit" - android:title="@string/cache_menu_visit_offline"> + android:title="@string/cache_menu_visit_offline" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_log_visit" android:icon="@drawable/ic_menu_edit" - android:title="@string/cache_menu_visit"> + android:title="@string/cache_menu_visit" + cgeo:showAsAction="ifRoom"> + </item> + <item + android:id="@+id/menu_calendar" + android:icon="@drawable/ic_menu_my_calendar" + android:title="@string/cache_menu_event" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_caches_around" android:icon="@drawable/ic_menu_rotate" - android:title="@string/cache_menu_around"> + android:title="@string/cache_menu_around" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_show_in_browser" android:icon="@drawable/ic_menu_info_details" - android:title="@string/cache_menu_browser"> + android:title="@string/cache_menu_browser" + cgeo:showAsAction="ifRoom"> + </item> + <item + android:id="@+id/menu_store" + android:icon="@drawable/ic_menu_save" + android:title="@string/cache_offline_store" + android:visible="false" + cgeo:showAsAction="ifRoom"> + </item> + <item + android:id="@+id/menu_refresh" + android:icon="@drawable/ic_menu_refresh" + android:title="@string/cache_offline_refresh" + android:visible="false" + cgeo:showAsAction="ifRoom"> + </item> + <item + android:id="@+id/menu_delete" + android:icon="@drawable/ic_menu_delete" + android:title="@string/cache_offline_drop" + android:visible="false" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_share" android:icon="@drawable/ic_menu_share" - android:title="@string/cache_menu_share"> + android:title="@string/cache_menu_share" + cgeo:actionProviderClass="android.support.v7.widget.ShareActionProvider" + cgeo:showAsAction="ifRoom"> </item> - + </menu>
\ No newline at end of file diff --git a/main/res/menu/compass_activity_options.xml b/main/res/menu/compass_activity_options.xml index 01c7d36..e2c6c8a 100644 --- a/main/res/menu/compass_activity_options.xml +++ b/main/res/menu/compass_activity_options.xml @@ -1,36 +1,43 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_switch_compass_gps" android:icon="@drawable/ic_menu_compass" + cgeo:showAsAction="never|withText" android:title="@string/use_gps"> <!-- will be replaced in code --> </item> <item android:id="@+id/menu_map" android:icon="@drawable/ic_menu_mapmode" + cgeo:showAsAction="ifRoom|withText" android:title="@string/caches_on_map"> </item> <item android:id="@+id/menu_edit_destination" android:icon="@drawable/ic_menu_edit" + cgeo:showAsAction="ifRoom|withText" android:title="@string/destination_set"> </item> <item android:id="@+id/menu_select_destination" android:icon="@drawable/ic_menu_myplaces" + cgeo:showAsAction="ifRoom|withText" android:title="@string/destination_select"> <menu /> <!-- filled dynamically --> </item> <item android:id="@+id/menu_tts_start" android:icon="@drawable/ic_menu_start_conversation" + cgeo:showAsAction="ifRoom|withText" android:title="@string/tts_start"> </item> <item android:id="@+id/menu_tts_stop" android:icon="@drawable/ic_menu_start_conversation" android:title="@string/tts_stop" + cgeo:showAsAction="ifRoom|withText" android:visible="false"> </item> diff --git a/main/res/menu/details_context.xml b/main/res/menu/details_context.xml index 3125459..fc61d5d 100644 --- a/main/res/menu/details_context.xml +++ b/main/res/menu/details_context.xml @@ -1,26 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/menu_copy" - android:title="@android:string/copy"> + android:icon="@drawable/ic_menu_copy" + android:title="@android:string/copy" + cgeo:showAsAction="always|withText"> </item> <item android:id="@+id/menu_translate_to_sys_lang" - android:title="@string/translate_to_sys_lang"> + android:title="@string/translate_to_sys_lang" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_translate_to_english" - android:title="@string/translate_to_english"> + android:title="@string/translate_to_english" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_cache_share_field" - android:title="@string/cache_share_field"> + android:title="@string/cache_share_field" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_calendar" + android:icon="@drawable/ic_menu_my_calendar" android:title="@string/cache_menu_event" - android:visible="false"> + android:visible="false" + cgeo:showAsAction="ifRoom"> </item> </menu>
\ No newline at end of file diff --git a/main/res/menu/images_list_context.xml b/main/res/menu/images_list_context.xml index 75d0ca0..0726267 100644 --- a/main/res/menu/images_list_context.xml +++ b/main/res/menu/images_list_context.xml @@ -1,12 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/image_open_file" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_image_open_file"> </item> <item android:id="@+id/image_open_browser" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_image_open_browser"> </item> diff --git a/main/res/menu/logging_ui.xml b/main/res/menu/logging_ui.xml index a8622c5..5baacfc 100644 --- a/main/res/menu/logging_ui.xml +++ b/main/res/menu/logging_ui.xml @@ -1,14 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_log_visit_offline" android:icon="@drawable/ic_menu_edit" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_menu_visit_offline"> </item> <item android:id="@+id/menu_log_visit" android:icon="@drawable/ic_menu_edit" + cgeo:showAsAction="ifRoom|withText" android:title="@string/cache_menu_visit"> </item> diff --git a/main/res/menu/main_activity_options.xml b/main/res/menu/main_activity_options.xml index fc949dc..6e5a198 100644 --- a/main/res/menu/main_activity_options.xml +++ b/main/res/menu/main_activity_options.xml @@ -1,34 +1,50 @@ <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:cgeo="http://schemas.android.com/apk/res-auto" >
+ <!-- TODO: use ic_action_search -->
<item
- android:id="@+id/menu_settings"
- android:icon="@drawable/ic_menu_preferences"
- android:title="@string/menu_settings">
- </item>
+ android:id="@+id/menu_gosearch"
+ style="@style/action_bar_action"
+ android:icon="@drawable/abc_ic_search"
+ android:title="@string/search_bar_hint"
+ cgeo:actionViewClass="android.support.v7.widget.SearchView"
+ cgeo:showAsAction="collapseActionView|always"/>
<item
android:id="@+id/menu_history"
android:icon="@drawable/ic_menu_recent_history"
- android:title="@string/menu_history">
+ android:title="@string/menu_history"
+ cgeo:showAsAction="ifRoom">
</item>
<item
android:id="@+id/menu_pocket_queries"
android:icon="@drawable/ic_menu_account_list"
- android:title="@string/menu_pocket_queries">
+ android:title="@string/menu_pocket_queries"
+ cgeo:showAsAction="ifRoom">
+ </item>
+ <item
+ android:id="@+id/menu_settings"
+ android:icon="@drawable/ic_menu_preferences"
+ android:title="@string/menu_settings"
+ cgeo:showAsAction="ifRoom">
</item>
<item
android:id="@+id/menu_helpers"
android:icon="@drawable/ic_menu_shopping"
- android:title="@string/menu_helpers">
+ android:title="@string/menu_helpers"
+ cgeo:showAsAction="ifRoom">
</item>
<item
android:id="@+id/menu_scan"
android:icon="@drawable/ic_menu_barcode"
- android:title="@string/menu_scan_geo">
+ android:title="@string/menu_scan_geo"
+ cgeo:showAsAction="ifRoom">
</item>
<item
android:id="@+id/menu_about"
android:icon="@drawable/ic_menu_info_details"
- android:title="@string/menu_about">
+ android:title="@string/menu_about"
+ cgeo:showAsAction="ifRoom">
</item>
+
</menu>
\ No newline at end of file diff --git a/main/res/menu/map_activity.xml b/main/res/menu/map_activity.xml index d81a49b..4c1dfd7 100644 --- a/main/res/menu/map_activity.xml +++ b/main/res/menu/map_activity.xml @@ -1,10 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto" > <item + android:id="@+id/menu_toggle_mypos" + android:icon="@drawable/ic_menu_myposition" + android:showAsAction="always" + android:title="@string/menu_centerposition" + cgeo:showAsAction="always"/> + <item android:id="@+id/menu_select_mapview" android:icon="@drawable/ic_menu_mapmode" - android:title="@string/map_view_map"> + android:title="@string/map_view_map" + cgeo:showAsAction="ifRoom|withText"> <menu> <group android:id="@+id/menu_group_map_sources" @@ -15,42 +23,51 @@ <item android:id="@+id/menu_map_live" android:icon="@drawable/ic_menu_refresh" - android:title="@string/map_live_disable"> + android:title="@string/map_live_disable" + cgeo:showAsAction="ifRoom|withText"> </item> <item android:id="@+id/menu_store_caches" - android:enabled="false" android:icon="@drawable/ic_menu_set_as" - android:title="@string/caches_store_offline"> + android:title="@string/caches_store_offline" + cgeo:showAsAction="ifRoom|withText"> </item> <item android:id="@+id/submenu_modes" android:icon="@drawable/ic_menu_mark" - android:title="@string/map_modes"> + android:title="@string/map_modes" + cgeo:showAsAction="ifRoom|withText"> <menu> <item android:id="@+id/menu_trail_mode" + android:checkable="true" android:icon="@drawable/ic_menu_trail" - android:title="@string/map_trail_hide"> + android:title="@string/map_trail_show" + cgeo:showAsAction="ifRoom|withText"> </item> <item android:id="@+id/menu_circle_mode" + android:checkable="true" android:icon="@drawable/ic_menu_circle" - android:title="@string/map_circles_hide"> - </item> - <item - android:id="@+id/menu_mycaches_mode" - android:icon="@android:drawable/ic_menu_myplaces" - android:title="@string/map_mycaches_hide"> + android:title="@string/map_circles_show" + cgeo:showAsAction="ifRoom|withText"> </item> <item - android:id="@+id/menu_theme_mode" - android:icon="@drawable/ic_menu_preferences" - android:title="@string/map_theme_select"> + android:id="@+id/menu_mycaches_mode" + android:checkable="true" + android:icon="@android:drawable/ic_menu_myplaces" + android:title="@string/map_mycaches_hide" + cgeo:showAsAction="ifRoom|withText"> </item> </menu> </item> <item + android:id="@+id/menu_theme_mode" + android:icon="@drawable/ic_menu_preferences" + android:title="@string/map_theme_select" + cgeo:showAsAction="ifRoom|withText"> + </item> + <item android:id="@+id/submenu_strategy" android:icon="@drawable/ic_menu_preferences" android:title="@string/map_strategy"> diff --git a/main/res/menu/navigate_any_point_activity_options.xml b/main/res/menu/navigate_any_point_activity_options.xml index 4f199e2..a17405b 100644 --- a/main/res/menu/navigate_any_point_activity_options.xml +++ b/main/res/menu/navigate_any_point_activity_options.xml @@ -1,25 +1,30 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_navigate" android:icon="@drawable/ic_menu_mapmode" - android:title="@string/cache_menu_navigate"> + android:title="@string/cache_menu_navigate" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_default_navigation" android:icon="@drawable/ic_menu_compass" - android:title="@string/cache_menu_navigate"> <!-- will be replaced in code --> + android:title="@string/cache_menu_navigate" + cgeo:showAsAction="ifRoom"> <!-- will be replaced in code --> </item> <item android:id="@+id/menu_caches_around" android:icon="@drawable/ic_menu_rotate" - android:title="@string/cache_menu_around"> + android:title="@string/cache_menu_around" + cgeo:showAsAction="ifRoom"> </item> <item android:id="@+id/menu_clear_history" android:icon="@drawable/ic_menu_delete" - android:title="@string/search_clear_history"> + android:title="@string/search_clear_history" + cgeo:showAsAction="ifRoom"> </item> </menu>
\ No newline at end of file diff --git a/main/res/menu/search_activity_options.xml b/main/res/menu/search_activity_options.xml index fcd7401..c4ee62b 100644 --- a/main/res/menu/search_activity_options.xml +++ b/main/res/menu/search_activity_options.xml @@ -1,10 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_search_own_caches" android:icon="@drawable/ic_menu_myplaces" - android:title="@string/search_own_caches"> + android:title="@string/search_own_caches" + cgeo:showAsAction="ifRoom|withText" + > </item> </menu>
\ No newline at end of file diff --git a/main/res/menu/static_maps_activity_options.xml b/main/res/menu/static_maps_activity_options.xml index 7850c92..8621153 100644 --- a/main/res/menu/static_maps_activity_options.xml +++ b/main/res/menu/static_maps_activity_options.xml @@ -1,9 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_refresh" android:icon="@drawable/ic_menu_refresh" + cgeo:showAsAction="ifRoom" android:title="@string/cache_offline_refresh"> </item> diff --git a/main/res/menu/trackable_activity.xml b/main/res/menu/trackable_activity.xml index ddf45f6..60eaa9e 100644 --- a/main/res/menu/trackable_activity.xml +++ b/main/res/menu/trackable_activity.xml @@ -1,14 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_log_touch" android:icon="@drawable/ic_menu_agenda" + cgeo:showAsAction="ifRoom|withText" android:title="@string/trackable_log_touch"> </item> <item android:id="@+id/menu_browser_trackable" android:icon="@drawable/ic_menu_info_details" + cgeo:showAsAction="ifRoom|withText" android:title="@string/trackable_browser_open"> </item> diff --git a/main/res/menu/waypoint_options.xml b/main/res/menu/waypoint_options.xml index f03cca6..5aaeac2 100644 --- a/main/res/menu/waypoint_options.xml +++ b/main/res/menu/waypoint_options.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:cgeo="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_waypoint_reset_cache_coords" diff --git a/main/res/values-ca/strings.xml b/main/res/values-ca/strings.xml index 527282c..4cd90db 100644 --- a/main/res/values-ca/strings.xml +++ b/main/res/values-ca/strings.xml @@ -18,6 +18,7 @@ <string name="letterbox">Letterbox</string> <string name="event">Trobada</string> <string name="mega">Mega</string> + <string name="giga">Giga</string> <string name="earth">Earthcatxé</string> <string name="cito">Trobada CITO</string> <string name="webcam">Webcam</string> @@ -79,21 +80,9 @@ <string name="log_saving_and_uploading">S\'està enviant el registre i pujant la imatge…</string> <string name="log_clear">Esborra</string> <string name="log_post">Envia el registre</string> - <string name="log_post_rate">Envia el registre i la valoració</string> - <string name="log_post_no_rate">Envia el registre sense valoració</string> <string name="log_post_not_possible">S\'està carregant la pàgina del registre…</string> <string name="log_add">Afegeix</string> - <string name="log_rating">Puntuació</string> <string name="log_no_rating">Sense puntuació</string> - <string name="log_stars_1">1 estrella</string> - <string name="log_stars_15">1,5 estrelles</string> - <string name="log_stars_2">2 estrelles</string> - <string name="log_stars_25">2,5 estrelles</string> - <string name="log_stars_3">3 estrelles</string> - <string name="log_stars_35">3,5 estrelles</string> - <string name="log_stars_4">4 estrelles</string> - <string name="log_stars_45">4,5 estrelles</string> - <string name="log_stars_5">5 estrelles</string> <string name="log_stars_1_description">Pobre</string> <string name="log_stars_15_description">Bastant pobre</string> <string name="log_stars_2_description">Per sota de la mitjana</string> @@ -112,7 +101,6 @@ <string name="log_smilies">Emoticones</string> <string name="log_image">Imatge</string> <string name="log_image_attach">Adjunta una imatge</string> - <string name="log_image_edit">Edita la imatge</string> <string name="log_image_stored">Existent</string> <string name="log_image_camera">Nou</string> <string name="log_image_caption">Títol</string> @@ -121,6 +109,13 @@ <string name="log_password_title">Contrasenya d\'accés:</string> <string name="log_hint_log_password">Introduïu la contrasenya d\'accés</string> <string name="log_oc_team_comment">Comentari de l\'equip OC</string> + <string-array name="log_image_scales"> + <item>Sense escala</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Tradueix a %s</string> <string name="translate_to_english">Tradueix a l\'anglès</string> <string name="translate_length_warning">La traducció pot fallar amb una gran quantitat de text.</string> @@ -241,6 +236,10 @@ <string name="caches_more_caches_currently">actualment</string> <string name="caches_downloading">S\'estan descarregant els catxés…\nETA: </string> <string name="caches_eta_ltm">Menys d\'un minut</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minut</item> + <item quantity="other">minuts</item> + </plurals> <string name="caches_store_offline">Desa per usar fora de línia</string> <string name="caches_store_selected">Desa els seleccionats</string> <string name="caches_history">Historial</string> @@ -282,6 +281,7 @@ <string name="caches_move_all">Mou-ho tot</string> <string name="caches_map_locus">Locus</string> <string name="caches_map_locus_export">Exporta al Locus</string> + <string name="caches_map_mapswithme">MapsWithMe</string> <string name="caches_recaptcha_title">reCAPTCHA</string> <string name="caches_recaptcha_explanation">Introduïu el text de la imatge. Això permet la baixada de les coordenades del catxé, que es pot desactivar a la configuració.</string> <string name="caches_recaptcha_hint">Text de la imatge</string> @@ -301,10 +301,8 @@ <string name="caches_removing_from_history">S\'està eliminant de l\'historial…</string> <string name="caches_clear_offlinelogs">Neteja els registres fora de línea</string> <string name="caches_clear_offlinelogs_progress">S\'estan netejant els registres fora línia</string> - <string name="list_menu">Llista</string> <string name="list_menu_create">Crea una llista nova</string> <string name="list_menu_drop">Elimina la llista actual</string> - <string name="list_menu_change">Canvia de llista</string> <string name="list_menu_rename">Reanomena la llista actual</string> <string name="list_title">Trieu una llista</string> <string name="list_inbox">Desats</string> @@ -402,8 +400,8 @@ <string name="init_signature_template_log">Text del registre</string> <string name="init_ratingwanted">Valoració del GCvote</string> <string name="init_summary_ratingwanted">Descarrega la valoració des de GCvote.com</string> - <string name="init_friendlogswanted">Mostra els registres d\'amics</string> - <string name="init_summary_friendlogswanted">Mostra els registres dels amics a una altra pàgina</string> + <string name="init_friends_and_own_logs_wanted">Mostra els dels amics i els propis</string> + <string name="init_summary_friends_and_own_logs_wanted">Visualitza una pàgina addicional del llibre de registre pels registres dels amics i els propis</string> <string name="init_openlastdetailspage">Obre l\'última pàgina de detalls</string> <string name="init_summary_openlastdetailspage">Obre els detalls amb l\'última pàgina utilitzada</string> <string name="init_autoload">Descripció llarga</string> @@ -524,7 +522,7 @@ <string name="init_sendToCgeo_description"><b>Send2c:geo</b> us permet enviar els catxés al vostre aparell Android directament des de Geocaching.com utilitzant un complement especial per al Firefox o pel Chrome. Abans de registrar-vos veieu <a href="http://send2.cgeo.org/"> http://send2.cgeo.org/</a>. Només cal que us registreu si voleu utilitzar el send2c:geo.</string> <string name="init_sendToCgeo_register">Sol·licita registre</string> <string name="init_sendToCgeo_registering">S\'està registrant el dispositiu per Send2c:geo…</string> - <string name="init_sendToCgeo_register_ok">Us heu registrat correctament. El codi PIN és # # #. Utilitzeu-lo al web del c:geo per connectar aquest dispositiu al navegador.</string> + <string name="init_sendToCgeo_register_ok">Us heu registrat correctament. El codi PIN és ####. Utilitzeu-lo al web del c:geo per connectar aquest dispositiu al navegador.</string> <string name="init_sendToCgeo_register_fail">S\'ha produït un error en el registre del sendToCgeo.</string> <string name="sendToCgeo_download_fail">El c:geo ha fallat al descarregar els catxés. No hi ha connexió a Internet o el send2c:geo no funciona.</string> <string name="sendToCgeo_no_registration">S\'ha produït un error descarregant els catxés. El registre a send2c:geo ha caducat. Registreu-vos de nou a la configuració.</string> @@ -542,6 +540,10 @@ <string name="auth_ocus">opencaching.us</string> <string name="auth_ocro">opencaching.ro</string> <string name="auth_dialog_completed_oc">El c:geo ara està autoritzat a interactuar amb %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Un catxé</item> + <item quantity="other">%1$d catxés</item> + </plurals> <string name="cache_offline">Fora de línia</string> <string name="cache_offline_refresh">Actualitza</string> <string name="cache_offline_drop">Esborra</string> @@ -568,8 +570,6 @@ <string name="cache_personal_note_uploading">S\'està pujant la nota personal</string> <string name="cache_personal_note_upload_done">S\'ha pujat la nota personal</string> <string name="cache_personal_note_upload_cancelled">S\'ha cancel·lat la pujada de la nota personal</string> - <string name="cache_personal_note_unstored">El catxé no s\'ha desat</string> - <string name="cache_personal_note_store">El catxé es desa en primer lloc per permetre una nota personal.</string> <string name="cache_description">Descripció</string> <string name="cache_description_long">Descripció llarga</string> <string name="cache_description_table_note">La descripció conté un format que pot necessitar visualitzar-se a %s per a veure\'s correctament.</string> @@ -586,10 +586,14 @@ <string name="cache_list_unknown">No està a cap llista</string> <string name="cache_images">Imatges</string> <string name="cache_waypoints">Fites</string> + <plurals name="waypoints"> + <item quantity="one">1 fita</item> + <item quantity="other">%d fites</item> + </plurals> <string name="cache_waypoints_add">Afegeix una fita</string> <string name="cache_hint">Pista</string> <string name="cache_logs">Llibre de registre</string> - <string name="cache_logsfriends">Llibre de registre (Amics)</string> + <string name="cache_logs_friends_and_own">Registres dels amics o propis</string> <string name="cache_dialog_loading_details">S\'està carregant els detalls del catxé…</string> <string name="cache_dialog_loading_details_status_loadpage">S\'està carregant la pàgina</string> <string name="cache_dialog_loading_details_status_details">S\'està processant els detalls</string> @@ -635,15 +639,15 @@ <string name="cache_menu_refresh">Actualitza</string> <string name="cache_menu_share">Comparteix el catxé</string> <string name="cache_menu_move_list">Mou a una llista diferent</string> - <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">Catxé de balisa</string> <string name="cache_menu_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> + <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Estat</string> <string name="cache_status_offline_log">Registre desat</string> <string name="cache_status_found">Trobat</string> + <string name="cache_not_status_found">No s\'ha trobat</string> <string name="cache_status_archived">Arxivat</string> <string name="cache_status_disabled">Desactivat</string> <string name="cache_status_premium">Només per membres Premium</string> @@ -755,10 +759,7 @@ <string name="map_view_map">Tria el mapa</string> <string name="map_modes">Configuració del mapa</string> <string name="map_trail_show">Mostra la ruta</string> - <string name="map_trail_hide">Amaga la ruta</string> <string name="map_circles_show">Mostra els cercles</string> - <string name="map_circles_hide">Amaga els cercles</string> - <string name="map_mycaches_show">Mostra els catxés propis/trobats</string> <string name="map_mycaches_hide">Amaga els catxés propis/trobats</string> <string name="map_theme_builtin">Per defecte</string> <string name="map_theme_select">Trieu els detalls del mapa</string> @@ -1112,7 +1113,6 @@ <string name="website">Lloc web: <a href=""> cgeo.org</a></string> <string name="facebook">Facebook: <a href="">Pàgina del c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">El c:geo a Google Play</a></string> <string name="about_twitter">Voleu que <b>el c:geo</b> publiqui un nou estatus al Twitter cada vegada que registreu un catxé?</string> <string name="faq">PMF: <a href=""> faq.cgeo.org</a></string> @@ -1128,50 +1128,28 @@ <string name="tts_stop">Deixa de parlar</string> <string name="err_tts_lang_not_supported">La llengua actual no és compatible amb la síntesi de veu.</string> <string name="tts_one_kilometer">un quilòmetre</string> - <string name="tts_one_meter">un metre</string> - <string name="tts_one_mile">una milla</string> - <string name="tts_one_foot">un peu</string> - <string name="tts_one_oclock">la una en punt</string> - <string name="tts_oclock">%s en punt</string> - <string name="clipboard_copy_ok">S\'ha copiat al portapapers</string> - <string name="percent_favorite_points">% \ preferits</string> - <string name="cgeo_shortcut">Drecera del c:geo</string> - <string name="create_shortcut">Crea una drecera</string> - <string-array name="log_image_scales"> - <item>Sense escala</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minut</item> - <item quantity="other">minuts</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Un catxé</item> - <item quantity="other">%1$d catxés</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 fita</item> - <item quantity="other">%d fites</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s quilòmetre</item> <item quantity="other">%s quilòmetres</item> </plurals> + <string name="tts_one_meter">un metre</string> <plurals name="tts_meters"> <item quantity="one">%s metre</item> <item quantity="other">%s metres</item> </plurals> + <string name="tts_one_mile">una milla</string> <plurals name="tts_miles"> <item quantity="one">%s milla</item> <item quantity="other">%s milles</item> </plurals> + <string name="tts_one_foot">un peu</string> <plurals name="tts_feet"> <item quantity="one">%s peu</item> <item quantity="other">%s peus</item> </plurals> + <string name="tts_one_oclock">la una en punt</string> + <string name="tts_oclock">%s en punt</string> + <string name="clipboard_copy_ok">S\'ha copiat al portapapers</string> <plurals name="days_ago"> <item quantity="one">ahir</item> <item quantity="other">fa %d dies</item> @@ -1180,4 +1158,7 @@ <item quantity="one">%s preferit</item> <item quantity="other">%s preferits</item> </plurals> + <string name="percent_favorite_points">% \ preferits</string> + <string name="cgeo_shortcut">Drecera del c:geo</string> + <string name="create_shortcut">Crea una drecera</string> </resources> diff --git a/main/res/values-cs/strings.xml b/main/res/values-cs/strings.xml index 3202869..e6d3c28 100644 --- a/main/res/values-cs/strings.xml +++ b/main/res/values-cs/strings.xml @@ -12,7 +12,7 @@ <string name="settings_titlebar">c:geo Nastavení</string> <string name="all_types">Všechny typy keší</string> <string name="traditional">Tradiční keš</string> - <string name="multi">Multi-keš</string> + <string name="multi">Multi keš</string> <string name="mystery">Mystery keš</string> <string name="letterbox">Dopisní schránka</string> <string name="event">Keš události</string> @@ -78,21 +78,9 @@ <string name="log_saving_and_uploading">Odesílání Logu a nahrávání obrázku…</string> <string name="log_clear">Vyčistit</string> <string name="log_post">Odeslat Log</string> - <string name="log_post_rate">Odeslat Log a hlasovat</string> - <string name="log_post_no_rate">Odeslat Log a nehlasovat</string> <string name="log_post_not_possible">Načítání stránky s Logovacím formulářem…</string> <string name="log_add">Přidat</string> - <string name="log_rating">Hodnocení</string> <string name="log_no_rating">Bez hodnocení</string> - <string name="log_stars_1">1 hvězdička</string> - <string name="log_stars_15">1,5 hvězdičky</string> - <string name="log_stars_2">2 hvězdičky</string> - <string name="log_stars_25">2,5 hvězdičky</string> - <string name="log_stars_3">3 hvězdičky</string> - <string name="log_stars_35">3,5 hvězdičky</string> - <string name="log_stars_4">4 hvězdičky</string> - <string name="log_stars_45">4,5 hvězdičky</string> - <string name="log_stars_5">5 hvězdiček</string> <string name="log_stars_1_description">Slabá</string> <string name="log_stars_15_description">Docela slabá</string> <string name="log_stars_2_description">Podprůměrná</string> @@ -111,7 +99,6 @@ <string name="log_smilies">Smajlíci</string> <string name="log_image">Obrázek</string> <string name="log_image_attach">Připojit obrázek</string> - <string name="log_image_edit">Upravit obrázek</string> <string name="log_image_stored">Existující</string> <string name="log_image_camera">Nový</string> <string name="log_image_caption">Titulek</string> @@ -120,6 +107,13 @@ <string name="log_password_title">Logovací heslo:</string> <string name="log_hint_log_password">Zadej své logovací heslo</string> <string name="log_oc_team_comment">Komentář týmu OC</string> + <string-array name="log_image_scales"> + <item>Bez měřítka</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Přeložit do %s</string> <string name="translate_to_english">Přeložit do angličtiny</string> <string name="translate_length_warning">Při velkém množství textu může překládání selhat.</string> @@ -240,6 +234,11 @@ <string name="caches_more_caches_currently">aktuálně</string> <string name="caches_downloading">Stahování keší…\nETA:</string> <string name="caches_eta_ltm">Méně než minutu</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuta</item> + <item quantity="few">minuty</item> + <item quantity="other">minuty</item> + </plurals> <string name="caches_store_offline">Uložit pro offline</string> <string name="caches_store_selected">Uložit vybrané</string> <string name="caches_history">Historie</string> @@ -301,10 +300,8 @@ <string name="caches_removing_from_history">Čištění Historie…</string> <string name="caches_clear_offlinelogs">Smazat offline Logy</string> <string name="caches_clear_offlinelogs_progress">Mazání offline logů</string> - <string name="list_menu">Seznam</string> <string name="list_menu_create">Vytvořit nový seznam</string> <string name="list_menu_drop">Smazat aktuální seznam</string> - <string name="list_menu_change">Změnit seznam</string> <string name="list_menu_rename">Přejmenovat aktuální seznam</string> <string name="list_title">Vyber seznam</string> <string name="list_inbox">Uložené</string> @@ -402,8 +399,6 @@ <string name="init_signature_template_log">Text logu</string> <string name="init_ratingwanted">Načítat hodnocení keše z GCvote.com</string> <string name="init_summary_ratingwanted">Načítat hodnocení keše z GCvote.com</string> - <string name="init_friendlogswanted">Načítat doplňkový Logbook s logy od kámošů</string> - <string name="init_summary_friendlogswanted">Načítat doplňkový Logbook s logy od kámošů</string> <string name="init_openlastdetailspage">Otevřít detaily na naposledy použité stránce</string> <string name="init_summary_openlastdetailspage">Otevřít detaily na naposledy použité stránce</string> <string name="init_autoload">Automaticky načítat dlouhý popis</string> @@ -568,8 +563,6 @@ <string name="cache_personal_note_uploading">Nahrávání osobní poznámky</string> <string name="cache_personal_note_upload_done">Osobní poznámka nahrána</string> <string name="cache_personal_note_upload_cancelled">Nahrávání osobní poznámky přerušeno</string> - <string name="cache_personal_note_unstored">Keš neuložena</string> - <string name="cache_personal_note_store">Keš bude nejdříve uložena kvůli povolení osobních poznámek.</string> <string name="cache_description">Popis</string> <string name="cache_description_long">Dlouhý popis</string> <string name="cache_description_table_note">Popis obsahuje tabulkové formátování, které je pravděpodobně nutné prohlížet na %s, aby bylo správně zobrazené.</string> @@ -589,7 +582,6 @@ <string name="cache_waypoints_add">Přidat Bod trasy</string> <string name="cache_hint">Nápověda</string> <string name="cache_logs">Logbook</string> - <string name="cache_logsfriends">Logbook (Přátelé)</string> <string name="cache_dialog_loading_details">Načítání detailů keše…</string> <string name="cache_dialog_loading_details_status_loadpage">Načítání stránky</string> <string name="cache_dialog_loading_details_status_details">Zpracovávání podrobností</string> @@ -635,10 +627,8 @@ <string name="cache_menu_refresh">Obnovit</string> <string name="cache_menu_share">Sdílet keš</string> <string name="cache_menu_move_list">Přesunout do jiného seznamu</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_menu_mapswithme">MapsWithMe</string> @@ -756,10 +746,7 @@ <string name="map_view_map">Vybrat typ mapy</string> <string name="map_modes">Režimy mapy</string> <string name="map_trail_show">Zobrazit záznam trasy</string> - <string name="map_trail_hide">Skrýt záznam trasy</string> <string name="map_circles_show">Zobrazit kruhy</string> - <string name="map_circles_hide">Skrýt kruhy</string> - <string name="map_mycaches_show">Zobrazovat vlastní/nalezené keše</string> <string name="map_mycaches_hide">Skrývat vlastní/nalezené keše</string> <string name="map_theme_builtin">Výchozí</string> <string name="map_theme_select">Vyber téma mapy</string> @@ -1113,7 +1100,6 @@ <string name="website">Stránka: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">Stránka c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Návod: <a href="">c:geo v Nutshell</a></string> <string name="market">Android: <a href="">c:geo na Google Play</a></string> <string name="about_twitter">Má <b>c:geo</b> publikovat nový status na Twitteru vždy, když zaloguješ keš?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1138,16 +1124,4 @@ <string name="percent_favorite_points">%\ oblíbené</string> <string name="cgeo_shortcut">c:geo zástupce</string> <string name="create_shortcut">Vytvořit zástupce</string> - <string-array name="log_image_scales"> - <item>Bez měřítka</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuta</item> - <item quantity="few">minuty</item> - <item quantity="other">minuty</item> - </plurals> </resources> diff --git a/main/res/values-da/strings.xml b/main/res/values-da/strings.xml index e3d3ba4..76b60f0 100644 --- a/main/res/values-da/strings.xml +++ b/main/res/values-da/strings.xml @@ -71,17 +71,7 @@ <string name="log_save">Gem</string> <string name="log_clear">Fjern</string> <string name="log_add">Tilføj</string> - <string name="log_rating">Vurdering</string> <string name="log_no_rating">Ingen vurdering</string> - <string name="log_stars_1">1 stjerne</string> - <string name="log_stars_15">1,5 stjerner</string> - <string name="log_stars_2">2 stjerner</string> - <string name="log_stars_25">2,5 stjerner</string> - <string name="log_stars_3">3 stjerner</string> - <string name="log_stars_35">3,5 stjerner</string> - <string name="log_stars_4">4 stjerner</string> - <string name="log_stars_45">4,5 stjerner</string> - <string name="log_stars_5">5 stjerner</string> <string name="log_stars_15_description">Temmelig dårlig</string> <string name="log_stars_2_description">Under gennemsnittet</string> <string name="log_stars_25_description">Ikke så slemt</string> @@ -161,6 +151,10 @@ <string name="auth_authorize">Godkend c:geo</string> <string name="auth_start">Start godkendelse</string> <string name="auth_again">Start igen</string> + <plurals name="cache_counts"> + <item quantity="one">En cache</item> + <item quantity="other">%1$d cacher</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Genindlæs</string> <string name="cache_offline_drop">Fjern</string> @@ -235,7 +229,6 @@ <string name="map_live">Live-kort</string> <string name="map_view_map">Kort-view</string> <string name="map_trail_show">Vis spor</string> - <string name="map_trail_hide">Skjul spor</string> <string name="map_live_enable">Aktivér live</string> <string name="map_live_disable">Deaktivér live</string> <string name="search_coordinates">Koordinater</string> @@ -264,8 +257,4 @@ <string name="facebook">Facebook: <a href="http://www.facebook.com/pages/cgeo/297269860090">c:geo page</a></string> <string name="twitter">Twitter: <a href="http://twitter.com/android_gc">@android_GC</a></string> <string name="about_twitter">Skal <b>c:geo</b> sende status til Twitter hvergang du logger en cache?</string> - <plurals name="cache_counts"> - <item quantity="one">En cache</item> - <item quantity="other">%1$d cacher</item> - </plurals> </resources> diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml index 9180f5e..69d1347 100644 --- a/main/res/values-de/strings.xml +++ b/main/res/values-de/strings.xml @@ -80,21 +80,9 @@ <string name="log_saving_and_uploading">Log und Bild werden gesendet…</string> <string name="log_clear">Leeren</string> <string name="log_post">Loggen</string> - <string name="log_post_rate">Loggen & bewerten</string> - <string name="log_post_no_rate">Loggen ohne Bewertung</string> <string name="log_post_not_possible">Lade Log-Seite…</string> <string name="log_add">Hinzufügen</string> - <string name="log_rating">Bewertung</string> <string name="log_no_rating">Keine Bewertung</string> - <string name="log_stars_1">1 Stern</string> - <string name="log_stars_15">1,5 Sterne</string> - <string name="log_stars_2">2 Sterne</string> - <string name="log_stars_25">2,5 Sterne</string> - <string name="log_stars_3">3 Sterne</string> - <string name="log_stars_35">3,5 Sterne</string> - <string name="log_stars_4">4 Sterne</string> - <string name="log_stars_45">4,5 Sterne</string> - <string name="log_stars_5">5 Sterne</string> <string name="log_stars_1_description">Schlecht</string> <string name="log_stars_15_description">Lohnt sich nicht</string> <string name="log_stars_2_description">Schwach</string> @@ -113,7 +101,6 @@ <string name="log_smilies">Smilies</string> <string name="log_image">Bild</string> <string name="log_image_attach">Bild hinzufügen</string> - <string name="log_image_edit">Bild bearbeiten</string> <string name="log_image_stored">Vorhanden</string> <string name="log_image_camera">Neu</string> <string name="log_image_caption">Überschrift</string> @@ -122,6 +109,13 @@ <string name="log_password_title">Log-Passwort:</string> <string name="log_hint_log_password">Log-Passwort eingeben</string> <string name="log_oc_team_comment">OC Team Bemerkung</string> + <string-array name="log_image_scales"> + <item>Keine Skalierung</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Übersetze in %s</string> <string name="translate_to_english">Übersetze in Englisch</string> <string name="translate_length_warning">Die Übersetzung kann bei sehr langen Texten evtl. fehlschlagen.</string> @@ -214,6 +208,7 @@ <string name="info_select_logimage_cancelled">Fotoauswahl oder -erstellung abgebrochen.</string> <string name="info_stored_image">Neues Foto gespeichert nach:</string> <string name="info_storing_static_maps">Versuche, statische Karten zu speichern</string> + <string name="info_cache_saved">Der Cache wurde gespeichert</string> <string name="loc_last">Letzte Position</string> <string name="loc_net">Netzwerk</string> <string name="loc_gps">GPS</string> @@ -221,14 +216,15 @@ <string name="loc_trying">Lokalisierung</string> <string name="loc_no_addr">Adresse unbekannt</string> <string name="loc_gps_disabled">GPS nicht aktiv</string> - <string name="menu_about">über c:geo</string> + <string name="menu_centerposition">Zentriere meine Position</string> + <string name="menu_about">Über c:geo</string> <string name="menu_helpers">Nützliche Apps</string> <string name="menu_settings">Einstellungen</string> <string name="menu_history">Verlauf</string> <string name="menu_filter">Filter</string> <string name="menu_scan_geo">Geocode scannen</string> <string name="menu_pocket_queries">Pocket Queries</string> - <string name="menu_scan_description">c:geo kann Geocodes, die als QR code abgebildet sind scannen. Die dafür notwendige App ist nicht installiert. Wollen sie Google Play öffnen, um sie zu installieren?</string> + <string name="menu_scan_description">c:geo kann Geocodes scannen, die als QR-Code abgebildet sind. Die dafür notwendige App ist nicht installiert. Möchten Sie Google Play öffnen, um sie zu installieren?</string> <string name="live_map_button">Live-Karte</string> <string name="caches_nearby_button">In der Nähe</string> <string name="advanced_search_button">Suche</string> @@ -242,6 +238,10 @@ <string name="caches_more_caches_currently">aktuell</string> <string name="caches_downloading">Lade Caches…\nGeschätzte Zeit: </string> <string name="caches_eta_ltm">Weniger als eine Minute</string> + <plurals name="caches_eta_mins"> + <item quantity="one">Minute</item> + <item quantity="other">Minuten</item> + </plurals> <string name="caches_store_offline">Für Offline speichern</string> <string name="caches_store_selected">Ausgewählte speichern</string> <string name="caches_history">Verlauf</string> @@ -303,10 +303,8 @@ <string name="caches_removing_from_history">Lösche aus Verlauf…</string> <string name="caches_clear_offlinelogs">Offline-Logs löschen</string> <string name="caches_clear_offlinelogs_progress">Lösche Offline-Logs</string> - <string name="list_menu">Liste</string> <string name="list_menu_create">Neue Liste</string> <string name="list_menu_drop">Aktuelle Liste löschen</string> - <string name="list_menu_change">Andere Liste anzeigen</string> <string name="list_menu_rename">Aktuelle Liste umbenennen</string> <string name="list_title">Liste wählen</string> <string name="list_inbox">Standardliste</string> @@ -404,8 +402,8 @@ <string name="init_signature_template_log">Log text</string> <string name="init_ratingwanted">GCvote-Bewertung</string> <string name="init_summary_ratingwanted">Lade Cache-Bewertung von GCvote.com</string> - <string name="init_friendlogswanted">Logs von Freunden zeigen</string> - <string name="init_summary_friendlogswanted">Lade zusätzliche Logbuch-Seite für Logs von Freunden</string> + <string name="init_friends_and_own_logs_wanted">Eigene und Logs von Freunden zeigen</string> + <string name="init_summary_friends_and_own_logs_wanted">Lade zusätzliche Logbuch-Seiten für eigene und Logs von Freunden</string> <string name="init_openlastdetailspage">Zuletzt genutzte Seite</string> <string name="init_summary_openlastdetailspage">Öffne Details mit zuletzt genutzter Seite</string> <string name="init_autoload">Ausführliche Beschreibung</string> @@ -417,6 +415,8 @@ <string name="init_captcha">Zeige CAPTCHA</string> <string name="init_summary_captcha">Zeige CAPTCHA wenn notwendig (nur Basic Member)</string> <string name="init_useenglish">Auf Englisch</string> + <string name="init_showoverflowmenu">Menü-Symbol immer anzeigen</string> + <string name="init_showoverflow_summary">Zeigt das Menü-Symbol (Drei Punkte ⋮) auch an wenn das Gerät eine Menütaste hat (Neustart benötigt)</string> <string name="init_summary_useenglish">c:geo auf Englisch nutzen (Neustart erforderlich)</string> <string name="init_exclude">Eigene und gefundene Caches</string> <string name="init_summary_exclude">Eigene und gefundene Caches ausblenden</string> @@ -494,6 +494,9 @@ <string name="init_maintenance">Wartung</string> <string name="init_maintenance_directories_note">c:geo speichert Bilder, Log-Bilder und weitere Dateien zu einem Cache in einem separaten Verzeichnis. In manchen Fällen (z.B. bei Sichern und Wiederherstellen der Datenbank) kann dieses Verzeichnis unnötige Daten enthalten, die gelöscht werden können.</string> <string name="init_maintenance_directories">Verwaiste Daten löschen</string> + <string name="init_create_memory_dump">Erzeuge ein Speicherabbild</string> + <string name="init_memory_dump">Speicherabbild</string> + <string name="init_memory_dumped">Speicherabbild in %s gespeichert</string> <string name="settings_open_website">Webseite öffnen</string> <string name="settings_settings">Einstellungen</string> <string name="settings_information">Information</string> @@ -541,6 +544,10 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo ist nun autorisiert, Caches zu laden und auf %s zu loggen.</string> + <plurals name="cache_counts"> + <item quantity="one">Ein Cache</item> + <item quantity="other">%1$d Caches</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Aktualisieren</string> <string name="cache_offline_drop">Löschen</string> @@ -567,8 +574,6 @@ <string name="cache_personal_note_uploading">Persönliche Notiz wird gesendet</string> <string name="cache_personal_note_upload_done">Persönliche Notiz wurde hochgeladen</string> <string name="cache_personal_note_upload_cancelled">Hochladen der Notiz abgebrochen</string> - <string name="cache_personal_note_unstored">Cache noch nicht gespeichert</string> - <string name="cache_personal_note_store">Der Cache wird zunächst gespeichert, damit die persönliche Notiz möglich ist.</string> <string name="cache_description">Beschreibung</string> <string name="cache_description_long">Ausführliche Beschreibung</string> <string name="cache_description_table_note">Diese Beschreibung enthält Tabellenelemente, die evtl. nur auf %s korrekt angezeigt werden.</string> @@ -585,10 +590,14 @@ <string name="cache_list_unknown">In keiner Liste</string> <string name="cache_images">Bilder</string> <string name="cache_waypoints">Wegpunkte</string> + <plurals name="waypoints"> + <item quantity="one">1 Wegpunkt</item> + <item quantity="other">%d Wegpunkte</item> + </plurals> <string name="cache_waypoints_add">Wegpunkt hinzufügen</string> <string name="cache_hint">Hinweis</string> <string name="cache_logs">Logbuch</string> - <string name="cache_logsfriends">Logbuch (Freunde)</string> + <string name="cache_logs_friends_and_own">Logbuch (Freunde/Eigene)</string> <string name="cache_dialog_loading_details">Lade Cache-Details…</string> <string name="cache_dialog_loading_details_status_loadpage">Lade Seite</string> <string name="cache_dialog_loading_details_status_details">Verarbeite Details</string> @@ -634,16 +643,15 @@ <string name="cache_menu_refresh">Aktualisieren</string> <string name="cache_menu_share">Weiterleiten</string> <string name="cache_menu_move_list">Auf andere Liste verschieben</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble Smartwatch</string> <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Status</string> <string name="cache_status_offline_log">Gespeicherter Log</string> <string name="cache_status_found">Gefunden</string> + <string name="cache_not_status_found">Nicht gefunden</string> <string name="cache_status_archived">Archiviert</string> <string name="cache_status_disabled">Deaktiviert</string> <string name="cache_status_premium">Nur für Premium-Mitglieder</string> @@ -656,7 +664,7 @@ <string name="cache_size">Größe</string> <string name="cache_distance">Entfernung</string> <string name="cache_difficulty">Schwierigkeit</string> - <string name="cache_terrain">Terrain</string> + <string name="cache_terrain">Gelände</string> <string name="cache_rating">Bewertung</string> <string name="cache_own_rating">Eigene Bewertung</string> <string name="cache_rating_of">von</string> @@ -755,10 +763,7 @@ <string name="map_view_map">Karte</string> <string name="map_modes">Karteneinstellungen</string> <string name="map_trail_show">Spur einblenden</string> - <string name="map_trail_hide">Spur ausblenden</string> <string name="map_circles_show">Kreise anzeigen</string> - <string name="map_circles_hide">Kreise verbergen</string> - <string name="map_mycaches_show">Eigene/gefundene Caches anzeigen</string> <string name="map_mycaches_hide">Eigene/gefundene Caches ausblenden</string> <string name="map_theme_builtin">Standard</string> <string name="map_theme_select">Kartendarstellung wählen</string> @@ -970,8 +975,8 @@ <string name="attribute_skiis_no">Langlauf-Ski nicht erforderlich</string> <string name="attribute_s_tool_yes">Besondere Werkzeuge erforderlich</string> <string name="attribute_s_tool_no">Keine besonderen Werkzeuge erforderlich</string> - <string name="attribute_wirelessbeacon_yes">Cache mit Funk-Sender (Chirp)</string> - <string name="attribute_wirelessbeacon_no">Kein Cache mit Funk-Sender (Chirp)</string> + <string name="attribute_wirelessbeacon_yes">Funk-Sender</string> + <string name="attribute_wirelessbeacon_no">Ohne Funk-Sender</string> <string name="attribute_treeclimbing_yes">Auf Bäume klettern erforderlich</string> <string name="attribute_treeclimbing_no">Auf Bäume klettern nicht erforderlich</string> <string name="attribute_poisonoak_yes">Giftige Pflanzen</string> @@ -1112,7 +1117,6 @@ <string name="website">Webseite: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Benutzung: <a href="">c:geo Kurzanleitung</a></string> <string name="market">Android: <a href="">c:geo auf Google Play</a></string> <string name="about_twitter">Soll jeder neue Fund auf Twitter veröffentlicht werden, wenn er über <b>c:geo</b> geloggt wird?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1128,50 +1132,28 @@ <string name="tts_stop">Stoppe Sprache</string> <string name="err_tts_lang_not_supported">Die aktuelle Sprache wird von TTS nicht unterstützt.</string> <string name="tts_one_kilometer">ein Kilometer</string> - <string name="tts_one_meter">ein Meter</string> - <string name="tts_one_mile">eine Meile</string> - <string name="tts_one_foot">ein Fuß</string> - <string name="tts_one_oclock">ein Uhr</string> - <string name="tts_oclock">%s Uhr</string> - <string name="clipboard_copy_ok">In Zwischenablage kopiert</string> - <string name="percent_favorite_points">% Favoriten</string> - <string name="cgeo_shortcut">c:geo Shortcut</string> - <string name="create_shortcut">Shortcut erstellen</string> - <string-array name="log_image_scales"> - <item>Keine Skalierung</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">Minute</item> - <item quantity="other">Minuten</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Ein Cache</item> - <item quantity="other">%1$d Caches</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 Wegpunkt</item> - <item quantity="other">%d Wegpunkte</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s Kilometer</item> <item quantity="other">%s Kilometer</item> </plurals> + <string name="tts_one_meter">ein Meter</string> <plurals name="tts_meters"> <item quantity="one">%s Meter</item> <item quantity="other">%s Meter</item> </plurals> + <string name="tts_one_mile">eine Meile</string> <plurals name="tts_miles"> <item quantity="one">%s Meile</item> <item quantity="other">%s Meilen</item> </plurals> + <string name="tts_one_foot">ein Fuß</string> <plurals name="tts_feet"> <item quantity="one">%s Fuß</item> <item quantity="other">%s Fuß</item> </plurals> + <string name="tts_one_oclock">ein Uhr</string> + <string name="tts_oclock">%s Uhr</string> + <string name="clipboard_copy_ok">In Zwischenablage kopiert</string> <plurals name="days_ago"> <item quantity="one">gestern</item> <item quantity="other">vor %d Tagen</item> @@ -1180,4 +1162,8 @@ <item quantity="one">%s Favorit</item> <item quantity="other">%s Favoriten</item> </plurals> + <string name="percent_favorite_points">% Favoriten</string> + <string name="cgeo_shortcut">c:geo Shortcut</string> + <string name="create_shortcut">Shortcut erstellen</string> + <string name="send">Senden</string> </resources> diff --git a/main/res/values-es/strings.xml b/main/res/values-es/strings.xml index e7da7a1..07f7a87 100644 --- a/main/res/values-es/strings.xml +++ b/main/res/values-es/strings.xml @@ -78,21 +78,9 @@ <string name="log_saving_and_uploading">Enviando registro y subiendo imagen…</string> <string name="log_clear">Limpiar</string> <string name="log_post">Enviar registro</string> - <string name="log_post_rate">Enviar registro y puntuación</string> - <string name="log_post_no_rate">Enviar registro sin puntuar</string> <string name="log_post_not_possible">Cargando página de registro…</string> <string name="log_add">Añadir</string> - <string name="log_rating">Puntuación</string> <string name="log_no_rating">Sin puntuación</string> - <string name="log_stars_1">1 estrella</string> - <string name="log_stars_15">1,5 estrellas</string> - <string name="log_stars_2">2 estrellas</string> - <string name="log_stars_25">2,5 estrellas</string> - <string name="log_stars_3">3 estrellas</string> - <string name="log_stars_35">3,5 estrellas</string> - <string name="log_stars_4">4 estrellas</string> - <string name="log_stars_45">4,5 estrellas</string> - <string name="log_stars_5">5 estrellas</string> <string name="log_stars_1_description">malísimo</string> <string name="log_stars_15_description">muy malo</string> <string name="log_stars_2_description">malo</string> @@ -111,7 +99,6 @@ <string name="log_smilies">Emoticonos</string> <string name="log_image">Imagen</string> <string name="log_image_attach">Adjuntar imagen</string> - <string name="log_image_edit">Editar imagen</string> <string name="log_image_stored">Galería</string> <string name="log_image_camera">Tomar foto</string> <string name="log_image_caption">Título</string> @@ -120,6 +107,13 @@ <string name="log_password_title">Contraseña:</string> <string name="log_hint_log_password">Introduzca su contraseña</string> <string name="log_oc_team_comment">Comentario equipo OC</string> + <string-array name="log_image_scales"> + <item>Sin redimensionar</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Traducir al %s</string> <string name="translate_to_english">Traducir al inglés</string> <string name="translate_length_warning">La traducción podría fallar con un texto muy largo.</string> @@ -240,6 +234,10 @@ <string name="caches_more_caches_currently">actualmente</string> <string name="caches_downloading">Descargando escondites…\nFaltan: </string> <string name="caches_eta_ltm">Menos de un minuto</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuto</item> + <item quantity="other">minutos</item> + </plurals> <string name="caches_store_offline">Usar sin conexión luego</string> <string name="caches_store_selected">Almacenamiento seleccionado</string> <string name="caches_history">Historial</string> @@ -300,10 +298,8 @@ <string name="caches_removing_from_history">Borrando del historial…</string> <string name="caches_clear_offlinelogs">Borrar registros sin conexión</string> <string name="caches_clear_offlinelogs_progress">Borrando registros sin conexión</string> - <string name="list_menu">Lista</string> <string name="list_menu_create">Crear nueva lista</string> <string name="list_menu_drop">Borrar lista actual</string> - <string name="list_menu_change">Cambiar lista</string> <string name="list_menu_rename">Renombrar la lista actual</string> <string name="list_title">Escoger lista</string> <string name="list_inbox">Guardadas</string> @@ -381,7 +377,6 @@ <string name="init_signature_template_name">Nombre</string> <string name="init_signature_template_url">URL</string> <string name="init_ratingwanted">Clasificación de GCvote</string> - <string name="init_friendlogswanted">Mostrar registros de amigos</string> <string name="init_openlastdetailspage">Detalles de la última página</string> <string name="init_autoload">Autocargar descripción larga</string> <string name="init_summary_autoload">Autocargar descripción larga</string> @@ -463,6 +458,10 @@ <string name="auth_again">Volver a iniciar</string> <string name="auth_dialog_waiting">Esperando a %s…</string> <string name="auth_ocde">Opencaching.de</string> + <plurals name="cache_counts"> + <item quantity="one">Un escondite</item> + <item quantity="other">%1$d Escondites</item> + </plurals> <string name="cache_offline">Desconectado</string> <string name="cache_offline_refresh">Actualizar</string> <string name="cache_offline_drop">Tirar</string> @@ -521,7 +520,6 @@ <string name="cache_menu_refresh">Actualizar</string> <string name="cache_menu_share">Compartir escondite</string> <string name="cache_menu_move_list">Mover a otra lista</string> - <string name="cache_menu_gcc">GCC</string> <string name="cache_menu_whereyougo">WhereYouGo</string> <string name="cache_menu_oruxmaps">OruxMaps</string> <string name="cache_status">Estado</string> @@ -595,9 +593,7 @@ <string name="map_view_map">Ver mapa</string> <string name="map_modes">Configuración del mapa</string> <string name="map_trail_show">Mostrar rastro</string> - <string name="map_trail_hide">Ocultar rastro</string> <string name="map_circles_show">Mostrar círculos</string> - <string name="map_circles_hide">Ocultar círculos</string> <string name="map_theme_builtin">Por defecto</string> <string name="map_live_enable">Activar en vivo</string> <string name="map_live_disable">Desactivar en vivo</string> @@ -837,7 +833,6 @@ <string name="website">Web: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">c:geo en breve</a></string> <string name="about_twitter">¿Debe <b>c:geo</b> publicar el nuevo estado en Twitter cuando registras un escondite?</string> <string name="status_new_release" tools:ignore="UnusedResources">Nueva versión disponible. \nClick para instalar.</string> <string name="tts_start">Empezar a hablar</string> @@ -849,19 +844,4 @@ <string name="tts_oclock">%s en punto</string> <string name="clipboard_copy_ok">Copiado al portapapeles</string> <string name="percent_favorite_points">% \ favoritos</string> - <string-array name="log_image_scales"> - <item>Sin redimensionar</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuto</item> - <item quantity="other">minutos</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Un escondite</item> - <item quantity="other">%1$d Escondites</item> - </plurals> </resources> diff --git a/main/res/values-fr/strings.xml b/main/res/values-fr/strings.xml index e8487bf..2bcbe1f 100644 --- a/main/res/values-fr/strings.xml +++ b/main/res/values-fr/strings.xml @@ -18,6 +18,7 @@ <string name="letterbox">Boîtes aux lettres hybrides</string> <string name="event">Événements</string> <string name="mega">Méga-événements</string> + <string name="giga">Giga-événements</string> <string name="earth">Earthcache</string> <string name="cito">Cache in trash out</string> <string name="webcam">Webcams</string> @@ -79,21 +80,9 @@ <string name="log_saving_and_uploading">Envoi de la note et de l\'image…</string> <string name="log_clear">Effacer</string> <string name="log_post">Envoyer</string> - <string name="log_post_rate">Envoyer & noter</string> - <string name="log_post_no_rate">Envoyer & ne pas noter</string> <string name="log_post_not_possible">Chargement de la page…</string> <string name="log_add">Ajouter</string> - <string name="log_rating">Note</string> <string name="log_no_rating">Pas de note</string> - <string name="log_stars_1">1 étoile</string> - <string name="log_stars_15">1,5 étoiles</string> - <string name="log_stars_2">2 étoiles</string> - <string name="log_stars_25">2,5 étoiles</string> - <string name="log_stars_3">3 étoiles</string> - <string name="log_stars_35">3,5 étoiles</string> - <string name="log_stars_4">4 étoiles</string> - <string name="log_stars_45">4,5 étoiles</string> - <string name="log_stars_5">5 étoiles</string> <string name="log_stars_1_description">faible</string> <string name="log_stars_15_description">plutôt faible</string> <string name="log_stars_2_description">en dessous de la moyenne</string> @@ -112,7 +101,6 @@ <string name="log_smilies">Sourillards</string> <string name="log_image">Image</string> <string name="log_image_attach">Ajouter une image</string> - <string name="log_image_edit">Éditer l\'image</string> <string name="log_image_stored">Existante</string> <string name="log_image_camera">Nouvelle</string> <string name="log_image_caption">Légende</string> @@ -121,6 +109,13 @@ <string name="log_password_title">Mot de passe du carnet :</string> <string name="log_hint_log_password">Entrez votre mot de passe pour le carnet</string> <string name="log_oc_team_comment">Commentaire de l\'équipe OC</string> + <string-array name="log_image_scales"> + <item>Taille originale</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Traduire en %s</string> <string name="translate_to_english">Traduire en anglais</string> <string name="translate_length_warning">La traduction d\'un texte trop long peut échouer.</string> @@ -220,6 +215,7 @@ <string name="loc_trying">Localisation en cours…</string> <string name="loc_no_addr">Adresse inconnue</string> <string name="loc_gps_disabled">GPS désactivé</string> + <string name="menu_centerposition">Centrer sur ma position</string> <string name="menu_about">À propos de c:geo</string> <string name="menu_helpers">Utilitaires</string> <string name="menu_settings">Paramètres</string> @@ -241,6 +237,10 @@ <string name="caches_more_caches_currently">actuellement</string> <string name="caches_downloading">Téléchargement des caches…\nRestant: </string> <string name="caches_eta_ltm">Moins d\'une minute</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minute</item> + <item quantity="other">minutes</item> + </plurals> <string name="caches_store_offline">Stocker localement</string> <string name="caches_store_selected">Stocker la sélection</string> <string name="caches_history">Historique</string> @@ -301,10 +301,8 @@ <string name="caches_removing_from_history">Effacer de l\'historique…</string> <string name="caches_clear_offlinelogs">Effacer les entrées de carnet hors-ligne</string> <string name="caches_clear_offlinelogs_progress">Effacement des entrées de carnet hors-ligne</string> - <string name="list_menu">Listes</string> <string name="list_menu_create">Nouvelle liste</string> <string name="list_menu_drop">Effacer la liste courante</string> - <string name="list_menu_change">Changer de liste</string> <string name="list_menu_rename">Renommer la liste courante</string> <string name="list_title">Choisir une liste</string> <string name="list_inbox">Enregistrées</string> @@ -402,8 +400,8 @@ <string name="init_signature_template_log">Texte du journal</string> <string name="init_ratingwanted">Charger la note depuis GCvote.com</string> <string name="init_summary_ratingwanted">Charger la note depuis GCvote.com</string> - <string name="init_friendlogswanted">Charger le carnet (amis)</string> - <string name="init_summary_friendlogswanted">Charger le carnet (amis)</string> + <string name="init_friends_and_own_logs_wanted">Montrer vos entrées / amis</string> + <string name="init_summary_friends_and_own_logs_wanted">Afficher une page de carnet supplémentaire avec vos entrées de carnet et celles de vos amis</string> <string name="init_openlastdetailspage">Réouvrir les détails à la dernière page ouverte</string> <string name="init_summary_openlastdetailspage">Réouvrir les détails à la dernière page ouverte</string> <string name="init_autoload">Afficher automatiquement les descriptions longues</string> @@ -415,6 +413,8 @@ <string name="init_captcha">Afficher le CAPTCHA si nécessaire</string> <string name="init_summary_captcha">Afficher le CAPTCHA si nécessaire</string> <string name="init_useenglish">Utiliser l\'anglais dans c:geo\n(redémarrage nécessaire)</string> + <string name="init_showoverflowmenu">Toujours afficher le menu</string> + <string name="init_showoverflow_summary">Toujours afficher le symbole pour obtenir le menu (trois points⋮) même si l\'appareil a un bouton menu (redémarrage nécessaire)</string> <string name="init_summary_useenglish">Utiliser l\'anglais dans c:geo\n(redémarrage nécessaire)</string> <string name="init_exclude">Exclure mes caches et les caches trouvées</string> <string name="init_summary_exclude">Exclure mes caches et les caches trouvées</string> @@ -492,6 +492,9 @@ <string name="init_maintenance">Maintenance</string> <string name="init_maintenance_directories_note">c:geo stocke les images et les autres fichiers associés à une géocache dans un dossier dédié. Dans certains cas (comme l\'importation/exportation de la base de données), ce dossier peut contenir des fichiers obsolètes, qui peuvent être supprimés ici.</string> <string name="init_maintenance_directories">Supprimer les fichiers orphelins</string> + <string name="init_create_memory_dump">Créer une image mémoire</string> + <string name="init_memory_dump">Image mémoire</string> + <string name="init_memory_dumped">Mémoire copiée dans %s</string> <string name="settings_open_website">Ouvrir le site dans un navigateur</string> <string name="settings_settings">Paramètres</string> <string name="settings_information">Information</string> @@ -539,6 +542,10 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo est désormais autorisé à interagir avec %s.</string> + <plurals name="cache_counts"> + <item quantity="one">%1$d cache</item> + <item quantity="other">%1$d caches</item> + </plurals> <string name="cache_offline">Hors ligne</string> <string name="cache_offline_refresh">Recharger</string> <string name="cache_offline_drop">Effacer</string> @@ -565,8 +572,6 @@ <string name="cache_personal_note_uploading">Envoi de la note personnelle</string> <string name="cache_personal_note_upload_done">Note personnelle envoyée</string> <string name="cache_personal_note_upload_cancelled">Envoi de la note personnelle annulé</string> - <string name="cache_personal_note_unstored">Cache non sauvegardée localement</string> - <string name="cache_personal_note_store">La cache va être sauvegardée localement avant d\'autoriser les notes personnelles.</string> <string name="cache_description">Description</string> <string name="cache_description_long">Description longue</string> <string name="cache_description_table_note">La description contient des informations de formattages qui nécessitent possiblement d\'être vues sur le site %s pour être affichées correctement.</string> @@ -583,10 +588,14 @@ <string name="cache_list_unknown">Dans aucune liste</string> <string name="cache_images">Images</string> <string name="cache_waypoints">Étapes</string> + <plurals name="waypoints"> + <item quantity="one">1 étape</item> + <item quantity="other">%d étapes</item> + </plurals> <string name="cache_waypoints_add">Ajouter une étape</string> <string name="cache_hint">Indice</string> <string name="cache_logs">Carnet de bord</string> - <string name="cache_logsfriends">Carnet (amis)</string> + <string name="cache_logs_friends_and_own">Vous / amis</string> <string name="cache_dialog_loading_details">Chargement des détails…</string> <string name="cache_dialog_loading_details_status_loadpage">Chargement de la page</string> <string name="cache_dialog_loading_details_status_details">Analyse</string> @@ -632,15 +641,14 @@ <string name="cache_menu_refresh">Recharger</string> <string name="cache_menu_share">Partager la cache</string> <string name="cache_menu_move_list">Déplacer dans une autre liste</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_status">Statut</string> <string name="cache_status_offline_log">Visite sauvée hors-ligne</string> <string name="cache_status_found">Trouvée</string> + <string name="cache_not_status_found">Pas trouvée</string> <string name="cache_status_archived">Archivée</string> <string name="cache_status_disabled">Désactivée</string> <string name="cache_status_premium">Membres privilégiés seulement</string> @@ -752,10 +760,7 @@ <string name="map_view_map">Voir carte</string> <string name="map_modes">Marqueurs</string> <string name="map_trail_show">Afficher le parcours</string> - <string name="map_trail_hide">Cacher le parcours</string> <string name="map_circles_show">Afficher les cercles</string> - <string name="map_circles_hide">Cacher les cercles</string> - <string name="map_mycaches_show">Montrer les caches placées/trouvées</string> <string name="map_mycaches_hide">Cacher les caches placées/trouvées</string> <string name="map_theme_builtin">Défault</string> <string name="map_theme_select">Sélectionner le thème</string> @@ -1109,7 +1114,6 @@ <string name="website">site: <a href="">cgeo.org</a></string> <string name="facebook">facebook: <a href="">page c:geo</a></string> <string name="twitter">twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manuel: <a href="">c:geo en bref</a></string> <string name="market">Android: <a href="">c:geo sur Google Play</a></string> <string name="about_twitter">Voulez-vous publier un nouveau statut sur Twitter à chaque nouvelle cache découverte sous <b>c:geo</b>?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1125,50 +1129,28 @@ <string name="tts_stop">Arrêter de parler</string> <string name="err_tts_lang_not_supported">La langue courante n\'est pas prise en charge par la synthèse vocale.</string> <string name="tts_one_kilometer">un kilomètre</string> - <string name="tts_one_meter">un mètre</string> - <string name="tts_one_mile">un mille</string> - <string name="tts_one_foot">un pied</string> - <string name="tts_one_oclock">une heure</string> - <string name="tts_oclock">%s heures</string> - <string name="clipboard_copy_ok">Copié dans le presse-papiers</string> - <string name="percent_favorite_points">%\ favoris</string> - <string name="cgeo_shortcut">c:geo raccourci</string> - <string name="create_shortcut">Créer un raccourci</string> - <string-array name="log_image_scales"> - <item>Taille originale</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minute</item> - <item quantity="other">minutes</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">une cache</item> - <item quantity="other">%1$d caches</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 étape</item> - <item quantity="other">%d étapes</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilomètre</item> <item quantity="other">%s kilomètres</item> </plurals> + <string name="tts_one_meter">un mètre</string> <plurals name="tts_meters"> <item quantity="one">%s mètre</item> <item quantity="other">%s mètres</item> </plurals> + <string name="tts_one_mile">un mille</string> <plurals name="tts_miles"> <item quantity="one">%s mille</item> <item quantity="other">%s milles</item> </plurals> + <string name="tts_one_foot">un pied</string> <plurals name="tts_feet"> <item quantity="one">%s pied</item> <item quantity="other">%s pieds</item> </plurals> + <string name="tts_one_oclock">une heure</string> + <string name="tts_oclock">%s heures</string> + <string name="clipboard_copy_ok">Copié dans le presse-papiers</string> <plurals name="days_ago"> <item quantity="one">hier</item> <item quantity="other">il y a %d jours</item> @@ -1177,4 +1159,7 @@ <item quantity="one">%s favori</item> <item quantity="other">%s favoris</item> </plurals> + <string name="percent_favorite_points">%\ favoris</string> + <string name="cgeo_shortcut">c:geo raccourci</string> + <string name="create_shortcut">Créer un raccourci</string> </resources> diff --git a/main/res/values-hu/strings.xml b/main/res/values-hu/strings.xml index 7e66ed5..ca8a51e 100644 --- a/main/res/values-hu/strings.xml +++ b/main/res/values-hu/strings.xml @@ -69,21 +69,9 @@ <string name="log_saving">Log mentése…</string> <string name="log_clear">Törlés</string> <string name="log_post">Log beküldése</string> - <string name="log_post_rate">Log beküldése & értékelés</string> - <string name="log_post_no_rate">Log beküldése & nincs értékelés</string> <string name="log_post_not_possible">Log oldal betöltése…</string> <string name="log_add">Hozzáadás</string> - <string name="log_rating">Értékelés</string> <string name="log_no_rating">Nincs értékelés</string> - <string name="log_stars_1">1 csillag</string> - <string name="log_stars_15">1.5 csillag</string> - <string name="log_stars_2">2 csillag</string> - <string name="log_stars_25">2.5 csillag</string> - <string name="log_stars_3">3 csillag</string> - <string name="log_stars_35">3.5 csillag</string> - <string name="log_stars_4">4 csillag</string> - <string name="log_stars_45">4.5 csillag</string> - <string name="log_stars_5">5 csillag</string> <string name="log_stars_1_description">nagyon rossz</string> <string name="log_stars_15_description">elég rossz</string> <string name="log_stars_2_description">átlagon aluli</string> @@ -258,10 +246,8 @@ <string name="caches_filter_clear">szűrők törlése</string> <string name="caches_filter_modified">Módosított koordinátákkal</string> <string name="caches_removing_from_history">Eltávolítás a Előzményekből…</string> - <string name="list_menu">Lista</string> <string name="list_menu_create">Új lista létrehozása</string> <string name="list_menu_drop">Jelenlegi lista elvetése</string> - <string name="list_menu_change">Lista megváltoztatása</string> <string name="list_menu_rename">Az aktuális lista átnevezése</string> <string name="list_title">Válassz listát</string> <string name="list_inbox">Mentett</string> @@ -302,8 +288,6 @@ <string name="init_signature_template_owner">Tulajdonos</string> <string name="init_ratingwanted">Értékelés betöltése a GCvote.com-ról</string> <string name="init_summary_ratingwanted">Értékelés betöltése a GCvote.com-ról</string> - <string name="init_friendlogswanted">További logbook oldal betöltése a barátok logjainak.</string> - <string name="init_summary_friendlogswanted">További logbook oldal betöltése a barátok logjainak.</string> <string name="init_openlastdetailspage">Az utoljára használt oldal részleteinek betöltése</string> <string name="init_summary_openlastdetailspage">Az utoljára használt oldal részleteinek betöltése</string> <string name="init_autoload">Hosszú leírás automatikus betöltése</string> @@ -431,7 +415,6 @@ <string name="cache_waypoints_add">Útpont hozzáadása</string> <string name="cache_hint">Segítség</string> <string name="cache_logs">Láda napló</string> - <string name="cache_logsfriends">Logbook (Barátok)</string> <string name="cache_dialog_loading_details">Láda adatainak betöltése…</string> <string name="cache_dialog_loading_details_status_loadpage">Oldal betöltése</string> <string name="cache_dialog_loading_details_status_details">Részletek feldolgozása</string> @@ -469,10 +452,8 @@ <string name="cache_menu_refresh">Frissítés</string> <string name="cache_menu_share">Láda megosztása</string> <string name="cache_menu_move_list">Mozgatás másik listára</string> - <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">Geoláda jelzőbója</string> <string name="cache_status">Állapot</string> <string name="cache_status_offline_log">Mentett bejegyzés</string> <string name="cache_status_found">Megtalált</string> @@ -566,9 +547,7 @@ <string name="map_view_map">Térkép nézet</string> <string name="map_modes">Térkép módok</string> <string name="map_trail_show">Ösvény mutatása</string> - <string name="map_trail_hide">Ösvény elrejtése</string> <string name="map_circles_show">Körök mutatása</string> - <string name="map_circles_hide">Körök elrejtése</string> <string name="map_theme_builtin">Alapértelmezett</string> <string name="map_theme_select">Válassz térképtémát</string> <string name="map_live_enable">Élő mód engedélyezése</string> @@ -807,7 +786,6 @@ <string name="website">Weboldal: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Kézikönyv: <a href="">A c:geo dióhéjban</a></string> <string name="about_twitter">Akarod, hogy <b>c:geo</b> új bejegyzést írjon Twitterre mindig mikor egy ládát megtalálsz?</string> <string name="status_new_release" tools:ignore="UnusedResources">Új kiadás található.\nKattints a telepítéshez.</string> <string name="status_new_nightly" tools:ignore="UnusedResources">Új napi verzió található.\nKattints a telepítéshez.</string> diff --git a/main/res/values-it/strings.xml b/main/res/values-it/strings.xml index 43e6c88..96b10eb 100644 --- a/main/res/values-it/strings.xml +++ b/main/res/values-it/strings.xml @@ -79,21 +79,9 @@ <string name="log_saving_and_uploading">Invio log e immagine…</string> <string name="log_clear">Azzera</string> <string name="log_post">Invia log</string> - <string name="log_post_rate">Invia log + voto</string> - <string name="log_post_no_rate">Invia log senza voto</string> <string name="log_post_not_possible">Connessione…</string> <string name="log_add">Aggiungi</string> - <string name="log_rating">Voto</string> <string name="log_no_rating">Nessun voto</string> - <string name="log_stars_1">1 stella</string> - <string name="log_stars_15">1.5 stelle</string> - <string name="log_stars_2">2 stelle</string> - <string name="log_stars_25">2.5 stelle</string> - <string name="log_stars_3">3 stelle</string> - <string name="log_stars_35">3.5 stelle</string> - <string name="log_stars_4">4 stelle</string> - <string name="log_stars_45">4.5 stelle</string> - <string name="log_stars_5">5 stelle</string> <string name="log_stars_1_description">proprio brutto</string> <string name="log_stars_15_description">abbastanza brutto</string> <string name="log_stars_2_description">bruttino</string> @@ -112,7 +100,6 @@ <string name="log_smilies">Faccine</string> <string name="log_image">Immagine</string> <string name="log_image_attach">Aggiungi immagine</string> - <string name="log_image_edit">Modifica immagine</string> <string name="log_image_stored">Esistente</string> <string name="log_image_camera">Nuova</string> <string name="log_image_caption">Didascalia</string> @@ -121,6 +108,13 @@ <string name="log_password_title">Log Password:</string> <string name="log_hint_log_password">Inserisci la password per il log</string> <string name="log_oc_team_comment">Commenti del Team OC</string> + <string-array name="log_image_scales"> + <item>Dimensioni originali</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Traduci in %s</string> <string name="translate_to_english">Traduci in inglese</string> <string name="translate_length_warning">La traduzione può fallire quando c\'è molto testo.</string> @@ -241,6 +235,10 @@ <string name="caches_more_caches_currently">attualmente</string> <string name="caches_downloading">Download cache in corso…\nETA: </string> <string name="caches_eta_ltm">Meno di un minuto</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuto</item> + <item quantity="other">minuti</item> + </plurals> <string name="caches_store_offline">Salva per Offline</string> <string name="caches_store_selected">Salva selezionati</string> <string name="caches_history">Cronologia</string> @@ -301,10 +299,8 @@ <string name="caches_removing_from_history">Rimozione dalla cronologia…</string> <string name="caches_clear_offlinelogs">Cancella i log offline</string> <string name="caches_clear_offlinelogs_progress">Cancellazione logs offline</string> - <string name="list_menu">Lista</string> <string name="list_menu_create">Crea nuova lista</string> <string name="list_menu_drop">Elimina la lista corrente</string> - <string name="list_menu_change">Cambia lista</string> <string name="list_menu_rename">Rinomina la lista corrente</string> <string name="list_title">Seleziona una lista</string> <string name="list_inbox">Salvate</string> @@ -399,8 +395,6 @@ <string name="init_signature_template_log">Testo di Log</string> <string name="init_ratingwanted">Rating da GCvote.com</string> <string name="init_summary_ratingwanted">Carica il rating del cache da GCvote.com</string> - <string name="init_friendlogswanted">Visualizza log dei miei amici</string> - <string name="init_summary_friendlogswanted">Carica logbook addizionale con i log dei miei amici</string> <string name="init_openlastdetailspage">Carica ultima pagina usata nei dettagli</string> <string name="init_summary_openlastdetailspage">Ricorda l\'ultima pagina usata nei dettagli</string> <string name="init_autoload">Descrizione estesa</string> @@ -536,6 +530,10 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo è ora autorizzato ad accedere a %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Un cache</item> + <item quantity="other">%1$d cache</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Aggiorna</string> <string name="cache_offline_drop">Elimina</string> @@ -562,8 +560,6 @@ <string name="cache_personal_note_uploading">Nota personale in caricamento</string> <string name="cache_personal_note_upload_done">Nota personale caricata</string> <string name="cache_personal_note_upload_cancelled">Caricamento nota personale annullato</string> - <string name="cache_personal_note_unstored">Cache non salvati</string> - <string name="cache_personal_note_store">Il cache verrà prima salvato per abilitare le note personali.</string> <string name="cache_description">Descrizione</string> <string name="cache_description_long">Descrizione estesa</string> <string name="cache_description_table_note">La descrizione contiene una tabella formattata in modo tale che potresti aver bisogno di andare su %s per vederla correttamente.</string> @@ -580,10 +576,13 @@ <string name="cache_list_unknown">Non in una lista</string> <string name="cache_images">Immagini</string> <string name="cache_waypoints">Waypoints</string> + <plurals name="waypoints"> + <item quantity="one">1 Waypoint</item> + <item quantity="other">%d Waypoint</item> + </plurals> <string name="cache_waypoints_add">Aggiungi waypoint</string> <string name="cache_hint">Aiuto (spoiler)</string> <string name="cache_logs">Logbook</string> - <string name="cache_logsfriends">Log amici</string> <string name="cache_dialog_loading_details">Caricamento dettagli del cache…</string> <string name="cache_dialog_loading_details_status_loadpage">Caricamento pagina</string> <string name="cache_dialog_loading_details_status_details">Elaborazione dettagli</string> @@ -629,10 +628,8 @@ <string name="cache_menu_refresh">Aggiorna</string> <string name="cache_menu_share">Condividi cache</string> <string name="cache_menu_move_list">Muovi in un\'altra lista</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_status">Stato</string> @@ -749,10 +746,7 @@ <string name="map_view_map">Scegli mappa</string> <string name="map_modes">Modi mappa</string> <string name="map_trail_show">Mostra scia</string> - <string name="map_trail_hide">Nasconde scia</string> <string name="map_circles_show">Mostra area cache</string> - <string name="map_circles_hide">Nascondi area cache</string> - <string name="map_mycaches_show">Visualizza cache tuoi o che hai trovato</string> <string name="map_mycaches_hide">Nascondi i tuoi cache o che hai trovato</string> <string name="map_theme_builtin">Tema predefinito</string> <string name="map_theme_select">Scegli un tema mappa</string> @@ -1106,7 +1100,6 @@ <string name="website">Sito: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">Pagina c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manuale: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">c:geo su Google Play</a></string> <string name="about_twitter">Può <b>c:geo</b> pubblicare su Twitter ogni volta che logghi un cache?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1122,50 +1115,28 @@ <string name="tts_stop">Stop voce</string> <string name="err_tts_lang_not_supported">Il linguaggio attivo non è supportato dal modulo di sintesi vocale.</string> <string name="tts_one_kilometer">un chilometro</string> - <string name="tts_one_meter">un metro</string> - <string name="tts_one_mile">un miglio</string> - <string name="tts_one_foot">un piede</string> - <string name="tts_one_oclock">a ore una</string> - <string name="tts_oclock">a ore %s</string> - <string name="clipboard_copy_ok">Copiato nella clipboard</string> - <string name="percent_favorite_points">%\ preferiti</string> - <string name="cgeo_shortcut">collegamento a c:geo</string> - <string name="create_shortcut">Crea collegamento</string> - <string-array name="log_image_scales"> - <item>Dimensioni originali</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuto</item> - <item quantity="other">minuti</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Un cache</item> - <item quantity="other">%1$d cache</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 Waypoint</item> - <item quantity="other">%d Waypoint</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">un chilometro</item> <item quantity="other">%s chilometri</item> </plurals> + <string name="tts_one_meter">un metro</string> <plurals name="tts_meters"> <item quantity="one">un metro</item> <item quantity="other">%s metri</item> </plurals> + <string name="tts_one_mile">un miglio</string> <plurals name="tts_miles"> <item quantity="one">un miglio</item> <item quantity="other">%s miglia</item> </plurals> + <string name="tts_one_foot">un piede</string> <plurals name="tts_feet"> <item quantity="one">un piede</item> <item quantity="other">%s piedi</item> </plurals> + <string name="tts_one_oclock">a ore una</string> + <string name="tts_oclock">a ore %s</string> + <string name="clipboard_copy_ok">Copiato nella clipboard</string> <plurals name="days_ago"> <item quantity="one">ieri</item> <item quantity="other">%d giorni fa</item> @@ -1174,4 +1145,7 @@ <item quantity="one">%s preferito</item> <item quantity="other">%s preferiti</item> </plurals> + <string name="percent_favorite_points">%\ preferiti</string> + <string name="cgeo_shortcut">collegamento a c:geo</string> + <string name="create_shortcut">Crea collegamento</string> </resources> diff --git a/main/res/values-ja/strings.xml b/main/res/values-ja/strings.xml index 9164a8c..16a7376 100644 --- a/main/res/values-ja/strings.xml +++ b/main/res/values-ja/strings.xml @@ -77,21 +77,9 @@ <string name="log_saving_and_uploading">ログと画像を送信中…</string> <string name="log_clear">消去</string> <string name="log_post">ログの投稿</string> - <string name="log_post_rate">ログの投稿と評価:</string> - <string name="log_post_no_rate">ログの投稿(未評価)</string> <string name="log_post_not_possible">ログのページをロード中…</string> <string name="log_add">挿入</string> - <string name="log_rating">評価</string> <string name="log_no_rating">未評価</string> - <string name="log_stars_1">星1つ</string> - <string name="log_stars_15">星1.5</string> - <string name="log_stars_2">星2つ</string> - <string name="log_stars_25">星2.5</string> - <string name="log_stars_3">星3つ</string> - <string name="log_stars_35">星3.5</string> - <string name="log_stars_4">星4つ</string> - <string name="log_stars_45">星4.5</string> - <string name="log_stars_5">星5つ</string> <string name="log_stars_1_description">お粗末</string> <string name="log_stars_15_description">見劣りする</string> <string name="log_stars_2_description">平均以下</string> @@ -110,7 +98,6 @@ <string name="log_smilies">スマイルマーク</string> <string name="log_image">画像</string> <string name="log_image_attach">画像を添付</string> - <string name="log_image_edit">添付画像を変更</string> <string name="log_image_stored">ファイル選択</string> <string name="log_image_camera">撮影</string> <string name="log_image_caption">タイトル</string> @@ -118,6 +105,13 @@ <string name="log_image_scale">拡大縮小</string> <string name="log_password_title">Log Password:</string> <string name="log_hint_log_password">Enter your log password</string> + <string-array name="log_image_scales"> + <item>実サイズ</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">%sに翻訳</string> <string name="translate_to_english">英語に翻訳</string> <string name="translate_length_warning">文章が長すぎるので翻訳できないかもしれません。</string> @@ -235,6 +229,9 @@ <string name="caches_more_caches_currently">現在</string> <string name="caches_downloading">キャッシュ情報をダウンロード中…\n残り時間: </string> <string name="caches_eta_ltm">1分以内</string> + <plurals name="caches_eta_mins"> + <item quantity="other">分</item> + </plurals> <string name="caches_store_offline">オフライン用に保存</string> <string name="caches_store_selected">選択したキャッシュを保存</string> <string name="caches_history">履歴</string> @@ -295,10 +292,8 @@ <string name="caches_removing_from_history">履歴から削除中…</string> <string name="caches_clear_offlinelogs">全てのオフラインログを削除</string> <string name="caches_clear_offlinelogs_progress">全てのオフラインログを削除中</string> - <string name="list_menu">リスト</string> <string name="list_menu_create">新しいリストを作成</string> <string name="list_menu_drop">このリストを消去</string> - <string name="list_menu_change">別のリストにする</string> <string name="list_menu_rename">このリスト名を変更</string> <string name="list_title">リストの選択</string> <string name="list_inbox">保存済み</string> @@ -381,8 +376,6 @@ <string name="init_signature_template_url">URL</string> <string name="init_ratingwanted">GCvote評価</string> <string name="init_summary_ratingwanted">キャッシュの評価をGCvote.comから取得</string> - <string name="init_friendlogswanted">友達のログページ</string> - <string name="init_summary_friendlogswanted">友達の書いたログを別ページに表示</string> <string name="init_openlastdetailspage">最後に表示したページ</string> <string name="init_summary_openlastdetailspage">キャッシュ情報の表示では最後に表示したページを開く</string> <string name="init_autoload">詳細表示</string> @@ -491,6 +484,9 @@ <string name="auth_dialog_completed_twitter">c:geoはTwitterにポストするための認証を受けました。</string> <string name="auth_ocde">opencaching.de</string> <string name="auth_dialog_completed_oc">c:geoは%sと連携するための認証を受けました。</string> + <plurals name="cache_counts"> + <item quantity="other">%1$d キャッシュ</item> + </plurals> <string name="cache_offline">オフライン</string> <string name="cache_offline_refresh">更新</string> <string name="cache_offline_drop">削除</string> @@ -517,8 +513,6 @@ <string name="cache_personal_note_uploading">パーソナルノートをアップロード中</string> <string name="cache_personal_note_upload_done">パーソナルノートをアップロードしました</string> <string name="cache_personal_note_upload_cancelled">パーソナルノートのアップロードをキャンセルしました</string> - <string name="cache_personal_note_unstored">キャッシュ情報が保存されていません</string> - <string name="cache_personal_note_store">パーソナルノートを有効にするためにキャッシュ情報を保存します。</string> <string name="cache_description">説明</string> <string name="cache_description_long">全て表示</string> <string name="cache_description_table_note">キャッシュ情報の説明にはhtmlを使ったテーブル表が含まれています。正しく表示するには%sで開く必要があるかもしれません。</string> @@ -535,10 +529,12 @@ <string name="cache_list_unknown">Not in a list</string> <string name="cache_images">画像</string> <string name="cache_waypoints">ウェイポイント</string> + <plurals name="waypoints"> + <item quantity="other">%d ウェイポイント</item> + </plurals> <string name="cache_waypoints_add">ウェイポイントを追加</string> <string name="cache_hint">ヒント</string> <string name="cache_logs">ログブック</string> - <string name="cache_logsfriends">ログブック(友達)</string> <string name="cache_dialog_loading_details">キャッシュの詳細をロード中…</string> <string name="cache_dialog_loading_details_status_loadpage">ページをロード中</string> <string name="cache_dialog_loading_details_status_details">詳細を処理中</string> @@ -584,10 +580,8 @@ <string name="cache_menu_refresh">更新</string> <string name="cache_menu_share">キャッシュを共有</string> <string name="cache_menu_move_list">他のリストに移動</string> - <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">キャッシュビーコン</string> <string name="cache_status">状態</string> <string name="cache_status_offline_log">保存済みのログ</string> <string name="cache_status_found">見つかった</string> @@ -701,10 +695,7 @@ <string name="map_view_map">地図の変更</string> <string name="map_modes">表示切替</string> <string name="map_trail_show">軌跡を表示</string> - <string name="map_trail_hide">軌跡を非表示</string> <string name="map_circles_show">0.1マイル円を表示</string> - <string name="map_circles_hide">円を非表示</string> - <string name="map_mycaches_show">所有/見つけたキャッシュを表示</string> <string name="map_mycaches_hide">所有/見つけたキャッシュを非表示</string> <string name="map_theme_builtin">デフォルト</string> <string name="map_theme_select">地図のテーマを選択</string> @@ -1023,7 +1014,6 @@ Google翻訳アプリで各言語の辞書をダウンロードしておけば <string name="website">Webサイト: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">マニュアル: <a href="">c:geo マニュアル(英語)</a></string> <string name="market">Android: <a href="">Google Playのc:geo</a></string> <string name="about_twitter">キャッシュのログを書いたら<b>c:geo</b>にTwitterでつぶやいてほしい?</string> <string name="status_new_release" tools:ignore="UnusedResources">新しいバージョンがあります。\nクリックしてインストールしてください。</string> @@ -1036,29 +1026,13 @@ Google翻訳アプリで各言語の辞書をダウンロードしておけば <string name="tts_start">音声案内開始</string> <string name="tts_stop">音声案内終了</string> <string name="tts_one_kilometer">1 km</string> + <plurals name="tts_kilometers"> + <item quantity="other">%s キロメートル</item> + </plurals> <string name="tts_one_meter">1 m</string> <string name="tts_one_mile">1 マイル</string> <string name="tts_one_foot">1 フィート</string> <string name="tts_one_oclock">1 時</string> <string name="tts_oclock">%s 時</string> <string name="clipboard_copy_ok">クリップボードにコピーしました</string> - <string-array name="log_image_scales"> - <item>実サイズ</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="other">分</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="other">%1$d キャッシュ</item> - </plurals> - <plurals name="waypoints"> - <item quantity="other">%d ウェイポイント</item> - </plurals> - <plurals name="tts_kilometers"> - <item quantity="other">%s キロメートル</item> - </plurals> </resources> diff --git a/main/res/values-lt/strings.xml b/main/res/values-lt/strings.xml index 2494f90..66f0e7f 100644 --- a/main/res/values-lt/strings.xml +++ b/main/res/values-lt/strings.xml @@ -80,21 +80,9 @@ <string name="log_saving_and_uploading">Siunčiamas įrašas ir įkeliama nuotrauka…</string> <string name="log_clear">Išvalyti</string> <string name="log_post">Siųsti įrašą</string> - <string name="log_post_rate">Siųsti įrašą ir Reitinguoti</string> - <string name="log_post_no_rate">Siųsti įrašą ir Nereitinguoti</string> <string name="log_post_not_possible">Įkeliamas įrašo puslapis…</string> <string name="log_add">Pridėti</string> - <string name="log_rating">Reitingas</string> <string name="log_no_rating">Nėra reitingo</string> - <string name="log_stars_1">1 žvaigždė</string> - <string name="log_stars_15">1,5 žvaigždės</string> - <string name="log_stars_2">2 žvaigždės</string> - <string name="log_stars_25">2,5 žvaigždės</string> - <string name="log_stars_3">3 žvaigždės</string> - <string name="log_stars_35">3,5 žvaigždės</string> - <string name="log_stars_4">4 žvaigždės</string> - <string name="log_stars_45">4,5 žvaigždės</string> - <string name="log_stars_5">5 žvaigždės</string> <string name="log_stars_1_description">Prasta</string> <string name="log_stars_15_description">Pakankamai prasta</string> <string name="log_stars_2_description">Žemiau vidutinio</string> @@ -113,7 +101,6 @@ <string name="log_smilies">Šypsenėlės</string> <string name="log_image">Nuotrauka</string> <string name="log_image_attach">Pridėti nuotrauką</string> - <string name="log_image_edit">Taisyti nuotrauką</string> <string name="log_image_stored">Esamą</string> <string name="log_image_camera">Naują</string> <string name="log_image_caption">Antraštė</string> @@ -122,6 +109,13 @@ <string name="log_password_title">Įrašo slaptažodis:</string> <string name="log_hint_log_password">Įveskite savo įrašo slaptažodį</string> <string name="log_oc_team_comment">OC komandos komentaras</string> + <string-array name="log_image_scales"> + <item>Nekeisti dydžio</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Išversti į %s</string> <string name="translate_to_english">Išversti į anglų</string> <string name="translate_length_warning">Vertimas gali nepavykti jei tekstas labai ilgas.</string> @@ -214,6 +208,7 @@ <string name="info_select_logimage_cancelled">Nuotraukos pasirinkimas ar fotografavimas buvo atšauktas.</string> <string name="info_stored_image">Nauja nuotrauka įrašyta į:</string> <string name="info_storing_static_maps">Bandoma išsaugoti statinius žemėlapius</string> + <string name="info_cache_saved">Slėptuvė buvo išsaugota lokaliai</string> <string name="loc_last">Paskutinė žinoma vieta</string> <string name="loc_net">Tinklas</string> <string name="loc_gps">GPS</string> @@ -221,6 +216,7 @@ <string name="loc_trying">Bandoma nustatyti</string> <string name="loc_no_addr">Nežinomas adresas</string> <string name="loc_gps_disabled">GPS išjungtas</string> + <string name="menu_centerposition">Centruoti mano poziciją</string> <string name="menu_about">Apie c:geo</string> <string name="menu_helpers">Naudingos programos</string> <string name="menu_settings">Nustatymai</string> @@ -240,12 +236,17 @@ <string name="caches_more_caches_no">Daugiau slėptuvių nėra</string> <string name="caches_more_caches_loading">Įkeliamos slėptuvės…</string> <string name="caches_more_caches_currently">dabar</string> - <string name="caches_downloading">Atsisiunčiamos slėptuvės…\nUžtruks</string> + <string name="caches_downloading">Atnaujinamos slėptuvės…\nUžtruks</string> <string name="caches_eta_ltm">mažiau nei minutę</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minutę</item> + <item quantity="few">minutes</item> + <item quantity="other">minučių</item> + </plurals> <string name="caches_store_offline">Išsaugoti slėptuves</string> <string name="caches_store_selected">Išsaugoti pasirinktas</string> <string name="caches_history">Istorija</string> - <string name="caches_on_map">Žemėlapyje</string> + <string name="caches_on_map">Rodyti žemėlapyje</string> <string name="caches_sort">Rūšiuoti</string> <string name="caches_sort_title">Rūšiuoti pagal</string> <string name="caches_sort_distance">Atstumą</string> @@ -303,10 +304,8 @@ <string name="caches_removing_from_history">Pašalinama iš Istorijos…</string> <string name="caches_clear_offlinelogs">Išvalyti išsaugotus įrašus</string> <string name="caches_clear_offlinelogs_progress">Išvalomi išsaugoti įrašai</string> - <string name="list_menu">Sąrašas</string> <string name="list_menu_create">Sukurti naują sąrašą</string> <string name="list_menu_drop">Išmesti dabartinį sąrašą</string> - <string name="list_menu_change">Pakeisti sąrašą</string> <string name="list_menu_rename">Pervadinti dabartinį sąrašą</string> <string name="list_title">Pasirinkti sąrašą</string> <string name="list_inbox">Išsaugota</string> @@ -400,8 +399,8 @@ <string name="init_signature_template_log">Įrašo tekstas</string> <string name="init_ratingwanted">GCvote reitingas</string> <string name="init_summary_ratingwanted">Įkelti slėptuvės reitingą iš GCvote.com</string> - <string name="init_friendlogswanted">Rodyti draugų įrašus</string> - <string name="init_summary_friendlogswanted">Rodyti papildomą draugų įrašų puslapį</string> + <string name="init_friends_and_own_logs_wanted">Rodyti draugų/savo</string> + <string name="init_summary_friends_and_own_logs_wanted">Rodyti papildomą draugų ir savų įrašų puslapį</string> <string name="init_openlastdetailspage">Paskutinis naudotas puslapis</string> <string name="init_summary_openlastdetailspage">Atidaryti kitą slėptuvę nuo paskutinio naudoto puslapio</string> <string name="init_autoload">Ilgas aprašymas</string> @@ -413,6 +412,8 @@ <string name="init_captcha">Rodyti CAPTCHA</string> <string name="init_summary_captcha">Jei reikia rodyti CAPTCHA (tik baziniams nariams)</string> <string name="init_useenglish">Anglu kalba</string> + <string name="init_showoverflowmenu">Visada rodyti papildomą meniu</string> + <string name="init_showoverflow_summary">Visada rodyti papildomą meniu (trys taškai ⋮) net jei prietaisas turi meniu mygtuką (reikia pakartotinai paleisti)</string> <string name="init_summary_useenglish">Naudoti anglų kalbą (reikia pakartotinai paleisti)</string> <string name="init_exclude">Atmesti savo ir rastas</string> <string name="init_summary_exclude">Atmesti nuosavas ir rastas slėptuves</string> @@ -490,6 +491,9 @@ <string name="init_maintenance">Priežiūra</string> <string name="init_maintenance_directories_note">c:geo saugo nuotraukas, įrašų nuotraukas ir kitus failus, susijusius su slėptuve, atskirame kataloge. Kai kuriais atvejais (pvz., importuojant/eksportuojant duomenų bazę) šiame kataloge gali likti pasenusių failų, kuriuos galima panaikinti čia.</string> <string name="init_maintenance_directories">Ištrinti nebereikalingus failus</string> + <string name="init_create_memory_dump">Sukurti atminties dump failą</string> + <string name="init_memory_dump">Atminties dump failas</string> + <string name="init_memory_dumped">Atminties dump failas išsaugotas %s</string> <string name="settings_open_website">Atidaryti interneto svetainę</string> <string name="settings_settings">Nustatymai</string> <string name="settings_information">Informacija</string> @@ -536,6 +540,11 @@ <string name="auth_dialog_completed_twitter">c:geo priregistruota ir jai leidžiama rašyti Twitter paskyroje.</string> <string name="auth_ocde">opencaching.de</string> <string name="auth_dialog_completed_oc">c:geo dabar registruota ir leidžiama naudotis %s.</string> + <plurals name="cache_counts"> + <item quantity="one">%1$d slėptuvė</item> + <item quantity="few">%1$d slėptuvės</item> + <item quantity="other">%1$d slėptuvių</item> + </plurals> <string name="cache_offline">Išsaugota</string> <string name="cache_offline_refresh">Naujinti</string> <string name="cache_offline_drop">Išmesti</string> @@ -562,8 +571,6 @@ <string name="cache_personal_note_uploading">Įkeliama asmeninė pastaba</string> <string name="cache_personal_note_upload_done">Asmeninė pastaba įkelta</string> <string name="cache_personal_note_upload_cancelled">Asmeninės pastabos įkėlimas atšauktas</string> - <string name="cache_personal_note_unstored">Slėptuvė neišsaugota</string> - <string name="cache_personal_note_store">Rašyti asmeninę pastabą galima tik išsaugotos slėptuvės aprašyme.</string> <string name="cache_description">Aprašymas</string> <string name="cache_description_long">Ilgas aprašymas</string> <string name="cache_description_table_note">Aprašymas turi lentelės formatavimą ir norint pamatyti jį atvaizduotą teisingai gali tekti apsilankyti %s.</string> @@ -580,10 +587,15 @@ <string name="cache_list_unknown">Nėra sąraše</string> <string name="cache_images">Nuotraukos</string> <string name="cache_waypoints">Papildomi taškai</string> + <plurals name="waypoints"> + <item quantity="one">1papildomas taškas</item> + <item quantity="few">%d papildomi taškai</item> + <item quantity="other">%d papildomų taškų</item> + </plurals> <string name="cache_waypoints_add">Pridėti papildomą tašką</string> <string name="cache_hint">Užuomina</string> <string name="cache_logs">Įrašai</string> - <string name="cache_logsfriends">Draugų įrašai</string> + <string name="cache_logs_friends_and_own">Draugų/savi įrašai</string> <string name="cache_dialog_loading_details">Įkeliama slėptuvės informacija…</string> <string name="cache_dialog_loading_details_status_loadpage">Įkeliamas puslapis</string> <string name="cache_dialog_loading_details_status_details">Apdorojama informacija</string> @@ -598,7 +610,7 @@ <string name="cache_dialog_offline_drop_title">Pašalinti</string> <string name="cache_dialog_offline_drop_message">Slėptuvė pašalinama iš prietaiso atminties…</string> <string name="cache_dialog_refresh_title">Atnaujinti</string> - <string name="cache_dialog_refresh_message">Slėptuvės informacija atsiunčiama iš naujo…</string> + <string name="cache_dialog_refresh_message">Atnaujinama slėptuvės informacija…</string> <string name="cache_dialog_watchlist_add_title">Įtraukti į stebimų slėptuvių sąrašą</string> <string name="cache_dialog_watchlist_add_message">Slėptuvė įtraukiama į stebimų slėptuvių sąrašą…</string> <string name="cache_dialog_watchlist_remove_title">Pašalinti iš stebimų slėptuvių sąrašo</string> @@ -629,15 +641,14 @@ <string name="cache_menu_refresh">Atnaujinti</string> <string name="cache_menu_share">Bendrinti slėptuvę</string> <string name="cache_menu_move_list">Perkelti į kitą sąrašą</string> - <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_pebble">Pebble</string> <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Būsena</string> - <string name="cache_status_offline_log">Įrašas išsaugotas</string> + <string name="cache_status_offline_log">Išsaugotas įrašas</string> <string name="cache_status_found">Rasta</string> + <string name="cache_not_status_found">Nerasta</string> <string name="cache_status_archived">Suarchyvuota</string> <string name="cache_status_disabled">Išjungta</string> <string name="cache_status_premium">Tik Premium nariams</string> @@ -749,10 +760,7 @@ <string name="map_view_map">Žemėlapio šaltinis</string> <string name="map_modes">Žemėlapio nustatymai</string> <string name="map_trail_show">Rodyti pėdsaką</string> - <string name="map_trail_hide">Slėpti pėdsaką</string> <string name="map_circles_show">Rodyti apskritimus</string> - <string name="map_circles_hide">Slėpti apskritimus</string> - <string name="map_mycaches_show">Rodyti savo/rastas slėptuves</string> <string name="map_mycaches_hide">Slėpti savo/rastas slėptuves</string> <string name="map_theme_builtin">Numatyta</string> <string name="map_theme_select">Pasirinkti žemėlapio temą</string> @@ -1105,7 +1113,6 @@ <string name="website">Tinklapis: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Vadovas: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">c:geo on Google Play</a></string> <string name="about_twitter">Kaskart registruojant slėptuvę <b>c:geo</b> paskelbs nauja statusą Twitter paskyroje.</string> <string name="status_new_release" tools:ignore="UnusedResources">Galima nauja versija. \nPaspauskite čia ir įdiekite.</string> @@ -1120,57 +1127,32 @@ <string name="tts_stop">Nekalbėti</string> <string name="err_tts_lang_not_supported">Dabartinė kalba nepalaikoma teksto-į-kalbą.</string> <string name="tts_one_kilometer">vienas kilometras</string> - <string name="tts_one_meter">vienas metras</string> - <string name="tts_one_mile">viena mylia</string> - <string name="tts_one_foot">viena pėda</string> - <string name="tts_one_oclock">one o\'clock</string> - <string name="tts_oclock">%s o\'clock</string> - <string name="clipboard_copy_ok">Nukopijuota į mainų sritį</string> - <string name="percent_favorite_points">%\ mėgiamos</string> - <string name="cgeo_shortcut">c:geo nuoroda</string> - <string name="create_shortcut">Sukurti nuorodą</string> - <string-array name="log_image_scales"> - <item>Nekeisti dydžio</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minutę</item> - <item quantity="few">minutes</item> - <item quantity="other">minučių</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">%1$d slėptuvė</item> - <item quantity="few">%1$d slėptuvės</item> - <item quantity="other">%1$d slėptuvių</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1papildomas taškas</item> - <item quantity="few">%d papildomi taškai</item> - <item quantity="other">%d papildomų taškų</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometras</item> <item quantity="few">%s kilometrai</item> <item quantity="other">%s kilometrų</item> </plurals> + <string name="tts_one_meter">vienas metras</string> <plurals name="tts_meters"> <item quantity="one">%s metras</item> <item quantity="few">%s metrai</item> <item quantity="other">%s metrų</item> </plurals> + <string name="tts_one_mile">viena mylia</string> <plurals name="tts_miles"> <item quantity="one">%s mylia</item> <item quantity="few">%s mylios</item> <item quantity="other">%s mylių</item> </plurals> + <string name="tts_one_foot">viena pėda</string> <plurals name="tts_feet"> <item quantity="one">%s pėda</item> <item quantity="few">%s pėdos</item> <item quantity="other">%s pėdų</item> </plurals> + <string name="tts_one_oclock">one o\'clock</string> + <string name="tts_oclock">%s o\'clock</string> + <string name="clipboard_copy_ok">Nukopijuota į mainų sritį</string> <plurals name="days_ago"> <item quantity="one">vakar</item> <item quantity="few">%d dienas atgal</item> @@ -1181,4 +1163,8 @@ <item quantity="few">%s mėgiamos</item> <item quantity="other">%s mėgiamų</item> </plurals> + <string name="percent_favorite_points">%\ mėgiamos</string> + <string name="cgeo_shortcut">c:geo nuoroda</string> + <string name="create_shortcut">Sukurti nuorodą</string> + <string name="send">Siųsti</string> </resources> diff --git a/main/res/values-nb/strings.xml b/main/res/values-nb/strings.xml index 6fe79e1..4a3404e 100644 --- a/main/res/values-nb/strings.xml +++ b/main/res/values-nb/strings.xml @@ -79,21 +79,9 @@ <string name="log_saving_and_uploading">Sender logg og laster opp bilde…</string> <string name="log_clear">Tøm</string> <string name="log_post">Last opp loggen</string> - <string name="log_post_rate">Last opp loggen og rangér</string> - <string name="log_post_no_rate">Last opp loggen uten å rangere</string> <string name="log_post_not_possible">Laster loggsiden…</string> <string name="log_add">Legg til</string> - <string name="log_rating">Rangering</string> <string name="log_no_rating">Ingen rangering</string> - <string name="log_stars_1">1 stjerne</string> - <string name="log_stars_15">1,5 stjerner</string> - <string name="log_stars_2">2 stjerner</string> - <string name="log_stars_25">2,5 stjerner</string> - <string name="log_stars_3">3 stjerner</string> - <string name="log_stars_35">3,5 stjerner</string> - <string name="log_stars_4">4 stjerner</string> - <string name="log_stars_45">4,5 stjerner</string> - <string name="log_stars_5">5 stjerner</string> <string name="log_stars_1_description">Dårlig</string> <string name="log_stars_15_description">Ganske dårlig</string> <string name="log_stars_2_description">Under gjennomsnitt</string> @@ -112,7 +100,6 @@ <string name="log_smilies">Smilefjes</string> <string name="log_image">Bilde</string> <string name="log_image_attach">Legg ved bilde</string> - <string name="log_image_edit">Rediger bilde</string> <string name="log_image_stored">Eksisterende</string> <string name="log_image_camera">Nytt</string> <string name="log_image_caption">Bildetekst</string> @@ -121,6 +108,13 @@ <string name="log_password_title">Passord for logg:</string> <string name="log_hint_log_password">Angi passordet for logg</string> <string name="log_oc_team_comment">Kommentar fra OC-teamet</string> + <string-array name="log_image_scales"> + <item>Ingen skalering</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Oversett til %s</string> <string name="translate_to_english">Oversett til engelsk</string> <string name="translate_length_warning">Oversettelse kan mislykkes med store mengder tekst.</string> @@ -241,6 +235,10 @@ <string name="caches_more_caches_currently">for øyeblikket</string> <string name="caches_downloading">Laster ned cacher…\nETA: </string> <string name="caches_eta_ltm">Mindre enn ett minutt</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minutt</item> + <item quantity="other">minutter</item> + </plurals> <string name="caches_store_offline">Lagre for offline-bruk</string> <string name="caches_store_selected">Lagre valgte</string> <string name="caches_history">Historikk</string> @@ -301,10 +299,8 @@ <string name="caches_removing_from_history">Fjerner fra historikken…</string> <string name="caches_clear_offlinelogs">Fjern offline-logger</string> <string name="caches_clear_offlinelogs_progress">Fjerner offline-logger</string> - <string name="list_menu">Liste</string> <string name="list_menu_create">Opprett ny liste</string> <string name="list_menu_drop">Fjern liste</string> - <string name="list_menu_change">Endre liste</string> <string name="list_menu_rename">Endre navn på listen</string> <string name="list_title">Velg en liste</string> <string name="list_inbox">Lagret</string> @@ -395,8 +391,6 @@ <string name="init_signature_template_log">Loggtekst</string> <string name="init_ratingwanted">GCvote-rangering</string> <string name="init_summary_ratingwanted">Last rangering for cachen fra GCvote.com</string> - <string name="init_friendlogswanted">Vis venners logger</string> - <string name="init_summary_friendlogswanted">Vis flere logger fra venner</string> <string name="init_openlastdetailspage">Sist brukte fane</string> <string name="init_summary_openlastdetailspage">Åpne detaljsiden til cacher på den siste brukte fanen</string> <string name="init_autoload">Last full beskrivelse automatisk</string> @@ -531,6 +525,10 @@ <string name="auth_dialog_completed_twitter">c:geo har nå fått godkjenning til å kvitre på Twitter.</string> <string name="auth_ocde">opencaching.de</string> <string name="auth_dialog_completed_oc">c:geo har nå fått godkjenning til å kommunisere med %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Én cache</item> + <item quantity="other">%1$d cacher</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Oppdater</string> <string name="cache_offline_drop">Fjern</string> @@ -557,8 +555,6 @@ <string name="cache_personal_note_uploading">Laster opp personlig cachenotat</string> <string name="cache_personal_note_upload_done">Personlig cachenotat er lastet opp</string> <string name="cache_personal_note_upload_cancelled">Personlig cachenotat ble avbrutt under opplasting</string> - <string name="cache_personal_note_unstored">Cachen er ikke lagret</string> - <string name="cache_personal_note_store">Cachen vil bli lagret for å skrive personlig cachenotat.</string> <string name="cache_description">Beskrivelse</string> <string name="cache_description_long">Full beskrivelse</string> <string name="cache_description_table_note">Beskrivelsen inneholder tabellformatering og må åpnes på %s for å vises riktig.</string> @@ -575,10 +571,13 @@ <string name="cache_list_unknown">Ikke i en liste</string> <string name="cache_images">Bilder</string> <string name="cache_waypoints">Veipunkter</string> + <plurals name="waypoints"> + <item quantity="one">1 veipunkt</item> + <item quantity="other">%d veipunkter</item> + </plurals> <string name="cache_waypoints_add">Legg til veipunkter</string> <string name="cache_hint">Hint</string> <string name="cache_logs">Loggbok</string> - <string name="cache_logsfriends">Loggbok (venner)</string> <string name="cache_dialog_loading_details">Laster cachens detaljer…</string> <string name="cache_dialog_loading_details_status_loadpage">Laster siden</string> <string name="cache_dialog_loading_details_status_details">Behandler detaljer</string> @@ -624,10 +623,8 @@ <string name="cache_menu_refresh">Oppdater</string> <string name="cache_menu_share">Del cachen</string> <string name="cache_menu_move_list">Flytt til annen liste</string> - <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_pebble">Pebble</string> <string name="cache_status">Status</string> <string name="cache_status_offline_log">Logg lagret</string> @@ -743,10 +740,7 @@ <string name="map_view_map">Kart</string> <string name="map_modes">Kartinnstillinger</string> <string name="map_trail_show">Vis spor</string> - <string name="map_trail_hide">Skjul spor</string> <string name="map_circles_show">Vis sirkler</string> - <string name="map_circles_hide">Skjul sirkler</string> - <string name="map_mycaches_show">Vis egne og funnede cacher</string> <string name="map_mycaches_hide">Skjul egne og funnede cacher</string> <string name="map_theme_builtin">Standard</string> <string name="map_theme_select">Velg karttema</string> @@ -1100,7 +1094,6 @@ <string name="website">web-side: <a href="http://cgeo.org/">cgeo.org</a></string> <string name="facebook">facebook: <a href="http://www.facebook.com/pages/cgeo/297269860090">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Bruksanvisning: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">c:geo i Google Play</a></string> <string name="about_twitter">Ønsker du at <b>c:geo</b> skal poste en status på Twitter hver gang du logger ett funn via <b>c:geo</b>?</string> <string name="status_new_release" tools:ignore="UnusedResources">Ny versjon tilgjengelig. \nKlikk for å installere.</string> @@ -1117,40 +1110,18 @@ <string name="tts_one_kilometer">en kilometer</string> <string name="tts_one_meter">en meter</string> <string name="tts_one_mile">En enkelsk mil</string> - <string name="tts_one_foot">En fot</string> - <string name="tts_one_oclock">klokken ett</string> - <string name="tts_oclock">klokken %s</string> - <string name="clipboard_copy_ok">Kopiert til utklippstavlen</string> - <string name="percent_favorite_points">%\ favoritter</string> - <string name="cgeo_shortcut">c:geo-snartvei</string> - <string name="create_shortcut">Opprett snarvei</string> - <string-array name="log_image_scales"> - <item>Ingen skalering</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minutt</item> - <item quantity="other">minutter</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Én cache</item> - <item quantity="other">%1$d cacher</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 veipunkt</item> - <item quantity="other">%d veipunkter</item> - </plurals> <plurals name="tts_miles"> <item quantity="one">%s engelsk mil</item> <item quantity="other">%s engelske mil</item> </plurals> + <string name="tts_one_foot">En fot</string> <plurals name="tts_feet"> <item quantity="one">%s fot</item> <item quantity="other">%s fot</item> </plurals> + <string name="tts_one_oclock">klokken ett</string> + <string name="tts_oclock">klokken %s</string> + <string name="clipboard_copy_ok">Kopiert til utklippstavlen</string> <plurals name="days_ago"> <item quantity="one">i går</item> <item quantity="other">%d dager siden</item> @@ -1159,4 +1130,7 @@ <item quantity="one">%s favoritt</item> <item quantity="other">%s favoritt</item> </plurals> + <string name="percent_favorite_points">%\ favoritter</string> + <string name="cgeo_shortcut">c:geo-snartvei</string> + <string name="create_shortcut">Opprett snarvei</string> </resources> diff --git a/main/res/values-nl/strings.xml b/main/res/values-nl/strings.xml index 3568423..ea6c0fc 100644 --- a/main/res/values-nl/strings.xml +++ b/main/res/values-nl/strings.xml @@ -18,6 +18,7 @@ <string name="letterbox">Letterbox hybrid</string> <string name="event">Event cache</string> <string name="mega">Mega-event cache</string> + <string name="giga">Giga-Event Cache</string> <string name="earth">Earthcache</string> <string name="cito">Cache in trash out event</string> <string name="webcam">Webcam cache</string> @@ -79,21 +80,9 @@ <string name="log_saving_and_uploading">Verzenden van log en uploaden foto…</string> <string name="log_clear">Wissen</string> <string name="log_post">Verzend log</string> - <string name="log_post_rate">Verzend log & beoordeel</string> - <string name="log_post_no_rate">Verzend log zonder beoordeling</string> <string name="log_post_not_possible">Laden Log Pagina…</string> <string name="log_add">Toevoegen</string> - <string name="log_rating">Beoordeling</string> <string name="log_no_rating">Geen beoordeling</string> - <string name="log_stars_1">1 ster</string> - <string name="log_stars_15">1.5 ster</string> - <string name="log_stars_2">2 sterren</string> - <string name="log_stars_25">2.5 sterren</string> - <string name="log_stars_3">3 sterren</string> - <string name="log_stars_35">3.5 sterren</string> - <string name="log_stars_4">4 sterren</string> - <string name="log_stars_45">4.5 sterren</string> - <string name="log_stars_5">5 sterren</string> <string name="log_stars_1_description">Slecht</string> <string name="log_stars_15_description">Redelijk slecht</string> <string name="log_stars_2_description">Beneden gemiddeld</string> @@ -112,7 +101,6 @@ <string name="log_smilies">Smilies</string> <string name="log_image">Foto</string> <string name="log_image_attach">Foto koppelen</string> - <string name="log_image_edit">Foto bewerken</string> <string name="log_image_stored">Bestaande</string> <string name="log_image_camera">Nieuw</string> <string name="log_image_caption">Bijschrift</string> @@ -121,6 +109,13 @@ <string name="log_password_title">Log wachtwoord:</string> <string name="log_hint_log_password">Voer Login Wachtwoord</string> <string name="log_oc_team_comment">OC Team commentaar</string> + <string-array name="log_image_scales"> + <item>Niet schalen</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Vertaal naar %s</string> <string name="translate_to_english">Vertaal naar engels</string> <string name="translate_length_warning">Vertaling kan mislukken bij grote stukken tekst.</string> @@ -241,6 +236,10 @@ <string name="caches_more_caches_currently">op dit moment</string> <string name="caches_downloading">Caches aan het downloaden…\nGeschatte tijd: </string> <string name="caches_eta_ltm">Minder dan een minuut</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuut</item> + <item quantity="other">minuten</item> + </plurals> <string name="caches_store_offline">Opslaan voor Offline gebruik</string> <string name="caches_store_selected">Geselecteerden opslaan</string> <string name="caches_history">Geschiedenis</string> @@ -282,6 +281,7 @@ <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_map_mapswithme">MapsWithMe</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> @@ -301,10 +301,8 @@ <string name="caches_removing_from_history">Verwijderen uit geschiedenis…</string> <string name="caches_clear_offlinelogs">Verwijderen offline logs</string> <string name="caches_clear_offlinelogs_progress">Offline logs worden verwijderd</string> - <string name="list_menu">Lijst</string> <string name="list_menu_create">Maak nieuwe lijst</string> <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> @@ -402,8 +400,8 @@ <string name="init_signature_template_log">Log tekst</string> <string name="init_ratingwanted">GCvote.com waardering</string> <string name="init_summary_ratingwanted">Laad cachewaardering van GCvote.com</string> - <string name="init_friendlogswanted">Lange omschrijving</string> - <string name="init_summary_friendlogswanted">Laad extra logbook pagina voor logs van vrienden</string> + <string name="init_friends_and_own_logs_wanted">Toon eigen/van vrienden</string> + <string name="init_summary_friends_and_own_logs_wanted">Toon additionele logboek pagina voor eigen en vrienden logs</string> <string name="init_openlastdetailspage">Laad details met laatst gebruikte pagina</string> <string name="init_summary_openlastdetailspage">Laad details met laatst gebruikte pagina</string> <string name="init_autoload">Lange omschrijving</string> @@ -542,6 +540,10 @@ <string name="auth_ocus">opencaching.us</string> <string name="auth_ocro">opencaching.ro</string> <string name="auth_dialog_completed_oc">c:geo is nu gekoppeld met %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Een cache</item> + <item quantity="other">%1$d Caches</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Verversen</string> <string name="cache_offline_drop">Laten vervallen</string> @@ -568,8 +570,6 @@ <string name="cache_personal_note_uploading">Uploading persoonlijke notitie</string> <string name="cache_personal_note_upload_done">Persoonlijke notitie geupload</string> <string name="cache_personal_note_upload_cancelled">Persoonlijk notitie uploaden geannulleerd</string> - <string name="cache_personal_note_unstored">Cache niet opgeslagen</string> - <string name="cache_personal_note_store">De cache zal eerst opgeslagen worden om persoonlijke notities toe te kunnen voegen.</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> @@ -586,10 +586,14 @@ <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> + <item quantity="other">%d Waypoints</item> + </plurals> <string name="cache_waypoints_add">Waypoint toevoegen</string> <string name="cache_hint">Hint</string> <string name="cache_logs">Logboek</string> - <string name="cache_logsfriends">Logboek (vrienden)</string> + <string name="cache_logs_friends_and_own">Vrienden/Eigen Logs</string> <string name="cache_dialog_loading_details">Cache details laden…</string> <string name="cache_dialog_loading_details_status_loadpage">Pagina laden</string> <string name="cache_dialog_loading_details_status_details">Verwerken details</string> @@ -635,15 +639,15 @@ <string name="cache_menu_refresh">Verversen</string> <string name="cache_menu_share">Deel cache</string> <string name="cache_menu_move_list">Verplaats naar andere lijst</string> - <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_menu_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> + <string name="cache_menu_mapswithme">MapsWithMe</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_not_status_found">Niet 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> @@ -755,10 +759,7 @@ <string name="map_view_map">Kaart weergave</string> <string name="map_modes">Kaartinstellingen</string> <string name="map_trail_show">Toon spoor</string> - <string name="map_trail_hide">Verberg spoor</string> <string name="map_circles_show">Laat cirkels zien</string> - <string name="map_circles_hide">Verberg cirkels</string> - <string name="map_mycaches_show">Tonen eigen/gevonden caches</string> <string name="map_mycaches_hide">Verbergen eigen/gevonden caches</string> <string name="map_theme_builtin">Standaard</string> <string name="map_theme_select">Selecteer mapthema</string> @@ -1112,7 +1113,6 @@ <string name="website">Website: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Handleiding: <a href="">c:geo in een notendop</a></string> <string name="market">Android: <a href="">c:geo op Google Play</a></string> <string name="about_twitter">Moet <b>c:geo</b> elke cache vondst publiceren naar Twitter?</string> <string name="faq">FAQ: <a href=""> faq.cgeo.org</a></string> @@ -1128,50 +1128,28 @@ <string name="tts_stop">Stop met praten</string> <string name="err_tts_lang_not_supported">De huidige taal wordt niet ondersteund door tekst naar spraak.</string> <string name="tts_one_kilometer">één kilometer</string> - <string name="tts_one_meter">één meter</string> - <string name="tts_one_mile">één mijl</string> - <string name="tts_one_foot">één voet</string> - <string name="tts_one_oclock">één uur</string> - <string name="tts_oclock">%s uur</string> - <string name="clipboard_copy_ok">Gekopieerd naar klembord</string> - <string name="percent_favorite_points">%\ favorieten</string> - <string name="cgeo_shortcut">c:geo snelkoppeling</string> - <string name="create_shortcut">Maak snelkoppeling</string> - <string-array name="log_image_scales"> - <item>Niet schalen</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuut</item> - <item quantity="other">minuten</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Een cache</item> - <item quantity="other">%1$d Caches</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 Waypoint</item> - <item quantity="other">%d Waypoints</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometer</item> <item quantity="other">%s kilometer</item> </plurals> + <string name="tts_one_meter">één meter</string> <plurals name="tts_meters"> <item quantity="one">%s meter</item> <item quantity="other">%s meter</item> </plurals> + <string name="tts_one_mile">één mijl</string> <plurals name="tts_miles"> <item quantity="one">%s mijl</item> <item quantity="other">%s mijl</item> </plurals> + <string name="tts_one_foot">één voet</string> <plurals name="tts_feet"> <item quantity="one">%s voet</item> <item quantity="other">%s voeten</item> </plurals> + <string name="tts_one_oclock">één uur</string> + <string name="tts_oclock">%s uur</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> @@ -1180,4 +1158,7 @@ <item quantity="one">%s favoriet</item> <item quantity="other">%s favorieten</item> </plurals> + <string name="percent_favorite_points">%\ favorieten</string> + <string name="cgeo_shortcut">c:geo snelkoppeling</string> + <string name="create_shortcut">Maak snelkoppeling</string> </resources> diff --git a/main/res/values-pl/strings.xml b/main/res/values-pl/strings.xml index 26b5e23..9127437 100644 --- a/main/res/values-pl/strings.xml +++ b/main/res/values-pl/strings.xml @@ -18,6 +18,7 @@ <string name="letterbox">Hybrydowa Letterbox</string> <string name="event">Wydarzenie</string> <string name="mega">Mega-Wydarzenie</string> + <string name="giga">Giga-Wydarzenie</string> <string name="earth">Earthcache</string> <string name="cito">CITO</string> <string name="webcam">Skrzynka Webcam</string> @@ -79,21 +80,9 @@ <string name="log_saving_and_uploading">Zapisuję w dzienniku i wysyłam zdjęcie…</string> <string name="log_clear">Wyczyść</string> <string name="log_post">Wpisz do dziennika</string> - <string name="log_post_rate">Wpisz do dziennika & oceń</string> - <string name="log_post_no_rate">Wpisz do dziennika & nie oceniaj</string> <string name="log_post_not_possible">Ładuję dziennik…</string> <string name="log_add">Dodaj</string> - <string name="log_rating">Ocena</string> <string name="log_no_rating">Bez oceny</string> - <string name="log_stars_1">1 gwiazdka</string> - <string name="log_stars_15">1,5 gwiazdki</string> - <string name="log_stars_2">2 gwiazdki</string> - <string name="log_stars_25">2,5 gwiazdki</string> - <string name="log_stars_3">3 gwiazdki</string> - <string name="log_stars_35">3,5 gwiazdki</string> - <string name="log_stars_4">4 gwiazdki</string> - <string name="log_stars_45">4,5 gwiazdki</string> - <string name="log_stars_5">5 gwiazdek</string> <string name="log_stars_1_description">Słaba</string> <string name="log_stars_15_description">Raczej słaba</string> <string name="log_stars_2_description">Poniżej średniej</string> @@ -112,7 +101,6 @@ <string name="log_smilies">Uśmiechy</string> <string name="log_image">Obraz</string> <string name="log_image_attach">Załącz obraz</string> - <string name="log_image_edit">Edytuj obraz</string> <string name="log_image_stored">Zapisany</string> <string name="log_image_camera">Nowy</string> <string name="log_image_caption">Podpis</string> @@ -121,6 +109,13 @@ <string name="log_password_title">Hasło do logu:</string> <string name="log_hint_log_password">Wpisz hasło do logu</string> <string name="log_oc_team_comment">Komentarz zespołu OC</string> + <string-array name="log_image_scales"> + <item>Brak skalowania</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Przetłumacz na %s</string> <string name="translate_to_english">Przetłumacz na angielski</string> <string name="translate_length_warning">Tłumaczenie może nie udać się przy dużej ilości tekstu.</string> @@ -213,7 +208,7 @@ <string name="info_select_logimage_cancelled">Wybór obrazu został anulowany.</string> <string name="info_stored_image">Nowy obraz zapisany w:</string> <string name="info_storing_static_maps">Próbuję zapisać mapy statyczne</string> - <string name="loc_last">Ostatnia znana pozycja</string> + <string name="loc_last">Ostatnia pozycja</string> <string name="loc_net">Sieć</string> <string name="loc_gps">GPS</string> <string name="loc_sat">Sat</string> @@ -241,6 +236,11 @@ <string name="caches_more_caches_currently">Obecnie</string> <string name="caches_downloading">Pobieram skrzynki…\nSzacowany czas: </string> <string name="caches_eta_ltm">Mniej niż minuta</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuta</item> + <item quantity="few">minuty</item> + <item quantity="other">minut</item> + </plurals> <string name="caches_store_offline">Zapisz offline</string> <string name="caches_store_selected">Zapisz wybrane</string> <string name="caches_history">Historia</string> @@ -299,12 +299,10 @@ <string name="caches_filter_popularity">Ulubione</string> <string name="caches_filter_popularity_ratio">Ulubione [%]</string> <string name="caches_removing_from_history">Usuwam z Historii…</string> - <string name="caches_clear_offlinelogs">Usuń logi offline</string> - <string name="caches_clear_offlinelogs_progress">Usuwanie logów offline</string> - <string name="list_menu">Lista</string> + <string name="caches_clear_offlinelogs">Usuń wpisy offline</string> + <string name="caches_clear_offlinelogs_progress">Usuwanie wpisów offline</string> <string name="list_menu_create">Utwórz nową listę</string> <string name="list_menu_drop">Usuń aktualną listę</string> - <string name="list_menu_change">Zmień listę</string> <string name="list_menu_rename">Zmień nazwę aktualnej listy</string> <string name="list_title">Wybierz listę</string> <string name="list_inbox">Zapisane</string> @@ -399,8 +397,8 @@ <string name="init_signature_template_log">Wpis</string> <string name="init_ratingwanted">Załaduj ocenę skrzynki z GCvote.com</string> <string name="init_summary_ratingwanted">Załaduj ocenę skrzynki z GCvote.com</string> - <string name="init_friendlogswanted">Załaduj dodatkowy dziennik dla wpisów od przyjaciół</string> - <string name="init_summary_friendlogswanted">Załaduj dodatkowy dziennik dla wpisów od przyjaciół</string> + <string name="init_friends_and_own_logs_wanted">Pokaż przyjaciół/własne</string> + <string name="init_summary_friends_and_own_logs_wanted">Wyświetl dodatkowy dziennik dla wpisów własnych i przyjaciół</string> <string name="init_openlastdetailspage">Otwórz szczegóły ostatnio używanej strony</string> <string name="init_summary_openlastdetailspage">Otwórz szczegóły ostatnio używanej strony</string> <string name="init_autoload">Automatyczne ładowanie długich opisów</string> @@ -501,7 +499,7 @@ <string name="feature_description">Podane funkcje <b>online</b> na tej stronie są wspierane przez c:geo (w porównaniu do funkcji offline):</string> <string name="feature_personal_notes">Notatka osobista</string> <string name="feature_online_logging">Wpisy online</string> - <string name="feature_log_images">Załączanie zdjęć do logów</string> + <string name="feature_log_images">Załączanie zdjęć do wpisów</string> <string name="feature_watch_list">Listy obserwowanych skrzynek</string> <string name="feature_own_coordinates">Przechowywanie zmodyfikowanych współrzędnych</string> <string name="feature_search_keyword">Szukanie po słowie kluczowym</string> @@ -536,6 +534,11 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo został zautoryzowany by komunikować się z %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Jedna skrzynka</item> + <item quantity="few">%1$d skrzynki</item> + <item quantity="other">%1$d skrzynek</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Odśwież</string> <string name="cache_offline_drop">Usuń</string> @@ -562,8 +565,6 @@ <string name="cache_personal_note_uploading">Wysyłam osobistą notatkę</string> <string name="cache_personal_note_upload_done">Notatka osobista wysłana</string> <string name="cache_personal_note_upload_cancelled">Wysyłanie notatki osobistej anulowane</string> - <string name="cache_personal_note_unstored">Skrzynka nie jest zapisana</string> - <string name="cache_personal_note_store">Skrzynka będzie najpierw zapisana aby umożliwić dodawanie notatek osobistych.</string> <string name="cache_description">Opis</string> <string name="cache_description_long">Długi opis</string> <string name="cache_description_table_note">Opis zawiera formatowanie w formie tabeli, które w celu poprawnego wyświetlania może wymagać odwiedzenia %s.</string> @@ -580,10 +581,15 @@ <string name="cache_list_unknown">Nie znajduje się na liście</string> <string name="cache_images">Zdjęcia</string> <string name="cache_waypoints">Punkty nawigacji</string> + <plurals name="waypoints"> + <item quantity="one">1 punkt</item> + <item quantity="few">%d punkty</item> + <item quantity="other">%d punktów nawigacji</item> + </plurals> <string name="cache_waypoints_add">Dodaj punkt nawigacji</string> <string name="cache_hint">Wskazówka</string> <string name="cache_logs">Dziennik</string> - <string name="cache_logsfriends">Dziennik (Przyjaciele)</string> + <string name="cache_logs_friends_and_own">Wpisy przyjaciół/własne</string> <string name="cache_dialog_loading_details">Ładuję szczegóły skrzynki…</string> <string name="cache_dialog_loading_details_status_loadpage">Ładuję stronę</string> <string name="cache_dialog_loading_details_status_details">Przetwarzam szczegóły</string> @@ -629,15 +635,14 @@ <string name="cache_menu_refresh">Odśwież</string> <string name="cache_menu_share">Podziel się skrzynką</string> <string name="cache_menu_move_list">Przenieś do innej listy</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Zegarek Pebble</string> <string name="cache_status">Status</string> <string name="cache_status_offline_log">Zapamiętany wpis</string> <string name="cache_status_found">Znaleziona</string> + <string name="cache_not_status_found">Nie znaleziono</string> <string name="cache_status_archived">Zarchiwizowana</string> <string name="cache_status_disabled">Niedostępna</string> <string name="cache_status_premium">Tylko dla użytkowników Premium</string> @@ -749,10 +754,7 @@ <string name="map_view_map">Widok mapy</string> <string name="map_modes">Tryb mapy</string> <string name="map_trail_show">Pokaż szlak</string> - <string name="map_trail_hide">Ukryj szlak</string> <string name="map_circles_show">Pokaż okręgi</string> - <string name="map_circles_hide">Ukryj okręgi</string> - <string name="map_mycaches_show">Pokazuj własne/znalezione skrzynki</string> <string name="map_mycaches_hide">Ukryj własne/znalezione skrzynki</string> <string name="map_theme_builtin">Domyślny</string> <string name="map_theme_select">Wybierz motyw mapy</string> @@ -1106,7 +1108,6 @@ <string name="website">Website: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo strona</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Podręcznik: <a href="">c:geo skrócona instrukcja obsługi</a></string> <string name="market">Android: <a href="">c:geo w Google Play</a></string> <string name="about_twitter">Czy chczesz aby <b>c:geo</b> publikował nowy status na Twitter za każdym razem kiedy znajdziesz skrzynkę?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1122,57 +1123,32 @@ <string name="tts_stop">Przestań mówić</string> <string name="err_tts_lang_not_supported">Aktualny język nie jest wspierany przez text-to-speech.</string> <string name="tts_one_kilometer">jeden kilometr</string> - <string name="tts_one_meter">jeden metr</string> - <string name="tts_one_mile">jedna mila</string> - <string name="tts_one_foot">jedna stopa</string> - <string name="tts_one_oclock">pierwsza</string> - <string name="tts_oclock">%s</string> - <string name="clipboard_copy_ok">Skopiowano do schowka</string> - <string name="percent_favorite_points">%\ ulubionych</string> - <string name="cgeo_shortcut">skrót do c:geo</string> - <string name="create_shortcut">Utwórz skrót</string> - <string-array name="log_image_scales"> - <item>Brak skalowania</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuta</item> - <item quantity="few">minuty</item> - <item quantity="other">minut</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Jedna skrzynka</item> - <item quantity="few">%1$d skrzynki</item> - <item quantity="other">%1$d skrzynek</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 punkt</item> - <item quantity="few">%d punkty</item> - <item quantity="other">%d punktów nawigacji</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometr</item> <item quantity="few">%s kilometry</item> <item quantity="other">%s kilometrów</item> </plurals> + <string name="tts_one_meter">jeden metr</string> <plurals name="tts_meters"> <item quantity="one">%s metr</item> <item quantity="few">%s metry</item> <item quantity="other">%s metrów</item> </plurals> + <string name="tts_one_mile">jedna mila</string> <plurals name="tts_miles"> <item quantity="one">%s mila</item> <item quantity="few">%s mile</item> <item quantity="other">%s mil</item> </plurals> + <string name="tts_one_foot">jedna stopa</string> <plurals name="tts_feet"> <item quantity="one">%s stopa</item> <item quantity="few">%s stopy</item> <item quantity="other">%s stóp</item> </plurals> + <string name="tts_one_oclock">pierwsza</string> + <string name="tts_oclock">%s</string> + <string name="clipboard_copy_ok">Skopiowano do schowka</string> <plurals name="days_ago"> <item quantity="one">wczoraj</item> <item quantity="few">%d dni temu</item> @@ -1183,4 +1159,7 @@ <item quantity="few">%s ulubione</item> <item quantity="other">%s ulubionych</item> </plurals> + <string name="percent_favorite_points">%\ ulubionych</string> + <string name="cgeo_shortcut">skrót do c:geo</string> + <string name="create_shortcut">Utwórz skrót</string> </resources> diff --git a/main/res/values-pt/strings.xml b/main/res/values-pt/strings.xml index 8d781b5..60a9892 100644 --- a/main/res/values-pt/strings.xml +++ b/main/res/values-pt/strings.xml @@ -79,21 +79,9 @@ <string name="log_saving_and_uploading">A enviar o registo e a imagem…</string> <string name="log_clear">Limpar</string> <string name="log_post">Publicar o registo</string> - <string name="log_post_rate">Publicar registo & Votar</string> - <string name="log_post_no_rate">Publicar registo & Não votar</string> <string name="log_post_not_possible">A carregar página de registo…</string> <string name="log_add">Adicionar</string> - <string name="log_rating">Pontuação</string> <string name="log_no_rating">Não votar</string> - <string name="log_stars_1">1 estrela</string> - <string name="log_stars_15">1.5 estrelas</string> - <string name="log_stars_2">2 estrelas</string> - <string name="log_stars_25">2.5 estrelas</string> - <string name="log_stars_3">3 estrelas</string> - <string name="log_stars_35">3.5 estrelas</string> - <string name="log_stars_4">4 estrelas</string> - <string name="log_stars_45">4.5 estrelas</string> - <string name="log_stars_5">5 estrelas</string> <string name="log_stars_1_description">Terrível</string> <string name="log_stars_15_description">Muito má</string> <string name="log_stars_2_description">Má</string> @@ -112,7 +100,6 @@ <string name="log_smilies">Smilies</string> <string name="log_image">Imagem</string> <string name="log_image_attach">Anexar Imagem</string> - <string name="log_image_edit">Editar Imagem</string> <string name="log_image_stored">Existente</string> <string name="log_image_camera">Nova</string> <string name="log_image_caption">Título</string> @@ -121,6 +108,13 @@ <string name="log_password_title">Password do registo:</string> <string name="log_hint_log_password">Inserira a password do registo</string> <string name="log_oc_team_comment">Comentário da OC Team</string> + <string-array name="log_image_scales"> + <item>Não dimensionar</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Traduzir para %s</string> <string name="translate_to_english">Traduzir para inglês</string> <string name="translate_length_warning">A tradução pode falhar se o texto fôr muito grande.</string> @@ -241,6 +235,10 @@ <string name="caches_more_caches_currently">actualmente</string> <string name="caches_downloading">Downloading caches…\nETE: </string> <string name="caches_eta_ltm">Menos de um minuto</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuto</item> + <item quantity="other">minutos</item> + </plurals> <string name="caches_store_offline">Arquivar para uso offline</string> <string name="caches_store_selected">Arquivar selecionadas</string> <string name="caches_history">Histórico</string> @@ -301,10 +299,8 @@ <string name="caches_removing_from_history">A remover do histórico…</string> <string name="caches_clear_offlinelogs">Limpar registos offline</string> <string name="caches_clear_offlinelogs_progress">A limpar registos offline</string> - <string name="list_menu">Listas</string> <string name="list_menu_create">Criar nova lista</string> <string name="list_menu_drop">Apagar lista actual</string> - <string name="list_menu_change">Mudar de lista</string> <string name="list_menu_rename">Mudar o nome da lista corrente.</string> <string name="list_title">Escolha uma lista</string> <string name="list_inbox">Arquivadas</string> @@ -402,8 +398,6 @@ <string name="init_signature_template_log">Texto de registo</string> <string name="init_ratingwanted">Carregar a pontuação da cache de GCvote.com</string> <string name="init_summary_ratingwanted">Carregar a pontuação da cache de GCvote.com</string> - <string name="init_friendlogswanted">Carregar página adicional de registos de amigos</string> - <string name="init_summary_friendlogswanted">Carregar página adicional de registos de amigos</string> <string name="init_openlastdetailspage">Abrir detalhes da última página vizualizada</string> <string name="init_summary_openlastdetailspage">Abrir detalhes da última página vizualizada</string> <string name="init_autoload">Carregar automaticamente a descrição longa</string> @@ -539,6 +533,10 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">Opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo está agora autorizado a interagir com %s.</string> + <plurals name="cache_counts"> + <item quantity="one">Uma cache</item> + <item quantity="other">%1$d Caches</item> + </plurals> <string name="cache_offline">Arquivo</string> <string name="cache_offline_refresh">Actualizar</string> <string name="cache_offline_drop">Apagar</string> @@ -565,8 +563,6 @@ <string name="cache_personal_note_uploading">A enviar nota pessoal</string> <string name="cache_personal_note_upload_done">Nota pessoal enviada</string> <string name="cache_personal_note_upload_cancelled">Envio de nota pessoal cancelado</string> - <string name="cache_personal_note_unstored">Cache não guaradada</string> - <string name="cache_personal_note_store">A cache vai ser guardada primeiro para permitir notas pessoais.</string> <string name="cache_description">Descrição</string> <string name="cache_description_long">Descrição longa</string> <string name="cache_description_table_note">A descrição contém a formatação da tabela que pode ser necessário para ser vista correctamente em %s.</string> @@ -583,10 +579,13 @@ <string name="cache_list_unknown">Não está numa lista</string> <string name="cache_images">Imagens</string> <string name="cache_waypoints">Pontos de referência</string> + <plurals name="waypoints"> + <item quantity="one">1 Waypoint</item> + <item quantity="other">%d Waypoints</item> + </plurals> <string name="cache_waypoints_add">Adicionar ponto de referência</string> <string name="cache_hint">Pista</string> <string name="cache_logs">Logbook</string> - <string name="cache_logsfriends">Logbook (Amigos)</string> <string name="cache_dialog_loading_details">A carregar os detalhes da cache…</string> <string name="cache_dialog_loading_details_status_loadpage">A carregar a página</string> <string name="cache_dialog_loading_details_status_details">A processar os detalhes</string> @@ -632,10 +631,8 @@ <string name="cache_menu_refresh">Actualizar</string> <string name="cache_menu_share">Partilhar cache</string> <string name="cache_menu_move_list">Mover para outra lista</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Seixo</string> <string name="cache_status">Estado</string> @@ -752,10 +749,7 @@ <string name="map_view_map">Vista de mapa</string> <string name="map_modes">Modos de mapa</string> <string name="map_trail_show">Mostrar caminho</string> - <string name="map_trail_hide">Esconder caminho</string> <string name="map_circles_show">Mostrar círculos</string> - <string name="map_circles_hide">Esconder círculos</string> - <string name="map_mycaches_show">Mostrar caches encontradas e minhas</string> <string name="map_mycaches_hide">Esconder caches encontradas e minhas</string> <string name="map_theme_builtin">Padrão</string> <string name="map_theme_select">Selecione o tema de mapa</string> @@ -1109,7 +1103,6 @@ <string name="website">Site na internet: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">página do c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">o essencial do c:geo</a></string> <string name="market">Android: <a href="">c:geo no Google Play</a></string> <string name="about_twitter">O <b>c:geo</b> deve publicar no Twitter de cada vez que uma cache foi registrada?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1125,52 +1118,33 @@ <string name="tts_stop">Páre de falar</string> <string name="err_tts_lang_not_supported">A linguagem corrente não é suportada pelo texto em fala.</string> <string name="tts_one_kilometer">um quilômetro</string> - <string name="tts_one_meter">um metro</string> - <string name="tts_one_mile">uma milha</string> - <string name="tts_one_foot">um pé</string> - <string name="tts_one_oclock">uma hora</string> - <string name="tts_oclock">%s horas</string> - <string name="clipboard_copy_ok">Copiado para a área de transferência</string> - <string name="percent_favorite_points">%\ favoritos</string> - <string name="cgeo_shortcut">Atalho c:geo</string> - <string name="create_shortcut">Criar atalho</string> - <string-array name="log_image_scales"> - <item>Não dimensionar</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuto</item> - <item quantity="other">minutos</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">Uma cache</item> - <item quantity="other">%1$d Caches</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 Waypoint</item> - <item quantity="other">%d Waypoints</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s quilômetros</item> <item quantity="other">%s quilômetros</item> </plurals> + <string name="tts_one_meter">um metro</string> <plurals name="tts_meters"> <item quantity="one">%s metro</item> <item quantity="other">%s metros</item> </plurals> + <string name="tts_one_mile">uma milha</string> <plurals name="tts_miles"> <item quantity="one">%s milha</item> <item quantity="other">%s milhas</item> </plurals> + <string name="tts_one_foot">um pé</string> <plurals name="tts_feet"> <item quantity="one">%s pé</item> <item quantity="other">%s pés</item> </plurals> + <string name="tts_one_oclock">uma hora</string> + <string name="tts_oclock">%s horas</string> + <string name="clipboard_copy_ok">Copiado para a área de transferência</string> <plurals name="days_ago"> <item quantity="one">ontem</item> <item quantity="other">%d dias atrás</item> </plurals> + <string name="percent_favorite_points">%\ favoritos</string> + <string name="cgeo_shortcut">Atalho c:geo</string> + <string name="create_shortcut">Criar atalho</string> </resources> diff --git a/main/res/values-ro/strings.xml b/main/res/values-ro/strings.xml index ecb96ec..5580b63 100644 --- a/main/res/values-ro/strings.xml +++ b/main/res/values-ro/strings.xml @@ -80,21 +80,9 @@ <string name="log_saving_and_uploading">Trimitre jurnal şi încarcare poze…</string> <string name="log_clear">Şterge</string> <string name="log_post">Trimite Însemnare</string> - <string name="log_post_rate">Trimite Însemnare & Votează</string> - <string name="log_post_no_rate">Trimite Însemnare & Fără Vot</string> <string name="log_post_not_possible">Încărcare pagină însemnări…</string> <string name="log_add">Adaugă</string> - <string name="log_rating">Vot</string> <string name="log_no_rating">Fără voturi</string> - <string name="log_stars_1">1 stea</string> - <string name="log_stars_15">1,5 stele</string> - <string name="log_stars_2">2 stele</string> - <string name="log_stars_25">2,5 stele</string> - <string name="log_stars_3">3 stele</string> - <string name="log_stars_35">3,5 stele</string> - <string name="log_stars_4">4 stele</string> - <string name="log_stars_45">4,5 stele</string> - <string name="log_stars_5">5 stele</string> <string name="log_stars_1_description">Foarte slabă</string> <string name="log_stars_15_description">Slabă</string> <string name="log_stars_2_description">Slăbuţă</string> @@ -113,7 +101,6 @@ <string name="log_smilies">Smilies</string> <string name="log_image">Imagine</string> <string name="log_image_attach">Ataşează imagine</string> - <string name="log_image_edit">Modifică imagine</string> <string name="log_image_stored">Existentă</string> <string name="log_image_camera">Nouă</string> <string name="log_image_caption">Titlu</string> @@ -122,6 +109,13 @@ <string name="log_password_title">Parolă:</string> <string name="log_hint_log_password">Introdu parola pentru jurnal</string> <string name="log_oc_team_comment">Comentariu din partea echipei OC</string> + <string-array name="log_image_scales"> + <item>Fără redimensionare</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Tradu în limba %s</string> <string name="translate_to_english">Tradu în limba engleză</string> <string name="translate_length_warning">Traducerea poate fi incompletă în cazul unui text mare.</string> @@ -221,6 +215,7 @@ <string name="loc_trying">Încerc să determin poziţia</string> <string name="loc_no_addr">Adresă necunoscută</string> <string name="loc_gps_disabled">GPS inactiv</string> + <string name="menu_centerposition">Centrează pe poziţia mea</string> <string name="menu_about">Despre c:geo</string> <string name="menu_helpers">Programe utilitare</string> <string name="menu_settings">Setări</string> @@ -303,10 +298,8 @@ <string name="caches_removing_from_history">Şterge din istoric…</string> <string name="caches_clear_offlinelogs">Şterge însemnări stocate local</string> <string name="caches_clear_offlinelogs_progress">Ştergere însemnări stocate local</string> - <string name="list_menu">Liste</string> <string name="list_menu_create">Crează listă nouă</string> <string name="list_menu_drop">Şterge lista curentă</string> - <string name="list_menu_change">Schimbă lista</string> <string name="list_menu_rename">Redenumeşte lista curentă</string> <string name="list_title">Alege o listă</string> <string name="list_inbox">Salvate</string> @@ -404,8 +397,8 @@ <string name="init_signature_template_log">Text însemnare</string> <string name="init_ratingwanted">Voturi GCvote</string> <string name="init_summary_ratingwanted">Încarcă voturi de la GCvote.com</string> - <string name="init_friendlogswanted">Arată însemnările prietenilor</string> - <string name="init_summary_friendlogswanted">Afişează o pagină suplimentară cu însemnări de la prieteni</string> + <string name="init_friends_and_own_logs_wanted">Arată ale mele/ale prietenilor</string> + <string name="init_summary_friends_and_own_logs_wanted">Afişează pagină de jurnal separată pentru însemnările proprii şi ale prietenilor</string> <string name="init_openlastdetailspage">Ultima pagină cu detalii</string> <string name="init_summary_openlastdetailspage">Arată detaliile de pe ultima pagină afişată</string> <string name="init_autoload">Descriere completă</string> @@ -417,6 +410,8 @@ <string name="init_captcha">Arată CAPTCHA</string> <string name="init_summary_captcha">Arată CAPTCHA dacă este necesar (doar Basic Member)</string> <string name="init_useenglish">Foloseşte limba engleză</string> + <string name="init_showoverflowmenu">Afişează întotdeauna meniul suprapus</string> + <string name="init_showoverflow_summary">Afişează întotdeauna meniul suprapus (trei puncte ⋮) chiar dacă dispozitivul are buton pentru meniu (necesită repornirea aplicaţiei)</string> <string name="init_summary_useenglish">Foloseşte limba engleză în c:geo (Aplicaţia trebuie repornită)</string> <string name="init_exclude">Exclude Găsite şi Ale mele</string> <string name="init_summary_exclude">Exclude cutiile găsite şi cele proprii</string> @@ -494,6 +489,9 @@ <string name="init_maintenance">Întreţinere</string> <string name="init_maintenance_directories_note">c:geo salvează imagini, imagini din însemnări şi alte fişiere legate de o geocutie într-un dosar separat. Este posibil ca în unele cazuri (precum import/export al bazei de date) acest dosar să conţină fişiere vechi ce pot fi şterse aici.</string> <string name="init_maintenance_directories">Şterge fişierele devenite inutile</string> + <string name="init_create_memory_dump">Creează un extras de memorie copie după memoria folosită de aplicaţie</string> + <string name="init_memory_dump">Extras de memorie</string> + <string name="init_memory_dumped">Extras de memorie salvat în %s</string> <string name="settings_open_website">Intră pe site</string> <string name="settings_settings">Opţiuni</string> <string name="settings_information">Informaţii</string> @@ -569,8 +567,6 @@ <string name="cache_personal_note_uploading">Încărcare notă personală</string> <string name="cache_personal_note_upload_done">Nota personală a fost încărcată</string> <string name="cache_personal_note_upload_cancelled">Încărcarea notei personale a fost anulată</string> - <string name="cache_personal_note_unstored">Cutia nu este salvată</string> - <string name="cache_personal_note_store">Cutia va fi mai întâi salvată pentru a permite adăugarea de note personale.</string> <string name="cache_description">Descriere</string> <string name="cache_description_long">Descriere completă</string> <string name="cache_description_table_note">Descrierea conţine tabele sau formatări care ar trebui vizualizate aici %s pentru a fi afişate corect.</string> @@ -590,7 +586,7 @@ <string name="cache_waypoints_add">Adaugă punct</string> <string name="cache_hint">Indiciu</string> <string name="cache_logs">Jurnal</string> - <string name="cache_logsfriends">Jurnal (Prieteni)</string> + <string name="cache_logs_friends_and_own">Însemnări proprii/de la prieteni</string> <string name="cache_dialog_loading_details">Încărcare detaliile cutiei…</string> <string name="cache_dialog_loading_details_status_loadpage">Încărcare pagină</string> <string name="cache_dialog_loading_details_status_details">Prelucrare detalii</string> @@ -636,16 +632,15 @@ <string name="cache_menu_refresh">Împrospătează</string> <string name="cache_menu_share">Distribuie geocutie</string> <string name="cache_menu_move_list">Mută în altă listă</string> - <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">Cutie Baliză</string> <string name="cache_menu_navigon">Navigon</string> <string name="cache_menu_pebble">Ceas \"Pebble\"</string> <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Stare</string> <string name="cache_status_offline_log">Jurnal salvat</string> <string name="cache_status_found">Găsit</string> + <string name="cache_not_status_found">Nu a fost găsită</string> <string name="cache_status_archived">Arhivată</string> <string name="cache_status_disabled">Inactivă</string> <string name="cache_status_premium">Doar membrii Premium</string> @@ -757,10 +752,7 @@ <string name="map_view_map">Hărţi</string> <string name="map_modes">Opţiuni hărţi</string> <string name="map_trail_show">Arată traseu</string> - <string name="map_trail_hide">Ascunde traseu</string> <string name="map_circles_show">Arată cercurile</string> - <string name="map_circles_hide">Ascunde cercurile</string> - <string name="map_mycaches_show">Arată geocutiile mele/găsite</string> <string name="map_mycaches_hide">Ascunde geocutiile mele/găsite</string> <string name="map_theme_builtin">Implicit</string> <string name="map_theme_select">Alege un stil pentru hartă</string> @@ -1114,7 +1106,6 @@ <string name="website">Site: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">pagina c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">c:geo într-o coajă de nucă</a></string> <string name="market">Android: <a href="">c:geo pe Google Play</a></string> <string name="about_twitter">Ar trebui ca <b>c:geo</b> să publice un statut nou pe Twitter de fiecare dată când scrii o însemnare pentru o geocutie?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1139,11 +1130,5 @@ <string name="percent_favorite_points">%\ favorite</string> <string name="cgeo_shortcut">legătură la c:geo</string> <string name="create_shortcut">Crează scurtătură</string> - <string-array name="log_image_scales"> - <item>Fără redimensionare</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> + <string name="send">Trimite</string> </resources> diff --git a/main/res/values-sk/strings.xml b/main/res/values-sk/strings.xml index b321f83..612ef76 100644 --- a/main/res/values-sk/strings.xml +++ b/main/res/values-sk/strings.xml @@ -79,21 +79,9 @@ <string name="log_saving_and_uploading">Odosielanie logu a nahrávanie obrázku…</string> <string name="log_clear">Vyčistiť</string> <string name="log_post">Odoslať log</string> - <string name="log_post_rate">Odoslať log a hlasovať</string> - <string name="log_post_no_rate">Odoslať log a nehlasovať</string> <string name="log_post_not_possible">Načítanie stránky s logmi…</string> <string name="log_add">Pridať</string> - <string name="log_rating">Hlasovať</string> <string name="log_no_rating">Nehlasovať</string> - <string name="log_stars_1">1 hviezdička</string> - <string name="log_stars_15">1,5 hviezdičky</string> - <string name="log_stars_2">2 hviezdičky</string> - <string name="log_stars_25">2,5 hviezdičky</string> - <string name="log_stars_3">3 hviezdičky</string> - <string name="log_stars_35">3,5 hviezdičky</string> - <string name="log_stars_4">4 hviezdičky</string> - <string name="log_stars_45">4,5 hviezdičky</string> - <string name="log_stars_5">5 hviezdičiek</string> <string name="log_stars_1_description">slabé</string> <string name="log_stars_15_description">dosť slabé</string> <string name="log_stars_2_description">podpriemerné</string> @@ -112,7 +100,6 @@ <string name="log_smilies">Smajlíci</string> <string name="log_image">Obrázok</string> <string name="log_image_attach">Pripojiť obrázok</string> - <string name="log_image_edit">Upraviť obrázok</string> <string name="log_image_stored">Existujúci</string> <string name="log_image_camera">Nový</string> <string name="log_image_caption">Titulok</string> @@ -121,6 +108,13 @@ <string name="log_password_title">Prihlásiť heslo:</string> <string name="log_hint_log_password">Zadajte svoje logovacie heslo</string> <string name="log_oc_team_comment">Komentár tímu OC</string> + <string-array name="log_image_scales"> + <item>Bez zmeny mierky</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Preložiť do jazyka %s</string> <string name="translate_to_english">Preložiť do angličtiny</string> <string name="translate_length_warning">Pre veľké texty môže preklad zlyhať.</string> @@ -301,10 +295,8 @@ <string name="caches_removing_from_history">Odstraňovanie z histórie…</string> <string name="caches_clear_offlinelogs">Vymazať offline záznamy</string> <string name="caches_clear_offlinelogs_progress">Vymazanie logov v režime offline</string> - <string name="list_menu">Zoznam</string> <string name="list_menu_create">Vytvoriť nový zoznam</string> <string name="list_menu_drop">Zahodiť aktuálny zoznam</string> - <string name="list_menu_change">Zmeniť zoznam</string> <string name="list_menu_rename">Premenovať tento zoznam</string> <string name="list_title">Výber zoznamu</string> <string name="list_inbox">Uložené</string> @@ -402,8 +394,6 @@ <string name="init_signature_template_log">Zápis do logu</string> <string name="init_ratingwanted">Načítať hodnotenie skrýše z GCvote.com</string> <string name="init_summary_ratingwanted">Načítať hodnotenie skrýše z GCvote.com</string> - <string name="init_friendlogswanted">Načítať dodatočnú stránku s logmi od priateľov</string> - <string name="init_summary_friendlogswanted">Načítať dodatočnú stránku s logmi od priateľov</string> <string name="init_openlastdetailspage">Otvoriť detaily na naposledy použitej stránke</string> <string name="init_summary_openlastdetailspage">Otvoriť detaily na naposledy použitej stránke</string> <string name="init_autoload">Automatické načítanie dlhého popisu</string> @@ -565,8 +555,6 @@ <string name="cache_personal_note_uploading">Nahrať osobnú poznámku</string> <string name="cache_personal_note_upload_done">Osobná poznámka nahraná</string> <string name="cache_personal_note_upload_cancelled">Nahrávanie osobnej poznámky zrušené</string> - <string name="cache_personal_note_unstored">Cache nie je uložená</string> - <string name="cache_personal_note_store">Cache sa najskôr uložia aby sa povolila osobná poznámka.</string> <string name="cache_description">Popis</string> <string name="cache_description_long">Dlhý popis</string> <string name="cache_description_table_note">Popis obsahuje formátovanie tabuľky, ktorý môže byť pre správne zobrazenie potrebné otvoriť v %s.</string> @@ -583,10 +571,14 @@ <string name="cache_list_unknown">Nie je v zozname</string> <string name="cache_images">Obrázky</string> <string name="cache_waypoints">Body trasy</string> + <plurals name="waypoints"> + <item quantity="one">1 bod trasy</item> + <item quantity="few">%d body trasy</item> + <item quantity="other">%d bodov trasy</item> + </plurals> <string name="cache_waypoints_add">Pridať bod</string> <string name="cache_hint">Nápoveda</string> <string name="cache_logs">Logbook</string> - <string name="cache_logsfriends">Logbook (priatelia)</string> <string name="cache_dialog_loading_details">Načítanie detailov skrýše…</string> <string name="cache_dialog_loading_details_status_loadpage">Načítanie stránky</string> <string name="cache_dialog_loading_details_status_details">Spracovanie detailov</string> @@ -632,10 +624,8 @@ <string name="cache_menu_refresh">Obnoviť</string> <string name="cache_menu_share">Zdielať skrýšu</string> <string name="cache_menu_move_list">Presunúť do iného zoznamu</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_status">Stav</string> @@ -752,10 +742,7 @@ <string name="map_view_map">Zobrazenie mapy</string> <string name="map_modes">Režimy mapy</string> <string name="map_trail_show">Zobraziť záznam trasy</string> - <string name="map_trail_hide">Skryť záznam trasy</string> <string name="map_circles_show">Zobraziť kruhy</string> - <string name="map_circles_hide">Skryť kruhy</string> - <string name="map_mycaches_show">Zobraziť vlastné/nájdené cache</string> <string name="map_mycaches_hide">Skryť vlastné/nájdené cache</string> <string name="map_theme_builtin">Predvolené</string> <string name="map_theme_select">Vybrať tému mapy</string> @@ -1109,7 +1096,6 @@ <string name="website">Web: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manuál: <a href="">c:geo v kocke</a></string> <string name="market">Android: <a href=""> c:geo na Google Play</a></string> <string name="about_twitter">Chcete, aby <b>c:geo</b> napísalo na váš Twitter vždy keď zapíšete nájdenie skrýše?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1125,47 +1111,32 @@ <string name="tts_stop">Prestať hovoriť</string> <string name="err_tts_lang_not_supported">Aktuálny jazyk nepodporuje prevod textu na reč.</string> <string name="tts_one_kilometer">jeden kilometer</string> - <string name="tts_one_meter">jeden meter</string> - <string name="tts_one_mile">jedna míľa</string> - <string name="tts_one_foot">jedna stopa</string> - <string name="tts_one_oclock">jedna hodina</string> - <string name="tts_oclock">%s hodín</string> - <string name="clipboard_copy_ok">Skopírované do schránky</string> - <string name="percent_favorite_points">% \ obľúbených</string> - <string name="cgeo_shortcut">c:Geo odkaz</string> - <string name="create_shortcut">Vytvoriť odkaz</string> - <string-array name="log_image_scales"> - <item>Bez zmeny mierky</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="waypoints"> - <item quantity="one">1 bod trasy</item> - <item quantity="few">%d body trasy</item> - <item quantity="other">%d bodov trasy</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometer</item> <item quantity="few">%s kilometre</item> <item quantity="other">%s kilometrov</item> </plurals> + <string name="tts_one_meter">jeden meter</string> <plurals name="tts_meters"> <item quantity="one">%s meter</item> <item quantity="few">%s metre</item> <item quantity="other">%s metrov</item> </plurals> + <string name="tts_one_mile">jedna míľa</string> <plurals name="tts_miles"> <item quantity="one">%s míľa</item> <item quantity="few">%s míľ</item> <item quantity="other">%s míľ</item> </plurals> + <string name="tts_one_foot">jedna stopa</string> <plurals name="tts_feet"> <item quantity="one">%s stopa</item> <item quantity="few">%s stopy</item> <item quantity="other">%s stôp</item> </plurals> + <string name="tts_one_oclock">jedna hodina</string> + <string name="tts_oclock">%s hodín</string> + <string name="clipboard_copy_ok">Skopírované do schránky</string> <plurals name="days_ago"> <item quantity="one">včera</item> <item quantity="few">pred %d dňami</item> @@ -1176,4 +1147,7 @@ <item quantity="few">%s obľúbené</item> <item quantity="other">%s obľúbených</item> </plurals> + <string name="percent_favorite_points">% \ obľúbených</string> + <string name="cgeo_shortcut">c:Geo odkaz</string> + <string name="create_shortcut">Vytvoriť odkaz</string> </resources> diff --git a/main/res/values-sl/strings.xml b/main/res/values-sl/strings.xml index 1237699..381cb32 100644 --- a/main/res/values-sl/strings.xml +++ b/main/res/values-sl/strings.xml @@ -79,21 +79,9 @@ <string name="log_saving_and_uploading">Pošiljam zapis in nalagam sliko…</string> <string name="log_clear">Počisti</string> <string name="log_post">Pošlji</string> - <string name="log_post_rate">Pošlji in oceni</string> - <string name="log_post_no_rate">Pošlji in ne oceni</string> <string name="log_post_not_possible">Nalagam stran…</string> <string name="log_add">Dodaj</string> - <string name="log_rating">Ocena</string> <string name="log_no_rating">Brez ocene</string> - <string name="log_stars_1">1 zvezdica</string> - <string name="log_stars_15">1.5 zvezdice</string> - <string name="log_stars_2">2 zvezdici</string> - <string name="log_stars_25">2.5 zvezdici</string> - <string name="log_stars_3">3 zvezdice</string> - <string name="log_stars_35">3.5 zvezdice</string> - <string name="log_stars_4">4 zvezdice</string> - <string name="log_stars_45">4.5 zvezdice</string> - <string name="log_stars_5">5 zvezdic</string> <string name="log_stars_1_description">Zelo slabo</string> <string name="log_stars_15_description">Slabo</string> <string name="log_stars_2_description">Pod povprečjem</string> @@ -112,7 +100,6 @@ <string name="log_smilies">Smeškoti</string> <string name="log_image">Slika</string> <string name="log_image_attach">Dodaj sliko</string> - <string name="log_image_edit">Uredi sliko</string> <string name="log_image_stored">Obstoječa</string> <string name="log_image_camera">Nova</string> <string name="log_image_caption">Naslov</string> @@ -121,6 +108,13 @@ <string name="log_password_title">Geslo zapisa:</string> <string name="log_hint_log_password">Vnesite geslo zapisa</string> <string name="log_oc_team_comment">Komentar ekipe OC</string> + <string-array name="log_image_scales"> + <item>Brez skaliranja</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Prevedi v: %s</string> <string name="translate_to_english">Prevedi v: angleščino</string> <string name="translate_length_warning">Prevod lahko spodleti zaradi velike količine besedila.</string> @@ -241,6 +235,12 @@ <string name="caches_more_caches_currently">trenutno</string> <string name="caches_downloading">Nalagam zaklade…\nČas do konca: </string> <string name="caches_eta_ltm">manj kot minuta</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minuta</item> + <item quantity="two">minuti</item> + <item quantity="few">minute</item> + <item quantity="other">minut</item> + </plurals> <string name="caches_store_offline">Shrani</string> <string name="caches_store_selected">Shrani izbrane</string> <string name="caches_history">Zgodovina</string> @@ -301,10 +301,8 @@ <string name="caches_removing_from_history">Brišem iz zgodovine…</string> <string name="caches_clear_offlinelogs">Izbriši shranjene zapise</string> <string name="caches_clear_offlinelogs_progress">Izbris shranjenih zapisov</string> - <string name="list_menu">Seznam</string> <string name="list_menu_create">Ustvari nov seznam</string> <string name="list_menu_drop">Izbriši trenutni seznam</string> - <string name="list_menu_change">Spremeni seznam</string> <string name="list_menu_rename">Preimenuj trenutni seznam</string> <string name="list_title">Izberi seznam</string> <string name="list_inbox">Shranjeni</string> @@ -399,8 +397,6 @@ <string name="init_signature_template_log">Vsebina zapisa</string> <string name="init_ratingwanted">GCvote ocene</string> <string name="init_summary_ratingwanted">Naloži ocene iz GCvote.com</string> - <string name="init_friendlogswanted">Naloži zapise prijateljev</string> - <string name="init_summary_friendlogswanted">Naloži tudi posebno stran zapisov mojih prijateljev</string> <string name="init_openlastdetailspage">Odpri nazadnje odprto stran</string> <string name="init_summary_openlastdetailspage">Pri podrobnostih zaklada vedno odpri zadnjo uporabljeno stran</string> <string name="init_autoload">Prikaži celoten opis</string> @@ -536,6 +532,12 @@ <string name="auth_ocde">opencaching.de</string> <string name="auth_ocpl">opencaching.pl</string> <string name="auth_dialog_completed_oc">c:geo je sedaj povezan z %s.</string> + <plurals name="cache_counts"> + <item quantity="one">%1$d zaklad</item> + <item quantity="two">%1$d zaklada</item> + <item quantity="few">%1$d zakladi</item> + <item quantity="other">%1$d zakladov</item> + </plurals> <string name="cache_offline">Brez povezave</string> <string name="cache_offline_refresh">Osveži</string> <string name="cache_offline_drop">Izbriši</string> @@ -562,8 +564,6 @@ <string name="cache_personal_note_uploading">Nalagam lastno opombo na spletno stran</string> <string name="cache_personal_note_upload_done">Lastna opomba je bila uspešno naložena na spletno stran</string> <string name="cache_personal_note_upload_cancelled">Nalaganje lastne opombe je bilo preklicano</string> - <string name="cache_personal_note_unstored">Zaklad ni shranjen</string> - <string name="cache_personal_note_store">Za vklop opomb bo zaklad najprej shranjen na napravo.</string> <string name="cache_description">Opis</string> <string name="cache_description_long">Daljši opis</string> <string name="cache_description_table_note">Opis vsebuje oblikovanje s tabelami. Za pravilen prikaz opisa bo mogoče potrebno obiskati %s.</string> @@ -580,10 +580,15 @@ <string name="cache_list_unknown">Ni v seznamu</string> <string name="cache_images">Slike</string> <string name="cache_waypoints">Dodatne točke</string> + <plurals name="waypoints"> + <item quantity="one">%d dodatna točka</item> + <item quantity="two">%d dodatni točki</item> + <item quantity="few">%d dodatne točke</item> + <item quantity="other">%d dodatnih točk</item> + </plurals> <string name="cache_waypoints_add">Dodaj točko</string> <string name="cache_hint">Namig</string> <string name="cache_logs">Dnevnik zapisov</string> - <string name="cache_logsfriends">Zapisi prijateljev</string> <string name="cache_dialog_loading_details">Nalaganje podatkov zaklada…</string> <string name="cache_dialog_loading_details_status_loadpage">Nalaganje strani</string> <string name="cache_dialog_loading_details_status_details">Obdelujem podatke</string> @@ -629,10 +634,8 @@ <string name="cache_menu_refresh">Osveži</string> <string name="cache_menu_share">Deli povezavo</string> <string name="cache_menu_move_list">Premakni v drug seznam</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_status">Status</string> @@ -749,10 +752,7 @@ <string name="map_view_map">Pogled zemljevida</string> <string name="map_modes">Možnosti</string> <string name="map_trail_show">Pokaži sled</string> - <string name="map_trail_hide">Skrij sled</string> <string name="map_circles_show">Pokaži kroge</string> - <string name="map_circles_hide">Skrij kroge</string> - <string name="map_mycaches_show">Pokaži lastne ali najdene zaklade</string> <string name="map_mycaches_hide">Skrij lastne ali najdene zaklade</string> <string name="map_theme_builtin">Privzeto</string> <string name="map_theme_select">Izberi temo zemljevida</string> @@ -1106,7 +1106,6 @@ <string name="website">Spletna stran: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo stran</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Priročnik: <a href="">c:geo na kratko</a></string> <string name="market">Android: <a href="">c:geo na Google Play</a></string> <string name="about_twitter">Naj <b>c:geo</b> objavi nov status na Twitter, ko objavite nov zapis pri zakladu?</string> <string name="faq">Pogosto zastavljena vprašanja: <a href="">faq.cgeo.org</a></string> @@ -1122,64 +1121,36 @@ <string name="tts_stop">Ustavi glasovno navigacijo</string> <string name="err_tts_lang_not_supported">Trenutno izbrani jezik ni podprt s storitvijo pretvorbe besedila v govor.</string> <string name="tts_one_kilometer">en kilometer</string> - <string name="tts_one_meter">en meter</string> - <string name="tts_one_mile">ena milja</string> - <string name="tts_one_foot">en čevelj</string> - <string name="tts_one_oclock">one o\'clock</string> - <string name="tts_oclock">%s o\'clock</string> - <string name="clipboard_copy_ok">Skopirano v odložišče</string> - <string name="percent_favorite_points">%\ favoritov</string> - <string name="cgeo_shortcut">Bližnjica c:geo</string> - <string name="create_shortcut">Ustvari bližnjico</string> - <string-array name="log_image_scales"> - <item>Brez skaliranja</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minuta</item> - <item quantity="two">minuti</item> - <item quantity="few">minute</item> - <item quantity="other">minut</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">%1$d zaklad</item> - <item quantity="two">%1$d zaklada</item> - <item quantity="few">%1$d zakladi</item> - <item quantity="other">%1$d zakladov</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">%d dodatna točka</item> - <item quantity="two">%d dodatni točki</item> - <item quantity="few">%d dodatne točke</item> - <item quantity="other">%d dodatnih točk</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometer</item> <item quantity="two">%s kilometra</item> <item quantity="few">%s kilometrov</item> <item quantity="other">%s kilometrov</item> </plurals> + <string name="tts_one_meter">en meter</string> <plurals name="tts_meters"> <item quantity="one">%s meter</item> <item quantity="two">%s metra</item> <item quantity="few">%s metri</item> <item quantity="other">%s metrov</item> </plurals> + <string name="tts_one_mile">ena milja</string> <plurals name="tts_miles"> <item quantity="one">%s milja</item> <item quantity="two">%s milji</item> <item quantity="few">%s milj</item> <item quantity="other">%s milj</item> </plurals> + <string name="tts_one_foot">en čevelj</string> <plurals name="tts_feet"> <item quantity="one">%s čevelj</item> <item quantity="two">%s čevlja</item> <item quantity="few">%s čevljev</item> <item quantity="other">%s čevljev</item> </plurals> + <string name="tts_one_oclock">one o\'clock</string> + <string name="tts_oclock">%s o\'clock</string> + <string name="clipboard_copy_ok">Skopirano v odložišče</string> <plurals name="days_ago"> <item quantity="one">Pred %d dnevom</item> <item quantity="two">Pred %d dnevoma</item> @@ -1192,4 +1163,7 @@ <item quantity="few">%s favoritov</item> <item quantity="other">%s favoritov</item> </plurals> + <string name="percent_favorite_points">%\ favoritov</string> + <string name="cgeo_shortcut">Bližnjica c:geo</string> + <string name="create_shortcut">Ustvari bližnjico</string> </resources> diff --git a/main/res/values-sv/strings.xml b/main/res/values-sv/strings.xml index 3c94ee2..d308966 100644 --- a/main/res/values-sv/strings.xml +++ b/main/res/values-sv/strings.xml @@ -18,6 +18,7 @@ <string name="letterbox">Letterbox hybrid</string> <string name="event">Event cache</string> <string name="mega">Mega-event cache</string> + <string name="giga">Giga-Event Cache</string> <string name="earth">Earthcache</string> <string name="cito">Cache in trash out event</string> <string name="webcam">Webcam cache</string> @@ -79,21 +80,9 @@ <string name="log_saving_and_uploading">Sparar logg och laddar upp bild…</string> <string name="log_clear">Rensa</string> <string name="log_post">Posta logg</string> - <string name="log_post_rate">Posta logg & ge betyget</string> - <string name="log_post_no_rate">Posta logg utan betyg</string> <string name="log_post_not_possible">Laddar loggningssida…</string> <string name="log_add">Lägg till</string> - <string name="log_rating">Betyg</string> <string name="log_no_rating">Inget betyg</string> - <string name="log_stars_1">1 stjärna</string> - <string name="log_stars_15">1.5 stjärnor</string> - <string name="log_stars_2">2 stjärnor</string> - <string name="log_stars_25">2.5 stjärnor</string> - <string name="log_stars_3">3 stjärnor</string> - <string name="log_stars_35">3.5 stjärnor</string> - <string name="log_stars_4">4 stjärnor</string> - <string name="log_stars_45">4.5 stjärnor</string> - <string name="log_stars_5">5 stjärnor</string> <string name="log_stars_1_description">Dålig</string> <string name="log_stars_15_description">Halvdålig</string> <string name="log_stars_2_description">Under medel</string> @@ -112,7 +101,6 @@ <string name="log_smilies">Smileys</string> <string name="log_image">Bild</string> <string name="log_image_attach">Lägg till bild</string> - <string name="log_image_edit">Redigera bild</string> <string name="log_image_stored">Från fil</string> <string name="log_image_camera">Ny</string> <string name="log_image_caption">Bildtext</string> @@ -121,6 +109,13 @@ <string name="log_password_title">Logglösenord:</string> <string name="log_hint_log_password">Ange ditt lösenord för loggning</string> <string name="log_oc_team_comment">Meddelande från OC Team</string> + <string-array name="log_image_scales"> + <item>Ingen skalning</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <string name="translate_to_sys_lang">Översätt till %s</string> <string name="translate_to_english">Översätt till engelska</string> <string name="translate_length_warning">Översättningen kan misslyckas med långa texter.</string> @@ -241,6 +236,10 @@ <string name="caches_more_caches_currently">nu</string> <string name="caches_downloading">Laddar ner cacher…\nTid kvar: </string> <string name="caches_eta_ltm">mindre än en minut</string> + <plurals name="caches_eta_mins"> + <item quantity="one">minut</item> + <item quantity="other">minuter</item> + </plurals> <string name="caches_store_offline">Spara för Offline</string> <string name="caches_store_selected">Spara valda</string> <string name="caches_history">Senast hittade cacher</string> @@ -282,6 +281,7 @@ <string name="caches_move_all">Flytta alla</string> <string name="caches_map_locus">Locus</string> <string name="caches_map_locus_export">Exportera till Locus</string> + <string name="caches_map_mapswithme">MapsWithMe</string> <string name="caches_recaptcha_title">reCAPTCHA</string> <string name="caches_recaptcha_explanation">Skriv texten som syns i bilden. Det krävs för att hämta koordinaterna för cacherna i listan. Det går att fortsätta ändå (men med sämre funktionalitet).</string> <string name="caches_recaptcha_hint">Text från bilden</string> @@ -301,10 +301,8 @@ <string name="caches_removing_from_history">Tar bort från historik…</string> <string name="caches_clear_offlinelogs">Rensa offline loggar</string> <string name="caches_clear_offlinelogs_progress">Rensar offline loggar</string> - <string name="list_menu">Listor</string> <string name="list_menu_create">Skapa en ny lista</string> <string name="list_menu_drop">Ta bort den här listan</string> - <string name="list_menu_change">Byt lista</string> <string name="list_menu_rename">Byt namn på den här listan</string> <string name="list_title">Välj en lista</string> <string name="list_inbox">Sparade</string> @@ -402,8 +400,8 @@ <string name="init_signature_template_log">Loggtext</string> <string name="init_ratingwanted">GCvote.com</string> <string name="init_summary_ratingwanted">Ladda cache betyg från GCvote.com</string> - <string name="init_friendlogswanted">Vänners loggar</string> - <string name="init_summary_friendlogswanted">Ladda extra sida med loggbok för dina vänner</string> + <string name="init_friends_and_own_logs_wanted">Visa vänners/egna</string> + <string name="init_summary_friends_and_own_logs_wanted">Visa en extra loggbok med dina vänners och egna loggar</string> <string name="init_openlastdetailspage">Visning av cachedetaljer</string> <string name="init_summary_openlastdetailspage">Visa senaste använda delsidan när detaljer öppnas</string> <string name="init_autoload">Cachebeskrivning</string> @@ -542,6 +540,10 @@ <string name="auth_ocus">opencaching.us</string> <string name="auth_ocro">opencaching.ro</string> <string name="auth_dialog_completed_oc">c:geo är nu godkänd för att kommunicera med %s.</string> + <plurals name="cache_counts"> + <item quantity="one">En cache</item> + <item quantity="other">%1$d cacher</item> + </plurals> <string name="cache_offline">Offline</string> <string name="cache_offline_refresh">Uppdatera</string> <string name="cache_offline_drop">Radera</string> @@ -568,8 +570,6 @@ <string name="cache_personal_note_uploading">Laddar upp personlig anteckning</string> <string name="cache_personal_note_upload_done">Den personliga anteckning har laddats upp</string> <string name="cache_personal_note_upload_cancelled">Uppladdningen av personliga anteckning avbruten</string> - <string name="cache_personal_note_unstored">Cachen ej sparad</string> - <string name="cache_personal_note_store">Cachen kommer att sparas först för att kunna hantera personlig anteckning.</string> <string name="cache_description">Beskrivning</string> <string name="cache_description_long">Lång beskrivning</string> <string name="cache_description_table_note">Beskrivningen innehåller tabellformatering som eventuellt behöver läsas på %s för att se korrekt ut.</string> @@ -586,10 +586,14 @@ <string name="cache_list_unknown">Ej i någon lista</string> <string name="cache_images">Bilder</string> <string name="cache_waypoints">Punkter</string> + <plurals name="waypoints"> + <item quantity="one">1 Punkt</item> + <item quantity="other">%d Punkter</item> + </plurals> <string name="cache_waypoints_add">Lägg till punkt</string> <string name="cache_hint">Tips</string> <string name="cache_logs">Loggbok</string> - <string name="cache_logsfriends">Loggbok (Vänner)</string> + <string name="cache_logs_friends_and_own">Vänners/egna loggar</string> <string name="cache_dialog_loading_details">Laddar detaljer om cachen…</string> <string name="cache_dialog_loading_details_status_loadpage">Hämtar från gc.com</string> <string name="cache_dialog_loading_details_status_details">Analyserar cacheinformation</string> @@ -635,15 +639,15 @@ <string name="cache_menu_refresh">Uppdatera</string> <string name="cache_menu_share">Skicka länk</string> <string name="cache_menu_move_list">Flytta till annan lista</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> + <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Status</string> <string name="cache_status_offline_log">Sparad logg</string> <string name="cache_status_found">Hittad</string> + <string name="cache_not_status_found">Ej hittad</string> <string name="cache_status_archived">Arkiverad</string> <string name="cache_status_disabled">Inaktiverad</string> <string name="cache_status_premium">Enbart för Premium medlemmar</string> @@ -755,10 +759,7 @@ <string name="map_view_map">Karttyp</string> <string name="map_modes">Kartlägen</string> <string name="map_trail_show">Visa spår</string> - <string name="map_trail_hide">Dölj spår</string> <string name="map_circles_show">Visa cirklar</string> - <string name="map_circles_hide">Dölj cirklar</string> - <string name="map_mycaches_show">Visa egna/funna cacher</string> <string name="map_mycaches_hide">Dölj egna/funna cacher</string> <string name="map_theme_builtin">Standard</string> <string name="map_theme_select">Välj karttema</string> @@ -1112,7 +1113,6 @@ <string name="website">Hemsida: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">c:geo på Google Play</a></string> <string name="about_twitter">Ska <b>c:geo</b> publicera ny status på Twitter varje gång en cache loggas?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1128,52 +1128,33 @@ <string name="tts_stop">Stoppa tal</string> <string name="err_tts_lang_not_supported">Detta språk hanteras inte av text-to-speech.</string> <string name="tts_one_kilometer">en kilometer</string> - <string name="tts_one_meter">en meter</string> - <string name="tts_one_mile">en engelsk mil</string> - <string name="tts_one_foot">en fot</string> - <string name="tts_one_oclock">Klockan ett</string> - <string name="tts_oclock">Klockan %s</string> - <string name="clipboard_copy_ok">Kopierat till urklipp</string> - <string name="percent_favorite_points">%\ favoriter</string> - <string name="cgeo_shortcut">c:geo genväg</string> - <string name="create_shortcut">Skapa genväg</string> - <string-array name="log_image_scales"> - <item>Ingen skalning</item> - <item>512 px</item> - <item>640 px</item> - <item>800 px</item> - <item>1024 px</item> - </string-array> - <plurals name="caches_eta_mins"> - <item quantity="one">minut</item> - <item quantity="other">minuter</item> - </plurals> - <plurals name="cache_counts"> - <item quantity="one">En cache</item> - <item quantity="other">%1$d cacher</item> - </plurals> - <plurals name="waypoints"> - <item quantity="one">1 Punkt</item> - <item quantity="other">%d Punkter</item> - </plurals> <plurals name="tts_kilometers"> <item quantity="one">%s kilometer</item> <item quantity="other">%s kilometer</item> </plurals> + <string name="tts_one_meter">en meter</string> <plurals name="tts_meters"> <item quantity="one">%s meter</item> <item quantity="other">%s meter</item> </plurals> + <string name="tts_one_mile">en engelsk mil</string> <plurals name="tts_miles"> <item quantity="one">%s engelsk mil</item> <item quantity="other">%s engelsk mil</item> </plurals> + <string name="tts_one_foot">en fot</string> <plurals name="tts_feet"> <item quantity="one">%s fot</item> <item quantity="other">%s fot</item> </plurals> + <string name="tts_one_oclock">Klockan ett</string> + <string name="tts_oclock">Klockan %s</string> + <string name="clipboard_copy_ok">Kopierat till urklipp</string> <plurals name="days_ago"> <item quantity="one">igår</item> <item quantity="other">%d dagar sedan</item> </plurals> + <string name="percent_favorite_points">%\ favoriter</string> + <string name="cgeo_shortcut">c:geo genväg</string> + <string name="create_shortcut">Skapa genväg</string> </resources> diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml index ab1db9f..be33f09 100644 --- a/main/res/values/attrs.xml +++ b/main/res/values/attrs.xml @@ -42,7 +42,6 @@ <!-- attributes for custom made preferences --> - <attr name="title" format="string" /> <attr name="text" format="string" /> <attr name="url" format="string" /> <attr name="urlButton" format="string" /> diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml index 1e3c3d4..2e1e38a 100644 --- a/main/res/values/changelog_master.xml +++ b/main/res/values/changelog_master.xml @@ -2,5 +2,29 @@ <resources> <!-- changelog for the master branch --> <string name="changelog_master" translatable="false"> + <b>Next feature release:</b>\n + · New: Implemented actionbar menus\n + · New: Show also own logs on friend log page\n + · New: Navigate - WhereYouGo will invoke automatic cartridge download in WhereYouGo\n + · New: Filter for caches which are not found\n + · New: Show "Import from web" also if not yet registered\n + · New: Popup list of changes on first start after upgrade\n + · New: Android Beam (NFC Sharing)\n + · New: Debugging option to save memory dumps on user demand\n + · New: Load Greokrety inventory for OC caches\n + · New: Autosave caches if user modifies waypoints\n + · New: Show recently viewed caches when clicking search icon on main screen\n + · Fix: Hiding own caches on opencaching\n + · Fix: Webcam caches not marked as found after posting log\n + · Fix: Archived caches now also hidden if hiding disabled caches is active\n + · Fix: Filter invalid characters in GPX files\n + · Fix: All caches shown as owned if no username stored\n + · Fix: GPX import from mail failing on some devices\n + · Fix: Updating cache history should not ask for list to save caches\n + · Fix: Speed now always shown in km or miles per hour\n + · Fix: USER template now shows the correct username for the site where the cache is hosted\n + · Fix: Keep filter active if user switches the list\n + \n + \n </string> </resources> diff --git a/main/res/values/colors.xml b/main/res/values/colors.xml index 0e85c36..30d00df 100644 --- a/main/res/values/colors.xml +++ b/main/res/values/colors.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <resources> + <color name="background_main_transparent">#D0000000</color> <color name="just_white">#FFFFFFFF</color> <color name="just_black">#FF000000</color> <color name="background_dark">#FF000000</color> diff --git a/main/res/values/preference_keys.xml b/main/res/values/preference_keys.xml index 6036be3..797ff11 100644 --- a/main/res/values/preference_keys.xml +++ b/main/res/values/preference_keys.xml @@ -19,6 +19,7 @@ <string name="preference_screen_ox">preference_screen_ox</string> <string name="preference_screen_twitter">preference_screen_twitter</string> <string name="preference_screen_navigation_menu">fakekey_navigation_menu_screen</string> + <string name="preference_screen_sendtocgeo">preference_screen_sendtocgeo</string> <string name="pref_fakekey_ocde_authorization">fakekey_ocde_authorization</string> <string name="pref_fakekey_ocpl_authorization">fakekey_ocpl_authorization</string> <string name="pref_fakekey_ocnl_authorization">fakekey_ocnl_authorization</string> @@ -45,6 +46,7 @@ <string name="pref_showaddress">showaddress</string> <string name="pref_useenglish">useenglish</string> <string name="pref_units">units</string> + <string name="pref_alwaysshowoverflowmenu">alwaysshowoverflowmenu</string> <string name="pref_autoloaddesc">autoloaddesc</string> <string name="pref_ratingwanted">ratingwanted</string> <string name="pref_friendlogswanted">friendlogswanted</string> @@ -133,8 +135,6 @@ <string name="pref_navigation_menu_google_walk">navigationGoogleWalk</string> <string name="pref_navigation_menu_google_bike">navigationGoogleBike</string> <string name="pref_navigation_menu_google_maps_directions">navigationMapsDirections</string> - <string name="pref_navigation_menu_cache_beacon">navigationCacheBeacon</string> - <string name="pref_navigation_menu_gcc">navigationGcc</string> <string name="pref_navigation_menu_where_you_go">navigationWhereYouGo</string> <string name="pref_navigation_menu_pebble">navigationPebble</string> <string name="pref_navigation_menu_mapswithme">navigationMapsWithMe</string> @@ -167,5 +167,8 @@ <string name="pref_twitter_cache_message">twitter_cache_message</string> <string name="pref_twitter_trackable_message">twitter_trackable_message</string> <string name="pref_ec_icons">ec_icons</string> - -</resources>
\ No newline at end of file + <string name="pref_memory_dump">memory_dump</string> + <string name="pref_appearance">pref_appearance</string> + <string name="pref_changelog_last_version">changelog_last_version</string> + <string name="pref_caches_history">caches_history</string> +</resources> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index 2aa3d00..cd6dd3b 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -92,21 +92,9 @@ <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 & Rate</string> - <string name="log_post_no_rate">Submit Log & Do not Rate</string> <string name="log_post_not_possible">Loading Log Page…</string> <string name="log_add">Add</string> - <string name="log_rating">Rating</string> <string name="log_no_rating">No rating</string> - <string name="log_stars_1">1 Star</string> - <string name="log_stars_15">1.5 Stars</string> - <string name="log_stars_2">2 Stars</string> - <string name="log_stars_25">2.5 Stars</string> - <string name="log_stars_3">3 Stars</string> - <string name="log_stars_35">3.5 Stars</string> - <string name="log_stars_4">4 Stars</string> - <string name="log_stars_45">4.5 Stars</string> - <string name="log_stars_5">5 Stars</string> <string name="log_stars_1_description">Poor</string> <string name="log_stars_15_description">Fairly poor</string> <string name="log_stars_2_description">Below average</string> @@ -125,7 +113,6 @@ <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> @@ -238,6 +225,7 @@ <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> + <string name="info_cache_saved">The cache has been stored locally</string> <!-- location service --> <string name="loc_last">Last known</string> @@ -247,6 +235,8 @@ <string name="loc_trying">Trying to Locate</string> <string name="loc_no_addr">Unknown address</string> <string name="loc_gps_disabled">GPS disabled</string> + <string name="menu_centerposition">Center on my position</string> + <!-- standard menu --> <string name="menu_about">About c:geo</string> @@ -343,10 +333,8 @@ <string name="caches_clear_offlinelogs_progress">Clearing offline logs</string> <!-- caches lists --> - <string name="list_menu">List</string> <string name="list_menu_create">Create new list</string> <string name="list_menu_drop">Drop current list</string> - <string name="list_menu_change">Change list</string> <string name="list_menu_rename">Rename current list</string> <string name="list_title">Pick a list</string> <string name="list_inbox">Stored</string> @@ -451,8 +439,8 @@ <string name="init_signature_template_log">Log text</string> <string name="init_ratingwanted">GCvote Rating</string> <string name="init_summary_ratingwanted">Load cache rating from GCvote.com</string> - <string name="init_friendlogswanted">Show Friends\' Logs</string> - <string name="init_summary_friendlogswanted">Display additional logbook page for logs from friends</string> + <string name="init_friends_and_own_logs_wanted">Show Friends\'/Own</string> + <string name="init_summary_friends_and_own_logs_wanted">Display additional logbook page for friends\' and own logs</string> <string name="init_openlastdetailspage">Last Details Page</string> <string name="init_summary_openlastdetailspage">Open details with last used page</string> <string name="init_autoload">Long Description</string> @@ -464,6 +452,8 @@ <string name="init_captcha">Show CAPTCHA</string> <string name="init_summary_captcha">Show CAPTCHA if necessary (only Basic Member)</string> <string name="init_useenglish">Use English</string> + <string name="init_showoverflowmenu">Always show overflow menu</string> + <string name="init_showoverflow_summary">Always show the overflow menu (three dots ⋮) even if the device has a menu button (Restart needed)</string> <string name="init_summary_useenglish">Use English language for c:geo (Restart needed)</string> <string name="init_exclude">Exclude Own and Found</string> <string name="init_summary_exclude">Exclude caches you own or have found</string> @@ -541,6 +531,9 @@ <string name="init_maintenance">Maintenance</string> <string name="init_maintenance_directories_note">c:geo stores images, log images and other files related to a cache in a separate directory. In some cases (like importing/exporting the database) this directory may contain outdated files, which can be deleted here.</string> <string name="init_maintenance_directories">Delete orphaned files</string> + <string name="init_create_memory_dump">Create memory dump</string> + <string name="init_memory_dump">Memory dump</string> + <string name="init_memory_dumped">Memory dumped to %s</string> <string name="settings_open_website">Open website</string> <string name="settings_settings">Settings</string> <string name="settings_information">Information</string> @@ -632,8 +625,6 @@ <string name="cache_personal_note_uploading">Uploading personal note</string> <string name="cache_personal_note_upload_done">Personal note uploaded</string> <string name="cache_personal_note_upload_cancelled">Personal note upload cancelled</string> - <string name="cache_personal_note_unstored">Cache not stored</string> - <string name="cache_personal_note_store">The cache will be stored first to allow a personal note.</string> <string name="cache_description">Description</string> <string name="cache_description_long">Long Description</string> <string name="cache_description_table_note">Description contains table formatting which may need to be viewed at %s to be seen correctly.</string> @@ -659,7 +650,7 @@ <string name="cache_waypoints_add">Add Waypoint</string> <string name="cache_hint">Hint</string> <string name="cache_logs">Logbook</string> - <string name="cache_logsfriends">Logbook (Friends)</string> + <string name="cache_logs_friends_and_own">Friends/Own Logs</string> <string name="cache_dialog_loading_details">Loading cache details…</string> <string name="cache_dialog_loading_details_status_loadpage">Loading page</string> <string name="cache_dialog_loading_details_status_details">Processing details</string> @@ -705,16 +696,15 @@ <string name="cache_menu_refresh">Refresh</string> <string name="cache_menu_share">Share cache</string> <string name="cache_menu_move_list">Move to different list</string> - <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_navigon">Navigon</string> <string name="cache_menu_pebble">Pebble</string> <string name="cache_menu_mapswithme">MapsWithMe</string> <string name="cache_status">Status</string> <string name="cache_status_offline_log">Saved Log</string> <string name="cache_status_found">Found</string> + <string name="cache_not_status_found">Not Found</string> <string name="cache_status_archived">Archived</string> <string name="cache_status_disabled">Disabled</string> <string name="cache_status_premium">Premium Members only</string> @@ -847,10 +837,7 @@ <string name="map_view_map">Map view</string> <string name="map_modes">Map settings</string> <string name="map_trail_show">Show trail</string> - <string name="map_trail_hide">Hide trail</string> <string name="map_circles_show">Show circles</string> - <string name="map_circles_hide">Hide circles</string> - <string name="map_mycaches_show">Show own/found caches</string> <string name="map_mycaches_hide">Hide own/found caches</string> <string name="map_theme_builtin">Default</string> <string name="map_theme_select">Select map theme</string> @@ -1226,7 +1213,6 @@ <string name="website">Website: <a href="">cgeo.org</a></string> <string name="facebook">Facebook: <a href="">c:geo page</a></string> <string name="twitter">Twitter: <a href="">@android_GC</a></string> - <string name="nutshellmanual">Manual: <a href="">c:geo in a Nutshell</a></string> <string name="market">Android: <a href="">c:geo on Google Play</a></string> <string name="about_twitter">Should <b>c:geo</b> publish a new status on Twitter every time you log a cache?</string> <string name="faq">FAQ: <a href="">faq.cgeo.org</a></string> @@ -1285,4 +1271,6 @@ <!-- shortcuts --> <string name="cgeo_shortcut">c:geo shortcut</string> <string name="create_shortcut">Create shortcut</string> + <string name="send">Send</string> + </resources> diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml index c566122..ffcb6aa 100644 --- a/main/res/values/styles.xml +++ b/main/res/values/styles.xml @@ -70,7 +70,7 @@ <item name="android:padding">2dip</item> <item name="android:scaleType">center</item> <item name="android:focusable">true</item> - <item name="android:src">@drawable/actionbar_home</item> + <item name="android:src">@drawable/actionbar_cgeo</item> <item name="android:background">@drawable/actionbar_button</item> </style> @@ -102,6 +102,10 @@ <item name="android:text">c:geo</item> </style> + <style name="actionbar_myposition"> + <item name="android:button">@drawable/ic_menu_myposition</item> + </style> + <!-- button: full width --> <style name="button_full" parent="button"> <item name="android:layout_width">fill_parent</item> diff --git a/main/res/values/themes.xml b/main/res/values/themes.xml index ed64ef5..82a4422 100644 --- a/main/res/values/themes.xml +++ b/main/res/values/themes.xml @@ -1,15 +1,43 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <style name="cgeo_main" parent="android:style/Theme.Wallpaper.NoTitleBar"> + + <style name="cgeo_main" parent="@style/Theme.AppCompat"> + + <!-- copy the style elements of the Wallpaper theme since AppCombat has no Wallpaper theme --> + <item name="android:windowBackground">@color/background_main_transparent</item> + <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:windowShowWallpaper">true</item> + <!-- system elements --> <item name="android:windowContentOverlay">@null</item> + + </style> + + <style name="cgeo" parent="@style/Theme.AppCompat"> + + + <item name="android:buttonStyle">@style/button</item> + <item name="android:editTextStyle">@style/edittext</item> + <item name="android:windowContentOverlay">@null</item> + + <!-- own values: colors --> + <item name="just_color">@color/just_black</item> + <item name="text_color_link">@color/link</item> + <item name="button_color_enabled">@color/button_enabled</item> + <item name="button_color_disabled">@color/button_disabled</item> </style> - <style name="cgeo" parent="android:style/Theme.NoTitleBar"> - <!-- system elements --> + <!-- Identical to cgeo aside from different parent style --> + <style name="cgeo_light" parent="@style/Theme.AppCompat.Light.DarkActionBar"> + + <!-- For some reason we get the non inversed texts here (bug in abc?), explicitly set text styles --> + <item name="titleTextStyle">@style/TextAppearance.AppCompat.Widget.ActionMode.Title.Inverse</item> + <item name="subtitleTextStyle">@style/TextAppearance.AppCompat.Widget.ActionMode.Subtitle.Inverse</item> + + <item name="android:buttonStyle">@style/button</item> <item name="android:editTextStyle">@style/edittext</item> <item name="android:windowContentOverlay">@null</item> @@ -21,6 +49,8 @@ <item name="button_color_disabled">@color/button_disabled</item> </style> + + <style name="dark" parent="cgeo"> <!-- own values: colors --> @@ -50,10 +80,10 @@ <item name="compass">0</item> </style> - <style name="light" parent="cgeo"> + <style name="light" parent="cgeo_light"> <!-- own values: colors --> - <item name="android:windowBackground">@color/just_white</item> + <item name="android:windowBackground">@color/just_white</item> <item name="text_color">@color/text_light</item> <item name="text_color_headline">@color/text_headline_light</item> <item name="text_color_grey">@color/text_grey_light</item> @@ -80,80 +110,33 @@ <item name="compass">1</item> </style> - <style name="cgeo_popup" parent="android:style/Theme.Dialog"> - - <!-- system elements --> - <item name="android:buttonStyle">@style/button</item> - <item name="android:editTextStyle">@style/edittext</item> - <item name="android:windowNoTitle">true</item> + + <style name="cgeo.Translucent.Light" parent="light"> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowAnimationStyle">@android:style/Animation</item> </style> - <!-- TODO: Popup probably doesn't need all these fields set. Should delete unnecessary ones. --> - <style name="popup_dark" parent="cgeo_popup"> - <!-- own values: colors --> - <item name="just_color">@color/just_black</item> - <item name="text_color">@color/text_dark</item> - <item name="text_color_headline">@color/text_headline_dark</item> - <item name="text_color_grey">@color/text_grey_dark</item> - <item name="text_color_hint">@color/text_hint_dark</item> - <item name="text_color_link">@color/link</item> - <item name="button_color_enabled">@color/button_enabled</item> - <item name="button_color_disabled">@color/button_disabled</item> - <item name="background_color">@color/background_dark</item> - <item name="background_color_notice">@color/background_dark_notice</item> - <item name="background_color_transparent">@color/background_dark_transparent</item> - <item name="separator_color">@color/separator_dark</item> + <style name="cgeo.Translucent" parent="dark"> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowAnimationStyle">@android:style/Animation</item> + </style> - <!-- own values: drawables --> - <item name="button">@drawable/action_button_dark</item> - <item name="input">@drawable/input_bcg_dark</item> - <item name="inventory">@drawable/inventory_background_dark</item> - <item name="favorite">@drawable/favorite_background_dark</item> - <item name="favorite_r">@drawable/favorite_background_red_dark</item> - <item name="favorite_o">@drawable/favorite_background_orange_dark</item> - <item name="favorite_g">@drawable/favorite_background_green_dark</item> - <item name="close">@drawable/map_close_dark</item> - <item name="log_img_icon">@drawable/log_img_dark</item> - <item name="actionbar_compass">@drawable/actionbar_compass_dark</item> - <item name="progressSpinnerLarge">@android:style/Widget.ProgressBar.Large</item> + <style name="cgeo_popup" parent="cgeo.Translucent.Light"> + <item name="android:windowNoTitle">true</item> + </style> - <!-- own values: other --> - <item name="compass">0</item> + <style name="popup_dark" parent="cgeo.Translucent"> </style> - <!-- TODO: Popup probably doesn't need all these fields set. Should delete unnecessary ones. --> <style name="popup_light" parent="cgeo_popup"> - - <!-- own values: colors --> - <item name="android:windowBackground">@color/just_white</item> - <item name="text_color">@color/text_light</item> - <item name="text_color_headline">@color/text_headline_light</item> - <item name="text_color_grey">@color/text_grey_light</item> - <item name="text_color_hint">@color/text_hint_light</item> - <item name="background_color">@color/background_light</item> - <item name="background_color_notice">@color/background_light_notice</item> - <item name="background_color_transparent">@color/background_light_transparent</item> - <item name="separator_color">@color/separator_light</item> - - <!-- own values: drawables --> - <item name="button">@drawable/action_button_light</item> - <item name="input">@drawable/input_bcg_light</item> - <item name="inventory">@drawable/inventory_background_light</item> - <item name="favorite">@drawable/favorite_background_light</item> - <item name="favorite_r">@drawable/favorite_background_red_light</item> - <item name="favorite_o">@drawable/favorite_background_orange_light</item> - <item name="favorite_g">@drawable/favorite_background_green_light</item> - <item name="close">@drawable/map_close_light</item> - <item name="log_img_icon">@drawable/log_img_light</item> - <item name="actionbar_compass">@drawable/actionbar_compass_light</item> - <item name="progressSpinnerLarge">@android:style/Widget.ProgressBar.Large.Inverse</item> - - <!-- own values: other --> - <item name="compass">1</item> </style> - <style name="settings" parent="android:Theme"> + <style name="settings" parent="@style/Theme.AppCompat"> <item name="settings_cloud">@drawable/settings_cloud_white</item> <item name="settings_details">@drawable/settings_details_white</item> <item name="settings_eye">@drawable/settings_eye_white</item> @@ -165,7 +148,7 @@ <item name="settings_info_icon">@drawable/settings_info_icon_white</item> </style> - <style name="settings.light" parent="android:Theme.Light"> + <style name="settings.light" parent="@style/Theme.AppCompat.Light"> <item name="settings_cloud">@drawable/settings_cloud_black</item> <item name="settings_details">@drawable/settings_details_black</item> <item name="settings_eye">@drawable/settings_eye_black</item> diff --git a/main/res/xml/preferences.xml b/main/res/xml/preferences.xml index d550dc8..90911ae 100644 --- a/main/res/xml/preferences.xml +++ b/main/res/xml/preferences.xml @@ -216,7 +216,9 @@ android:title="@string/settings_open_website" /> </PreferenceCategory> </PreferenceScreen> - <PreferenceScreen android:title="@string/settings_title_ec" android:key="@string/preference_screen_ec"> + <PreferenceScreen + android:key="@string/preference_screen_ec" + android:title="@string/settings_title_ec" > <PreferenceCategory android:title="@string/settings_settings" > <CheckBoxPreference android:defaultValue="false" @@ -266,7 +268,9 @@ android:title="@string/settings_open_website" /> </PreferenceCategory> </PreferenceScreen> - <PreferenceScreen android:title="@string/settings_title_ox" android:key="@string/preference_screen_ox"> + <PreferenceScreen + android:key="@string/preference_screen_ox" + android:title="@string/settings_title_ox" > <PreferenceCategory android:title="@string/settings_settings" > <CheckBoxPreference android:defaultValue="false" @@ -285,11 +289,12 @@ </PreferenceScreen> <PreferenceScreen android:title="@string/init_gcvote" > <PreferenceCategory android:title="@string/settings_settings" > - <CheckBoxPreference - android:defaultValue="true" - android:key="@string/pref_ratingwanted" - android:summary="@string/init_summary_ratingwanted" - android:title="@string/init_ratingwanted" /> + <CheckBoxPreference + android:defaultValue="true" + android:key="@string/pref_ratingwanted" + android:summary="@string/init_summary_ratingwanted" + android:title="@string/init_ratingwanted" /> + <cgeo.geocaching.settings.EditPasswordPreference android:dialogTitle="@string/init_password" android:hint="@string/init_password" @@ -305,7 +310,9 @@ android:title="@string/settings_open_website" /> </PreferenceCategory> </PreferenceScreen> - <PreferenceScreen android:title="@string/init_sendToCgeo" > + <PreferenceScreen + android:key="@string/preference_screen_sendtocgeo" + android:title="@string/init_sendToCgeo" > <PreferenceCategory android:title="@string/settings_settings" > <EditTextPreference android:dialogTitle="@string/init_sendToCgeo_name" @@ -368,6 +375,7 @@ </PreferenceCategory> </PreferenceScreen> <PreferenceScreen + android:key="@string/pref_appearance" android:icon="?attr/settings_eye" android:title="@string/settings_title_appearance" > <CheckBoxPreference @@ -395,6 +403,12 @@ android:key="@string/pref_units" android:summary="@string/init_summary_units" android:title="@string/init_units" /> + <!-- this preference is only shown on < 4.4 devices, 4.4 unconditionally enables it --> + <CheckBoxPreference + android:title="@string/init_showoverflowmenu" + android:summary="@string/init_showoverflow_summary" + android:key="@string/pref_alwaysshowoverflowmenu" + android:defaultValue="false" /> </PreferenceScreen> <PreferenceScreen android:icon="?attr/settings_details" @@ -407,8 +421,8 @@ <CheckBoxPreference android:defaultValue="true" android:key="@string/pref_friendlogswanted" - android:summary="@string/init_summary_friendlogswanted" - android:title="@string/init_friendlogswanted" /> + android:summary="@string/init_summary_friends_and_own_logs_wanted" + android:title="@string/init_friends_and_own_logs_wanted" /> <CheckBoxPreference android:defaultValue="false" android:key="@string/pref_opendetailslastpage" @@ -649,16 +663,6 @@ <CheckBoxPreference android:defaultValue="true" android:enabled="false" - android:key="@string/pref_navigation_menu_cache_beacon" - android:title="@string/cache_menu_cachebeacon" /> - <CheckBoxPreference - android:defaultValue="true" - android:enabled="false" - android:key="@string/pref_navigation_menu_gcc" - android:title="@string/cache_menu_gcc" /> - <CheckBoxPreference - android:defaultValue="true" - android:enabled="false" android:key="@string/pref_navigation_menu_where_you_go" android:title="@string/cache_menu_whereyougo" /> <CheckBoxPreference @@ -726,7 +730,10 @@ android:defaultValue="false" android:key="@string/pref_debug" android:title="@string/init_debug" /> + <Preference + android:key="@string/pref_memory_dump" + android:title="@string/init_create_memory_dump" /> </PreferenceCategory> </PreferenceScreen> -</PreferenceScreen>
\ No newline at end of file +</PreferenceScreen> diff --git a/main/src/cgeo/calendar/CalendarAddon.java b/main/src/cgeo/calendar/CalendarAddon.java index 117fb9a..4a672fa 100644 --- a/main/src/cgeo/calendar/CalendarAddon.java +++ b/main/src/cgeo/calendar/CalendarAddon.java @@ -18,6 +18,11 @@ import android.net.Uri; import java.util.Date; public class CalendarAddon { + + private CalendarAddon() { + // utility class + } + public static boolean isAvailable() { return ProcessUtils.isIntentAvailable(ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST)); } diff --git a/main/src/cgeo/contacts/ContactsAddon.java b/main/src/cgeo/contacts/ContactsAddon.java index f2498ea..7165a77 100644 --- a/main/src/cgeo/contacts/ContactsAddon.java +++ b/main/src/cgeo/contacts/ContactsAddon.java @@ -8,6 +8,11 @@ import android.content.Intent; import android.net.Uri; public class ContactsAddon { + + private ContactsAddon() { + // utility class + } + public static void openContactCard(Activity context, String userName) { final Parameters params = new Parameters( IContacts.PARAM_NAME, userName diff --git a/main/src/cgeo/geocaching/AboutActivity.java b/main/src/cgeo/geocaching/AboutActivity.java index 6cda723..5bf0f06 100644 --- a/main/src/cgeo/geocaching/AboutActivity.java +++ b/main/src/cgeo/geocaching/AboutActivity.java @@ -14,6 +14,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -28,6 +29,8 @@ import java.util.Scanner; public class AboutActivity extends AbstractViewPagerActivity<AboutActivity.Page> { + private static final String EXTRA_ABOUT_STARTPAGE = "cgeo.geocaching.extra.about.startpage"; + class LicenseViewCreator extends AbstractCachingPageViewCreator<ScrollView> { @InjectView(R.id.license) protected TextView licenseLink; @@ -84,7 +87,6 @@ public class AboutActivity extends AbstractViewPagerActivity<AboutActivity.Page> @InjectView(R.id.website) protected TextView website; @InjectView(R.id.facebook) protected TextView facebook; @InjectView(R.id.twitter) protected TextView twitter; - @InjectView(R.id.nutshellmanual) protected TextView nutshellmanual; @InjectView(R.id.market) protected TextView market; @InjectView(R.id.faq) protected TextView faq; @@ -96,7 +98,6 @@ public class AboutActivity extends AbstractViewPagerActivity<AboutActivity.Page> setClickListener(website, "http://www.cgeo.org/"); setClickListener(facebook, "http://www.facebook.com/pages/cgeo/297269860090"); setClickListener(twitter, "http://twitter.com/android_gc"); - setClickListener(nutshellmanual, "http://manual.cgeo.org/"); setClickListener(faq, "http://faq.cgeo.org/"); market.setOnClickListener(new View.OnClickListener() { @@ -142,7 +143,13 @@ public class AboutActivity extends AbstractViewPagerActivity<AboutActivity.Page> @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState, R.layout.viewpager_activity); - createViewPager(0, null); + + int startPage = Page.VERSION.ordinal(); + Bundle extras = getIntent().getExtras(); + if (extras != null) { + startPage = extras.getInt(EXTRA_ABOUT_STARTPAGE, startPage); + } + createViewPager(startPage, null); reinitializeViewPager(); } @@ -210,4 +217,10 @@ public class AboutActivity extends AbstractViewPagerActivity<AboutActivity.Page> return result; } + public static void showChangeLog(Context fromActivity) { + final Intent intent = new Intent(fromActivity, AboutActivity.class); + intent.putExtra(EXTRA_ABOUT_STARTPAGE, Page.CHANGELOG.ordinal()); + fromActivity.startActivity(intent); + } + } diff --git a/main/src/cgeo/geocaching/AbstractDialogFragment.java b/main/src/cgeo/geocaching/AbstractDialogFragment.java new file mode 100644 index 0000000..6de8fec --- /dev/null +++ b/main/src/cgeo/geocaching/AbstractDialogFragment.java @@ -0,0 +1,358 @@ +package cgeo.geocaching; + +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.enumerations.CacheSize; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.gcvote.GCVote; +import cgeo.geocaching.gcvote.GCVoteRating; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.Units; +import cgeo.geocaching.sensors.GeoDirHandler; +import cgeo.geocaching.sensors.IGeoData; +import cgeo.geocaching.settings.Settings; +import cgeo.geocaching.ui.CacheDetailsCreator; +import cgeo.geocaching.ui.LoggingUI; +import cgeo.geocaching.utils.Log; + +import rx.Observable; +import rx.Subscription; +import rx.android.observables.AndroidObservable; +import rx.functions.Action1; +import rx.functions.Func0; +import rx.schedulers.Schedulers; +import rx.subscriptions.Subscriptions; + +import android.annotation.TargetApi; +import android.content.DialogInterface; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v7.widget.PopupMenu; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +public abstract class AbstractDialogFragment extends DialogFragment implements CacheMenuHandler.ActivityInterface, PopupMenu.OnMenuItemClickListener, MenuItem.OnMenuItemClickListener { + protected CgeoApplication app = null; + protected Resources res = null; + protected String geocode; + protected CacheDetailsCreator details; + + private Subscription resumeSubscription = Subscriptions.empty(); + private TextView cacheDistance = null; + + + protected static final String GEOCODE_ARG= "GEOCODE"; + protected static final String WAYPOINT_ARG= "WAYPOINT"; + + protected Geocache cache; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + res = getResources(); + app = (CgeoApplication) getActivity().getApplication(); + setHasOptionsMenu(true); + } + + protected void initCustomActionBar(View v) + { + final ImageView defaultNavigationImageView = (ImageView) v.findViewById(R.id.defaultNavigation); + defaultNavigationImageView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + startDefaultNavigation2(); + return true; + } + }); + defaultNavigationImageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + navigateTo(); + } + }); + + final View overflowActionBar = v.findViewById(R.id.overflowActionBar); + overflowActionBar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showPopup(v); + } + }); + /* Use a context menu instead popup where the popup menu is not working */ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + registerForContextMenu(overflowActionBar); + } + + } + + final public void setTitle(final CharSequence title) { + final TextView titleview = (TextView) getView().findViewById(R.id.actionbar_title); + if (titleview != null) { + titleview.setText(title); + + } + } + + @Override + public void onStart() { + super.onStart(); + geocode = getArguments().getString(GEOCODE_ARG); + } + + + protected void showPopup(View view) + { + // For reason I totally not understand the PopupMenu from Appcompat is broken beyond + // repair. Chicken out here and show the old menu on Gingerbread. + // The "correct" way of implementing this is stil in + // showPopupCompat(view) + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + view.showContextMenu(); + } else { + showPopupHoneycomb(view); + } + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void showPopupHoneycomb(View view) { + android.widget.PopupMenu popupMenu = new android.widget.PopupMenu(getActivity(), view); + CacheMenuHandler.addMenuItems(new MenuInflater(getActivity()), popupMenu.getMenu(), cache); + popupMenu.setOnMenuItemClickListener( + new android.widget.PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return AbstractDialogFragment.this.onMenuItemClick(item); + } + } + ); + popupMenu.show(); + } + + protected void showPopupCompat(View view) + { + PopupMenu popupMenu = new PopupMenu(getActivity(), view); + + // Directly instantiate SupportMenuInflater instead of getActivity().getMenuinflator + // getMenuinflator will throw a NPE since it tries to get the not displayed ActionBar + // menuinflator = getActivity().getMenuInflater(); + // MenuInflater menuinflator = new SupportMenuInflater(getActivity()); + CacheMenuHandler.addMenuItems(popupMenu.getMenuInflater(), popupMenu.getMenu(), cache); + popupMenu.setOnMenuItemClickListener(this); + popupMenu.show(); + } + + + protected void init() + { + cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + + if (cache == null) { + ((AbstractActivity) getActivity()).showToast(res.getString(R.string.err_detail_cache_find)); + + getActivity().finish(); + return; + } + + geocode = cache.getGeocode(); + } + + @Override + public void onResume() { + super.onResume(); + this.resumeSubscription = geoUpdate.start(GeoDirHandler.UPDATE_GEODATA); + init(); + } + + + @Override + public void onPause() { + resumeSubscription.unsubscribe(); + super.onPause(); + } + + + private void aquireGCVote() { + if (!Settings.isRatingWanted()) { + return; + } + if (!cache.supportsGCVote()) { + return; + } + AndroidObservable.bindActivity(getActivity(), Observable.defer(new Func0<Observable<GCVoteRating>>() { + @Override + public Observable<GCVoteRating> call() { + final GCVoteRating rating = GCVote.getRating(cache.getGuid(), geocode); + return rating != null ? Observable.just(rating) : Observable.<GCVoteRating>empty(); + } + })).subscribeOn(Schedulers.io()).subscribe(new Action1<GCVoteRating>() { + @Override + public void call(final GCVoteRating rating) { + cache.setRating(rating.getRating()); + cache.setVotes(rating.getVotes()); + DataStore.saveChangedCache(cache); + details.addRating(cache); + } + }); + } + + protected final void addCacheDetails() { + assert cache != null; + // cache type + final String cacheType = cache.getType().getL10n(); + final String cacheSize = cache.getSize() != CacheSize.UNKNOWN ? " (" + cache.getSize().getL10n() + ")" : ""; + details.add(R.string.cache_type, cacheType + cacheSize); + + details.add(R.string.cache_geocode, cache.getGeocode()); + details.addCacheState(cache); + + details.addDistance(cache, cacheDistance); + cacheDistance = details.getValueView(); + + details.addDifficulty(cache); + details.addTerrain(cache); + details.addEventDate(cache); + + // rating + if (cache.getRating() > 0) { + details.addRating(cache); + } else { + aquireGCVote(); + } + + // favorite count + details.add(R.string.cache_favorite, cache.getFavoritePoints() + "×"); + + // more details + final Button buttonMore = (Button) getView().findViewById(R.id.more_details); + + buttonMore.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View arg0) { + CacheDetailActivity.startActivity(getActivity(), geocode); + getActivity().finish(); + } + }); + + /* Only working combination as it seems */ + registerForContextMenu(buttonMore); + } + + public final void showToast(String text) { + ActivityMixin.showToast(getActivity(), text); + } + + private final GeoDirHandler geoUpdate = new GeoDirHandler() { + + @Override + public void updateGeoData(final IGeoData geo) { + try { + if (geo.getCoords() != null && cache != null && cache.getCoords() != null) { + cacheDistance.setText(Units.getDistanceFromKilometers(geo.getCoords().distanceTo(cache.getCoords()))); + cacheDistance.bringToFront(); + } + onUpdateGeoData(geo); + } catch (final RuntimeException e) { + Log.w("Failed to UpdateLocation location."); + } + } + }; + + /** + * @param geo + * location + */ + protected void onUpdateGeoData(final IGeoData geo) { + // do nothing by default + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + CacheMenuHandler.addMenuItems(inflater, menu, cache); + + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + CacheMenuHandler.addMenuItems(new MenuInflater(getActivity()), menu, cache); + for (int i=0;i<menu.size();i++) { + MenuItem m = menu.getItem(i); + m.setOnMenuItemClickListener(this); + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + return onOptionsItemSelected(item); + } + + + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + return onOptionsItemSelected(menuItem); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (CacheMenuHandler.onMenuItemSelected(item, this, cache)) { + return true; + } + if (LoggingUI.onMenuItemSelected(item, getActivity(), cache)) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + try { + CacheMenuHandler.onPrepareOptionsMenu(menu, cache); + LoggingUI.onPrepareOptionsMenu(menu, cache); + } catch (final RuntimeException e) { + // nothing + } + } + + + protected abstract Geopoint getCoordinates(); + + protected abstract void startDefaultNavigation2(); + + + @Override + public void cachesAround() { + final Geopoint coords = getCoordinates(); + if (coords == null) { + showToast(res.getString(R.string.err_location_unknown)); + return; + } + CacheListActivity.startActivityCoordinates((AbstractActivity) getActivity(), coords); + getActivity().finish(); + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + getActivity().finish(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + } +} diff --git a/main/src/cgeo/geocaching/AbstractLoggingActivity.java b/main/src/cgeo/geocaching/AbstractLoggingActivity.java index c3ba7d2..bca5db1 100644 --- a/main/src/cgeo/geocaching/AbstractLoggingActivity.java +++ b/main/src/cgeo/geocaching/AbstractLoggingActivity.java @@ -1,32 +1,29 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.gc.GCConnector; import cgeo.geocaching.connector.gc.GCSmiliesProvider; import cgeo.geocaching.connector.gc.GCSmiliesProvider.Smiley; import cgeo.geocaching.connector.trackable.TravelBugConnector; -import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.LogTemplateProvider; import cgeo.geocaching.utils.LogTemplateProvider.LogContext; import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate; -import org.apache.commons.lang3.StringUtils; - import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.widget.EditText; -public abstract class AbstractLoggingActivity extends AbstractActivity { +public abstract class AbstractLoggingActivity extends AbstractActionBarActivity { @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.abstract_logging_activity, menu); final SubMenu menuLog = menu.findItem(R.id.menu_templates).getSubMenu(); - for (final LogTemplate template : LogTemplateProvider.getTemplates()) { + for (final LogTemplate template : LogTemplateProvider.getTemplatesWithSignature()) { menuLog.add(0, template.getItemId(), 0, template.getResourceId()); } @@ -39,10 +36,7 @@ public abstract class AbstractLoggingActivity extends AbstractActivity { } @Override - public boolean onPrepareOptionsMenu(Menu menu) { - final boolean signatureAvailable = StringUtils.isNotBlank(Settings.getSignature()); - menu.findItem(R.id.menu_signature).setVisible(signatureAvailable); - + public boolean onPrepareOptionsMenu(final Menu menu) { boolean smileyVisible = false; final Geocache cache = getLogContext().getCache(); if (cache != null && ConnectorFactory.getConnector(cache).equals(GCConnector.getInstance())) { @@ -59,14 +53,9 @@ public abstract class AbstractLoggingActivity extends AbstractActivity { } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { final int id = item.getItemId(); - if (id == R.id.menu_signature) { - insertIntoLog(LogTemplateProvider.applyTemplates(Settings.getSignature(), getLogContext()), true); - return true; - } - final LogTemplate template = LogTemplateProvider.getTemplate(id); if (template != null) { insertIntoLog(template.getValue(getLogContext()), true); @@ -79,12 +68,12 @@ public abstract class AbstractLoggingActivity extends AbstractActivity { return true; } - return false; + return super.onOptionsItemSelected(item); } protected abstract LogContext getLogContext(); - protected void insertIntoLog(String newText, final boolean moveCursor) { + protected void insertIntoLog(final String newText, final boolean moveCursor) { final EditText log = (EditText) findViewById(R.id.log); ActivityMixin.insertAtPosition(log, newText, moveCursor); } diff --git a/main/src/cgeo/geocaching/AbstractPopupActivity.java b/main/src/cgeo/geocaching/AbstractPopupActivity.java deleted file mode 100644 index 88cad01..0000000 --- a/main/src/cgeo/geocaching/AbstractPopupActivity.java +++ /dev/null @@ -1,260 +0,0 @@ -package cgeo.geocaching; - -import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.activity.ActivityMixin; -import cgeo.geocaching.enumerations.CacheSize; -import cgeo.geocaching.enumerations.LoadFlags; -import cgeo.geocaching.gcvote.GCVote; -import cgeo.geocaching.gcvote.GCVoteRating; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.Units; -import cgeo.geocaching.sensors.GeoDirHandler; -import cgeo.geocaching.sensors.IGeoData; -import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.ui.CacheDetailsCreator; -import cgeo.geocaching.ui.LoggingUI; -import cgeo.geocaching.utils.Log; - -import org.apache.commons.lang3.StringUtils; - -import rx.Observable; -import rx.android.observables.AndroidObservable; -import rx.functions.Action1; -import rx.functions.Func0; -import rx.schedulers.Schedulers; - -import android.graphics.Rect; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; - -public abstract class AbstractPopupActivity extends AbstractActivity implements CacheMenuHandler.ActivityInterface { - - protected Geocache cache = null; - protected String geocode = null; - protected CacheDetailsCreator details; - - private TextView cacheDistance = null; - private final int layout; - - private final GeoDirHandler geoUpdate = new GeoDirHandler() { - - @Override - public void updateGeoData(final IGeoData geo) { - try { - if (geo.getCoords() != null && cache != null && cache.getCoords() != null) { - cacheDistance.setText(Units.getDistanceFromKilometers(geo.getCoords().distanceTo(cache.getCoords()))); - cacheDistance.bringToFront(); - } - onUpdateGeoData(geo); - } catch (final RuntimeException e) { - Log.w("Failed to UpdateLocation location."); - } - } - }; - - /** - * Callback to run when new location information is available. - * This may be overridden by deriving classes. The default implementation does nothing. - * - * @param geo - * the new data - */ - public void onUpdateGeoData(final IGeoData geo) { - } - - protected AbstractPopupActivity(int layout) { - this.layout = layout; - } - - private void aquireGCVote() { - if (!Settings.isRatingWanted()) { - return; - } - if (!cache.supportsGCVote()) { - return; - } - AndroidObservable.bindActivity(this, Observable.defer(new Func0<Observable<GCVoteRating>>() { - @Override - public Observable<GCVoteRating> call() { - final GCVoteRating rating = GCVote.getRating(cache.getGuid(), geocode); - return rating != null ? Observable.just(rating) : Observable.<GCVoteRating>empty(); - } - })).subscribe(new Action1<GCVoteRating>() { - @Override - public void call(final GCVoteRating rating) { - cache.setRating(rating.getRating()); - cache.setVotes(rating.getVotes()); - DataStore.saveChangedCache(cache); - details.addRating(cache); - } - }, Schedulers.io()); - } - - protected void init() { - cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); - - if (cache == null) { - showToast(res.getString(R.string.err_detail_cache_find)); - - finish(); - return; - } - - geocode = cache.getGeocode(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // set theme - this.setTheme(ActivityMixin.getDialogTheme()); - // set layout - setContentView(layout); - - // get parameters - final Bundle extras = getIntent().getExtras(); - if (extras != null) { - geocode = extras.getString(Intents.EXTRA_GEOCODE); - } - - if (StringUtils.isBlank(geocode)) { - showToast(res.getString(R.string.err_detail_cache_find)); - - finish(); - return; - } - - final ImageView defaultNavigationImageView = (ImageView) findViewById(R.id.defaultNavigation); - defaultNavigationImageView.setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - startDefaultNavigation2(); - return true; - } - }); - - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - CacheMenuHandler.addMenuItems(this, menu, cache); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (CacheMenuHandler.onMenuItemSelected(item, this, cache)) { - return true; - } - if (LoggingUI.onMenuItemSelected(item, this, cache)) { - return true; - } - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - try { - CacheMenuHandler.onPrepareOptionsMenu(menu, cache); - LoggingUI.onPrepareOptionsMenu(menu, cache); - } catch (final RuntimeException e) { - // nothing - } - - return true; - } - - protected abstract Geopoint getCoordinates(); - - @Override - public void onResume() { - super.onResume(geoUpdate.start(GeoDirHandler.UPDATE_GEODATA)); - init(); - } - - @Override - public boolean onTouchEvent(final MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP) { - final Rect r = new Rect(0, 0, 0, 0); - getWindow().getDecorView().getHitRect(r); - if (!r.contains((int) event.getX(), (int) event.getY())) { - finish(); - return true; - } - } - return super.onTouchEvent(event); - } - - protected abstract void startDefaultNavigation2(); - - protected final void addCacheDetails() { - assert cache != null; - // cache type - final String cacheType = cache.getType().getL10n(); - final String cacheSize = cache.getSize() != CacheSize.UNKNOWN ? " (" + cache.getSize().getL10n() + ")" : ""; - details.add(R.string.cache_type, cacheType + cacheSize); - - details.add(R.string.cache_geocode, cache.getGeocode()); - details.addCacheState(cache); - - details.addDistance(cache, cacheDistance); - cacheDistance = details.getValueView(); - - details.addDifficulty(cache); - details.addTerrain(cache); - details.addEventDate(cache); - - // rating - if (cache.getRating() > 0) { - details.addRating(cache); - } else { - aquireGCVote(); - } - - // favorite count - details.add(R.string.cache_favorite, cache.getFavoritePoints() + "×"); - - // more details - final Button buttonMore = (Button) findViewById(R.id.more_details); - buttonMore.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View arg0) { - CacheDetailActivity.startActivity(AbstractPopupActivity.this, geocode); - finish(); - } - }); - } - - @Override - public void cachesAround() { - final Geopoint coords = getCoordinates(); - if (coords == null) { - showToast(res.getString(R.string.err_location_unknown)); - return; - } - CacheListActivity.startActivityCoordinates(this, coords); - finish(); - } - - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public final void goDefaultNavigation(View view) { - navigateTo(); - finish(); - } - -} diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index a66d181..062c97a 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -46,6 +46,7 @@ import cgeo.geocaching.utils.CryptUtils; import cgeo.geocaching.utils.ImageUtils; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.RxUtils; import cgeo.geocaching.utils.SimpleCancellableHandler; import cgeo.geocaching.utils.SimpleHandler; import cgeo.geocaching.utils.TextUtils; @@ -60,9 +61,9 @@ import org.apache.commons.lang3.tuple.Pair; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Observer; -import rx.Scheduler.Inner; import rx.Subscriber; import rx.android.observables.AndroidObservable; +import rx.functions.Action0; import rx.functions.Action1; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; @@ -84,6 +85,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentManager; +import android.support.v7.view.ActionMode; import android.text.Editable; import android.text.Html; import android.text.Spannable; @@ -165,7 +167,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private Waypoint selectedWaypoint; @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState, R.layout.cachedetail_activity); createSubscriptions = new CompositeSubscription(); @@ -272,22 +274,13 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // nothing, we lost the window } - final ImageView defaultNavigationImageView = (ImageView) findViewById(R.id.defaultNavigation); - defaultNavigationImageView.setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - startDefaultNavigation2(); - return true; - } - }); - final int pageToOpen = savedInstanceState != null ? savedInstanceState.getInt(STATE_PAGE_INDEX, 0) : Settings.isOpenLastDetailsPage() ? Settings.getLastDetailsPage() : 1; createViewPager(pageToOpen, new OnPageSelectedListener() { @Override - public void onPageSelected(int position) { + public void onPageSelected(final int position) { if (Settings.isOpenLastDetailsPage()) { Settings.setLastDetailsPage(position); } @@ -300,9 +293,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final String realGeocode = geocode; final String realGuid = guid; - Schedulers.io().schedule(new Action1<Inner>() { + Schedulers.io().createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { search = Geocache.searchByGeocode(realGeocode, StringUtils.isBlank(realGeocode) ? realGuid : null, 0, false, loadCacheHandler); loadCacheHandler.sendMessage(Message.obtain()); } @@ -342,53 +335,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { + public void onCreateContextMenu(final ContextMenu menu, final View view, final ContextMenu.ContextMenuInfo info) { super.onCreateContextMenu(menu, view, info); final int viewId = view.getId(); switch (viewId) { - case R.id.value: // coordinates, gc-code, name - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - final CharSequence itemTitle = ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); - buildDetailsContextMenu(menu, clickedItemText, itemTitle, true); - break; - case R.id.shortdesc: - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_description), false); - break; - case R.id.longdesc: - assert view instanceof TextView; - // combine short and long description - final String shortDesc = cache.getShortDescription(); - if (StringUtils.isBlank(shortDesc)) { - clickedItemText = ((TextView) view).getText(); - } else { - clickedItemText = shortDesc + "\n\n" + ((TextView) view).getText(); - } - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_description), false); - break; - case R.id.personalnote: - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_personal_note), true); - break; - case R.id.hint: - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_hint), false); - break; - case R.id.log: - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_logs), false); - break; - case R.id.date: // event date - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_event), true); - menu.findItem(R.id.menu_calendar).setVisible(cache.canBeAddedToCalendar()); - break; case R.id.waypoint: menu.setHeaderTitle(selectedWaypoint.getName() + " (" + res.getString(R.string.waypoint) + ")"); getMenuInflater().inflate(R.menu.waypoint_options, menu); @@ -414,25 +364,25 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override - public boolean onContextItemSelected(MenuItem item) { - if (onClipboardItemSelected(item, clickedItemText)) { - return true; - } + public boolean onContextItemSelected(final MenuItem item) { switch (item.getItemId()) { // waypoints case R.id.menu_waypoint_edit: if (selectedWaypoint != null) { + ensureSaved(); EditWaypointActivity.startActivityEditWaypoint(this, cache, selectedWaypoint.getId()); refreshOnResume = true; } return true; case R.id.menu_waypoint_duplicate: + ensureSaved(); if (cache.duplicateWaypoint(selectedWaypoint)) { DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); notifyDataSetChanged(); } return true; case R.id.menu_waypoint_delete: + ensureSaved(); if (cache.deleteWaypoint(selectedWaypoint)) { DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); notifyDataSetChanged(); @@ -454,10 +404,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } return true; case R.id.menu_waypoint_reset_cache_coords: + ensureSaved(); if (ConnectorFactory.getConnector(cache).supportsOwnCoordinates()) { createResetCacheCoordinatesDialog(cache, selectedWaypoint).show(); - } - else { + } else { final ProgressDialog progressDialog = ProgressDialog.show(this, getString(R.string.cache), getString(R.string.waypoint_reset), true); final HandlerResetCoordinates handler = new HandlerResetCoordinates(this, progressDialog, false); new ResetCoordsThread(cache, handler, selectedWaypoint, true, false, progressDialog).start(); @@ -476,20 +426,23 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { CacheMenuHandler.addMenuItems(this, menu, cache); return true; } @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(final Menu menu) { CacheMenuHandler.onPrepareOptionsMenu(menu, cache); LoggingUI.onPrepareOptionsMenu(menu, cache); + menu.findItem(R.id.menu_store).setVisible(cache != null && !cache.isOffline()); + menu.findItem(R.id.menu_delete).setVisible(cache != null && cache.isOffline()); + menu.findItem(R.id.menu_refresh).setVisible(cache != null && cache.isOffline()); return super.onPrepareOptionsMenu(menu); } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { if (CacheMenuHandler.onMenuItemSelected(item, this, cache)) { return true; } @@ -497,9 +450,15 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final int menuItem = item.getItemId(); switch (menuItem) { - case 0: - // no menu selected, but a new sub menu shown - return false; + case R.id.menu_delete: + dropCache(); + return true; + case R.id.menu_store: + storeCache(); + return true; + case R.id.menu_refresh: + refreshCache(); + return true; default: if (NavigationAppFactory.onMenuItemSelected(item, this, cache)) { return true; @@ -510,7 +469,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - return true; + return super.onOptionsItemSelected(item); } private static final class CacheDetailsGeoDirHandler extends GeoDirHandler { @@ -539,7 +498,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private final static class LoadCacheHandler extends SimpleCancellableHandler { - public LoadCacheHandler(CacheDetailActivity activity, Progress progress) { + public LoadCacheHandler(final CacheDetailActivity activity, final Progress progress) { super(activity, progress); } @@ -574,7 +533,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } private void updateStatusMsg(final String msg) { - CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get()); + final CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get()); if (activity == null) { return; } @@ -613,7 +572,18 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } else { setTitle(cache.getGeocode()); } - ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(cache.getType().markerId), null, null, null); + + getSupportActionBar().setIcon(getResources().getDrawable(cache.getType().markerId)); + + // if we have a newer Android device setup Android Beam for easy cache sharing + initializeAndroidBeam( + new ActivitySharingInterface() { + @Override + public String getUri() { + return cache.getCgeoUrl(); + } + } + ); // reset imagesList so Images view page will be redrawn imagesList = null; @@ -622,8 +592,11 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // rendering done! remove progress popup if any there invalidateOptionsMenuCompatible(); progress.dismiss(); + + Settings.addCacheToHistory(cache.getGeocode()); } + /** * Tries to navigate to the {@link Geocache} of this activity. */ @@ -632,23 +605,16 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } /** - * Tries to navigate to the {@link Geocache} of this activity. - */ - private void startDefaultNavigation2() { - NavigationAppFactory.startDefaultNavigationApplication(2, this, cache); - } - - /** * Wrapper for the referenced method in the xml-layout. */ - public void goDefaultNavigation(@SuppressWarnings("unused") View view) { + public void goDefaultNavigation(@SuppressWarnings("unused") final View view) { startDefaultNavigation(); } /** * referenced from XML view */ - public void showNavigationMenu(@SuppressWarnings("unused") View view) { + public void showNavigationMenu(@SuppressWarnings("unused") final View view) { NavigationAppFactory.showNavigationMenu(this, cache, null, null, true, true); } @@ -681,7 +647,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc DETAILS(R.string.detail), DESCRIPTION(R.string.cache_description), LOGS(R.string.cache_logs), - LOGSFRIENDS(R.string.cache_logsfriends), + LOGSFRIENDS(R.string.cache_logs_friends_and_own), WAYPOINTS(R.string.cache_waypoints), INVENTORY(R.string.cache_inventory), IMAGES(R.string.cache_images); @@ -723,7 +689,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc attributeBox.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { + public void onClick(final View v) { // toggle between attribute icons and descriptions toggleAttributeDisplay(attributeBox, attributeBoxMaxWidth); } @@ -748,7 +714,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc * lazy-creates the layout holding the icons of the caches attributes * and makes it visible */ - private void showAttributeIcons(LinearLayout attribBox, int parentWidth) { + private void showAttributeIcons(final LinearLayout attribBox, final int parentWidth) { if (attributeIconsLayout == null) { attributeIconsLayout = createAttributeIconsLayout(parentWidth); // no matching icons found? show text @@ -766,7 +732,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc * lazy-creates the layout holding the descriptions of the caches attributes * and makes it visible */ - private void showAttributeDescriptions(LinearLayout attribBox) { + private void showAttributeDescriptions(final LinearLayout attribBox) { if (attributeDescriptionsLayout == null) { attributeDescriptionsLayout = createAttributeDescriptionsLayout(); } @@ -778,7 +744,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc /** * toggle attribute descriptions and icons */ - private void toggleAttributeDisplay(LinearLayout attribBox, int parentWidth) { + private void toggleAttributeDisplay(final LinearLayout attribBox, final int parentWidth) { // Don't toggle when there are no icons to show. if (noAttributeIconsFound) { return; @@ -792,7 +758,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - private ViewGroup createAttributeIconsLayout(int parentWidth) { + private ViewGroup createAttributeIconsLayout(final int parentWidth) { final LinearLayout rows = new LinearLayout(CacheDetailActivity.this); rows.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); rows.setOrientation(LinearLayout.VERTICAL); @@ -857,7 +823,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc for (String attributeName : cache.getAttributes()) { final boolean enabled = CacheAttribute.isEnabled(attributeName); // search for a translation of the attribute - CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName)); + final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName)); if (attrib != null) { attributeName = attrib.getL10n(enabled); } @@ -873,6 +839,54 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } + private void refreshCache() { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + if (!Network.isNetworkConnected(getApplicationContext())) { + showToast(getString(R.string.err_server)); + return; + } + + final RefreshCacheHandler refreshCacheHandler = new RefreshCacheHandler(CacheDetailActivity.this, progress); + + progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, refreshCacheHandler.cancelMessage()); + + cache.refresh(refreshCacheHandler, Schedulers.io()); + } + + private void dropCache() { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, null); + cache.drop(new ChangeNotificationHandler(CacheDetailActivity.this, progress), Schedulers.io()); + } + + private void storeCache() { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + if (Settings.getChooseList()) { + // let user select list to store cache in + new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title, + new Action1<Integer>() { + @Override + public void call(final Integer selectedListId) { + storeCache(selectedListId, new StoreCacheHandler(CacheDetailActivity.this, progress)); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + storeCache(StoredList.TEMPORARY_LIST_ID, new StoreCacheHandler(CacheDetailActivity.this, progress)); + } + } + /** * Creator for details-view. */ @@ -894,17 +908,18 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc view = (ScrollView) getLayoutInflater().inflate(R.layout.cachedetail_details_page, null); // Start loading preview map - AndroidObservable.bindActivity(CacheDetailActivity.this, previewMap).subscribe(new Action1<BitmapDrawable>() { - @Override - public void call(final BitmapDrawable image) { - final Bitmap bitmap = image.getBitmap(); - if (bitmap != null && bitmap.getWidth() > 10) { - final ImageView imageView = (ImageView) view.findViewById(R.id.map_preview); - imageView.setImageDrawable(image); - view.findViewById(R.id.map_preview_box).setVisibility(View.VISIBLE); - } - } - }, Schedulers.io()); + AndroidObservable.bindActivity(CacheDetailActivity.this, previewMap).subscribeOn(Schedulers.io()) + .subscribe(new Action1<BitmapDrawable>() { + @Override + public void call(final BitmapDrawable image) { + final Bitmap bitmap = image.getBitmap(); + if (bitmap != null && bitmap.getWidth() > 10) { + final ImageView imageView = (ImageView) view.findViewById(R.id.map_preview); + imageView.setImageDrawable(image); + view.findViewById(R.id.map_preview_box).setVisibility(View.VISIBLE); + } + } + }); detailsList = (LinearLayout) view.findViewById(R.id.details_list); final CacheDetailsCreator details = new CacheDetailsCreator(CacheDetailActivity.this, detailsList); @@ -918,10 +933,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc span.setSpan(new ForegroundColorSpan(res.getColor(R.color.archived_cache_color)), 0, span.toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } - registerForContextMenu(details.add(R.string.cache_name, span)); + addContextMenu(details.add(R.string.cache_name, span)); details.add(R.string.cache_type, cache.getType().getL10n()); details.addSize(cache); - registerForContextMenu(details.add(R.string.cache_geocode, cache.getGeocode())); + addContextMenu(details.add(R.string.cache_geocode, cache.getGeocode())); details.addCacheState(cache); details.addDistance(cache, cacheDistanceView); @@ -955,7 +970,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // hidden or event date final TextView hiddenView = details.addHiddenDate(cache); if (hiddenView != null) { - registerForContextMenu(hiddenView); + addContextMenu(hiddenView); } // cache location @@ -967,7 +982,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc if (cache.getCoords() != null) { final TextView valueView = details.add(R.string.cache_coordinates, cache.getCoords().toString()); valueView.setOnClickListener(new CoordinatesFormatSwitcher(cache.getCoords())); - registerForContextMenu(valueView); + addContextMenu(valueView); } // cache attributes @@ -1015,59 +1030,23 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private class StoreCacheClickListener implements View.OnClickListener { @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - if (Settings.getChooseList()) { - // let user select list to store cache in - new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title, - new Action1<Integer>() { - @Override - public void call(final Integer selectedListId) { - storeCache(selectedListId, new StoreCacheHandler(CacheDetailActivity.this, progress)); - } - }, true, StoredList.TEMPORARY_LIST_ID); - } else { - storeCache(StoredList.TEMPORARY_LIST_ID, new StoreCacheHandler(CacheDetailActivity.this, progress)); - } + public void onClick(final View arg0) { + storeCache(); } } private class RefreshCacheClickListener implements View.OnClickListener { @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - if (!Network.isNetworkConnected(getApplicationContext())) { - showToast(getString(R.string.err_server)); - return; - } - - final RefreshCacheHandler refreshCacheHandler = new RefreshCacheHandler(CacheDetailActivity.this, progress); - - progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, refreshCacheHandler.cancelMessage()); - - cache.refresh(cache.getListId(), refreshCacheHandler, Schedulers.io()); + public void onClick(final View arg0) { + refreshCache(); } } private class DropCacheClickListener implements View.OnClickListener { @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, null); - cache.drop(new ChangeNotificationHandler(CacheDetailActivity.this, progress), Schedulers.io()); + public void onClick(final View arg0) { + dropCache(); } } @@ -1075,7 +1054,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc * Abstract Listener for add / remove buttons for watchlist */ private abstract class AbstractWatchlistClickListener implements View.OnClickListener { - public void doExecute(int titleId, int messageId, Thread thread) { + public void doExecute(final int titleId, final int messageId, final Thread thread) { if (progress.isShowing()) { showToast(res.getString(R.string.err_watchlist_still_managing)); return; @@ -1096,7 +1075,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc */ private class AddToWatchlistClickListener extends AbstractWatchlistClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { doExecute(R.string.cache_dialog_watchlist_add_title, R.string.cache_dialog_watchlist_add_message, new WatchlistAddThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress))); @@ -1108,7 +1087,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc */ private class RemoveFromWatchlistClickListener extends AbstractWatchlistClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { doExecute(R.string.cache_dialog_watchlist_remove_title, R.string.cache_dialog_watchlist_remove_message, new WatchlistRemoveThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress))); @@ -1119,7 +1098,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private class WatchlistAddThread extends Thread { private final Handler handler; - public WatchlistAddThread(Handler handler) { + public WatchlistAddThread(final Handler handler) { this.handler = handler; } @@ -1131,7 +1110,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc msg = Message.obtain(handler, MESSAGE_SUCCEEDED); } else { msg = Message.obtain(handler, MESSAGE_FAILED); - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_watchlist_failed)); msg.setData(bundle); } @@ -1143,7 +1122,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private class WatchlistRemoveThread extends Thread { private final Handler handler; - public WatchlistRemoveThread(Handler handler) { + public WatchlistRemoveThread(final Handler handler) { this.handler = handler; } @@ -1155,7 +1134,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc msg = Message.obtain(handler, MESSAGE_SUCCEEDED); } else { msg = Message.obtain(handler, MESSAGE_FAILED); - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_watchlist_failed)); msg.setData(bundle); } @@ -1167,7 +1146,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private class FavoriteAddThread extends Thread { private final Handler handler; - public FavoriteAddThread(Handler handler) { + public FavoriteAddThread(final Handler handler) { this.handler = handler; } @@ -1179,7 +1158,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc msg = Message.obtain(handler, MESSAGE_SUCCEEDED); } else { msg = Message.obtain(handler, MESSAGE_FAILED); - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_favorite_failed)); msg.setData(bundle); } @@ -1191,7 +1170,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private class FavoriteRemoveThread extends Thread { private final Handler handler; - public FavoriteRemoveThread(Handler handler) { + public FavoriteRemoveThread(final Handler handler) { this.handler = handler; } @@ -1203,7 +1182,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc msg = Message.obtain(handler, MESSAGE_SUCCEEDED); } else { msg = Message.obtain(handler, MESSAGE_FAILED); - Bundle bundle = new Bundle(); + final Bundle bundle = new Bundle(); bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_favorite_failed)); msg.setData(bundle); } @@ -1216,7 +1195,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc */ private class FavoriteAddClickListener extends AbstractWatchlistClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { doExecute(R.string.cache_dialog_favorite_add_title, R.string.cache_dialog_favorite_add_message, new FavoriteAddThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress))); @@ -1228,7 +1207,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc */ private class FavoriteRemoveClickListener extends AbstractWatchlistClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { doExecute(R.string.cache_dialog_favorite_remove_title, R.string.cache_dialog_favorite_remove_message, new FavoriteRemoveThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress))); @@ -1240,7 +1219,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc */ private class ChangeListClickListener implements View.OnClickListener { @Override - public void onClick(View view) { + public void onClick(final View view) { new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title, new Action1<Integer>() { @Override @@ -1257,7 +1236,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc * @param listId * the ID of the list */ - public void switchListById(int listId) { + public void switchListById(final int listId) { if (listId < 0) { return; } @@ -1360,7 +1339,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - private Observable<BitmapDrawable> previewMap = Observable.create(new OnSubscribe<BitmapDrawable>() { + private final Observable<BitmapDrawable> previewMap = Observable.create(new OnSubscribe<BitmapDrawable>() { @Override public void call(final Subscriber<? super BitmapDrawable> subscriber) { try { @@ -1369,7 +1348,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc if (image == null) { if (Settings.isStoreOfflineMaps() && cache.getCoords() != null) { - StaticMapsProvider.storeCachePreviewMap(cache); + RxUtils.waitForCompletion(StaticMapsProvider.storeCachePreviewMap(cache)); image = StaticMapsProvider.getPreviewMap(cache); } } @@ -1417,7 +1396,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc showDesc.setVisibility(View.VISIBLE); showDesc.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { loadLongDescription(); } }); @@ -1427,16 +1406,13 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // cache personal note setPersonalNote(personalNoteView, cache.getPersonalNote()); personalNoteView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); - registerForContextMenu(personalNoteView); + addContextMenu(personalNoteView); final Button personalNoteEdit = (Button) view.findViewById(R.id.edit_personalnote); personalNoteEdit.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { - if (cache.isOffline()) { - editPersonalNote(cache, CacheDetailActivity.this); - } else { - warnPersonalNoteNeedsStoring(); - } + public void onClick(final View v) { + ensureSaved(); + editPersonalNote(cache, CacheDetailActivity.this); } }); final Button personalNoteUpload = (Button) view.findViewById(R.id.upload_personalnote); @@ -1444,7 +1420,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc personalNoteUpload.setVisibility(View.VISIBLE); personalNoteUpload.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { + public void onClick(final View v) { if (StringUtils.length(cache.getPersonalNote()) > GCConstants.PERSONAL_NOTE_MAX_CHARS) { warnPersonalNoteExceedsLimit(); } else { @@ -1478,7 +1454,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc hintView.setOnClickListener(new DecryptTextClickListener(hintView)); hintBoxView.setOnClickListener(new DecryptTextClickListener(hintView)); hintBoxView.setClickable(true); - registerForContextMenu(hintView); + addContextMenu(hintView); } else { hintView.setVisibility(View.GONE); hintView.setClickable(false); @@ -1493,7 +1469,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc spoilerlinkView.setClickable(true); spoilerlinkView.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { if (cache == null || CollectionUtils.isEmpty(cache.getSpoilers())) { showToast(res.getString(R.string.err_detail_no_spoiler)); return; @@ -1516,7 +1492,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private void uploadPersonalNote() { final SimpleCancellableHandler myHandler = new SimpleCancellableHandler(CacheDetailActivity.this, progress); - Message cancelMessage = myHandler.cancelMessage(res.getString(R.string.cache_personal_note_upload_cancelled)); + final Message cancelMessage = myHandler.cancelMessage(res.getString(R.string.cache_personal_note_upload_cancelled)); progress.show(CacheDetailActivity.this, res.getString(R.string.cache_personal_note_uploading), res.getString(R.string.cache_personal_note_uploading), true, cancelMessage); if (currentThread != null) { @@ -1533,30 +1509,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final String longDescription = cache.getDescription(); loadDescription(longDescription, longDescView, loadingView); - - // Hide the short description, if it is contained somewhere at the start of the long description. - if (shortDescView != null) { - final String shortDescription = cache.getShortDescription(); - if (StringUtils.isNotBlank(shortDescription)) { - final int index = longDescription.indexOf(shortDescription); - if (index >= 0 && index < 200) { - shortDescView.setVisibility(View.GONE); - } - } - } - } - - private void warnPersonalNoteNeedsStoring() { - Dialogs.confirm(CacheDetailActivity.this, R.string.cache_personal_note_unstored, R.string.cache_personal_note_store, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - storeCache(StoredList.STANDARD_LIST_ID, new StoreCachePersonalNoteHandler(CacheDetailActivity.this, progress)); - } - - }); } private void warnPersonalNoteExceedsLimit() { @@ -1564,7 +1516,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { + public void onClick(final DialogInterface dialog, final int which) { dialog.dismiss(); uploadPersonalNote(); } @@ -1621,7 +1573,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } }); - AndroidObservable.bindActivity(this, producer).subscribe(new Observer<Spanned>() { + AndroidObservable.bindActivity(this, producer).subscribeOn(Schedulers.io()).subscribe(new Observer<Spanned>() { @Override public void onCompleted() { if (null != loadingIndicatorView) { @@ -1648,7 +1600,8 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc descriptionView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); fixTextColor(descriptionString); descriptionView.setVisibility(View.VISIBLE); - registerForContextMenu(descriptionView); + addContextMenu(descriptionView); + potentiallyHideShortDescription(); } } @@ -1684,7 +1637,36 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } descriptionView.setBackgroundResource(backcolor); } - }, Schedulers.io()); + }); + } + + /** + * Hide the short description, if it is contained somewhere at the start of the long description. + */ + public void potentiallyHideShortDescription() { + final View shortView = ButterKnife.findById(this, R.id.shortdesc); + if (shortView == null) { + return; + } + if (shortView.getVisibility() == View.GONE) { + return; + } + final String shortDescription = cache.getShortDescription(); + if (StringUtils.isNotBlank(shortDescription)) { + final int index = StringUtils.indexOf(cache.getDescription(), shortDescription); + // allow up to 200 characters of HTML formatting + if (index >= 0 && index < 200) { + shortView.setVisibility(View.GONE); + } + } + } + + private void ensureSaved() { + if (!cache.isOffline()) { + showToast(getString(R.string.info_cache_saved)); + cache.setListId(StoredList.STANDARD_LIST_ID); + DataStore.saveCache(cache, LoadFlags.SAVE_ALL); + } } private class WaypointsViewCreator extends AbstractCachingPageViewCreator<ListView> { @@ -1703,12 +1685,13 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc view = (ListView) getLayoutInflater().inflate(R.layout.cachedetail_waypoints_page, null); view.setClickable(true); - View addWaypointButton = getLayoutInflater().inflate(R.layout.cachedetail_waypoints_footer, null); + final View addWaypointButton = getLayoutInflater().inflate(R.layout.cachedetail_waypoints_footer, null); view.addFooterView(addWaypointButton); addWaypointButton.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { + public void onClick(final View v) { + ensureSaved(); EditWaypointActivity.startActivityAddWaypoint(CacheDetailActivity.this, cache); refreshOnResume = true; } @@ -1716,7 +1699,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc view.setAdapter(new ArrayAdapter<Waypoint>(CacheDetailActivity.this, R.layout.waypoint_item, sortedWaypoints) { @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(final int position, final View convertView, final ViewGroup parent) { View rowView = convertView; if (null == rowView) { rowView = getLayoutInflater().inflate(R.layout.waypoint_item, null); @@ -1737,7 +1720,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc return view; } - protected void fillViewHolder(View rowView, final WaypointViewHolder holder, final Waypoint wpt) { + protected void fillViewHolder(final View rowView, final WaypointViewHolder holder, final Waypoint wpt) { // coordinates final TextView coordinatesView = holder.coordinatesView; if (null != wpt.getCoords()) { @@ -1800,22 +1783,22 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final View wpNavView = holder.wpNavView; wpNavView.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { + public void onClick(final View v) { NavigationAppFactory.startDefaultNavigationApplication(1, CacheDetailActivity.this, wpt); } }); wpNavView.setOnLongClickListener(new View.OnLongClickListener() { @Override - public boolean onLongClick(View v) { + public boolean onLongClick(final View v) { NavigationAppFactory.startDefaultNavigationApplication(2, CacheDetailActivity.this, wpt); return true; } }); - registerForContextMenu(rowView); + addContextMenu(rowView); rowView.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { + public void onClick(final View v) { selectedWaypoint = wpt; openContextMenu(v); } @@ -1823,8 +1806,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc rowView.setOnLongClickListener(new View.OnLongClickListener() { @Override - public boolean onLongClick(View v) { + public boolean onLongClick(final View v) { selectedWaypoint = wpt; + ensureSaved(); EditWaypointActivity.startActivityEditWaypoint(CacheDetailActivity.this, cache, wpt.getId()); refreshOnResume = true; return true; @@ -1836,7 +1820,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final WaypointType waypointType = wpt.getWaypointType(); final Drawable icon; if (wpt.isVisited()) { - LayerDrawable ld = new LayerDrawable(new Drawable[] { + final LayerDrawable ld = new LayerDrawable(new Drawable[] { res.getDrawable(waypointType.markerId), res.getDrawable(R.drawable.tick) }); ld.setLayerInset(0, 0, 0, VISITED_INSET, VISITED_INSET); @@ -1865,7 +1849,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc view.setAdapter(new ArrayAdapter<Trackable>(CacheDetailActivity.this, R.layout.simple_list_item_1, cache.getInventory())); view.setOnItemClickListener(new OnItemClickListener() { @Override - public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { + public void onItemClick(final AdapterView<?> arg0, final View arg1, final int arg2, final long arg3) { final Object selection = arg0.getItemAtPosition(arg2); if (selection instanceof Trackable) { final Trackable trackable = (Trackable) selection; @@ -1901,6 +1885,86 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc context.startActivity(cachesIntent); } + public void addContextMenu(final View view) { + view.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(final View v) { + startSupportActionMode(new ActionMode.Callback() { + + @Override + public boolean onPrepareActionMode(final ActionMode actionMode, final Menu menu) { + switch (view.getId()) { + case R.id.value: // coordinates, gc-code, name + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + final CharSequence itemTitle = ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, itemTitle, true); + return true; + case R.id.shortdesc: + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_description), false); + return true; + case R.id.longdesc: + assert view instanceof TextView; + // combine short and long description + final String shortDesc = cache.getShortDescription(); + if (StringUtils.isBlank(shortDesc)) { + clickedItemText = ((TextView) view).getText(); + } else { + clickedItemText = shortDesc + "\n\n" + ((TextView) view).getText(); + } + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_description), false); + return true; + case R.id.personalnote: + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_personal_note), true); + return true; + case R.id.hint: + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_hint), false); + return true; + case R.id.log: + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_logs), false); + return true; + case R.id.date: // event date + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_event), true); + menu.findItem(R.id.menu_calendar).setVisible(cache.canBeAddedToCalendar()); + return true; + } + return false; + } + + @Override + public void onDestroyActionMode(final ActionMode actionMode) { + // do nothing + } + + @Override + public boolean onCreateActionMode(final ActionMode actionMode, final Menu menu) { + actionMode.getMenuInflater().inflate(R.menu.details_context, menu); + + // Return true so that the action mode is shown + return true; + } + + @Override + public boolean onActionItemClicked(final ActionMode actionMode, final MenuItem menuItem) { + return onClipboardItemSelected(actionMode, menuItem, clickedItemText); + } + }); + return false; + } + }); + } + public static void startActivityGuid(final Context context, final String guid, final String cacheName) { final Intent cacheIntent = new Intent(context, CacheDetailActivity.class); cacheIntent.putExtra(Intents.EXTRA_GUID, guid); @@ -1920,7 +1984,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, final int which) { + public void onClick(final DialogInterface dialog, final int which) { dialog.dismiss(); final ProgressDialog progressDialog = ProgressDialog.show(CacheDetailActivity.this, getString(R.string.cache), getString(R.string.waypoint_reset), true); final HandlerResetCoordinates handler = new HandlerResetCoordinates(CacheDetailActivity.this, progressDialog, which == 1); @@ -1936,14 +2000,14 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private final ProgressDialog progressDialog; private final boolean resetRemote; - protected HandlerResetCoordinates(CacheDetailActivity activity, ProgressDialog progressDialog, boolean resetRemote) { + protected HandlerResetCoordinates(final CacheDetailActivity activity, final ProgressDialog progressDialog, final boolean resetRemote) { super(activity); this.progressDialog = progressDialog; this.resetRemote = resetRemote; } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { if (msg.what == ResetCoordsThread.LOCAL) { localFinished = true; } else { @@ -1972,7 +2036,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc public static final int LOCAL = 0; public static final int ON_WEBSITE = 1; - public ResetCoordsThread(Geocache cache, Handler handler, final Waypoint wpt, boolean local, boolean remote, final ProgressDialog progress) { + public ResetCoordsThread(final Geocache cache, final Handler handler, final Waypoint wpt, final boolean local, final boolean remote, final ProgressDialog progress) { this.cache = cache; this.handler = handler; this.local = local; @@ -2032,19 +2096,19 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private Geocache cache = null; private CancellableHandler handler = null; - public UploadPersonalNoteThread(Geocache cache, CancellableHandler handler) { + public UploadPersonalNoteThread(final Geocache cache, final CancellableHandler handler) { this.cache = cache; this.handler = handler; } @Override public void run() { - IConnector con = ConnectorFactory.getConnector(cache); + final IConnector con = ConnectorFactory.getConnector(cache); if (con.supportsPersonalNote()) { con.uploadPersonalNote(cache); } - Message msg = Message.obtain(); - Bundle bundle = new Bundle(); + final Message msg = Message.obtain(); + final Bundle bundle = new Bundle(); bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.cache_personal_note_upload_done)); msg.setData(bundle); handler.sendMessage(msg); @@ -2052,7 +2116,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override - protected String getTitle(Page page) { + protected String getTitle(final Page page) { // show number of waypoints directly in waypoint title if (page == Page.WAYPOINTS) { final int waypointCount = cache.getWaypoints().size(); @@ -2084,7 +2148,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override - protected AbstractViewPagerActivity.PageViewCreator createViewCreator(Page page) { + protected AbstractViewPagerActivity.PageViewCreator createViewCreator(final Page page) { switch (page) { case DETAILS: return new DetailsViewCreator(); @@ -2112,9 +2176,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } static void updateOfflineBox(final View view, final Geocache cache, final Resources res, - final OnClickListener refreshCacheClickListener, - final OnClickListener dropCacheClickListener, - final OnClickListener storeCacheClickListener) { + final OnClickListener refreshCacheClickListener, + final OnClickListener dropCacheClickListener, + final OnClickListener storeCacheClickListener) { // offline use final TextView offlineText = (TextView) view.findViewById(R.id.offline_text); final Button offlineRefresh = (Button) view.findViewById(R.id.offline_refresh); @@ -2160,12 +2224,12 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private static class StoreCacheHandler extends SimpleCancellableHandler { - public StoreCacheHandler(CacheDetailActivity activity, Progress progress) { + public StoreCacheHandler(final CacheDetailActivity activity, final Progress progress) { super(activity, progress); } @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { updateStatusMsg(R.string.cache_dialog_offline_save_message, (String) msg.obj); } else { @@ -2176,12 +2240,12 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private static final class RefreshCacheHandler extends SimpleCancellableHandler { - public RefreshCacheHandler(CacheDetailActivity activity, Progress progress) { + public RefreshCacheHandler(final CacheDetailActivity activity, final Progress progress) { super(activity, progress); } @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { updateStatusMsg(R.string.cache_dialog_refresh_message, (String) msg.obj); } else { @@ -2192,24 +2256,24 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private static final class ChangeNotificationHandler extends SimpleHandler { - public ChangeNotificationHandler(CacheDetailActivity activity, Progress progress) { + public ChangeNotificationHandler(final CacheDetailActivity activity, final Progress progress) { super(activity, progress); } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { notifyDatasetChanged(activityRef); } } private static final class SimpleUpdateHandler extends SimpleHandler { - public SimpleUpdateHandler(CacheDetailActivity activity, Progress progress) { + public SimpleUpdateHandler(final CacheDetailActivity activity, final Progress progress) { super(activity, progress); } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { if (msg.what == MESSAGE_FAILED) { super.handleMessage(msg); } else { @@ -2218,8 +2282,8 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - private static void notifyDatasetChanged(WeakReference<AbstractActivity> activityRef) { - CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get()); + private static void notifyDatasetChanged(final WeakReference<AbstractActivity> activityRef) { + final CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get()); if (activity != null) { activity.notifyDataSetChanged(); } @@ -2227,42 +2291,22 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc protected void storeCache(final int listId, final StoreCacheHandler storeCacheHandler) { progress.show(this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage()); - Schedulers.io().schedule(new Action1<Inner>() { + Schedulers.io().createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { cache.store(listId, storeCacheHandler); } }); } - private static final class StoreCachePersonalNoteHandler extends StoreCacheHandler { - - public StoreCachePersonalNoteHandler(CacheDetailActivity activity, Progress progress) { - super(activity, progress); - } - - @Override - public void handleRegularMessage(Message msg) { - if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { - updateStatusMsg(R.string.cache_dialog_offline_save_message, (String) msg.obj); - } else { - dismissProgress(); - CacheDetailActivity activity = (CacheDetailActivity) activityRef.get(); - if (activity != null) { - editPersonalNote(activity.getCache(), activity); - } - } - } - } - public static void editPersonalNote(final Geocache cache, final CacheDetailActivity activity) { if (cache.isOffline()) { - EditNoteDialogListener editNoteDialogListener = new EditNoteDialogListener() { + final EditNoteDialogListener editNoteDialogListener = new EditNoteDialogListener() { @Override public void onFinishEditNoteDialog(final String note) { cache.setPersonalNote(note); cache.parseWaypointsFromNote(); - TextView personalNoteView = (TextView) activity.findViewById(R.id.personalnote); + final TextView personalNoteView = (TextView) activity.findViewById(R.id.personalnote); setPersonalNote(personalNoteView, note); DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); activity.notifyDataSetChanged(); diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java index 0aec119..0fd3826 100644 --- a/main/src/cgeo/geocaching/CacheListActivity.java +++ b/main/src/cgeo/geocaching/CacheListActivity.java @@ -18,6 +18,7 @@ import cgeo.geocaching.files.GPXImporter; import cgeo.geocaching.filter.FilterUserInterface; import cgeo.geocaching.filter.IFilter; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.list.AbstractList; import cgeo.geocaching.list.PseudoList; import cgeo.geocaching.list.StoredList; import cgeo.geocaching.loaders.AbstractSearchLoader; @@ -40,6 +41,7 @@ import cgeo.geocaching.sensors.DirectionProvider; import cgeo.geocaching.sensors.GeoDirHandler; import cgeo.geocaching.sensors.IGeoData; import cgeo.geocaching.settings.Settings; +import cgeo.geocaching.settings.SettingsActivity; import cgeo.geocaching.sorting.CacheComparator; import cgeo.geocaching.sorting.ComparatorUserInterface; import cgeo.geocaching.ui.CacheListAdapter; @@ -57,6 +59,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import rx.Subscription; import rx.functions.Action1; @@ -67,8 +70,10 @@ import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.res.Configuration; +import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -77,6 +82,7 @@ import android.os.Message; import android.provider.OpenableColumns; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; +import android.support.v7.app.ActionBar; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.KeyEvent; @@ -160,7 +166,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA dialog.setNegativeButton(res.getString(R.string.license_dismiss), new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int id) { + public void onClick(final DialogInterface dialog, final int id) { Cookies.clearCookies(); dialog.cancel(); } @@ -168,7 +174,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA dialog.setPositiveButton(res.getString(R.string.license_show), new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int id) { + public void onClick(final DialogInterface dialog, final int id) { Cookies.clearCookies(); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/software/agreement.aspx?ID=0"))); } @@ -212,12 +218,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private static class LoadCachesHandler extends WeakReferenceHandler<CacheListActivity> { - protected LoadCachesHandler(CacheListActivity activity) { + protected LoadCachesHandler(final CacheListActivity activity) { super(activity); } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { final CacheListActivity activity = getActivity(); if (activity == null) { return; @@ -252,26 +258,20 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } } + private String getCacheNumberString(final Resources res, final int count) { + return res.getQuantityString(R.plurals.cache_counts, count, count); + } + protected void updateTitle() { - final ArrayList<Integer> numbers = new ArrayList<Integer>(); - if (adapter.isFiltered()) { - numbers.add(adapter.getCount()); - } - if (search != null) { - numbers.add(search.getCount()); - } - if (numbers.isEmpty()) { - setTitle(title); - } - else { - setTitle(title + " [" + StringUtils.join(numbers, '/') + ']'); - } + setTitle(title); + getSupportActionBar().setSubtitle(getCurrentSubtitle()); + refreshSpinnerAdapter(); } private final CancellableHandler loadDetailsHandler = new CancellableHandler() { @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { updateAdapter(); if (msg.what > -1) { @@ -310,7 +310,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA */ private class DownloadFromWebHandler extends CancellableHandler { @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { updateAdapter(); adapter.notifyDataSetChanged(); @@ -348,7 +348,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private final CancellableHandler clearOfflineLogsHandler = new CancellableHandler() { @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { adapter.setSelectMode(false); refreshCurrentList(); @@ -361,7 +361,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private final Handler importGpxAttachementFinishedHandler = new Handler() { @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { refreshCurrentList(); } }; @@ -373,10 +373,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setTheme(); + setContentView(R.layout.cacheslist_activity); // get parameters @@ -396,22 +398,16 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } } - // Add the list selection in code. This way we can leave the XML layout of the action bar the same as for other activities. - final View titleBar = findViewById(R.id.actionbar_title); - titleBar.setClickable(true); - titleBar.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - selectList(); - } - }); - setTitle(title); + initAdapter(); prepareFilterBar(); + if (type.canSwitch) { + initActionBarSpinner(); + } + currentLoader = (AbstractSearchLoader) getSupportLoaderManager().initLoader(type.getLoaderId(), extras, this); // init @@ -427,11 +423,55 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA if (isInvokedFromAttachment()) { importGpxAttachement(); } + + + } + /** + * Action bar spinner adapter. {@code null} for list types that don't allow switching (search results, ...). + */ + CacheListSpinnerAdapter mCacheListSpinnerAdapter; + + /** + * remember current filter when switching between lists, so it can be re-applied afterwards + */ + private IFilter currentFilter = null; + + private void initActionBarSpinner() { + mCacheListSpinnerAdapter = new CacheListSpinnerAdapter(this, R.layout.support_simple_spinner_dropdown_item); + getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); + getSupportActionBar().setDisplayShowTitleEnabled(false); + getSupportActionBar().setListNavigationCallbacks(mCacheListSpinnerAdapter, new ActionBar.OnNavigationListener() { + @Override + public boolean onNavigationItemSelected(final int i, final long l) { + final int newListId = mCacheListSpinnerAdapter.getItem(i).id; + if (newListId != listId) { + switchListById(newListId); + } + return true; + } + }); + } + + private void refreshSpinnerAdapter() { + /* If the activity does not use the Spinner this will be null */ + if (mCacheListSpinnerAdapter==null) { + return; + } + mCacheListSpinnerAdapter.clear(); + + final AbstractList list = AbstractList.getListById(listId); + + for (final AbstractList l: StoredList.UserInterface.getMenuLists(false, PseudoList.NEW_LIST.id)) { + mCacheListSpinnerAdapter.add(l); + } + + getSupportActionBar().setSelectedNavigationItem(mCacheListSpinnerAdapter.getPosition(list)); + } @Override - public void onConfigurationChanged(Configuration newConfig) { + public void onConfigurationChanged(final Configuration newConfig) { super.onConfigurationChanged(newConfig); if (currentLoader != null && currentLoader.isLoading()) { showFooterLoadingCaches(); @@ -452,7 +492,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA new StoredList.UserInterface(this).promptForListSelection(R.string.gpx_import_select_list_title, new Action1<Integer>() { @Override - public void call(Integer listId) { + public void call(final Integer listId) { new GPXImporter(CacheListActivity.this, listId, importGpxAttachementFinishedHandler).importGPX(); switchListById(listId); } @@ -499,7 +539,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.cache_list_options, menu); CacheListAppFactory.addMenuItems(menu, this, res); @@ -512,7 +552,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(final Menu menu) { super.onPrepareOptionsMenu(menu); final boolean isHistory = type == CacheListType.HISTORY; @@ -532,18 +572,19 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA setVisible(menu, R.id.menu_switch_select_mode, !isEmpty); setVisible(menu, R.id.submenu_manage, (isHistory && !isEmpty) || isOffline); - setVisible(menu, R.id.submenu_manage_lists, isOffline); + + setVisible(menu, R.id.menu_create_list, isOffline); setVisible(menu, R.id.menu_sort, !isEmpty && !isHistory); setVisible(menu, R.id.menu_refresh_stored, !isEmpty && (isConcrete || type != CacheListType.OFFLINE)); setVisible(menu, R.id.menu_drop_caches, !isEmpty && isOffline); setVisible(menu, R.id.menu_drop_caches_and_list, isConcrete && !isEmpty && isOffline); - setVisible(menu, R.id.menu_delete_events, isConcrete && !isEmpty && containsEvents()); + setVisible(menu, R.id.menu_delete_events, isConcrete && !isEmpty && containsPastEvents()); setVisible(menu, R.id.menu_move_to_list, isOffline && !isEmpty); setVisible(menu, R.id.menu_export, !isEmpty && (isHistory || isOffline)); setVisible(menu, R.id.menu_remove_from_history, !isEmpty && isHistory); setVisible(menu, R.id.menu_clear_offline_logs, !isEmpty && containsOfflineLogs() && (isHistory || isOffline)); - setVisible(menu, R.id.menu_import_web, isOffline && Settings.getWebDeviceCode() != null); + setVisible(menu, R.id.menu_import_web, isOffline); setVisible(menu, R.id.menu_import_gpx, isOffline); setVisible(menu, R.id.menu_refresh_stored_top, !isOffline && !isEmpty); @@ -568,13 +609,11 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA menu.findItem(R.id.menu_drop_list).setVisible(isNonDefaultList); menu.findItem(R.id.menu_rename_list).setVisible(isNonDefaultList); - final boolean multipleLists = DataStore.getLists().size() >= 2; - menu.findItem(R.id.menu_switch_list).setVisible(multipleLists); menu.findItem(R.id.menu_move_to_list).setVisible(!isEmpty); setMenuItemLabel(menu, R.id.menu_remove_from_history, R.string.cache_remove_from_history, R.string.cache_clear_history); setMenuItemLabel(menu, R.id.menu_export, R.string.export, R.string.export); - menu.findItem(R.id.menu_import_android).setVisible(Compatibility.isStorageAccessFrameworkAvailable()); + menu.findItem(R.id.menu_import_android).setVisible(Compatibility.isStorageAccessFrameworkAvailable() && isOffline); } catch (final RuntimeException e) { Log.e("CacheListActivity.onPrepareOptionsMenu", e); } @@ -582,9 +621,9 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA return true; } - private boolean containsEvents() { + private boolean containsPastEvents() { for (final Geocache cache : adapter.getCheckedOrAllCaches()) { - if (cache.isEventCache()) { + if (DateUtils.isPastEvent(cache)) { return true; } } @@ -614,8 +653,14 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { + if (super.onOptionsItemSelected(item)) { + return true; + } switch (item.getItemId()) { + case R.id.menu_show_on_map: + goMap(); + return true; case R.id.menu_switch_select_mode: adapter.switchSelectMode(); invalidateOptionsMenuCompatible(); @@ -643,6 +688,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA return false; case R.id.menu_create_list: new StoredList.UserInterface(this).promptForListCreation(getListSwitchingRunnable(), newListName); + refreshSpinnerAdapter(); invalidateOptionsMenuCompatible(); return false; case R.id.menu_drop_list: @@ -656,10 +702,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA adapter.invertSelection(); invalidateOptionsMenuCompatible(); return false; - case R.id.menu_switch_list: - selectList(); - invalidateOptionsMenuCompatible(); - return false; case R.id.menu_filter: showFilterMenu(null); return true; @@ -667,7 +709,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA final CacheComparator oldComparator = adapter.getCacheComparator(); new ComparatorUserInterface(this).selectComparator(oldComparator, new Action1<CacheComparator>() { @Override - public void call(CacheComparator selectedComparator) { + public void call(final CacheComparator selectedComparator) { // selecting the same sorting twice will toggle the order if (selectedComparator != null && oldComparator != null && selectedComparator.getClass().equals(oldComparator.getClass())) { adapter.toggleInverseSort(); @@ -750,13 +792,8 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA public void showFilterMenu(final View view) { new FilterUserInterface(this).selectFilter(new Action1<IFilter>() { @Override - public void call(IFilter selectedFilter) { - if (selectedFilter != null) { - setFilter(selectedFilter); - } else { - // clear filter - setFilter(null); - } + public void call(@Nullable final IFilter selectedFilter) { + setFilter(selectedFilter); } }); } @@ -806,7 +843,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new Action1<Integer>() { @Override - public void call(Integer newListId) { + public void call(final Integer newListId) { DataStore.moveToList(adapter.getCheckedOrAllCaches(), newListId); adapter.setSelectMode(false); @@ -816,7 +853,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public boolean onContextItemSelected(MenuItem item) { + public boolean onContextItemSelected(final MenuItem item) { ContextMenu.ContextMenuInfo info = item.getMenuInfo(); // restore menu info for sub menu items, see @@ -853,7 +890,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA case R.id.menu_drop_cache: cache.drop(new Handler() { @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { adapter.notifyDataSetChanged(); refreshCurrentList(); } @@ -863,7 +900,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new Action1<Integer>() { @Override - public void call(Integer newListId) { + public void call(final Integer newListId) { DataStore.moveToList(Collections.singletonList(cache), newListId); adapter.setSelectMode(false); refreshCurrentList(); @@ -904,7 +941,8 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA return adapter.findCacheByGeocode(contextMenuGeocode); } - private boolean setFilter(IFilter filter) { + private boolean setFilter(final IFilter filter) { + currentFilter = filter; adapter.setFilter(filter); prepareFilterBar(); updateTitle(); @@ -913,7 +951,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { + public boolean onKeyDown(final int keyCode, final KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (adapter.isSelectMode()) { adapter.setSelectMode(false); @@ -927,12 +965,15 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA final ListView list = getListView(); registerForContextMenu(list); adapter = new CacheListAdapter(this, cacheList, type); + adapter.setFilter(currentFilter); - listFooter = getLayoutInflater().inflate(R.layout.cacheslist_footer, null); - listFooter.setClickable(true); - listFooter.setOnClickListener(new MoreCachesListener()); - listFooterText = (TextView) listFooter.findViewById(R.id.more_caches); - list.addFooterView(listFooter); + if (listFooter == null) { + listFooter = getLayoutInflater().inflate(R.layout.cacheslist_footer, null); + listFooter.setClickable(true); + listFooter.setOnClickListener(new MoreCachesListener()); + listFooterText = (TextView) listFooter.findViewById(R.id.more_caches); + list.addFooterView(listFooter); + } setListAdapter(adapter); adapter.forceSort(); } @@ -975,7 +1016,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_IMPORT_GPX && resultCode == Activity.RESULT_OK) { @@ -991,7 +1032,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA refreshCurrentList(); } - private String getDisplayName(Uri uri) { + private String getDisplayName(final Uri uri) { Cursor cursor = null; try { cursor = getContentResolver().query(uri, new String[] { OpenableColumns.DISPLAY_NAME }, null, null, null); @@ -1017,21 +1058,25 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA return; } - if (Settings.getChooseList() && type != CacheListType.OFFLINE) { + if (Settings.getChooseList() && (type != CacheListType.OFFLINE && type != CacheListType.HISTORY)) { // let user select list to store cache in new StoredList.UserInterface(this).promptForListSelection(R.string.list_title, new Action1<Integer>() { @Override public void call(final Integer selectedListId) { - refreshStored(caches, selectedListId); + // in case of online lists, set the list id to a concrete list now + for (final Geocache geocache : caches) { + geocache.setListId(selectedListId); + } + refreshStoredInternal(caches); } }, true, StoredList.TEMPORARY_LIST_ID, newListName); } else { - refreshStored(caches, this.listId); + refreshStoredInternal(caches); } } - private void refreshStored(final List<Geocache> caches, final int storeListId) { + private void refreshStoredInternal(final List<Geocache> caches) { detailProgress = 0; showProgress(false); @@ -1049,16 +1094,16 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA detailProgressTime = System.currentTimeMillis(); - final LoadDetailsThread threadDetails = new LoadDetailsThread(loadDetailsHandler, caches, storeListId); + final LoadDetailsThread threadDetails = new LoadDetailsThread(loadDetailsHandler, caches); threadDetails.start(); } public void removeFromHistoryCheck() { - int message = (adapter != null && adapter.getCheckedCount() > 0) ? R.string.cache_remove_from_history + final int message = (adapter != null && adapter.getCheckedCount() > 0) ? R.string.cache_remove_from_history : R.string.cache_clear_history; Dialogs.confirmYesNo(this, R.string.caches_removing_from_history, message, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int id) { + public void onClick(final DialogInterface dialog, final int id) { removeFromHistory(); dialog.cancel(); } @@ -1077,8 +1122,19 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } public void importWeb() { - detailProgress = 0; + // menu is also shown with no device connected + if (Settings.getWebDeviceCode() == null) { + Dialogs.confirm(this, R.string.web_import_title, R.string.init_sendToCgeo_description, new OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + SettingsActivity.openForScreen(R.string.preference_screen_sendtocgeo, CacheListActivity.this); + } + }); + return; + } + + detailProgress = 0; showProgress(false); final DownloadFromWebHandler downloadFromWebHandler = new DownloadFromWebHandler(); progress.show(this, null, res.getString(R.string.web_import_waiting), true, downloadFromWebHandler.cancelMessage()); @@ -1088,18 +1144,18 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } public void dropStored(final boolean removeListAfterwards) { - int message = (adapter.getCheckedCount() > 0) ? R.string.caches_drop_selected_ask : R.string.caches_drop_all_ask; + final int message = (adapter.getCheckedCount() > 0) ? R.string.caches_drop_selected_ask : R.string.caches_drop_all_ask; Dialogs.confirmYesNo(this, R.string.caches_drop_stored, message, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int id) { + public void onClick(final DialogInterface dialog, final int id) { dropSelected(removeListAfterwards); dialog.cancel(); } }); } - public void dropSelected(boolean removeListAfterwards) { + public void dropSelected(final boolean removeListAfterwards) { final List<Geocache> selected = adapter.getCheckedOrAllCaches(); new DropDetailsTask(removeListAfterwards).execute(selected.toArray(new Geocache[selected.size()])); } @@ -1111,15 +1167,11 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private class LoadDetailsThread extends Thread { final private CancellableHandler handler; - final private int listIdLD; final private List<Geocache> caches; - public LoadDetailsThread(CancellableHandler handler, List<Geocache> caches, int listId) { + public LoadDetailsThread(final CancellableHandler handler, final List<Geocache> caches) { this.handler = handler; this.caches = caches; - - // in case of online lists, set the list id to the standard list - this.listIdLD = Math.max(listId, StoredList.STANDARD_LIST_ID); } @Override @@ -1148,13 +1200,13 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA * @return * <code>false</code> if the storing was interrupted, <code>true</code> otherwise */ - private boolean refreshCache(Geocache cache) { + private boolean refreshCache(final Geocache cache) { try { if (handler.isCancelled()) { throw new InterruptedException("Stopped storing process."); } detailProgress++; - cache.refreshSynchronous(listIdLD, null); + cache.refreshSynchronous(null); handler.sendEmptyMessage(cacheList.indexOf(cache)); } catch (final InterruptedException e) { Log.i(e.getMessage()); @@ -1172,7 +1224,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA final private CancellableHandler handler; final private int listIdLFW; - public LoadFromWebThread(CancellableHandler handler, int listId) { + public LoadFromWebThread(final CancellableHandler handler, final int listId) { this.handler = handler; listIdLFW = StoredList.getConcreteList(listId); } @@ -1224,19 +1276,19 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private final boolean removeListAfterwards; - public DropDetailsTask(boolean removeListAfterwards) { + public DropDetailsTask(final boolean removeListAfterwards) { super(CacheListActivity.this, null, res.getString(R.string.caches_drop_progress), true); this.removeListAfterwards = removeListAfterwards; } @Override - protected Void doInBackgroundInternal(Geocache[] caches) { + protected Void doInBackgroundInternal(final Geocache[] caches) { DataStore.markDropped(Arrays.asList(caches)); return null; } @Override - protected void onPostExecuteInternal(Void result) { + protected void onPostExecuteInternal(final Void result) { // remove list in UI because of toast if (removeListAfterwards) { removeList(false); @@ -1254,7 +1306,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA final private Handler handler; final private List<Geocache> selected; - public ClearOfflineLogsThread(Handler handlerIn) { + public ClearOfflineLogsThread(final Handler handlerIn) { handler = handlerIn; selected = adapter.getCheckedOrAllCaches(); } @@ -1269,7 +1321,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private class MoreCachesListener implements View.OnClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { showProgress(true); showFooterLoadingCaches(); listFooter.setOnClickListener(null); @@ -1287,13 +1339,6 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } } - public void selectList() { - if (!type.canSwitch) { - return; - } - new StoredList.UserInterface(this).promptForListSelection(R.string.list_title, getListSwitchingRunnable()); - } - @NonNull private Action1<Integer> getListSwitchingRunnable() { return new Action1<Integer>() { @@ -1305,7 +1350,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA }; } - public void switchListById(int id) { + public void switchListById(final int id) { if (id < 0) { return; } @@ -1323,18 +1368,17 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA listId = list.id; title = list.title; + type = CacheListType.OFFLINE; Settings.saveLastList(listId); + initAdapter(); + showProgress(true); showFooterLoadingCaches(); DataStore.moveToList(adapter.getCheckedCaches(), listId); - currentLoader = (OfflineGeocacheListLoader) getSupportLoaderManager().initLoader(CacheListType.OFFLINE.getLoaderId(), new Bundle(), this); - currentLoader.reset(); - ((OfflineGeocacheListLoader) currentLoader).setListId(listId); - ((OfflineGeocacheListLoader) currentLoader).setSearchCenter(coords); - currentLoader.startLoading(); + currentLoader = (OfflineGeocacheListLoader) getSupportLoaderManager().restartLoader(CacheListType.OFFLINE.getLoaderId(), OfflineGeocacheListLoader.getBundleForList(listId), this); invalidateOptionsMenuCompatible(); } @@ -1352,6 +1396,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA private void removeListInternal() { if (DataStore.removeList(listId)) { showToast(res.getString(R.string.list_dialog_remove_ok)); + refreshSpinnerAdapter(); switchListById(StoredList.STANDARD_LIST_ID); } else { showToast(res.getString(R.string.list_dialog_remove_err)); @@ -1374,17 +1419,13 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA // ask him, if there are caches on the list Dialogs.confirm(this, R.string.list_dialog_remove_title, R.string.list_dialog_remove_description, R.string.list_dialog_remove, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int whichButton) { + public void onClick(final DialogInterface dialog, final int whichButton) { removeListInternal(); } }); } - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void goMap(View view) { + public void goMap() { if (!cacheToShow()) { return; } @@ -1400,6 +1441,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } private void refreshCurrentList() { + refreshSpinnerAdapter(); switchListById(listId); } @@ -1463,7 +1505,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA context.startActivity(cachesIntent); } - public static void startActivityHistory(Context context) { + public static void startActivityHistory(final Context context) { final Intent cachesIntent = new Intent(context, CacheListActivity.class); cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.HISTORY); context.startActivity(cachesIntent); @@ -1487,7 +1529,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA context.startActivity(cachesIntent); } - private static boolean isValidCoords(AbstractActivity context, Geopoint coords) { + private static boolean isValidCoords(final AbstractActivity context, final Geopoint coords) { if (coords == null) { context.showToast(CgeoApplication.getInstance().getString(R.string.warn_no_coordinates)); return false; @@ -1529,7 +1571,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA // Loaders @Override - public Loader<SearchResult> onCreateLoader(int type, Bundle extras) { + public Loader<SearchResult> onCreateLoader(final int type, final Bundle extras) { if (type >= CacheListLoaderType.values().length) { throw new IllegalArgumentException("invalid loader type " + type); } @@ -1562,6 +1604,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA break; case HISTORY: title = res.getString(R.string.caches_history); + listId = PseudoList.HISTORY_LIST.id; loader = new HistoryGeocacheListLoader(app, coords); break; case NEAREST: @@ -1621,7 +1664,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA loader = new PocketGeocacheListLoader(app, guid); break; } - setTitle(title); + updateTitle(); showProgress(true); showFooterLoadingCaches(); @@ -1631,7 +1674,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA return loader; } - private void rememberTerm(String term) { + private void rememberTerm(final String term) { // set the title of the activity title = term; // and remember this term for potential use in list creation @@ -1639,7 +1682,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } @Override - public void onLoadFinished(Loader<SearchResult> arg0, SearchResult searchIn) { + public void onLoadFinished(final Loader<SearchResult> arg0, final SearchResult searchIn) { // The database search was moved into the UI call intentionally. If this is done before the runOnUIThread, // then we have 2 sets of caches in memory. This can lead to OOM for huge cache lists. if (searchIn != null) { @@ -1656,10 +1699,46 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } showProgress(false); hideLoading(); + invalidateOptionsMenuCompatible(); } @Override - public void onLoaderReset(Loader<SearchResult> arg0) { + public void onLoaderReset(final Loader<SearchResult> arg0) { //Not interesting } + + /** + * Allow the title bar spinner to show the same subtitle like the activity itself would show. + * + * @param list + * @return + */ + public CharSequence getCacheListSubtitle(@NonNull final AbstractList list) { + // if this is the current list, be aware of filtering + if (list.id == listId) { + return getCurrentSubtitle(); + } + // otherwise return the overall number + final int numberOfCaches = list.getNumberOfCaches(); + if (numberOfCaches < 0) { + return StringUtils.EMPTY; + } + return getCacheNumberString(getResources(), numberOfCaches); + } + + /** + * Calculate the subtitle of the current list depending on (optional) filters. + * + * @return + */ + private CharSequence getCurrentSubtitle() { + final ArrayList<String> numbers = new ArrayList<String>(); + if (adapter.isFiltered()) { + numbers.add(getCacheNumberString(getResources(), adapter.getCount())); + } + if (search != null) { + numbers.add(getCacheNumberString(getResources(), search.getCount())); + } + return numbers.isEmpty() ? null : StringUtils.join(numbers, '/'); + } } diff --git a/main/src/cgeo/geocaching/CacheListSpinnerAdapter.java b/main/src/cgeo/geocaching/CacheListSpinnerAdapter.java new file mode 100644 index 0000000..6311e47 --- /dev/null +++ b/main/src/cgeo/geocaching/CacheListSpinnerAdapter.java @@ -0,0 +1,68 @@ +package cgeo.geocaching; + +import cgeo.geocaching.list.AbstractList; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +class CacheListSpinnerAdapter extends ArrayAdapter<AbstractList> { + + static class ViewHolder { + TextView title; + TextView subtitle; + } + + private final CacheListActivity cacheListActivity; + + public CacheListSpinnerAdapter(final CacheListActivity context, final int resource) { + super(context, resource); + cacheListActivity = context; + } + + + @Override + public View getView(final int position, final View convertView, final ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + + @Override + public View getDropDownView(final int position, final View convertView, final ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + public View getCustomView(final int position, final View convertView, final ViewGroup parent) { + + View resultView = convertView; + final LayoutInflater inflater = + (LayoutInflater) cacheListActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + + CacheListSpinnerAdapter.ViewHolder holder; + if (resultView == null) { + resultView = inflater.inflate(R.layout.cachelist_spinneritem, parent, false); + holder = new ViewHolder(); + holder.title = (TextView) resultView.findViewById(android.R.id.text1); + holder.subtitle = (TextView) resultView.findViewById(android.R.id.text2); + + resultView.setTag(holder); + } else { + holder = (CacheListSpinnerAdapter.ViewHolder) resultView.getTag(); + } + + final AbstractList list = getItem(position); + holder.title.setText(list.getTitle()); + if (list.getNumberOfCaches() >= 0) { + holder.subtitle.setVisibility(View.VISIBLE); + holder.subtitle.setText(cacheListActivity.getCacheListSubtitle(list)); + } else { + holder.subtitle.setVisibility(View.GONE); + } + + return resultView; + } +}
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/CacheMenuHandler.java b/main/src/cgeo/geocaching/CacheMenuHandler.java index cfe9eeb..5b0fdba 100644 --- a/main/src/cgeo/geocaching/CacheMenuHandler.java +++ b/main/src/cgeo/geocaching/CacheMenuHandler.java @@ -5,7 +5,11 @@ import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.ui.AbstractUIFactory; import android.app.Activity; +import android.support.v4.app.Fragment; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.widget.ShareActionProvider; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; /** @@ -19,7 +23,7 @@ public class CacheMenuHandler extends AbstractUIFactory { * Methods to be implemented by the activity to react to the cache menu selections. * */ - protected interface ActivityInterface { + interface ActivityInterface { public void navigateTo(); public void showNavigationMenu(); @@ -29,8 +33,14 @@ public class CacheMenuHandler extends AbstractUIFactory { } public static boolean onMenuItemSelected(MenuItem item, CacheMenuHandler.ActivityInterface activityInterface, Geocache cache) { - assert activityInterface instanceof Activity; - final Activity activity = (Activity) activityInterface; + assert activityInterface instanceof Activity || activityInterface instanceof Fragment; + final Activity activity; + if (activityInterface instanceof Activity) { + activity = (Activity) activityInterface; + } else { + activity = ((Fragment)activityInterface).getActivity(); + } + switch (item.getItemId()) { case R.id.menu_default_navigation: activityInterface.navigateTo(); @@ -68,10 +78,22 @@ public class CacheMenuHandler extends AbstractUIFactory { menu.findItem(R.id.menu_show_in_browser).setVisible(cache.canOpenInBrowser()); menu.findItem(R.id.menu_default_navigation).setTitle(NavigationAppFactory.getDefaultNavigationApplication().getName()); + + MenuItem shareItem = menu.findItem(R.id.menu_share); + ShareActionProvider shareActionProvider = (ShareActionProvider) + MenuItemCompat.getActionProvider(shareItem); + if(shareActionProvider != null) { + shareActionProvider.setShareIntent(cache.getIntent()); + } + } - public static void addMenuItems(Activity activity, Menu menu, Geocache cache) { - activity.getMenuInflater().inflate(R.menu.cache_options, menu); + public static void addMenuItems(MenuInflater inflater, Menu menu, Geocache cache) { + inflater.inflate(R.menu.cache_options, menu); onPrepareOptionsMenu(menu, cache); } + + public static void addMenuItems(Activity activity, Menu menu, Geocache cache) { + addMenuItems(activity.getMenuInflater(), menu, cache); + } } diff --git a/main/src/cgeo/geocaching/CachePopup.java b/main/src/cgeo/geocaching/CachePopup.java index 543be22..9036d00 100644 --- a/main/src/cgeo/geocaching/CachePopup.java +++ b/main/src/cgeo/geocaching/CachePopup.java @@ -1,203 +1,63 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.Progress; -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.list.StoredList; -import cgeo.geocaching.network.Network; -import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.ui.CacheDetailsCreator; -import cgeo.geocaching.utils.CancellableHandler; -import cgeo.geocaching.utils.Log; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; import org.apache.commons.lang3.StringUtils; -import rx.Scheduler.Inner; -import rx.functions.Action1; -import rx.schedulers.Schedulers; import android.content.Context; import android.content.Intent; -import android.content.res.Configuration; -import android.os.Handler; -import android.os.Message; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.view.Window; -public class CachePopup extends AbstractPopupActivity { - private final Progress progress = new Progress(); +public class CachePopup extends AbstractActivity { - private class StoreCacheHandler extends CancellableHandler { - private final int progressMessage; + protected String geocode = null; - public StoreCacheHandler(final int progressMessage) { - this.progressMessage = progressMessage; - } - - @Override - public void handleRegularMessage(Message msg) { - if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { - updateStatusMsg((String) msg.obj); - } else { - init(); - } - } - private void updateStatusMsg(final String msg) { - progress.setMessage(res.getString(progressMessage) - + "\n\n" - + msg); + void showDialog() { + // DialogFragment.show() will take care of adding the fragment + // in a transaction. We also want to remove any currently showing + // dialog, so make our own transaction and take care of that here. + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog"); + if (prev != null) { + ft.remove(prev); } - } + ft.addToBackStack(null); - private class DropCacheHandler extends Handler { - @Override - public void handleMessage(Message msg) { - CachePopup.this.finish(); - } - } - - public CachePopup() { - super(R.layout.popup); + // Create and show the dialog. + DialogFragment newFragment = CachePopupFragment.newInstance(geocode); + newFragment.show(ft, "dialog"); } @Override - public void showNavigationMenu() { - NavigationAppFactory.showNavigationMenu(this, cache, null, null); - } - - @Override - protected void init() { - super.init(); - try { - if (StringUtils.isNotBlank(cache.getName())) { - setTitle(cache.getName()); - } else { - setTitle(geocode); - } - - // actionbar icon - ((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(cache.getType().markerId), null, null, null); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + supportRequestWindowFeature(Window.FEATURE_NO_TITLE); + this.setTheme(ActivityMixin.getDialogTheme()); - details = new CacheDetailsCreator(this, (LinearLayout) findViewById(R.id.details_list)); - addCacheDetails(); - - // offline use - CacheDetailActivity.updateOfflineBox(findViewById(android.R.id.content), cache, res, new RefreshCacheClickListener(), new DropCacheClickListener(), new StoreCacheClickListener()); - - } catch (Exception e) { - Log.e("CachePopup.init", e); + final Bundle extras = getIntent().getExtras(); + if (extras != null) { + geocode = extras.getString(Intents.EXTRA_GEOCODE); } - // cache is loaded. remove progress-popup if any there - progress.dismiss(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - init(); - } - - private class StoreCacheClickListener implements View.OnClickListener { - @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - if (Settings.getChooseList()) { - // let user select list to store cache in - new StoredList.UserInterface(CachePopup.this).promptForListSelection(R.string.list_title, - new Action1<Integer>() { - @Override - public void call(final Integer selectedListId) { - storeCache(selectedListId); - } - }, true, StoredList.TEMPORARY_LIST_ID); - } else { - storeCache(StoredList.TEMPORARY_LIST_ID); - } - } + if (StringUtils.isBlank(geocode)) { + showToast(res.getString(R.string.err_detail_cache_find)); - protected void storeCache(final int listId) { - final StoreCacheHandler storeCacheHandler = new StoreCacheHandler(R.string.cache_dialog_offline_save_message); - progress.show(CachePopup.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage()); - Schedulers.io().schedule(new Action1<Inner>() { - @Override - public void call(final Inner inner) { - cache.store(listId, storeCacheHandler); - invalidateOptionsMenuCompatible(); - } - }); - } - } - - private class RefreshCacheClickListener implements View.OnClickListener { - @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - if (!Network.isNetworkConnected(getApplicationContext())) { - showToast(getString(R.string.err_server)); - return; - } - - final StoreCacheHandler refreshCacheHandler = new StoreCacheHandler(R.string.cache_dialog_offline_save_message); - progress.show(CachePopup.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, refreshCacheHandler.cancelMessage()); - cache.refresh(cache.getListId(), refreshCacheHandler, Schedulers.io()); - } - } - - private class DropCacheClickListener implements View.OnClickListener { - @Override - public void onClick(View arg0) { - if (progress.isShowing()) { - showToast(res.getString(R.string.err_detail_still_working)); - return; - } - - final DropCacheHandler dropCacheHandler = new DropCacheHandler(); - progress.show(CachePopup.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, null); - cache.drop(dropCacheHandler, Schedulers.io()); - } - } - - @Override - public void navigateTo() { - NavigationAppFactory.startDefaultNavigationApplication(1, this, cache); - } - - /** - * Tries to navigate to the {@link Geocache} of this activity. - */ - @Override - protected void startDefaultNavigation2() { - if (cache == null || cache.getCoords() == null) { - showToast(res.getString(R.string.cache_coordinates_no)); + finish(); return; } - NavigationAppFactory.startDefaultNavigationApplication(2, this, cache); - finish(); + showDialog(); } - public static void startActivity(final Context context, final String geocode) { + public static void startActivity(Context context, String geocode) { final Intent popupIntent = new Intent(context, CachePopup.class); popupIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); context.startActivity(popupIntent); } - - @Override - protected Geopoint getCoordinates() { - if (cache == null) { - return null; - } - return cache.getCoords(); - } } diff --git a/main/src/cgeo/geocaching/CachePopupFragment.java b/main/src/cgeo/geocaching/CachePopupFragment.java new file mode 100644 index 0000000..010d701 --- /dev/null +++ b/main/src/cgeo/geocaching/CachePopupFragment.java @@ -0,0 +1,229 @@ +package cgeo.geocaching; + +import cgeo.geocaching.activity.Progress; +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.list.StoredList; +import cgeo.geocaching.network.Network; +import cgeo.geocaching.settings.Settings; +import cgeo.geocaching.ui.CacheDetailsCreator; +import cgeo.geocaching.utils.CancellableHandler; +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringUtils; + +import rx.functions.Action0; +import rx.functions.Action1; +import rx.schedulers.Schedulers; + +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class CachePopupFragment extends AbstractDialogFragment { + private final Progress progress = new Progress(); + + public static DialogFragment newInstance(String geocode) { + + Bundle args = new Bundle(); + args.putString(GEOCODE_ARG,geocode); + + DialogFragment f = new CachePopupFragment(); + f.setStyle(DialogFragment.STYLE_NO_TITLE,0); + f.setArguments(args); + + return f; + } + + private class StoreCacheHandler extends CancellableHandler { + private final int progressMessage; + + public StoreCacheHandler(final int progressMessage) { + this.progressMessage = progressMessage; + } + + @Override + public void handleRegularMessage(Message msg) { + if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { + updateStatusMsg((String) msg.obj); + } else { + init(); + } + } + + private void updateStatusMsg(final String msg) { + progress.setMessage(res.getString(progressMessage) + + "\n\n" + + msg); + } + } + + private class DropCacheHandler extends Handler { + @Override + public void handleMessage(Message msg) { + getActivity().finish(); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.popup, container, false); + initCustomActionBar(v); + return v; + } + + @Override + protected void init() { + super.init(); + + try { + if (StringUtils.isNotBlank(cache.getName())) { + setTitle(cache.getName()); + } else { + setTitle(geocode); + } + + ((TextView) getView().findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(cache.getType().markerId), null, null, null); + + details = new CacheDetailsCreator(getActivity(), (LinearLayout) getView().findViewById(R.id.details_list)); + + addCacheDetails(); + + // offline use + CacheDetailActivity.updateOfflineBox(getView(), cache, res, new RefreshCacheClickListener(), new DropCacheClickListener(), new StoreCacheClickListener()); + + } catch (Exception e) { + Log.e("CachePopupFragment.init", e); + } + + // cache is loaded. remove progress-popup if any there + progress.dismiss(); + } + + + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + init(); + } + + private class StoreCacheClickListener implements View.OnClickListener { + @Override + public void onClick(View arg0) { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + if (Settings.getChooseList()) { + // let user select list to store cache in + new StoredList.UserInterface(getActivity()).promptForListSelection(R.string.list_title, + new Action1<Integer>() { + @Override + public void call(final Integer selectedListId) { + storeCache(selectedListId); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + storeCache(StoredList.TEMPORARY_LIST_ID); + } + } + + protected void storeCache(final int listId) { + final StoreCacheHandler storeCacheHandler = new StoreCacheHandler(R.string.cache_dialog_offline_save_message); + progress.show(getActivity(), res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage()); + Schedulers.io().createWorker().schedule(new Action0() { + @Override + public void call() { + cache.store(listId, storeCacheHandler); + getActivity().supportInvalidateOptionsMenu(); + } + }); + } + } + + private class RefreshCacheClickListener implements View.OnClickListener { + @Override + public void onClick(View arg0) { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + if (!Network.isNetworkConnected(getActivity())) { + showToast(getString(R.string.err_server)); + return; + } + + final StoreCacheHandler refreshCacheHandler = new StoreCacheHandler(R.string.cache_dialog_offline_save_message); + progress.show(getActivity(), res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, refreshCacheHandler.cancelMessage()); + cache.refresh(refreshCacheHandler, Schedulers.io()); + } + } + + private class DropCacheClickListener implements View.OnClickListener { + @Override + public void onClick(View arg0) { + if (progress.isShowing()) { + showToast(res.getString(R.string.err_detail_still_working)); + return; + } + + final DropCacheHandler dropCacheHandler = new DropCacheHandler(); + progress.show(getActivity(), res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, null); + cache.drop(dropCacheHandler, Schedulers.io()); + } + } + + + @Override + public void navigateTo() { + NavigationAppFactory.startDefaultNavigationApplication(1, getActivity(), cache); + } + + @Override + public void showNavigationMenu() { + // TODO + } + + + /** + * Tries to navigate to the {@link cgeo.geocaching.Geocache} of this activity. + */ + @Override + protected void startDefaultNavigation2() { + if (cache == null || cache.getCoords() == null) { + showToast(res.getString(R.string.cache_coordinates_no)); + return; + } + NavigationAppFactory.startDefaultNavigationApplication(2, getActivity(), cache); + getActivity().finish(); + } + + public static void startActivity(final Context context, final String geocode) { + final Intent popupIntent = new Intent(context, CachePopup.class); + popupIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); + context.startActivity(popupIntent); + } + + @Override + protected Geopoint getCoordinates() { + if (cache == null) { + return null; + } + return cache.getCoords(); + } + + +} diff --git a/main/src/cgeo/geocaching/CgeoApplication.java b/main/src/cgeo/geocaching/CgeoApplication.java index 09aee93..78f3a23 100644 --- a/main/src/cgeo/geocaching/CgeoApplication.java +++ b/main/src/cgeo/geocaching/CgeoApplication.java @@ -3,6 +3,7 @@ package cgeo.geocaching; import cgeo.geocaching.sensors.DirectionProvider; import cgeo.geocaching.sensors.GeoDataProvider; import cgeo.geocaching.sensors.IGeoData; +import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.Log; import rx.Observable; @@ -10,6 +11,12 @@ import rx.functions.Action1; import rx.observables.ConnectableObservable; import android.app.Application; +import android.os.Environment; +import android.view.ViewConfiguration; + +import java.io.IOException; +import java.lang.Thread.UncaughtExceptionHandler; +import java.lang.reflect.Field; public class CgeoApplication extends Application { @@ -22,6 +29,31 @@ public class CgeoApplication extends Application { private volatile IGeoData currentGeo = null; private volatile float currentDirection = 0.0f; + static { + final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + + Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { + + @Override + public void uncaughtException(Thread thread, Throwable ex) { + Log.e("UncaughtException", ex); + Throwable exx = ex; + while (exx.getCause() != null) { + exx = exx.getCause(); + } + if (exx.getClass().equals(OutOfMemoryError.class)) { + try { + Log.e("OutOfMemory"); + android.os.Debug.dumpHprofData(Environment.getExternalStorageDirectory().getPath() + "/dump.hprof"); + } catch (IOException e) { + Log.e("Error writing dump", e); + } + } + defaultHandler.uncaughtException(thread, ex); + } + }); + } + public CgeoApplication() { setInstance(this); } @@ -35,6 +67,24 @@ public class CgeoApplication extends Application { } @Override + public void onCreate() { + if (Settings.isAlwaysShowOverlfowMenu()) { + try { + ViewConfiguration config = ViewConfiguration.get(this); + Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); + + if (menuKeyField != null) { + menuKeyField.setAccessible(true); + menuKeyField.setBoolean(config, false); + } + } catch (Exception ex) { + // Ignore + } + } + } + + + @Override public void onLowMemory() { Log.i("Cleaning applications cache."); DataStore.removeAllFromCache(); @@ -69,7 +119,7 @@ public class CgeoApplication extends Application { } public IGeoData currentGeo() { - return currentGeo != null ? currentGeo : geoDataObservable().toBlockingObservable().first(); + return currentGeo != null ? currentGeo : geoDataObservable().toBlocking().first(); } public float currentDirection() { diff --git a/main/src/cgeo/geocaching/CompassActivity.java b/main/src/cgeo/geocaching/CompassActivity.java index 36dcf27..531e07d 100644 --- a/main/src/cgeo/geocaching/CompassActivity.java +++ b/main/src/cgeo/geocaching/CompassActivity.java @@ -3,7 +3,7 @@ package cgeo.geocaching; import butterknife.ButterKnife; import butterknife.InjectView; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.Units; @@ -38,7 +38,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class CompassActivity extends AbstractActivity { +public class CompassActivity extends AbstractActionBarActivity { private static final int COORDINATES_OFFSET = 10; @@ -69,7 +69,7 @@ public class CompassActivity extends AbstractActivity { private boolean hasMagneticFieldSensor; @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState, R.layout.compass_activity); final SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); @@ -79,7 +79,7 @@ public class CompassActivity extends AbstractActivity { } // get parameters - Bundle extras = getIntent().getExtras(); + final Bundle extras = getIntent().getExtras(); if (extras != null) { final String geocode = extras.getString(EXTRAS_GEOCODE); if (StringUtils.isNotEmpty(geocode)) { @@ -98,7 +98,7 @@ public class CompassActivity extends AbstractActivity { } } } else { - Intent pointIntent = new Intent(this, NavigateAnyPointActivity.class); + final Intent pointIntent = new Intent(this, NavigateAnyPointActivity.class); startActivity(pointIntent); finish(); @@ -129,7 +129,7 @@ public class CompassActivity extends AbstractActivity { } @Override - public void onConfigurationChanged(Configuration newConfig) { + public void onConfigurationChanged(final Configuration newConfig) { super.onConfigurationChanged(newConfig); setContentView(R.layout.compass_activity); @@ -167,7 +167,7 @@ public class CompassActivity extends AbstractActivity { } @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(final Menu menu) { super.onPrepareOptionsMenu(menu); menu.findItem(R.id.menu_switch_compass_gps).setTitle(res.getString(Settings.isUseCompass() ? R.string.use_gps : R.string.use_compass)); menu.findItem(R.id.menu_tts_start).setVisible(!SpeechService.isRunning()); @@ -176,34 +176,36 @@ public class CompassActivity extends AbstractActivity { } @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); + public boolean onOptionsItemSelected(final MenuItem item) { + final int id = item.getItemId(); switch (id) { case R.id.menu_map: CGeoMap.startActivityCoords(this, dstCoords, null, null); return true; case R.id.menu_switch_compass_gps: - boolean oldSetting = Settings.isUseCompass(); + final boolean oldSetting = Settings.isUseCompass(); Settings.setUseCompass(!oldSetting); invalidateOptionsMenuCompatible(); return true; case R.id.menu_edit_destination: - Intent pointIntent = new Intent(this, NavigateAnyPointActivity.class); + final Intent pointIntent = new Intent(this, NavigateAnyPointActivity.class); startActivity(pointIntent); finish(); return true; case R.id.menu_tts_start: SpeechService.startService(this, dstCoords); + invalidateOptionsMenuCompatible(); return true; case R.id.menu_tts_stop: SpeechService.stopService(this); + invalidateOptionsMenuCompatible(); return true; default: if (LoggingUI.onMenuItemSelected(item, this, cache)) { return true; } - int coordinatesIndex = id - COORDINATES_OFFSET; + final int coordinatesIndex = id - COORDINATES_OFFSET; if (coordinatesIndex >= 0 && coordinatesIndex < coordinates.size()) { final IWaypoint coordinate = coordinates.get(coordinatesIndex); title = coordinate.getName(); @@ -217,7 +219,7 @@ public class CompassActivity extends AbstractActivity { return true; } } - return false; + return super.onOptionsItemSelected(item); } private void setTitle() { @@ -255,7 +257,7 @@ public class CompassActivity extends AbstractActivity { headingView.setText(Math.round(cacheHeading) + "°"); } - private GeoDirHandler geoDirHandler = new GeoDirHandler() { + private final GeoDirHandler geoDirHandler = new GeoDirHandler() { @Override public void updateGeoDir(final IGeoData geo, final float dir) { try { @@ -283,7 +285,7 @@ public class CompassActivity extends AbstractActivity { } updateNorthHeading(DirectionProvider.getDirectionNow(dir)); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.w("Failed to LocationUpdater location."); } } @@ -299,7 +301,7 @@ public class CompassActivity extends AbstractActivity { final String info) { coordinates.clear(); if (coordinatesWithType != null) { - for (IWaypoint coordinate : coordinatesWithType) { + for (final IWaypoint coordinate : coordinatesWithType) { if (coordinate != null) { coordinates.add(coordinate); } diff --git a/main/src/cgeo/geocaching/CreateShortcutActivity.java b/main/src/cgeo/geocaching/CreateShortcutActivity.java index b6ea4f6..ffcf81b 100644 --- a/main/src/cgeo/geocaching/CreateShortcutActivity.java +++ b/main/src/cgeo/geocaching/CreateShortcutActivity.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.list.PseudoList; import cgeo.geocaching.list.StoredList; @@ -10,7 +10,7 @@ import android.content.Intent; import android.content.Intent.ShortcutIconResource; import android.os.Bundle; -public class CreateShortcutActivity extends AbstractActivity { +public class CreateShortcutActivity extends AbstractActionBarActivity { @Override public void onCreate(Bundle savedInstanceState) { @@ -27,7 +27,7 @@ public class CreateShortcutActivity extends AbstractActivity { @Override public void call(final Integer listId) { - final Intent shortcut = createShortcut(listId.intValue()); + final Intent shortcut = createShortcut(listId); setResult(RESULT_OK, shortcut); // finish activity to return the shortcut diff --git a/main/src/cgeo/geocaching/DataStore.java b/main/src/cgeo/geocaching/DataStore.java index 32a4b64..bdbb97e 100644 --- a/main/src/cgeo/geocaching/DataStore.java +++ b/main/src/cgeo/geocaching/DataStore.java @@ -16,6 +16,7 @@ import cgeo.geocaching.geopoint.Viewport; import cgeo.geocaching.list.AbstractList; import cgeo.geocaching.list.PseudoList; import cgeo.geocaching.list.StoredList; +import cgeo.geocaching.search.SearchSuggestionCursor; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.ui.dialog.Dialogs; import cgeo.geocaching.utils.FileUtils; @@ -36,7 +37,6 @@ import rx.util.async.Async; import android.app.Activity; import android.app.ProgressDialog; -import android.app.SearchManager; import android.content.ContentValues; import android.content.Context; import android.content.ContextWrapper; @@ -49,7 +49,6 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteDoneException; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; -import android.provider.BaseColumns; import java.io.File; import java.io.FilenameFilter; @@ -57,6 +56,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.EnumSet; import java.util.HashMap; @@ -325,7 +325,7 @@ public class DataStore { final DbHelper dbHelper = new DbHelper(new DBContext(CgeoApplication.getInstance())); try { database = dbHelper.getWritableDatabase(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.init: unable to open database for R/W", e); recreateDatabase(dbHelper); } @@ -347,7 +347,7 @@ public class DataStore { } try { database = dbHelper.getWritableDatabase(); - } catch (Exception f) { + } catch (final Exception f) { Log.e("DataStore.init: unable to recreate database and open it for R/W", f); } } @@ -420,14 +420,14 @@ public class DataStore { init(); return true; } - })).subscribe(new Action1<Boolean>() { + })).subscribeOn(Schedulers.io()).subscribe(new Action1<Boolean>() { @Override public void call(final Boolean success) { dialog.dismiss(); final String message = success ? fromActivity.getString(R.string.init_dbmove_success) : fromActivity.getString(R.string.init_dbmove_failed); Dialogs.message(fromActivity, R.string.init_dbmove_dbmove, message); } - }, Schedulers.io()); + }); } private static File databasePath(final boolean internal) { @@ -464,7 +464,7 @@ public class DataStore { private static class DBContext extends ContextWrapper { - public DBContext(Context base) { + public DBContext(final Context base) { super(base); } @@ -473,8 +473,8 @@ public class DataStore { * causes issues on other devices too. */ @Override - public SQLiteDatabase openOrCreateDatabase(String name, int mode, - CursorFactory factory) { + public SQLiteDatabase openOrCreateDatabase(final String name, final int mode, + final CursorFactory factory) { final File file = new File(name); FileUtils.mkdirs(file.getParentFile()); return SQLiteDatabase.openOrCreateDatabase(file, factory); @@ -486,12 +486,12 @@ public class DataStore { private static boolean firstRun = true; - DbHelper(Context context) { + DbHelper(final Context context) { super(context, databasePath().getPath(), null, dbVersion); } @Override - public void onCreate(SQLiteDatabase db) { + public void onCreate(final SQLiteDatabase db) { newlyCreatedDatabase = true; db.execSQL(dbCreateCaches); db.execSQL(dbCreateLists); @@ -528,7 +528,7 @@ public class DataStore { } @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { Log.i("Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": start"); try { @@ -553,7 +553,7 @@ public class DataStore { db.execSQL(dbCreateSearchDestinationHistory); Log.i("Added table " + dbTableSearchDestionationHistory + "."); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 52", e); } } @@ -563,7 +563,7 @@ public class DataStore { db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer"); Log.i("Column onWatchlist added to " + dbTableCaches + "."); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 53", e); } } @@ -571,7 +571,7 @@ public class DataStore { if (oldVersion < 54) { // update to 54 try { db.execSQL(dbCreateLogImages); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 54", e); } @@ -580,7 +580,7 @@ public class DataStore { if (oldVersion < 55) { // update to 55 try { db.execSQL("alter table " + dbTableCaches + " add column personal_note text"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 55", e); } } @@ -592,7 +592,7 @@ public class DataStore { db.execSQL("update " + dbTableAttributes + " set attribute = " + "lower(attribute) where attribute like \"%_yes\" " + "or attribute like \"%_no\""); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 56", e); } } @@ -607,7 +607,7 @@ public class DataStore { db.execSQL("drop index in_e"); db.execSQL("drop index in_f"); createIndices(db); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 57", e); } } @@ -696,7 +696,7 @@ public class DataStore { db.setTransactionSuccessful(); Log.i("Removed latitude_string and longitude_string columns"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 58", e); } finally { db.endTransaction(); @@ -708,7 +708,7 @@ public class DataStore { // Add new indices and remove obsolete cache files createIndices(db); removeObsoleteCacheDirectories(db); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 59", e); } } @@ -716,7 +716,7 @@ public class DataStore { if (oldVersion < 60) { try { removeSecEmptyDirs(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 60", e); } } @@ -724,7 +724,7 @@ public class DataStore { try { db.execSQL("alter table " + dbTableLogs + " add column friend integer"); db.execSQL("alter table " + dbTableCaches + " add column coordsChanged integer default 0"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 61", e); } @@ -735,7 +735,7 @@ public class DataStore { db.execSQL("alter table " + dbTableCaches + " add column finalDefined integer default 0"); db.execSQL("alter table " + dbTableWaypoints + " add column own integer default 0"); db.execSQL("update " + dbTableWaypoints + " set own = 1 where type = 'own'"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 62", e); } @@ -743,7 +743,7 @@ public class DataStore { if (oldVersion < 63) { try { removeDoubleUnderscoreMapFiles(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 63", e); } @@ -755,7 +755,7 @@ public class DataStore { // rather than symbolic ones because the fix must be applied with the values at the time // of the problem. The problem was introduced in release 2012.06.01. db.execSQL("update " + dbTableCaches + " set reason=1 where reason=2"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 64", e); } } @@ -764,7 +764,7 @@ public class DataStore { try { // Set all waypoints where name is Original coordinates to type ORIGINAL db.execSQL("update " + dbTableWaypoints + " set type='original', own=0 where name='Original Coordinates'"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 65:", e); } } @@ -772,7 +772,7 @@ public class DataStore { if (oldVersion < 66) { try { db.execSQL("alter table " + dbTableWaypoints + " add column visited integer default 0"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 66", e); } @@ -782,7 +782,7 @@ public class DataStore { try { db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_yes' where geocode like 'OC%' and attribute = 'climbing_yes'"); db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_no' where geocode like 'OC%' and attribute = 'climbing_no'"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 67", e); } @@ -791,7 +791,7 @@ public class DataStore { if (oldVersion < 68) { try { db.execSQL("alter table " + dbTableCaches + " add column logPasswordRequired integer default 0"); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Failed to upgrade to ver. 68", e); } @@ -838,7 +838,7 @@ public class DataStore { if (ArrayUtils.isNotEmpty(geocodeDirs)) { final FilenameFilter filter = new FilenameFilter() { @Override - public boolean accept(File dir, String filename) { + public boolean accept(final File dir, final String filename) { return filename.startsWith("map_") && filename.contains("__"); } }; @@ -914,7 +914,7 @@ public class DataStore { } } - private static void dropDatabase(SQLiteDatabase db) { + private static void dropDatabase(final SQLiteDatabase db) { db.execSQL("drop table if exists " + dbTableCaches); db.execSQL("drop table if exists " + dbTableAttributes); db.execSQL("drop table if exists " + dbTableWaypoints); @@ -925,7 +925,7 @@ public class DataStore { db.execSQL("drop table if exists " + dbTableTrackables); } - public static boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { + public static boolean isThere(final String geocode, final String guid, final boolean detailed, final boolean checkTime) { init(); long dataUpdated = 0; @@ -990,7 +990,7 @@ public class DataStore { } /** is cache stored in one of the lists (not only temporary) */ - public static boolean isOffline(String geocode, String guid) { + public static boolean isOffline(final String geocode, final String guid) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { return false; } @@ -1011,16 +1011,16 @@ public class DataStore { listId.bindString(1, value); return listId.simpleQueryForLong() != StoredList.TEMPORARY_LIST_ID; } - } catch (SQLiteDoneException e) { + } catch (final SQLiteDoneException e) { // Do nothing, it only means we have no information on the cache - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.isOffline", e); } return false; } - public static String getGeocodeForGuid(String guid) { + public static String getGeocodeForGuid(final String guid) { if (StringUtils.isBlank(guid)) { return null; } @@ -1032,16 +1032,16 @@ public class DataStore { description.bindString(1, guid); return description.simpleQueryForString(); } - } catch (SQLiteDoneException e) { + } catch (final SQLiteDoneException e) { // Do nothing, it only means we have no information on the cache - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.getGeocodeForGuid", e); } return null; } - public static String getCacheidForGeocode(String geocode) { + public static String getCacheidForGeocode(final String geocode) { if (StringUtils.isBlank(geocode)) { return null; } @@ -1053,9 +1053,9 @@ public class DataStore { description.bindString(1, geocode); return description.simpleQueryForString(); } - } catch (SQLiteDoneException e) { + } catch (final SQLiteDoneException e) { // Do nothing, it only means we have no information on the cache - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.getCacheidForGeocode", e); } @@ -1070,7 +1070,7 @@ public class DataStore { * @param saveFlags * */ - public static void saveCache(Geocache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) { + public static void saveCache(final Geocache cache, final EnumSet<LoadFlags.SaveFlag> saveFlags) { saveCaches(Collections.singletonList(cache), saveFlags); } @@ -1082,7 +1082,7 @@ public class DataStore { * @param saveFlags * */ - public static void saveCaches(Collection<Geocache> caches, EnumSet<LoadFlags.SaveFlag> saveFlags) { + public static void saveCaches(final Collection<Geocache> caches, final EnumSet<LoadFlags.SaveFlag> saveFlags) { if (CollectionUtils.isEmpty(caches)) { return; } @@ -1090,7 +1090,7 @@ public class DataStore { final HashMap<String, Geocache> existingCaches = new HashMap<String, Geocache>(); // first check which caches are in the memory cache - for (Geocache cache : caches) { + for (final Geocache cache : caches) { final String geocode = cache.getGeocode(); final Geocache cacheFromCache = cacheCache.getCacheFromCache(geocode); if (cacheFromCache == null) { @@ -1102,7 +1102,7 @@ public class DataStore { } // then load all remaining caches from the database in one step - for (Geocache cacheFromDatabase : loadCaches(cachesFromDatabase, LoadFlags.LOAD_ALL_DB_ONLY)) { + for (final Geocache cacheFromDatabase : loadCaches(cachesFromDatabase, LoadFlags.LOAD_ALL_DB_ONLY)) { existingCaches.put(cacheFromDatabase.getGeocode(), cacheFromDatabase); } @@ -1113,7 +1113,7 @@ public class DataStore { // (as it may be more recent than the version in the database), or if the // version coming from the database is different than the version we are entering // into the cache (that includes absence from the database). - for (Geocache cache : caches) { + for (final Geocache cache : caches) { final String geocode = cache.getGeocode(); final Geocache existingCache = existingCaches.get(geocode); final boolean dbUpdateRequired = !cache.gatherMissingFrom(existingCache) || cacheCache.getCacheFromCache(geocode) != null; @@ -1127,7 +1127,7 @@ public class DataStore { } } - for (Geocache geocache : toBeStored) { + for (final Geocache geocache : toBeStored) { storeIntoDatabase(geocache); } } @@ -1137,7 +1137,7 @@ public class DataStore { cacheCache.putCacheInCache(cache); Log.d("Saving " + cache.toString() + " (" + cache.getListId() + ") to DB"); - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); if (cache.getUpdated() == 0) { values.put("updated", System.currentTimeMillis()); @@ -1200,7 +1200,7 @@ public class DataStore { saveLogCountsWithoutTransaction(cache); saveInventoryWithoutTransaction(cache.getGeocode(), cache.getInventory()); - int rows = database.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() }); + final int rows = database.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() }); if (rows == 0) { // cache is not in the DB, insert it /* long id = */ @@ -1208,7 +1208,7 @@ public class DataStore { } database.setTransactionSuccessful(); return true; - } catch (Exception e) { + } catch (final Exception e) { Log.e("SaveCache", e); } finally { database.endTransaction(); @@ -1228,7 +1228,7 @@ public class DataStore { if (attributes.isEmpty()) { return; } - SQLiteStatement statement = PreparedStatements.getInsertAttribute(); + final SQLiteStatement statement = PreparedStatements.getInsertAttribute(); final long timestamp = System.currentTimeMillis(); for (final String attribute : attributes) { statement.bindString(1, geocode); @@ -1251,10 +1251,10 @@ public class DataStore { database.beginTransaction(); try { - SQLiteStatement insertDestination = PreparedStatements.getInsertSearchDestination(destination); + final SQLiteStatement insertDestination = PreparedStatements.getInsertSearchDestination(destination); insertDestination.executeInsert(); database.setTransactionSuccessful(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("Updating searchedDestinations db failed", e); } finally { database.endTransaction(); @@ -1269,7 +1269,7 @@ public class DataStore { saveWaypointsWithoutTransaction(cache); database.setTransactionSuccessful(); return true; - } catch (Exception e) { + } catch (final Exception e) { Log.e("saveWaypoints", e); } finally { database.endTransaction(); @@ -1278,14 +1278,14 @@ public class DataStore { } private static void saveWaypointsWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); + final String geocode = cache.getGeocode(); - List<Waypoint> waypoints = cache.getWaypoints(); + final List<Waypoint> waypoints = cache.getWaypoints(); if (CollectionUtils.isNotEmpty(waypoints)) { final ArrayList<String> currentWaypointIds = new ArrayList<String>(); - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (Waypoint oneWaypoint : waypoints) { + final ContentValues values = new ContentValues(); + final long timeStamp = System.currentTimeMillis(); + for (final Waypoint oneWaypoint : waypoints) { values.clear(); values.put("geocode", geocode); @@ -1356,7 +1356,7 @@ public class DataStore { return new Geopoint(cursor.getDouble(indexLat), cursor.getDouble(indexLon)); } - private static boolean saveWaypointInternal(int id, String geocode, Waypoint waypoint) { + private static boolean saveWaypointInternal(final int id, final String geocode, final Waypoint waypoint) { if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { return false; } @@ -1366,7 +1366,7 @@ public class DataStore { database.beginTransaction(); boolean ok = false; try { - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put("geocode", geocode); values.put("updated", System.currentTimeMillis()); values.put("type", waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null); @@ -1394,7 +1394,7 @@ public class DataStore { return ok; } - public static boolean deleteWaypoint(int id) { + public static boolean deleteWaypoint(final int id) { if (id == 0) { return false; } @@ -1405,14 +1405,14 @@ public class DataStore { } private static void saveSpoilersWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); + final String geocode = cache.getGeocode(); database.delete(dbTableSpoilers, "geocode = ?", new String[]{geocode}); - List<Image> spoilers = cache.getSpoilers(); + final List<Image> spoilers = cache.getSpoilers(); if (CollectionUtils.isNotEmpty(spoilers)) { - SQLiteStatement insertSpoiler = PreparedStatements.getInsertSpoiler(); + final SQLiteStatement insertSpoiler = PreparedStatements.getInsertSpoiler(); final long timestamp = System.currentTimeMillis(); - for (Image spoiler : spoilers) { + for (final Image spoiler : spoilers) { insertSpoiler.bindString(1, geocode); insertSpoiler.bindLong(2, timestamp); insertSpoiler.bindString(3, spoiler.getUrl()); @@ -1429,17 +1429,13 @@ public class DataStore { } } - public static void saveLogsWithoutTransaction(final String geocode, final List<LogEntry> logs) { + public static void saveLogsWithoutTransaction(final String geocode, final Iterable<LogEntry> logs) { // TODO delete logimages referring these logs database.delete(dbTableLogs, "geocode = ?", new String[]{geocode}); - if (logs.isEmpty()) { - return; - } - - SQLiteStatement insertLog = PreparedStatements.getInsertLog(); + final SQLiteStatement insertLog = PreparedStatements.getInsertLog(); final long timestamp = System.currentTimeMillis(); - for (LogEntry log : logs) { + for (final LogEntry log : logs) { insertLog.bindString(1, geocode); insertLog.bindLong(2, timestamp); insertLog.bindLong(3, log.type.id); @@ -1448,10 +1444,10 @@ public class DataStore { insertLog.bindLong(6, log.date); insertLog.bindLong(7, log.found); insertLog.bindLong(8, log.friend ? 1 : 0); - long logId = insertLog.executeInsert(); + final long logId = insertLog.executeInsert(); if (log.hasLogImages()) { - SQLiteStatement insertImage = PreparedStatements.getInsertLogImage(); - for (Image img : log.getLogImages()) { + final SQLiteStatement insertImage = PreparedStatements.getInsertLogImage(); + for (final Image img : log.getLogImages()) { insertImage.bindLong(1, logId); insertImage.bindString(2, img.getTitle()); insertImage.bindString(3, img.getUrl()); @@ -1462,15 +1458,15 @@ public class DataStore { } private static void saveLogCountsWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); + final String geocode = cache.getGeocode(); database.delete(dbTableLogCount, "geocode = ?", new String[]{geocode}); - Map<LogType, Integer> logCounts = cache.getLogCounts(); + final Map<LogType, Integer> logCounts = cache.getLogCounts(); if (MapUtils.isNotEmpty(logCounts)) { - Set<Entry<LogType, Integer>> logCountsItems = logCounts.entrySet(); - SQLiteStatement insertLogCounts = PreparedStatements.getInsertLogCounts(); + final Set<Entry<LogType, Integer>> logCountsItems = logCounts.entrySet(); + final SQLiteStatement insertLogCounts = PreparedStatements.getInsertLogCounts(); final long timestamp = System.currentTimeMillis(); - for (Entry<LogType, Integer> pair : logCountsItems) { + for (final Entry<LogType, Integer> pair : logCountsItems) { insertLogCounts.bindString(1, geocode); insertLogCounts.bindLong(2, timestamp); insertLogCounts.bindLong(3, pair.getKey().id); @@ -1499,9 +1495,9 @@ public class DataStore { } if (CollectionUtils.isNotEmpty(trackables)) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (Trackable trackable : trackables) { + final ContentValues values = new ContentValues(); + final long timeStamp = System.currentTimeMillis(); + for (final Trackable trackable : trackables) { final String tbCode = trackable.getGeocode(); if (StringUtils.isNotBlank(tbCode)) { database.delete(dbTableTrackables, "tbcode = ?", new String[] { tbCode }); @@ -1566,12 +1562,12 @@ public class DataStore { return new HashSet<Geocache>(); } - Set<Geocache> result = new HashSet<Geocache>(); - Set<String> remaining = new HashSet<String>(geocodes); + final Set<Geocache> result = new HashSet<Geocache>(); + final Set<String> remaining = new HashSet<String>(geocodes); if (loadFlags.contains(LoadFlag.LOAD_CACHE_BEFORE)) { - for (String geocode : new HashSet<String>(remaining)) { - Geocache cache = cacheCache.getCacheFromCache(geocode); + for (final String geocode : new HashSet<String>(remaining)) { + final Geocache cache = cacheCache.getCacheFromCache(geocode); if (cache != null) { result.add(cache); remaining.remove(cache.getGeocode()); @@ -1595,8 +1591,8 @@ public class DataStore { } if (loadFlags.contains(LoadFlag.LOAD_CACHE_AFTER)) { - for (String geocode : new HashSet<String>(remaining)) { - Geocache cache = cacheCache.getCacheFromCache(geocode); + for (final String geocode : new HashSet<String>(remaining)) { + final Geocache cache = cacheCache.getCacheFromCache(geocode); if (cache != null) { result.add(cache); remaining.remove(cache.getGeocode()); @@ -1638,13 +1634,13 @@ public class DataStore { query.append(" WHERE ").append(dbTableCaches).append('.'); query.append(DataStore.whereGeocodeIn(geocodes)); - Cursor cursor = database.rawQuery(query.toString(), null); + final Cursor cursor = database.rawQuery(query.toString(), null); try { final Set<Geocache> caches = new HashSet<Geocache>(); int logIndex = -1; while (cursor.moveToNext()) { - Geocache cache = DataStore.createCacheFromDatabaseContent(cursor); + final Geocache cache = DataStore.createCacheFromDatabaseContent(cursor); if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) { cache.setAttributes(loadAttributes(cache.getGeocode())); @@ -1718,8 +1714,8 @@ public class DataStore { * @param cursor * @return Cache from DB */ - private static Geocache createCacheFromDatabaseContent(Cursor cursor) { - Geocache cache = new Geocache(); + private static Geocache createCacheFromDatabaseContent(final Cursor cursor) { + final Geocache cache = new Geocache(); cache.setUpdated(cursor.getLong(0)); cache.setListId(cursor.getInt(1)); @@ -1733,7 +1729,7 @@ public class DataStore { cache.setName(cursor.getString(9)); cache.setOwnerDisplayName(cursor.getString(10)); cache.setOwnerUserId(cursor.getString(11)); - long dateValue = cursor.getLong(12); + final long dateValue = cursor.getLong(12); if (dateValue != 0) { cache.setHidden(new Date(dateValue)); } @@ -1779,7 +1775,7 @@ public class DataStore { return cache; } - public static List<String> loadAttributes(String geocode) { + public static List<String> loadAttributes(final String geocode) { if (StringUtils.isBlank(geocode)) { return null; } @@ -1796,7 +1792,7 @@ public class DataStore { GET_STRING_0); } - public static Waypoint loadWaypoint(int id) { + public static Waypoint loadWaypoint(final int id) { if (id == 0) { return null; } @@ -1915,7 +1911,7 @@ public class DataStore { database.delete(dbTableSearchDestionationHistory, null, null); database.setTransactionSuccessful(); return true; - } catch (Exception e) { + } catch (final Exception e) { Log.e("Unable to clear searched destinations", e); } finally { database.endTransaction(); @@ -1929,8 +1925,8 @@ public class DataStore { * @return an immutable, non null list of logs */ @NonNull - public static List<LogEntry> loadLogs(String geocode) { - List<LogEntry> logs = new ArrayList<LogEntry>(); + public static List<LogEntry> loadLogs(final String geocode) { + final List<LogEntry> logs = new ArrayList<LogEntry>(); if (StringUtils.isBlank(geocode)) { return logs; @@ -1967,7 +1963,7 @@ public class DataStore { return Collections.unmodifiableList(logs); } - public static Map<LogType, Integer> loadLogCounts(String geocode) { + public static Map<LogType, Integer> loadLogCounts(final String geocode) { if (StringUtils.isBlank(geocode)) { return null; } @@ -1995,7 +1991,7 @@ public class DataStore { return logCounts; } - private static List<Trackable> loadInventory(String geocode) { + private static List<Trackable> loadInventory(final String geocode) { if (StringUtils.isBlank(geocode)) { return null; } @@ -2056,7 +2052,7 @@ public class DataStore { final String released = cursor.getString(cursor.getColumnIndex("released")); if (released != null) { try { - long releaseMilliSeconds = Long.parseLong(released); + final long releaseMilliSeconds = Long.parseLong(released); trackable.setReleased(new Date(releaseMilliSeconds)); } catch (final NumberFormatException e) { Log.e("createTrackableFromDatabaseContent", e); @@ -2085,7 +2081,7 @@ public class DataStore { init(); try { - StringBuilder sql = new StringBuilder("select count(_id) from " + dbTableCaches + " where detailed = 1"); + final StringBuilder sql = new StringBuilder("select count(_id) from " + dbTableCaches + " where detailed = 1"); String typeKey; int reasonIndex; if (cacheType != CacheType.ALL) { @@ -2106,9 +2102,9 @@ public class DataStore { listKey = "list"; } - String key = "CountCaches_" + typeKey + "_" + listKey; + final String key = "CountCaches_" + typeKey + "_" + listKey; - SQLiteStatement compiledStmnt = PreparedStatements.getStatement(key, sql.toString()); + final SQLiteStatement compiledStmnt = PreparedStatements.getStatement(key, sql.toString()); if (cacheType != CacheType.ALL) { compiledStmnt.bindString(1, cacheType.id); } @@ -2116,7 +2112,7 @@ public class DataStore { compiledStmnt.bindLong(reasonIndex, list); } return (int) compiledStmnt.simpleQueryForLong(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.loadAllStoredCachesCount", e); } @@ -2128,7 +2124,7 @@ public class DataStore { try { return (int) PreparedStatements.getCountHistoryCaches().simpleQueryForLong(); - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.getAllHistoricCachesCount", e); } @@ -2239,7 +2235,7 @@ public class DataStore { null, new HashSet<String>(), GET_STRING_0); - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.loadBatchOfHistoricGeocodes", e); } @@ -2399,7 +2395,7 @@ public class DataStore { cacheCache.removeAllFromCache(); } - public static void removeCache(final String geocode, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + public static void removeCache(final String geocode, final EnumSet<LoadFlags.RemoveFlag> removeFlags) { removeCaches(Collections.singleton(geocode), removeFlags); } @@ -2409,7 +2405,7 @@ public class DataStore { * @param geocodes * list of geocodes to drop from cache */ - public static void removeCaches(final Set<String> geocodes, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + public static void removeCaches(final Set<String> geocodes, final EnumSet<LoadFlags.RemoveFlag> removeFlags) { if (CollectionUtils.isEmpty(geocodes)) { return; } @@ -2457,7 +2453,7 @@ public class DataStore { } } - public static boolean saveLogOffline(String geocode, Date date, LogType type, String log) { + public static boolean saveLogOffline(final String geocode, final Date date, final LogType type, final String log) { if (StringUtils.isBlank(geocode)) { Log.e("DataStore.saveLogOffline: cannot log a blank geocode"); return false; @@ -2484,7 +2480,7 @@ public class DataStore { return id != -1; } - public static LogEntry loadLogOffline(String geocode) { + public static LogEntry loadLogOffline(final String geocode) { if (StringUtils.isBlank(geocode)) { return null; } @@ -2515,7 +2511,7 @@ public class DataStore { return log; } - public static void clearLogOffline(String geocode) { + public static void clearLogOffline(final String geocode) { if (StringUtils.isBlank(geocode)) { return; } @@ -2525,15 +2521,15 @@ public class DataStore { database.delete(dbTableLogsOffline, "geocode = ?", new String[]{geocode}); } - public static void clearLogsOffline(List<Geocache> caches) { + public static void clearLogsOffline(final List<Geocache> caches) { if (CollectionUtils.isEmpty(caches)) { return; } init(); - Set<String> geocodes = new HashSet<String>(caches.size()); - for (Geocache cache : caches) { + final Set<String> geocodes = new HashSet<String>(caches.size()); + for (final Geocache cache : caches) { geocodes.add(cache.getGeocode()); cache.setLogOffline(false); } @@ -2553,14 +2549,14 @@ public class DataStore { logCount.bindString(1, geocode); return logCount.simpleQueryForLong() > 0; } - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.hasLogOffline", e); } return false; } - private static void setVisitDate(List<String> geocodes, long visitedDate) { + private static void setVisitDate(final List<String> geocodes, final long visitedDate) { if (geocodes.isEmpty()) { return; } @@ -2569,9 +2565,9 @@ public class DataStore { database.beginTransaction(); try { - SQLiteStatement setVisit = PreparedStatements.getUpdateVisitDate(); + final SQLiteStatement setVisit = PreparedStatements.getUpdateVisitDate(); - for (String geocode : geocodes) { + for (final String geocode : geocodes) { setVisit.bindLong(1, visitedDate); setVisit.bindString(2, geocode); setVisit.execute(); @@ -2617,10 +2613,10 @@ public class DataStore { }); } - public static StoredList getList(int id) { + public static StoredList getList(final int id) { init(); if (id >= customListIdOffset) { - Cursor cursor = database.query( + final Cursor cursor = database.query( dbTableLists, new String[]{"_id", "title"}, "_id = ? ", @@ -2628,13 +2624,13 @@ public class DataStore { null, null, null); - ArrayList<StoredList> lists = getListsFromCursor(cursor); + final ArrayList<StoredList> lists = getListsFromCursor(cursor); if (!lists.isEmpty()) { return lists.get(0); } } - Resources res = CgeoApplication.getInstance().getResources(); + final Resources res = CgeoApplication.getInstance().getResources(); if (id == PseudoList.ALL_LIST.id) { return new StoredList(PseudoList.ALL_LIST.id, res.getString(R.string.list_all_lists), getAllCachesCount()); } @@ -2658,7 +2654,7 @@ public class DataStore { * Name * @return new listId */ - public static int createList(String name) { + public static int createList(final String name) { int id = -1; if (StringUtils.isBlank(name)) { return id; @@ -2668,7 +2664,7 @@ public class DataStore { database.beginTransaction(); try { - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put("title", name); values.put("updated", System.currentTimeMillis()); @@ -2698,7 +2694,7 @@ public class DataStore { database.beginTransaction(); int count = 0; try { - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put("title", name); values.put("updated", System.currentTimeMillis()); @@ -2717,7 +2713,7 @@ public class DataStore { * @param listId * @return true if the list got deleted, false else */ - public static boolean removeList(int listId) { + public static boolean removeList(final int listId) { if (listId < customListIdOffset) { return false; } @@ -2727,11 +2723,11 @@ public class DataStore { database.beginTransaction(); boolean status = false; try { - int cnt = database.delete(dbTableLists, "_id = " + (listId - customListIdOffset), null); + final int cnt = database.delete(dbTableLists, "_id = " + (listId - customListIdOffset), null); if (cnt > 0) { // move caches from deleted list to standard list - SQLiteStatement moveToStandard = PreparedStatements.getMoveToStandardList(); + final SQLiteStatement moveToStandard = PreparedStatements.getMoveToStandardList(); moveToStandard.bindLong(1, listId); moveToStandard.execute(); @@ -2763,11 +2759,11 @@ public class DataStore { } init(); - SQLiteStatement move = PreparedStatements.getMoveToList(); + final SQLiteStatement move = PreparedStatements.getMoveToList(); database.beginTransaction(); try { - for (Geocache cache : caches) { + for (final Geocache cache : caches) { move.bindLong(1, listId); move.bindString(2, cache.getGeocode()); move.execute(); @@ -2783,7 +2779,7 @@ public class DataStore { return database != null; } - public static boolean removeSearchedDestination(Destination destination) { + public static boolean removeSearchedDestination(final Destination destination) { if (destination == null) { return false; } @@ -2794,7 +2790,7 @@ public class DataStore { database.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null); database.setTransactionSuccessful(); return true; - } catch (Exception e) { + } catch (final Exception e) { Log.e("Unable to remove searched destination", e); } finally { database.endTransaction(); @@ -2839,9 +2835,9 @@ public class DataStore { } cursor.close(); - } catch (SQLiteDoneException e) { + } catch (final SQLiteDoneException e) { // Do nothing, it only means we have no information on the cache - } catch (Exception e) { + } catch (final Exception e) { Log.e("DataStore.getCacheDescription", e); } @@ -2888,13 +2884,14 @@ public class DataStore { * @return */ - public static Set<Waypoint> loadWaypoints(final Viewport viewport, boolean excludeMine, boolean excludeDisabled, CacheType type) { + public static Set<Waypoint> loadWaypoints(final Viewport viewport, final boolean excludeMine, final boolean excludeDisabled, final CacheType type) { final StringBuilder where = buildCoordinateWhere(dbTableWaypoints, viewport); if (excludeMine) { where.append(" and ").append(dbTableCaches).append(".found == 0"); } if (excludeDisabled) { where.append(" and ").append(dbTableCaches).append(".disabled == 0"); + where.append(" and ").append(dbTableCaches).append(".archived == 0"); } if (type != CacheType.ALL) { where.append(" and ").append(dbTableCaches).append(".type == '").append(type.id).append('\''); @@ -2916,7 +2913,7 @@ public class DataStore { }); } - public static void saveChangedCache(Geocache cache) { + public static void saveChangedCache(final Geocache cache) { DataStore.saveCache(cache, cache.getStorageLocation().contains(StorageLocation.DATABASE) ? LoadFlags.SAVE_ALL : EnumSet.of(SaveFlag.SAVE_CACHE)); } @@ -2948,7 +2945,7 @@ public class DataStore { return getStatement("InsertSpoiler", "INSERT INTO " + dbTableSpoilers + " (geocode, updated, url, title, description) VALUES (?, ?, ?, ?, ?)"); } - public static SQLiteStatement getInsertSearchDestination(Destination destination) { + public static SQLiteStatement getInsertSearchDestination(final Destination destination) { final SQLiteStatement statement = getStatement("InsertSearch", "INSERT INTO " + dbTableSearchDestionationHistory + " (date, latitude, longitude) VALUES (?, ?, ?)"); statement.bindLong(1, destination.getDate()); final Geopoint coords = destination.getCoords(); @@ -2958,7 +2955,7 @@ public class DataStore { } private static void clearPreparedStatements() { - for (SQLiteStatement statement : statements.values()) { + for (final SQLiteStatement statement : statements.values()) { statement.close(); } statements.clear(); @@ -3020,11 +3017,11 @@ public class DataStore { setVisitDate(Collections.singletonList(geocode), System.currentTimeMillis()); } - public static void markDropped(List<Geocache> caches) { + public static void markDropped(final List<Geocache> caches) { moveToList(caches, StoredList.TEMPORARY_LIST_ID); } - public static Viewport getBounds(String geocode) { + public static Viewport getBounds(final String geocode) { if (geocode == null) { return null; } @@ -3032,21 +3029,21 @@ public class DataStore { return DataStore.getBounds(Collections.singleton(geocode)); } - public static void clearVisitDate(String[] selected) { + public static void clearVisitDate(final String[] selected) { setVisitDate(Arrays.asList(selected), 0); } - public static SearchResult getBatchOfStoredCaches(Geopoint coords, CacheType cacheType, int listId) { + public static SearchResult getBatchOfStoredCaches(final Geopoint coords, final CacheType cacheType, final int listId) { final Set<String> geocodes = DataStore.loadBatchOfStoredGeocodes(coords, cacheType, listId); return new SearchResult(geocodes, DataStore.getAllStoredCachesCount(cacheType, listId)); } - public static SearchResult getHistoryOfCaches(boolean detailedOnly, CacheType cacheType) { + public static SearchResult getHistoryOfCaches(final boolean detailedOnly, final CacheType cacheType) { final Set<String> geocodes = DataStore.loadBatchOfHistoricGeocodes(detailedOnly, cacheType); return new SearchResult(geocodes, DataStore.getAllHistoryCachesCount()); } - public static boolean saveWaypoint(int id, String geocode, Waypoint waypoint) { + public static boolean saveWaypoint(final int id, final String geocode, final Waypoint waypoint) { if (DataStore.saveWaypointInternal(id, geocode, waypoint)) { DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); return true; @@ -3090,13 +3087,7 @@ public class DataStore { return null; } init(); - final MatrixCursor resultCursor = new MatrixCursor(new String[] { - BaseColumns._ID, - SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2, - SearchManager.SUGGEST_COLUMN_INTENT_ACTION, - SearchManager.SUGGEST_COLUMN_QUERY - }); + final SearchSuggestionCursor resultCursor = new SearchSuggestionCursor(); try { final String selectionArg = getSuggestionArgument(searchTerm); findCaches(resultCursor, selectionArg); @@ -3107,10 +3098,10 @@ public class DataStore { return resultCursor; } - private static void findCaches(final MatrixCursor resultCursor, final String selectionArg) { - Cursor cursor = database.query( + private static void findCaches(final SearchSuggestionCursor resultCursor, final String selectionArg) { + final Cursor cursor = database.query( dbTableCaches, - new String[] { "geocode", "name" }, + new String[] { "geocode", "name", "type" }, "geocode IS NOT NULL AND geocode != '' AND (geocode LIKE ? OR name LIKE ? OR owner LIKE ?)", new String[] { selectionArg, selectionArg, selectionArg }, null, @@ -3118,23 +3109,19 @@ public class DataStore { "name"); while (cursor.moveToNext()) { final String geocode = cursor.getString(0); - resultCursor.addRow(new String[] { - String.valueOf(resultCursor.getCount()), - cursor.getString(1), - geocode, - Intents.ACTION_GEOCACHE, - geocode - }); + final String cacheName = cursor.getString(1); + final String type = cursor.getString(2); + resultCursor.addCache(geocode, cacheName, type); } cursor.close(); } - private static String getSuggestionArgument(String input) { + private static String getSuggestionArgument(final String input) { return "%" + StringUtils.trim(input) + "%"; } private static void findTrackables(final MatrixCursor resultCursor, final String selectionArg) { - Cursor cursor = database.query( + final Cursor cursor = database.query( dbTableTrackables, new String[] { "tbcode", "title" }, "tbcode IS NOT NULL AND tbcode != '' AND (tbcode LIKE ? OR title LIKE ?)", @@ -3156,31 +3143,53 @@ public class DataStore { } public static String[] getSuggestions(final String table, final String column, final String input) { - Cursor cursor = database.rawQuery("SELECT DISTINCT " + column + final Cursor cursor = database.rawQuery("SELECT DISTINCT " + column + " FROM " + table + " WHERE " + column + " LIKE ?" + " ORDER BY " + column + " COLLATE NOCASE ASC;", new String[] { getSuggestionArgument(input) }); return cursorToColl(cursor, new LinkedList<String>(), GET_STRING_0).toArray(new String[cursor.getCount()]); } - public static String[] getSuggestionsOwnerName(String input) { - return getSuggestions(dbTableCaches, "owner", input); + public static String[] getSuggestionsOwnerName(final String input) { + return getSuggestions(dbTableCaches, "owner_real", input); } - public static String[] getSuggestionsTrackableCode(String input) { + public static String[] getSuggestionsTrackableCode(final String input) { return getSuggestions(dbTableTrackables, "tbcode", input); } - public static String[] getSuggestionsFinderName(String input) { + public static String[] getSuggestionsFinderName(final String input) { return getSuggestions(dbTableLogs, "author", input); } - public static String[] getSuggestionsGeocode(String input) { + public static String[] getSuggestionsGeocode(final String input) { return getSuggestions(dbTableCaches, "geocode", input); } - public static String[] getSuggestionsKeyword(String input) { + public static String[] getSuggestionsKeyword(final String input) { return getSuggestions(dbTableCaches, "name", input); } + /** + * + * @return list of last caches opened in the details view, ordered by most recent first + */ + public static ArrayList<Geocache> getLastOpenedCaches() { + final List<String> geocodes = Settings.getLastOpenedCaches(); + final Set<Geocache> cachesSet = DataStore.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); + + // order result set by time again + final ArrayList<Geocache> caches = new ArrayList<Geocache>(cachesSet); + Collections.sort(caches, new Comparator<Geocache>() { + + @Override + public int compare(final Geocache lhs, final Geocache rhs) { + final int lhsIndex = geocodes.indexOf(lhs.getGeocode()); + final int rhsIndex = geocodes.indexOf(rhs.getGeocode()); + return lhsIndex < rhsIndex ? -1 : (lhsIndex == rhsIndex ? 0 : 1); + } + }); + return caches; + } + } diff --git a/main/src/cgeo/geocaching/EditWaypointActivity.java b/main/src/cgeo/geocaching/EditWaypointActivity.java index 55de0a6..0eeb0d7 100644 --- a/main/src/cgeo/geocaching/EditWaypointActivity.java +++ b/main/src/cgeo/geocaching/EditWaypointActivity.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.enumerations.CacheType; @@ -48,7 +48,7 @@ import java.util.EnumSet; import java.util.List; @EActivity -public class EditWaypointActivity extends AbstractActivity { +public class EditWaypointActivity extends AbstractActionBarActivity implements CoordinatesInputDialog.CoordinateUpdate { private static final ArrayList<WaypointType> POSSIBLE_WAYPOINT_TYPES = new ArrayList<WaypointType>(WaypointType.ALL_TYPES_EXCEPT_OWN_AND_ORIGINAL); @ViewById(R.id.buttonLatitude) protected Button buttonLat; @@ -294,17 +294,18 @@ public class EditWaypointActivity extends AbstractActivity { // button text is blank when creating new waypoint } Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); - CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(EditWaypointActivity.this, cache, gp, app.currentGeo()); + CoordinatesInputDialog coordsDialog = CoordinatesInputDialog.getInstance(cache, gp, app.currentGeo()); coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { - @Override - public void update(final Geopoint gp) { - buttonLat.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); - buttonLon.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); - } - }); - coordsDialog.show(); + coordsDialog.show(getSupportFragmentManager(),"wpeditdialog"); } + + + } + + @Override + public void updateCoordinates(Geopoint gp) { + buttonLat.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); + buttonLon.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); } public static final int SUCCESS = 0; @@ -442,7 +443,7 @@ public class EditWaypointActivity extends AbstractActivity { if (!StaticMapsProvider.hasAllStaticMapsForWaypoint(geocode, waypoint)) { StaticMapsProvider.removeWpStaticMaps(oldWaypoint, geocode); if (Settings.isStoreOfflineWpMaps()) { - StaticMapsProvider.storeWaypointStaticMap(cache, waypoint, false); + StaticMapsProvider.storeWaypointStaticMap(cache, waypoint).subscribe(); } } if (modifyLocal.isChecked() || modifyBoth.isChecked()) { diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java index 19c15fd..193930c 100644 --- a/main/src/cgeo/geocaching/Geocache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -2,6 +2,7 @@ package cgeo.geocaching; import cgeo.geocaching.DataStore.StorageLocation; import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.activity.SimpleWebviewActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.connector.ILoggingManager; @@ -32,6 +33,7 @@ import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider; import cgeo.geocaching.utils.LogTemplateProvider.LogContext; import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.RxUtils; import cgeo.geocaching.utils.UncertainProperty; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -46,9 +48,8 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import rx.Scheduler; -import rx.Scheduler.Inner; import rx.Subscription; -import rx.functions.Action1; +import rx.functions.Action0; import android.app.Activity; import android.content.Intent; @@ -58,6 +59,7 @@ import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Message; +import android.os.Parcelable; import android.text.Html; import android.text.Html.ImageGetter; @@ -80,10 +82,6 @@ import java.util.regex.Pattern; /** * Internal c:geo representation of a "cache" */ -/** - * @author kep9fe - * - */ public class Geocache implements ICache, IWaypoint { private static final int OWN_WP_PREFIX_OFFSET = 17; @@ -160,7 +158,6 @@ public class Geocache implements ICache, IWaypoint { private final EnumSet<StorageLocation> storageLocation = EnumSet.of(StorageLocation.HEAP); private boolean finalDefined = false; private boolean logPasswordRequired = false; - // private int zoomlevel = Tile.ZOOMLEVEL_MIN - 1; private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+"); @@ -183,13 +180,13 @@ public class Geocache implements ICache, IWaypoint { * * @param gpxParser */ - public Geocache(GPXParser gpxParser) { + public Geocache(final GPXParser gpxParser) { setReliableLatLon(true); setAttributes(Collections.<String> emptyList()); setWaypoints(Collections.<Waypoint> emptyList(), false); } - public void setChangeNotificationHandler(Handler newNotificationHandler) { + public void setChangeNotificationHandler(final Handler newNotificationHandler) { changeNotificationHandler = newNotificationHandler; } @@ -471,7 +468,7 @@ public class Geocache implements ICache, IWaypoint { logOffline(fromActivity, initial, Calendar.getInstance(), logType); } - void logOffline(final Activity fromActivity, final String log, Calendar date, final LogType logType) { + void logOffline(final Activity fromActivity, final String log, final Calendar date, final LogType logType) { if (logType == LogType.UNKNOWN) { return; } @@ -498,18 +495,30 @@ public class Geocache implements ICache, IWaypoint { return getConnector().getPossibleLogTypes(this); } - public void openInBrowser(Activity fromActivity) { - fromActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getBrowserCacheUrl()))); + public void openInBrowser(final Activity fromActivity) { + final Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getUrl())); + + // Check if cgeo is the default, show the chooser to let the user choose a browser + if (viewIntent.resolveActivity(fromActivity.getPackageManager()).getPackageName().equals(fromActivity.getPackageName())) { + final Intent chooser = Intent.createChooser(viewIntent, fromActivity.getString(R.string.cache_menu_browser)); + + final Intent internalBrowser = new Intent(fromActivity, SimpleWebviewActivity.class); + internalBrowser.setData(Uri.parse(getUrl())); + + chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[] {internalBrowser}); + + + fromActivity.startActivity(chooser); + } else { + fromActivity.startActivity(viewIntent); + } } + private String getCacheUrl() { return getConnector().getCacheUrl(this); } - private String getBrowserCacheUrl() { - return getConnector().getLongCacheUrl(this); - } - private IConnector getConnector() { return ConnectorFactory.getConnector(this); } @@ -589,7 +598,7 @@ public class Geocache implements ICache, IWaypoint { return BooleanUtils.isTrue(premiumMembersOnly); } - public void setPremiumMembersOnly(boolean members) { + public void setPremiumMembersOnly(final boolean members) { this.premiumMembersOnly = members; } @@ -704,11 +713,17 @@ public class Geocache implements ICache, IWaypoint { return getConnector() instanceof ISearchByCenter; } - public void shareCache(Activity fromActivity, Resources res) { + public void shareCache(final Activity fromActivity, final Resources res) { if (geocode == null) { return; } + final Intent intent = getIntent(); + + fromActivity.startActivity(Intent.createChooser(intent, res.getText(R.string.action_bar_share_title))); + } + + public Intent getIntent() { final StringBuilder subject = new StringBuilder("Geocache "); subject.append(geocode); if (StringUtils.isNotBlank(name)) { @@ -720,13 +735,15 @@ public class Geocache implements ICache, IWaypoint { intent.putExtra(Intent.EXTRA_SUBJECT, subject.toString()); intent.putExtra(Intent.EXTRA_TEXT, getUrl()); - fromActivity.startActivity(Intent.createChooser(intent, res.getText(R.string.action_bar_share_title))); + return intent; } public String getUrl() { return getConnector().getCacheUrl(this); } + public String getCgeoUrl() { return getConnector().getCacheUrl(this); } + public boolean supportsGCVote() { return StringUtils.startsWithIgnoreCase(geocode, "GC"); } @@ -745,7 +762,7 @@ public class Geocache implements ICache, IWaypoint { return BooleanUtils.isTrue(favorite); } - public void setFavorite(boolean favorite) { + public void setFavorite(final boolean favorite) { this.favorite = favorite; } @@ -816,7 +833,7 @@ public class Geocache implements ICache, IWaypoint { return updated; } - public void setUpdated(long updated) { + public void setUpdated(final long updated) { this.updated = updated; } @@ -824,7 +841,7 @@ public class Geocache implements ICache, IWaypoint { return detailedUpdate; } - public void setDetailedUpdate(long detailedUpdate) { + public void setDetailedUpdate(final long detailedUpdate) { this.detailedUpdate = detailedUpdate; } @@ -832,7 +849,7 @@ public class Geocache implements ICache, IWaypoint { return visitedDate; } - public void setVisitedDate(long visitedDate) { + public void setVisitedDate(final long visitedDate) { this.visitedDate = visitedDate; } @@ -840,7 +857,7 @@ public class Geocache implements ICache, IWaypoint { return listId; } - public void setListId(int listId) { + public void setListId(final int listId) { this.listId = listId; } @@ -848,7 +865,7 @@ public class Geocache implements ICache, IWaypoint { return detailed; } - public void setDetailed(boolean detailed) { + public void setDetailed(final boolean detailed) { this.detailed = detailed; } @@ -865,7 +882,7 @@ public class Geocache implements ICache, IWaypoint { return direction; } - public void setDirection(Float direction) { + public void setDirection(final Float direction) { this.direction = direction; } @@ -873,7 +890,7 @@ public class Geocache implements ICache, IWaypoint { return distance; } - public void setDistance(Float distance) { + public void setDistance(final Float distance) { this.distance = distance; } @@ -891,7 +908,7 @@ public class Geocache implements ICache, IWaypoint { * * @param coords */ - public void setCoords(Geopoint coords) { + public void setCoords(final Geopoint coords) { this.coords = new UncertainProperty<Geopoint>(coords); } @@ -901,7 +918,7 @@ public class Geocache implements ICache, IWaypoint { * @param coords * @param zoomlevel */ - public void setCoords(Geopoint coords, int zoomlevel) { + public void setCoords(final Geopoint coords, final int zoomlevel) { this.coords = new UncertainProperty<Geopoint>(coords, zoomlevel); } @@ -912,15 +929,15 @@ public class Geocache implements ICache, IWaypoint { return getConnector().isReliableLatLon(reliableLatLon); } - public void setReliableLatLon(boolean reliableLatLon) { + public void setReliableLatLon(final boolean reliableLatLon) { this.reliableLatLon = reliableLatLon; } - public void setShortDescription(String shortdesc) { + public void setShortDescription(final String shortdesc) { this.shortdesc = shortdesc; } - public void setFavoritePoints(int favoriteCnt) { + public void setFavoritePoints(final int favoriteCnt) { this.favoritePoints = favoriteCnt; } @@ -928,7 +945,7 @@ public class Geocache implements ICache, IWaypoint { return rating; } - public void setRating(float rating) { + public void setRating(final float rating) { this.rating = rating; } @@ -936,7 +953,7 @@ public class Geocache implements ICache, IWaypoint { return votes; } - public void setVotes(int votes) { + public void setVotes(final int votes) { this.votes = votes; } @@ -944,7 +961,7 @@ public class Geocache implements ICache, IWaypoint { return myVote; } - public void setMyVote(float myVote) { + public void setMyVote(final float myVote) { this.myVote = myVote; } @@ -952,7 +969,7 @@ public class Geocache implements ICache, IWaypoint { return inventoryItems; } - public void setInventoryItems(int inventoryItems) { + public void setInventoryItems(final int inventoryItems) { this.inventoryItems = inventoryItems; } @@ -961,7 +978,7 @@ public class Geocache implements ICache, IWaypoint { return BooleanUtils.isTrue(onWatchlist); } - public void setOnWatchlist(boolean onWatchlist) { + public void setOnWatchlist(final boolean onWatchlist) { this.onWatchlist = onWatchlist; } @@ -982,7 +999,7 @@ public class Geocache implements ICache, IWaypoint { * called while loading or building a cache * @return <code>true</code> if waypoints successfully added to waypoint database */ - public boolean setWaypoints(List<Waypoint> waypoints, boolean saveToDatabase) { + public boolean setWaypoints(final List<Waypoint> waypoints, final boolean saveToDatabase) { this.waypoints.clear(); if (waypoints != null) { this.waypoints.addAll(waypoints); @@ -1029,7 +1046,7 @@ public class Geocache implements ICache, IWaypoint { return BooleanUtils.isTrue(logOffline); } - public void setLogOffline(boolean logOffline) { + public void setLogOffline(final boolean logOffline) { this.logOffline = logOffline; } @@ -1037,7 +1054,7 @@ public class Geocache implements ICache, IWaypoint { return statusChecked; } - public void setStatusChecked(boolean statusChecked) { + public void setStatusChecked(final boolean statusChecked) { this.statusChecked = statusChecked; } @@ -1045,39 +1062,39 @@ public class Geocache implements ICache, IWaypoint { return directionImg; } - public void setDirectionImg(String directionImg) { + public void setDirectionImg(final String directionImg) { this.directionImg = directionImg; } - public void setGeocode(String geocode) { + public void setGeocode(final String geocode) { this.geocode = StringUtils.upperCase(geocode); } - public void setCacheId(String cacheId) { + public void setCacheId(final String cacheId) { this.cacheId = cacheId; } - public void setGuid(String guid) { + public void setGuid(final String guid) { this.guid = guid; } - public void setName(String name) { + public void setName(final String name) { this.name = name; } - public void setOwnerDisplayName(String ownerDisplayName) { + public void setOwnerDisplayName(final String ownerDisplayName) { this.ownerDisplayName = ownerDisplayName; } - public void setOwnerUserId(String ownerUserId) { + public void setOwnerUserId(final String ownerUserId) { this.ownerUserId = ownerUserId; } - public void setHint(String hint) { + public void setHint(final String hint) { this.hint = hint; } - public void setSize(CacheSize size) { + public void setSize(final CacheSize size) { if (size == null) { this.size = CacheSize.UNKNOWN; } @@ -1086,50 +1103,50 @@ public class Geocache implements ICache, IWaypoint { } } - public void setDifficulty(float difficulty) { + public void setDifficulty(final float difficulty) { this.difficulty = difficulty; } - public void setTerrain(float terrain) { + public void setTerrain(final float terrain) { this.terrain = terrain; } - public void setLocation(String location) { + public void setLocation(final String location) { this.location = location; } - public void setPersonalNote(String personalNote) { + public void setPersonalNote(final String personalNote) { this.personalNote = StringUtils.trimToNull(personalNote); } - public void setDisabled(boolean disabled) { + public void setDisabled(final boolean disabled) { this.disabled = disabled; } - public void setArchived(boolean archived) { + public void setArchived(final boolean archived) { this.archived = archived; } - public void setFound(boolean found) { + public void setFound(final boolean found) { this.found = found; } - public void setAttributes(List<String> attributes) { + public void setAttributes(final List<String> attributes) { this.attributes.clear(); if (attributes != null) { this.attributes.addAll(attributes); } } - public void setSpoilers(List<Image> spoilers) { + public void setSpoilers(final List<Image> spoilers) { this.spoilers = spoilers; } - public void setInventory(List<Trackable> inventory) { + public void setInventory(final List<Trackable> inventory) { this.inventory = inventory; } - public void setLogCounts(Map<LogType, Integer> logCounts) { + public void setLogCounts(final Map<LogType, Integer> logCounts) { this.logCounts = logCounts; } @@ -1145,14 +1162,14 @@ public class Geocache implements ICache, IWaypoint { return cacheType.getValue(); } - public void setType(CacheType cacheType) { + public void setType(final CacheType cacheType) { if (cacheType == null || CacheType.ALL == cacheType) { throw new IllegalArgumentException("Illegal cache type"); } this.cacheType = new UncertainProperty<CacheType>(cacheType); } - public void setType(CacheType cacheType, final int zoomlevel) { + public void setType(final CacheType cacheType, final int zoomlevel) { if (cacheType == null || CacheType.ALL == cacheType) { throw new IllegalArgumentException("Illegal cache type"); } @@ -1190,7 +1207,7 @@ public class Geocache implements ICache, IWaypoint { * called while loading or building a cache * @return <code>true</code> if waypoint successfully added to waypoint database */ - public boolean addOrChangeWaypoint(final Waypoint waypoint, boolean saveToDatabase) { + public boolean addOrChangeWaypoint(final Waypoint waypoint, final boolean saveToDatabase) { waypoint.setGeocode(geocode); if (waypoint.getId() < 0) { // this is a new waypoint @@ -1202,7 +1219,7 @@ public class Geocache implements ICache, IWaypoint { } else { // this is a waypoint being edited final int index = getWaypointIndex(waypoint); if (index >= 0) { - Waypoint oldWaypoint = waypoints.remove(index); + final Waypoint oldWaypoint = waypoints.remove(index); waypoint.setPrefix(oldWaypoint.getPrefix()); //migration if (StringUtils.isBlank(waypoint.getPrefix()) @@ -1221,15 +1238,15 @@ public class Geocache implements ICache, IWaypoint { * Assigns a unique two-digit (compatibility with gc.com) * prefix within the scope of this cache. */ - private void assignUniquePrefix(Waypoint waypoint) { + private void assignUniquePrefix(final Waypoint waypoint) { // gather existing prefixes - Set<String> assignedPrefixes = new HashSet<String>(); - for (Waypoint wp : waypoints) { + final Set<String> assignedPrefixes = new HashSet<String>(); + for (final Waypoint wp : waypoints) { assignedPrefixes.add(wp.getPrefix()); } for (int i = OWN_WP_PREFIX_OFFSET; i < 100; i++) { - String prefixCandidate = StringUtils.leftPad(String.valueOf(i), 2, '0'); + final String prefixCandidate = StringUtils.leftPad(String.valueOf(i), 2, '0'); if (!assignedPrefixes.contains(prefixCandidate)) { waypoint.setPrefix(prefixCandidate); break; @@ -1247,7 +1264,7 @@ public class Geocache implements ICache, IWaypoint { } // Only for loading - public void setFinalDefined(boolean finalDefined) { + public void setFinalDefined(final boolean finalDefined) { this.finalDefined = finalDefined; } @@ -1268,7 +1285,7 @@ public class Geocache implements ICache, IWaypoint { return userModifiedCoords; } - public void setUserModifiedCoords(boolean coordsChanged) { + public void setUserModifiedCoords(final boolean coordsChanged) { userModifiedCoords = coordsChanged; } @@ -1325,7 +1342,7 @@ public class Geocache implements ICache, IWaypoint { * @param waypoint */ - public void deleteWaypointForce(Waypoint waypoint) { + public void deleteWaypointForce(final Waypoint waypoint) { final int index = getWaypointIndex(waypoint); waypoints.remove(index); DataStore.deleteWaypoint(waypoint.getId()); @@ -1405,17 +1422,17 @@ public class Geocache implements ICache, IWaypoint { } @Override - public boolean equals(Object obj) { + public boolean equals(final Object obj) { // TODO: explain the following line or remove this non-standard equality method // just compare the geocode even if that is not what "equals" normally does return this == obj || (obj instanceof Geocache && StringUtils.isNotEmpty(geocode) && geocode.equals(((Geocache) obj).geocode)); } - public void store(CancellableHandler handler) { + public void store(final CancellableHandler handler) { store(StoredList.TEMPORARY_LIST_ID, handler); } - public void store(final int listId, CancellableHandler handler) { + public void store(final int listId, final CancellableHandler handler) { final int newListId = listId < StoredList.STANDARD_LIST_ID ? Math.max(getListId(), StoredList.STANDARD_LIST_ID) : listId; @@ -1438,9 +1455,9 @@ public class Geocache implements ICache, IWaypoint { } public Subscription drop(final Handler handler, final Scheduler scheduler) { - return scheduler.schedule(new Action1<Inner>() { + return scheduler.createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { try { dropSynchronous(); handler.sendMessage(Message.obtain()); @@ -1498,22 +1515,22 @@ public class Geocache implements ICache, IWaypoint { } } - public Subscription refresh(final int newListId, final CancellableHandler handler, final Scheduler scheduler) { - return scheduler.schedule(new Action1<Inner>() { + public Subscription refresh(final CancellableHandler handler, final Scheduler scheduler) { + return scheduler.createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { - refreshSynchronous(newListId, handler); + public void call() { + refreshSynchronous(handler); handler.sendEmptyMessage(CancellableHandler.DONE); } }); } - public void refreshSynchronous(final int newListId, final CancellableHandler handler) { + public void refreshSynchronous(final CancellableHandler handler) { DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); - storeCache(null, geocode, newListId, true, handler); + storeCache(null, geocode, listId, true, handler); } - public static void storeCache(Geocache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) { + public static void storeCache(final Geocache origCache, final String geocode, final int listId, final boolean forceRedownload, final CancellableHandler handler) { try { Geocache cache = null; // get cache details, they may not yet be complete @@ -1591,9 +1608,7 @@ public class Geocache implements ICache, IWaypoint { return; } - StaticMapsProvider.downloadMaps(cache); - - imgGetter.waitForBackgroundLoading(handler); + RxUtils.waitForCompletion(StaticMapsProvider.downloadMaps(cache), imgGetter.waitForEndObservable(handler)); if (handler != null) { handler.sendMessage(Message.obtain()); @@ -1643,7 +1658,7 @@ public class Geocache implements ICache, IWaypoint { } final String hourLocalized = CgeoApplication.getInstance().getString(R.string.cache_time_full_hours); - ArrayList<Pattern> patterns = new ArrayList<Pattern>(); + final ArrayList<Pattern> patterns = new ArrayList<Pattern>(); // 12:34 patterns.add(Pattern.compile("\\b(\\d{1,2})\\:(\\d\\d)\\b")); @@ -1655,7 +1670,7 @@ public class Geocache implements ICache, IWaypoint { } final String searchText = getShortDescription() + ' ' + getDescription(); - for (Pattern pattern : patterns) { + for (final Pattern pattern : patterns) { final MatcherWrapper matcher = new MatcherWrapper(pattern, searchText); while (matcher.find()) { try { @@ -1683,7 +1698,7 @@ public class Geocache implements ICache, IWaypoint { * true if we are looking for the attribute_yes version, false for the attribute_no version * @return */ - public boolean hasAttribute(CacheAttribute attribute, boolean yes) { + public boolean hasAttribute(final CacheAttribute attribute, final boolean yes) { Geocache fullCache = DataStore.loadCache(getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); if (fullCache == null) { fullCache = this; @@ -1762,7 +1777,7 @@ public class Geocache implements ICache, IWaypoint { * Gets whether the user has logged the specific log type for this cache. Only checks the currently stored logs of * the cache, so the result might be wrong. */ - public boolean hasOwnLog(LogType logType) { + public boolean hasOwnLog(final LogType logType) { for (final LogEntry logEntry : getLogs()) { if (logEntry.type == logType && logEntry.isOwn()) { return true; @@ -1779,15 +1794,15 @@ public class Geocache implements ICache, IWaypoint { return logPasswordRequired; } - public void setLogPasswordRequired(boolean required) { + public void setLogPasswordRequired(final boolean required) { logPasswordRequired = required; } - public String getWaypointGpxId(String prefix) { + public String getWaypointGpxId(final String prefix) { return getConnector().getWaypointGpxId(prefix, geocode); } - public String getWaypointPrefix(String name) { + public String getWaypointPrefix(final String name) { return getConnector().getWaypointPrefix(name); } @@ -1800,7 +1815,7 @@ public class Geocache implements ICache, IWaypoint { if (getLogCounts().isEmpty()) { setLogCounts(DataStore.loadLogCounts(getGeocode())); } - Integer logged = getLogCounts().get(LogType.FOUND_IT); + final Integer logged = getLogCounts().get(LogType.FOUND_IT); if (logged != null) { return logged; } @@ -1814,7 +1829,7 @@ public class Geocache implements ICache, IWaypoint { public LogType getDefaultLogType() { if (isEventCache()) { final Date eventDate = getHiddenDate(); - boolean expired = DateUtils.isPastEvent(this); + final boolean expired = DateUtils.isPastEvent(this); if (hasOwnLog(LogType.WILL_ATTEND) || expired || (eventDate != null && DateUtils.daysSince(eventDate.getTime()) == 0)) { return hasOwnLog(LogType.ATTENDED) ? LogType.NOTE : LogType.ATTENDED; diff --git a/main/src/cgeo/geocaching/ImageSelectActivity.java b/main/src/cgeo/geocaching/ImageSelectActivity.java index b5fb38e..a64b4cf 100644 --- a/main/src/cgeo/geocaching/ImageSelectActivity.java +++ b/main/src/cgeo/geocaching/ImageSelectActivity.java @@ -3,7 +3,7 @@ package cgeo.geocaching; import butterknife.ButterKnife; import butterknife.InjectView; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.files.LocalStorage; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.ui.dialog.Dialogs; @@ -37,7 +37,7 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; -public class ImageSelectActivity extends AbstractActivity { +public class ImageSelectActivity extends AbstractActionBarActivity { @InjectView(R.id.caption) protected EditText captionView; @InjectView(R.id.description) protected EditText descriptionView; diff --git a/main/src/cgeo/geocaching/ImagesActivity.java b/main/src/cgeo/geocaching/ImagesActivity.java index 3da1ade..bc2616b 100644 --- a/main/src/cgeo/geocaching/ImagesActivity.java +++ b/main/src/cgeo/geocaching/ImagesActivity.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.ui.ImagesList; import cgeo.geocaching.ui.ImagesList.ImageType; @@ -19,7 +19,7 @@ import android.view.View; import java.util.ArrayList; import java.util.List; -public class ImagesActivity extends AbstractActivity { +public class ImagesActivity extends AbstractActionBarActivity { private boolean offline; private ArrayList<Image> imageNames; diff --git a/main/src/cgeo/geocaching/LogCacheActivity.java b/main/src/cgeo/geocaching/LogCacheActivity.java index 2b05263..25906de 100644 --- a/main/src/cgeo/geocaching/LogCacheActivity.java +++ b/main/src/cgeo/geocaching/LogCacheActivity.java @@ -25,7 +25,6 @@ import org.apache.commons.lang3.StringUtils; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; -import android.app.Dialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; @@ -35,12 +34,13 @@ import android.util.SparseArray; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; -import android.view.SubMenu; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.RatingBar; +import android.widget.RatingBar.OnRatingBarChangeListener; import android.widget.TextView; import java.util.ArrayList; @@ -52,7 +52,6 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia static final String EXTRAS_GEOCODE = "geocode"; static final String EXTRAS_ID = "id"; - private static final int SUBMENU_VOTE = 3; 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"; @@ -68,7 +67,6 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private String text = null; private List<LogType> possibleLogTypes = new ArrayList<LogType>(); private List<TrackableLog> trackables = null; - private Button postButton = null; private CheckBox tweetCheck = null; private LinearLayout tweetBox = null; private LinearLayout logPasswordBox = null; @@ -84,6 +82,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private String imageCaption; private String imageDescription; private Uri imageUri; + private boolean sendButtonEnabled; public void onLoadFinished() { @@ -123,7 +122,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private void initializeTrackablesAction() { if (Settings.isTrackableAutoVisit()) { - for (TrackableLog trackable : trackables) { + for (final TrackableLog trackable : trackables) { trackable.action = LogTypeTrackable.VISITED; tbChanged = true; } @@ -142,8 +141,8 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory); inventoryView.removeAllViews(); - for (TrackableLog tb : trackables) { - LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.logcache_trackable_item, null); + for (final TrackableLog tb : trackables) { + final LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.logcache_trackable_item, null); ((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode); ((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name); @@ -154,7 +153,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia actionButton.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(final View view) { selectTrackableAction(view); } }); @@ -164,7 +163,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(final View view) { final Intent trackablesIntent = new Intent(LogCacheActivity.this, TrackableActivity.class); trackablesIntent.putExtra(Intents.EXTRA_GEOCODE, tbCode); startActivity(trackablesIntent); @@ -184,7 +183,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia changeButton.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(final View view) { selectAllTrackablesAction(); } }); @@ -193,33 +192,9 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } } - private void enablePostButton(boolean enabled) { - postButton.setEnabled(enabled); - if (enabled) { - postButton.setOnClickListener(new PostListener()); - } - else { - postButton.setOnTouchListener(null); - postButton.setOnClickListener(null); - } - updatePostButtonText(); - } - - private void updatePostButtonText() { - postButton.setText(getPostButtonText()); - } - - private String getPostButtonText() { - if (!postButton.isEnabled()) { - return res.getString(R.string.log_post_not_possible); - } - if (!GCVote.isVotingPossible(cache)) { - return res.getString(R.string.log_post); - } - if (GCVote.isValidRating(rating)) { - return res.getString(R.string.log_post_rate) + " " + GCVote.getRatingText(rating) + "*"; - } - return res.getString(R.string.log_post_no_rate); + private void enablePostButton(final boolean enabled) { + sendButtonEnabled = enabled; + invalidateOptionsMenuCompatible(); } @Override @@ -239,6 +214,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + invalidateOptionsMenuCompatible(); possibleLogTypes = cache.getPossibleLogTypes(); if (StringUtils.isNotBlank(cache.getName())) { @@ -248,11 +224,13 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } // Get ids for later use - postButton = (Button) findViewById(R.id.post); tweetBox = (LinearLayout) findViewById(R.id.tweet_box); tweetCheck = (CheckBox) findViewById(R.id.tweet); logPasswordBox = (LinearLayout) findViewById(R.id.log_password_box); + final RatingBar ratingBar = (RatingBar) findViewById(R.id.gcvoteRating); + initializeRatingBar(ratingBar); + // initialize with default values setDefaultValues(); @@ -277,8 +255,6 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia insertIntoLog(LogTemplateProvider.applyTemplates(Settings.getSignature(), new LogContext(cache, null)), false); } } - updatePostButtonText(); - updateImageButton(); enablePostButton(false); final Button typeButton = (Button) findViewById(R.id.type); @@ -286,7 +262,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia typeButton.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { + public void onClick(final View view) { selectLogType(); } }); @@ -305,36 +281,30 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia updateTweetBox(typeSelected); updateLogPasswordBox(typeSelected); - 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() { + loggingManager = cache.getLoggingManager(this); - @Override - public void onClick(View v) { - saveLog(true); - } - }); + loggingManager.init(); + } - final Button clearButton = (Button) findViewById(R.id.clear); - clearButton.setOnClickListener(new View.OnClickListener() { + private void initializeRatingBar(final RatingBar ratingBar) { + final TextView label = (TextView) findViewById(R.id.gcvoteLabel); + if (GCVote.isVotingPossible(cache)) { + ratingBar.setVisibility(View.VISIBLE); + label.setVisibility(View.VISIBLE); + } + ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() { @Override - public void onClick(View v) { - clearLog(); + public void onRatingChanged(final RatingBar ratingBar, final float stars, final boolean fromUser) { + // 0.5 is not a valid rating, therefore we must limit + rating = GCVote.isValidRating(stars) ? stars : 0; + if (rating < stars) { + ratingBar.setRating(rating); + } + label.setText(GCVote.getDescription(rating)); } }); - - loggingManager = cache.getLoggingManager(this); - - loggingManager.init(); + ratingBar.setRating(cache.getMyVote()); } private void setDefaultValues() { @@ -364,8 +334,6 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia final EditText logPasswordView = (EditText) findViewById(R.id.log_password); logPasswordView.setText(StringUtils.EMPTY); - updateImageButton(); - showToast(res.getString(R.string.info_log_cleared)); } @@ -382,53 +350,6 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } @Override - public boolean onCreateOptionsMenu(final Menu menu) { - super.onCreateOptionsMenu(menu); - - final SubMenu menuStars = menu.addSubMenu(0, SUBMENU_VOTE, 0, res.getString(R.string.log_rating)).setIcon(R.drawable.ic_menu_sort_by_size); - menuStars.add(0, 10, 0, res.getString(R.string.log_no_rating)); - menuStars.add(0, 19, 0, res.getString(R.string.log_stars_5) + " (" + res.getString(R.string.log_stars_5_description) + ")"); - menuStars.add(0, 18, 0, res.getString(R.string.log_stars_45) + " (" + res.getString(R.string.log_stars_45_description) + ")"); - menuStars.add(0, 17, 0, res.getString(R.string.log_stars_4) + " (" + res.getString(R.string.log_stars_4_description) + ")"); - menuStars.add(0, 16, 0, res.getString(R.string.log_stars_35) + " (" + res.getString(R.string.log_stars_35_description) + ")"); - menuStars.add(0, 15, 0, res.getString(R.string.log_stars_3) + " (" + res.getString(R.string.log_stars_3_description) + ")"); - menuStars.add(0, 14, 0, res.getString(R.string.log_stars_25) + " (" + res.getString(R.string.log_stars_25_description) + ")"); - menuStars.add(0, 13, 0, res.getString(R.string.log_stars_2) + " (" + res.getString(R.string.log_stars_2_description) + ")"); - menuStars.add(0, 12, 0, res.getString(R.string.log_stars_15) + " (" + res.getString(R.string.log_stars_15_description) + ")"); - menuStars.add(0, 11, 0, res.getString(R.string.log_stars_1) + " (" + res.getString(R.string.log_stars_1_description) + ")"); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - menu.findItem(SUBMENU_VOTE).setVisible(GCVote.isVotingPossible(cache)); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (super.onOptionsItemSelected(item)) { - return true; - } - - final int id = item.getItemId(); - if (id >= 10 && id <= 19) { - rating = (id - 9) / 2.0f; - if (!GCVote.isValidRating(rating)) { - rating = GCVote.NO_RATING; - } - updatePostButtonText(); - return true; - } - - return false; - } - - @Override protected void onSaveInstanceState(final Bundle outState) { super.onSaveInstanceState(outState); outState.putDouble(SAVED_STATE_RATING, rating); @@ -440,14 +361,14 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } @Override - public void setDate(Calendar dateIn) { + public void setDate(final Calendar dateIn) { date = dateIn; final Button dateButton = (Button) findViewById(R.id.date); dateButton.setText(Formatter.formatShortDateVerbally(date.getTime().getTime())); } - public void setType(LogType type) { + public void setType(final LogType type) { final Button typeButton = (Button) findViewById(R.id.type); typeSelected = type; @@ -461,11 +382,9 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia updateTweetBox(type); updateLogPasswordBox(type); - - updatePostButtonText(); } - private void updateTweetBox(LogType type) { + private void updateTweetBox(final LogType type) { if (type == LogType.FOUND_IT && Settings.isUseTwitter() && Settings.isTwitterLoginValid()) { tweetBox.setVisibility(View.VISIBLE); } else { @@ -473,7 +392,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } } - private void updateLogPasswordBox(LogType type) { + private void updateLogPasswordBox(final LogType type) { if (type == LogType.FOUND_IT && cache.isLogPasswordRequired()) { logPasswordBox.setVisibility(View.VISIBLE); } else { @@ -484,20 +403,10 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private class DateListener implements View.OnClickListener { @Override - public void onClick(View arg0) { - final Dialog dateDialog = new DateDialog(LogCacheActivity.this, LogCacheActivity.this, date); + public void onClick(final View arg0) { + final DateDialog dateDialog = DateDialog.getInstance(date); dateDialog.setCancelable(true); - dateDialog.show(); - } - } - - private class PostListener implements View.OnClickListener { - @Override - public void onClick(View arg0) { - final String message = res.getString(StringUtils.isBlank(imageUri.getPath()) ? - R.string.log_saving : - R.string.log_saving_and_uploading); - new Poster(LogCacheActivity.this, message).execute(currentLogText(), currentLogPassword()); + dateDialog.show(getSupportFragmentManager(), "date_dialog"); } } @@ -516,15 +425,16 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia if (logResult.getPostLogResult() == StatusCode.NO_ERROR) { // update geocache in DB - if (typeSelected == LogType.FOUND_IT || typeSelected == LogType.ATTENDED) { + if (typeSelected == LogType.FOUND_IT || typeSelected == LogType.ATTENDED || typeSelected == LogType.WEBCAM_PHOTO_TAKEN) { cache.setFound(true); cache.setVisitedDate(new Date().getTime()); } DataStore.saveChangedCache(cache); // update logs in DB - ArrayList<LogEntry> newLogs = new ArrayList<LogEntry>(cache.getLogs()); + final ArrayList<LogEntry> newLogs = new ArrayList<LogEntry>(cache.getLogs()); final LogEntry logNow = new LogEntry(date.getTimeInMillis(), typeSelected, log); + logNow.friend = true; newLogs.add(0, logNow); DataStore.saveLogsWithoutTransaction(cache.getGeocode(), newLogs); @@ -541,7 +451,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } if (StringUtils.isNotBlank(imageUri.getPath())) { - ImageResult imageResult = loggingManager.postLogImage(logResult.getLogId(), imageCaption, imageDescription, imageUri); + final ImageResult imageResult = loggingManager.postLogImage(logResult.getLogId(), imageCaption, imageDescription, imageUri); final String uploadedImageUrl = imageResult.getImageUri(); if (StringUtils.isNotEmpty(uploadedImageUrl)) { logNow.addLogImage(new Image(uploadedImageUrl, imageCaption, imageDescription)); @@ -552,7 +462,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } return logResult.getPostLogResult(); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.e("VisitCacheActivity.Poster.doInBackgroundInternal", e); } @@ -601,15 +511,15 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } private void selectAllTrackablesAction() { - Builder alert = new AlertDialog.Builder(this); + final Builder alert = new AlertDialog.Builder(this); alert.setTitle(res.getString(R.string.log_tb_changeall)); - String[] tbLogTypes = getTBLogTypes(); + final String[] tbLogTypes = getTBLogTypes(); alert.setItems(tbLogTypes, new OnClickListener() { @Override - public void onClick(DialogInterface dialog, int position) { + public void onClick(final DialogInterface dialog, final int position) { final LogTypeTrackable logType = LogTypeTrackable.values()[position]; - for (TrackableLog tb : trackables) { + for (final TrackableLog tb : trackables) { tb.action = logType; } tbChanged = true; @@ -622,7 +532,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private static String[] getTBLogTypes() { final LogTypeTrackable[] logTypeValues = LogTypeTrackable.values(); - String[] logTypes = new String[logTypeValues.length]; + final String[] logTypes = new String[logTypeValues.length]; for (int i = 0; i < logTypes.length; i++) { logTypes[i] = logTypeValues[i].getLabel(); } @@ -633,15 +543,15 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia // use a local copy of the possible types, as that one might be modified in the background by the loader final ArrayList<LogType> possible = new ArrayList<LogType>(possibleLogTypes); - Builder alert = new AlertDialog.Builder(this); - String[] choices = new String[possible.size()]; + final Builder alert = new AlertDialog.Builder(this); + final String[] choices = new String[possible.size()]; for (int i = 0; i < choices.length; i++) { choices[i] = possible.get(i).getL10n(); } alert.setSingleChoiceItems(choices, possible.indexOf(typeSelected), new OnClickListener() { @Override - public void onClick(DialogInterface dialog, int position) { + public void onClick(final DialogInterface dialog, final int position) { setType(possible.get(position)); dialog.dismiss(); } @@ -649,16 +559,16 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia alert.create().show(); } - private void selectTrackableAction(View view) { + private void selectTrackableAction(final View view) { final int realViewId = view.getId(); - Builder alert = new AlertDialog.Builder(this); + final Builder alert = new AlertDialog.Builder(this); final TrackableLog trackableLog = actionButtons.get(realViewId); alert.setTitle(trackableLog.name); - String[] tbLogTypes = getTBLogTypes(); + final String[] tbLogTypes = getTBLogTypes(); alert.setItems(tbLogTypes, new OnClickListener() { @Override - public void onClick(DialogInterface dialog, int position) { + public void onClick(final DialogInterface dialog, final int position) { final LogTypeTrackable logType = LogTypeTrackable.values()[position]; tbChanged = true; trackableLog.action = logType; @@ -671,7 +581,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } private void selectImage() { - Intent selectImageIntent = new Intent(this, ImageSelectActivity.class); + final 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()); @@ -680,7 +590,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { if (requestCode == SELECT_IMAGE) { if (resultCode == RESULT_OK) { imageCaption = data.getStringExtra(ImageSelectActivity.EXTRAS_CAPTION); @@ -690,19 +600,51 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia // Image capture failed, advise user showToast(getResources().getString(R.string.err_select_logimage_failed)); } - updateImageButton(); + } + } + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_send: + sendLog(); + return true; + case R.id.menu_image: + selectImage(); + return true; + case R.id.save: + saveLog(true); + finish(); + return true; + case R.id.clear: + clearLog(); + return true; + default: + break; } + + return super.onOptionsItemSelected(item); } - private void updateImageButton() { - final Button imageButton = (Button) findViewById(R.id.image_btn); - if (cache.supportsLogImages()) { - imageButton.setVisibility(View.VISIBLE); - imageButton.setText(StringUtils.isNotBlank(imageUri.getPath()) ? - res.getString(R.string.log_image_edit) : res.getString(R.string.log_image_attach)); - } else { - imageButton.setVisibility(View.GONE); + private void sendLog() { + if (!sendButtonEnabled) { + Dialogs.message(this, R.string.log_post_not_possible); } + else { + final String message = res.getString(StringUtils.isBlank(imageUri.getPath()) ? + R.string.log_saving : + R.string.log_saving_and_uploading); + new Poster(LogCacheActivity.this, message).execute(currentLogText(), currentLogPassword()); + } + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + super.onCreateOptionsMenu(menu); + menu.findItem(R.id.menu_image).setVisible(cache.supportsLogImages()); + menu.findItem(R.id.save).setVisible(true); + menu.findItem(R.id.clear).setVisible(true); + return true; } + } diff --git a/main/src/cgeo/geocaching/LogTrackableActivity.java b/main/src/cgeo/geocaching/LogTrackableActivity.java index fabe391..9f1bc88 100644 --- a/main/src/cgeo/geocaching/LogTrackableActivity.java +++ b/main/src/cgeo/geocaching/LogTrackableActivity.java @@ -20,7 +20,6 @@ import cgeo.geocaching.utils.LogTemplateProvider.LogContext; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; @@ -240,9 +239,9 @@ public class LogTrackableActivity extends AbstractLoggingActivity implements Dat @Override public void onClick(View arg0) { - final Dialog dateDialog = new DateDialog(LogTrackableActivity.this, LogTrackableActivity.this, date); + final DateDialog dateDialog = DateDialog.getInstance(date); dateDialog.setCancelable(true); - dateDialog.show(); + dateDialog.show(getSupportFragmentManager(),"date_dialog"); } } diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java index 42dd58d..d901e05 100644 --- a/main/src/cgeo/geocaching/MainActivity.java +++ b/main/src/cgeo/geocaching/MainActivity.java @@ -3,9 +3,11 @@ package cgeo.geocaching; import butterknife.ButterKnife; import butterknife.InjectView; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.capability.ILogin; +import cgeo.geocaching.connector.gc.GCConnector; +import cgeo.geocaching.connector.gc.GCLogin; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.geopoint.Geopoint; @@ -25,7 +27,9 @@ import cgeo.geocaching.utils.Version; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; + import org.apache.commons.lang3.StringUtils; + import rx.Observable; import rx.Observable.OnSubscribe; import rx.Subscriber; @@ -37,6 +41,7 @@ import rx.subscriptions.Subscriptions; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.SearchManager; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; @@ -45,6 +50,8 @@ import android.location.Geocoder; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -61,7 +68,7 @@ import java.util.Comparator; import java.util.List; import java.util.Locale; -public class MainActivity extends AbstractActivity { +public class MainActivity extends AbstractActionBarActivity { @InjectView(R.id.nav_satellites) protected TextView navSatellites; @InjectView(R.id.filter_button_title)protected TextView filterTitle; @InjectView(R.id.map) protected ImageView findOnMap; @@ -86,24 +93,24 @@ public class MainActivity extends AbstractActivity { private final UpdateLocation locationUpdater = new UpdateLocation(); - private Handler updateUserInfoHandler = new Handler() { + private final Handler updateUserInfoHandler = new Handler() { @Override public void handleMessage(final Message msg) { // Get active connectors with login status - ILogin[] loginConns = ConnectorFactory.getActiveLiveConnectors(); + final ILogin[] loginConns = ConnectorFactory.getActiveLiveConnectors(); // Update UI infoArea.removeAllViews(); - LayoutInflater inflater = getLayoutInflater(); + final LayoutInflater inflater = getLayoutInflater(); - for (ILogin conn : loginConns) { + for (final ILogin conn : loginConns) { - TextView connectorInfo = (TextView) inflater.inflate(R.layout.main_activity_connectorstatus, null); + final TextView connectorInfo = (TextView) inflater.inflate(R.layout.main_activity_connectorstatus, null); infoArea.addView(connectorInfo); - StringBuilder userInfo = new StringBuilder(conn.getName()).append(Formatter.SEPARATOR); + final StringBuilder userInfo = new StringBuilder(conn.getName()).append(Formatter.SEPARATOR); if (conn.isLoggedIn()) { userInfo.append(conn.getUserName()); if (conn.getCachesFound() >= 0) { @@ -167,9 +174,9 @@ public class MainActivity extends AbstractActivity { } - private SatellitesHandler satellitesHandler = new SatellitesHandler(); + private final SatellitesHandler satellitesHandler = new SatellitesHandler(); - private Handler firstLoginHandler = new Handler() { + private final Handler firstLoginHandler = new Handler() { @Override public void handleMessage(final Message msg) { @@ -179,7 +186,7 @@ public class MainActivity extends AbstractActivity { if (reason != null && reason != StatusCode.NO_ERROR) { //LoginFailed showToast(res.getString(reason == StatusCode.MAINTENANCE ? reason.getErrorString() : R.string.err_login_failed_toast)); } - } catch (Exception e) { + } catch (final Exception e) { Log.w("MainActivity.firstLoginHander", e); } } @@ -189,6 +196,10 @@ public class MainActivity extends AbstractActivity { public void onCreate(final Bundle savedInstanceState) { // don't call the super implementation with the layout argument, as that would set the wrong theme super.onCreate(savedInstanceState); + + // Disable the up navigation for this activity + getSupportActionBar().setDisplayHomeAsUpEnabled(false); + setContentView(R.layout.main_activity); ButterKnife.inject(this); @@ -204,6 +215,8 @@ public class MainActivity extends AbstractActivity { Log.i("Starting " + getPackageName() + ' ' + version + " a.k.a " + Version.getVersionName(this)); init(); + + checkShowChangelog(); } @Override @@ -231,6 +244,10 @@ public class MainActivity extends AbstractActivity { new Thread() { @Override public void run() { + if (mustLogin && conn == GCConnector.getInstance()) { + // Properly log out from geocaching.com + GCLogin.getInstance().logout(); + } conn.login(firstLoginHandler, MainActivity.this); updateUserInfoHandler.sendEmptyMessage(-1); } @@ -262,6 +279,11 @@ public class MainActivity extends AbstractActivity { @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.main_activity_options, menu); + final SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + final MenuItem searchItem = menu.findItem(R.id.menu_gosearch); + final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + return true; } @@ -276,6 +298,10 @@ public class MainActivity extends AbstractActivity { public boolean onOptionsItemSelected(final MenuItem item) { final int id = item.getItemId(); switch (id) { + case android.R.id.home: + // this activity must handle the home navigation different than all others + showAbout(null); + return true; case R.id.menu_about: showAbout(null); return true; @@ -303,13 +329,12 @@ public class MainActivity extends AbstractActivity { } }); return true; - default: - return super.onOptionsItemSelected(item); } + return super.onOptionsItemSelected(item); } private void startScannerApplication() { - IntentIntegrator integrator = new IntentIntegrator(this); + final IntentIntegrator integrator = new IntentIntegrator(this); // integrator dialog is English only, therefore localize it integrator.setButtonYesByID(android.R.string.yes); integrator.setButtonNoByID(android.R.string.no); @@ -320,9 +345,9 @@ public class MainActivity extends AbstractActivity { @Override public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { - IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); + final IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanResult != null) { - String scan = scanResult.getContents(); + final String scan = scanResult.getContents(); if (StringUtils.isBlank(scan)) { return; } @@ -434,7 +459,7 @@ public class MainActivity extends AbstractActivity { cacheTypes.add(CacheType.MYSTERY); // then add all other cache types sorted alphabetically - List<CacheType> sorted = new ArrayList<CacheType>(); + final List<CacheType> sorted = new ArrayList<CacheType>(); sorted.addAll(Arrays.asList(CacheType.values())); sorted.removeAll(cacheTypes); @@ -453,18 +478,18 @@ public class MainActivity extends AbstractActivity { checkedItem = 0; } - String[] items = new String[cacheTypes.size()]; + final String[] items = new String[cacheTypes.size()]; for (int i = 0; i < cacheTypes.size(); i++) { items[i] = cacheTypes.get(i).getL10n(); } - Builder builder = new AlertDialog.Builder(this); + final Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.menu_filter); builder.setSingleChoiceItems(items, checkedItem, new DialogInterface.OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int position) { - CacheType cacheType = cacheTypes.get(position); + final CacheType cacheType = cacheTypes.get(position); Settings.setCacheType(cacheType); setFilterTitle(); dialog.dismiss(); @@ -524,7 +549,7 @@ public class MainActivity extends AbstractActivity { navType.setText(res.getString(geo.getLocationProvider().resourceId)); if (geo.getAccuracy() >= 0) { - int speed = Math.round(geo.getSpeed()) * 60 * 60 / 1000; + final int speed = Math.round(geo.getSpeed()) * 60 * 60 / 1000; navAccuracy.setText("±" + Units.getDistanceFromMeters(geo.getAccuracy()) + Formatter.SEPARATOR + Units.getSpeed(speed)); } else { navAccuracy.setText(null); @@ -553,12 +578,13 @@ public class MainActivity extends AbstractActivity { } }); AndroidObservable.bindActivity(MainActivity.this, address.onErrorResumeNext(Observable.from(geo.getCoords().toString()))) + .subscribeOn(Schedulers.io()) .subscribe(new Action1<String>() { @Override public void call(final String address) { navLocation.setText(address); } - }, Schedulers.io()); + }); } } else { navLocation.setText(geo.getCoords().toString()); @@ -633,7 +659,7 @@ public class MainActivity extends AbstractActivity { } private class CountBubbleUpdateThread extends Thread { - private Handler countBubbleHandler = new Handler() { + private final Handler countBubbleHandler = new Handler() { @Override public void handleMessage(final Message msg) { @@ -645,7 +671,7 @@ public class MainActivity extends AbstractActivity { countBubble.bringToFront(); countBubble.setVisibility(View.VISIBLE); } - } catch (Exception e) { + } catch (final Exception e) { Log.w("MainActivity.countBubbleHander", e); } } @@ -662,7 +688,7 @@ public class MainActivity extends AbstractActivity { try { sleep(500); checks++; - } catch (Exception e) { + } catch (final Exception e) { Log.e("MainActivity.CountBubbleUpdateThread.run", e); } @@ -705,20 +731,21 @@ public class MainActivity extends AbstractActivity { } } - /** - * @param view - * unused here but needed since this method is referenced from XML layout - */ - public void showAbout(final View view) { - startActivity(new Intent(this, AboutActivity.class)); + private void checkShowChangelog() { + final int lastVersion = Settings.getLastChangelogVersion(); + final int version = Version.getVersionCode(this); + Settings.setLastChangelogVersion(version); + // don't show change log after new install... + if (lastVersion > 0 && version != lastVersion) { + AboutActivity.showChangeLog(this); + } } /** * @param view * unused here but needed since this method is referenced from XML layout */ - public void goSearch(final View view) { - onSearchRequested(); + public void showAbout(final View view) { + startActivity(new Intent(this, AboutActivity.class)); } - } diff --git a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java index 0a750e0..39531f1 100644 --- a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java +++ b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java @@ -4,7 +4,7 @@ import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.Optional; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; @@ -44,7 +44,7 @@ import android.widget.TextView; import java.util.List; -public class NavigateAnyPointActivity extends AbstractActivity { +public class NavigateAnyPointActivity extends AbstractActionBarActivity implements CoordinatesInputDialog.CoordinateUpdate { @InjectView(R.id.historyList) protected ListView historyListView; @@ -278,18 +278,17 @@ public class NavigateAnyPointActivity extends AbstractActivity { if (latButton.getText().length() > 0 && lonButton.getText().length() > 0) { gp = new Geopoint(latButton.getText().toString() + " " + lonButton.getText().toString()); } - CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(NavigateAnyPointActivity.this, null, gp, app.currentGeo()); + CoordinatesInputDialog coordsDialog = CoordinatesInputDialog.getInstance(null, gp, app.currentGeo()); coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { - @Override - public void update(Geopoint gp) { - latButton.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); - lonButton.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); - changed = true; - } - }); - coordsDialog.show(); + coordsDialog.show(getSupportFragmentManager(),"wpedit_dialog"); } + + } + @Override + public void updateCoordinates(Geopoint gp) { + latButton.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); + lonButton.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); + changed = true; } private static class ChangeDistanceUnit implements OnItemSelectedListener { @@ -328,7 +327,7 @@ public class NavigateAnyPointActivity extends AbstractActivity { menu.findItem(R.id.menu_default_navigation).setVisible(visible); menu.findItem(R.id.menu_caches_around).setVisible(visible); - menu.findItem(R.id.menu_clear_history).setEnabled(!getHistoryOfSearchedLocations().isEmpty()); + menu.findItem(R.id.menu_clear_history).setVisible(!getHistoryOfSearchedLocations().isEmpty()); } catch (RuntimeException e) { // nothing } @@ -362,9 +361,8 @@ public class NavigateAnyPointActivity extends AbstractActivity { case R.id.menu_navigate: NavigationAppFactory.showNavigationMenu(this, null, null, coords); return true; - default: - return false; } + return super.onOptionsItemSelected(item); } private void addToHistory(final Geopoint coords) { diff --git a/main/src/cgeo/geocaching/PocketQueryList.java b/main/src/cgeo/geocaching/PocketQueryList.java index 2ac137f..4e84881 100644 --- a/main/src/cgeo/geocaching/PocketQueryList.java +++ b/main/src/cgeo/geocaching/PocketQueryList.java @@ -52,13 +52,13 @@ public final class PocketQueryList { subscriber.onNext(GCParser.searchPocketQueryList()); subscriber.onCompleted(); } - })).subscribe(new Action1<List<PocketQueryList>>() { + })).subscribeOn(Schedulers.io()).subscribe(new Action1<List<PocketQueryList>>() { @Override public void call(final List<PocketQueryList> pocketQueryLists) { waitDialog.dismiss(); selectFromPocketQueries(activity, pocketQueryLists, runAfterwards); } - }, Schedulers.io()); + }); } private static void selectFromPocketQueries(final Activity activity, final List<PocketQueryList> pocketQueryList, final Action1<PocketQueryList> runAfterwards) { if (CollectionUtils.isEmpty(pocketQueryList)) { diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java index 2a37e27..81dec98 100644 --- a/main/src/cgeo/geocaching/SearchActivity.java +++ b/main/src/cgeo/geocaching/SearchActivity.java @@ -3,7 +3,7 @@ package cgeo.geocaching; import butterknife.ButterKnife; import butterknife.InjectView; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.connector.capability.ISearchByGeocode; @@ -37,7 +37,7 @@ import android.widget.Button; import java.util.Locale; -public class SearchActivity extends AbstractActivity { +public class SearchActivity extends AbstractActionBarActivity implements CoordinatesInputDialog.CoordinateUpdate { @InjectView(R.id.buttonLatitude) protected Button buttonLatitude; @InjectView(R.id.buttonLongitude) protected Button buttonLongitude; @@ -174,8 +174,20 @@ public class SearchActivity extends AbstractActivity { } private void init() { - buttonLatitude.setOnClickListener(new FindByCoordsAction()); - buttonLongitude.setOnClickListener(new FindByCoordsAction()); + buttonLatitude.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + updateCoordinates(); + } + }); + buttonLongitude.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + updateCoordinates(); + } + }); buttonSearchCoords.setOnClickListener(new View.OnClickListener() { @@ -277,21 +289,16 @@ public class SearchActivity extends AbstractActivity { } } - private class FindByCoordsAction implements OnClickListener { - - @Override - public void onClick(final View arg0) { - final CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(SearchActivity.this, null, null, app.currentGeo()); - coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { - @Override - public void update(final Geopoint gp) { - buttonLatitude.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); - buttonLongitude.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); - } - }); - coordsDialog.show(); - } + private void updateCoordinates() { + final CoordinatesInputDialog coordsDialog = CoordinatesInputDialog.getInstance(null, null, app.currentGeo()); + coordsDialog.setCancelable(true); + coordsDialog.show(getSupportFragmentManager(), "wpedit_dialog"); + } + + @Override + public void updateCoordinates(final Geopoint gp) { + buttonLatitude.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); + buttonLongitude.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); } private void findByCoordsFn() { diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java index 12a2522..2e8a3f6 100644 --- a/main/src/cgeo/geocaching/SearchResult.java +++ b/main/src/cgeo/geocaching/SearchResult.java @@ -11,7 +11,9 @@ import cgeo.geocaching.gcvote.GCVote; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; + import rx.Observable; import rx.functions.Func1; import rx.functions.Func2; @@ -60,6 +62,14 @@ public class SearchResult implements Parcelable { } /** + * Build a new empty search result with an error status. + */ + public SearchResult(final StatusCode statusCode) { + this(); + error = statusCode; + } + + /** * Copy a search result, for example to apply different filters on it. * * @param searchResult the original search result, which cannot be null @@ -155,6 +165,7 @@ public class SearchResult implements Parcelable { return 0; } + @NonNull public Set<String> getGeocodes() { return Collections.unmodifiableSet(geocodes); } @@ -218,7 +229,7 @@ public class SearchResult implements Parcelable { int excluded = 0; for (Geocache cache : caches) { // Is there any reason to exclude the cache from the list? - final boolean excludeCache = (excludeDisabled && cache.isDisabled()) || + final boolean excludeCache = (excludeDisabled && (cache.isDisabled() || cache.isArchived())) || (excludeMine && (cache.isOwner() || cache.isFound())) || (!cacheType.contains(cache)); if (excludeCache) { @@ -319,7 +330,7 @@ public class SearchResult implements Parcelable { searchResult.addSearchResult(searchResult2); return searchResult; } - }).toBlockingObservable().first(); + }).toBlocking().first(); } } diff --git a/main/src/cgeo/geocaching/SelectMapfileActivity.java b/main/src/cgeo/geocaching/SelectMapfileActivity.java index c617012..b2cdf17 100644 --- a/main/src/cgeo/geocaching/SelectMapfileActivity.java +++ b/main/src/cgeo/geocaching/SelectMapfileActivity.java @@ -115,8 +115,7 @@ public class SelectMapfileActivity extends AbstractFileListActivity<FileSelectio } if (requestCode == REQUEST_DIRECTORY) { - final String directory = new File(data.getData().getPath()).getAbsolutePath(); - mapFile = directory; + mapFile = new File(data.getData().getPath()).getAbsolutePath(); close(); } } diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java index 16fce37..134e134 100644 --- a/main/src/cgeo/geocaching/StaticMapsActivity.java +++ b/main/src/cgeo/geocaching/StaticMapsActivity.java @@ -1,8 +1,9 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RxUtils; import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.Extra; @@ -11,7 +12,6 @@ import org.androidannotations.annotations.OptionsMenu; import org.apache.commons.collections4.CollectionUtils; import android.app.ProgressDialog; -import android.content.Context; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Handler; @@ -25,7 +25,7 @@ import java.util.List; @EActivity @OptionsMenu(R.menu.static_maps_activity_options) -public class StaticMapsActivity extends AbstractActivity { +public class StaticMapsActivity extends AbstractActionBarActivity { private static final String EXTRAS_WAYPOINT = "waypoint"; private static final String EXTRAS_DOWNLOAD = "download"; @@ -153,7 +153,7 @@ public class StaticMapsActivity extends AbstractActivity { final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); if (waypointId == null) { showToast(res.getString(R.string.info_storing_static_maps)); - StaticMapsProvider.storeCacheStaticMap(cache, true); + RxUtils.waitForCompletion(StaticMapsProvider.storeCacheStaticMap(cache)); return cache.hasStaticMap(); } final Waypoint waypoint = cache.getWaypointById(waypointId); @@ -161,18 +161,10 @@ public class StaticMapsActivity extends AbstractActivity { showToast(res.getString(R.string.info_storing_static_maps)); // refresh always removes old waypoint files StaticMapsProvider.removeWpStaticMaps(waypoint, geocode); - StaticMapsProvider.storeWaypointStaticMap(cache, waypoint, true); + RxUtils.waitForCompletion(StaticMapsProvider.storeWaypointStaticMap(cache, waypoint)); return StaticMapsProvider.hasStaticMapForWaypoint(geocode, waypoint); } showToast(res.getString(R.string.err_detail_not_load_map_static)); return false; } - - public static void startActivity(final Context activity, final String geocode, final boolean download, final Waypoint waypoint) { - StaticMapsActivity_.IntentBuilder_ builder = StaticMapsActivity_.intent(activity).geocode(geocode).download(download); - if (waypoint != null) { - builder.waypointId(waypoint.getId()); - } - builder.start(); - } }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/StaticMapsProvider.java b/main/src/cgeo/geocaching/StaticMapsProvider.java index eaab159..0551fc0 100644 --- a/main/src/cgeo/geocaching/StaticMapsProvider.java +++ b/main/src/cgeo/geocaching/StaticMapsProvider.java @@ -1,7 +1,6 @@ package cgeo.geocaching; import cgeo.geocaching.compatibility.Compatibility; -import cgeo.geocaching.concurrent.BlockingThreadPool; import cgeo.geocaching.files.LocalStorage; import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.network.Network; @@ -11,15 +10,22 @@ import cgeo.geocaching.utils.FileUtils; import cgeo.geocaching.utils.Log; import ch.boye.httpclientandroidlib.HttpResponse; + import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import rx.Observable; +import rx.functions.Action0; +import rx.schedulers.Schedulers; +import rx.util.async.Async; + import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Point; import java.io.File; -import java.util.concurrent.TimeUnit; +import java.util.LinkedList; +import java.util.List; public final class StaticMapsProvider { static final int MAPS_LEVEL_MAX = 5; @@ -34,9 +40,6 @@ public final class StaticMapsProvider { /** We assume there is no real usable image with less than 1k. */ private static final int MIN_MAP_IMAGE_BYTES = 1000; - /** ThreadPool restricting this to 1 Thread. **/ - private static final BlockingThreadPool POOL = new BlockingThreadPool(1, Thread.MIN_PRIORITY); - /** * max size in free API version: https://developers.google.com/maps/documentation/staticmaps/#Imagesizes */ @@ -50,69 +53,78 @@ public final class StaticMapsProvider { return LocalStorage.getStorageFile(geocode, MAP_FILENAME_PREFIX + prefix, false, createDirs); } - private static void downloadDifferentZooms(final String geocode, final String markerUrl, final String prefix, final String latlonMap, final int edge, final Parameters waypoints) { - downloadMap(geocode, 20, SATELLITE, markerUrl, prefix + '1', "", latlonMap, edge, edge, waypoints); - downloadMap(geocode, 18, SATELLITE, markerUrl, prefix + '2', "", latlonMap, edge, edge, waypoints); - downloadMap(geocode, 16, ROADMAP, markerUrl, prefix + '3', "", latlonMap, edge, edge, waypoints); - downloadMap(geocode, 14, ROADMAP, markerUrl, prefix + '4', "", latlonMap, edge, edge, waypoints); - downloadMap(geocode, 11, ROADMAP, markerUrl, prefix + '5', "", latlonMap, edge, edge, waypoints); + private static Observable<String> downloadDifferentZooms(final String geocode, final String markerUrl, final String prefix, final String latlonMap, final int edge, final Parameters waypoints) { + return Observable.merge(downloadMap(geocode, 20, SATELLITE, markerUrl, prefix + '1', "", latlonMap, edge, edge, waypoints), + downloadMap(geocode, 18, SATELLITE, markerUrl, prefix + '2', "", latlonMap, edge, edge, waypoints), + downloadMap(geocode, 16, ROADMAP, markerUrl, prefix + '3', "", latlonMap, edge, edge, waypoints), + downloadMap(geocode, 14, ROADMAP, markerUrl, prefix + '4', "", latlonMap, edge, edge, waypoints), + downloadMap(geocode, 11, ROADMAP, markerUrl, prefix + '5', "", latlonMap, edge, edge, waypoints)); } - private static void downloadMap(final String geocode, final int zoom, final String mapType, final String markerUrl, final String prefix, final String shadow, final String latlonMap, final int width, final int height, final Parameters waypoints) { - final Parameters params = new Parameters( - "center", latlonMap, - "zoom", String.valueOf(zoom), - "size", String.valueOf(limitSize(width)) + 'x' + String.valueOf(limitSize(height)), - "maptype", mapType, - "markers", "icon:" + markerUrl + '|' + shadow + latlonMap, - "sensor", "false"); - if (waypoints != null) { - params.addAll(waypoints); - } - final HttpResponse httpResponse = Network.getRequest(GOOGLE_STATICMAP_URL, params); + private static Observable<String> downloadMap(final String geocode, final int zoom, final String mapType, final String markerUrl, final String prefix, final String shadow, final String latlonMap, final int width, final int height, final Parameters waypoints) { + return Async.fromAction(new Action0() { + @Override + public void call() { + final Parameters params = new Parameters( + "center", latlonMap, + "zoom", String.valueOf(zoom), + "size", String.valueOf(limitSize(width)) + 'x' + String.valueOf(limitSize(height)), + "maptype", mapType, + "markers", "icon:" + markerUrl + '|' + shadow + latlonMap, + "sensor", "false"); + if (waypoints != null) { + params.addAll(waypoints); + } + final HttpResponse httpResponse = Network.getRequest(GOOGLE_STATICMAP_URL, params); - if (httpResponse == null) { - Log.e("StaticMapsProvider.downloadMap: httpResponse is null"); - return; - } - if (httpResponse.getStatusLine().getStatusCode() != 200) { - Log.d("StaticMapsProvider.downloadMap: httpResponseCode = " + httpResponse.getStatusLine().getStatusCode()); - return; - } - final File file = getMapFile(geocode, prefix, true); - if (LocalStorage.saveEntityToFile(httpResponse, file)) { - // Delete image if it has no contents - final long fileSize = file.length(); - if (fileSize < MIN_MAP_IMAGE_BYTES) { - FileUtils.deleteIgnoringFailure(file); + if (httpResponse == null) { + Log.e("StaticMapsProvider.downloadMap: httpResponse is null"); + return; + } + if (httpResponse.getStatusLine().getStatusCode() != 200) { + Log.d("StaticMapsProvider.downloadMap: httpResponseCode = " + httpResponse.getStatusLine().getStatusCode()); + return; + } + final File file = getMapFile(geocode, prefix, true); + if (LocalStorage.saveEntityToFile(httpResponse, file)) { + // Delete image if it has no contents + final long fileSize = file.length(); + if (fileSize < MIN_MAP_IMAGE_BYTES) { + FileUtils.deleteIgnoringFailure(file); + } + } } - } + }, prefix, Schedulers.io()); } private static int limitSize(final int imageSize) { return Math.min(imageSize, GOOGLE_MAPS_MAX_SIZE); } - public static void downloadMaps(final Geocache cache) { + public static Observable<String> downloadMaps(final Geocache cache) { if ((!Settings.isStoreOfflineMaps() && !Settings.isStoreOfflineWpMaps()) || StringUtils.isBlank(cache.getGeocode())) { - return; + return Observable.empty(); } int edge = guessMaxDisplaySide(); + final List<Observable<String>> downloaders = new LinkedList<Observable<String>>(); + if (Settings.isStoreOfflineMaps() && cache.getCoords() != null) { - storeCachePreviewMap(cache); - storeCacheStaticMap(cache, edge, false); + downloaders.add(storeCachePreviewMap(cache)); + downloaders.add(storeCacheStaticMap(cache, edge)); } // clean old and download static maps for waypoints if one is missing if (Settings.isStoreOfflineWpMaps()) { for (final Waypoint waypoint : cache.getWaypoints()) { if (!hasAllStaticMapsForWaypoint(cache.getGeocode(), waypoint)) { - refreshAllWpStaticMaps(cache, edge); + downloaders.add(refreshAllWpStaticMaps(cache, edge)); } } } + + return Observable.merge(downloaders); } /** @@ -123,44 +135,47 @@ public final class StaticMapsProvider { * @param edge * The boundings */ - private static void refreshAllWpStaticMaps(final Geocache cache, final int edge) { + private static Observable<String> refreshAllWpStaticMaps(final Geocache cache, final int edge) { LocalStorage.deleteFilesWithPrefix(cache.getGeocode(), MAP_FILENAME_PREFIX + WAYPOINT_PREFIX); + final List<Observable<String>> downloaders = new LinkedList<Observable<String>>(); for (Waypoint waypoint : cache.getWaypoints()) { - storeWaypointStaticMap(cache.getGeocode(), edge, waypoint, false); + downloaders.add(storeWaypointStaticMap(cache.getGeocode(), edge, waypoint)); } + return Observable.merge(downloaders); } - public static void storeWaypointStaticMap(final Geocache cache, final Waypoint waypoint, final boolean waitForResult) { - int edge = StaticMapsProvider.guessMaxDisplaySide(); - storeWaypointStaticMap(cache.getGeocode(), edge, waypoint, waitForResult); + public static Observable<String> storeWaypointStaticMap(final Geocache cache, final Waypoint waypoint) { + final int edge = StaticMapsProvider.guessMaxDisplaySide(); + return storeWaypointStaticMap(cache.getGeocode(), edge, waypoint); } - private static void storeWaypointStaticMap(final String geocode, final int edge, final Waypoint waypoint, final boolean waitForResult) { + private static Observable<String> storeWaypointStaticMap(final String geocode, final int edge, final Waypoint waypoint) { if (geocode == null) { Log.e("storeWaypointStaticMap - missing input parameter geocode"); - return; + return Observable.empty(); } if (waypoint == null) { Log.e("storeWaypointStaticMap - missing input parameter waypoint"); - return; + return Observable.empty(); } if (waypoint.getCoords() == null) { - return; + return Observable.empty(); } String wpLatlonMap = waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); String wpMarkerUrl = getWpMarkerUrl(waypoint); if (!hasAllStaticMapsForWaypoint(geocode, waypoint)) { // download map images in separate background thread for higher performance - downloadMaps(geocode, wpMarkerUrl, WAYPOINT_PREFIX + waypoint.getId() + '_' + waypoint.getStaticMapsHashcode() + "_", wpLatlonMap, edge, null, waitForResult); + return downloadMaps(geocode, wpMarkerUrl, WAYPOINT_PREFIX + waypoint.getId() + '_' + waypoint.getStaticMapsHashcode() + "_", wpLatlonMap, edge, null); } + return Observable.empty(); } - public static void storeCacheStaticMap(final Geocache cache, final boolean waitForResult) { + public static Observable<String> storeCacheStaticMap(final Geocache cache) { int edge = guessMaxDisplaySide(); - storeCacheStaticMap(cache, edge, waitForResult); + return storeCacheStaticMap(cache, edge); } - private static void storeCacheStaticMap(final Geocache cache, final int edge, final boolean waitForResult) { + private static Observable<String> storeCacheStaticMap(final Geocache cache, final int edge) { final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); final Parameters waypoints = new Parameters(); for (final Waypoint waypoint : cache.getWaypoints()) { @@ -172,15 +187,15 @@ public final class StaticMapsProvider { } // download map images in separate background thread for higher performance final String cacheMarkerUrl = getCacheMarkerUrl(cache); - downloadMaps(cache.getGeocode(), cacheMarkerUrl, "", latlonMap, edge, waypoints, waitForResult); + return downloadMaps(cache.getGeocode(), cacheMarkerUrl, "", latlonMap, edge, waypoints); } - public static void storeCachePreviewMap(final Geocache cache) { + public static Observable<String> storeCachePreviewMap(final Geocache cache) { final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); final Point displaySize = Compatibility.getDisplaySize(); final int minSize = Math.min(displaySize.x, displaySize.y); final String markerUrl = MARKERS_URL + "my_location_mdpi.png"; - downloadMap(cache.getGeocode(), 15, ROADMAP, markerUrl, PREFIX_PREVIEW, "shadow:false|", latlonMap, minSize, minSize, null); + return downloadMap(cache.getGeocode(), 15, ROADMAP, markerUrl, PREFIX_PREVIEW, "shadow:false|", latlonMap, minSize, minSize, null); } private static int guessMaxDisplaySide() { @@ -188,24 +203,10 @@ public final class StaticMapsProvider { return Math.max(displaySize.x, displaySize.y) - 25; } - private static void downloadMaps(final String geocode, final String markerUrl, final String prefix, final String latlonMap, final int edge, - final Parameters waypoints, final boolean waitForResult) { - if (waitForResult) { - downloadDifferentZooms(geocode, markerUrl, prefix, latlonMap, edge, waypoints); - } - else { - final Runnable currentTask = new Runnable() { - @Override - public void run() { - downloadDifferentZooms(geocode, markerUrl, prefix, latlonMap, edge, waypoints); - } - }; - try { - POOL.add(currentTask, 20, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.e("StaticMapsProvider.downloadMaps error adding task", e); - } - } + private static Observable<String> downloadMaps(final String geocode, final String markerUrl, final String prefix, + final String latlonMap, final int edge, + final Parameters waypoints) { + return downloadDifferentZooms(geocode, markerUrl, prefix, latlonMap, edge, waypoints); } private static String getCacheMarkerUrl(final Geocache cache) { @@ -213,7 +214,7 @@ public final class StaticMapsProvider { url.append("marker_cache_").append(cache.getType().id); if (cache.isFound()) { url.append("_found"); - } else if (cache.isDisabled()) { + } else if (cache.isDisabled() || cache.isArchived()) { url.append("_disabled"); } url.append(".png"); diff --git a/main/src/cgeo/geocaching/StatusFragment.java b/main/src/cgeo/geocaching/StatusFragment.java index f8552d7..553acc1 100644 --- a/main/src/cgeo/geocaching/StatusFragment.java +++ b/main/src/cgeo/geocaching/StatusFragment.java @@ -31,7 +31,8 @@ public class StatusFragment extends Fragment { final ViewGroup statusGroup = (ViewGroup) inflater.inflate(R.layout.status, container, false); final ImageView statusIcon = (ImageView) statusGroup.findViewById(R.id.status_icon); final TextView statusMessage = (TextView) statusGroup.findViewById(R.id.status_message); - statusSubscription = AndroidObservable.bindFragment(this, StatusUpdater.latestStatus).subscribe(new Action1<Status>() { + statusSubscription = AndroidObservable.bindFragment(this, StatusUpdater.latestStatus).subscribeOn(Schedulers.io()) + .subscribe(new Action1<Status>() { @Override public void call(final Status status) { if (status == null) { @@ -77,7 +78,7 @@ public class StatusFragment extends Fragment { statusGroup.setClickable(false); } } - }, Schedulers.io()); + }); return statusGroup; } diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java index 81d23c9..2a228c1 100644 --- a/main/src/cgeo/geocaching/TrackableActivity.java +++ b/main/src/cgeo/geocaching/TrackableActivity.java @@ -25,6 +25,7 @@ import cgeo.geocaching.utils.UnknownTagsHandler; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; + import rx.android.observables.AndroidObservable; import rx.android.observables.ViewObservable; import rx.functions.Action1; @@ -36,12 +37,15 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.support.v7.app.ActionBar; +import android.support.v7.view.ActionMode; import android.text.Html; -import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ScrollView; @@ -74,7 +78,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi private final Handler loadTrackableHandler = new Handler() { @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { if (trackable == null) { if (waitDialog != null) { waitDialog.dismiss(); @@ -110,13 +114,27 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi if (waitDialog != null) { waitDialog.dismiss(); } + + // if we have a newer Android device setup Android Beam for easy cache sharing + initializeAndroidBeam( + new ActivitySharingInterface() { + @Override + public String getUri() { + return trackable.getUrl(); + } + } + ); } }; private CharSequence clickedItemText = null; + /** + * Action mode of the current contextual action bar (e.g. for copy and share actions). + */ + private ActionMode currentActionMode; @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState, R.layout.viewpager_activity); // set title in code, as the activity needs a hard coded title due to the intent filters @@ -198,43 +216,13 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - switch (viewId) { - case R.id.value: // name, TB-code, origin, released, distance - final String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); - buildDetailsContextMenu(menu, clickedItemText, itemTitle, true); - break; - case R.id.goal: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_goal), false); - break; - case R.id.details: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_details), false); - break; - case R.id.log: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_logs), false); - break; - default: - break; - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - return onClipboardItemSelected(item, clickedItemText) || onOptionsItemSelected(item); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.trackable_activity, menu); return true; } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case R.id.menu_log_touch: LogTrackableActivity.startActivity(this, trackable); @@ -242,16 +230,15 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi case R.id.menu_browser_trackable: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(trackable.getUrl()))); return true; - default: - return false; } + return super.onOptionsItemSelected(item); } @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(final Menu menu) { if (trackable != null) { - menu.findItem(R.id.menu_log_touch).setEnabled(StringUtils.isNotBlank(geocode) && trackable.isLoggable()); - menu.findItem(R.id.menu_browser_trackable).setEnabled(StringUtils.isNotBlank(trackable.getUrl())); + menu.findItem(R.id.menu_log_touch).setVisible(StringUtils.isNotBlank(geocode) && trackable.isLoggable()); + menu.findItem(R.id.menu_browser_trackable).setVisible(StringUtils.isNotBlank(trackable.getUrl())); } return super.onPrepareOptionsMenu(menu); } @@ -262,7 +249,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi final private String guid; final private String id; - public LoadTrackableThread(Handler handlerIn, String geocodeIn, String guidIn, String idIn) { + public LoadTrackableThread(final Handler handlerIn, final String geocodeIn, final String guidIn, final String idIn) { handler = handlerIn; geocode = geocodeIn; guid = guidIn; @@ -272,19 +259,20 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi @Override public void run() { if (StringUtils.isNotEmpty(geocode)) { - trackable = DataStore.loadTrackable(geocode); - - if (trackable == null || trackable.isLoggable()) { - // iterate over the connectors as some codes may be handled by multiple connectors - for (final TrackableConnector trackableConnector : ConnectorFactory.getTrackableConnectors()) { - if (trackableConnector.canHandleTrackable(geocode)) { - trackable = trackableConnector.searchTrackable(geocode, guid, id); - if (trackable != null) { - break; - } + + // iterate over the connectors as some codes may be handled by multiple connectors + for (final TrackableConnector trackableConnector : ConnectorFactory.getTrackableConnectors()) { + if (trackableConnector.canHandleTrackable(geocode)) { + trackable = trackableConnector.searchTrackable(geocode, guid, id); + if (trackable != null) { + break; } } } + // Check local storage (offline case) + if (trackable == null) { + trackable = DataStore.loadTrackable(geocode); + } } // fall back to GC search by GUID if (trackable == null) { @@ -298,7 +286,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi final private String url; final private Handler handler; - public TrackableIconThread(String urlIn, Handler handlerIn) { + public TrackableIconThread(final String urlIn, final Handler handlerIn) { url = urlIn; handler = handlerIn; } @@ -322,18 +310,18 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } private static class TrackableIconHandler extends Handler { - final private TextView view; + final private ActionBar view; - public TrackableIconHandler(TextView viewIn) { + public TrackableIconHandler(final ActionBar viewIn) { view = viewIn; } @Override - public void handleMessage(Message message) { + public void handleMessage(final Message message) { final BitmapDrawable image = (BitmapDrawable) message.obj; if (image != null && view != null) { image.setBounds(0, 0, view.getHeight(), view.getHeight()); - view.setCompoundDrawables(image, null, null, null); + view.setIcon(image); } } } @@ -348,7 +336,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } @Override - protected PageViewCreator createViewCreator(Page page) { + protected PageViewCreator createViewCreator(final Page page) { switch (page) { case DETAILS: return new DetailsViewCreator(); @@ -359,7 +347,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } @Override - protected String getTitle(Page page) { + protected String getTitle(final Page page) { return res.getString(page.resId); } @@ -392,13 +380,13 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi // action bar icon if (StringUtils.isNotBlank(trackable.getIconUrl())) { - final TrackableIconHandler iconHandler = new TrackableIconHandler(((TextView) findViewById(R.id.actionbar_title))); + final TrackableIconHandler iconHandler = new TrackableIconHandler(getSupportActionBar()); final TrackableIconThread iconThread = new TrackableIconThread(trackable.getIconUrl(), iconHandler); iconThread.start(); } // trackable name - registerForContextMenu(details.add(R.string.trackable_name, StringUtils.isNotBlank(trackable.getName()) ? Html.fromHtml(trackable.getName()).toString() : res.getString(R.string.trackable_unknown))); + addContextMenu(details.add(R.string.trackable_name, StringUtils.isNotBlank(trackable.getName()) ? Html.fromHtml(trackable.getName()).toString() : res.getString(R.string.trackable_unknown))); // trackable type String tbType; @@ -410,7 +398,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi details.add(R.string.trackable_type, tbType); // trackable geocode - registerForContextMenu(details.add(R.string.trackable_code, trackable.getGeocode())); + addContextMenu(details.add(R.string.trackable_code, trackable.getGeocode())); // trackable owner final TextView owner = details.add(R.string.trackable_owner, res.getString(R.string.trackable_unknown)); @@ -455,7 +443,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi if (Trackable.SPOTTED_CACHE == trackable.getSpottedType()) { spotted.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { if (StringUtils.isNotBlank(trackable.getSpottedGuid())) { CacheDetailActivity.startActivityGuid(TrackableActivity.this, trackable.getSpottedGuid(), trackable.getSpottedName()); } @@ -479,17 +467,17 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi if (StringUtils.isNotBlank(trackable.getOrigin())) { final TextView origin = details.add(R.string.trackable_origin, ""); origin.setText(Html.fromHtml(trackable.getOrigin()), TextView.BufferType.SPANNABLE); - registerForContextMenu(origin); + addContextMenu(origin); } // trackable released if (trackable.getReleased() != null) { - registerForContextMenu(details.add(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime()))); + addContextMenu(details.add(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime()))); } // trackable distance if (trackable.getDistance() >= 0) { - registerForContextMenu(details.add(R.string.trackable_distance, Units.getDistanceFromKilometers(trackable.getDistance()))); + addContextMenu(details.add(R.string.trackable_distance, Units.getDistanceFromKilometers(trackable.getDistance()))); } // trackable goal @@ -498,7 +486,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi goalTextView.setVisibility(View.VISIBLE); goalTextView.setText(Html.fromHtml(trackable.getGoal(), new HtmlImage(geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); goalTextView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); - registerForContextMenu(goalTextView); + addContextMenu(goalTextView); } // trackable details @@ -507,7 +495,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi detailsTextView.setVisibility(View.VISIBLE); detailsTextView.setText(Html.fromHtml(trackable.getDetails(), new HtmlImage(geocode, true, 0, false), new UnknownTagsHandler()), TextView.BufferType.SPANNABLE); detailsTextView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); - registerForContextMenu(detailsTextView); + addContextMenu(detailsTextView); } // trackable image @@ -538,4 +526,70 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } + public void addContextMenu(final View view) { + view.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(final View v) { + return startContextualActionBar(view); + } + }); + + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(final View v) { + startContextualActionBar(view); + } + }); + } + + private boolean startContextualActionBar(final View view) { + if (currentActionMode != null) { + return false; + } + currentActionMode = startSupportActionMode(new ActionMode.Callback() { + + @Override + public boolean onPrepareActionMode(final ActionMode actionMode, final Menu menu) { + final int viewId = view.getId(); + assert view instanceof TextView; + clickedItemText = ((TextView) view).getText(); + switch (viewId) { + case R.id.value: // name, TB-code, origin, released, distance + final String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); + buildDetailsContextMenu(actionMode, menu, clickedItemText, itemTitle, true); + return true; + case R.id.goal: + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.trackable_goal), false); + return true; + case R.id.details: + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.trackable_details), false); + return true; + case R.id.log: + buildDetailsContextMenu(actionMode, menu, clickedItemText, res.getString(R.string.cache_logs), false); + return true; + } + return false; + } + + @Override + public void onDestroyActionMode(final ActionMode actionMode) { + currentActionMode = null; + } + + @Override + public boolean onCreateActionMode(final ActionMode actionMode, final Menu menu) { + actionMode.getMenuInflater().inflate(R.menu.details_context, menu); + return true; + } + + @Override + public boolean onActionItemClicked(final ActionMode actionMode, final MenuItem menuItem) { + return onClipboardItemSelected(actionMode, menuItem, clickedItemText); + } + }); + return false; + } + } diff --git a/main/src/cgeo/geocaching/UsefulAppsActivity.java b/main/src/cgeo/geocaching/UsefulAppsActivity.java index 39c527d..1159453 100644 --- a/main/src/cgeo/geocaching/UsefulAppsActivity.java +++ b/main/src/cgeo/geocaching/UsefulAppsActivity.java @@ -3,7 +3,7 @@ package cgeo.geocaching; import butterknife.ButterKnife; import butterknife.InjectView; -import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.AbstractActionBarActivity; import cgeo.geocaching.ui.AbstractViewHolder; import android.app.Activity; @@ -18,7 +18,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; -public class UsefulAppsActivity extends AbstractActivity { +public class UsefulAppsActivity extends AbstractActionBarActivity { @InjectView(R.id.apps_list) protected ListView list; diff --git a/main/src/cgeo/geocaching/Waypoint.java b/main/src/cgeo/geocaching/Waypoint.java index efedff5..275882f 100644 --- a/main/src/cgeo/geocaching/Waypoint.java +++ b/main/src/cgeo/geocaching/Waypoint.java @@ -157,7 +157,7 @@ public class Waypoint implements IWaypoint { } public String getUrl() { - return "http://www.geocaching.com//seek/cache_details.aspx?wp=" + geocode; + return "http://www.geocaching.com/seek/cache_details.aspx?wp=" + geocode; } @Override diff --git a/main/src/cgeo/geocaching/WaypointPopup.java b/main/src/cgeo/geocaching/WaypointPopup.java index 916ad4c..f1ffc1d 100644 --- a/main/src/cgeo/geocaching/WaypointPopup.java +++ b/main/src/cgeo/geocaching/WaypointPopup.java @@ -1,115 +1,35 @@ package cgeo.geocaching; -import butterknife.ButterKnife; -import butterknife.InjectView; - -import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.Units; -import cgeo.geocaching.sensors.IGeoData; -import cgeo.geocaching.ui.CacheDetailsCreator; -import cgeo.geocaching.utils.Log; - -import org.apache.commons.lang3.StringUtils; - import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.view.Window; -public class WaypointPopup extends AbstractPopupActivity { - @InjectView(R.id.actionbar_title) protected TextView actionBarTitle; - @InjectView(R.id.waypoint_details_list) protected LinearLayout waypointDetailsLayout; - @InjectView(R.id.edit) protected Button buttonEdit; - @InjectView(R.id.details_list) protected LinearLayout cacheDetailsLayout; +import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; +public class WaypointPopup extends AbstractActivity { private int waypointId = 0; - private Waypoint waypoint = null; - private TextView waypointDistance = null; - - public WaypointPopup() { - super(R.layout.waypoint_popup); - } + private String geocode; @Override - public void onCreate(final Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ButterKnife.inject(this); - // get parameters - final Bundle extras = getIntent().getExtras(); - if (extras != null) { - waypointId = extras.getInt(Intents.EXTRA_WAYPOINT_ID); - } - } - - @Override - public void onUpdateGeoData(IGeoData geo) { - if (geo.getCoords() != null && waypoint != null && waypoint.getCoords() != null) { - waypointDistance.setText(Units.getDistanceFromKilometers(geo.getCoords().distanceTo(waypoint.getCoords()))); - waypointDistance.bringToFront(); - } - } - - @Override - protected void init() { - super.init(); - waypoint = DataStore.loadWaypoint(waypointId); - try { - if (StringUtils.isNotBlank(waypoint.getName())) { - setTitle(waypoint.getName()); - } else { - setTitle(waypoint.getGeocode()); - } - - actionBarTitle.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(waypoint.getWaypointType().markerId), null, null, null); - - details = new CacheDetailsCreator(this, waypointDetailsLayout); + supportRequestWindowFeature(Window.FEATURE_NO_TITLE); - //Waypoint geocode - details.add(R.string.cache_geocode, waypoint.getPrefix() + waypoint.getGeocode().substring(2)); - details.addDistance(waypoint, waypointDistance); - waypointDistance = details.getValueView(); - details.add(R.string.waypoint_note, waypoint.getNote()); + this.setTheme(ActivityMixin.getDialogTheme()); - buttonEdit.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View arg0) { - EditWaypointActivity.startActivityEditWaypoint(WaypointPopup.this, cache, waypoint.getId()); - finish(); - } - }); - - details = new CacheDetailsCreator(this, cacheDetailsLayout); - details.add(R.string.cache_name, cache.getName()); - - addCacheDetails(); - - } catch (Exception e) { - Log.e("WaypointPopup.init", e); + final Bundle extras = getIntent().getExtras(); + if (extras != null) { + waypointId = extras.getInt(Intents.EXTRA_WAYPOINT_ID); + geocode = extras.getString(Intents.EXTRA_GEOCODE); } - } - - @Override - public void navigateTo() { - NavigationAppFactory.startDefaultNavigationApplication(1, this, waypoint); - } + showDialog(); - /** - * Tries to navigate to the {@link Geocache} of this activity. - */ - @Override - protected void startDefaultNavigation2() { - if (waypoint == null || waypoint.getCoords() == null) { - showToast(res.getString(R.string.cache_coordinates_no)); - return; - } - NavigationAppFactory.startDefaultNavigationApplication(2, this, waypoint); - finish(); } public static void startActivity(final Context context, final int waypointId, final String geocode) { @@ -119,16 +39,22 @@ public class WaypointPopup extends AbstractPopupActivity { context.startActivity(popupIntent); } - @Override - public void showNavigationMenu() { - NavigationAppFactory.showNavigationMenu(this, null, waypoint, null); - } - @Override - protected Geopoint getCoordinates() { - if (waypoint == null) { - return null; + void showDialog() { + // DialogFragment.show() will take care of adding the fragment + // in a transaction. We also want to remove any currently showing + // dialog, so make our own transaction and take care of that here. + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog"); + if (prev != null) { + ft.remove(prev); } - return waypoint.getCoords(); + ft.addToBackStack(null); + + // Create and show the dialog. + DialogFragment newFragment = WaypointPopupFragment.newInstance(geocode, waypointId); + newFragment.show(ft, "dialog"); } + + } diff --git a/main/src/cgeo/geocaching/WaypointPopupFragment.java b/main/src/cgeo/geocaching/WaypointPopupFragment.java new file mode 100644 index 0000000..03d95e5 --- /dev/null +++ b/main/src/cgeo/geocaching/WaypointPopupFragment.java @@ -0,0 +1,147 @@ +package cgeo.geocaching; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.Units; +import cgeo.geocaching.sensors.IGeoData; +import cgeo.geocaching.ui.CacheDetailsCreator; +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringUtils; + +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class WaypointPopupFragment extends AbstractDialogFragment { + @InjectView(R.id.actionbar_title) protected TextView actionBarTitle; + @InjectView(R.id.waypoint_details_list) protected LinearLayout waypointDetailsLayout; + @InjectView(R.id.edit) protected Button buttonEdit; + @InjectView(R.id.details_list) protected LinearLayout cacheDetailsLayout; + + private int waypointId = 0; + private Waypoint waypoint = null; + private TextView waypointDistance = null; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.waypoint_popup, container, false); + initCustomActionBar(v); + ButterKnife.inject(this,v); + + return v; + } + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + waypointId = getArguments().getInt(WAYPOINT_ARG); + } + + @Override + protected void onUpdateGeoData(IGeoData geo) { + if (geo.getCoords() != null && waypoint != null && waypoint.getCoords() != null) { + waypointDistance.setText(Units.getDistanceFromKilometers(geo.getCoords().distanceTo(waypoint.getCoords()))); + waypointDistance.bringToFront(); + } + } + + @Override + protected void init() { + super.init(); + + waypoint = DataStore.loadWaypoint(waypointId); + try { + if (StringUtils.isNotBlank(waypoint.getName())) { + setTitle(waypoint.getName()); + } else { + setTitle(waypoint.getGeocode()); + } + + + actionBarTitle.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(waypoint.getWaypointType().markerId), null, null, null); + + //getSupportActionBar().setIcon(getResources().getDrawable(waypoint.getWaypointType().markerId)); + + details = new CacheDetailsCreator(getActivity(), waypointDetailsLayout); + + //Waypoint geocode + details.add(R.string.cache_geocode, waypoint.getPrefix() + waypoint.getGeocode().substring(2)); + details.addDistance(waypoint, waypointDistance); + waypointDistance = details.getValueView(); + details.add(R.string.waypoint_note, waypoint.getNote()); + + buttonEdit.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + EditWaypointActivity.startActivityEditWaypoint(getActivity(), cache, waypoint.getId()); + getActivity().finish(); + } + }); + + details = new CacheDetailsCreator(getActivity(), cacheDetailsLayout); + details.add(R.string.cache_name, cache.getName()); + + addCacheDetails(); + + } catch (Exception e) { + Log.e("WaypointPopup.init", e); + } + } + + @Override + public void navigateTo() { + NavigationAppFactory.startDefaultNavigationApplication(1, getActivity(), waypoint); + } + + /** + * Tries to navigate to the {@link Geocache} of this activity. + */ + @Override + public void startDefaultNavigation2() { + if (waypoint == null || waypoint.getCoords() == null) { + showToast(res.getString(R.string.cache_coordinates_no)); + return; + } + NavigationAppFactory.startDefaultNavigationApplication(2, getActivity(), waypoint); + getActivity().finish(); + } + + + + @Override + public void showNavigationMenu() { + NavigationAppFactory.showNavigationMenu(getActivity(), null, waypoint, null); + } + + @Override + protected Geopoint getCoordinates() { + if (waypoint == null) { + return null; + } + return waypoint.getCoords(); + } + + public static DialogFragment newInstance(String geocode, int waypointId) { + + Bundle args = new Bundle(); + args.putInt(WAYPOINT_ARG, waypointId); + args.putString(GEOCODE_ARG, geocode); + + DialogFragment f = new WaypointPopupFragment(); + f.setArguments(args); + f.setStyle(DialogFragment.STYLE_NO_TITLE,0); + + return f; + } +} diff --git a/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java b/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java new file mode 100644 index 0000000..a732f65 --- /dev/null +++ b/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java @@ -0,0 +1,34 @@ +package cgeo.geocaching.activity; + +import android.os.Bundle; + +/** + * Classes actually having an ActionBar (as opposed to the Dialog activities) + */ +public class AbstractActionBarActivity extends AbstractActivity { + @Override + protected void onCreate(Bundle savedInstanceState, int resourceLayoutID) { + super.onCreate(savedInstanceState, resourceLayoutID); + initUpAction(); + showProgress(false); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initUpAction(); + showProgress(false); + } + + + private void initUpAction() { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public void setTitle(CharSequence title) { + super.setTitle(title); + // reflect the title in the actionbar + ActivityMixin.setTitle(this, title); + } +} diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index 542dd05..e3df1f7 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -12,21 +12,31 @@ import cgeo.geocaching.utils.HtmlUtils; import cgeo.geocaching.utils.TranslationUtils; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import rx.Subscription; +import rx.subscriptions.Subscriptions; + +import android.annotation.TargetApi; import android.content.Intent; import android.content.res.Resources; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.nfc.NfcEvent; +import android.os.Build; import android.os.Bundle; -import android.support.v4.app.FragmentActivity; -import android.view.ContextMenu; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.view.ActionMode; +import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.Window; import android.widget.EditText; -import rx.Subscription; -import rx.subscriptions.Subscriptions; import java.util.Locale; -public abstract class AbstractActivity extends FragmentActivity implements IAbstractActivity { +public abstract class AbstractActivity extends ActionBarActivity implements IAbstractActivity { protected CgeoApplication app = null; protected Resources res = null; @@ -41,15 +51,6 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst this.keepScreenOn = keepScreenOn; } - @Override - final public void goHome(final View view) { - ActivityMixin.goHome(this); - } - - final protected void setTitle(final String title) { - ActivityMixin.setTitle(this, title); - } - final protected void showProgress(final boolean show) { ActivityMixin.showProgress(this, show); } @@ -71,7 +72,18 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + initializeCommonFields(); + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + return ActivityMixin.navigateUp(this); + } + return super.onOptionsItemSelected(item); } public void onResume(final Subscription resumeSubscription) { @@ -104,21 +116,14 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst } protected void onCreate(final Bundle savedInstanceState, final int resourceLayoutID) { - onCreate(savedInstanceState, resourceLayoutID, false); - } - - protected void onCreate(final Bundle savedInstanceState, final int resourceLayoutID, boolean useDialogTheme) { super.onCreate(savedInstanceState); initializeCommonFields(); // non declarative part of layout - if (useDialogTheme) { - setTheme(ActivityMixin.getDialogTheme()); - } else { - setTheme(); - } + setTheme(); + setContentView(resourceLayoutID); // create view variables @@ -151,9 +156,8 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst new Keyboard(this).show(view); } - protected void buildDetailsContextMenu(final ContextMenu menu, final CharSequence clickedItemText, final CharSequence fieldTitle, final boolean copyOnly) { - menu.setHeaderTitle(fieldTitle); - getMenuInflater().inflate(R.menu.details_context, menu); + protected void buildDetailsContextMenu(final ActionMode actionMode, final Menu menu, final CharSequence clickedItemText, final CharSequence fieldTitle, final boolean copyOnly) { + actionMode.setTitle(fieldTitle); menu.findItem(R.id.menu_translate_to_sys_lang).setVisible(!copyOnly); if (!copyOnly) { if (clickedItemText.length() > TranslationUtils.TRANSLATION_TEXT_LENGTH_WARN) { @@ -165,27 +169,62 @@ public abstract class AbstractActivity extends FragmentActivity implements IAbst menu.findItem(R.id.menu_translate_to_english).setVisible(!copyOnly && !localeIsEnglish); } - protected boolean onClipboardItemSelected(final MenuItem item, final CharSequence clickedItemText) { + protected boolean onClipboardItemSelected(@NonNull final ActionMode actionMode, final MenuItem item, final CharSequence clickedItemText) { switch (item.getItemId()) { // detail fields case R.id.menu_copy: ClipboardUtils.copyToClipboard(clickedItemText); showToast(res.getString(R.string.clipboard_copy_ok)); + actionMode.finish(); return true; case R.id.menu_translate_to_sys_lang: TranslationUtils.startActivityTranslate(this, Locale.getDefault().getLanguage(), HtmlUtils.extractText(clickedItemText)); + actionMode.finish(); return true; case R.id.menu_translate_to_english: TranslationUtils.startActivityTranslate(this, Locale.ENGLISH.getLanguage(), HtmlUtils.extractText(clickedItemText)); + actionMode.finish(); return true; case R.id.menu_cache_share_field: final Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, clickedItemText.toString()); startActivity(Intent.createChooser(intent, res.getText(R.string.cache_share_field))); + actionMode.finish(); return true; default: return false; } } + + // Do not support older devices than Android 4.0 + // Although there even are 2.3 devices (Nexus S) + // these are so few that we don't want to deal with the older (non Android Beam) API + + public interface ActivitySharingInterface { + /** Return an URL that represent the current activity for sharing */ + public String getUri(); + } + + protected void initializeAndroidBeam(ActivitySharingInterface sharingInterface) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + initializeICSAndroidBeam(sharingInterface); + } + } + + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + protected void initializeICSAndroidBeam(final ActivitySharingInterface sharingInterface) { + NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (nfcAdapter == null) { + return; + } + nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() { + @Override + public NdefMessage createNdefMessage(NfcEvent event) { + NdefRecord record = NdefRecord.createUri(sharingInterface.getUri()); + return new NdefMessage(new NdefRecord[]{record}); + } + }, this); + + } } diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index a5d5c14..eac191a 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -4,10 +4,10 @@ import cgeo.geocaching.CgeoApplication; import android.content.res.Resources; import android.os.Bundle; -import android.support.v4.app.FragmentListActivity; -import android.view.View; +import android.view.MenuItem; +import android.view.Window; -public abstract class AbstractListActivity extends FragmentListActivity implements +public abstract class AbstractListActivity extends ActionBarListActivity implements IAbstractActivity { private boolean keepScreenOn = false; @@ -23,11 +23,6 @@ public abstract class AbstractListActivity extends FragmentListActivity implemen this.keepScreenOn = keepScreenOn; } - @Override - final public void goHome(View view) { - ActivityMixin.goHome(this); - } - final public void showProgress(final boolean show) { ActivityMixin.showProgress(this, show); } @@ -49,7 +44,22 @@ public abstract class AbstractListActivity extends FragmentListActivity implemen @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + initializeCommonFields(); + initUpAction(); + } + + protected void initUpAction() { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId()== android.R.id.home) { + return ActivityMixin.navigateUp(this); + } + return super.onOptionsItemSelected(item); } private void initializeCommonFields() { diff --git a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java index 6e2900d..e98c935 100644 --- a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java @@ -30,7 +30,7 @@ import java.util.Map; * Enum listing all available pages of this activity. The pages available at a certain point of time are * defined by overriding {@link #getOrderedPages()}. */ -public abstract class AbstractViewPagerActivity<Page extends Enum<Page>> extends AbstractActivity { +public abstract class AbstractViewPagerActivity<Page extends Enum<Page>> extends AbstractActionBarActivity { /** * A {@link List} of all available pages. diff --git a/main/src/cgeo/geocaching/activity/ActionBarListActivity.java b/main/src/cgeo/geocaching/activity/ActionBarListActivity.java new file mode 100644 index 0000000..07c7ec3 --- /dev/null +++ b/main/src/cgeo/geocaching/activity/ActionBarListActivity.java @@ -0,0 +1,34 @@ +package cgeo.geocaching.activity; + +import android.support.v7.app.ActionBarActivity; +import android.widget.HeaderViewListAdapter; +import android.widget.ListAdapter; +import android.widget.ListView; + +/** + * Compatbility Class until cgeo switches from ListActivities to ListFragments + */ +public class ActionBarListActivity extends ActionBarActivity { + + private ListView mListView; + protected ListView getListView() { + if (mListView == null) { + mListView = (ListView) findViewById(android.R.id.list); + } + return mListView; + } + + protected void setListAdapter(ListAdapter adapter) { + getListView().setAdapter(adapter); + } + + protected ListAdapter getListAdapter() { + ListAdapter adapter = getListView().getAdapter(); + if (adapter instanceof HeaderViewListAdapter) { + return ((HeaderViewListAdapter)adapter).getWrappedAdapter(); + } + return adapter; + } +} + + diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index bfd45da..e2181d0 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -1,55 +1,45 @@ package cgeo.geocaching.activity; -import cgeo.geocaching.MainActivity; import cgeo.geocaching.R; -import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.settings.Settings; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; import android.app.Activity; import android.content.Intent; -import android.os.Build; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.NavUtils; +import android.support.v4.app.TaskStackBuilder; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; import android.view.Gravity; -import android.view.View; import android.view.WindowManager; import android.widget.EditText; -import android.widget.ProgressBar; -import android.widget.TextView; import android.widget.Toast; public final class ActivityMixin { - public final static void goHome(final Activity fromActivity) { - final Intent intent = new Intent(fromActivity, MainActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - - fromActivity.startActivity(intent); - fromActivity.finish(); - } - public static void setTitle(final Activity activity, final CharSequence text) { if (StringUtils.isBlank(text)) { return; } - final TextView title = (TextView) activity.findViewById(R.id.actionbar_title); - if (title != null) { - title.setText(text); + if (activity instanceof ActionBarActivity) { + final ActionBar actionBar = ((ActionBarActivity) activity).getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(text); + } } } - public static void showProgress(final Activity activity, final boolean show) { + public static void showProgress(final ActionBarActivity activity, final boolean show) { if (activity == null) { return; } - final ProgressBar progress = (ProgressBar) activity.findViewById(R.id.actionbar_progress); - if (show) { - progress.setVisibility(View.VISIBLE); - } else { - progress.setVisibility(View.GONE); - } + activity.setSupportProgressBarIndeterminateVisibility(show); + } public static void setTheme(final Activity activity) { @@ -62,10 +52,10 @@ public final class ActivityMixin { public static int getDialogTheme() { // Light theme dialogs don't work on Android Api < 11 - if (Settings.isLightSkin() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // The compat theme should fix this + if (Settings.isLightSkin()) { return R.style.popup_light; } - return R.style.popup_dark; } @@ -98,7 +88,12 @@ public final class ActivityMixin { } public static void invalidateOptionsMenu(Activity activity) { - Compatibility.invalidateOptionsMenu(activity); + if (activity instanceof ActionBarActivity) { + ((ActionBarActivity) activity).supportInvalidateOptionsMenu(); + } + else { + ActivityCompat.invalidateOptionsMenu(activity); + } } /** @@ -127,4 +122,27 @@ public final class ActivityMixin { int newCursor = moveCursor ? start + completeText.length() : start; editText.setSelection(newCursor); } + + public static boolean navigateUp(@NonNull final Activity activity) { + // see http://developer.android.com/training/implementing-navigation/ancestral.html + Intent upIntent = NavUtils.getParentActivityIntent(activity); + if (upIntent == null) { + activity.finish(); + return true; + } + if (NavUtils.shouldUpRecreateTask(activity, upIntent)) { + // This activity is NOT part of this app's task, so create a new task + // when navigating up, with a synthesized back stack. + TaskStackBuilder.create(activity) + // Add all of this activity's parents to the back stack + .addNextIntentWithParentStack(upIntent) + // Navigate up to the closest parent + .startActivities(); + } else { + // This activity is part of this app's task, so simply + // navigate up to the logical parent activity. + NavUtils.navigateUpTo(activity, upIntent); + } + return true; + } } diff --git a/main/src/cgeo/geocaching/activity/IAbstractActivity.java b/main/src/cgeo/geocaching/activity/IAbstractActivity.java index 7ca2322..4fb6a2a 100644 --- a/main/src/cgeo/geocaching/activity/IAbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/IAbstractActivity.java @@ -1,11 +1,8 @@ package cgeo.geocaching.activity; -import android.view.View; public interface IAbstractActivity { - public void goHome(View view); - public void showToast(String text); public void showShortToast(String text); diff --git a/main/src/cgeo/geocaching/activity/SimpleWebviewActivity.java b/main/src/cgeo/geocaching/activity/SimpleWebviewActivity.java new file mode 100644 index 0000000..83b9281 --- /dev/null +++ b/main/src/cgeo/geocaching/activity/SimpleWebviewActivity.java @@ -0,0 +1,32 @@ +package cgeo.geocaching.activity; + +import cgeo.geocaching.R; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +public class SimpleWebviewActivity extends AbstractActionBarActivity { + + private WebView webview; + + class SimplelWebviewClient extends WebViewClient { + @Override + public boolean shouldOverrideUrlLoading(final WebView view, final String url) { + webview.loadUrl(url); + return true; + } + } + + @SuppressLint("SetJavaScriptEnabled") + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState, R.layout.internal_browser); + + webview = (WebView) findViewById(R.id.webview); + webview.getSettings().setJavaScriptEnabled(true); + webview.setWebViewClient(new SimplelWebviewClient()); + webview.loadUrl(String.valueOf(getIntent().getData())); + } +} diff --git a/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java b/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java deleted file mode 100644 index 34c9074..0000000 --- a/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package cgeo.geocaching.apps.cache; - -import cgeo.geocaching.Geocache; -import cgeo.geocaching.R; -import cgeo.geocaching.enumerations.CacheAttribute; - -public class CacheBeaconApp extends AbstractGeneralApp { - - public CacheBeaconApp() { - super(getString(R.string.cache_menu_cachebeacon), R.id.cache_app_cache_beacon, "de.fun2code.android.cachebeacon"); - } - - @Override - public boolean isEnabled(Geocache cache) { - return cache.hasAttribute(CacheAttribute.WIRELESSBEACON, true); - } - -} diff --git a/main/src/cgeo/geocaching/apps/cache/GccApp.java b/main/src/cgeo/geocaching/apps/cache/GccApp.java deleted file mode 100644 index 4423977..0000000 --- a/main/src/cgeo/geocaching/apps/cache/GccApp.java +++ /dev/null @@ -1,28 +0,0 @@ -package cgeo.geocaching.apps.cache; - -import cgeo.geocaching.R; -import cgeo.geocaching.utils.ProcessUtils; - -import android.content.Intent; - -public class GccApp extends AbstractGeneralApp { - private static final String PACKAGE = "eisbehr.gcc"; - private static final String PACKAGE_PRO = "eisbehr.gcc.pro"; - - public GccApp() { - super(getString(R.string.cache_menu_gcc), R.id.cache_app_gcc, null); - } - - @Override - public boolean isInstalled() { - return ProcessUtils.isLaunchable(PACKAGE) || ProcessUtils.isLaunchable(PACKAGE_PRO); - } - - @Override - protected Intent getLaunchIntent() { - if (ProcessUtils.isLaunchable(PACKAGE_PRO)) { - return ProcessUtils.getLaunchIntent(PACKAGE_PRO); - } - return ProcessUtils.getLaunchIntent(PACKAGE); - } -} diff --git a/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java b/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java index 79a5975..b2a2cad 100644 --- a/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java +++ b/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java @@ -3,14 +3,34 @@ package cgeo.geocaching.apps.cache; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.utils.TextUtils; + +import org.apache.commons.lang3.StringUtils; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; + +import java.util.regex.Pattern; public class WhereYouGoApp extends AbstractGeneralApp { + private static final Pattern PATTERN_CARTRIDGE = Pattern.compile("(" + Pattern.quote("http://www.wherigo.com/cartridge/details.aspx?") + ".*?)" + Pattern.quote("\"")); + public WhereYouGoApp() { super(getString(R.string.cache_menu_whereyougo), R.id.cache_app_whereyougo, "menion.android.whereyougo"); } @Override public boolean isEnabled(Geocache cache) { - return cache.getType() == CacheType.WHERIGO; + return cache.getType() == CacheType.WHERIGO && StringUtils.isNotEmpty(getWhereIGoUrl(cache)); + } + + @Override + public void navigate(Activity activity, Geocache cache) { + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getWhereIGoUrl(cache)))); + } + + protected static String getWhereIGoUrl(Geocache cache) { + return TextUtils.getMatch(cache.getDescription(), PATTERN_CARTRIDGE, null); } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java index c42c2a2..a2a5803 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java @@ -4,7 +4,7 @@ import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.ILogable; import cgeo.geocaching.R; -import cgeo.geocaching.StaticMapsActivity; +import cgeo.geocaching.StaticMapsActivity_; import cgeo.geocaching.StaticMapsProvider; import cgeo.geocaching.Waypoint; import cgeo.geocaching.activity.ActivityMixin; @@ -49,7 +49,11 @@ abstract class AbstractStaticMapsApp extends AbstractApp implements CacheNavigat } final String geocode = StringUtils.upperCase(logable.getGeocode()); - StaticMapsActivity.startActivity(activity, geocode, download, waypoint); + StaticMapsActivity_.IntentBuilder_ builder = StaticMapsActivity_.intent(activity).geocode(geocode).download(download); + if (waypoint != null) { + builder.waypointId(waypoint.getId()); + } + builder.start(); return true; } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java index 19b5e02..e9bdb74 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java @@ -13,22 +13,22 @@ class DownloadStaticMapsApp extends AbstractStaticMapsApp { } @Override - public boolean isEnabled(Geocache cache) { - return !cache.hasStaticMap(); + public boolean isEnabled(final Geocache cache) { + return cache.isOffline() && !cache.hasStaticMap(); } @Override - public boolean isEnabled(Waypoint waypoint) { + public boolean isEnabled(final Waypoint waypoint) { return !hasStaticMap(waypoint); } @Override - public void navigate(Activity activity, Geocache cache) { + public void navigate(final Activity activity, final Geocache cache) { invokeStaticMaps(activity, cache, null, true); } @Override - public void navigate(Activity activity, Waypoint waypoint) { + public void navigate(final Activity activity, final Waypoint waypoint) { invokeStaticMaps(activity, null, waypoint, true); } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java index 3177a29..6120116 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java @@ -7,8 +7,6 @@ import cgeo.geocaching.Waypoint; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.AbstractAppFactory; import cgeo.geocaching.apps.App; -import cgeo.geocaching.apps.cache.CacheBeaconApp; -import cgeo.geocaching.apps.cache.GccApp; import cgeo.geocaching.apps.cache.WhereYouGoApp; import cgeo.geocaching.apps.cache.navi.GoogleNavigationApp.GoogleNavigationBikeApp; import cgeo.geocaching.apps.cache.navi.GoogleNavigationApp.GoogleNavigationDrivingApp; @@ -69,8 +67,6 @@ public final class NavigationAppFactory extends AbstractAppFactory { */ GOOGLE_MAPS_DIRECTIONS(new GoogleMapsDirectionApp(), 13, R.string.pref_navigation_menu_google_maps_directions), - CACHE_BEACON(new CacheBeaconApp(), 14, R.string.pref_navigation_menu_cache_beacon), - GCC(new GccApp(), 15, R.string.pref_navigation_menu_gcc), WHERE_YOU_GO(new WhereYouGoApp(), 16, R.string.pref_navigation_menu_where_you_go), PEBBLE(new PebbleApp(), 17, R.string.pref_navigation_menu_pebble), MAPSWITHME(new MapsWithMeApp(), 22, R.string.pref_navigation_menu_mapswithme); @@ -182,7 +178,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { builder.setTitle(R.string.cache_menu_navigate); builder.setAdapter(adapter, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int item) { + public void onClick(final DialogInterface dialog, final int item) { final NavigationAppsEnum selectedItem = adapter.getItem(item); invokeNavigation(activity, cache, waypoint, destination, selectedItem.app); } @@ -230,27 +226,27 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param cache * @return */ - public static boolean onMenuItemSelected(final MenuItem item, Activity activity, Geocache cache) { + public static boolean onMenuItemSelected(final MenuItem item, final Activity activity, final Geocache cache) { final App menuItem = getAppFromMenuItem(item); navigateCache(activity, cache, menuItem); return menuItem != null; } - private static void navigateCache(Activity activity, Geocache cache, @Nullable App app) { + private static void navigateCache(final Activity activity, final Geocache cache, @Nullable final App app) { if (app instanceof CacheNavigationApp) { final CacheNavigationApp cacheApp = (CacheNavigationApp) app; cacheApp.navigate(activity, cache); } } - private static void navigateWaypoint(Activity activity, Waypoint waypoint, @Nullable App app) { + private static void navigateWaypoint(final Activity activity, final Waypoint waypoint, @Nullable final App app) { if (app instanceof WaypointNavigationApp) { final WaypointNavigationApp waypointApp = (WaypointNavigationApp) app; waypointApp.navigate(activity, waypoint); } } - private static void navigateGeopoint(Activity activity, Geopoint destination, App app) { + private static void navigateGeopoint(final Activity activity, final Geopoint destination, final App app) { if (app instanceof GeopointNavigationApp) { final GeopointNavigationApp geopointApp = (GeopointNavigationApp) app; geopointApp.navigate(activity, destination); @@ -258,7 +254,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { } @Nullable - private static App getAppFromMenuItem(MenuItem item) { + private static App getAppFromMenuItem(final MenuItem item) { final int id = item.getItemId(); for (final NavigationAppsEnum navApp : NavigationAppsEnum.values()) { if (navApp.id == id) { @@ -276,7 +272,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param activity * @param cache */ - public static void startDefaultNavigationApplication(int defaultNavigation, Activity activity, Geocache cache) { + public static void startDefaultNavigationApplication(final int defaultNavigation, final Activity activity, final Geocache cache) { if (cache == null || cache.getCoords() == null) { ActivityMixin.showToast(activity, CgeoApplication.getInstance().getString(R.string.err_location_unknown)); return; @@ -285,7 +281,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { navigateCache(activity, cache, getDefaultNavigationApplication(defaultNavigation)); } - private static App getDefaultNavigationApplication(int defaultNavigation) { + private static App getDefaultNavigationApplication(final int defaultNavigation) { if (defaultNavigation == 2) { return getNavigationAppForId(Settings.getDefaultNavigationTool2()); } @@ -298,7 +294,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param activity * @param waypoint */ - public static void startDefaultNavigationApplication(int defaultNavigation, Activity activity, Waypoint waypoint) { + public static void startDefaultNavigationApplication(final int defaultNavigation, final Activity activity, final Waypoint waypoint) { if (waypoint == null || waypoint.getCoords() == null) { ActivityMixin.showToast(activity, CgeoApplication.getInstance().getString(R.string.err_location_unknown)); return; @@ -312,7 +308,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param activity * @param destination */ - public static void startDefaultNavigationApplication(int defaultNavigation, Activity activity, final Geopoint destination) { + public static void startDefaultNavigationApplication(final int defaultNavigation, final Activity activity, final Geopoint destination) { if (destination == null) { ActivityMixin.showToast(activity, CgeoApplication.getInstance().getString(R.string.err_location_unknown)); return; diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigonApp.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigonApp.java index da988aa..024bf37 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/NavigonApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigonApp.java @@ -23,8 +23,8 @@ class NavigonApp extends AbstractPointNavigationApp { /* * Long/Lat are float values in decimal degree format (+-DDD.DDDDD). * Example: - * intent.putExtra(INTENT_EXTRA_KEY_LATITUDE, 46.12345f); - * intent.putExtra(INTENT_EXTRA_KEY_LONGITUDE, 23.12345f); + * intent.putExtra(INTENT_EXTRA_KEY_LATITUDE, 46.12345f) + * intent.putExtra(INTENT_EXTRA_KEY_LONGITUDE, 23.12345f) */ intent.putExtra(INTENT_EXTRA_KEY_LATITUDE, (float) point.getLatitude()); intent.putExtra(INTENT_EXTRA_KEY_LONGITUDE, (float) point.getLongitude()); diff --git a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java index 9e1b3f0..5151088 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java @@ -13,22 +13,22 @@ class StaticMapApp extends AbstractStaticMapsApp { } @Override - public boolean isEnabled(Geocache cache) { - return cache.hasStaticMap(); + public boolean isEnabled(final Geocache cache) { + return cache.isOffline() && cache.hasStaticMap(); } @Override - public boolean isEnabled(Waypoint waypoint) { + public boolean isEnabled(final Waypoint waypoint) { return hasStaticMap(waypoint); } @Override - public void navigate(Activity activity, Geocache cache) { + public void navigate(final Activity activity, final Geocache cache) { invokeStaticMaps(activity, cache, null, false); } @Override - public void navigate(Activity activity, Waypoint waypoint) { + public void navigate(final Activity activity, final Waypoint waypoint) { invokeStaticMaps(activity, null, waypoint, false); } } diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel11.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel11.java deleted file mode 100644 index a425ee5..0000000 --- a/main/src/cgeo/geocaching/compatibility/AndroidLevel11.java +++ /dev/null @@ -1,17 +0,0 @@ -package cgeo.geocaching.compatibility; - -import android.annotation.TargetApi; -import android.app.Activity; - -/** - * Android level 11 support - */ -@TargetApi(11) -public class AndroidLevel11 implements AndroidLevel11Interface { - - @Override - public void invalidateOptionsMenu(final Activity activity) { - activity.invalidateOptionsMenu(); - } - -} diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel11Emulation.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel11Emulation.java deleted file mode 100644 index 6a23ed5..0000000 --- a/main/src/cgeo/geocaching/compatibility/AndroidLevel11Emulation.java +++ /dev/null @@ -1,15 +0,0 @@ -package cgeo.geocaching.compatibility; - -import android.app.Activity; - -/** - * implement level 11 API using older methods - */ -public class AndroidLevel11Emulation implements AndroidLevel11Interface { - - @Override - public void invalidateOptionsMenu(final Activity activity) { - // do nothing - } - -} diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel11Interface.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel11Interface.java deleted file mode 100644 index 236e92d..0000000 --- a/main/src/cgeo/geocaching/compatibility/AndroidLevel11Interface.java +++ /dev/null @@ -1,8 +0,0 @@ -package cgeo.geocaching.compatibility; - -import android.app.Activity; - -public interface AndroidLevel11Interface { - public void invalidateOptionsMenu(final Activity activity); - -} diff --git a/main/src/cgeo/geocaching/compatibility/Compatibility.java b/main/src/cgeo/geocaching/compatibility/Compatibility.java index a293cfd..54e2966 100644 --- a/main/src/cgeo/geocaching/compatibility/Compatibility.java +++ b/main/src/cgeo/geocaching/compatibility/Compatibility.java @@ -8,35 +8,33 @@ import android.os.Build; public final class Compatibility { - private final static int sdkVersion = Build.VERSION.SDK_INT; + private static final int SDK_VERSION = Build.VERSION.SDK_INT; - private final static AndroidLevel11Interface level11; - private final static AndroidLevel13Interface level13; - private final static AndroidLevel19Interface level19; + private static final AndroidLevel13Interface LEVEL_13; + private static final AndroidLevel19Interface LEVEL_19; static { - level11 = sdkVersion >= 11 ? new AndroidLevel11() : new AndroidLevel11Emulation(); - level13 = sdkVersion >= 13 ? new AndroidLevel13() : new AndroidLevel13Emulation(); - level19 = sdkVersion >= 19 ? new AndroidLevel19() : new AndroidLevel19Emulation(); + LEVEL_13 = SDK_VERSION >= 13 ? new AndroidLevel13() : new AndroidLevel13Emulation(); + LEVEL_19 = SDK_VERSION >= 19 ? new AndroidLevel19() : new AndroidLevel19Emulation(); } - public static void invalidateOptionsMenu(final Activity activity) { - level11.invalidateOptionsMenu(activity); + private Compatibility() { + // utility class } public static int getDisplayWidth() { - return level13.getDisplayWidth(); + return LEVEL_13.getDisplayWidth(); } public static Point getDisplaySize() { - return level13.getDisplaySize(); + return LEVEL_13.getDisplaySize(); } public static void importGpxFromStorageAccessFramework(final @NonNull Activity activity, int requestCodeImportGpx) { - level19.importGpxFromStorageAccessFramework(activity, requestCodeImportGpx); + LEVEL_19.importGpxFromStorageAccessFramework(activity, requestCodeImportGpx); } public static boolean isStorageAccessFrameworkAvailable() { - return sdkVersion >= 19; + return SDK_VERSION >= 19; } } diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index 925f6f0..294e969 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -50,7 +50,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, private static final String CACHE_URL_SHORT = "http://coord.info/"; // Double slash is used to force open in browser - private static final String CACHE_URL_LONG = "http://www.geocaching.com//seek/cache_details.aspx?wp="; + private static final String CACHE_URL_LONG = "http://www.geocaching.com/seek/cache_details.aspx?wp="; /** * Pocket queries downloaded from the website use a numeric prefix. The pocket query creator Android app adds a * verbatim "pocketquery" prefix. @@ -192,8 +192,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, @Override public boolean isOwner(final ICache cache) { - return StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), Settings.getUsername()); - + final String user = Settings.getUsername(); + return StringUtils.isNotEmpty(user) && StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), user); } @Override diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java index dc2408f..dd81507 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCMap.java +++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java @@ -146,30 +146,6 @@ public class GCMap { throw new JSONException("No data inside JSON"); } - /* - * Optimization: the grid can get ignored. The keys are the grid position in the format x_y - * It's not used at the moment due to optimizations - * But maybe we need it some day... - * - * // attach all keys with the cache positions in the tile - * Map<String, UTFGridPosition> keyPositions = new HashMap<String, UTFGridPosition>(); // JSON key, (x/y) in - * grid - * for (int y = 0; y < grid.length(); y++) { - * String rowUTF8 = grid.getString(y); - * if (rowUTF8.length() != (UTFGrid.GRID_MAXX + 1)) { - * throw new JSONException("Grid has wrong size"); - * } - * - * for (int x = 0; x < UTFGrid.GRID_MAXX; x++) { - * char c = rowUTF8.charAt(x); - * if (c != ' ') { - * short id = UTFGrid.getUTFGridId(c); - * keyPositions.put(keys.getString(id), new UTFGridPosition(x, y)); - * } - * } - * } - */ - // iterate over the data and construct all caches in this tile Map<String, List<UTFGridPosition>> positions = new HashMap<String, List<UTFGridPosition>>(); // JSON id as key Map<String, List<UTFGridPosition>> singlePositions = new HashMap<String, List<UTFGridPosition>>(); // JSON id as key diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 5422c11..6887654 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -47,6 +47,14 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import rx.Observable; +import rx.Observable.OnSubscribe; +import rx.Subscriber; +import rx.functions.Action1; +import rx.functions.Func0; +import rx.functions.Func2; +import rx.schedulers.Schedulers; + import android.net.Uri; import android.text.Html; @@ -136,7 +144,6 @@ public abstract class GCParser { while (matcherGuidAndDisabled.find()) { if (matcherGuidAndDisabled.groupCount() > 0) { - //cache.setGuid(matcherGuidAndDisabled.group(1)); if (matcherGuidAndDisabled.group(2) != null) { cache.setName(Html.fromHtml(matcherGuidAndDisabled.group(2).trim()).toString()); } @@ -335,32 +342,50 @@ public abstract class GCParser { } static SearchResult parseCache(final String page, final CancellableHandler handler) { - final SearchResult searchResult = parseCacheFromText(page, handler); + final ImmutablePair<StatusCode, Geocache> parsed = parseCacheFromText(page, handler); // attention: parseCacheFromText already stores implicitly through searchResult.addCache - if (searchResult != null && !searchResult.getGeocodes().isEmpty()) { - final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); - if (cache == null) { - return null; - } - getExtraOnlineInfo(cache, page, handler); - // too late: it is already stored through parseCacheFromText - cache.setDetailedUpdatedNow(); - if (CancellableHandler.isCancelled(handler)) { - return null; - } + if (parsed.left != StatusCode.NO_ERROR) { + return new SearchResult(parsed.left); + } + + final Geocache cache = parsed.right; + getExtraOnlineInfo(cache, page, handler); + // too late: it is already stored through parseCacheFromText + cache.setDetailedUpdatedNow(); + if (CancellableHandler.isCancelled(handler)) { + return null; + } - // save full detailed caches - CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache); - DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + // save full detailed caches + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); - // update progress message so user knows we're still working. This is more of a place holder than - // actual indication of what the program is doing - CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render); + // update progress message so user knows we're still working. This is more of a place holder than + // actual indication of what the program is doing + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render); + return new SearchResult(cache); + } + + static SearchResult parseAndSaveCacheFromText(final String page, @Nullable final CancellableHandler handler) { + final ImmutablePair<StatusCode, Geocache> parsed = parseCacheFromText(page, handler); + final SearchResult result = new SearchResult(parsed.left); + if (parsed.left == StatusCode.NO_ERROR) { + result.addAndPutInCache(Collections.singletonList(parsed.right)); + DataStore.saveLogsWithoutTransaction(parsed.right.getGeocode(), getLogsFromDetails(page).toBlocking().toIterable()); } - return searchResult; + return result; } - static SearchResult parseCacheFromText(final String pageIn, final CancellableHandler handler) { + /** + * Parse cache from text and return either an error code or a cache object in a pair. Note that inline logs are + * not parsed nor saved, while the cache itself is. + * + * @param pageIn the page text to parse + * @param handler the handler to send the progress notifications to + * @return a pair, with a {@link StatusCode} on the left, and a non-nulll cache objet on the right + * iff the status code is {@link StatusCode.NO_ERROR}. + */ + static private ImmutablePair<StatusCode, Geocache> parseCacheFromText(final String pageIn, @Nullable final CancellableHandler handler) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details); if (StringUtils.isBlank(pageIn)) { @@ -368,22 +393,17 @@ public abstract class GCParser { return null; } - final SearchResult searchResult = new SearchResult(); - if (pageIn.contains(GCConstants.STRING_UNPUBLISHED_OTHER) || pageIn.contains(GCConstants.STRING_UNPUBLISHED_FROM_SEARCH)) { - searchResult.setError(StatusCode.UNPUBLISHED_CACHE); - return searchResult; + return ImmutablePair.of(StatusCode.UNPUBLISHED_CACHE, null); } if (pageIn.contains(GCConstants.STRING_PREMIUMONLY_1) || pageIn.contains(GCConstants.STRING_PREMIUMONLY_2)) { - searchResult.setError(StatusCode.PREMIUM_ONLY); - return searchResult; + return ImmutablePair.of(StatusCode.PREMIUM_ONLY, null); } final String cacheName = Html.fromHtml(TextUtils.getMatch(pageIn, GCConstants.PATTERN_NAME, true, "")).toString(); if (GCConstants.STRING_UNKNOWN_ERROR.equalsIgnoreCase(cacheName)) { - searchResult.setError(StatusCode.UNKNOWN_ERROR); - return searchResult; + return ImmutablePair.of(StatusCode.UNKNOWN_ERROR, null); } // first handle the content with line breaks, then trim everything for easier matching and reduced memory consumption in parsed fields @@ -726,14 +746,11 @@ public abstract class GCParser { // last check for necessary cache conditions if (StringUtils.isBlank(cache.getGeocode())) { - searchResult.setError(StatusCode.UNKNOWN_ERROR); - return searchResult; + return ImmutablePair.of(StatusCode.UNKNOWN_ERROR, null); } cache.setDetailedUpdatedNow(); - searchResult.addAndPutInCache(Collections.singletonList(cache)); - DataStore.saveLogsWithoutTransaction(cache.getGeocode(), getLogsFromDetails(page, false)); - return searchResult; + return ImmutablePair.of(StatusCode.NO_ERROR, cache); } private static String getNumberString(final String numberWithPunctuation) { @@ -1622,116 +1639,142 @@ public abstract class GCParser { * * @param page * the text of the details page - * @param friends - * return friends logs only (will require a network request) - * @return a list of log entries or <code>null</code> if the logs could not be retrieved + * @return a list of log entries which will be empty if the logs could not be retrieved * */ - @Nullable - private static List<LogEntry> getLogsFromDetails(final String page, final boolean friends) { - String rawResponse; + @NonNull + private static Observable<LogEntry> getLogsFromDetails(final String page) { + // extract embedded JSON data from page + return parseLogs(false, TextUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, "")); + } - if (friends) { - final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page); - if (!userTokenMatcher.find()) { - Log.e("GCParser.loadLogsFromDetails: unable to extract userToken"); - return null; - } + private enum SpecialLogs { + FRIENDS("sf"), + OWN("sp"); - final String userToken = userTokenMatcher.group(1); - final Parameters params = new Parameters( - "tkn", userToken, - "idx", "1", - "num", String.valueOf(GCConstants.NUMBER_OF_LOGS), - "decrypt", "true", - // "sp", Boolean.toString(personal), // personal logs - "sf", Boolean.toString(friends)); + final String paramName; - final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params); - if (response == null) { - Log.e("GCParser.loadLogsFromDetails: cannot log logs, response is null"); - return null; - } - final int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - Log.e("GCParser.loadLogsFromDetails: error " + statusCode + " when requesting log information"); - return null; - } - rawResponse = Network.getResponseData(response); - if (rawResponse == null) { - Log.e("GCParser.loadLogsFromDetails: unable to read whole response"); - return null; - } - } else { - // extract embedded JSON data from page - rawResponse = TextUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, ""); + SpecialLogs(String paramName) { + this.paramName = paramName; } - return parseLogs(friends, rawResponse); + private String getParamName() { + return this.paramName; + } } - private static List<LogEntry> parseLogs(final boolean friends, String rawResponse) { - final List<LogEntry> logs = new ArrayList<LogEntry>(); - - // for non logged in users the log book is not shown - if (StringUtils.isBlank(rawResponse)) { - return logs; - } + /** + * Extract special logs (friends, own) through seperate request. + * + * @param page + * The page to extrat userToken from + * @param logType + * The logType to request + * @return Observable<LogEntry> The logs + */ + private static Observable<LogEntry> getSpecialLogs(final String page, final SpecialLogs logType) { + return Observable.defer(new Func0<Observable<? extends LogEntry>>() { + @Override + public Observable<? extends LogEntry> call() { + final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page); + if (!userTokenMatcher.find()) { + Log.e("GCParser.loadLogsFromDetails: unable to extract userToken"); + return Observable.empty(); + } - try { - final JSONObject resp = new JSONObject(rawResponse); - if (!resp.getString("status").equals("success")) { - Log.e("GCParser.loadLogsFromDetails: status is " + resp.getString("status")); - return null; + final String userToken = userTokenMatcher.group(1); + final Parameters params = new Parameters( + "tkn", userToken, + "idx", "1", + "num", String.valueOf(GCConstants.NUMBER_OF_LOGS), + logType.getParamName(), Boolean.toString(Boolean.TRUE), + "decrypt", "true"); + final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params); + if (response == null) { + Log.e("GCParser.loadLogsFromDetails: cannot log logs, response is null"); + return Observable.empty(); + } + final int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != 200) { + Log.e("GCParser.loadLogsFromDetails: error " + statusCode + " when requesting log information"); + return Observable.empty(); + } + String rawResponse = Network.getResponseData(response); + if (rawResponse == null) { + Log.e("GCParser.loadLogsFromDetails: unable to read whole response"); + return Observable.empty(); + } + return parseLogs(true, rawResponse); } + }).subscribeOn(Schedulers.io()); + } - final JSONArray data = resp.getJSONArray("data"); + private static Observable<LogEntry> parseLogs(final boolean markAsFriendsLog, final String rawResponse) { + return Observable.create(new OnSubscribe<LogEntry>() { + @Override + public void call(final Subscriber<? super LogEntry> subscriber) { + // for non logged in users the log book is not shown + if (StringUtils.isBlank(rawResponse)) { + subscriber.onCompleted(); + return; + } - for (int index = 0; index < data.length(); index++) { - final JSONObject entry = data.getJSONObject(index); + try { + final JSONObject resp = new JSONObject(rawResponse); + if (!resp.getString("status").equals("success")) { + Log.e("GCParser.loadLogsFromDetails: status is " + resp.getString("status")); + subscriber.onCompleted(); + return; + } - // FIXME: use the "LogType" field instead of the "LogTypeImage" one. - final String logIconNameExt = entry.optString("LogTypeImage", ".gif"); - final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4); + final JSONArray data = resp.getJSONArray("data"); - long date = 0; - try { - date = GCLogin.parseGcCustomDate(entry.getString("Visited")).getTime(); - } catch (final ParseException e) { - Log.e("GCParser.loadLogsFromDetails: failed to parse log date."); - } + for (int index = 0; index < data.length(); index++) { + final JSONObject entry = data.getJSONObject(index); - // TODO: we should update our log data structure to be able to record - // proper coordinates, and make them clickable. In the meantime, it is - // better to integrate those coordinates into the text rather than not - // display them at all. - final String latLon = entry.getString("LatLonString"); - final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.getString("LogText")); - final LogEntry logDone = new LogEntry( - TextUtils.removeControlCharacters(entry.getString("UserName")), - date, - LogType.getByIconName(logIconName), - logText); - logDone.found = entry.getInt("GeocacheFindCount"); - logDone.friend = friends; - - final JSONArray images = entry.getJSONArray("Images"); - for (int i = 0; i < images.length(); i++) { - final JSONObject image = images.getJSONObject(i); - final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName"); - final String title = TextUtils.removeControlCharacters(image.getString("Name")); - final Image logImage = new Image(url, title); - logDone.addLogImage(logImage); - } + // FIXME: use the "LogType" field instead of the "LogTypeImage" one. + final String logIconNameExt = entry.optString("LogTypeImage", ".gif"); + final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4); - logs.add(logDone); - } - } catch (final JSONException e) { - // failed to parse logs - Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e); - } + long date = 0; + try { + date = GCLogin.parseGcCustomDate(entry.getString("Visited")).getTime(); + } catch (final ParseException e) { + Log.e("GCParser.loadLogsFromDetails: failed to parse log date."); + } - return logs; + // TODO: we should update our log data structure to be able to record + // proper coordinates, and make them clickable. In the meantime, it is + // better to integrate those coordinates into the text rather than not + // display them at all. + final String latLon = entry.getString("LatLonString"); + final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.getString("LogText")); + final LogEntry logDone = new LogEntry( + TextUtils.removeControlCharacters(entry.getString("UserName")), + date, + LogType.getByIconName(logIconName), + logText); + logDone.found = entry.getInt("GeocacheFindCount"); + logDone.friend = markAsFriendsLog; + + final JSONArray images = entry.getJSONArray("Images"); + for (int i = 0; i < images.length(); i++) { + final JSONObject image = images.getJSONObject(i); + final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName"); + final String title = TextUtils.removeControlCharacters(image.getString("Name")); + final Image logImage = new Image(url, title); + logDone.addLogImage(logImage); + } + + subscriber.onNext(logDone); + } + } catch (final JSONException e) { + // failed to parse logs + Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e); + } + subscriber.onCompleted(); + } + }); } @NonNull @@ -1823,32 +1866,39 @@ public abstract class GCParser { } private static void getExtraOnlineInfo(final Geocache cache, final String page, final CancellableHandler handler) { + // This method starts the page parsing for logs in the background, as well as retrieve the friends and own logs + // if requested. It merges them and stores them in the background, while the rating is retrieved if needed and + // stored. Then we wait for the log merging and saving to be completed before returning. if (CancellableHandler.isCancelled(handler)) { return; } - //cache.setLogs(loadLogsFromDetails(page, cache, false)); + final Observable<LogEntry> logs = getLogsFromDetails(page).subscribeOn(Schedulers.computation()); + Observable<LogEntry> specialLogs; if (Settings.isFriendLogsWanted()) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); - final List<LogEntry> friendLogs = getLogsFromDetails(page, true); - if (friendLogs != null && !friendLogs.isEmpty()) { - // create new list, as the existing log list is immutable - ArrayList<LogEntry> mergedLogs = new ArrayList<LogEntry>(cache.getLogs()); - for (final LogEntry log : friendLogs) { - if (mergedLogs.contains(log)) { - mergedLogs.get(mergedLogs.indexOf(log)).friend = true; - } else { - mergedLogs.add(log); + specialLogs = Observable.merge(getSpecialLogs(page, SpecialLogs.FRIENDS), + getSpecialLogs(page, SpecialLogs.OWN)); + } else { + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); + specialLogs = Observable.empty(); + } + final Observable<List<LogEntry>> mergedLogs = Observable.zip(logs.toList(), specialLogs.toList(), + new Func2<List<LogEntry>, List<LogEntry>, List<LogEntry>>() { + @Override + public List<LogEntry> call(final List<LogEntry> logEntries, final List<LogEntry> specialLogEntries) { + mergeFriendsLogs(logEntries, specialLogEntries); + return logEntries; } - } - DataStore.saveLogsWithoutTransaction(cache.getGeocode(), mergedLogs); - } - } - - if (Settings.isRatingWanted()) { - if (CancellableHandler.isCancelled(handler)) { - return; - } + }).cache(); + mergedLogs.subscribe(new Action1<List<LogEntry>>() { + @Override + public void call(final List<LogEntry> logEntries) { + DataStore.saveLogsWithoutTransaction(cache.getGeocode(), logEntries); + } + }); + + if (Settings.isRatingWanted() && !CancellableHandler.isCancelled(handler)) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote); final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode()); if (rating != null) { @@ -1857,6 +1907,28 @@ public abstract class GCParser { cache.setMyVote(rating.getMyVote()); } } + + // Wait for completion of logs parsing, retrieving and merging + mergedLogs.toBlocking().last(); + } + + /** + * Merge log entries and mark them as friends logs (personal and friends) to identify + * them on friends/personal logs tab. + * + * @param mergedLogs + * the list to merge logs with + * @param logsToMerge + * the list of logs to merge + */ + private static void mergeFriendsLogs(final List<LogEntry> mergedLogs, final Iterable<LogEntry> logsToMerge) { + for (final LogEntry log : logsToMerge) { + if (mergedLogs.contains(log)) { + mergedLogs.get(mergedLogs.indexOf(log)).friend = true; + } else { + mergedLogs.add(log); + } + } } public static boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { diff --git a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java index c7b470a..c6a2afc 100644 --- a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java +++ b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java @@ -35,7 +35,7 @@ public abstract class IconDecoder { return false; //out of image position } - int numberOfDetections = 7; //for level 12 and 13; + int numberOfDetections = 7; //for level 12 and 13 if (zoomlevel < 12) { numberOfDetections = 5; } diff --git a/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java b/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java index 7cced74..5327bea 100644 --- a/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java +++ b/main/src/cgeo/geocaching/connector/gc/RecaptchaHandler.java @@ -57,7 +57,7 @@ public class RecaptchaHandler extends Handler { return Observable.empty(); } }); - AndroidObservable.bindActivity(activity, captcha).subscribe(new Action1<Bitmap>() { + AndroidObservable.bindActivity(activity, captcha).subscribeOn(Schedulers.io()).subscribe(new Action1<Bitmap>() { @Override public void call(final Bitmap bitmap) { imageView.setImageBitmap(bitmap); @@ -67,7 +67,7 @@ public class RecaptchaHandler extends Handler { public void call(final Throwable throwable) { // Do nothing } - }, Schedulers.io()); + }); reloadButton.setEnabled(true); } diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java index ca70111..d7b3a48 100644 --- a/main/src/cgeo/geocaching/connector/gc/Tile.java +++ b/main/src/cgeo/geocaching/connector/gc/Tile.java @@ -9,6 +9,7 @@ import cgeo.geocaching.utils.LeastRecentlyUsedSet; import cgeo.geocaching.utils.Log; import ch.boye.httpclientandroidlib.HttpResponse; + import org.eclipse.jdt.annotation.NonNull; import android.graphics.Bitmap; @@ -88,10 +89,6 @@ public class Tile { * */ private static int calcY(final Geopoint origin, final int zoomlevel) { - - // double latRad = Math.toRadians(origin.getLatitude()); - // return (int) ((1 - (Math.log(Math.tan(latRad) + (1 / Math.cos(latRad))) / Math.PI)) / 2 * numberOfTiles); - // Optimization from Bing double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude())); // The cut of the fractional part instead of rounding to the nearest integer is intentional and part of the algorithm diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java index 049c633..3771443 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java @@ -3,6 +3,7 @@ package cgeo.geocaching.connector.oc; import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import cgeo.geocaching.LogCacheActivity; import cgeo.geocaching.SearchResult; import cgeo.geocaching.connector.ILoggingManager; @@ -149,6 +150,11 @@ public class OCApiLiveConnector extends OCApiConnector implements ISearchByCente } @Override + public boolean isOwner(ICache cache) { + return StringUtils.isNotEmpty(getUserName()) && StringUtils.equals(cache.getOwnerDisplayName(), getUserName()); + } + + @Override public String getUserName() { return userInfo.getName(); } diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java index 3c93488..7d64b31 100644 --- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -6,6 +6,7 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; +import cgeo.geocaching.Trackable; import cgeo.geocaching.Waypoint; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; @@ -98,6 +99,11 @@ final class OkapiClient { private static final String CACHE_CODE = "code"; private static final String CACHE_REQ_PASSWORD = "req_passwd"; private static final String CACHE_MY_NOTES = "my_notes"; + private static final String CACHE_TRACKABLES_COUNT = "trackables_count"; + private static final String CACHE_TRACKABLES = "trackables"; + + private static final String TRK_GEOCODE = "code"; + private static final String TRK_NAME = "name"; private static final String LOG_TYPE = "type"; private static final String LOG_COMMENT = "comment"; @@ -112,9 +118,9 @@ final class OkapiClient { // the several realms of possible fields for cache retrieval: // Core: for livemap requests (L3 - only with level 3 auth) // Additional: additional fields for full cache (L3 - only for level 3 auth, current - only for connectors with current api) - private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size|size2|date_hidden"; + private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size|size2|date_hidden|trackables_count"; private static final String SERVICE_CACHE_CORE_L3_FIELDS = "is_found"; - private static final String SERVICE_CACHE_ADDITIONAL_FIELDS = "owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|alt_wpts|attrnames|req_passwd"; + private static final String SERVICE_CACHE_ADDITIONAL_FIELDS = "owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|alt_wpts|attrnames|req_passwd|trackables"; private static final String SERVICE_CACHE_ADDITIONAL_CURRENT_FIELDS = "gc_code|attribution_note|attr_acodes"; private static final String SERVICE_CACHE_ADDITIONAL_L3_FIELDS = "is_watched|my_notes"; @@ -328,8 +334,11 @@ final class OkapiClient { parseCoreCache(response, cache); // not used: url - final JSONObject owner = response.getJSONObject(CACHE_OWNER); - cache.setOwnerDisplayName(parseUser(owner)); + final JSONObject ownerObject = response.getJSONObject(CACHE_OWNER); + final String owner = parseUser(ownerObject); + cache.setOwnerDisplayName(owner); + // OpenCaching has no distinction between user id and user display name. Set the ID anyway to simplify c:geo workflows. + cache.setOwnerUserId(owner); cache.getLogCounts().put(LogType.FOUND_IT, response.getInt(CACHE_FOUNDS)); cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.getInt(CACHE_NOTFOUNDS)); @@ -375,6 +384,9 @@ final class OkapiClient { //TODO: Store license per cache //cache.setLicense(response.getString("attribution_note")); cache.setWaypoints(parseWaypoints(response.getJSONArray(CACHE_WPTS)), false); + + cache.setInventory(parseTrackables(response.getJSONArray(CACHE_TRACKABLES))); + if (!response.isNull(CACHE_IS_WATCHED)) { cache.setOnWatchlist(response.getBoolean(CACHE_IS_WATCHED)); } @@ -409,6 +421,8 @@ final class OkapiClient { cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY)); cache.setTerrain((float) response.getDouble(CACHE_TERRAIN)); + cache.setInventoryItems(response.getInt(CACHE_TRACKABLES_COUNT)); + if (!response.isNull(CACHE_IS_FOUND)) { cache.setFound(response.getBoolean(CACHE_IS_FOUND)); } @@ -478,6 +492,27 @@ final class OkapiClient { return result; } + private static List<Trackable> parseTrackables(final JSONArray trackablesJson) { + if (trackablesJson.length() == 0) { + return Collections.emptyList(); + } + final List<Trackable> result = new ArrayList<Trackable>(); + for (int i = 0; i < trackablesJson.length(); i++) { + try { + final JSONObject trackableResponse = trackablesJson.getJSONObject(i); + final Trackable trk = new Trackable(); + trk.setGeocode(trackableResponse.getString(TRK_GEOCODE)); + trk.setName(trackableResponse.getString(TRK_NAME)); + result.add(trk); + } catch (final JSONException e) { + Log.e("OkapiClient.parseWaypoints", e); + // Don't overwrite internal state with possibly partial result + return null; + } + } + return result; + } + private static LogType parseLogType(final String logType) { if ("Found it".equalsIgnoreCase(logType)) { return LogType.FOUND_IT; @@ -593,7 +628,7 @@ final class OkapiClient { try { final String size = response.getString(CACHE_SIZE2); return CacheSize.getById(size); - } catch (JSONException e) { + } catch (final JSONException e) { Log.e("OkapiClient.getCacheSize", e); return getCacheSizeDeprecated(response); } @@ -702,7 +737,7 @@ final class OkapiClient { params.add("langpref", getPreferredLanguage()); if (connector.getSupportedAuthLevel() == OAuthLevel.Level3) { - ImmutablePair<String, String> tokens = Settings.getTokenPair(connector.getTokenPublicPrefKeyId(), connector.getTokenSecretPrefKeyId()); + final ImmutablePair<String, String> tokens = Settings.getTokenPair(connector.getTokenPublicPrefKeyId(), connector.getTokenSecretPrefKeyId()); OAuth.signOAuth(host, service.methodName, "GET", false, params, tokens.left, tokens.right, connector.getCK(), connector.getCS()); } else { connector.addAuthentication(params); @@ -769,7 +804,7 @@ final class OkapiClient { return null; } - JSONObject data = result.data; + final JSONObject data = result.data; if (!data.isNull(USER_UUID)) { try { return data.getString(USER_UUID); @@ -792,7 +827,7 @@ final class OkapiClient { return new UserInfo(StringUtils.EMPTY, 0, UserInfoStatus.getFromOkapiError(error.getResult())); } - JSONObject data = result.data; + final JSONObject data = result.data; String name = StringUtils.EMPTY; boolean successUserName = false; @@ -828,7 +863,7 @@ final class OkapiClient { * response containing an error object * @return OkapiError object with detailed information */ - public static OkapiError decodeErrorResponse(HttpResponse response) { + public static OkapiError decodeErrorResponse(final HttpResponse response) { final JSONResult result = new JSONResult(response); if (!result.isSuccess) { return new OkapiError(result.data); @@ -846,7 +881,7 @@ final class OkapiClient { public final JSONObject data; public JSONResult(final @Nullable HttpResponse response) { - boolean isSuccess = Network.isSuccess(response); + final boolean isSuccess = Network.isSuccess(response); final String responseData = Network.getResponseDataAlways(response); JSONObject data = null; if (responseData != null) { diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java index 08fca0b..39f4bcf 100644 --- a/main/src/cgeo/geocaching/export/GpxExport.java +++ b/main/src/cgeo/geocaching/export/GpxExport.java @@ -8,6 +8,7 @@ import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.AsyncTaskWithProgress; import cgeo.geocaching.utils.FileUtils; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.ShareUtils; import org.apache.commons.lang3.CharEncoding; @@ -15,8 +16,6 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; import android.os.Environment; import android.view.ContextThemeWrapper; import android.view.View; @@ -168,11 +167,7 @@ class GpxExport extends AbstractExport { if (exportFile != null) { ActivityMixin.showToast(activity, getName() + ' ' + getString(R.string.export_exportedto) + ": " + exportFile.toString()); if (Settings.getShareAfterExport()) { - final Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(exportFile)); - shareIntent.setType("application/xml"); - activity.startActivity(Intent.createChooser(shareIntent, getString(R.string.export_gpx_to))); + ShareUtils.share(activity, exportFile, "application/xml", R.string.export_gpx_to); } } else { ActivityMixin.showToast(activity, getString(R.string.export_failed)); diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java index 396a589..973e65f 100644 --- a/main/src/cgeo/geocaching/files/FileParser.java +++ b/main/src/cgeo/geocaching/files/FileParser.java @@ -4,6 +4,8 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.utils.CancellableHandler; import org.apache.commons.io.IOUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.io.BufferedInputStream; import java.io.BufferedReader; @@ -29,7 +31,7 @@ public abstract class FileParser { * @throws ParserException * if the input stream contains data not matching the file format of the parser */ - public abstract Collection<Geocache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException; + public abstract Collection<Geocache> parse(@NonNull final InputStream stream, @Nullable final CancellableHandler progressHandler) throws IOException, ParserException; /** * Convenience method for parsing a file. @@ -49,7 +51,7 @@ public abstract class FileParser { } } - protected static StringBuilder readStream(InputStream is, CancellableHandler progressHandler) throws IOException { + protected static StringBuilder readStream(@NonNull final InputStream is, @Nullable final CancellableHandler progressHandler) throws IOException { final StringBuilder buffer = new StringBuilder(); ProgressInputStream progressInputStream = new ProgressInputStream(is); final BufferedReader input = new BufferedReader(new InputStreamReader(progressInputStream, "UTF-8")); @@ -66,7 +68,7 @@ public abstract class FileParser { } } - protected static void showProgressMessage(final CancellableHandler handler, final int bytesRead) { + protected static void showProgressMessage(@Nullable final CancellableHandler handler, final int bytesRead) { if (handler != null) { if (handler.isCancelled()) { throw new CancellationException(); diff --git a/main/src/cgeo/geocaching/files/FileType.java b/main/src/cgeo/geocaching/files/FileType.java new file mode 100644 index 0000000..ef62351 --- /dev/null +++ b/main/src/cgeo/geocaching/files/FileType.java @@ -0,0 +1,8 @@ +package cgeo.geocaching.files; + +public enum FileType { + UNKNOWN, + LOC, + GPX, + ZIP +} diff --git a/main/src/cgeo/geocaching/files/FileTypeDetector.java b/main/src/cgeo/geocaching/files/FileTypeDetector.java new file mode 100644 index 0000000..389b83a --- /dev/null +++ b/main/src/cgeo/geocaching/files/FileTypeDetector.java @@ -0,0 +1,77 @@ +package cgeo.geocaching.files; + +import cgeo.geocaching.utils.Log; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; + +import android.content.ContentResolver; +import android.net.Uri; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class FileTypeDetector { + + private final ContentResolver contentResolver; + private final Uri uri; + + public FileTypeDetector(Uri uri, ContentResolver contentResolver) { + this.uri = uri; + this.contentResolver = contentResolver; + } + + public @NonNull FileType getFileType() { + InputStream is = null; + BufferedReader reader = null; + FileType type = FileType.UNKNOWN; + try { + is = contentResolver.openInputStream(uri); + if (is == null) { + return FileType.UNKNOWN; + } + reader = new BufferedReader(new InputStreamReader(is)); + type = detectHeader(reader); + reader.close(); + } catch (FileNotFoundException e) { + Log.e("FileTypeDetector", e); + } catch (IOException e) { + Log.e("FileTypeDetector", e); + } finally { + IOUtils.closeQuietly(reader); + IOUtils.closeQuietly(is); + } + return type; + } + + private static FileType detectHeader(BufferedReader reader) + throws IOException { + String line = reader.readLine(); + if (isZip(line)) { + return FileType.ZIP; + } + // scan at most 5 lines of a GPX file + for (int i = 0; i < 5; i++) { + line = StringUtils.trim(line); + if (StringUtils.contains(line, "<loc")) { + return FileType.LOC; + } + if (StringUtils.contains(line, "<gpx")) { + return FileType.GPX; + } + line = reader.readLine(); + } + return FileType.UNKNOWN; + } + + private static boolean isZip(String line) { + return StringUtils.length(line) >= 4 + && StringUtils.startsWith(line, "PK") && line.charAt(2) == 3 + && line.charAt(3) == 4; + } + +} diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java index cd2f445..52f68e1 100644 --- a/main/src/cgeo/geocaching/files/GPXImporter.java +++ b/main/src/cgeo/geocaching/files/GPXImporter.java @@ -12,8 +12,10 @@ import cgeo.geocaching.settings.Settings; import cgeo.geocaching.ui.dialog.Dialogs; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RxUtils; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import android.app.Activity; @@ -93,46 +95,77 @@ public class GPXImporter { * * @param uri * URI of the file to import - * @param knownMimeType - * @param knownPathName + * @param mimeType + * @param pathName */ - public void importGPX(final Uri uri, final @Nullable String knownMimeType, final @Nullable String knownPathName) { + public void importGPX(final Uri uri, final @Nullable String mimeType, final @Nullable String pathName) { final ContentResolver contentResolver = fromActivity.getContentResolver(); - String mimeType = knownMimeType; - final String pathName = knownPathName != null ? knownPathName : uri.getPath(); - - // if mimetype can't be determined (e.g. for emulators email app), derive it from uri file extension - // contentResolver.getType(uri) doesn't help but throws exception for emulators email app - // Permission Denial: reading com.android.email.provider.EmailProvider uri - // Google search says: there is no solution for this problem - // Gmail doesn't work at all, see #967 - if (mimeType == null) { - if (StringUtils.endsWithIgnoreCase(pathName, GPX_FILE_EXTENSION) || StringUtils.endsWithIgnoreCase(pathName, LOC_FILE_EXTENSION)) { - mimeType = "application/xml"; - } else { - // if we can't determine a better type, default to zip import - // emulator email sends e.g. content://com.android.email.attachmentprovider/1/1/RAW, mimetype=null - mimeType = "application/zip"; - } - } Log.i("importGPX: " + uri + ", mimetype=" + mimeType); - if (GPX_MIME_TYPES.contains(mimeType)) { - if (StringUtils.endsWithIgnoreCase(pathName, LOC_FILE_EXTENSION)) { - new ImportLocAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start(); - } else { - new ImportGpxAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start(); - } - } else if (ZIP_MIME_TYPES.contains(mimeType)) { - new ImportGpxZipAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start(); - } else { - importFinished(); + @NonNull + FileType fileType = new FileTypeDetector(uri, contentResolver) + .getFileType(); + + if (fileType == FileType.UNKNOWN) { + fileType = getFileTypeFromPathName(pathName); + } + if (fileType == FileType.UNKNOWN) { + fileType = getFileTypeFromMimeType(mimeType); + } + + ImportThread importer = getImporterFromFileType(uri, contentResolver, + fileType); + + if (importer != null) { + importer.start(); + } else { + importFinished(); + } + } + + private static @NonNull FileType getFileTypeFromPathName( + final String pathName) { + if (StringUtils.endsWithIgnoreCase(pathName, GPX_FILE_EXTENSION)) { + return FileType.GPX; } - } - /** - * Import GPX provided via intent of activity that instantiated this GPXImporter. - */ + if (StringUtils.endsWithIgnoreCase(pathName, LOC_FILE_EXTENSION)) { + return FileType.LOC; + } + return FileType.UNKNOWN; + } + + private static @NonNull FileType getFileTypeFromMimeType( + final String mimeType) { + if (GPX_MIME_TYPES.contains(mimeType)) { + return FileType.GPX; + } else if (ZIP_MIME_TYPES.contains(mimeType)) { + return FileType.ZIP; + } + return FileType.UNKNOWN; + } + + private ImportThread getImporterFromFileType(Uri uri, + ContentResolver contentResolver, FileType fileType) { + switch (fileType) { + case ZIP: + return new ImportGpxZipAttachmentThread(uri, contentResolver, + listId, importStepHandler, progressHandler); + case GPX: + return new ImportGpxAttachmentThread(uri, contentResolver, listId, + importStepHandler, progressHandler); + case LOC: + return new ImportLocAttachmentThread(uri, contentResolver, listId, + importStepHandler, progressHandler); + default: + return null; + } + } + + /** + * Import GPX provided via intent of activity that instantiated this + * GPXImporter. + */ public void importGPX() { final Intent intent = fromActivity.getIntent(); final Uri uri = intent.getData(); @@ -194,7 +227,7 @@ public class GPXImporter { final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); if (cache != null) { Log.d("GPXImporter.ImportThread.importStaticMaps start downloadMaps for cache " + geocode); - StaticMapsProvider.downloadMaps(cache); + RxUtils.waitForCompletion(StaticMapsProvider.downloadMaps(cache)); } else { Log.d("GPXImporter.ImportThread.importStaticMaps: no data found for " + geocode); } diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 6161088..f3cd326 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -25,6 +25,8 @@ import cgeo.geocaching.utils.SynchronizedDateFormat; import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -270,7 +272,7 @@ public abstract class GPXParser extends FileParser { } @Override - public Collection<Geocache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException { + public Collection<Geocache> parse(@NonNull final InputStream stream, @Nullable final CancellableHandler progressHandler) throws IOException, ParserException { resetCache(); final RootElement root = new RootElement(namespace, "gpx"); final Element waypoint = root.getChild(namespace, "wpt"); diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java index 3d01c1b..223fb5a 100644 --- a/main/src/cgeo/geocaching/files/LocParser.java +++ b/main/src/cgeo/geocaching/files/LocParser.java @@ -12,6 +12,8 @@ import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.io.IOException; import java.io.InputStream; @@ -116,9 +118,9 @@ public final class LocParser extends FileParser { } @Override - public Collection<Geocache> parse(InputStream stream, CancellableHandler progressHandler) throws IOException, ParserException { - // TODO: progress reporting happens during reading stream only, not during parsing - String streamContent = readStream(stream, progressHandler).toString(); + public Collection<Geocache> parse(@NonNull final InputStream stream, @Nullable final CancellableHandler progressHandler) throws IOException, ParserException { + final String streamContent = readStream(stream, null).toString(); + final int maxSize = streamContent.length(); final Map<String, Geocache> coords = parseCoordinates(streamContent); final List<Geocache> caches = new ArrayList<Geocache>(); for (Entry<String, Geocache> entry : coords.entrySet()) { @@ -136,6 +138,9 @@ public final class LocParser extends FileParser { cache.setListId(listId); cache.setDetailed(true); cache.store(null); + if (progressHandler != null) { + progressHandler.sendMessage(progressHandler.obtainMessage(0, maxSize * caches.size() / coords.size(), 0)); + } } Log.i("Caches found in .loc file: " + caches.size()); return caches; diff --git a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java index 2d7207a..5bfab28 100644 --- a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java +++ b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java @@ -24,22 +24,15 @@ class PopularityRatioFilter extends AbstractFilter { @Override public boolean accepts(final Geocache cache) { + final int finds = getFindsCount(cache); - int finds; - int favorites; - float ratio; - - finds = getFindsCount(cache); - - // prevent division by zero - if (finds == 0) { + if (finds == 0) { // Prevent division by zero return false; } - favorites = cache.getFavoritePoints(); - ratio = ((float) favorites / (float) finds) * 100.0f; - - return (ratio > minRatio) && (ratio <= maxRatio); + final int favorites = cache.getFavoritePoints(); + final float ratio = 100.0f * favorites / finds; + return ratio > minRatio && ratio <= maxRatio; } private static int getFindsCount(Geocache cache) { diff --git a/main/src/cgeo/geocaching/filter/StateFilter.java b/main/src/cgeo/geocaching/filter/StateFilter.java index f452259..fd14b69 100644 --- a/main/src/cgeo/geocaching/filter/StateFilter.java +++ b/main/src/cgeo/geocaching/filter/StateFilter.java @@ -32,6 +32,19 @@ abstract class StateFilter extends AbstractFilter { } + static class StateNotFoundFilter extends StateFilter { + + public StateNotFoundFilter() { + super(res.getString(R.string.cache_not_status_found)); + } + + @Override + public boolean accepts(final Geocache cache) { + return !cache.isFound(); + } + + } + static class StateArchivedFilter extends StateFilter { public StateArchivedFilter() { super(res.getString(R.string.cache_status_archived)); @@ -115,6 +128,7 @@ abstract class StateFilter extends AbstractFilter { public List<StateFilter> getFilters() { final List<StateFilter> filters = new ArrayList<StateFilter>(6); filters.add(new StateFoundFilter()); + filters.add(new StateNotFoundFilter()); filters.add(new StateArchivedFilter()); filters.add(new StateDisabledFilter()); filters.add(new StatePremiumFilter()); diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java index 0ab1fe3..d77a4e6 100644 --- a/main/src/cgeo/geocaching/gcvote/GCVote.java +++ b/main/src/cgeo/geocaching/gcvote/GCVote.java @@ -1,6 +1,8 @@ package cgeo.geocaching.gcvote; +import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.settings.Settings; @@ -253,7 +255,7 @@ public final class GCVote { /** * Get geocodes of all the caches, which can be used with GCVote. Non-GC caches will be filtered out. - * + * * @param caches * @return */ @@ -281,4 +283,33 @@ public final class GCVote { return Settings.isGCvoteLogin() && StringUtils.isNotBlank(cache.getGuid()) && cache.supportsGCVote(); } + public static String getDescription(final float rating) { + switch (Math.round(rating * 2f)) { + case 2: + return getString(R.string.log_stars_1_description); + case 3: + return getString(R.string.log_stars_15_description); + case 4: + return getString(R.string.log_stars_2_description); + case 5: + return getString(R.string.log_stars_25_description); + case 6: + return getString(R.string.log_stars_3_description); + case 7: + return getString(R.string.log_stars_35_description); + case 8: + return getString(R.string.log_stars_4_description); + case 9: + return getString(R.string.log_stars_45_description); + case 10: + return getString(R.string.log_stars_5_description); + default: + return getString(R.string.log_no_rating); + } + } + + private static String getString(int resId) { + return CgeoApplication.getInstance().getString(resId); + } + } diff --git a/main/src/cgeo/geocaching/geopoint/Geopoint.java b/main/src/cgeo/geocaching/geopoint/Geopoint.java index 1655343..bb34114 100644 --- a/main/src/cgeo/geocaching/geopoint/Geopoint.java +++ b/main/src/cgeo/geocaching/geopoint/Geopoint.java @@ -556,15 +556,14 @@ public final class Geopoint implements ICoordinates, Parcelable { * Gets distance in meters (workaround for 4.2.1 JIT bug). */ public static double getDistance(double lat1, double lon1, double lat2, double lon2) { - double earthRadius = 6372.8; // for haversine use R = 6372.8 km instead of 6371 km + // for haversine use R = 6372.8 km instead of 6371 km + double earthRadius = 6372.8; double dLat = toRadians(lat2 - lat1); double dLon = toRadians(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); - //double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); - //return R * c * 1000; - // simplify haversine: + // simplify haversine return (2 * earthRadius * 1000 * Math.asin(Math.sqrt(a))); } @@ -582,8 +581,8 @@ public final class Geopoint implements ICoordinates, Parcelable { } /** - * Check whether a lo bngitudeuilt from user supplied data is valid. We accept both E180/W180. - * + * Check whether a longitude from user supplied data is valid. We accept both E180/W180. + * * @return <tt>true</tt> if the longitude looks valid, <tt>false</tt> otherwise */ public static boolean isValidLongitude(final double longitude) { diff --git a/main/src/cgeo/geocaching/geopoint/Units.java b/main/src/cgeo/geocaching/geopoint/Units.java index b99e00e..d00e075 100644 --- a/main/src/cgeo/geocaching/geopoint/Units.java +++ b/main/src/cgeo/geocaching/geopoint/Units.java @@ -4,6 +4,8 @@ import cgeo.geocaching.settings.Settings; import org.apache.commons.lang3.tuple.ImmutablePair; +import java.util.Locale; + public class Units { public static ImmutablePair<Double, String> scaleDistance(final double distanceKilometers) { @@ -51,11 +53,10 @@ public class Units { return getDistanceFromKilometers(meters / 1000f); } - public static String getSpeed(float kilometersPerHour) { - final String speed = getDistanceFromKilometers(kilometersPerHour); - if (speed.endsWith("mi")) { - return speed.substring(0, speed.length() - 2) + "mph"; + public static String getSpeed(final float kilometersPerHour) { + if (Settings.isUseImperialUnits()) { + return String.format(Locale.US, "%.0f mph", kilometersPerHour / IConversion.MILES_TO_KILOMETER); } - return speed + (!Settings.isUseImperialUnits() ? "/h" : "ph"); + return String.format(Locale.US, "%.0f km/h", kilometersPerHour); } } diff --git a/main/src/cgeo/geocaching/list/AbstractList.java b/main/src/cgeo/geocaching/list/AbstractList.java index ec783eb..06f44a2 100644 --- a/main/src/cgeo/geocaching/list/AbstractList.java +++ b/main/src/cgeo/geocaching/list/AbstractList.java @@ -20,6 +20,10 @@ public abstract class AbstractList { public abstract boolean isConcrete(); + public abstract String getTitle(); + + public abstract int getNumberOfCaches(); + @Nullable public static AbstractList getListById(int listId) { return LISTS.get(listId); diff --git a/main/src/cgeo/geocaching/list/PseudoList.java b/main/src/cgeo/geocaching/list/PseudoList.java index f2cc7ed..9ee920c 100644 --- a/main/src/cgeo/geocaching/list/PseudoList.java +++ b/main/src/cgeo/geocaching/list/PseudoList.java @@ -1,32 +1,48 @@ package cgeo.geocaching.list; import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.DataStore; import cgeo.geocaching.R; -public class PseudoList extends AbstractList { +public abstract class PseudoList extends AbstractList { private static final int ALL_LIST_ID = 2; /** * list entry to show all caches */ - public static final PseudoList ALL_LIST = new PseudoList(ALL_LIST_ID, R.string.list_all_lists); + public static final PseudoList ALL_LIST = new PseudoList(ALL_LIST_ID, R.string.list_all_lists) { + @Override + public int getNumberOfCaches() { + return DataStore.getAllCachesCount(); + } + }; private static final int NEW_LIST_ID = 3; /** * list entry to create a new list */ - public static final AbstractList NEW_LIST = new PseudoList(NEW_LIST_ID, R.string.list_menu_create); + public static final AbstractList NEW_LIST = new PseudoList(NEW_LIST_ID, R.string.list_menu_create) { + @Override + public int getNumberOfCaches() { + return -1; + } + }; private static final int HISTORY_LIST_ID = 4; /** * list entry to create a new list */ - public static final AbstractList HISTORY_LIST = new PseudoList(HISTORY_LIST_ID, R.string.menu_history); + public static final AbstractList HISTORY_LIST = new PseudoList(HISTORY_LIST_ID, R.string.menu_history) { + @Override + public int getNumberOfCaches() { + return DataStore.getAllHistoryCachesCount(); + } + }; /** * private constructor to have all instances as constants in the class */ - private PseudoList(int id, final int titleResourceId) { + private PseudoList(final int id, final int titleResourceId) { super(id, CgeoApplication.getInstance().getResources().getString(titleResourceId)); } @@ -36,6 +52,11 @@ public class PseudoList extends AbstractList { } @Override + public String getTitle() { + return title; + } + + @Override public boolean isConcrete() { return false; } diff --git a/main/src/cgeo/geocaching/list/StoredList.java b/main/src/cgeo/geocaching/list/StoredList.java index e557fc8..6dac1a7 100644 --- a/main/src/cgeo/geocaching/list/StoredList.java +++ b/main/src/cgeo/geocaching/list/StoredList.java @@ -16,6 +16,7 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.content.res.Resources; +import java.lang.ref.WeakReference; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; @@ -58,12 +59,12 @@ public final class StoredList extends AbstractList { } public static class UserInterface { - private final Activity activity; + private final WeakReference<Activity> activityRef; private final CgeoApplication app; private final Resources res; - public UserInterface(final Activity activity) { - this.activity = activity; + public UserInterface(final @NonNull Activity activity) { + this.activityRef = new WeakReference<Activity>(activity); app = CgeoApplication.getInstance(); res = app.getResources(); } @@ -77,25 +78,7 @@ public final class StoredList extends AbstractList { } public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId, final String newListName) { - final List<AbstractList> lists = new ArrayList<AbstractList>(); - lists.addAll(getSortedLists()); - - if (exceptListId > StoredList.TEMPORARY_LIST_ID) { - StoredList exceptList = DataStore.getList(exceptListId); - if (exceptList != null) { - lists.remove(exceptList); - } - } - - if (!onlyConcreteLists) { - if (exceptListId != PseudoList.ALL_LIST.id) { - lists.add(PseudoList.ALL_LIST); - } - if (exceptListId != PseudoList.HISTORY_LIST.id) { - lists.add(PseudoList.HISTORY_LIST); - } - } - lists.add(PseudoList.NEW_LIST); + final List<AbstractList> lists = getMenuLists(onlyConcreteLists, exceptListId); final List<CharSequence> listsTitle = new ArrayList<CharSequence>(); for (AbstractList list : lists) { @@ -104,6 +87,7 @@ public final class StoredList extends AbstractList { final CharSequence[] items = new CharSequence[listsTitle.size()]; + final Activity activity = activityRef.get(); AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(res.getString(titleId)); builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() { @@ -122,6 +106,31 @@ public final class StoredList extends AbstractList { builder.create().show(); } + public static List<AbstractList> getMenuLists(boolean onlyConcreteLists, int exceptListId) { + final List<AbstractList> lists = new ArrayList<AbstractList>(); + lists.addAll(getSortedLists()); + + if (exceptListId > StoredList.TEMPORARY_LIST_ID) { + StoredList exceptList = DataStore.getList(exceptListId); + if (exceptList != null) { + lists.remove(exceptList); + } + } + + if (!onlyConcreteLists) { + if (exceptListId != PseudoList.ALL_LIST.id) { + lists.add(PseudoList.ALL_LIST); + } + if (exceptListId != PseudoList.HISTORY_LIST.id) { + lists.add(PseudoList.HISTORY_LIST); + } + } + if (exceptListId != PseudoList.NEW_LIST.id) { + lists.add(PseudoList.NEW_LIST); + } + return lists; + } + @NonNull private static List<StoredList> getSortedLists() { final Collator collator = Collator.getInstance(); @@ -151,6 +160,10 @@ public final class StoredList extends AbstractList { @SuppressWarnings("unused") @Override public void call(final String listName) { + final Activity activity = activityRef.get(); + if (activity == null) { + return; + } final int newId = DataStore.createList(listName); new StoredList(newId, listName, 0); @@ -165,6 +178,10 @@ public final class StoredList extends AbstractList { } private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final Action1<String> runnable) { + final Activity activity = activityRef.get(); + if (activity == null) { + return; + } Dialogs.input(activity, dialogTitle, defaultValue, buttonTitle, new Action1<String>() { @Override @@ -193,14 +210,18 @@ public final class StoredList extends AbstractList { } /** - * Get the list title. This method is not public by intention to make clients use the {@link UserInterface} class. - * - * @return + * Get the list title. */ - protected String getTitle() { + @Override + public String getTitle() { return title; } + @Override + public int getNumberOfCaches() { + return count; + } + /** * Return the given list, if it is a concrete list. Return the default list otherwise. */ diff --git a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java index b80a1b8..0d5af6a 100644 --- a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java +++ b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java @@ -1,18 +1,20 @@ package cgeo.geocaching.loaders; import cgeo.geocaching.DataStore; +import cgeo.geocaching.Intents; import cgeo.geocaching.SearchResult; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.settings.Settings; import android.content.Context; +import android.os.Bundle; public class OfflineGeocacheListLoader extends AbstractSearchLoader { - private int listId; - private Geopoint searchCenter; + private final int listId; + private final Geopoint searchCenter; - public OfflineGeocacheListLoader(Context context, Geopoint searchCenter, int listId) { + public OfflineGeocacheListLoader(final Context context, final Geopoint searchCenter, final int listId) { super(context); this.searchCenter = searchCenter; this.listId = listId; @@ -23,12 +25,14 @@ public class OfflineGeocacheListLoader extends AbstractSearchLoader { return DataStore.getBatchOfStoredCaches(searchCenter, Settings.getCacheType(), listId); } - public void setListId(int listId) { - this.listId = listId; - } - - public void setSearchCenter(Geopoint searchCenter) { - this.searchCenter = searchCenter; + /** + * @param listId + * @return the bundle needed for querying the LoaderManager for the offline list with the given id + */ + public static Bundle getBundleForList(final int listId) { + final Bundle bundle = new Bundle(); + bundle.putInt(Intents.EXTRA_LIST_ID, listId); + return bundle; } } diff --git a/main/src/cgeo/geocaching/maps/AbstractMap.java b/main/src/cgeo/geocaching/maps/AbstractMap.java index d341823..2eceadb 100644 --- a/main/src/cgeo/geocaching/maps/AbstractMap.java +++ b/main/src/cgeo/geocaching/maps/AbstractMap.java @@ -5,10 +5,11 @@ import cgeo.geocaching.maps.interfaces.MapActivityImpl; import android.app.Activity; import android.content.res.Resources; +import android.os.Build; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; -import android.view.View; +import android.view.Window; /** * Base class for the map activity. Delegates base class calls to the @@ -31,7 +32,11 @@ public abstract class AbstractMap { } public void onCreate(Bundle savedInstanceState) { + mapActivity.superOnCreate(savedInstanceState); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { + mapActivity.getActivity().requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + } } public void onResume() { @@ -64,8 +69,6 @@ public abstract class AbstractMap { return mapActivity.superOnOptionsItemSelected(item); } - public abstract void goHome(View view); - public abstract void onSaveInstanceState(final Bundle outState); } diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 00aee36..9a3f713 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -43,14 +43,16 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; -import rx.Scheduler; import rx.Subscription; +import rx.functions.Action0; import rx.functions.Action1; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; import rx.subscriptions.Subscriptions; +import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -61,6 +63,7 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.location.Location; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -70,9 +73,11 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.ViewGroup.LayoutParams; +import android.widget.CheckBox; import android.widget.ImageSwitcher; import android.widget.ImageView; import android.widget.ImageView.ScaleType; +import android.widget.ProgressBar; import android.widget.TextView; import android.widget.ViewSwitcher.ViewFactory; @@ -92,7 +97,7 @@ import java.util.concurrent.TimeUnit; /** * Class representing the Map in c:geo */ -public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFactory { +public class CGeoMap extends AbstractMap implements ViewFactory { /** max. number of caches displayed in the Live Map */ public static final int MAX_CACHES = 500; @@ -171,7 +176,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 }, { 25, 33, 0, 0 } }; // bottom right, 12x12 / 26x26 / 35x35 private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 }, { 0, 33, 25, 0 } }; // bottom left, 12x12 / 26x26 / 35x35 - private SparseArray<LayerDrawable> overlaysCache = new SparseArray<LayerDrawable>(); + private final SparseArray<LayerDrawable> overlaysCache = new SparseArray<LayerDrawable>(); /** Count of caches currently visible */ private int cachesCnt = 0; /** List of caches in the viewport */ @@ -184,9 +189,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto private int detailProgress = 0; private long detailProgressTime = 0L; // views - private ImageSwitcher myLocSwitch = null; + private CheckBox myLocSwitch = null; - /** Controls the map behaviour */ + /** Controls the map behavior */ private MapMode mapMode = null; /** Live mode enabled for map. **/ private boolean isLiveEnabled; @@ -210,74 +215,130 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto // handlers /** Updates the titles */ - final private Handler displayHandler = new Handler() { + private final static class DisplayHandler extends Handler { + + private final WeakReference<CGeoMap> mapRef; + + public DisplayHandler(@NonNull final CGeoMap map) { + this.mapRef = new WeakReference<CGeoMap>(map); + } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { final int what = msg.what; + final CGeoMap map = mapRef.get(); + if (map == null) { + return; + } switch (what) { case UPDATE_TITLE: // set title final StringBuilder title = new StringBuilder(); - if (mapMode == MapMode.LIVE && isLiveEnabled) { - title.append(res.getString(R.string.map_live)); + if (map.mapMode == MapMode.LIVE && map.isLiveEnabled) { + title.append(map.res.getString(R.string.map_live)); } else { - title.append(mapTitle); + title.append(map.mapTitle); } - countVisibleCaches(); - if (caches != null && !caches.isEmpty() && !mapTitle.contains("[")) { - title.append(" [").append(cachesCnt); - if (cachesCnt != caches.size()) { - title.append('/').append(caches.size()); + map.countVisibleCaches(); + if (map.caches != null && !map.caches.isEmpty() && !map.mapTitle.contains("[")) { + title.append(" [").append(map.cachesCnt); + if (map.cachesCnt != map.caches.size()) { + title.append('/').append(map.caches.size()); } title.append(']'); } - if (Settings.isDebug() && lastSearchResult != null && StringUtils.isNotBlank(lastSearchResult.getUrl())) { - title.append('[').append(lastSearchResult.getUrl()).append(']'); + if (Settings.isDebug() && map.lastSearchResult != null && StringUtils.isNotBlank(map.lastSearchResult.getUrl())) { + title.append('[').append(map.lastSearchResult.getUrl()).append(']'); } - ActivityMixin.setTitle(activity, title.toString()); + map.setTitle(title.toString()); break; case INVALIDATE_MAP: - mapView.repaintRequired(null); + map.mapView.repaintRequired(null); break; default: break; } } - }; - /** Updates the progress. */ - final private Handler showProgressHandler = new Handler() { + } + + final private Handler displayHandler = new DisplayHandler(this); + private void setTitle(final String title) { + /* Compatibility for the old Action Bar, only used by the maps activity at the moment */ + final TextView titleview = (TextView) activity.findViewById(R.id.actionbar_title); + if (titleview != null) { + titleview.setText(title); + + } + if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)) { + setTitleHoneyComb(title); + } + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void setTitleHoneyComb(final String title) { + activity.getActionBar().setTitle(title); + } + + /** Updates the progress. */ + private static final class ShowProgressHandler extends Handler { private int counter = 0; + @NonNull private final WeakReference<CGeoMap> mapRef; + + public ShowProgressHandler(@NonNull final CGeoMap map) { + this.mapRef = new WeakReference<CGeoMap>(map); + } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { final int what = msg.what; if (what == HIDE_PROGRESS) { if (--counter == 0) { - ActivityMixin.showProgress(activity, false); + showProgress(false); } } else if (what == SHOW_PROGRESS) { - ActivityMixin.showProgress(activity, true); + showProgress(true); counter++; } } - }; + + private void showProgress(final boolean show) { + final CGeoMap map = mapRef.get(); + if (map == null) { + return; + } + + final ProgressBar progress = (ProgressBar) map.activity.findViewById(R.id.actionbar_progress); + if (progress != null) { + if (show) { + progress.setVisibility(View.VISIBLE); + } else { + progress.setVisibility(View.GONE); + + } + } + if (Build.VERSION.SDK_INT >= 11) { + map.activity.setProgressBarIndeterminateVisibility(show); + } + } + } + + final private Handler showProgressHandler = new ShowProgressHandler(this); final private class LoadDetailsHandler extends CancellableHandler { @Override - public void handleRegularMessage(Message msg) { + public void handleRegularMessage(final Message msg) { if (msg.what == UPDATE_PROGRESS) { if (waitDialog != null) { - int secondsElapsed = (int) ((System.currentTimeMillis() - detailProgressTime) / 1000); + final int secondsElapsed = (int) ((System.currentTimeMillis() - detailProgressTime) / 1000); int secondsRemaining; if (detailProgress > 0) { secondsRemaining = (detailTotal - detailProgress) * secondsElapsed / detailProgress; @@ -289,7 +350,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (secondsRemaining < 40) { waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); } else { - int minsRemaining = secondsRemaining / 60; + final int minsRemaining = secondsRemaining / 60; waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + minsRemaining + " " + res.getQuantityString(R.plurals.caches_eta_mins, minsRemaining)); } } @@ -312,7 +373,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final private Handler noMapTokenHandler = new Handler() { @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { if (!noMapTokenShowed) { ActivityMixin.showToast(activity, res.getString(R.string.map_token_err)); @@ -328,7 +389,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto /* Current source id */ private int currentSourceId; - public CGeoMap(MapActivityImpl activity) { + public CGeoMap(final MapActivityImpl activity) { super(activity); geoDirUpdate = new UpdateLoc(this); } @@ -361,8 +422,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } + @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // class init @@ -370,7 +432,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto activity = this.getActivity(); app = (CgeoApplication) activity.getApplication(); - int countBubbleCnt = DataStore.getAllCachesCount(); + final int countBubbleCnt = DataStore.getAllCachesCount(); caches = new LeastRecentlyUsedSet<Geocache>(MAX_CACHES + countBubbleCnt); final MapProvider mapProvider = Settings.getMapProvider(); @@ -418,10 +480,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto ActivityMixin.keepScreenOn(activity, true); + // set layout - ActivityMixin.setTheme(activity); + //ActivityMixin.setTheme(activity); + // TODO: set a proper theme + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { + activity.setTheme(android.R.style.Theme_Holo); + activity.getActionBar().setDisplayHomeAsUpEnabled(true); + } activity.setContentView(mapProvider.getMapLayoutId()); - ActivityMixin.setTitle(activity, res.getString(R.string.map_map)); + setTitle(res.getString(R.string.map_map)); // initialize map mapView = (MapViewImpl) activity.findViewById(mapProvider.getMapViewId()); @@ -429,7 +497,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto mapView.setBuiltInZoomControls(true); mapView.displayZoomControls(true); mapView.preLoad(); - mapView.setOnDragListener(this); + mapView.setOnDragListener(new MapDragListener(this)); // initialize overlays mapView.clearOverlays(); @@ -439,7 +507,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } if (overlayPositionAndScale == null) { - overlayPositionAndScale = mapView.createAddPositionAndScaleOverlay(activity); + overlayPositionAndScale = mapView.createAddPositionAndScaleOverlay(); if (trailHistory != null) { overlayPositionAndScale.setHistory(trailHistory); } @@ -462,14 +530,11 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto centerMap(geocodeIntent, searchIntent, coordsIntent, mapStateIntent); } - // prepare my location button - myLocSwitch = (ImageSwitcher) activity.findViewById(R.id.my_position); - myLocSwitch.setFactory(this); - myLocSwitch.setInAnimation(activity, android.R.anim.fade_in); - myLocSwitch.setOutAnimation(activity, android.R.anim.fade_out); - myLocSwitch.setOnClickListener(new MyLocationListener()); - switchMyLocationButton(); + final CheckBox locSwitch = (CheckBox) activity.findViewById(R.id.my_position); + if (locSwitch!=null) { + initMyLocationSwitchButton(locSwitch); + } prepareFilterBar(); if (!app.isLiveMapHintShownInThisSession() && !Settings.getHideLiveMapHint() && Settings.getLiveMapHintShowCount() <= 3) { @@ -477,6 +542,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } + private void initMyLocationSwitchButton(final CheckBox locSwitch) { + myLocSwitch = locSwitch; + /* TODO: Switch back to ImageSwitcher for animations? + myLocSwitch.setFactory(this); + myLocSwitch.setInAnimation(activity, android.R.anim.fade_in); + myLocSwitch.setOutAnimation(activity, android.R.anim.fade_out); */ + myLocSwitch.setOnClickListener(new MyLocationListener(this)); + switchMyLocationButton(); + } + /** * Set the zoom of the map. The zoom is restricted to a certain minimum in case of live map. * @@ -489,7 +564,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto private void prepareFilterBar() { // show the filter warning bar if the filter is set if (Settings.getCacheType() != CacheType.ALL) { - String cacheType = Settings.getCacheType().getL10n(); + final String cacheType = Settings.getCacheType().getL10n(); ((TextView) activity.findViewById(R.id.filter_text)).setText(cacheType); activity.findViewById(R.id.filter_bar).setVisibility(View.VISIBLE); } else { @@ -503,8 +578,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto resumeSubscription = Subscriptions.from(geoDirUpdate.start(GeoDirHandler.UPDATE_GEODIR), startTimer()); if (!CollectionUtils.isEmpty(dirtyCaches)) { - for (String geocode : dirtyCaches) { - Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + for (final String geocode : dirtyCaches) { + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); if (cache != null) { // new collection type needs to remove first caches.remove(cache); @@ -514,7 +589,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } dirtyCaches.clear(); // Update display - displayExecutor.execute(new DisplayRunnable(mapView.getViewport())); + displayExecutor.execute(new DisplayRunnable(this)); } } @@ -532,8 +607,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto super.onPause(); } + @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { // menu inflation happens in Google/Mapsforge specific classes super.onCreateOptionsMenu(menu); @@ -541,26 +617,35 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final SubMenu subMenuStrategy = menu.findItem(R.id.submenu_strategy).getSubMenu(); subMenuStrategy.setHeaderTitle(res.getString(R.string.map_strategy_title)); + + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { + /* if we have an Actionbar find the my position toggle */ + final MenuItem item = menu.findItem(R.id.menu_toggle_mypos); + myLocSwitch = new CheckBox(activity); + myLocSwitch.setButtonDrawable(R.drawable.ic_menu_myposition); + item.setActionView(myLocSwitch); + initMyLocationSwitchButton(myLocSwitch); + } else { + // Already on the fake Actionbar + menu.removeItem(R.id.menu_toggle_mypos); + } return true; } @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(final Menu menu) { super.onPrepareOptionsMenu(menu); - for (MapSource mapSource : MapProviderFactory.getMapSources()) { + for (final MapSource mapSource : MapProviderFactory.getMapSources()) { final MenuItem menuItem = menu.findItem(mapSource.getNumericalId()); if (menuItem != null) { - menuItem.setEnabled(mapSource.isAvailable()); + menuItem.setVisible(mapSource.isAvailable()); } } try { MenuItem item = menu.findItem(R.id.menu_trail_mode); - if (Settings.isMapTrail()) { - item.setTitle(res.getString(R.string.map_trail_hide)); - } else { - item.setTitle(res.getString(R.string.map_trail_show)); - } + item.setChecked(Settings.isMapTrail()); item = menu.findItem(R.id.menu_map_live); // live map if (isLiveEnabled) { @@ -570,28 +655,20 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } item = menu.findItem(R.id.menu_mycaches_mode); // own & found caches - if (Settings.isExcludeMyCaches()) { - item.setTitle(res.getString(R.string.map_mycaches_show)); - } else { - item.setTitle(res.getString(R.string.map_mycaches_hide)); - } + item.setChecked(Settings.isExcludeMyCaches()); final Set<String> geocodesInViewport = getGeocodesForCachesInViewport(); - menu.findItem(R.id.menu_store_caches).setEnabled(!isLoading() && CollectionUtils.isNotEmpty(geocodesInViewport) && new SearchResult(geocodesInViewport).hasUnsavedCaches()); + menu.findItem(R.id.menu_store_caches).setVisible(!isLoading() && CollectionUtils.isNotEmpty(geocodesInViewport) && new SearchResult(geocodesInViewport).hasUnsavedCaches()); item = menu.findItem(R.id.menu_circle_mode); // show circles - if (overlayCaches != null && overlayCaches.getCircles()) { - item.setTitle(res.getString(R.string.map_circles_hide)); - } else { - item.setTitle(res.getString(R.string.map_circles_show)); - } + item.setChecked(overlayCaches != null && overlayCaches.getCircles()); item = menu.findItem(R.id.menu_theme_mode); // show theme selection item.setVisible(mapView.hasMapThemes()); - menu.findItem(R.id.menu_as_list).setEnabled(!isLoading()); + menu.findItem(R.id.menu_as_list).setVisible(!isLoading()); - menu.findItem(R.id.submenu_strategy).setEnabled(isLiveEnabled); + menu.findItem(R.id.submenu_strategy).setVisible(isLiveEnabled); switch (Settings.getLiveMapStrategy()) { case FASTEST: @@ -606,7 +683,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto default: // DETAILED menu.findItem(R.id.menu_strategy_detailed).setChecked(true); } - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.e("CGeoMap.onPrepareOptionsMenu", e); } @@ -614,9 +691,12 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(final MenuItem item) { final int id = item.getItemId(); switch (id) { + case android.R.id.home: + ActivityMixin.navigateUp(activity); + return true; case R.id.menu_trail_mode: Settings.setMapTrail(!Settings.isMapTrail()); mapView.repaintRequired(overlayPositionAndScale); @@ -726,16 +806,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final File[] themeFiles = Settings.getMapThemeFiles(); String currentTheme = StringUtils.EMPTY; - String currentThemePath = Settings.getCustomRenderThemeFilePath(); + final String currentThemePath = Settings.getCustomRenderThemeFilePath(); if (StringUtils.isNotEmpty(currentThemePath)) { - File currentThemeFile = new File(currentThemePath); + final File currentThemeFile = new File(currentThemePath); currentTheme = currentThemeFile.getName(); } - List<String> names = new ArrayList<String>(); + final List<String> names = new ArrayList<String>(); names.add(res.getString(R.string.map_theme_builtin)); int currentItem = 0; - for (File file : themeFiles) { + for (final File file : themeFiles) { if (currentTheme.equalsIgnoreCase(file.getName())) { currentItem = names.size(); } @@ -744,7 +824,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final int selectedItem = currentItem; - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.map_theme_select); @@ -752,7 +832,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int newItem) { + public void onClick(final DialogInterface dialog, final int newItem) { if (newItem != selectedItem) { // Adjust index because of <default> selection if (newItem > 0) { @@ -818,7 +898,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto activity.finish(); // prepare information to restart a similar view - Intent mapIntent = new Intent(activity, Settings.getMapProvider().getMapClass()); + final Intent mapIntent = new Intent(activity, Settings.getMapProvider().getMapClass()); mapIntent.putExtra(EXTRAS_SEARCH, searchIntent); mapIntent.putExtra(EXTRAS_GEOCODE, geocodeIntent); @@ -896,7 +976,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto */ private final WeakReference<CGeoMap> map; - public UpdateLoc(CGeoMap map) { + public UpdateLoc(final CGeoMap map) { this.map = new WeakReference<CGeoMap>(map); } @@ -922,15 +1002,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto timeLastPositionOverlayCalculation = currentTimeMillis; try { - CGeoMap cgeoMapRef = map.get(); + final CGeoMap cgeoMapRef = map.get(); if (cgeoMapRef != null) { if (cgeoMapRef.mapView != null) { if (cgeoMapRef.overlayPositionAndScale == null) { - cgeoMapRef.overlayPositionAndScale = cgeoMapRef.mapView.createAddPositionAndScaleOverlay(cgeoMapRef.activity); + cgeoMapRef.overlayPositionAndScale = cgeoMapRef.mapView.createAddPositionAndScaleOverlay(); } - boolean needsRepaintForDistance = needsRepaintForDistance(); - boolean needsRepaintForHeading = needsRepaintForHeading(); + final boolean needsRepaintForDistance = needsRepaintForDistance(); + final boolean needsRepaintForHeading = needsRepaintForHeading(); if (needsRepaintForDistance) { if (cgeoMapRef.followMyLocation) { @@ -945,7 +1025,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } } - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.w("Failed to update location."); } } @@ -1003,50 +1083,84 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto return loadTimer; } - /** - * loading timer Triggers every 250ms and checks for viewport change and starts a {@link LoadRunnable}. - */ - private Subscription startLoadTimer() { - return Schedulers.newThread().schedulePeriodically(new Action1<Scheduler.Inner>() { - @Override - public void call(Scheduler.Inner inner) { - try { - if (mapView != null) { - // get current viewport - final Viewport viewportNow = mapView.getViewport(); - // Since zoomNow is used only for local comparison purposes, - // it is ok to use the Google Maps compatible zoom level of OSM Maps - final int zoomNow = mapView.getMapZoomLevel(); - - // check if map moved or zoomed - //TODO Portree Use Rectangle inside with bigger search window. That will stop reloading on every move - final boolean moved = markersInvalidated || (isLiveEnabled && !downloaded) || (viewport == null) || zoomNow != zoom || - (mapMoved(viewport, viewportNow) && (cachesCnt <= 0 || CollectionUtils.isEmpty(caches) || !viewport.includes(viewportNow))); - - // update title on any change - if (moved || !viewportNow.equals(viewport)) { - displayHandler.sendEmptyMessage(UPDATE_TITLE); - } - zoom = zoomNow; + private static final class LoadTimerAction implements Action0, Subscription { - // save new values - if (moved) { - markersInvalidated = false; + private volatile boolean isUnsubscribed = false; - long currentTime = System.currentTimeMillis(); + @NonNull private final WeakReference<CGeoMap> mapRef; - if (1000 < (currentTime - loadThreadRun)) { - viewport = viewportNow; - loadExecutor.execute(new LoadRunnable(viewport)); - } - } + public LoadTimerAction(@NonNull final CGeoMap map) { + this.mapRef = new WeakReference<CGeoMap>(map); + } + + @Override + public void call() { + final CGeoMap map = mapRef.get(); + if (map == null) { + return; + } + try { + if (map.mapView != null && !isUnsubscribed) { + // get current viewport + final Viewport viewportNow = map.mapView.getViewport(); + // Since zoomNow is used only for local comparison purposes, + // it is ok to use the Google Maps compatible zoom level of OSM Maps + final int zoomNow = map.mapView.getMapZoomLevel(); + + // check if map moved or zoomed + //TODO Portree Use Rectangle inside with bigger search window. That will stop reloading on every move + final boolean moved = map.markersInvalidated || (map.isLiveEnabled && !map.downloaded) || (map.viewport == null) || zoomNow != map.zoom || + (mapMoved(map.viewport, viewportNow) && (map.cachesCnt <= 0 || CollectionUtils.isEmpty(map.caches) || !map.viewport.includes(viewportNow))); + + // update title on any change + if (moved || !viewportNow.equals(map.viewport)) { + map.displayHandler.sendEmptyMessage(UPDATE_TITLE); } + map.zoom = zoomNow; - } catch (Exception e) { - Log.w("CGeoMap.startLoadtimer.start", e); + // save new values + if (moved) { + map.markersInvalidated = false; + + final long currentTime = System.currentTimeMillis(); + + if (1000 < (currentTime - map.loadThreadRun)) { + map.viewport = viewportNow; + loadExecutor.execute(new LoadRunnable(map)); + } + } } + + } catch (final Exception e) { + Log.w("CGeoMap.startLoadtimer.start", e); } - }, 250, 250, TimeUnit.MILLISECONDS); + + if (!isUnsubscribed) { + Schedulers.newThread().createWorker().schedule(this, 250, TimeUnit.MILLISECONDS); + } + } + + @Override + public void unsubscribe() { + isUnsubscribed = true; + } + + @Override + public boolean isUnsubscribed() { + return isUnsubscribed; + } + } + + /** + * loading timer Triggers every 250ms and checks for viewport change and starts a {@link LoadRunnable}. + */ + private Subscription startLoadTimer() { + // We cannot use schedulePeriodically with RxJava 0.19 and earlier because the unsubscription + // mechanism fails. As a consequence, we reschedule periodically by hand as long as we are not + // unsubscribed. There may be a small drift, but it has no consequence. + final LoadTimerAction action = new LoadTimerAction(this); + Schedulers.newThread().createWorker().schedule(action, 250, TimeUnit.MILLISECONDS); + return action; } /** @@ -1066,79 +1180,87 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto * started by {@link LoadTimer} */ - private class LoadRunnable extends DoRunnable { + private static class LoadRunnable extends DoRunnable { - public LoadRunnable(final Viewport viewport) { - super(viewport); + public LoadRunnable(@NonNull final CGeoMap map) { + super(map); } @Override public void run() { - try { - showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); - loadThreadRun = System.currentTimeMillis(); - - SearchResult searchResult; - if (mapMode == MapMode.LIVE) { - searchResult = isLiveEnabled ? new SearchResult() : new SearchResult(DataStore.loadStoredInViewport(viewport, Settings.getCacheType())); - } else { - // map started from another activity - searchResult = searchIntent != null ? new SearchResult(searchIntent) : new SearchResult(); - if (geocodeIntent != null) { - searchResult.addGeocode(geocodeIntent); - } - } - // live mode search result - if (isLiveEnabled) { - searchResult.addSearchResult(DataStore.loadCachedInViewport(viewport, Settings.getCacheType())); - } + final CGeoMap map = getMap(); + if (map != null) { + map.doLoadRun(); + } + } + } - 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); + private void doLoadRun() { + try { + showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); + loadThreadRun = System.currentTimeMillis(); - final boolean excludeMine = Settings.isExcludeMyCaches(); - final boolean excludeDisabled = Settings.isExcludeDisabledCaches(); - if (mapMode == MapMode.LIVE) { - CGeoMap.filter(caches); + SearchResult searchResult; + if (mapMode == MapMode.LIVE) { + searchResult = isLiveEnabled ? new SearchResult() : new SearchResult(DataStore.loadStoredInViewport(viewport, Settings.getCacheType())); + } else { + // map started from another activity + searchResult = searchIntent != null ? new SearchResult(searchIntent) : new SearchResult(); + if (geocodeIntent != null) { + searchResult.addGeocode(geocodeIntent); } - countVisibleCaches(); - if (cachesCnt < Settings.getWayPointsThreshold() || geocodeIntent != null) { - // we don't want to see any stale waypoints - waypoints.clear(); - if (isLiveEnabled || mapMode == MapMode.LIVE - || mapMode == MapMode.COORDS) { - //All visible waypoints - CacheType type = Settings.getCacheType(); - Set<Waypoint> waypointsInViewport = DataStore.loadWaypoints(viewport, excludeMine, excludeDisabled, type); - waypoints.addAll(waypointsInViewport); - } - else { - //All waypoints from the viewed caches - for (Geocache c : caches.getAsList()) { - waypoints.addAll(c.getWaypoints()); - } - } + } + // live mode search result + if (isLiveEnabled) { + searchResult.addSearchResult(DataStore.loadCachedInViewport(viewport, Settings.getCacheType())); + } + + downloaded = true; + final 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(); + final boolean excludeDisabled = Settings.isExcludeDisabledCaches(); + if (mapMode == MapMode.LIVE) { + CGeoMap.filter(caches); + } + countVisibleCaches(); + if (cachesCnt < Settings.getWayPointsThreshold() || geocodeIntent != null) { + // we don't want to see any stale waypoints + waypoints.clear(); + if (isLiveEnabled || mapMode == MapMode.LIVE + || mapMode == MapMode.COORDS) { + //All visible waypoints + final CacheType type = Settings.getCacheType(); + final Set<Waypoint> waypointsInViewport = DataStore.loadWaypoints(viewport, excludeMine, excludeDisabled, type); + waypoints.addAll(waypointsInViewport); } else { - // we don't want to see any stale waypoints when above threshold - waypoints.clear(); + //All waypoints from the viewed caches + for (final Geocache c : caches.getAsList()) { + waypoints.addAll(c.getWaypoints()); + } } + } + else { + // we don't want to see any stale waypoints when above threshold + waypoints.clear(); + } - //render - displayExecutor.execute(new DisplayRunnable(viewport)); + //render + displayExecutor.execute(new DisplayRunnable(this)); - if (isLiveEnabled) { - downloadExecutor.execute(new DownloadRunnable(viewport)); - } - lastSearchResult = searchResult; - } finally { - showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress + if (isLiveEnabled) { + downloadExecutor.execute(new DownloadRunnable(this)); } + lastSearchResult = searchResult; + } finally { + showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress } + } /** @@ -1146,111 +1268,125 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto * Started by {@link LoadRunnable}. */ - private class DownloadRunnable extends DoRunnable { + private static class DownloadRunnable extends DoRunnable { - public DownloadRunnable(final Viewport viewport) { - super(viewport); + public DownloadRunnable(final CGeoMap map) { + super(map); } @Override public void run() { - try { - showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); // show progress - if (Settings.isGCConnectorActive()) { - if (tokens == null) { - tokens = GCLogin.getInstance().getMapTokens(); - if (noMapTokenHandler != null && (StringUtils.isEmpty(tokens.getUserSession()) || StringUtils.isEmpty(tokens.getSessionToken()))) { - tokens = null; - noMapTokenHandler.sendEmptyMessage(0); - } + final CGeoMap map = getMap(); + if (map != null) { + map.doDownloadRun(); + } + } + } + + private void doDownloadRun() { + try { + showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); // show progress + if (Settings.isGCConnectorActive()) { + if (tokens == null) { + tokens = GCLogin.getInstance().getMapTokens(); + if (noMapTokenHandler != null && (StringUtils.isEmpty(tokens.getUserSession()) || StringUtils.isEmpty(tokens.getSessionToken()))) { + tokens = null; + noMapTokenHandler.sendEmptyMessage(0); } } - final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens); - downloaded = true; - - Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); - CGeoMap.filter(result); - // update the caches - // first remove filtered out - final Set<String> filteredCodes = searchResult.getFilteredGeocodes(); - Log.d("Filtering out " + filteredCodes.size() + " caches: " + filteredCodes.toString()); - caches.removeAll(DataStore.loadCaches(filteredCodes, LoadFlags.LOAD_CACHE_ONLY)); - DataStore.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.REMOVE_CACHE)); - // new collection type needs to remove first to refresh - caches.removeAll(result); - caches.addAll(result); - lastSearchResult = searchResult; - - //render - displayExecutor.execute(new DisplayRunnable(viewport)); - - } catch (ThreadDeath e) { - Log.d("DownloadThread stopped"); - displayHandler.sendEmptyMessage(UPDATE_TITLE); - } finally { - showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress } + final SearchResult searchResult = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens); + downloaded = true; + + final Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + CGeoMap.filter(result); + // update the caches + // first remove filtered out + final Set<String> filteredCodes = searchResult.getFilteredGeocodes(); + Log.d("Filtering out " + filteredCodes.size() + " caches: " + filteredCodes.toString()); + caches.removeAll(DataStore.loadCaches(filteredCodes, LoadFlags.LOAD_CACHE_ONLY)); + DataStore.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + // new collection type needs to remove first to refresh + caches.removeAll(result); + caches.addAll(result); + lastSearchResult = searchResult; + + //render + displayExecutor.execute(new DisplayRunnable(this)); + + } catch (final ThreadDeath e) { + Log.d("DownloadThread stopped"); + displayHandler.sendEmptyMessage(UPDATE_TITLE); + } finally { + showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress } } /** * Thread to Display (down)loaded caches. Started by {@link LoadRunnable} and {@link DownloadRunnable} */ - private class DisplayRunnable extends DoRunnable { + private static class DisplayRunnable extends DoRunnable { - public DisplayRunnable(final Viewport viewport) { - super(viewport); + public DisplayRunnable(@NonNull final CGeoMap map) { + super(map); } @Override public void run() { - try { - showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); - if (mapView == null || caches == null) { - throw new ThreadDeath(); - } - - // display caches - final List<Geocache> cachesToDisplay = caches.getAsList(); - final List<Waypoint> waypointsToDisplay = new ArrayList<Waypoint>(waypoints); - final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>(); + final CGeoMap map = getMap(); + if (map != null) { + map.doDisplayRun(); + } + } + } - if (!cachesToDisplay.isEmpty()) { - // Only show waypoints for single view or setting - // when less than showWaypointsthreshold Caches shown - if (mapMode == MapMode.SINGLE || (cachesCnt < Settings.getWayPointsThreshold())) { - for (Waypoint waypoint : waypointsToDisplay) { + private void doDisplayRun() { + try { + showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); + if (mapView == null || caches == null) { + throw new ThreadDeath(); + } - if (waypoint == null || waypoint.getCoords() == null) { - continue; - } + // display caches + final List<Geocache> cachesToDisplay = caches.getAsList(); + final List<Waypoint> waypointsToDisplay = new ArrayList<Waypoint>(waypoints); + final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>(); - itemsToDisplay.add(getWaypointItem(waypoint)); - } - } - for (Geocache cache : cachesToDisplay) { + if (!cachesToDisplay.isEmpty()) { + // Only show waypoints for single view or setting + // when less than showWaypointsthreshold Caches shown + if (mapMode == MapMode.SINGLE || (cachesCnt < Settings.getWayPointsThreshold())) { + for (final Waypoint waypoint : waypointsToDisplay) { - if (cache == null || cache.getCoords() == null) { + if (waypoint == null || waypoint.getCoords() == null) { continue; } - itemsToDisplay.add(getCacheItem(cache)); - } - overlayCaches.updateItems(itemsToDisplay); - displayHandler.sendEmptyMessage(INVALIDATE_MAP); + itemsToDisplay.add(getWaypointItem(waypoint)); + } + } + for (final Geocache cache : cachesToDisplay) { - } else { - overlayCaches.updateItems(itemsToDisplay); - displayHandler.sendEmptyMessage(INVALIDATE_MAP); + if (cache == null || cache.getCoords() == null) { + continue; + } + itemsToDisplay.add(getCacheItem(cache)); } - displayHandler.sendEmptyMessage(UPDATE_TITLE); - } catch (ThreadDeath e) { - Log.d("DisplayThread stopped"); - displayHandler.sendEmptyMessage(UPDATE_TITLE); - } finally { - showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); + overlayCaches.updateItems(itemsToDisplay); + displayHandler.sendEmptyMessage(INVALIDATE_MAP); + + } else { + overlayCaches.updateItems(itemsToDisplay); + displayHandler.sendEmptyMessage(INVALIDATE_MAP); } + + displayHandler.sendEmptyMessage(UPDATE_TITLE); + } catch (final ThreadDeath e) { + Log.d("DisplayThread stopped"); + displayHandler.sendEmptyMessage(UPDATE_TITLE); + } finally { + showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); } } @@ -1268,10 +1404,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto private static abstract class DoRunnable implements Runnable { - final protected Viewport viewport; + private final WeakReference<CGeoMap> mapRef; - protected DoRunnable(final Viewport viewport) { - this.viewport = viewport; + protected DoRunnable(@NonNull final CGeoMap map) { + mapRef = new WeakReference<CGeoMap>(map); + } + + protected @Nullable + final CGeoMap getMap() { + return mapRef.get(); } } @@ -1281,7 +1422,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto * @param listId * the list to store the caches in */ - private void storeCaches(List<String> geocodes, int listId) { + private void storeCaches(final List<String> geocodes, final int listId) { final LoadDetailsHandler loadDetailsHandler = new LoadDetailsHandler(); waitDialog = new ProgressDialog(activity); @@ -1292,19 +1433,19 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override - public void onCancel(DialogInterface arg0) { + public void onCancel(final DialogInterface arg0) { try { if (loadDetailsThread != null) { loadDetailsThread.stopIt(); } - } catch (Exception e) { + } catch (final Exception e) { Log.e("CGeoMap.storeCaches.onCancel", e); } } }); - float etaTime = detailTotal * 7.0f / 60.0f; - int roundedEta = Math.round(etaTime); + final float etaTime = detailTotal * 7.0f / 60.0f; + final int roundedEta = Math.round(etaTime); if (etaTime < 0.4) { waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); } else { @@ -1353,7 +1494,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (!DataStore.isOffline(geocode, null)) { Geocache.storeCache(null, geocode, listId, false, handler); } - } catch (Exception e) { + } catch (final Exception e) { Log.e("CGeoMap.LoadDetails.run", e); } finally { // one more cache over @@ -1367,13 +1508,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } - private static synchronized void filter(Collection<Geocache> caches) { - boolean excludeMine = Settings.isExcludeMyCaches(); - boolean excludeDisabled = Settings.isExcludeDisabledCaches(); + private static synchronized void filter(final Collection<Geocache> caches) { + final boolean excludeMine = Settings.isExcludeMyCaches(); + final boolean excludeDisabled = Settings.isExcludeDisabledCaches(); - List<Geocache> removeList = new ArrayList<Geocache>(); - for (Geocache cache : caches) { - if ((excludeMine && cache.isFound()) || (excludeMine && cache.isOwner()) || (excludeDisabled && cache.isDisabled())) { + final List<Geocache> removeList = new ArrayList<Geocache>(); + for (final Geocache cache : caches) { + if ((excludeMine && cache.isFound()) || (excludeMine && cache.isOwner()) || (excludeDisabled && cache.isDisabled()) || (excludeDisabled && cache.isArchived())) { removeList.add(cache); } } @@ -1410,14 +1551,14 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } // move map to view results of searchIntent - private void centerMap(String geocodeCenter, final SearchResult searchCenter, final Geopoint coordsCenter, int[] mapState) { + private void centerMap(final String geocodeCenter, final SearchResult searchCenter, final Geopoint coordsCenter, final int[] mapState) { final MapControllerImpl mapController = mapView.getMapController(); if (!centered && mapState != null) { try { mapController.setCenter(mapItemFactory.getGeoPointBase(new Geopoint(mapState[0] / 1.0e6, mapState[1] / 1.0e6))); setZoom(mapState[2]); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.e("centermap", e); } @@ -1441,7 +1582,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (viewport.getLatitudeSpan() != 0 && viewport.getLongitudeSpan() != 0) { mapController.zoomToSpan((int) (viewport.getLatitudeSpan() * 1e6), (int) (viewport.getLongitudeSpan() * 1e6)); } - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.e("centermap", e); } @@ -1450,7 +1591,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } else if (!centered && coordsCenter != null) { try { mapController.setCenter(makeGeoPoint(coordsCenter)); - } catch (Exception e) { + } catch (final Exception e) { Log.e("centermap", e); } @@ -1461,25 +1602,54 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto // switch My Location button image private void switchMyLocationButton() { + myLocSwitch.setChecked(followMyLocation); if (followMyLocation) { - myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_on); myLocationInMiddle(app.currentGeo()); - } else { - myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_off); } } // set my location listener - private class MyLocationListener implements View.OnClickListener { + private static class MyLocationListener implements View.OnClickListener { + + private final WeakReference<CGeoMap> mapRef; + + public MyLocationListener(@NonNull final CGeoMap map) { + mapRef = new WeakReference<CGeoMap>(map); + } + @Override - public void onClick(View view) { - followMyLocation = !followMyLocation; - switchMyLocationButton(); + public void onClick(final View view) { + final CGeoMap map = mapRef.get(); + if (map != null) { + map.onFollowMyLocationClicked(); + } } } - @Override - public void onDrag() { + private void onFollowMyLocationClicked() { + followMyLocation = !followMyLocation; + switchMyLocationButton(); + } + + public static class MapDragListener implements OnMapDragListener { + + private final WeakReference<CGeoMap> mapRef; + + public MapDragListener(@NonNull final CGeoMap map) { + mapRef = new WeakReference<CGeoMap>(map); + } + + @Override + public void onDrag() { + final CGeoMap map = mapRef.get(); + if (map != null) { + map.onDrag(); + } + } + + } + + private void onDrag() { if (followMyLocation) { followMyLocation = false; switchMyLocationButton(); @@ -1491,15 +1661,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto return mapItemFactory.getGeoPointBase(coords); } - // close activity and open homescreen - @Override - public void goHome(View view) { - ActivityMixin.goHome(activity); - } - @Override public View makeView() { - ImageView imageView = new ImageView(activity); + final ImageView imageView = new ImageView(activity); imageView.setScaleType(ScaleType.CENTER); imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); return imageView; @@ -1637,7 +1801,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto private CachesOverlayItemImpl getWaypointItem(final Waypoint waypoint) { final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(waypoint, waypoint.getWaypointType().applyDistanceRule()); - Drawable marker = getResources().getDrawable(!waypoint.isVisited() ? R.drawable.marker : R.drawable.marker_transparent); + final Drawable marker = getResources().getDrawable(!waypoint.isVisited() ? R.drawable.marker : R.drawable.marker_transparent); final Drawable[] layers = new Drawable[] { marker, getResources().getDrawable(waypoint.getWaypointType().markerId) diff --git a/main/src/cgeo/geocaching/maps/CachesOverlay.java b/main/src/cgeo/geocaching/maps/CachesOverlay.java index 0c7c296..8607c88 100644 --- a/main/src/cgeo/geocaching/maps/CachesOverlay.java +++ b/main/src/cgeo/geocaching/maps/CachesOverlay.java @@ -211,9 +211,9 @@ public class CachesOverlay extends AbstractItemizedOverlay { progress.show(context, context.getResources().getString(R.string.map_live), context.getResources().getString(R.string.cache_dialog_loading_details), true, null); - CachesOverlayItemImpl item = null; // prevent concurrent changes getOverlayImpl().lock(); + CachesOverlayItemImpl item = null; try { if (index < items.size()) { item = items.get(index); diff --git a/main/src/cgeo/geocaching/maps/PositionAndScaleOverlay.java b/main/src/cgeo/geocaching/maps/PositionAndScaleOverlay.java index 6b34b75..63fcd73 100644 --- a/main/src/cgeo/geocaching/maps/PositionAndScaleOverlay.java +++ b/main/src/cgeo/geocaching/maps/PositionAndScaleOverlay.java @@ -5,7 +5,6 @@ import cgeo.geocaching.maps.interfaces.MapProjectionImpl; import cgeo.geocaching.maps.interfaces.MapViewImpl; import cgeo.geocaching.maps.interfaces.OverlayImpl; -import android.app.Activity; import android.graphics.Canvas; import android.graphics.Point; import android.location.Location; @@ -18,10 +17,10 @@ public class PositionAndScaleOverlay implements GeneralOverlay { PositionDrawer positionDrawer = null; ScaleDrawer scaleDrawer = null; - public PositionAndScaleOverlay(Activity activity, OverlayImpl ovlImpl) { + public PositionAndScaleOverlay(OverlayImpl ovlImpl) { this.ovlImpl = ovlImpl; - positionDrawer = new PositionDrawer(activity); - scaleDrawer = new ScaleDrawer(activity); + positionDrawer = new PositionDrawer(); + scaleDrawer = new ScaleDrawer(); } public void setCoordinates(Location coordinatesIn) { diff --git a/main/src/cgeo/geocaching/maps/PositionDrawer.java b/main/src/cgeo/geocaching/maps/PositionDrawer.java index 1a5dcaf..0e20e7c 100644 --- a/main/src/cgeo/geocaching/maps/PositionDrawer.java +++ b/main/src/cgeo/geocaching/maps/PositionDrawer.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps; +import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.R; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.maps.interfaces.GeoPointImpl; @@ -7,7 +8,6 @@ import cgeo.geocaching.maps.interfaces.MapItemFactory; import cgeo.geocaching.maps.interfaces.MapProjectionImpl; import cgeo.geocaching.settings.Settings; -import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -36,11 +36,9 @@ public class PositionDrawer { private PaintFlagsDrawFilter setfil = null; private PaintFlagsDrawFilter remfil = null; private PositionHistory positionHistory = new PositionHistory(); - private Activity activity; private MapItemFactory mapItemFactory; - public PositionDrawer(Activity activity) { - this.activity = activity; + public PositionDrawer() { this.mapItemFactory = Settings.getMapProvider().getMapItemFactory(); } @@ -144,7 +142,7 @@ public class PositionDrawer { } if (arrow == null) { - arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron); + arrow = BitmapFactory.decodeResource(CgeoApplication.getInstance().getResources(), R.drawable.my_location_chevron); widthArrowHalf = arrow.getWidth() / 2; heightArrowHalf = arrow.getHeight() / 2; } diff --git a/main/src/cgeo/geocaching/maps/ScaleDrawer.java b/main/src/cgeo/geocaching/maps/ScaleDrawer.java index fb46408..95c987d 100644 --- a/main/src/cgeo/geocaching/maps/ScaleDrawer.java +++ b/main/src/cgeo/geocaching/maps/ScaleDrawer.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps; +import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.Units; import cgeo.geocaching.maps.interfaces.GeoPointImpl; @@ -7,12 +8,13 @@ import cgeo.geocaching.maps.interfaces.MapViewImpl; import org.apache.commons.lang3.tuple.ImmutablePair; -import android.app.Activity; +import android.content.Context; import android.graphics.BlurMaskFilter; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Typeface; import android.util.DisplayMetrics; +import android.view.WindowManager; public class ScaleDrawer { private static final double SCALE_WIDTH_FACTOR = 1.0 / 2.5; @@ -22,9 +24,10 @@ public class ScaleDrawer { private BlurMaskFilter blur = null; private float pixelDensity = 0; - public ScaleDrawer(Activity activity) { + public ScaleDrawer() { DisplayMetrics metrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + WindowManager windowManager = (WindowManager) CgeoApplication.getInstance().getSystemService(Context.WINDOW_SERVICE); + windowManager.getDefaultDisplay().getMetrics(metrics); pixelDensity = metrics.density; } diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java b/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java index a98241f..2a29cc9 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps.google; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.FilteredActivity; import cgeo.geocaching.maps.AbstractMap; import cgeo.geocaching.maps.CGeoMap; @@ -97,6 +98,11 @@ public class GoogleMapActivity extends MapActivity implements MapActivityImpl, F } @Override + public void navigateUp(View view) { + ActivityMixin.navigateUp(this); + } + + @Override public void superOnResume() { super.onResume(); } @@ -116,12 +122,6 @@ public class GoogleMapActivity extends MapActivity implements MapActivityImpl, F return super.onPrepareOptionsMenu(menu); } - // close activity and open homescreen - @Override - public void goHome(View view) { - mapBase.goHome(view); - } - @Override public void showFilterMenu(View view) { // do nothing, the filter bar only shows the global filter diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java index 610dbe1..ea815ab 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java @@ -20,7 +20,6 @@ import com.google.android.maps.MapView; import org.apache.commons.lang3.reflect.MethodUtils; import org.eclipse.jdt.annotation.NonNull; -import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; @@ -39,16 +38,23 @@ public class GoogleMapView extends MapView implements MapViewImpl { public GoogleMapView(Context context, AttributeSet attrs) { super(context, attrs); - gestureDetector = new GestureDetector(context, new GestureListener()); + initialize(context); } public GoogleMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - gestureDetector = new GestureDetector(context, new GestureListener()); + initialize(context); } public GoogleMapView(Context context, String apiKey) { super(context, apiKey); + initialize(context); + } + + private void initialize(Context context) { + if (isInEditMode()) { + return; + } gestureDetector = new GestureDetector(context, new GestureListener()); } @@ -120,9 +126,9 @@ public class GoogleMapView extends MapView implements MapViewImpl { } @Override - public PositionAndScaleOverlay createAddPositionAndScaleOverlay(Activity activity) { + public PositionAndScaleOverlay createAddPositionAndScaleOverlay() { - GoogleOverlay ovl = new GoogleOverlay(activity); + GoogleOverlay ovl = new GoogleOverlay(); getOverlays().add(ovl); return (PositionAndScaleOverlay) ovl.getBase(); } diff --git a/main/src/cgeo/geocaching/maps/google/GoogleOverlay.java b/main/src/cgeo/geocaching/maps/google/GoogleOverlay.java index 0a5cf69..c684b9a 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleOverlay.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleOverlay.java @@ -8,7 +8,6 @@ import cgeo.geocaching.maps.interfaces.OverlayImpl; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; -import android.app.Activity; import android.graphics.Canvas; import java.util.concurrent.locks.Lock; @@ -19,8 +18,8 @@ public class GoogleOverlay extends Overlay implements OverlayImpl { private PositionAndScaleOverlay overlayBase = null; private Lock lock = new ReentrantLock(); - public GoogleOverlay(Activity activityIn) { - overlayBase = new PositionAndScaleOverlay(activityIn, this); + public GoogleOverlay() { + overlayBase = new PositionAndScaleOverlay(this); } @Override diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java index e7deebd..3596d5f 100644 --- a/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java +++ b/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java @@ -33,6 +33,5 @@ public interface MapActivityImpl { boolean superOnOptionsItemSelected(MenuItem item); - public abstract void goHome(View view); - + public abstract void navigateUp(View view); } diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java index 5ae8e15..4a6d733 100644 --- a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java +++ b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java @@ -6,7 +6,6 @@ import cgeo.geocaching.maps.PositionAndScaleOverlay; import org.eclipse.jdt.annotation.NonNull; -import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; @@ -47,7 +46,7 @@ public interface MapViewImpl { CachesOverlay createAddMapOverlay(Context context, Drawable drawable); - PositionAndScaleOverlay createAddPositionAndScaleOverlay(Activity activity); + PositionAndScaleOverlay createAddPositionAndScaleOverlay(); void setMapSource(); diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapActivity.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapActivity.java index a0384b8..94213ba 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapActivity.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapActivity.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps.mapsforge; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.FilteredActivity; import cgeo.geocaching.maps.AbstractMap; import cgeo.geocaching.maps.CGeoMap; @@ -111,10 +112,9 @@ public class MapsforgeMapActivity extends MapActivity implements MapActivityImpl return super.onPrepareOptionsMenu(menu); } - // close activity and open homescreen @Override - public void goHome(View view) { - mapBase.goHome(view); + public void navigateUp(View view) { + ActivityMixin.navigateUp(this); } @Override diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java index 7a5aab2..d95cc80 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java @@ -24,7 +24,6 @@ import org.mapsforge.android.maps.mapgenerator.MapGeneratorInternal; import org.mapsforge.android.maps.overlay.Overlay; import org.mapsforge.core.GeoPoint; -import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; @@ -43,6 +42,13 @@ public class MapsforgeMapView extends MapView implements MapViewImpl { public MapsforgeMapView(Context context, AttributeSet attrs) { super(context, attrs); + initialize(context); + } + + private void initialize(Context context) { + if (isInEditMode()) { + return; + } gestureDetector = new GestureDetector(context, new GestureListener()); if (Settings.isScaleMapsforgeText()) { this.setTextScale(getResources().getDisplayMetrics().density); @@ -105,8 +111,8 @@ public class MapsforgeMapView extends MapView implements MapViewImpl { } @Override - public PositionAndScaleOverlay createAddPositionAndScaleOverlay(Activity activity) { - MapsforgeOverlay ovl = new MapsforgeOverlay(activity); + public PositionAndScaleOverlay createAddPositionAndScaleOverlay() { + MapsforgeOverlay ovl = new MapsforgeOverlay(); getOverlays().add(ovl); return (PositionAndScaleOverlay) ovl.getBase(); } diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOverlay.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOverlay.java index 74a8601..3df4ab0 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOverlay.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOverlay.java @@ -8,7 +8,6 @@ import cgeo.geocaching.maps.interfaces.OverlayImpl; import org.mapsforge.android.maps.Projection; import org.mapsforge.android.maps.overlay.Overlay; -import android.app.Activity; import android.graphics.Canvas; import android.graphics.Point; @@ -20,8 +19,8 @@ public class MapsforgeOverlay extends Overlay implements OverlayImpl { private PositionAndScaleOverlay overlayBase = null; private Lock lock = new ReentrantLock(); - public MapsforgeOverlay(Activity activityIn) { - overlayBase = new PositionAndScaleOverlay(activityIn, this); + public MapsforgeOverlay() { + overlayBase = new PositionAndScaleOverlay(this); } @Override diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapActivity024.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapActivity024.java index 33ed30e..daeb2b8 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapActivity024.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapActivity024.java @@ -1,5 +1,6 @@ package cgeo.geocaching.maps.mapsforge.v024; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.FilteredActivity; import cgeo.geocaching.maps.AbstractMap; import cgeo.geocaching.maps.CGeoMap; @@ -111,10 +112,9 @@ public class MapsforgeMapActivity024 extends MapActivity implements MapActivityI return super.onPrepareOptionsMenu(menu); } - // close activity and open homescreen @Override - public void goHome(View view) { - mapBase.goHome(view); + public void navigateUp(View view) { + ActivityMixin.navigateUp(this); } @Override diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java index 4fa4e02..8dd15fc 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java @@ -21,7 +21,6 @@ import org.mapsforge.android.mapsold.MapViewMode; import org.mapsforge.android.mapsold.Overlay; import org.mapsforge.android.mapsold.Projection; -import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; @@ -37,6 +36,13 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl { public MapsforgeMapView024(Context context, AttributeSet attrs) { super(context, attrs); + initialize(context); + } + + private void initialize(Context context) { + if (isInEditMode()) { + return; + } gestureDetector = new GestureDetector(context, new GestureListener()); } @@ -96,8 +102,8 @@ public class MapsforgeMapView024 extends MapView implements MapViewImpl { } @Override - public PositionAndScaleOverlay createAddPositionAndScaleOverlay(Activity activity) { - MapsforgeOverlay ovl = new MapsforgeOverlay(activity); + public PositionAndScaleOverlay createAddPositionAndScaleOverlay() { + MapsforgeOverlay ovl = new MapsforgeOverlay(); getOverlays().add(ovl); return (PositionAndScaleOverlay) ovl.getBase(); } diff --git a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeOverlay.java b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeOverlay.java index 655e0b9..bfb3548 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeOverlay.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeOverlay.java @@ -8,7 +8,6 @@ import cgeo.geocaching.maps.interfaces.OverlayImpl; import org.mapsforge.android.mapsold.Overlay; import org.mapsforge.android.mapsold.Projection; -import android.app.Activity; import android.graphics.Canvas; import android.graphics.Point; @@ -20,8 +19,8 @@ public class MapsforgeOverlay extends Overlay implements OverlayImpl { private PositionAndScaleOverlay overlayBase = null; private Lock lock = new ReentrantLock(); - public MapsforgeOverlay(Activity activityIn) { - overlayBase = new PositionAndScaleOverlay(activityIn, this); + public MapsforgeOverlay() { + overlayBase = new PositionAndScaleOverlay(this); } @Override diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java index 9c55fe9..ce832fb 100644 --- a/main/src/cgeo/geocaching/network/HtmlImage.java +++ b/main/src/cgeo/geocaching/network/HtmlImage.java @@ -13,21 +13,20 @@ import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.RxUtils; import ch.boye.httpclientandroidlib.HttpResponse; + import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; + import rx.Observable; import rx.Observable.OnSubscribe; -import rx.Scheduler; -import rx.Scheduler.Inner; import rx.Subscriber; -import rx.functions.Action1; +import rx.functions.Action0; import rx.functions.Func0; import rx.functions.Func1; -import rx.schedulers.Schedulers; import rx.subjects.PublishSubject; import rx.subscriptions.CompositeSubscription; @@ -44,6 +43,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Date; +import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -92,10 +92,9 @@ public class HtmlImage implements Html.ImageGetter { // Background loading final private PublishSubject<Observable<String>> loading = PublishSubject.create(); - final Observable<String> waitForEnd = Observable.merge(loading).publish().refCount(); + final private Observable<String> waitForEnd = Observable.merge(loading).publish().refCount(); final CompositeSubscription subscription = new CompositeSubscription(waitForEnd.subscribe()); - final private Scheduler downloadScheduler = Schedulers.executor(new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS, - new LinkedBlockingQueue<Runnable>())); + final private Executor downloadExecutor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); public HtmlImage(final String geocode, final boolean returnErrorImage, final int listId, final boolean onlySave) { this.geocode = geocode; @@ -122,7 +121,7 @@ public class HtmlImage implements Html.ImageGetter { })); return null; } - return drawable.toBlockingObservable().lastOrDefault(null); + return drawable.toBlocking().lastOrDefault(null); } // Caches are loaded from disk on a computation scheduler to avoid using more threads than cores while decoding @@ -152,9 +151,9 @@ public class HtmlImage implements Html.ImageGetter { @Override public void call(final Subscriber<? super BitmapDrawable> subscriber) { subscription.add(subscriber); - subscriber.add(RxUtils.computationScheduler.schedule(new Action1<Inner>() { + subscriber.add(RxUtils.computationScheduler.createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { final Pair<BitmapDrawable, Boolean> loaded = loadFromDisk(); final BitmapDrawable bitmap = loaded.getLeft(); if (loaded.getRight()) { @@ -165,12 +164,11 @@ public class HtmlImage implements Html.ImageGetter { if (bitmap != null && !onlySave) { subscriber.onNext(bitmap); } - subscriber.add(downloadScheduler.schedule(new Action1<Inner>() { - @Override - public void call(final Inner inner) { + downloadExecutor.execute(new Runnable() { + @Override public void run() { downloadAndSave(subscriber); } - })); + }); } })); } @@ -205,9 +203,9 @@ public class HtmlImage implements Html.ImageGetter { if (onlySave) { subscriber.onCompleted(); } else { - RxUtils.computationScheduler.schedule(new Action1<Inner>() { + RxUtils.computationScheduler.createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { final Pair<BitmapDrawable, Boolean> loaded = loadFromDisk(); final BitmapDrawable image = loaded.getLeft(); if (image != null) { @@ -225,12 +223,12 @@ public class HtmlImage implements Html.ImageGetter { }); } - public void waitForBackgroundLoading(@Nullable final CancellableHandler handler) { + public Observable<String> waitForEndObservable(@Nullable final CancellableHandler handler) { if (handler != null) { handler.unsubscribeIfCancelled(subscription); } loading.onCompleted(); - waitForEnd.toBlockingObservable().lastOrDefault(null); + return waitForEnd; } /** diff --git a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java index e74751b..eb56f0b 100644 --- a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java +++ b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java @@ -106,7 +106,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity { @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState, R.layout.authorization_activity, true); + super.onCreate(savedInstanceState, R.layout.authorization_activity); Bundle extras = getIntent().getExtras(); if (extras != null) { diff --git a/main/src/cgeo/geocaching/network/StatusUpdater.java b/main/src/cgeo/geocaching/network/StatusUpdater.java index 4055f01..bf9ebdf 100644 --- a/main/src/cgeo/geocaching/network/StatusUpdater.java +++ b/main/src/cgeo/geocaching/network/StatusUpdater.java @@ -5,10 +5,9 @@ import cgeo.geocaching.utils.Version; import org.json.JSONException; import org.json.JSONObject; -import rx.Scheduler; +import rx.functions.Action0; import rx.schedulers.Schedulers; import rx.subjects.BehaviorSubject; -import rx.functions.Action1; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; @@ -52,9 +51,9 @@ public class StatusUpdater { final static public BehaviorSubject<Status> latestStatus = BehaviorSubject.create(Status.defaultStatus(null)); static { - Schedulers.io().schedulePeriodically(new Action1<Scheduler.Inner>() { + Schedulers.io().createWorker().schedulePeriodically(new Action0() { @Override - public void call(final Scheduler.Inner inner) { + public void call() { final JSONObject response = Network.requestJSON("http://status.cgeo.org/api/status.json", new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())), diff --git a/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java b/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java index 45559f4..21cf089 100644 --- a/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java +++ b/main/src/cgeo/geocaching/search/AutoCompleteAdapter.java @@ -1,6 +1,7 @@ package cgeo.geocaching.search; import org.apache.commons.lang3.StringUtils; + import rx.functions.Func1; import android.content.Context; @@ -14,11 +15,11 @@ import android.widget.Filter; */ public class AutoCompleteAdapter extends ArrayAdapter<String> { - private final String[] EMPTY = new String[0]; + private final static String[] EMPTY = new String[0]; private String[] suggestions = EMPTY; private final Func1<String, String[]> suggestionFunction; - public AutoCompleteAdapter(Context context, int textViewResourceId, final Func1<String, String[]> suggestionFunction) { + public AutoCompleteAdapter(final Context context, final int textViewResourceId, final Func1<String, String[]> suggestionFunction) { super(context, textViewResourceId); this.suggestionFunction = suggestionFunction; } @@ -29,7 +30,7 @@ public class AutoCompleteAdapter extends ArrayAdapter<String> { } @Override - public String getItem(int index) { + public String getItem(final int index) { return suggestions[index]; } @@ -38,14 +39,14 @@ public class AutoCompleteAdapter extends ArrayAdapter<String> { return new Filter() { @Override - protected FilterResults performFiltering(CharSequence constraint) { - FilterResults filterResults = new FilterResults(); + protected FilterResults performFiltering(final CharSequence constraint) { + final FilterResults filterResults = new FilterResults(); if (constraint == null) { return filterResults; } - String trimmed = StringUtils.trim(constraint.toString()); + final String trimmed = StringUtils.trim(constraint.toString()); if (StringUtils.length(trimmed) >= 2) { - String[] newResults = suggestionFunction.call(trimmed); + final String[] newResults = suggestionFunction.call(trimmed); // Assign the data to the FilterResults, but do not yet store in the global member. // Otherwise we might invalidate the adapter and cause an IllegalStateException. @@ -56,7 +57,7 @@ public class AutoCompleteAdapter extends ArrayAdapter<String> { } @Override - protected void publishResults(CharSequence constraint, FilterResults filterResults) { + protected void publishResults(final CharSequence constraint, final FilterResults filterResults) { if (filterResults != null && filterResults.count > 0) { suggestions = (String[]) filterResults.values; notifyDataSetChanged(); diff --git a/main/src/cgeo/geocaching/search/SearchSuggestionCursor.java b/main/src/cgeo/geocaching/search/SearchSuggestionCursor.java new file mode 100644 index 0000000..350e23a --- /dev/null +++ b/main/src/cgeo/geocaching/search/SearchSuggestionCursor.java @@ -0,0 +1,46 @@ +package cgeo.geocaching.search; + +import cgeo.geocaching.Intents; +import cgeo.geocaching.enumerations.CacheType; + +import org.eclipse.jdt.annotation.NonNull; + +import android.app.SearchManager; +import android.database.MatrixCursor; +import android.provider.BaseColumns; + +/** + * Fixed fields cursor holding the necessary data for the search provider of the global search bar. + * + */ +public class SearchSuggestionCursor extends MatrixCursor { + + /** + * id of the row for callbacks after selection + */ + private int rowId = 0; + + public SearchSuggestionCursor() { + super(new String[] { + BaseColumns._ID, + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_TEXT_2, + SearchManager.SUGGEST_COLUMN_INTENT_ACTION, + SearchManager.SUGGEST_COLUMN_QUERY, + SearchManager.SUGGEST_COLUMN_ICON_1 }); + } + + public void addCache(@NonNull final String geocode, @NonNull final String name, final String type) { + final int icon = CacheType.getById(type).markerId; + addRow(new String[] { + String.valueOf(rowId), + name, + geocode, + Intents.ACTION_GEOCACHE, + geocode, + String.valueOf(icon) + }); + rowId++; + } + +} diff --git a/main/src/cgeo/geocaching/search/SuggestionProvider.java b/main/src/cgeo/geocaching/search/SuggestionProvider.java index c0a7728..f60a43e 100644 --- a/main/src/cgeo/geocaching/search/SuggestionProvider.java +++ b/main/src/cgeo/geocaching/search/SuggestionProvider.java @@ -1,6 +1,7 @@ package cgeo.geocaching.search; import cgeo.geocaching.DataStore; +import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; @@ -12,8 +13,6 @@ import android.net.Uri; public class SuggestionProvider extends ContentProvider { - private static Cursor lastCursor; - @Override public boolean onCreate() { return true; @@ -29,14 +28,21 @@ public class SuggestionProvider extends ContentProvider { final String searchTerm = uri.getLastPathSegment(); // can be empty when deleting the query if (StringUtils.equals(searchTerm, SearchManager.SUGGEST_URI_PATH_QUERY)) { - return lastCursor; + return getLastOpenedCaches(); } return getSuggestions(searchTerm); } + private static Cursor getLastOpenedCaches() { + final SearchSuggestionCursor resultCursor = new SearchSuggestionCursor(); + for (final Geocache geocache : DataStore.getLastOpenedCaches()) { + resultCursor.addCache(geocache.getGeocode(), geocache.getName(), geocache.getType().id); + } + return resultCursor; + } + private static Cursor getSuggestions(final String searchTerm) { - lastCursor = DataStore.findSuggestions(searchTerm); - return lastCursor; + return DataStore.findSuggestions(searchTerm); } @Override diff --git a/main/src/cgeo/geocaching/sensors/DirectionProvider.java b/main/src/cgeo/geocaching/sensors/DirectionProvider.java index ff4a439..ed5d76a 100644 --- a/main/src/cgeo/geocaching/sensors/DirectionProvider.java +++ b/main/src/cgeo/geocaching/sensors/DirectionProvider.java @@ -21,9 +21,13 @@ import android.view.WindowManager; public class DirectionProvider { - private static final BehaviorSubject<Float> subject = BehaviorSubject.create(0.0f); + private static final BehaviorSubject<Float> SUBJECT = BehaviorSubject.create(0.0f); - private static final WindowManager windowManager = (WindowManager) CgeoApplication.getInstance().getSystemService(Context.WINDOW_SERVICE); + private static final WindowManager WINDOW_MANAGER = (WindowManager) CgeoApplication.getInstance().getSystemService(Context.WINDOW_SERVICE); + + private DirectionProvider() { + // utility class + } static class Listener implements SensorEventListener, StartableHandlerThread.Callback { @@ -33,22 +37,17 @@ public class DirectionProvider { @Override public void onSensorChanged(final SensorEvent event) { - subject.onNext(event.values[0]); + SUBJECT.onNext(event.values[0]); } @Override public void onAccuracyChanged(final Sensor sensor, final int accuracy) { - /* - * There is a bug in Android, which apparently causes this method to be called every - * time the sensor _value_ changed, even if the _accuracy_ did not change. So logging - * this event leads to the log being flooded with multiple entries _per second_, - * which I experienced when running cgeo in a building (with GPS and network being - * unreliable). - * - * See for example https://code.google.com/p/android/issues/detail?id=14792 - */ - - //Log.i(Settings.tag, "Compass' accuracy is low (" + accuracy + ")"); + /* + * There is a bug in Android, which apparently causes this method to be called every + * time the sensor _value_ changed, even if the _accuracy_ did not change. Do not have any code in here. + * + * See for example https://code.google.com/p/android/issues/detail?id=14792 + */ } @Override @@ -83,7 +82,7 @@ public class DirectionProvider { private boolean hasSensorChecked = false; public boolean hasSensor(Context context) { - if (hasSensorChecked == false) { + if (!hasSensorChecked) { hasSensor = getOrientationSensor(context) != null; hasSensorChecked = true; } @@ -99,18 +98,19 @@ public class DirectionProvider { } - private static final StartableHandlerThread handlerThread = + private static final StartableHandlerThread HANDLER_THREAD = new StartableHandlerThread("DirectionProvider thread", Process.THREAD_PRIORITY_BACKGROUND, new Listener()); static { - handlerThread.start(); + HANDLER_THREAD.start(); } - static public Observable<Float> create(final Context context) { + + public static Observable<Float> create(final Context context) { return Observable.create(new OnSubscribe<Float>() { @Override public void call(final Subscriber<? super Float> subscriber) { - handlerThread.start(subscriber, context); - subject.subscribe(subscriber); + HANDLER_THREAD.start(subscriber, context); + SUBJECT.subscribe(subscriber); } }); } @@ -131,7 +131,7 @@ public class DirectionProvider { } private static int getRotationOffset() { - switch (windowManager.getDefaultDisplay().getRotation()) { + switch (WINDOW_MANAGER.getDefaultDisplay().getRotation()) { case Surface.ROTATION_90: return 90; case Surface.ROTATION_180: diff --git a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java index a77b477..a4799cb 100644 --- a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java +++ b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java @@ -1,13 +1,12 @@ package cgeo.geocaching.sensors; -import android.os.*; import cgeo.geocaching.utils.Log; - import cgeo.geocaching.utils.StartableHandlerThread; + import org.apache.commons.lang3.StringUtils; + import rx.Observable; import rx.Observable.OnSubscribe; -import rx.Scheduler.Inner; import rx.Subscriber; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -24,6 +23,7 @@ import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; +import android.os.Bundle; import java.util.concurrent.TimeUnit; @@ -96,11 +96,11 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { final private Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation); @Override - public Subscription connect() { + public void connect(Action1<? super Subscription> connection) { final CompositeSubscription subscription = new CompositeSubscription(); - AndroidSchedulers.handlerThread(handlerThread.getHandler()).schedule(new Action1<Inner>() { + AndroidSchedulers.handlerThread(handlerThread.getHandler()).createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { synchronized(lock) { if (count++ == 0) { Log.d("GeoDataProvider: starting the GPS and network listeners" + " (" + ++debugSessionCounter + ")"); @@ -118,9 +118,9 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { subscription.add(Subscriptions.create(new Action0() { @Override public void call() { - AndroidSchedulers.handlerThread(handlerThread.getHandler()).schedule(new Action1<Inner>() { + AndroidSchedulers.handlerThread(handlerThread.getHandler()).createWorker().schedule(new Action0() { @Override - public void call(final Inner inner) { + public void call() { synchronized (lock) { if (--count == 0) { Log.d("GeoDataProvider: stopping the GPS and network listeners" + " (" + debugSessionCounter + ")"); @@ -135,7 +135,7 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> { })); } }); - return subscription; + connection.call(subscription); } }; diff --git a/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java b/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java index 917c9c4..b209a70 100644 --- a/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java +++ b/main/src/cgeo/geocaching/settings/AbstractCheckCredentialsPreference.java @@ -70,7 +70,7 @@ public abstract class AbstractCheckCredentialsPreference extends AbstractClickab public ImmutablePair<StatusCode, ? extends Drawable> call() { return login(); } - })).subscribe(new Action1<ImmutablePair<StatusCode, ? extends Drawable>>() { + })).subscribeOn(Schedulers.io()).subscribe(new Action1<ImmutablePair<StatusCode, ? extends Drawable>>() { @Override public void call(final ImmutablePair<StatusCode, ? extends Drawable> loginInfo) { loginDialog.dismiss(); @@ -86,7 +86,7 @@ public abstract class AbstractCheckCredentialsPreference extends AbstractClickab } activity.initBasicMemberPreferences(); } - }, Schedulers.io()); + }); return false; // no shared preference has to be changed } diff --git a/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java b/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java index cc2de9f..e899be9 100644 --- a/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java +++ b/main/src/cgeo/geocaching/settings/RegisterSend2CgeoPreference.java @@ -75,7 +75,7 @@ public class RegisterSend2CgeoPreference extends AbstractClickablePreference { return Observable.empty(); } - }).firstOrDefault(0)).subscribe(new Action1<Integer>() { + }).firstOrDefault(0)).subscribeOn(Schedulers.io()).subscribe(new Action1<Integer>() { @Override public void call(final Integer pin) { progressDialog.dismiss(); @@ -87,7 +87,7 @@ public class RegisterSend2CgeoPreference extends AbstractClickablePreference { Dialogs.message(activity, R.string.init_sendToCgeo, R.string.init_sendToCgeo_register_fail); } } - }, Schedulers.io()); + }); return true; } diff --git a/main/src/cgeo/geocaching/settings/Settings.java b/main/src/cgeo/geocaching/settings/Settings.java index 7a4dfdd..d4adcbd 100644 --- a/main/src/cgeo/geocaching/settings/Settings.java +++ b/main/src/cgeo/geocaching/settings/Settings.java @@ -39,6 +39,7 @@ import android.preference.PreferenceManager; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -47,6 +48,7 @@ import java.util.Locale; */ public class Settings { + private static final char HISTORY_SEPARATOR = ','; public static final int SHOW_WP_THRESHOLD_DEFAULT = 10; public static final int SHOW_WP_THRESHOLD_MAX = 50; private static final int MAP_SOURCE_DEFAULT = GoogleMapProvider.GOOGLE_MAP_ID.hashCode(); @@ -63,7 +65,7 @@ public class Settings { Min, Sec; - public static CoordInputFormatEnum fromInt(int id) { + public static CoordInputFormatEnum fromInt(final int id) { final CoordInputFormatEnum[] values = CoordInputFormatEnum.values(); if (id < 0 || id >= values.length) { return Min; @@ -91,7 +93,7 @@ public class Settings { private static void migrateSettings() { // migrate from non standard file location and integer based boolean types - int oldVersion = getInt(R.string.pref_settingsversion, 0); + final int oldVersion = getInt(R.string.pref_settingsversion, 0); if (oldVersion < 1) { final String oldPreferencesName = "cgeo.pref"; final SharedPreferences old = CgeoApplication.getInstance().getSharedPreferences(oldPreferencesName, Context.MODE_PRIVATE); @@ -173,13 +175,13 @@ public class Settings { e.putInt(getKey(R.string.pref_showwaypointsthreshold), wpThreshold); // KEY_MAP_SOURCE must be string, because it is the key for a ListPreference now - int ms = sharedPrefs.getInt(getKey(R.string.pref_mapsource), MAP_SOURCE_DEFAULT); + final int ms = sharedPrefs.getInt(getKey(R.string.pref_mapsource), MAP_SOURCE_DEFAULT); e.remove(getKey(R.string.pref_mapsource)); e.putString(getKey(R.string.pref_mapsource), String.valueOf(ms)); // navigation tool ids must be string, because ListPreference uses strings as keys - int dnt1 = sharedPrefs.getInt(getKey(R.string.pref_defaultNavigationTool), NavigationAppsEnum.COMPASS.id); - int dnt2 = sharedPrefs.getInt(getKey(R.string.pref_defaultNavigationTool2), NavigationAppsEnum.INTERNAL_MAP.id); + final int dnt1 = sharedPrefs.getInt(getKey(R.string.pref_defaultNavigationTool), NavigationAppsEnum.COMPASS.id); + final int dnt2 = sharedPrefs.getInt(getKey(R.string.pref_defaultNavigationTool2), NavigationAppsEnum.INTERNAL_MAP.id); e.remove(getKey(R.string.pref_defaultNavigationTool)); e.remove(getKey(R.string.pref_defaultNavigationTool2)); e.putString(getKey(R.string.pref_defaultNavigationTool), String.valueOf(dnt1)); @@ -258,7 +260,7 @@ public class Settings { return sharedPrefs.contains(getKey(prefKeyId)); } - public static void setLanguage(boolean useEnglish) { + public static void setLanguage(final boolean useEnglish) { final Configuration config = new Configuration(); config.locale = useEnglish ? Locale.ENGLISH : Locale.getDefault(); final Resources resources = CgeoApplication.getInstance().getResources(); @@ -346,11 +348,11 @@ public class Settings { } } - public static boolean isOCConnectorActive(int isActivePrefKeyId) { + public static boolean isOCConnectorActive(final int isActivePrefKeyId) { return getBoolean(isActivePrefKeyId, false); } - public static boolean hasOCAuthorization(int tokenPublicPrefKeyId, int tokenSecretPrefKeyId) { + public static boolean hasOCAuthorization(final int tokenPublicPrefKeyId, final int tokenSecretPrefKeyId) { return StringUtils.isNotBlank(getString(tokenPublicPrefKeyId, "")) && StringUtils.isNotBlank(getString(tokenSecretPrefKeyId, "")); } @@ -374,7 +376,7 @@ public class Settings { } public static String getSignature() { - return getString(R.string.pref_signature, null); + return getString(R.string.pref_signature, StringUtils.EMPTY); } public static boolean setCookieStore(final String cookies) { @@ -424,7 +426,7 @@ public class Settings { } public static boolean setMapFile(final String mapFile) { - boolean result = putString(R.string.pref_mapfile, mapFile); + final boolean result = putString(R.string.pref_mapfile, mapFile); if (mapFile != null) { setMapFileDirectory(new File(mapFile).getParent()); } @@ -444,7 +446,7 @@ public class Settings { } public static boolean setMapFileDirectory(final String mapFileDirectory) { - boolean result = putString(R.string.pref_mapDirectory, mapFileDirectory); + final boolean result = putString(R.string.pref_mapDirectory, mapFileDirectory); MapsforgeMapProvider.getInstance().updateOfflineMaps(); return result; } @@ -557,6 +559,10 @@ public class Settings { return getBoolean(R.string.pref_units, getImperialUnitsDefault()); } + public static boolean isAlwaysShowOverlfowMenu() { + return getBoolean(R.string.pref_alwaysshowoverflowmenu, false); + } + static boolean getImperialUnitsDefault() { final String countryCode = Locale.getDefault().getCountry(); return "US".equals(countryCode) // USA @@ -624,6 +630,7 @@ public class Settings { private final static int MAPNIK = 1; private final static int CYCLEMAP = 3; private final static int OFFLINE = 4; + private static final int HISTORY_SIZE = 10; /** * convert old preference ids for maps (based on constant values) into new hash based ids @@ -676,8 +683,8 @@ public class Settings { public static Geopoint getAnyCoordinates() { if (contains(R.string.pref_anylatitude) && contains(R.string.pref_anylongitude)) { - float lat = getFloat(R.string.pref_anylatitude, 0); - float lon = getFloat(R.string.pref_anylongitude, 0); + final float lat = getFloat(R.string.pref_anylatitude, 0); + final float lon = getFloat(R.string.pref_anylongitude, 0); return new Geopoint(lat, lon); } return null; @@ -760,7 +767,7 @@ public class Settings { } public static void setTwitterTokens(@Nullable final String tokenPublic, - @Nullable final String tokenSecret, boolean enableTwitter) { + @Nullable final String tokenSecret, final boolean enableTwitter) { putString(R.string.pref_twitter_token_public, tokenPublic); putString(R.string.pref_twitter_token_secret, tokenSecret); if (tokenPublic != null) { @@ -777,8 +784,8 @@ public class Settings { } public static ImmutablePair<String, String> getTempToken() { - String tokenPublic = getString(R.string.pref_temp_twitter_token_public, null); - String tokenSecret = getString(R.string.pref_temp_twitter_token_secret, null); + final String tokenPublic = getString(R.string.pref_temp_twitter_token_public, null); + final String tokenSecret = getString(R.string.pref_temp_twitter_token_secret, null); return new ImmutablePair<String, String>(tokenPublic, tokenSecret); } @@ -889,8 +896,8 @@ public class Settings { } public static File[] getMapThemeFiles() { - File directory = new File(Settings.getCustomRenderThemeBaseFolder()); - List<File> result = new ArrayList<File>(); + final File directory = new File(Settings.getCustomRenderThemeBaseFolder()); + final List<File> result = new ArrayList<File>(); FileUtils.listDir(result, directory, new ExtensionsBasedFileSelector(new String[] { "xml" }), null); return result.toArray(new File[result.size()]); @@ -898,13 +905,13 @@ public class Settings { private static class ExtensionsBasedFileSelector extends FileSelector { private final String[] extensions; - public ExtensionsBasedFileSelector(String[] extensions) { + public ExtensionsBasedFileSelector(final String[] extensions) { this.extensions = extensions; } @Override - public boolean isSelected(File file) { - String filename = file.getName(); - for (String ext : extensions) { + public boolean isSelected(final File file) { + final String filename = file.getName(); + for (final String ext : extensions) { if (StringUtils.endsWithIgnoreCase(filename, ext)) { return true; } @@ -970,7 +977,7 @@ public class Settings { putLong(R.string.pref_fieldNoteExportDate, date); } - public static boolean isUseNavigationApp(NavigationAppsEnum navApp) { + public static boolean isUseNavigationApp(final NavigationAppsEnum navApp) { return getBoolean(navApp.preferenceKey, true); } @@ -979,7 +986,7 @@ public class Settings { * * @param upload */ - public static void setFieldNoteExportUpload(boolean upload) { + public static void setFieldNoteExportUpload(final boolean upload) { putBoolean(R.string.pref_fieldNoteExportUpload, upload); } @@ -992,7 +999,7 @@ public class Settings { * * @param onlyNew */ - public static void setFieldNoteExportOnlyNew(boolean onlyNew) { + public static void setFieldNoteExportOnlyNew(final boolean onlyNew) { putBoolean(R.string.pref_fieldNoteExportOnlyNew, onlyNew); } @@ -1004,4 +1011,25 @@ public class Settings { return getString(R.string.pref_ec_icons, "1"); } + /* Store last version for the changelog display */ + public static int getLastChangelogVersion() { + return getInt(R.string.pref_changelog_last_version, 0); + } + + public static void setLastChangelogVersion(final int version) { + putInt(R.string.pref_changelog_last_version, version); + } + + public static List<String> getLastOpenedCaches() { + final List<String> history = Arrays.asList(StringUtils.split(getString(R.string.pref_caches_history, StringUtils.EMPTY), HISTORY_SEPARATOR)); + return history.subList(0, Math.min(HISTORY_SIZE, history.size())); + } + + public static void addCacheToHistory(@NonNull final String geocode) { + final ArrayList<String> history = new ArrayList<String>(getLastOpenedCaches()); + // bring entry to front, if it already existed + history.remove(geocode); + history.add(0, geocode); + putString(R.string.pref_caches_history, StringUtils.join(history, HISTORY_SEPARATOR)); + } } diff --git a/main/src/cgeo/geocaching/settings/SettingsActivity.java b/main/src/cgeo/geocaching/settings/SettingsActivity.java index dc1a39d..b8c298b 100644 --- a/main/src/cgeo/geocaching/settings/SettingsActivity.java +++ b/main/src/cgeo/geocaching/settings/SettingsActivity.java @@ -9,11 +9,11 @@ import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory.NavigationAppsEnum; import cgeo.geocaching.connector.gc.GCConnector; -import cgeo.geocaching.connector.gc.GCLogin; import cgeo.geocaching.files.SimpleDirChooser; import cgeo.geocaching.maps.MapProviderFactory; import cgeo.geocaching.maps.interfaces.MapSource; import cgeo.geocaching.utils.DatabaseBackupUtils; +import cgeo.geocaching.utils.DebugUtils; import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; @@ -62,7 +62,7 @@ public class SettingsActivity extends PreferenceActivity { * directory and preference key in onActivityResult() easily just by knowing * the result code. */ - private enum DirChooserType { + private static enum DirChooserType { GPX_IMPORT_DIR(1, R.string.pref_gpxImportDir, Environment.getExternalStorageDirectory().getPath() + "/gpx", false), GPX_EXPORT_DIR(2, R.string.pref_gpxExportDir, @@ -90,8 +90,19 @@ public class SettingsActivity extends PreferenceActivity { SettingsActivity.addPreferencesFromResource(this, R.xml.preferences); initPreferences(); + /* Remove the show overflow preference on Android version where the platform always or never + * shows the overflow menu and the app cannot influence the behaviour + */ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) { + Preference pref = findPreference(this, getString(R.string.pref_alwaysshowoverflowmenu)); + PreferenceScreen appearence = (PreferenceScreen) findPreference(this, getString(R.string.pref_appearance)); + appearence.removePreference(pref); + + } Intent intent = getIntent(); openInitialScreen(intent.getIntExtra(INTENT_OPEN_SCREEN, 0)); + + } private void openInitialScreen(int initialScreen) { @@ -189,7 +200,7 @@ public class SettingsActivity extends PreferenceActivity { private static void setServiceScreenSummary(PreferenceManager preferenceManager, final int preferenceKey) { - String summary = StringUtils.EMPTY; + String summary; switch (preferenceKey) { case R.string.pref_connectorGCActive: @@ -380,6 +391,15 @@ public class SettingsActivity extends PreferenceActivity { return true; } }); + Preference memoryDumpPref = getPreference(R.string.pref_memory_dump); + memoryDumpPref + .setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override public boolean onPreferenceClick( + Preference preference) { + DebugUtils.createMemoryDump(SettingsActivity.this); + return true; + } + }); } private void initDbLocationPreference() { @@ -582,7 +602,7 @@ public class SettingsActivity extends PreferenceActivity { || isPreference(preference, R.string.pref_connectorOXActive) || isPreference(preference, R.string.pref_connectorECActive)) { // update summary - boolean boolVal = ((Boolean) value).booleanValue(); + final boolean boolVal = (Boolean) value; String summary = getServiceSummary(boolVal); if (OCPreferenceKeys.isOCPreference(preference.getKey())) { OCPreferenceKeys prefKey = OCPreferenceKeys.getByKey(preference.getKey()); @@ -625,9 +645,6 @@ public class SettingsActivity extends PreferenceActivity { // TODO: do not special case geocaching.com here if ((isPreference(preference, R.string.pref_username) && !stringValue.equals(Settings.getUsername())) || (isPreference(preference, R.string.pref_password) && !stringValue.equals(Settings.getGcCredentials().getRight()))) { // reset log-in if gc user or password is changed - if (GCLogin.getInstance().isActualLoginStatus()) { - GCLogin.getInstance().logout(); - } CgeoApplication.getInstance().forceRelog(); } return true; diff --git a/main/src/cgeo/geocaching/settings/TemplateTextPreference.java b/main/src/cgeo/geocaching/settings/TemplateTextPreference.java index 667b02b..1f420ef 100644 --- a/main/src/cgeo/geocaching/settings/TemplateTextPreference.java +++ b/main/src/cgeo/geocaching/settings/TemplateTextPreference.java @@ -58,7 +58,7 @@ public class TemplateTextPreference extends DialogPreference { public void onClick(View button) { AlertDialog.Builder alert = new AlertDialog.Builder(TemplateTextPreference.this.getContext()); alert.setTitle(R.string.init_signature_template_button); - final ArrayList<LogTemplate> templates = LogTemplateProvider.getTemplates(); + final ArrayList<LogTemplate> templates = LogTemplateProvider.getTemplatesWithoutSignature(); String[] items = new String[templates.size()]; for (int i = 0; i < templates.size(); i++) { items[i] = settingsActivity.getResources().getString(templates.get(i).getResourceId()); diff --git a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java index 1ed8e68..57a69ee 100644 --- a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java +++ b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java @@ -12,16 +12,14 @@ public class PopularityRatioComparator extends AbstractCacheComparator { @Override protected int compareCaches(final Geocache cache1, final Geocache cache2) { - - float ratio1 = 0.0f; - float ratio2 = 0.0f; - int finds1 = cache1.getFindsCount(); int finds2 = cache2.getFindsCount(); + float ratio1 = 0.0f; if (finds1 != 0) { ratio1 = (((float) cache1.getFavoritePoints()) / ((float) finds1)); } + float ratio2 = 0.0f; if (finds2 != 0) { ratio2 = (((float) cache2.getFavoritePoints()) / ((float) finds2)); } diff --git a/main/src/cgeo/geocaching/ui/AbstractCachingListViewPageViewCreator.java b/main/src/cgeo/geocaching/ui/AbstractCachingListViewPageViewCreator.java index 799b695..06fa1fa 100644 --- a/main/src/cgeo/geocaching/ui/AbstractCachingListViewPageViewCreator.java +++ b/main/src/cgeo/geocaching/ui/AbstractCachingListViewPageViewCreator.java @@ -51,7 +51,6 @@ public abstract class AbstractCachingListViewPageViewCreator extends AbstractCac int logViewPosition = state.getInt(STATE_POSITION); int logViewPositionFromTop = state.getInt(STATE_POSITION_FROM_TOP); view.setSelectionFromTop(logViewPosition, logViewPositionFromTop); - return; } } diff --git a/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java b/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java index 0c67384..71cd3b4 100644 --- a/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java +++ b/main/src/cgeo/geocaching/ui/AbstractCachingPageViewCreator.java @@ -52,6 +52,5 @@ public abstract class AbstractCachingPageViewCreator<ViewClass extends View> imp */ @Override public void setViewState(@NonNull Bundle state) { - return; } } diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java index 0d90d9f..3a451a5 100644 --- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java +++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java @@ -45,6 +45,7 @@ import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -377,7 +378,7 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> { final boolean lightSkin = Settings.isLightSkin(); - final TouchListener touchListener = new TouchListener(cache); + final TouchListener touchListener = new TouchListener(cache, this); v.setOnClickListener(touchListener); v.setOnLongClickListener(touchListener); v.setOnTouchListener(touchListener); @@ -536,24 +537,30 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> { } } - private class TouchListener implements View.OnClickListener, View.OnLongClickListener, View.OnTouchListener { + private static class TouchListener implements View.OnClickListener, View.OnLongClickListener, View.OnTouchListener { private final Geocache cache; private final GestureDetector gestureDetector; + private final @NonNull WeakReference<CacheListAdapter> adapterRef; - public TouchListener(final Geocache cache) { + public TouchListener(final Geocache cache, final @NonNull CacheListAdapter adapter) { this.cache = cache; - gestureDetector = new GestureDetector(getContext(), new FlingGesture(cache)); + gestureDetector = new GestureDetector(adapter.getContext(), new FlingGesture(cache, adapter)); + adapterRef = new WeakReference<CacheListAdapter>(adapter); } // Tap on item @Override public void onClick(final View view) { - if (isSelectMode()) { + final CacheListAdapter adapter = adapterRef.get(); + if (adapter == null) { + return; + } + if (adapter.isSelectMode()) { cache.setStatusChecked(!cache.isStatusChecked()); - notifyDataSetChanged(); + adapter.notifyDataSetChanged(); } else { - CacheDetailActivity.startActivity(getContext(), cache.getGeocode(), cache.getName()); + CacheDetailActivity.startActivity(adapter.getContext(), cache.getGeocode(), cache.getName()); } } @@ -572,12 +579,14 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> { } } - private class FlingGesture extends GestureDetector.SimpleOnGestureListener { + private static class FlingGesture extends GestureDetector.SimpleOnGestureListener { private final Geocache cache; + private final @NonNull WeakReference<CacheListAdapter> adapterRef; - public FlingGesture(final Geocache cache) { + public FlingGesture(final Geocache cache, final @NonNull CacheListAdapter adapter) { this.cache = cache; + adapterRef = new WeakReference<CacheListAdapter>(adapter); } @Override @@ -586,11 +595,15 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> { if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) { return false; } + final CacheListAdapter adapter = adapterRef.get(); + if (adapter == null) { + return false; + } // left to right swipe if ((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { - if (!selectMode) { - switchSelectMode(); + if (!adapter.selectMode) { + adapter.switchSelectMode(); cache.setStatusChecked(true); } return true; @@ -598,8 +611,8 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> { // right to left swipe if ((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > Math.abs(velocityY)) { - if (selectMode) { - switchSelectMode(); + if (adapter.selectMode) { + adapter.switchSelectMode(); } return true; } diff --git a/main/src/cgeo/geocaching/ui/CompassView.java b/main/src/cgeo/geocaching/ui/CompassView.java index f7111f7..60982a9 100644 --- a/main/src/cgeo/geocaching/ui/CompassView.java +++ b/main/src/cgeo/geocaching/ui/CompassView.java @@ -3,10 +3,9 @@ package cgeo.geocaching.ui; import cgeo.geocaching.R; import cgeo.geocaching.utils.AngleUtils; -import rx.Scheduler; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; +import rx.functions.Action0; import android.content.Context; import android.content.res.Resources; @@ -18,6 +17,7 @@ import android.graphics.PaintFlagsDrawFilter; import android.util.AttributeSet; import android.view.View; +import java.lang.ref.WeakReference; import java.util.concurrent.TimeUnit; public class CompassView extends View { @@ -56,11 +56,40 @@ public class CompassView extends View { private boolean initialDisplay; private Subscription periodicUpdate; + private static final class UpdateAction implements Action0 { + + private final WeakReference<CompassView> compassViewRef; + + private UpdateAction(CompassView view) { + this.compassViewRef = new WeakReference<CompassView>(view); + } + + @Override + public void call() { + final CompassView compassView = compassViewRef.get(); + if (compassView == null) { + return; + } + compassView.updateGraphics(); + } + } + public CompassView(Context contextIn) { super(contextIn); context = contextIn; } + public void updateGraphics() { + final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown); + final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown); + if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 || + Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) { + azimuthShown = newAzimuthShown; + cacheHeadingShown = newCacheHeadingShown; + invalidate(); + } + } + public CompassView(Context contextIn, AttributeSet attrs) { super(contextIn, attrs); context = contextIn; @@ -88,24 +117,13 @@ public class CompassView extends View { initialDisplay = true; - periodicUpdate = AndroidSchedulers.mainThread().schedulePeriodically(new Action1<Scheduler.Inner>() { - @Override - public void call(final Scheduler.Inner inner) { - final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown); - final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown); - if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 || - Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) { - azimuthShown = newAzimuthShown; - cacheHeadingShown = newCacheHeadingShown; - invalidate(); - } - } - }, 0, 40, TimeUnit.MILLISECONDS); + periodicUpdate = AndroidSchedulers.mainThread().createWorker().schedulePeriodically(new UpdateAction(this), 0, 40, TimeUnit.MILLISECONDS); } @Override public void onDetachedFromWindow() { periodicUpdate.unsubscribe(); + super.onDetachedFromWindow(); if (compassUnderlay != null) { diff --git a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java index b2ce11a..00b5abe 100644 --- a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java +++ b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java @@ -1,12 +1,11 @@ package cgeo.geocaching.ui.dialog; import cgeo.geocaching.Geocache; -import cgeo.geocaching.sensors.IGeoData; import cgeo.geocaching.R; import cgeo.geocaching.activity.AbstractActivity; -import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.sensors.IGeoData; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.settings.Settings.CoordInputFormatEnum; import cgeo.geocaching.utils.EditUtils; @@ -14,9 +13,12 @@ import cgeo.geocaching.utils.EditUtils; import org.apache.commons.lang3.StringUtils; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.text.Editable; import android.text.TextWatcher; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; @@ -25,12 +27,11 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -public class CoordinatesInputDialog extends NoTitleDialog { +public class CoordinatesInputDialog extends DialogFragment { - final private AbstractActivity context; - final private IGeoData geo; - final private Geocache cache; private Geopoint gp; + private Geopoint gpinitial; + private Geopoint cacheCoords; private EditText eLat, eLon; private Button bLat, bLon; @@ -39,34 +40,64 @@ public class CoordinatesInputDialog extends NoTitleDialog { private TextView tLatSep1, tLatSep2, tLatSep3; private TextView tLonSep1, tLonSep2, tLonSep3; - private CoordinateUpdate cuListener; - private CoordInputFormatEnum currentFormat = null; - public CoordinatesInputDialog(final AbstractActivity context, final Geocache cache, final Geopoint gp, final IGeoData geo) { - super(context, ActivityMixin.getDialogTheme()); - this.context = context; - this.geo = geo; - this.cache = cache; + + private static final String GEOPOINT_ARG = "GEOPOINT"; + private static final String GEOPOINT_INTIAL_ARG = "GEOPOINT_INITIAL"; + private static final String CACHECOORDS_ARG = "CACHECOORDS"; + + + public static CoordinatesInputDialog getInstance(final Geocache cache, final Geopoint gp, final IGeoData geo) { + + Bundle args = new Bundle(); if (gp != null) { - this.gp = gp; + args.putParcelable(GEOPOINT_ARG, gp); } else if (geo != null && geo.getCoords() != null) { - this.gp = geo.getCoords(); + args.putParcelable(GEOPOINT_ARG, geo.getCoords()); } else { - this.gp = Geopoint.ZERO; + args.putParcelable(GEOPOINT_ARG, Geopoint.ZERO); } + + if (geo !=null) + args.putParcelable(GEOPOINT_INTIAL_ARG, geo.getCoords()); + + if (cache != null) + args.putParcelable(CACHECOORDS_ARG, cache.getCoords()); + + CoordinatesInputDialog cid = new CoordinatesInputDialog(); + cid.setArguments(args); + return cid; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + gp = getArguments().getParcelable(GEOPOINT_ARG); + gpinitial = getArguments().getParcelable(GEOPOINT_INTIAL_ARG); + cacheCoords = getArguments().getParcelable(CACHECOORDS_ARG); - setContentView(R.layout.coordinatesinput_dialog); + if (savedInstanceState != null && savedInstanceState.getParcelable(GEOPOINT_ARG)!=null) + gp = savedInstanceState.getParcelable(GEOPOINT_ARG); - final Spinner spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + // TODO: if current input is not commited in gp, read the current input into gp + outState.putParcelable(GEOPOINT_ARG, gp); + } + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { + getDialog().setTitle(R.string.cache_coordinates); + + View v = inflater.inflate(R.layout.coordinatesinput_dialog, container, false); + final Spinner spinner = (Spinner) v.findViewById(R.id.spinnerCoordinateFormats); final ArrayAdapter<CharSequence> adapter = - ArrayAdapter.createFromResource(context, + ArrayAdapter.createFromResource(getActivity(), R.array.waypoint_coordinate_formats, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -74,25 +105,25 @@ public class CoordinatesInputDialog extends NoTitleDialog { spinner.setSelection(Settings.getCoordInputFormat().ordinal()); spinner.setOnItemSelectedListener(new CoordinateFormatListener()); - bLat = (Button) findViewById(R.id.ButtonLat); - eLat = (EditText) findViewById(R.id.latitude); - eLatDeg = (EditText) findViewById(R.id.EditTextLatDeg); - eLatMin = (EditText) findViewById(R.id.EditTextLatMin); - eLatSec = (EditText) findViewById(R.id.EditTextLatSec); - eLatSub = (EditText) findViewById(R.id.EditTextLatSecFrac); - tLatSep1 = (TextView) findViewById(R.id.LatSeparator1); - tLatSep2 = (TextView) findViewById(R.id.LatSeparator2); - tLatSep3 = (TextView) findViewById(R.id.LatSeparator3); - - bLon = (Button) findViewById(R.id.ButtonLon); - eLon = (EditText) findViewById(R.id.longitude); - eLonDeg = (EditText) findViewById(R.id.EditTextLonDeg); - eLonMin = (EditText) findViewById(R.id.EditTextLonMin); - eLonSec = (EditText) findViewById(R.id.EditTextLonSec); - eLonSub = (EditText) findViewById(R.id.EditTextLonSecFrac); - tLonSep1 = (TextView) findViewById(R.id.LonSeparator1); - tLonSep2 = (TextView) findViewById(R.id.LonSeparator2); - tLonSep3 = (TextView) findViewById(R.id.LonSeparator3); + bLat = (Button) v.findViewById(R.id.ButtonLat); + eLat = (EditText) v.findViewById(R.id.latitude); + eLatDeg = (EditText) v.findViewById(R.id.EditTextLatDeg); + eLatMin = (EditText) v.findViewById(R.id.EditTextLatMin); + eLatSec = (EditText) v.findViewById(R.id.EditTextLatSec); + eLatSub = (EditText) v.findViewById(R.id.EditTextLatSecFrac); + tLatSep1 = (TextView) v.findViewById(R.id.LatSeparator1); + tLatSep2 = (TextView) v.findViewById(R.id.LatSeparator2); + tLatSep3 = (TextView) v.findViewById(R.id.LatSeparator3); + + bLon = (Button) v.findViewById(R.id.ButtonLon); + eLon = (EditText) v.findViewById(R.id.longitude); + eLonDeg = (EditText) v.findViewById(R.id.EditTextLonDeg); + eLonMin = (EditText) v.findViewById(R.id.EditTextLonMin); + eLonSec = (EditText) v.findViewById(R.id.EditTextLonSec); + eLonSub = (EditText) v.findViewById(R.id.EditTextLonSecFrac); + tLonSep1 = (TextView) v.findViewById(R.id.LonSeparator1); + tLonSep2 = (TextView) v.findViewById(R.id.LonSeparator2); + tLonSep3 = (TextView) v.findViewById(R.id.LonSeparator3); eLatDeg.addTextChangedListener(new TextChanged(eLatDeg)); eLatMin.addTextChangedListener(new TextChanged(eLatMin)); @@ -115,18 +146,24 @@ public class CoordinatesInputDialog extends NoTitleDialog { bLat.setOnClickListener(new ButtonClickListener()); bLon.setOnClickListener(new ButtonClickListener()); - final Button buttonCurrent = (Button) findViewById(R.id.current); + final Button buttonCurrent = (Button) v.findViewById(R.id.current); buttonCurrent.setOnClickListener(new CurrentListener()); - final Button buttonCache = (Button) findViewById(R.id.cache); - if (cache != null) { + final Button buttonCache = (Button) v.findViewById(R.id.cache); + + if (cacheCoords != null) { buttonCache.setOnClickListener(new CacheListener()); } else { buttonCache.setVisibility(View.GONE); } - final Button buttonDone = (Button) findViewById(R.id.done); + + final Button buttonDone = (Button) v.findViewById(R.id.done); buttonDone.setOnClickListener(new InputDoneListener()); + + return v; } + + private void updateGUI() { if (gp == null) { return; @@ -137,14 +174,14 @@ public class CoordinatesInputDialog extends NoTitleDialog { switch (currentFormat) { case Plain: - findViewById(R.id.coordTable).setVisibility(View.GONE); + getView().findViewById(R.id.coordTable).setVisibility(View.GONE); eLat.setVisibility(View.VISIBLE); eLon.setVisibility(View.VISIBLE); eLat.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); eLon.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE)); break; case Deg: // DDD.DDDDD° - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + getView().findViewById(R.id.coordTable).setVisibility(View.VISIBLE); eLat.setVisibility(View.GONE); eLon.setVisibility(View.GONE); eLatSec.setVisibility(View.GONE); @@ -165,7 +202,7 @@ public class CoordinatesInputDialog extends NoTitleDialog { eLonMin.setText(addZeros(gp.getLonDegFrac(), 5)); break; case Min: // DDD° MM.MMM - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + getView().findViewById(R.id.coordTable).setVisibility(View.VISIBLE); eLat.setVisibility(View.GONE); eLon.setVisibility(View.GONE); eLatSec.setVisibility(View.VISIBLE); @@ -190,7 +227,7 @@ public class CoordinatesInputDialog extends NoTitleDialog { eLonSec.setText(addZeros(gp.getLonMinFrac(), 3)); break; case Sec: // DDD° MM SS.SSS - findViewById(R.id.coordTable).setVisibility(View.VISIBLE); + getView().findViewById(R.id.coordTable).setVisibility(View.VISIBLE); eLat.setVisibility(View.GONE); eLon.setVisibility(View.GONE); eLatSec.setVisibility(View.VISIBLE); @@ -371,7 +408,8 @@ public class CoordinatesInputDialog extends NoTitleDialog { // Signaled and returned below } if (signalError) { - context.showToast(context.getResources().getString(R.string.err_parse_lat_lon)); + final AbstractActivity activity = (AbstractActivity) getActivity(); + activity.showToast(activity.getResources().getString(R.string.err_parse_lat_lon)); } return false; } @@ -399,8 +437,8 @@ public class CoordinatesInputDialog extends NoTitleDialog { // Start new format with an acceptable value: either the current one // entered by the user, else our current coordinates, else (0,0). if (!areCurrentCoordinatesValid(false)) { - if (geo != null && geo.getCoords() != null) { - gp = geo.getCoords(); + if (gpinitial != null) { + gp = gpinitial; } else { gp = Geopoint.ZERO; } @@ -422,12 +460,13 @@ public class CoordinatesInputDialog extends NoTitleDialog { @Override public void onClick(View v) { - if (geo == null || geo.getCoords() == null) { - context.showToast(context.getResources().getString(R.string.err_point_unknown_position)); + if (gpinitial == null) { + final AbstractActivity activity = (AbstractActivity) getActivity(); + activity.showToast(activity.getResources().getString(R.string.err_point_unknown_position)); return; } - gp = geo.getCoords(); + gp = gpinitial; updateGUI(); } } @@ -436,16 +475,18 @@ public class CoordinatesInputDialog extends NoTitleDialog { @Override public void onClick(View v) { - if (cache == null || cache.getCoords() == null) { - context.showToast(context.getResources().getString(R.string.err_location_unknown)); + if (cacheCoords == null) { + final AbstractActivity activity = (AbstractActivity) getActivity(); + activity.showToast(activity.getResources().getString(R.string.err_location_unknown)); return; } - gp = cache.getCoords(); + gp = cacheCoords; updateGUI(); } } + private class InputDoneListener implements View.OnClickListener { @Override @@ -454,18 +495,14 @@ public class CoordinatesInputDialog extends NoTitleDialog { return; } if (gp != null) { - cuListener.update(gp); + ((CoordinateUpdate) getActivity()).updateCoordinates(gp); } dismiss(); } } - public void setOnCoordinateUpdate(CoordinateUpdate cu) { - cuListener = cu; - } - public interface CoordinateUpdate { - public void update(final Geopoint gp); + public void updateCoordinates(final Geopoint gp); } } diff --git a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java index 18f8e2e..fc69f44 100644 --- a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java +++ b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java @@ -2,48 +2,56 @@ package cgeo.geocaching.ui.dialog; import cgeo.geocaching.R; -import android.app.Activity; import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import android.widget.DatePicker; import java.util.Calendar; -public class DateDialog extends NoTitleDialog { +public class DateDialog extends DialogFragment { public interface DateDialogParent { abstract public void setDate(final Calendar date); } - private final DateDialogParent parent; - private final Calendar date; + private Calendar date; - public DateDialog(Activity contextIn, DateDialogParent parentIn, Calendar dateIn) { - super(contextIn); - - // init - this.date = dateIn; - this.parent = parentIn; + public static DateDialog getInstance(Calendar date) { + DateDialog dd = new DateDialog(); + Bundle args = new Bundle(); + args.putSerializable("date", date); + dd.setArguments(args); + return dd; } @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setStyle(DialogFragment.STYLE_NO_TITLE, 0); + Bundle args = getArguments(); + date = (Calendar) args.getSerializable("date"); + } - setContentView(R.layout.date); + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.date, container, false); - final DatePicker picker = (DatePicker) findViewById(R.id.picker); + final DatePicker picker = (DatePicker) v.findViewById(R.id.picker); picker.init(date.get(Calendar.YEAR), date.get(Calendar.MONTH), date.get(Calendar.DATE), new DatePickerListener()); + return v; } private class DatePickerListener implements DatePicker.OnDateChangedListener { @Override public void onDateChanged(DatePicker picker, int year, int month, int day) { - if (parent != null) { - date.set(year, month, day); + date.set(year, month, day); + + ((DateDialogParent) getActivity()).setDate(date); - parent.setDate(date); - } } } }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/ui/dialog/Dialogs.java b/main/src/cgeo/geocaching/ui/dialog/Dialogs.java index cb8926a..6a2f9a5 100644 --- a/main/src/cgeo/geocaching/ui/dialog/Dialogs.java +++ b/main/src/cgeo/geocaching/ui/dialog/Dialogs.java @@ -218,7 +218,19 @@ public final class Dialogs { /** * Show a message dialog with a single "OK" button. - * + * + * @param context + * activity owning the dialog + * @param message + * message dialog content + */ + public static void message(final Activity context, final int message) { + message(context, null, getString(message)); + } + + /** + * Show a message dialog with a single "OK" button. + * * @param context * activity owning the dialog * @param title diff --git a/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java b/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java deleted file mode 100644 index 8660a7b..0000000 --- a/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java +++ /dev/null @@ -1,32 +0,0 @@ -package cgeo.geocaching.ui.dialog; - -import cgeo.geocaching.utils.Log; - -import android.app.Dialog; -import android.content.Context; -import android.os.Bundle; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; - -public abstract class NoTitleDialog extends Dialog { - - public NoTitleDialog(Context context) { - super(context); - } - - public NoTitleDialog(Context context, int theme) { - super(context, theme); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - try { - requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } catch (final Exception e) { - Log.e("NoTitleDialog.onCreate", e); - } - } -} diff --git a/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java b/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java index 4ce2e0c..14840b9 100644 --- a/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java +++ b/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java @@ -10,7 +10,6 @@ import org.apache.commons.lang3.StringUtils; import android.app.Activity; import android.app.ProgressDialog; -import android.content.Context; import android.content.res.Resources; import java.io.File; @@ -53,7 +52,6 @@ public class DatabaseBackupUtils { } public static boolean createBackup(final Activity activity, final Runnable runAfterwards) { - final Context context = activity; // avoid overwriting an existing backup with an empty database // (can happen directly after reinstalling the app) if (DataStore.getAllCachesCount() == 0) { @@ -61,9 +59,9 @@ public class DatabaseBackupUtils { return false; } - final ProgressDialog dialog = ProgressDialog.show(context, - context.getString(R.string.init_backup), - context.getString(R.string.init_backup_running), true, false); + final ProgressDialog dialog = ProgressDialog.show(activity, + activity.getString(R.string.init_backup), + activity.getString(R.string.init_backup_running), true, false); new Thread() { @Override public void run() { @@ -75,9 +73,9 @@ public class DatabaseBackupUtils { Dialogs.message(activity, R.string.init_backup_backup, backupFileName != null - ? context.getString(R.string.init_backup_success) + ? activity.getString(R.string.init_backup_success) + "\n" + backupFileName - : context.getString(R.string.init_backup_failed)); + : activity.getString(R.string.init_backup_failed)); if (runAfterwards != null) { runAfterwards.run(); } diff --git a/main/src/cgeo/geocaching/utils/DebugUtils.java b/main/src/cgeo/geocaching/utils/DebugUtils.java new file mode 100644 index 0000000..07aac64 --- /dev/null +++ b/main/src/cgeo/geocaching/utils/DebugUtils.java @@ -0,0 +1,37 @@ +package cgeo.geocaching.utils; + +import cgeo.geocaching.R; + +import org.eclipse.jdt.annotation.NonNull; + +import android.content.Context; +import android.os.Environment; +import android.widget.Toast; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class DebugUtils { + + private DebugUtils() { + // utility class + } + + public static void createMemoryDump(final @NonNull Context context) { + try { + final Date now = new Date(); + final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyy-MM-dd_hh-mm", Locale.US); + File file = FileUtils.getUniqueNamedFile(Environment.getExternalStorageDirectory().getPath() + + File.separatorChar + "cgeo_dump_" + fileNameDateFormat.format(now) + ".hprof"); + android.os.Debug.dumpHprofData(file.getPath()); + Toast.makeText(context, context.getString(R.string.init_memory_dumped, file.getAbsolutePath()), + Toast.LENGTH_LONG).show(); + ShareUtils.share(context, file, R.string.init_memory_dump); + } catch (IOException e) { + Log.e("createMemoryDump", e); + } + } +} diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 5fa0982..3507116 100644 --- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -36,9 +36,9 @@ public final class LogTemplateProvider { private Geocache cache; private Trackable trackable; private boolean offline = false; - private LogEntry logEntry; + private final LogEntry logEntry; - public LogContext(final Geocache cache, LogEntry logEntry) { + public LogContext(final Geocache cache, final LogEntry logEntry) { this(cache, logEntry, false); } @@ -47,7 +47,7 @@ public final class LogTemplateProvider { this.logEntry = logEntry; } - public LogContext(final Geocache cache, LogEntry logEntry, final boolean offline) { + public LogContext(final Geocache cache, final LogEntry logEntry, final boolean offline) { this.cache = cache; this.offline = offline; this.logEntry = logEntry; @@ -104,8 +104,11 @@ public final class LogTemplateProvider { } } - public static ArrayList<LogTemplate> getTemplates() { - ArrayList<LogTemplate> templates = new ArrayList<LogTemplateProvider.LogTemplate>(); + /** + * @return all templates, but not the signature template itself + */ + public static ArrayList<LogTemplate> getTemplatesWithoutSignature() { + final ArrayList<LogTemplate> templates = new ArrayList<LogTemplateProvider.LogTemplate>(); templates.add(new LogTemplate("DATE", R.string.init_signature_template_date) { @Override @@ -132,6 +135,13 @@ public final class LogTemplateProvider { @Override public String getValue(final LogContext context) { + final Geocache cache = context.getCache(); + if (cache != null) { + final IConnector connector = ConnectorFactory.getConnector(cache); + if (connector instanceof ILogin) { + return ((ILogin) connector).getUserName(); + } + } return Settings.getUsername(); } }); @@ -171,11 +181,11 @@ public final class LogTemplateProvider { @Override public String getValue(final LogContext context) { - Trackable trackable = context.getTrackable(); + final Trackable trackable = context.getTrackable(); if (trackable != null) { return trackable.getOwner(); } - Geocache cache = context.getCache(); + final Geocache cache = context.getCache(); if (cache != null) { return cache.getOwnerDisplayName(); } @@ -184,12 +194,12 @@ public final class LogTemplateProvider { }); templates.add(new LogTemplate("NAME", R.string.init_signature_template_name) { @Override - public String getValue(LogContext context) { - Trackable trackable = context.getTrackable(); + public String getValue(final LogContext context) { + final Trackable trackable = context.getTrackable(); if (trackable != null) { return trackable.getName(); } - Geocache cache = context.getCache(); + final Geocache cache = context.getCache(); if (cache != null) { return cache.getName(); } @@ -199,12 +209,12 @@ public final class LogTemplateProvider { templates.add(new LogTemplate("URL", R.string.init_signature_template_url) { @Override - public String getValue(LogContext context) { - Trackable trackable = context.getTrackable(); + public String getValue(final LogContext context) { + final Trackable trackable = context.getTrackable(); if (trackable != null) { return trackable.getUrl(); } - Geocache cache = context.getCache(); + final Geocache cache = context.getCache(); if (cache != null) { return cache.getUrl(); } @@ -213,8 +223,8 @@ public final class LogTemplateProvider { }); templates.add(new LogTemplate("LOG", R.string.init_signature_template_log) { @Override - public String getValue(LogContext context) { - LogEntry logEntry = context.getLogEntry(); + public String getValue(final LogContext context) { + final LogEntry logEntry = context.getLogEntry(); if (logEntry != null) { return logEntry.getDisplayText(); } @@ -224,8 +234,26 @@ public final class LogTemplateProvider { return templates; } + /** + * @return all templates, including the signature template + */ + public static ArrayList<LogTemplate> getTemplatesWithSignature() { + final ArrayList<LogTemplate> templates = getTemplatesWithoutSignature(); + templates.add(new LogTemplate("SIGNATURE", R.string.init_signature) { + @Override + public String getValue(final LogContext context) { + final String nestedTemplate = StringUtils.defaultString(Settings.getSignature()); + if (StringUtils.contains(nestedTemplate, "SIGNATURE")) { + return "invalid signature template"; + } + return LogTemplateProvider.applyTemplates(nestedTemplate, context); + } + }); + return templates; + } + public static LogTemplate getTemplate(final int itemId) { - for (LogTemplate template : getTemplates()) { + for (final LogTemplate template : getTemplatesWithSignature()) { if (template.getItemId() == itemId) { return template; } @@ -238,7 +266,7 @@ public final class LogTemplateProvider { return StringUtils.EMPTY; } String result = signature; - for (LogTemplate template : getTemplates()) { + for (final LogTemplate template : getTemplatesWithSignature()) { result = template.apply(result, context); } return result; diff --git a/main/src/cgeo/geocaching/utils/RxUtils.java b/main/src/cgeo/geocaching/utils/RxUtils.java index 8e7864c..b865f0b 100644 --- a/main/src/cgeo/geocaching/utils/RxUtils.java +++ b/main/src/cgeo/geocaching/utils/RxUtils.java @@ -1,18 +1,23 @@ package cgeo.geocaching.utils; +import rx.Observable; import rx.Scheduler; +import rx.observables.BlockingObservable; import rx.schedulers.Schedulers; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - public class RxUtils { // Utility class, not to be instanciated private RxUtils() {} - final static private int cores = Runtime.getRuntime().availableProcessors(); - public final static Scheduler computationScheduler = Schedulers.executor(new ThreadPoolExecutor(1, cores, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>())); + public final static Scheduler computationScheduler = Schedulers.computation(); + + public static <T> void waitForCompletion(final BlockingObservable<T> observable) { + observable.lastOrDefault(null); + return; + } + public static void waitForCompletion(final Observable<?>... observables) { + waitForCompletion(Observable.merge(observables).toBlocking()); + } } diff --git a/main/src/cgeo/geocaching/utils/ShareUtils.java b/main/src/cgeo/geocaching/utils/ShareUtils.java new file mode 100644 index 0000000..bfd6838 --- /dev/null +++ b/main/src/cgeo/geocaching/utils/ShareUtils.java @@ -0,0 +1,27 @@ +package cgeo.geocaching.utils; + +import org.eclipse.jdt.annotation.NonNull; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + +import java.io.File; + +public class ShareUtils { + private ShareUtils() { + // utility class + } + + public static void share(final Context context, final @NonNull File file, final @NonNull String mimeType, final int titleResourceId) { + final Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); + shareIntent.setType(mimeType); + context.startActivity(Intent.createChooser(shareIntent, context.getString(titleResourceId))); + } + + public static void share(final Context context, final @NonNull File file, final int titleResourceId) { + share(context, file, "*/*", titleResourceId); + } +} diff --git a/main/src/cgeo/geocaching/utils/TranslationUtils.java b/main/src/cgeo/geocaching/utils/TranslationUtils.java index 619db08..ea3c395 100644 --- a/main/src/cgeo/geocaching/utils/TranslationUtils.java +++ b/main/src/cgeo/geocaching/utils/TranslationUtils.java @@ -1,10 +1,10 @@ package cgeo.geocaching.utils; -import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.network.Network; import org.apache.commons.lang3.StringUtils; +import android.app.Activity; import android.content.Intent; import android.net.Uri; @@ -51,7 +51,7 @@ public final class TranslationUtils { * @param text * The text to be translated */ - public static void startActivityTranslate(final AbstractActivity context, final String toLang, final String text) { + public static void startActivityTranslate(final Activity context, final String toLang, final String text) { context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(buildTranslationURI(toLang, text)))); } } diff --git a/main/version.properties b/main/version.properties new file mode 100644 index 0000000..67edd0d --- /dev/null +++ b/main/version.properties @@ -0,0 +1,21 @@ +# +# Copyright 2014 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +code = 1000 +name = 0.0.1 + +# Latest beta number for this version. Only applies to beta builds. +betaNumber = Beta 1 |
