diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt index 977951374..dfeebc180 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt @@ -10,6 +10,7 @@ import android.view.Menu import android.view.MenuItem import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.Utils +import com.simplemobiletools.gallery.dialogs.SaveAsDialog import com.simplemobiletools.gallery.extensions.toast import com.theartofdev.edmodo.cropper.CropImageView import kotlinx.android.synthetic.main.activity_edit.* @@ -20,6 +21,8 @@ import java.io.OutputStream class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener { val TAG: String = EditActivity::class.java.simpleName + + var overrideOriginal = false lateinit var uri: Uri override fun onCreate(savedInstanceState: Bundle?) { @@ -54,6 +57,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.save -> { + overrideOriginal = true crop_image_view.getCroppedImageAsync() true } @@ -70,17 +74,38 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener } private fun saveAs() { - + overrideOriginal = false + crop_image_view.getCroppedImageAsync() } override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) { if (result.error == null) { if (uri.scheme == "file") { - saveBitmapToFile(result.bitmap, uri.path) + if (overrideOriginal) + saveBitmapToFile(result.bitmap, uri.path) + else { + SaveAsDialog(this, uri.path, object : SaveAsDialog.OnSaveAsListener { + override fun onSaveAsSuccess(filename: String) { + val parent = File(uri.path).parent + val path = File(parent, filename).absolutePath + saveBitmapToFile(result.bitmap, path) + } + }) + } } else if (uri.scheme == "content") { val newPath = Utils.getRealPathFromURI(applicationContext, uri) ?: "" if (!newPath.isEmpty()) { - saveBitmapToFile(result.bitmap, newPath) + if (overrideOriginal) { + saveBitmapToFile(result.bitmap, newPath) + } else { + SaveAsDialog(this, newPath, object : SaveAsDialog.OnSaveAsListener { + override fun onSaveAsSuccess(filename: String) { + val parent = File(uri.path).parent + val path = File(parent, filename).absolutePath + saveBitmapToFile(result.bitmap, path) + } + }) + } } else { toast(R.string.image_editing_failed) finish() @@ -96,7 +121,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener private fun saveBitmapToFile(bitmap: Bitmap, path: String) { val file = File(path) - if (!file.exists()) { + if (overrideOriginal && !file.exists()) { toast(R.string.error_saving_file) finish() return @@ -108,7 +133,10 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener if (Utils.isShowingWritePermissions(this, file)) return - val document = Utils.getFileDocument(this, path) + var document = Utils.getFileDocument(this, path) + if (!file.exists()) { + document = document.createFile("", file.name) + } out = contentResolver.openOutputStream(document.uri) } else { out = FileOutputStream(file) @@ -117,7 +145,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener bitmap.compress(getCompressionFormat(file), 90, out) setResult(Activity.RESULT_OK, intent) } catch (e: Exception) { - Log.e(TAG, "Crop compressing failed $e") + Log.e(TAG, "Crop compressing failed $path $e") toast(R.string.image_editing_failed) finish() } finally { @@ -130,7 +158,12 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener MediaScannerConnection.scanFile(applicationContext, arrayOf(path), null, { path: String, uri: Uri -> setResult(Activity.RESULT_OK, intent) - finish() + runOnUiThread { + toast(R.string.file_saved) + } + + if (overrideOriginal) + finish() }) } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt index e39373014..fe35b1f1f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt @@ -43,7 +43,7 @@ class RenameFileDialog(val activity: Activity, val file: File, val listener: OnR val extension = view.file_extension.value if (fileName.isEmpty() || extension.isEmpty()) { - context.toast(R.string.rename_file_empty) + context.toast(R.string.filename_cannot_be_empty) return@setOnClickListener } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt new file mode 100644 index 000000000..7c5c0bf80 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt @@ -0,0 +1,51 @@ +package com.simplemobiletools.gallery.dialogs + +import android.app.Activity +import android.support.v7.app.AlertDialog +import android.view.LayoutInflater +import android.view.WindowManager +import com.simplemobiletools.filepicker.extensions.getFilenameFromPath +import com.simplemobiletools.gallery.R +import com.simplemobiletools.gallery.extensions.isNameValid +import com.simplemobiletools.gallery.extensions.toast +import com.simplemobiletools.gallery.extensions.value +import kotlinx.android.synthetic.main.rename_file.view.* + +class SaveAsDialog(val activity: Activity, val path: String, val listener: OnSaveAsListener) { + + init { + val context = activity + val view = LayoutInflater.from(context).inflate(R.layout.dialog_save_as, null) + view.file_name.setText(path.getFilenameFromPath()) + + AlertDialog.Builder(context) + .setTitle(context.resources.getString(R.string.save_as)) + .setView(view) + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.cancel, null) + .create().apply { + window!!.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + show() + getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener({ + val filename = view.file_name.value + + if (filename.isEmpty()) { + context.toast(R.string.filename_cannot_be_empty) + return@setOnClickListener + } + + if (!filename.isNameValid()) { + context.toast(R.string.filename_invalid_characters) + return@setOnClickListener + } + + listener.onSaveAsSuccess(filename) + dismiss() + }) + } + } + + interface OnSaveAsListener { + fun onSaveAsSuccess(filename: String) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/string.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/string.kt new file mode 100644 index 000000000..3ad03ec42 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/string.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.gallery.extensions + +import java.util.regex.Pattern + +fun String.isNameValid(): Boolean { + val pattern = Pattern.compile("^[-_.A-Za-z0-9()#& ]+$") + val matcher = pattern.matcher(this) + return matcher.matches() +} diff --git a/app/src/main/res/layout/dialog_save_as.xml b/app/src/main/res/layout/dialog_save_as.xml new file mode 100644 index 000000000..1e224d9d7 --- /dev/null +++ b/app/src/main/res/layout/dialog_save_as.xml @@ -0,0 +1,16 @@ + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 13e665cea..37c75b55f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -13,11 +13,12 @@ Datei umbenennen Ordner umbenennen Konnte die Datei nicht umbenennen - Dateiname darf nicht leer sein Konnte den Ordner nicht umbenennen Ordnername darf nicht leer sein Ordner erfolgreich umbenannt Benenne Ordner um + Dateiname darf nicht leer sein + Filename contains invalid characters Dateiendung Datei gelöscht Kamera öffnen @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 Ordner gelöscht diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 9f31fdb64..525e193e2 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -13,11 +13,12 @@ Renombrar archivo Renombrar carpeta No se pudo renombrar el archivo - El nombre de archivo no puede estar vacío No se pudo renombrar la carpeta El nombre de carpeta no puede estar vacío Carpeta renombrada correctamente Renombrando carpeta + El nombre de archivo no puede estar vacío + Filename contains invalid characters Extensión Archivo eliminado Abrir cámara @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 carpeta eliminada diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index c2da02165..c2ffa03a4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -13,11 +13,12 @@ Rinomina file Rinomina cartella Impossibile rinominare il file - Il nome del file non deve essere vuoto Impossibile rinominare la cartella Il nome della cartella non deve essere vuoto Cartella rinominata correttamente Rinominazione cartella + Il nome del file non deve essere vuoto + Filename contains invalid characters Estensione File eliminato Apri fotocamera @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 cartella eliminata diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 5a2778c19..0ec1fece6 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -13,11 +13,12 @@ ファイルの名前を変更 フォルダーの名前を変更 ファイルの名前を変更できませんでした - ファイル名は空にできません フォルダーの名前を変更できませんでした フォルダー名は空にできません フォルダーの名前を正常に変更しました フォルダーの名前を変更中 + ファイル名は空にできません + Filename contains invalid characters 拡張 ファイルを削除しました カメラを開く @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 フォルダーを削除しました diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 1aa782bbe..9265c4201 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -13,11 +13,12 @@ Renomear ficheiro Renomear pasta Não foi possível renomear o ficheiro - O nome do ficheiro não pode ficar em branco Não foi possível renomear a pasta O nome da pasta não pode ficar em branco A pasta foi renomeada com sucesso A renomear pasta + O nome do ficheiro não pode ficar em branco + Filename contains invalid characters Extensão Ficheiro eliminado Abrir câmara @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 pasta eliminada diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 764fa21b0..19dd867d6 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -13,11 +13,12 @@ Döp om fil Döp om mapp Det gick inte att döpa om filen - Du måste ange ett filnamn Det gick inte att döpa om mappen Du måste ange ett mappnamn Mappen döptes om Döper om mappen + Du måste ange ett filnamn + Filename contains invalid characters Filändelse Fil borttagen Starta kameran @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 mapp borttagen diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9ee0e69e9..635446143 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,11 +13,12 @@ Rename file Rename folder Could not rename the file - File name must not be empty Could not rename the folder Folder name must not be empty Folder renamed successfully Renaming folder + Filename cannot be empty + Filename contains invalid characters Extension File deleted Open camera @@ -38,6 +39,7 @@ Confirm external storage access Please choose the root folder of the SD card to grant write access on the next screen Save as + File saved successfully 1 folder deleted