fix #2308, add a setting item for exporting favorites

This commit is contained in:
tibbi 2023-01-14 19:26:34 +01:00
parent 9d5908ab75
commit 6fac277bbb
6 changed files with 213 additions and 0 deletions

View file

@ -1,9 +1,11 @@
package com.simplemobiletools.gallery.pro.activities package com.simplemobiletools.gallery.pro.activities
import android.app.Activity import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.widget.Toast
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.simplemobiletools.commons.dialogs.* import com.simplemobiletools.commons.dialogs.*
@ -18,11 +20,13 @@ import com.simplemobiletools.gallery.pro.models.AlbumCover
import kotlinx.android.synthetic.main.activity_settings.* import kotlinx.android.synthetic.main.activity_settings.*
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream
import java.util.* import java.util.*
import kotlin.system.exitProcess import kotlin.system.exitProcess
class SettingsActivity : SimpleActivity() { class SettingsActivity : SimpleActivity() {
private val PICK_IMPORT_SOURCE_INTENT = 1 private val PICK_IMPORT_SOURCE_INTENT = 1
private val SELECT_EXPORT_FAVORITES_FILE_INTENT = 2
private var mRecycleBinContentSize = 0L private var mRecycleBinContentSize = 0L
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -91,6 +95,7 @@ class SettingsActivity : SimpleActivity() {
setupEmptyRecycleBin() setupEmptyRecycleBin()
updateTextColors(settings_holder) updateTextColors(settings_holder)
setupClearCache() setupClearCache()
setupExportFavorites()
setupExportSettings() setupExportSettings()
setupImportSettings() setupImportSettings()
@ -118,6 +123,9 @@ class SettingsActivity : SimpleActivity() {
if (requestCode == PICK_IMPORT_SOURCE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) { if (requestCode == PICK_IMPORT_SOURCE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
val inputStream = contentResolver.openInputStream(resultData.data!!) val inputStream = contentResolver.openInputStream(resultData.data!!)
parseFile(inputStream) parseFile(inputStream)
} else if (requestCode == SELECT_EXPORT_FAVORITES_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
val outputStream = contentResolver.openOutputStream(resultData.data!!)
exportFavoritesTo(outputStream)
} }
} }
@ -704,6 +712,66 @@ class SettingsActivity : SimpleActivity() {
} }
} }
private fun setupExportFavorites() {
settings_export_favorites_holder.setOnClickListener {
if (isQPlus()) {
ExportFavoritesDialog(this, getExportFavoritesFilename(), true) { path, filename ->
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TITLE, filename)
addCategory(Intent.CATEGORY_OPENABLE)
try {
startActivityForResult(this, SELECT_EXPORT_FAVORITES_FILE_INTENT)
} catch (e: ActivityNotFoundException) {
toast(R.string.system_service_disabled, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
} else {
handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) {
ExportFavoritesDialog(this, getExportFavoritesFilename(), false) { path, filename ->
val file = File(path)
getFileOutputStream(file.toFileDirItem(this), true) {
exportFavoritesTo(it)
}
}
}
}
}
}
}
private fun exportFavoritesTo(outputStream: OutputStream?) {
if (outputStream == null) {
toast(R.string.unknown_error_occurred)
return
}
ensureBackgroundThread {
val favoritePaths = favoritesDB.getValidFavoritePaths()
if (favoritePaths.isNotEmpty()) {
outputStream.bufferedWriter().use { out ->
favoritePaths.forEach { path ->
out.writeLn(path)
}
}
toast(R.string.exporting_successful)
} else {
toast(R.string.no_items_found)
}
}
}
private fun getExportFavoritesFilename(): String {
val appName = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro").removePrefix("com.simplemobiletools.")
return "$appName-favorites_${getCurrentFormattedDateTime()}"
}
private fun setupExportSettings() { private fun setupExportSettings() {
settings_export_holder.setOnClickListener { settings_export_holder.setOnClickListener {
val configItems = LinkedHashMap<String, Any>().apply { val configItems = LinkedHashMap<String, Any>().apply {

View file

@ -0,0 +1,75 @@
package com.simplemobiletools.gallery.pro.dialogs
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.config
import kotlinx.android.synthetic.main.dialog_export_favorites.view.*
class ExportFavoritesDialog(
val activity: BaseSimpleActivity, val defaultFilename: String, val hidePath: Boolean,
callback: (path: String, filename: String) -> Unit
) {
init {
val lastUsedFolder = activity.config.lastExportedFavoritesFolder
var folder = if (lastUsedFolder.isNotEmpty() && activity.getDoesFilePathExist(lastUsedFolder)) {
lastUsedFolder
} else {
activity.internalStoragePath
}
val view = activity.layoutInflater.inflate(R.layout.dialog_export_favorites, null).apply {
export_favorites_filename.setText(defaultFilename.removeSuffix(".txt"))
if (hidePath) {
export_favorites_path_label.beGone()
export_favorites_path.beGone()
} else {
export_favorites_path.text = activity.humanizePath(folder)
export_favorites_path.setOnClickListener {
FilePickerDialog(activity, folder, false, showFAB = true) {
export_favorites_path.text = activity.humanizePath(it)
folder = it
}
}
}
}
activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.apply {
activity.setupDialogStuff(view, this, R.string.export_favorite_paths) { alertDialog ->
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
var filename = view.export_favorites_filename.value
if (filename.isEmpty()) {
activity.toast(R.string.filename_cannot_be_empty)
return@setOnClickListener
}
filename += ".txt"
val newPath = "${folder.trimEnd('/')}/$filename"
if (!newPath.getFilenameFromPath().isAValidFilename()) {
activity.toast(R.string.filename_invalid_characters)
return@setOnClickListener
}
activity.config.lastExportedFavoritesFolder = folder
if (!hidePath && activity.getDoesFilePathExist(newPath)) {
val title = String.format(activity.getString(R.string.file_already_exists_overwrite), newPath.getFilenameFromPath())
ConfirmationDialog(activity, title) {
callback(newPath, filename)
alertDialog.dismiss()
}
} else {
callback(newPath, filename)
alertDialog.dismiss()
}
}
}
}
}
}

View file

@ -554,4 +554,8 @@ class Config(context: Context) : BaseConfig(context) {
var searchAllFilesByDefault: Boolean var searchAllFilesByDefault: Boolean
get() = prefs.getBoolean(SEARCH_ALL_FILES_BY_DEFAULT, false) get() = prefs.getBoolean(SEARCH_ALL_FILES_BY_DEFAULT, false)
set(searchAllFilesByDefault) = prefs.edit().putBoolean(SEARCH_ALL_FILES_BY_DEFAULT, searchAllFilesByDefault).apply() set(searchAllFilesByDefault) = prefs.edit().putBoolean(SEARCH_ALL_FILES_BY_DEFAULT, searchAllFilesByDefault).apply()
var lastExportedFavoritesFolder: String
get() = prefs.getString(LAST_EXPORTED_FAVORITES_FOLDER, "")!!
set(lastExportedFavoritesFolder) = prefs.edit().putString(LAST_EXPORTED_FAVORITES_FOLDER, lastExportedFavoritesFolder).apply()
} }

View file

@ -98,6 +98,7 @@ const val FILE_ROUNDED_CORNERS = "file_rounded_corners"
const val CUSTOM_FOLDERS_ORDER = "custom_folders_order" const val CUSTOM_FOLDERS_ORDER = "custom_folders_order"
const val AVOID_SHOWING_ALL_FILES_PROMPT = "avoid_showing_all_files_prompt" const val AVOID_SHOWING_ALL_FILES_PROMPT = "avoid_showing_all_files_prompt"
const val SEARCH_ALL_FILES_BY_DEFAULT = "search_all_files_by_default" const val SEARCH_ALL_FILES_BY_DEFAULT = "search_all_files_by_default"
const val LAST_EXPORTED_FAVORITES_FOLDER = "last_exported_favorites_folder"
// slideshow // slideshow
const val SLIDESHOW_INTERVAL = "slideshow_interval" const val SLIDESHOW_INTERVAL = "slideshow_interval"

View file

@ -952,6 +952,21 @@
</RelativeLayout> </RelativeLayout>
<RelativeLayout
android:id="@+id/settings_export_favorites_holder"
style="@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_export_favorites"
style="@style/SettingsTextLabelStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/export_favorite_paths" />
</RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/settings_export_holder" android:id="@+id/settings_export_holder"
style="@style/SettingsHolderTextViewOneLinerStyle" style="@style/SettingsHolderTextViewOneLinerStyle"

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/export_favorites_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/export_favorites_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/export_favorites_path_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/small_margin"
android:text="@string/path"
android:textSize="@dimen/smaller_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/export_favorites_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/small_margin"
android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:paddingBottom="@dimen/activity_margin" />
<com.simplemobiletools.commons.views.MyTextInputLayout
android:id="@+id/export_favorites_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/filename_without_txt">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/export_favorites_filename"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_margin"
android:singleLine="true"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size" />
</com.simplemobiletools.commons.views.MyTextInputLayout>
</LinearLayout>
</ScrollView>