diff options
Diffstat (limited to 'main')
85 files changed, 1352 insertions, 873 deletions
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 dbf370e..2cdbc2c 100644 --- a/main/AndroidManifest.xml +++ b/main/AndroidManifest.xml @@ -22,7 +22,6 @@ <uses-feature android:name="android.hardware.screen.portrait" android:required="false" /> - <uses-feature android:name="android.hardware.nfc" android:required="false" /> @@ -84,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> @@ -104,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" @@ -139,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> @@ -425,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" @@ -469,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" /> diff --git a/main/build.gradle b/main/build.gradle new file mode 100644 index 0000000..42aaf4b --- /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.18.3' +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 + testPackageName "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/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_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_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_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/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_maps.xml b/main/res/layout/actionbar_maps.xml index 348342c..0e3dc0e 100644 --- a/main/res/layout/actionbar_maps.xml +++ b/main/res/layout/actionbar_maps.xml @@ -13,7 +13,7 @@ <ImageView style="@style/action_bar_action" android:layout_marginLeft="-13dp" - android:onClick="goHome" /> + android:onClick="navigateUp" /> <View style="@style/action_bar_separator" /> diff --git a/main/res/layout/addresslist_activity.xml b/main/res/layout/addresslist_activity.xml index e5c6491..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_maps" /> - <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/logcache_activity.xml b/main/res/layout/logcache_activity.xml index b08bb02..5445285 100644 --- a/main/res/layout/logcache_activity.xml +++ b/main/res/layout/logcache_activity.xml @@ -70,6 +70,27 @@ 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/tweet_box" android:layout_width="fill_parent" @@ -98,45 +119,6 @@ android:textColor="?text_color" android:textSize="14sp" /> </LinearLayout> - - <Button - android:id="@+id/image_btn" - style="@style/button_full" - android:text="@string/log_image_attach" /> - - <Button - android:id="@+id/post" - style="@style/button_full" - android:text="@string/log_post" /> - - <RelativeLayout style="@style/separator_horizontal_layout" > - - <View style="@style/separator_horizontal" /> - - <TextView - style="@style/separator_horizontal_headline" - android:text="@string/cache_log_offline" /> - </RelativeLayout> - - <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="@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> </LinearLayout> <LinearLayout 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/main_activity.xml b/main/res/layout/main_activity.xml index 29a445f..d2bd025 100644 --- a/main/res/layout/main_activity.xml +++ b/main/res/layout/main_activity.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:id="@+id/mainscreen" android:layout_width="fill_parent" android:layout_height="fill_parent" @@ -13,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/simple_dir_chooser.xml b/main/res/layout/simple_dir_chooser.xml index 77b1950..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" @@ -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/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 fa2112e..e15cd7a 100644 --- a/main/res/layout/usefulapps_activity.xml +++ b/main/res/layout/usefulapps_activity.xml @@ -1,5 +1,6 @@ <?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" @@ -15,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/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 a7841a5..586b93e 100644 --- a/main/res/menu/abstract_logging_activity.xml +++ b/main/res/menu/abstract_logging_activity.xml @@ -1,12 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:cgeo="http://schemas.android.com/apk/res-auto"> + 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" - cgeo:showAsAction="ifRoom|withText"> + 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" @@ -16,11 +17,33 @@ <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" 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_options.xml b/main/res/menu/cache_list_options.xml index c66af39..1ff0851 100644 --- a/main/res/menu/cache_list_options.xml +++ b/main/res/menu/cache_list_options.xml @@ -4,7 +4,7 @@ <item android:id="@+id/menu_show_on_map" - android:icon="@drawable/actionbar_map" + android:icon="@drawable/ic_menu_mapmode" cgeo:showAsAction="ifRoom" android:title="@string/caches_on_map"> </item> diff --git a/main/res/menu/cache_options.xml b/main/res/menu/cache_options.xml index 2bd0c44..4429baf 100644 --- a/main/res/menu/cache_options.xml +++ b/main/res/menu/cache_options.xml @@ -14,19 +14,6 @@ android:title="@string/cache_menu_navigate"> </item> <item - android:id="@+id/menu_share" - android:icon="@drawable/ic_menu_share" - cgeo:showAsAction="ifRoom" - cgeo:actionProviderClass="android.support.v7.widget.ShareActionProvider" - android:title="@string/cache_menu_share"> - </item> - <item - android:id="@+id/menu_calendar" - android:icon="@drawable/ic_menu_agenda" - cgeo:showAsAction="ifRoom" - android:title="@string/cache_menu_event"> - </item> - <item android:id="@+id/menu_log_visit_offline" android:icon="@drawable/ic_menu_edit" cgeo:showAsAction="ifRoom" @@ -39,6 +26,12 @@ android:title="@string/cache_menu_visit"> </item> <item + android:id="@+id/menu_calendar" + android:icon="@drawable/ic_menu_my_calendar" + cgeo:showAsAction="ifRoom" + android:title="@string/cache_menu_event"> + </item> + <item android:id="@+id/menu_caches_around" android:icon="@drawable/ic_menu_rotate" cgeo:showAsAction="ifRoom" @@ -50,6 +43,13 @@ cgeo:showAsAction="ifRoom" android:title="@string/cache_menu_browser"> </item> - + <item + android:id="@+id/menu_share" + android:icon="@drawable/ic_menu_share" + cgeo:showAsAction="ifRoom" + cgeo:actionProviderClass="android.support.v7.widget.ShareActionProvider" + android:title="@string/cache_menu_share"> + </item> + </menu>
\ No newline at end of file diff --git a/main/res/menu/details_context.xml b/main/res/menu/details_context.xml index 53f326a..fc61d5d 100644 --- a/main/res/menu/details_context.xml +++ b/main/res/menu/details_context.xml @@ -1,27 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:cgeo="http://schemas.android.com/apk/res-auto"> + 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/values-ca/strings.xml b/main/res/values-ca/strings.xml index b6bb051..a209e75 100644 --- a/main/res/values-ca/strings.xml +++ b/main/res/values-ca/strings.xml @@ -654,7 +654,6 @@ <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> @@ -1133,7 +1132,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> diff --git a/main/res/values-cs/strings.xml b/main/res/values-cs/strings.xml index ac3e78f..7a95d63 100644 --- a/main/res/values-cs/strings.xml +++ b/main/res/values-cs/strings.xml @@ -642,7 +642,6 @@ <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> @@ -1120,7 +1119,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> diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml index bd5956c..e056c48 100644 --- a/main/res/values-de/strings.xml +++ b/main/res/values-de/strings.xml @@ -236,7 +236,7 @@ <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> @@ -657,7 +657,6 @@ <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> @@ -1136,7 +1135,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> diff --git a/main/res/values-es/strings.xml b/main/res/values-es/strings.xml index 0c14188..bc7804c 100644 --- a/main/res/values-es/strings.xml +++ b/main/res/values-es/strings.xml @@ -533,7 +533,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> @@ -849,7 +848,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> diff --git a/main/res/values-fr/strings.xml b/main/res/values-fr/strings.xml index 359efbb..212f0da 100644 --- a/main/res/values-fr/strings.xml +++ b/main/res/values-fr/strings.xml @@ -646,7 +646,6 @@ <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> @@ -1123,7 +1122,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> diff --git a/main/res/values-hu/strings.xml b/main/res/values-hu/strings.xml index 4501eec..6be2408 100644 --- a/main/res/values-hu/strings.xml +++ b/main/res/values-hu/strings.xml @@ -464,7 +464,6 @@ <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> @@ -802,7 +801,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 22c72be..36c78cd 100644 --- a/main/res/values-it/strings.xml +++ b/main/res/values-it/strings.xml @@ -643,7 +643,6 @@ <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> @@ -1120,7 +1119,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> diff --git a/main/res/values-ja/strings.xml b/main/res/values-ja/strings.xml index e3a1800..1e90291 100644 --- a/main/res/values-ja/strings.xml +++ b/main/res/values-ja/strings.xml @@ -595,7 +595,6 @@ <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> @@ -1034,7 +1033,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> diff --git a/main/res/values-lt/strings.xml b/main/res/values-lt/strings.xml index 6907f67..77e9a93 100644 --- a/main/res/values-lt/strings.xml +++ b/main/res/values-lt/strings.xml @@ -655,7 +655,6 @@ <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> @@ -1132,7 +1131,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> diff --git a/main/res/values-nb/strings.xml b/main/res/values-nb/strings.xml index f8bb5b7..5f3dacd 100644 --- a/main/res/values-nb/strings.xml +++ b/main/res/values-nb/strings.xml @@ -638,7 +638,6 @@ <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> @@ -1114,7 +1113,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> diff --git a/main/res/values-nl/strings.xml b/main/res/values-nl/strings.xml index 8e60147..82a8f87 100644 --- a/main/res/values-nl/strings.xml +++ b/main/res/values-nl/strings.xml @@ -654,7 +654,6 @@ <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> @@ -1133,7 +1132,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> diff --git a/main/res/values-pl/strings.xml b/main/res/values-pl/strings.xml index 78ca431..8e9e495 100644 --- a/main/res/values-pl/strings.xml +++ b/main/res/values-pl/strings.xml @@ -650,7 +650,6 @@ <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> @@ -1128,7 +1127,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> diff --git a/main/res/values-pt/strings.xml b/main/res/values-pt/strings.xml index 32ff6f7..69eb3b6 100644 --- a/main/res/values-pt/strings.xml +++ b/main/res/values-pt/strings.xml @@ -646,7 +646,6 @@ <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> @@ -1123,7 +1122,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> diff --git a/main/res/values-ro/strings.xml b/main/res/values-ro/strings.xml index badcf2f..95d8307 100644 --- a/main/res/values-ro/strings.xml +++ b/main/res/values-ro/strings.xml @@ -638,7 +638,6 @@ <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> @@ -1116,7 +1115,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> diff --git a/main/res/values-sk/strings.xml b/main/res/values-sk/strings.xml index 6af9675..4e6a9dc 100644 --- a/main/res/values-sk/strings.xml +++ b/main/res/values-sk/strings.xml @@ -310,7 +310,7 @@ <string name="caches_clear_offlinelogs_progress">Vymazanie logov v režime offline</string> <string name="list_menu_create">VytvoriÅ¥ nový zoznam</string> <string name="list_menu_drop">ZahodiÅ¥ aktuálny zoznam</string> - <string name="list_menu_rename">PremenovaÅ¥ tento 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> <string name="list_all_lists">VÅ¡etky skrýše</string> @@ -639,7 +639,6 @@ <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> @@ -1116,7 +1115,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> diff --git a/main/res/values-sl/strings.xml b/main/res/values-sl/strings.xml index cde779e..a3559ef 100644 --- a/main/res/values-sl/strings.xml +++ b/main/res/values-sl/strings.xml @@ -649,7 +649,6 @@ <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> @@ -1126,7 +1125,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> diff --git a/main/res/values-sv/strings.xml b/main/res/values-sv/strings.xml index aeb8e7d..72aa975 100644 --- a/main/res/values-sv/strings.xml +++ b/main/res/values-sv/strings.xml @@ -654,7 +654,6 @@ <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> @@ -1133,7 +1132,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> diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml index 9b5a562..c62ec3a 100644 --- a/main/res/values/changelog_master.xml +++ b/main/res/values/changelog_master.xml @@ -5,9 +5,11 @@ <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 · Fix: Hiding own caches on opencaching\n · Fix: Webcam caches not marked as found after posting log\n @@ -16,6 +18,7 @@ · 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 \n \n </string> 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 f8b9230..1d14d8e 100644 --- a/main/res/values/preference_keys.xml +++ b/main/res/values/preference_keys.xml @@ -136,7 +136,6 @@ <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> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index d87e01f..ab41c29 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -710,7 +710,6 @@ <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> @@ -1232,7 +1231,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> @@ -1291,5 +1289,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/themes.xml b/main/res/values/themes.xml index 7928e80..82a4422 100644 --- a/main/res/values/themes.xml +++ b/main/res/values/themes.xml @@ -5,7 +5,7 @@ <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">@android:color/transparent</item> + <item name="android:windowBackground">@color/background_main_transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowShowWallpaper">true</item> diff --git a/main/res/xml/preferences.xml b/main/res/xml/preferences.xml index 124bd0d..148c4aa 100644 --- a/main/res/xml/preferences.xml +++ b/main/res/xml/preferences.xml @@ -668,11 +668,6 @@ <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 diff --git a/main/src/cgeo/geocaching/AboutActivity.java b/main/src/cgeo/geocaching/AboutActivity.java index f46a5a6..5bf0f06 100644 --- a/main/src/cgeo/geocaching/AboutActivity.java +++ b/main/src/cgeo/geocaching/AboutActivity.java @@ -87,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; @@ -99,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() { diff --git a/main/src/cgeo/geocaching/AbstractDialogFragment.java b/main/src/cgeo/geocaching/AbstractDialogFragment.java index 1c8d089..84a20ea 100644 --- a/main/src/cgeo/geocaching/AbstractDialogFragment.java +++ b/main/src/cgeo/geocaching/AbstractDialogFragment.java @@ -106,7 +106,6 @@ public abstract class AbstractDialogFragment extends DialogFragment implements C public void onStart() { super.onStart(); geocode = getArguments().getString(GEOCODE_ARG); - init(); } diff --git a/main/src/cgeo/geocaching/AbstractLoggingActivity.java b/main/src/cgeo/geocaching/AbstractLoggingActivity.java index 3b0f78d..bca5db1 100644 --- a/main/src/cgeo/geocaching/AbstractLoggingActivity.java +++ b/main/src/cgeo/geocaching/AbstractLoggingActivity.java @@ -7,13 +7,10 @@ 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; @@ -26,7 +23,7 @@ public abstract class AbstractLoggingActivity extends AbstractActionBarActivity 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 AbstractActionBarActivity } @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 AbstractActionBarActivity } @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 AbstractActionBarActivity 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/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index 8672847..f5871e3 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -84,6 +84,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; @@ -97,6 +98,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; @@ -336,49 +338,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc 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); @@ -405,9 +364,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc @Override public boolean onContextItemSelected(MenuItem item) { - if (onClipboardItemSelected(item, clickedItemText)) { - return true; - } switch (item.getItemId()) { // waypoints case R.id.menu_waypoint_edit: @@ -599,9 +555,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // action bar: title and icon if (StringUtils.isNotBlank(cache.getName())) { - getSupportActionBar().setTitle(cache.getName() + " (" + cache.getGeocode() + ')'); + setTitle(cache.getName() + " (" + cache.getGeocode() + ')'); } else { - getSupportActionBar().setTitle(cache.getGeocode()); + setTitle(cache.getGeocode()); } getSupportActionBar().setIcon(getResources().getDrawable(cache.getType().markerId)); @@ -913,10 +869,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); @@ -950,7 +906,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 @@ -962,7 +918,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 @@ -1422,7 +1378,7 @@ 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 @@ -1473,7 +1429,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); @@ -1643,7 +1599,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc descriptionView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); fixTextColor(descriptionString); descriptionView.setVisibility(View.VISIBLE); - registerForContextMenu(descriptionView); + addContextMenu(descriptionView); } } @@ -1807,7 +1763,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } }); - registerForContextMenu(rowView); + addContextMenu(rowView); rowView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -1896,6 +1852,86 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc context.startActivity(cachesIntent); } + public void addContextMenu(final View view) { + view.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + startSupportActionMode(new ActionMode.Callback() { + + @Override + public boolean onPrepareActionMode(ActionMode actionMode, 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(ActionMode actionMode) { + // do nothing + } + + @Override + public boolean onCreateActionMode(ActionMode actionMode, 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(ActionMode actionMode, 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); diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java index 333dfb7..21ff113 100644 --- a/main/src/cgeo/geocaching/CacheListActivity.java +++ b/main/src/cgeo/geocaching/CacheListActivity.java @@ -85,13 +85,10 @@ import android.support.v7.app.ActionBar; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; @@ -260,14 +257,14 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } } - private static String getCacheNumberString(Resources res, int count) + static String getCacheNumberString(Resources res, int count) { return res.getQuantityString(R.plurals.cache_counts, count, count); } protected void updateTitle() { - getSupportActionBar().setTitle(title); + setTitle(title); final ArrayList<String> numbers = new ArrayList<String>(); if (adapter.isFiltered()) { @@ -446,68 +443,13 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } - static class CacheArrayAdapter extends ArrayAdapter<AbstractList> { - - static class ViewHolder { - TextView title; - TextView subtitle; - } - - private final Context mContext; - - public CacheArrayAdapter(Context context, int resource) { - super(context, resource); - mContext = context; - } - - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - return getCustomView(position, convertView, parent); - } - - - @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { - return getCustomView(position, convertView, parent); - } - - public View getCustomView(final int position, final View convertView, final ViewGroup parent) { - - View resultView = convertView; - LayoutInflater inflater = - (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - - 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 = (ViewHolder) resultView.getTag(); - } - - AbstractList list = getItem(position); - holder.title.setText(list.getTitle()); - if (list.getCount() >= 0) { - holder.subtitle.setVisibility(View.VISIBLE); - holder.subtitle.setText(getCacheNumberString(mContext.getResources(),list.getCount())); - } else { - holder.subtitle.setVisibility(View.GONE); - } - - return resultView; - } - } - - CacheArrayAdapter mCacheListSpinnerAdapter; + /** + * Action bar spinner adapter. {@code null} for list types that don't allow switching (search results, ...). + */ + CacheListSpinnerAdapter mCacheListSpinnerAdapter; private void initActionBarSpinner() { - mCacheListSpinnerAdapter = new CacheArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item); + 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() { @@ -647,7 +589,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA 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); @@ -689,9 +631,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; } } @@ -1739,7 +1681,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA loader = new PocketGeocacheListLoader(app, guid); break; } - setTitle(title); + updateTitle(); showProgress(true); showFooterLoadingCaches(); @@ -1774,6 +1716,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA } showProgress(false); hideLoading(); + invalidateOptionsMenuCompatible(); } @Override diff --git a/main/src/cgeo/geocaching/CacheListSpinnerAdapter.java b/main/src/cgeo/geocaching/CacheListSpinnerAdapter.java new file mode 100644 index 0000000..5ace70e --- /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 Context mContext; + + public CacheListSpinnerAdapter(Context context, int resource) { + super(context, resource); + mContext = context; + } + + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + public View getCustomView(final int position, final View convertView, final ViewGroup parent) { + + View resultView = convertView; + LayoutInflater inflater = + (LayoutInflater) mContext.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(); + } + + AbstractList list = getItem(position); + holder.title.setText(list.getTitle()); + if (list.getCount() >= 0) { + holder.subtitle.setVisibility(View.VISIBLE); + holder.subtitle.setText(CacheListActivity.getCacheNumberString(mContext.getResources(),list.getCount())); + } else { + holder.subtitle.setVisibility(View.GONE); + } + + return resultView; + } +}
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/CompassActivity.java b/main/src/cgeo/geocaching/CompassActivity.java index e5c38a3..1d86c49 100644 --- a/main/src/cgeo/geocaching/CompassActivity.java +++ b/main/src/cgeo/geocaching/CompassActivity.java @@ -217,7 +217,7 @@ public class CompassActivity extends AbstractActionBarActivity { return true; } } - return false; + return super.onOptionsItemSelected(item); } private void setTitle() { diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java index 0000fcc..6084762 100644 --- a/main/src/cgeo/geocaching/Geocache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -81,10 +81,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; diff --git a/main/src/cgeo/geocaching/LogCacheActivity.java b/main/src/cgeo/geocaching/LogCacheActivity.java index 5149dbc..1f77113 100644 --- a/main/src/cgeo/geocaching/LogCacheActivity.java +++ b/main/src/cgeo/geocaching/LogCacheActivity.java @@ -34,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; @@ -51,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"; @@ -67,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; @@ -83,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() { @@ -122,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; } @@ -141,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); @@ -153,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); } }); @@ -163,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); @@ -183,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(); } }); @@ -192,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 @@ -238,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())) { @@ -247,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(); @@ -276,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); @@ -285,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(); } }); @@ -304,36 +281,29 @@ 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(); } private void setDefaultValues() { @@ -363,8 +333,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)); } @@ -381,53 +349,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); @@ -439,14 +360,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; @@ -460,11 +381,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 { @@ -472,7 +391,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 { @@ -483,23 +402,13 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia private class DateListener implements View.OnClickListener { @Override - public void onClick(View arg0) { + public void onClick(final View arg0) { final DateDialog dateDialog = DateDialog.getInstance(date); dateDialog.setCancelable(true); dateDialog.show(getSupportFragmentManager(), "date_dialog"); } } - 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()); - } - } - private class Poster extends AsyncTaskWithProgress<String, StatusCode> { public Poster(final Activity activity, final String progressMessage) { @@ -522,7 +431,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia 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); @@ -541,7 +450,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 +461,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 +510,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 +531,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 +542,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 +558,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 +580,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 +589,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 +599,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/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java index 8de27b0..cf323bb 100644 --- a/main/src/cgeo/geocaching/MainActivity.java +++ b/main/src/cgeo/geocaching/MainActivity.java @@ -326,9 +326,8 @@ public class MainActivity extends AbstractActionBarActivity { case R.id.menu_gosearch: onSearchRequested(); return true; - default: - return super.onOptionsItemSelected(item); } + return super.onOptionsItemSelected(item); } private void startScannerApplication() { diff --git a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java index c9b1b3f..39531f1 100644 --- a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java +++ b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java @@ -361,9 +361,8 @@ public class NavigateAnyPointActivity extends AbstractActionBarActivity implemen case R.id.menu_navigate: NavigationAppFactory.showNavigationMenu(this, null, null, coords); return true; - default: - return super.onOptionsItemSelected(item); } + return super.onOptionsItemSelected(item); } private void addToHistory(final Geopoint coords) { diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java index bc8582e..f1dab50 100644 --- a/main/src/cgeo/geocaching/TrackableActivity.java +++ b/main/src/cgeo/geocaching/TrackableActivity.java @@ -38,12 +38,14 @@ 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; @@ -97,9 +99,9 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi geocode = trackable.getGeocode(); if (StringUtils.isNotBlank(trackable.getName())) { - getSupportActionBar().setTitle(Html.fromHtml(trackable.getName()).toString()); + setTitle(Html.fromHtml(trackable.getName()).toString()); } else { - getSupportActionBar().setTitle(trackable.getName()); + setTitle(trackable.getName()); } invalidateOptionsMenuCompatible(); @@ -126,13 +128,17 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi }; 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) { super.onCreate(savedInstanceState, R.layout.viewpager_activity); // set title in code, as the activity needs a hard coded title due to the intent filters - getSupportActionBar().setTitle(res.getString(R.string.trackable)); + setTitle(res.getString(R.string.trackable)); // get parameters final Bundle extras = getIntent().getExtras(); @@ -210,36 +216,6 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) { - super.onCreateContextMenu(menu, view, info); - final int viewId = view.getId(); - assert view instanceof TextView; - clickedItemText = ((TextView) view).getText(); - switch (viewId) { - case R.id.value: // name, TB-code, origin, released, distance - final String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); - buildDetailsContextMenu(menu, clickedItemText, itemTitle, true); - break; - case R.id.goal: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_goal), false); - break; - case R.id.details: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.trackable_details), false); - break; - case R.id.log: - buildDetailsContextMenu(menu, clickedItemText, res.getString(R.string.cache_logs), false); - break; - default: - break; - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - return onClipboardItemSelected(item, clickedItemText) || onOptionsItemSelected(item); - } - - @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.trackable_activity, menu); return true; @@ -254,9 +230,8 @@ 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 @@ -410,7 +385,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } // 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; @@ -422,7 +397,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)); @@ -491,17 +466,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 @@ -510,7 +485,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 @@ -519,7 +494,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 @@ -550,4 +525,70 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi } + public void addContextMenu(final View view) { + view.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + return startContextualActionBar(view); + } + }); + + view.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + startContextualActionBar(view); + } + }); + } + + private boolean startContextualActionBar(final View view) { + if (currentActionMode != null) { + return false; + } + currentActionMode = startSupportActionMode(new ActionMode.Callback() { + + @Override + public boolean onPrepareActionMode(ActionMode actionMode, 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(ActionMode actionMode) { + currentActionMode = null; + } + + @Override + public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { + actionMode.getMenuInflater().inflate(R.menu.details_context, menu); + return true; + } + + @Override + public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { + return onClipboardItemSelected(actionMode, menuItem, clickedItemText); + } + }); + return false; + } + } diff --git a/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java b/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java index 615a432..a732f65 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActionBarActivity.java @@ -24,4 +24,11 @@ public class AbstractActionBarActivity extends AbstractActivity { 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 d542b13..e3df1f7 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -12,6 +12,7 @@ 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; @@ -26,7 +27,8 @@ import android.nfc.NfcEvent; import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; -import android.view.ContextMenu; +import android.support.v7.view.ActionMode; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; @@ -49,11 +51,6 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs this.keepScreenOn = keepScreenOn; } - @Override - final public void goHome(final View view) { - ActivityMixin.navigateToMain(this); - } - final protected void showProgress(final boolean show) { ActivityMixin.showProgress(this, show); } @@ -83,9 +80,8 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs @Override public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId()== android.R.id.home) { - ActivityMixin.navigateToMain(this); - return true; + if (item.getItemId() == android.R.id.home) { + return ActivityMixin.navigateUp(this); } return super.onOptionsItemSelected(item); } @@ -160,9 +156,8 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs 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) { @@ -174,24 +169,28 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs 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; @@ -208,8 +207,9 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs } protected void initializeAndroidBeam(ActivitySharingInterface sharingInterface) { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) { initializeICSAndroidBeam(sharingInterface); + } } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index eaa8a96..eac191a 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -5,7 +5,6 @@ import cgeo.geocaching.CgeoApplication; import android.content.res.Resources; import android.os.Bundle; import android.view.MenuItem; -import android.view.View; import android.view.Window; public abstract class AbstractListActivity extends ActionBarListActivity implements @@ -24,11 +23,6 @@ public abstract class AbstractListActivity extends ActionBarListActivity impleme this.keepScreenOn = keepScreenOn; } - @Override - final public void goHome(View view) { - ActivityMixin.navigateToMain(this); - } - final public void showProgress(final boolean show) { ActivityMixin.showProgress(this, show); } @@ -41,7 +35,7 @@ public abstract class AbstractListActivity extends ActionBarListActivity impleme public final void showToast(String text) { ActivityMixin.showToast(this, text); } - + @Override public final void showShortToast(String text) { ActivityMixin.showShortToast(this, text); @@ -56,16 +50,14 @@ public abstract class AbstractListActivity extends ActionBarListActivity impleme initUpAction(); } - protected void initUpAction() - { + protected void initUpAction() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId()== android.R.id.home) { - ActivityMixin.navigateToMain(this); - return true; + return ActivityMixin.navigateUp(this); } return super.onOptionsItemSelected(item); } diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index c43e1bd..e2181d0 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -1,15 +1,17 @@ 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.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.WindowManager; @@ -23,12 +25,14 @@ public final class ActivityMixin { return; } - if (((ActionBarActivity) activity).getSupportActionBar() != null) { - ((ActionBarActivity) activity).getSupportActionBar().setTitle(text); + if (activity instanceof ActionBarActivity) { + final ActionBar actionBar = ((ActionBarActivity) activity).getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(text); + } } } - public static void showProgress(final ActionBarActivity activity, final boolean show) { if (activity == null) { return; @@ -84,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); + } } /** @@ -114,8 +123,26 @@ public final class ActivityMixin { editText.setSelection(newCursor); } - public static void navigateToMain(Activity activity) { - final Intent main = new Intent(activity, MainActivity.class); - NavUtils.navigateUpTo(activity, main); + 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/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/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java index 3177a29..1446d8a 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java @@ -8,7 +8,6 @@ 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; @@ -70,7 +69,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); 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 887bb32..54e2966 100644 --- a/main/src/cgeo/geocaching/compatibility/Compatibility.java +++ b/main/src/cgeo/geocaching/compatibility/Compatibility.java @@ -10,12 +10,10 @@ public final class Compatibility { private static final int SDK_VERSION = Build.VERSION.SDK_INT; - private static final AndroidLevel11Interface LEVEL_11; private static final AndroidLevel13Interface LEVEL_13; private static final AndroidLevel19Interface LEVEL_19; static { - LEVEL_11 = SDK_VERSION >= 11 ? new AndroidLevel11() : new AndroidLevel11Emulation(); LEVEL_13 = SDK_VERSION >= 13 ? new AndroidLevel13() : new AndroidLevel13Emulation(); LEVEL_19 = SDK_VERSION >= 19 ? new AndroidLevel19() : new AndroidLevel19Emulation(); } @@ -24,10 +22,6 @@ public final class Compatibility { // utility class } - public static void invalidateOptionsMenu(final Activity activity) { - LEVEL_11.invalidateOptionsMenu(activity); - } - public static int getDisplayWidth() { return LEVEL_13.getDisplayWidth(); } 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/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/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/maps/AbstractMap.java b/main/src/cgeo/geocaching/maps/AbstractMap.java index aff9c75..2eceadb 100644 --- a/main/src/cgeo/geocaching/maps/AbstractMap.java +++ b/main/src/cgeo/geocaching/maps/AbstractMap.java @@ -9,7 +9,6 @@ import android.os.Build; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; -import android.view.View; import android.view.Window; /** @@ -70,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 9c67723..87d5366 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -43,6 +43,7 @@ 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.Subscription; import rx.functions.Action0; @@ -96,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; @@ -175,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 */ @@ -190,7 +191,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto // views private CheckBox myLocSwitch = null; - /** Controls the map behaviour */ + /** Controls the map behavior */ private MapMode mapMode = null; /** Live mode enabled for map. **/ private boolean isLiveEnabled; @@ -223,7 +224,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } @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) { @@ -268,7 +269,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final private Handler displayHandler = new DisplayHandler(this); - private void setTitle(String title) { + 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) { @@ -281,7 +282,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } @TargetApi(Build.VERSION_CODES.HONEYCOMB) - private void setTitleHoneyComb(String title) { + private void setTitleHoneyComb(final String title) { activity.getActionBar().setTitle(title); } @@ -295,7 +296,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } @Override - public void handleMessage(Message msg) { + public void handleMessage(final Message msg) { final int what = msg.what; if (what == HIDE_PROGRESS) { @@ -308,7 +309,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } - private void showProgress(boolean show) { + private void showProgress(final boolean show) { final CGeoMap map = mapRef.get(); if (map == null) { return; @@ -334,10 +335,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto 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; @@ -349,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)); } } @@ -372,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)); @@ -388,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); } @@ -423,7 +424,7 @@ 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 @@ -431,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(); @@ -496,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(); @@ -530,7 +531,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } - CheckBox locSwitch = (CheckBox) activity.findViewById(R.id.my_position); + final CheckBox locSwitch = (CheckBox) activity.findViewById(R.id.my_position); if (locSwitch!=null) { initMyLocationSwitchButton(locSwitch); } @@ -541,13 +542,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } - private void initMyLocationSwitchButton(CheckBox locSwitch) { + 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()); + myLocSwitch.setOnClickListener(new MyLocationListener(this)); switchMyLocationButton(); } @@ -563,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 { @@ -577,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); @@ -588,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)); } } @@ -608,7 +609,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto @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); @@ -620,7 +621,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) { /* if we have an Actionbar find the my position toggle */ - MenuItem item = menu.findItem(R.id.menu_toggle_mypos); + final MenuItem item = menu.findItem(R.id.menu_toggle_mypos); myLocSwitch = new CheckBox(activity); myLocSwitch.setButtonDrawable(R.drawable.ic_menu_myposition); item.setActionView(myLocSwitch); @@ -633,9 +634,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } @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.setVisible(mapSource.isAvailable()); @@ -694,7 +695,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); } @@ -702,11 +703,11 @@ 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.navigateToMain(activity); + ActivityMixin.navigateUp(activity); return true; case R.id.menu_trail_mode: Settings.setMapTrail(!Settings.isMapTrail()); @@ -817,16 +818,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(); } @@ -835,7 +836,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); @@ -843,7 +844,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) { @@ -909,7 +910,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); @@ -987,7 +988,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); } @@ -1013,15 +1014,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(); } - boolean needsRepaintForDistance = needsRepaintForDistance(); - boolean needsRepaintForHeading = needsRepaintForHeading(); + final boolean needsRepaintForDistance = needsRepaintForDistance(); + final boolean needsRepaintForHeading = needsRepaintForHeading(); if (needsRepaintForDistance) { if (cgeoMapRef.followMyLocation) { @@ -1036,7 +1037,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } } } - } catch (RuntimeException e) { + } catch (final RuntimeException e) { Log.w("Failed to update location."); } } @@ -1131,16 +1132,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (moved) { map.markersInvalidated = false; - long currentTime = System.currentTimeMillis(); + final long currentTime = System.currentTimeMillis(); if (1000 < (currentTime - map.loadThreadRun)) { map.viewport = viewportNow; - loadExecutor.execute(map.new LoadRunnable(map.viewport)); + loadExecutor.execute(new LoadRunnable(map)); } } } - } catch (Exception e) { + } catch (final Exception e) { Log.w("CGeoMap.startLoadtimer.start", e); } } @@ -1170,79 +1171,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 } + } /** @@ -1250,111 +1259,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(); - } + final CGeoMap map = getMap(); + if (map != null) { + map.doDisplayRun(); + } + } + } - // display caches - final List<Geocache> cachesToDisplay = caches.getAsList(); - final List<Waypoint> waypointsToDisplay = new ArrayList<Waypoint>(waypoints); - final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>(); + private void doDisplayRun() { + try { + showProgressHandler.sendEmptyMessage(SHOW_PROGRESS); + if (mapView == null || caches == null) { + throw new ThreadDeath(); + } - 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) { + // display caches + final List<Geocache> cachesToDisplay = caches.getAsList(); + final List<Waypoint> waypointsToDisplay = new ArrayList<Waypoint>(waypoints); + final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>(); - if (waypoint == null || waypoint.getCoords() == null) { - continue; - } + 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) { - itemsToDisplay.add(getWaypointItem(waypoint)); - } - } - for (Geocache cache : cachesToDisplay) { - - 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); } } @@ -1372,10 +1395,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(@NonNull final CGeoMap map) { + mapRef = new WeakReference<CGeoMap>(map); + } - protected DoRunnable(final Viewport viewport) { - this.viewport = viewport; + protected @Nullable + final CGeoMap getMap() { + return mapRef.get(); } } @@ -1385,7 +1413,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); @@ -1396,19 +1424,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 { @@ -1457,7 +1485,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 @@ -1471,12 +1499,12 @@ 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) { + 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); } @@ -1514,14 +1542,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); } @@ -1545,7 +1573,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); } @@ -1554,7 +1582,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); } @@ -1572,16 +1600,47 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } // 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(); @@ -1593,15 +1652,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.navigateToMain(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; @@ -1739,7 +1792,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/google/GoogleMapActivity.java b/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java index 8a1bad6..2a29cc9 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleMapActivity.java @@ -98,8 +98,8 @@ public class GoogleMapActivity extends MapActivity implements MapActivityImpl, F } @Override - public void goHome(View view) { - ActivityMixin.navigateToMain(this); + public void navigateUp(View view) { + ActivityMixin.navigateUp(this); } @Override diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java index 094c456..ea815ab 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java @@ -38,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()); } diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java index 08309f4..3596d5f 100644 --- a/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java +++ b/main/src/cgeo/geocaching/maps/interfaces/MapActivityImpl.java @@ -33,5 +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/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 fb057a4..d95cc80 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java @@ -42,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); 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 68a03b7..8dd15fc 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/v024/MapsforgeMapView024.java @@ -36,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()); } diff --git a/main/src/cgeo/geocaching/settings/Settings.java b/main/src/cgeo/geocaching/settings/Settings.java index 474558d..9de272b 100644 --- a/main/src/cgeo/geocaching/settings/Settings.java +++ b/main/src/cgeo/geocaching/settings/Settings.java @@ -374,7 +374,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) { 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/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/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 5fa0982..76400cf 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 @@ -171,11 +174,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 +187,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 +202,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 +216,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 +227,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 +259,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/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 |
