From a5bac9311ef0de8b2ccaacaf7f889f1be547e289 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 12 Mar 2017 21:27:45 +0100 Subject: [PATCH] tweaking some file related operations --- app/build.gradle | 2 +- .../gallery/activities/EditActivity.kt | 42 ++++++----- .../gallery/activities/MainActivity.kt | 48 +++---------- .../gallery/activities/MediaActivity.kt | 30 ++------ .../gallery/activities/ViewPagerActivity.kt | 69 ++++++------------- .../gallery/adapters/DirectoryAdapter.kt | 38 +++++----- .../gallery/adapters/MediaAdapter.kt | 30 +++----- .../gallery/dialogs/CopyDialog.kt | 51 +++++++------- .../gallery/dialogs/RenameDirectoryDialog.kt | 15 ++-- .../gallery/dialogs/RenameFileDialog.kt | 19 +++-- .../gallery/extensions/activity.kt | 20 ++---- .../gallery/extensions/context.kt | 8 +-- 12 files changed, 140 insertions(+), 232 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c4c7471c6..795bd43ec 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,7 +32,7 @@ android { } dependencies { - compile 'com.simplemobiletools:commons:2.9.9' + compile 'com.simplemobiletools:commons:2.10.5' compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0' compile 'com.theartofdev.edmodo:android-image-cropper:2.3.1' compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' 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 ac04d6ca1..92675b824 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/EditActivity.kt @@ -122,38 +122,42 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener private fun saveBitmapToFile(bitmap: Bitmap, path: String) { val file = File(path) - var out: OutputStream? = null try { if (needsStupidWritePermissions(path)) { - if (isShowingPermDialog(file)) - return - - var document = getFileDocument(path, config.treeUri) ?: return - if (!file.exists()) { - document = document.createFile("", file.name) + handleSAFDialog(file) { + var document = getFileDocument(path, config.treeUri) ?: return@handleSAFDialog + if (!file.exists()) { + document = document.createFile("", file.name) + } + val out = contentResolver.openOutputStream(document.uri) + saveBitmap(file, bitmap, out) } - out = contentResolver.openOutputStream(document.uri) } else { - out = FileOutputStream(file) + val out = FileOutputStream(file) + saveBitmap(file, bitmap, out) } - - if (resizeWidth > 0 && resizeHeight > 0) { - val resized = Bitmap.createScaledBitmap(bitmap, resizeWidth, resizeHeight, false) - resized.compress(file.getCompressionFormat(), 90, out) - } else { - bitmap.compress(file.getCompressionFormat(), 90, out) - } - setResult(Activity.RESULT_OK, intent) } catch (e: Exception) { Log.e(TAG, "Crop compressing failed $path $e") toast(R.string.image_editing_failed) finish() } catch (e: OutOfMemoryError) { toast(R.string.out_of_memory_error) - } finally { - out?.close() } + } + private fun saveBitmap(file: File, bitmap: Bitmap, out: OutputStream) { + if (resizeWidth > 0 && resizeHeight > 0) { + val resized = Bitmap.createScaledBitmap(bitmap, resizeWidth, resizeHeight, false) + resized.compress(file.getCompressionFormat(), 90, out) + } else { + bitmap.compress(file.getCompressionFormat(), 90, out) + } + setResult(Activity.RESULT_OK, intent) + scanFinalPath(file.absolutePath) + out.close() + } + + private fun scanFinalPath(path: String) { scanPath(path) { setResult(Activity.RESULT_OK, intent) runOnUiThread { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt index 727edb2db..f509f1ed0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt @@ -19,13 +19,15 @@ import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.adapters.DirectoryAdapter import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog -import com.simplemobiletools.gallery.extensions.* +import com.simplemobiletools.gallery.extensions.config +import com.simplemobiletools.gallery.extensions.launchAbout +import com.simplemobiletools.gallery.extensions.launchCamera +import com.simplemobiletools.gallery.extensions.launchSettings import com.simplemobiletools.gallery.helpers.* import com.simplemobiletools.gallery.models.Directory import com.simplemobiletools.gallery.views.MyScalableRecyclerView import kotlinx.android.synthetic.main.activity_main.* import java.io.File -import java.net.URLDecoder import java.util.* class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { @@ -181,44 +183,14 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { } } - override fun deleteFiles(paths: ArrayList) { - val updatedFiles = ArrayList() - for (delPath in paths) { - val dir = File(delPath) - if (dir.exists()) { - val files = dir.listFiles() ?: continue - files.forEach { - if (it.isFile && it.isImageVideoGif()) { - updatedFiles.add(it) - deleteItem(it) - } - } - updatedFiles.add(dir) - if (dir.listFiles().isEmpty()) - deleteItem(dir) - } - } - - scanFiles(updatedFiles) {} - } - - private fun deleteItem(file: File) { - if (isShowingPermDialog(file)) { - return - } - - Thread({ - if (!file.delete()) { - val document = getFileDocument(file.absolutePath, config.treeUri) ?: return@Thread - - // double check we have the uri to the proper file path, not some parent folder - val uri = URLDecoder.decode(document.uri.toString(), "UTF-8") - val filename = URLDecoder.decode(file.absolutePath.getFilenameFromPath(), "UTF-8") - if (uri.endsWith(filename)) { - document.delete() + override fun tryDeleteFolders(folders: ArrayList) { + for (file in folders) { + deleteFolders(folders) { + runOnUiThread { + refreshItems() } } - }).start() + } } private fun handleZooming() { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt index 48f818bcd..20b547ab9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt @@ -29,7 +29,6 @@ import com.simplemobiletools.gallery.views.MyScalableRecyclerView import kotlinx.android.synthetic.main.activity_media.* import java.io.File import java.io.IOException -import java.util.* class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private val TAG = MediaActivity::class.java.simpleName @@ -268,32 +267,15 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { } override fun deleteFiles(files: ArrayList) { - if (isShowingPermDialog(files[0])) { - return - } - - Thread({ - var hadSuccess = false - files.filter { it.exists() && it.isImageVideoGif() } - .forEach { - if (it.delete() || tryFastDocumentDelete(it)) { - hadSuccess = true - } else { - val document = getFileDocument(it.absolutePath, config.treeUri) ?: return@forEach - if (document.isFile && document.delete()) { - hadSuccess = true - } - } - deleteFromMediaStore(it) - } - if (!hadSuccess) + val filtered = files.filter { it.exists() && it.isImageVideoGif() } as ArrayList + deleteFiles(filtered) { + if (!it) { runOnUiThread { toast(R.string.unknown_error_occurred) } - }).start() - - if (mMedia.isEmpty()) { - finish() + } else if (mMedia.isEmpty()) { + finish() + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt index 575902e37..228484cde 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt @@ -189,7 +189,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View private fun saveImageAs() { val currPath = getCurrentMedium()!!.path SaveAsDialog(this, currPath) { - var out: OutputStream? = null try { val file = File(it) if (file.exists()) { @@ -197,36 +196,38 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View return@SaveAsDialog } - var bitmap = BitmapFactory.decodeFile(currPath) + val bitmap = BitmapFactory.decodeFile(currPath) if (needsStupidWritePermissions(it)) { - if (isShowingPermDialog(file)) - return@SaveAsDialog - - var document = getFileDocument(it, config.treeUri) ?: return@SaveAsDialog - if (!file.exists()) { - document = document.createFile("", file.name) + handleSAFDialog(file) { + var document = getFileDocument(it, config.treeUri) ?: return@handleSAFDialog + if (!file.exists()) { + document = document.createFile("", file.name) + } + val out = contentResolver.openOutputStream(document.uri) + saveFile(file, bitmap, out) } - out = contentResolver.openOutputStream(document.uri) } else { - out = FileOutputStream(file) + val out = FileOutputStream(file) + saveFile(file, bitmap, out) } - - val matrix = Matrix() - matrix.postRotate(mRotationDegrees) - bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) - bitmap.compress(file.getCompressionFormat(), 90, out) - out?.flush() - toast(R.string.file_saved) } catch (e: OutOfMemoryError) { toast(R.string.out_of_memory_error) } catch (e: Exception) { toast(R.string.unknown_error_occurred) - } finally { - out?.close() } } } + private fun saveFile(file: File, bitmap: Bitmap, out: OutputStream) { + val matrix = Matrix() + matrix.postRotate(mRotationDegrees) + val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + bmp.compress(file.getCompressionFormat(), 90, out) + out.flush() + toast(R.string.file_saved) + out.close() + } + private fun rotateImage(degrees: Float) { mRotationDegrees = (mRotationDegrees + degrees) % 360 getCurrentFragment()?.rotateImageViewBy(mRotationDegrees) @@ -319,36 +320,10 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View private fun askConfirmDelete() { ConfirmationDialog(this) { - deleteFile() - } - } - - private fun deleteFile() { - val file = File(mMedia[mPos].path) - if (isShowingPermDialog(file)) { - return - } - - Thread { - if (!file.delete() && !tryFastDocumentDelete(file)) { - val document = getFileDocument(file.absolutePath, config.treeUri) ?: return@Thread - - if (!document.isFile || !document.delete()) { - runOnUiThread { - toast(R.string.unknown_error_occurred) - } - return@Thread - } - } - - if (deleteFromMediaStore(file)) { + deleteFileBg(File(mMedia[mPos].path)) { reloadViewPager() - } else { - scanFile(file) { - reloadViewPager() - } } - }.start() + } } private fun isDirEmpty(): Boolean { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt index 22e60d289..1c0c1ced1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt @@ -273,30 +273,30 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList(selections.size) - val removeDirs = ArrayList(selections.size) + val folders = ArrayList(selections.size) + val removeFolders = ArrayList(selections.size) - var isShowingPermDialog = false - activity.runOnUiThread { - if (activity.isShowingPermDialog(File(dirs[selections[0]].path))) { - isShowingPermDialog = true + var needPermissionForPath = "" + selections.forEach { + val path = dirs[it].path + if (activity.needsStupidWritePermissions(path) && activity.config.treeUri.isEmpty()) { + needPermissionForPath = path } } - if (isShowingPermDialog) - return + activity.handleSAFDialog(File(needPermissionForPath)) { + selections.reverse() + selections.forEach { + val directory = dirs[it] + folders.add(File(directory.path)) + removeFolders.add(directory) + notifyItemRemoved(it) + } - selections.reverse() - selections.forEach { - val directory = dirs[it] - paths.add(directory.path) - removeDirs.add(directory) - notifyItemRemoved(it) + dirs.removeAll(removeFolders) + markedItems.clear() + listener?.tryDeleteFolders(folders) } - - dirs.removeAll(removeDirs) - markedItems.clear() - listener?.deleteFiles(paths) } private fun getSelectedPaths(): HashSet { @@ -387,6 +387,6 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList) + fun tryDeleteFolders(folders: ArrayList) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt index e7a7b31bc..b40c792b1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt @@ -190,27 +190,19 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, val files = ArrayList(selections.size) val removeMedia = ArrayList(selections.size) - var isShowingPermDialog = false - activity.runOnUiThread { - if (activity.isShowingPermDialog(File(media[selections[0]].path))) { - isShowingPermDialog = true + activity.handleSAFDialog(File(media[selections[0]].path)) { + selections.reverse() + selections.forEach { + val medium = media[it] + files.add(File(medium.path)) + removeMedia.add(medium) + notifyItemRemoved(it) } + + media.removeAll(removeMedia) + markedItems.clear() + listener?.deleteFiles(files) } - - if (isShowingPermDialog) - return - - selections.reverse() - selections.forEach { - val medium = media[it] - files.add(File(medium.path)) - removeMedia.add(medium) - notifyItemRemoved(it) - } - - media.removeAll(removeMedia) - markedItems.clear() - listener?.deleteFiles(files) } private fun getSelectedMedia(): List { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/CopyDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/CopyDialog.kt index 9bb13ed8b..abf8a97d4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/CopyDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/CopyDialog.kt @@ -59,38 +59,35 @@ class CopyDialog(val activity: SimpleActivity, val files: ArrayList, val c } } - if (activity.isShowingPermDialog(destinationDir)) { - return@setOnClickListener - } - - if (view.dialog_radio_group.checkedRadioButtonId == R.id.dialog_radio_copy) { - context.toast(R.string.copying) - val pair = Pair, File>(files, destinationDir) - CopyMoveTask(context, false, context.config.treeUri, true, copyMoveListener).execute(pair) - dismiss() - } else { - if (context.isPathOnSD(sourcePath) || context.isPathOnSD(destinationPath)) { - if (activity.isShowingPermDialog(files[0])) { - return@setOnClickListener - } - - context.toast(R.string.moving) + activity.handleSAFDialog(destinationDir) { + if (view.dialog_radio_group.checkedRadioButtonId == R.id.dialog_radio_copy) { + context.toast(R.string.copying) val pair = Pair, File>(files, destinationDir) - CopyMoveTask(context, true, context.config.treeUri, true, copyMoveListener).execute(pair) + CopyMoveTask(activity, false, context.config.treeUri, true, copyMoveListener).execute(pair) dismiss() } else { - val updatedFiles = ArrayList(files.size * 2) - updatedFiles.addAll(files) - for (file in files) { - val destination = File(destinationDir, file.name) - if (file.renameTo(destination)) - updatedFiles.add(destination) - } - context.scanFiles(updatedFiles) { - activity.runOnUiThread { - copyMoveListener.copySucceeded(true, files.size * 2 == updatedFiles.size) + if (context.isPathOnSD(sourcePath) || context.isPathOnSD(destinationPath)) { + activity.handleSAFDialog(files[0]) { + context.toast(R.string.moving) + val pair = Pair, File>(files, destinationDir) + CopyMoveTask(activity, true, context.config.treeUri, true, copyMoveListener).execute(pair) dismiss() } + } else { + val updatedFiles = ArrayList(files.size * 2) + updatedFiles.addAll(files) + for (file in files) { + val destination = File(destinationDir, file.name) + if (file.renameTo(destination)) + updatedFiles.add(destination) + } + + context.scanFiles(updatedFiles) { + activity.runOnUiThread { + copyMoveListener.copySucceeded(true, files.size * 2 == updatedFiles.size) + dismiss() + } + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameDirectoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameDirectoryDialog.kt index 6a6539c24..41ce6b85e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameDirectoryDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameDirectoryDialog.kt @@ -46,14 +46,13 @@ class RenameDirectoryDialog(val activity: SimpleActivity, val dir: File, val cal } if (context.needsStupidWritePermissions(dir.absolutePath)) { - if (activity.isShowingPermDialog(dir)) - return@setOnClickListener - - val document = context.getFileDocument(dir.absolutePath, context.config.treeUri) ?: return@setOnClickListener - if (document.canWrite()) - document.renameTo(newDirName) - sendSuccess(updatedFiles, newDir) - dismiss() + activity.handleSAFDialog(dir) { + val document = context.getFileDocument(dir.absolutePath, context.config.treeUri) ?: return@handleSAFDialog + if (document.canWrite()) + document.renameTo(newDirName) + sendSuccess(updatedFiles, newDir) + dismiss() + } } else if (dir.renameTo(newDir)) { sendSuccess(updatedFiles, newDir) dismiss() 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 bd1c62caf..23f23ccb2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/RenameFileDialog.kt @@ -26,7 +26,7 @@ class RenameFileDialog(val activity: SimpleActivity, val file: File, val callbac } view.file_name.setText(name) - view.file_path.text = "${activity.humanizePath(file.parent)}/" + view.file_path.text = activity.humanizePath(file.parent) + "/" AlertDialog.Builder(activity) .setPositiveButton(R.string.ok, null) @@ -55,17 +55,16 @@ class RenameFileDialog(val activity: SimpleActivity, val file: File, val callbac } if (context.needsStupidWritePermissions(file.absolutePath)) { - if (activity.isShowingPermDialog(file)) - return@setOnClickListener + activity.handleSAFDialog(file) { + var document = context.getFastDocument(file) + if (document?.isFile == false) { + document = context.getFileDocument(file.absolutePath, context.config.treeUri) + } - var document = context.getFastDocument(file) - if (document?.isFile == false) { - document = context.getFileDocument(file.absolutePath, context.config.treeUri) + DocumentsContract.renameDocument(context.contentResolver, document!!.uri, newFile.name) + sendSuccess(file, newFile) + dismiss() } - - DocumentsContract.renameDocument(context.contentResolver, document!!.uri, newFile.name) - sendSuccess(file, newFile) - dismiss() } else if (file.renameTo(newFile)) { sendSuccess(file, newFile) dismiss() diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt index c37c76e40..a5a298635 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt @@ -161,7 +161,7 @@ fun SimpleActivity.addNoMedia(path: String, callback: () -> Unit) { return if (needsStupidWritePermissions(path)) { - if (!isShowingPermDialog(file)) { + handleSAFDialog(file) { getFileDocument(path, config.treeUri)?.createFile("", NOMEDIA) } } else { @@ -174,21 +174,9 @@ fun SimpleActivity.addNoMedia(path: String, callback: () -> Unit) { fun SimpleActivity.removeNoMedia(path: String, callback: () -> Unit) { val file = File(path, NOMEDIA) - if (!file.exists()) - return - - if (!file.delete() && !tryFastDocumentDelete(file)) { - if (needsStupidWritePermissions(path)) { - if (!isShowingPermDialog(file)) { - getFileDocument(path, config.treeUri)?.apply { - if (isFile) { - delete() - } - } - } + deleteFile(file) { + scanFile(File(path)) { + callback() } } - scanFile(file) { - callback.invoke() - } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt index 0012b1a06..c446567b2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt @@ -70,6 +70,10 @@ fun Context.getParents(): ArrayList { val noMediaFolders = getNoMediaFolders() val parents = ArrayList() + if (config.showHiddenFolders) { + parentsSet.addAll(noMediaFolders) + } + parentsSet.filterTo(parents, { if (File(it).isDirectory) { if (!config.showHiddenFolders) { @@ -81,10 +85,6 @@ fun Context.getParents(): ArrayList { } }) - if (config.showHiddenFolders) { - parents.addAll(noMediaFolders) - } - return parents }