option to delete all recordings that are not starred

master
y20k 2020-03-09 15:39:48 +01:00
parent d68a767e3e
commit 54d875ff2d
No known key found for this signature in database
GPG Key ID: 824D4259F41FAFF6
12 changed files with 107 additions and 27 deletions

View File

@ -81,7 +81,7 @@ dependencies {
implementation "com.google.android.material:material:1.1.0-beta01" implementation "com.google.android.material:material:1.1.0-beta01"
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.6"
implementation "org.osmdroid:osmdroid-android:6.1.5" implementation "org.osmdroid:osmdroid-android:6.1.6"
} }
androidExtensions { androidExtensions {

View File

@ -69,7 +69,8 @@ object Keys {
// dialog types // dialog types
const val DIALOG_EMPTY_RECORDING: Int = 0 const val DIALOG_EMPTY_RECORDING: Int = 0
const val DIALOG_REMOVE_TRACK: Int = 1 const val DIALOG_DELETE_TRACK: Int = 1
const val DIALOG_DELETE_NON_STARRED: Int = 2
// dialog results // dialog results
const val DIALOG_EMPTY_PAYLOAD_STRING: String = "" const val DIALOG_EMPTY_PAYLOAD_STRING: String = ""

View File

@ -18,11 +18,15 @@
package org.y20k.trackbook package org.y20k.trackbook
import YesNoDialog
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.preference.* import androidx.preference.*
import kotlinx.coroutines.*
import org.y20k.trackbook.core.Tracklist
import org.y20k.trackbook.helpers.AppThemeHelper import org.y20k.trackbook.helpers.AppThemeHelper
import org.y20k.trackbook.helpers.FileHelper
import org.y20k.trackbook.helpers.LengthUnitHelper import org.y20k.trackbook.helpers.LengthUnitHelper
import org.y20k.trackbook.helpers.LogHelper import org.y20k.trackbook.helpers.LogHelper
@ -30,7 +34,7 @@ import org.y20k.trackbook.helpers.LogHelper
/* /*
* SettingsFragment class * SettingsFragment class
*/ */
class SettingsFragment : PreferenceFragmentCompat() { class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogListener {
/* Define log tag */ /* Define log tag */
private val TAG: String = LogHelper.makeLogTag(SettingsFragment::class.java) private val TAG: String = LogHelper.makeLogTag(SettingsFragment::class.java)
@ -88,12 +92,16 @@ class SettingsFragment : PreferenceFragmentCompat() {
return@setOnPreferenceChangeListener false return@setOnPreferenceChangeListener false
} }
} }
// preferenceThemeSelection.setOnPreferenceClickListener {
// preferenceThemeSelection.summary = "${getString(R.string.pref_theme_selection_theme_summary)} ${AppThemeHelper.getCurrentTheme(activity as Context)}"
// return@setOnPreferenceClickListener true
// }
// set up "Delete Non-Starred" preference
val preferenceDeleteNonStarred: Preference = Preference(activity as Context)
preferenceDeleteNonStarred.title = getString(R.string.pref_delete_non_starred_title)
preferenceDeleteNonStarred.setIcon(R.drawable.ic_delete_24dp)
preferenceDeleteNonStarred.summary = getString(R.string.pref_delete_non_starred_summary)
preferenceDeleteNonStarred.setOnPreferenceClickListener{
YesNoDialog(this as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_NON_STARRED, message = R.string.dialog_yes_no_message_delete_non_starred, yesButton = R.string.dialog_yes_no_positive_button_delete_non_starred)
return@setOnPreferenceClickListener true
}
// set up "Accuracy Threshold" preference // set up "Accuracy Threshold" preference
val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context) val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context)
@ -120,6 +128,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
preferenceCategoryGeneral.title = getString(R.string.pref_general_title) preferenceCategoryGeneral.title = getString(R.string.pref_general_title)
preferenceCategoryGeneral.contains(preferenceImperialMeasurementUnits) preferenceCategoryGeneral.contains(preferenceImperialMeasurementUnits)
preferenceCategoryGeneral.contains(preferenceGpsOnly) preferenceCategoryGeneral.contains(preferenceGpsOnly)
val preferenceCategoryMaintenance: PreferenceCategory = PreferenceCategory(activity as Context)
preferenceCategoryMaintenance.title = getString(R.string.pref_maintenance_title)
preferenceCategoryMaintenance.contains(preferenceDeleteNonStarred)
val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context) val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context)
preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title) preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title)
preferenceCategoryAdvanced.contains(preferenceAccuracyThreshold) preferenceCategoryAdvanced.contains(preferenceAccuracyThreshold)
@ -130,10 +142,45 @@ class SettingsFragment : PreferenceFragmentCompat() {
screen.addPreference(preferenceGpsOnly) screen.addPreference(preferenceGpsOnly)
screen.addPreference(preferenceImperialMeasurementUnits) screen.addPreference(preferenceImperialMeasurementUnits)
screen.addPreference(preferenceThemeSelection) screen.addPreference(preferenceThemeSelection)
screen.addPreference(preferenceCategoryMaintenance)
screen.addPreference(preferenceDeleteNonStarred)
screen.addPreference(preferenceCategoryAdvanced) screen.addPreference(preferenceCategoryAdvanced)
screen.addPreference(preferenceAccuracyThreshold) screen.addPreference(preferenceAccuracyThreshold)
screen.addPreference(preferenceResetAdvanced) screen.addPreference(preferenceResetAdvanced)
preferenceScreen = screen preferenceScreen = screen
} }
/* Overrides onYesNoDialog from YesNoDialogListener */
override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) {
when (type) {
Keys.DIALOG_DELETE_NON_STARRED -> {
when (dialogResult) {
// user tapped delete
true -> {
deleteNonStarred(activity as Context)
}
}
}
else -> {
super.onYesNoDialog(type, dialogResult, payload, payloadString)
}
}
}
/* Removes track and track files for given position - used by TracklistFragment */
fun deleteNonStarred(context: Context) {
val backgroundJob = Job()
val uiScope = CoroutineScope(Dispatchers.Main + backgroundJob)
uiScope.launch {
var tracklist: Tracklist = FileHelper.readTracklist(context)
val deferred: Deferred<Tracklist> = async { FileHelper.deleteNonStarredSuspended(context, tracklist) }
// wait for result and store in tracklist
tracklist = deferred.await()
backgroundJob.cancel()
}
}
} }

View File

@ -85,8 +85,8 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
} }
// set up delete button // set up delete button
layout.deleteButton.setOnClickListener { layout.deleteButton.setOnClickListener {
val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_remove_recording)}\n\n- ${layout.trackNameView.text}" val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${layout.trackNameView.text}"
YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_REMOVE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_remove_recording) YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_delete_recording)
} }
// set up rename button // set up rename button
layout.editButton.setOnClickListener { layout.editButton.setOnClickListener {
@ -147,7 +147,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
/* Overrides onYesNoDialog from YesNoDialogListener */ /* Overrides onYesNoDialog from YesNoDialogListener */
override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) {
when (type) { when (type) {
Keys.DIALOG_REMOVE_TRACK -> { Keys.DIALOG_DELETE_TRACK -> {
when (dialogResult) { when (dialogResult) {
// user tapped remove track // user tapped remove track
true -> { true -> {

View File

@ -77,8 +77,8 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener,
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
// ask user // ask user
val adapterPosition: Int = viewHolder.adapterPosition val adapterPosition: Int = viewHolder.adapterPosition
val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_remove_recording)}\n\n- ${tracklistAdapter.getTrackName(adapterPosition)}" val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${tracklistAdapter.getTrackName(adapterPosition)}"
YesNoDialog(this@TracklistFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_REMOVE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_remove_recording, payload = adapterPosition) YesNoDialog(this@TracklistFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_delete_recording, payload = adapterPosition)
} }
} }
val itemTouchHelper = ItemTouchHelper(swipeHandler) val itemTouchHelper = ItemTouchHelper(swipeHandler)
@ -105,7 +105,7 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener,
/* Overrides onYesNoDialog from YesNoDialogListener */ /* Overrides onYesNoDialog from YesNoDialogListener */
override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) {
when (type) { when (type) {
Keys.DIALOG_REMOVE_TRACK -> { Keys.DIALOG_DELETE_TRACK -> {
when (dialogResult) { when (dialogResult) {
// user tapped remove track // user tapped remove track
true -> { true -> {

View File

@ -224,6 +224,20 @@ object FileHelper {
} }
/* Suspend function: Deletes tracks that are not starred using deleteTracks */
suspend fun deleteNonStarredSuspended(context: Context, tracklist: Tracklist): Tracklist {
return suspendCoroutine { cont ->
val tracklistElements = mutableListOf<TracklistElement>()
tracklist.tracklistElements.forEach { tracklistElement ->
if (!tracklistElement.starred) {
tracklistElements.add(tracklistElement)
}
}
cont.resume(deleteTracks(context, tracklistElements, tracklist))
}
}
/* Suspend function: Wrapper for readTracklist */ /* Suspend function: Wrapper for readTracklist */
suspend fun readTracklistSuspended(context: Context): Tracklist { suspend fun readTracklistSuspended(context: Context): Tracklist {
return suspendCoroutine {cont -> return suspendCoroutine {cont ->
@ -314,7 +328,20 @@ object FileHelper {
} }
/* Deletes track */ /* Deletes multiple tracks track */
private fun deleteTracks(context: Context, tracklistElements: MutableList<TracklistElement>, tracklist: Tracklist): Tracklist {
tracklistElements.forEach { tracklistElement ->
// delete track files
tracklistElement.trackUriString.toUri().toFile().delete()
tracklistElement.gpxUriString.toUri().toFile().delete()
}
tracklist.tracklistElements.removeAll{ tracklistElements.contains(it) }
saveTracklist(context, tracklist, GregorianCalendar.getInstance().time)
return tracklist
}
/* Deletes one track */
private fun deleteTrack(context: Context, position: Int, tracklist: Tracklist): Tracklist { private fun deleteTrack(context: Context, position: Int, tracklist: Tracklist): Tracklist {
val tracklistElement: TracklistElement = tracklist.tracklistElements[position] val tracklistElement: TracklistElement = tracklist.tracklistElements[position]
// delete track files // delete track files

View File

@ -65,8 +65,8 @@
<string name="dialog_rename_track_button">Renommer</string> <string name="dialog_rename_track_button">Renommer</string>
<string name="dialog_rename_track_input_hint">Entrez un nouveau nom</string> <string name="dialog_rename_track_input_hint">Entrez un nouveau nom</string>
<string name="dialog_yes_no_positive_button_default">Oui</string> <string name="dialog_yes_no_positive_button_default">Oui</string>
<string name="dialog_yes_no_positive_button_remove_recording">Supprimer</string> <string name="dialog_yes_no_positive_button_delete_recording">Supprimer</string>
<string name="dialog_yes_no_message_remove_recording">Supprimer cet enregistrement \?</string> <string name="dialog_yes_no_message_delete_recording">Supprimer cet enregistrement \?</string>
<string name="pref_accuracy_threshold_summary">Annuler les corrections d\'emplacement avec une précision supérieure à :</string> <string name="pref_accuracy_threshold_summary">Annuler les corrections d\'emplacement avec une précision supérieure à :</string>
<string name="pref_accuracy_threshold_title">Seuil de précision</string> <string name="pref_accuracy_threshold_title">Seuil de précision</string>
<string name="pref_advanced_title">Avancé</string> <string name="pref_advanced_title">Avancé</string>

View File

@ -65,8 +65,8 @@
<string name="dialog_rename_track_button">Rinomina</string> <string name="dialog_rename_track_button">Rinomina</string>
<string name="dialog_rename_track_input_hint">Inserisci un nuovo nome</string> <string name="dialog_rename_track_input_hint">Inserisci un nuovo nome</string>
<string name="dialog_yes_no_positive_button_default"></string> <string name="dialog_yes_no_positive_button_default"></string>
<string name="dialog_yes_no_positive_button_remove_recording">Rimuovi</string> <string name="dialog_yes_no_positive_button_delete_recording">Rimuovi</string>
<string name="dialog_yes_no_message_remove_recording">Rimuovere questa registrazione\?</string> <string name="dialog_yes_no_message_delete_recording">Rimuovere questa registrazione\?</string>
<string name="pref_accuracy_threshold_summary">Elimina le correzioni di posizione con una precisione maggiore di:</string> <string name="pref_accuracy_threshold_summary">Elimina le correzioni di posizione con una precisione maggiore di:</string>
<string name="pref_accuracy_threshold_title">Soglia della precisione</string> <string name="pref_accuracy_threshold_title">Soglia della precisione</string>
<string name="pref_advanced_title">Avanzate</string> <string name="pref_advanced_title">Avanzate</string>

View File

@ -65,8 +65,8 @@
<string name="dialog_rename_track_button">Gi nytt navn</string> <string name="dialog_rename_track_button">Gi nytt navn</string>
<string name="dialog_rename_track_input_hint">Skriv inn nytt navn</string> <string name="dialog_rename_track_input_hint">Skriv inn nytt navn</string>
<string name="dialog_yes_no_positive_button_default">Ja</string> <string name="dialog_yes_no_positive_button_default">Ja</string>
<string name="dialog_yes_no_positive_button_remove_recording">Fjern</string> <string name="dialog_yes_no_positive_button_delete_recording">Fjern</string>
<string name="dialog_yes_no_message_remove_recording">Fjern dette opptaket\?</string> <string name="dialog_yes_no_message_delete_recording">Fjern dette opptaket\?</string>
<string name="pref_accuracy_threshold_summary">Forkast posisjonsendringer med nøyaktighet større enn</string> <string name="pref_accuracy_threshold_summary">Forkast posisjonsendringer med nøyaktighet større enn</string>
<string name="pref_accuracy_threshold_title">Nøyaktighetsterskel</string> <string name="pref_accuracy_threshold_title">Nøyaktighetsterskel</string>
<string name="pref_advanced_title">Avansert</string> <string name="pref_advanced_title">Avansert</string>

View File

@ -65,8 +65,8 @@
<string name="dialog_rename_track_button">Naam wijzigen</string> <string name="dialog_rename_track_button">Naam wijzigen</string>
<string name="dialog_rename_track_input_hint">Voer een naam in</string> <string name="dialog_rename_track_input_hint">Voer een naam in</string>
<string name="dialog_yes_no_positive_button_default">Ja</string> <string name="dialog_yes_no_positive_button_default">Ja</string>
<string name="dialog_yes_no_positive_button_remove_recording">Verwijderen</string> <string name="dialog_yes_no_positive_button_delete_recording">Verwijderen</string>
<string name="dialog_yes_no_message_remove_recording">Wil je deze opname verwijderen\?</string> <string name="dialog_yes_no_message_delete_recording">Wil je deze opname verwijderen\?</string>
<string name="pref_accuracy_threshold_summary">Locatie-aanpassingen verwerpen indien nauwkeurigheid hoger is dan:</string> <string name="pref_accuracy_threshold_summary">Locatie-aanpassingen verwerpen indien nauwkeurigheid hoger is dan:</string>
<string name="pref_accuracy_threshold_title">Nauwkeurigheidsdrempelwaarde</string> <string name="pref_accuracy_threshold_title">Nauwkeurigheidsdrempelwaarde</string>
<string name="pref_advanced_title">Geavanceerd</string> <string name="pref_advanced_title">Geavanceerd</string>

View File

@ -34,8 +34,8 @@
<string name="dialog_rename_track_input_hint">输入一个新名称</string> <string name="dialog_rename_track_input_hint">输入一个新名称</string>
<string name="dialog_share_gpx">分享GPX文件到</string> <string name="dialog_share_gpx">分享GPX文件到</string>
<string name="dialog_yes_no_positive_button_default"></string> <string name="dialog_yes_no_positive_button_default"></string>
<string name="dialog_yes_no_positive_button_remove_recording">删除</string> <string name="dialog_yes_no_positive_button_delete_recording">删除</string>
<string name="dialog_yes_no_message_remove_recording">删除此记录?</string> <string name="dialog_yes_no_message_delete_recording">删除此记录?</string>
<!-- Toast Messages --> <!-- Toast Messages -->
<string name="toast_message_elevation_info">提示:海拔数据的准确性取决于您的设备.测量整个路线的上坡和下坡海拔.</string> <string name="toast_message_elevation_info">提示:海拔数据的准确性取决于您的设备.测量整个路线的上坡和下坡海拔.</string>
<string name="toast_message_install_file_helper">请先安装一个文件管理器或GPX轨迹查看器.</string> <string name="toast_message_install_file_helper">请先安装一个文件管理器或GPX轨迹查看器.</string>

View File

@ -34,8 +34,10 @@
<string name="dialog_rename_track_input_hint">Enter a new name</string> <string name="dialog_rename_track_input_hint">Enter a new name</string>
<string name="dialog_share_gpx">Share GPX file with</string> <string name="dialog_share_gpx">Share GPX file with</string>
<string name="dialog_yes_no_positive_button_default">Yes</string> <string name="dialog_yes_no_positive_button_default">Yes</string>
<string name="dialog_yes_no_positive_button_remove_recording">Remove</string> <string name="dialog_yes_no_positive_button_delete_recording">Delete</string>
<string name="dialog_yes_no_message_remove_recording">Remove this recording?</string> <string name="dialog_yes_no_positive_button_delete_non_starred">Delete</string>
<string name="dialog_yes_no_message_delete_non_starred">Delete all non-starred recordings? This action cannot be undone.</string>
<string name="dialog_yes_no_message_delete_recording">Delete this recording?</string>
<!-- Toast Messages --> <!-- Toast Messages -->
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string> <string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
<string name="toast_message_install_file_helper">Please install a file manager or a GPX track viewer first.</string> <string name="toast_message_install_file_helper">Please install a file manager or a GPX track viewer first.</string>
@ -69,7 +71,10 @@
<string name="pref_accuracy_threshold_summary">Discard location fixes with an accuracy larger than:</string> <string name="pref_accuracy_threshold_summary">Discard location fixes with an accuracy larger than:</string>
<string name="pref_accuracy_threshold_title">Accuracy Threshold</string> <string name="pref_accuracy_threshold_title">Accuracy Threshold</string>
<string name="pref_advanced_title">Advanced</string> <string name="pref_advanced_title">Advanced</string>
<string name="pref_delete_non_starred_summary">Delete all recordings in \"Tracks\" that are not starred.</string>
<string name="pref_delete_non_starred_title">Delete Non-Starred Recordings</string>
<string name="pref_general_title">General</string> <string name="pref_general_title">General</string>
<string name="pref_maintenance_title">Maintenance</string>
<string name="pref_gps_only_title">Restrict to GPS</string> <string name="pref_gps_only_title">Restrict to GPS</string>
<string name="pref_gps_only_summary_gps_and_network">Currently using GPS and Network for localization.</string> <string name="pref_gps_only_summary_gps_and_network">Currently using GPS and Network for localization.</string>
<string name="pref_gps_only_summary_gps_only">Currently using only GPS for localization.</string> <string name="pref_gps_only_summary_gps_only">Currently using only GPS for localization.</string>