tweaking some file related operations

This commit is contained in:
tibbi 2017-03-12 21:27:45 +01:00
parent 8ebdc91649
commit a5bac9311e
12 changed files with 140 additions and 232 deletions

View file

@ -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'

View file

@ -122,21 +122,30 @@ 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
handleSAFDialog(file) {
var document = getFileDocument(path, config.treeUri) ?: return@handleSAFDialog
if (!file.exists()) {
document = document.createFile("", file.name)
}
out = contentResolver.openOutputStream(document.uri)
val out = contentResolver.openOutputStream(document.uri)
saveBitmap(file, bitmap, out)
}
} else {
out = FileOutputStream(file)
val out = FileOutputStream(file)
saveBitmap(file, bitmap, out)
}
} 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)
}
}
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)
@ -144,16 +153,11 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
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()
scanFinalPath(file.absolutePath)
out.close()
}
private fun scanFinalPath(path: String) {
scanPath(path) {
setResult(Activity.RESULT_OK, intent)
runOnUiThread {

View file

@ -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,46 +183,16 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
}
}
override fun deleteFiles(paths: ArrayList<String>) {
val updatedFiles = ArrayList<File>()
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)
override fun tryDeleteFolders(folders: ArrayList<File>) {
for (file in folders) {
deleteFolders(folders) {
runOnUiThread {
refreshItems()
}
}
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()
}
}
}).start()
}
private fun handleZooming() {
val layoutManager = directories_grid.layoutManager as GridLayoutManager
layoutManager.spanCount = config.dirColumnCnt

View file

@ -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,34 +267,17 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
}
override fun deleteFiles(files: ArrayList<File>) {
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()) {
} else if (mMedia.isEmpty()) {
finish()
}
}
}
private fun isSetWallpaperIntent() = intent.getBooleanExtra(SET_WALLPAPER_INTENT, false)

View file

@ -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
handleSAFDialog(file) {
var document = getFileDocument(it, config.treeUri) ?: return@handleSAFDialog
if (!file.exists()) {
document = document.createFile("", file.name)
}
out = contentResolver.openOutputStream(document.uri)
} else {
out = FileOutputStream(file)
val out = contentResolver.openOutputStream(document.uri)
saveFile(file, bitmap, out)
}
} else {
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)) {
reloadViewPager()
} else {
scanFile(file) {
deleteFileBg(File(mMedia[mPos].path)) {
reloadViewPager()
}
}
}.start()
}
private fun isDirEmpty(): Boolean {

View file

@ -273,30 +273,30 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
private fun deleteFiles() {
val selections = multiSelector.selectedPositions
val paths = ArrayList<String>(selections.size)
val removeDirs = ArrayList<Directory>(selections.size)
val folders = ArrayList<File>(selections.size)
val removeFolders = ArrayList<Directory>(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]
paths.add(directory.path)
removeDirs.add(directory)
folders.add(File(directory.path))
removeFolders.add(directory)
notifyItemRemoved(it)
}
dirs.removeAll(removeDirs)
dirs.removeAll(removeFolders)
markedItems.clear()
listener?.deleteFiles(paths)
listener?.tryDeleteFolders(folders)
}
}
private fun getSelectedPaths(): HashSet<String> {
@ -387,6 +387,6 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
interface DirOperationsListener {
fun refreshItems()
fun deleteFiles(paths: ArrayList<String>)
fun tryDeleteFolders(folders: ArrayList<File>)
}
}

View file

@ -190,16 +190,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
val files = ArrayList<File>(selections.size)
val removeMedia = ArrayList<Medium>(selections.size)
var isShowingPermDialog = false
activity.runOnUiThread {
if (activity.isShowingPermDialog(File(media[selections[0]].path))) {
isShowingPermDialog = true
}
}
if (isShowingPermDialog)
return
activity.handleSAFDialog(File(media[selections[0]].path)) {
selections.reverse()
selections.forEach {
val medium = media[it]
@ -212,6 +203,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
markedItems.clear()
listener?.deleteFiles(files)
}
}
private fun getSelectedMedia(): List<Medium> {
val positions = multiSelector.selectedPositions

View file

@ -59,25 +59,20 @@ class CopyDialog(val activity: SimpleActivity, val files: ArrayList<File>, val c
}
}
if (activity.isShowingPermDialog(destinationDir)) {
return@setOnClickListener
}
activity.handleSAFDialog(destinationDir) {
if (view.dialog_radio_group.checkedRadioButtonId == R.id.dialog_radio_copy) {
context.toast(R.string.copying)
val pair = Pair<ArrayList<File>, File>(files, destinationDir)
CopyMoveTask(context, false, context.config.treeUri, true, copyMoveListener).execute(pair)
CopyMoveTask(activity, false, context.config.treeUri, true, copyMoveListener).execute(pair)
dismiss()
} else {
if (context.isPathOnSD(sourcePath) || context.isPathOnSD(destinationPath)) {
if (activity.isShowingPermDialog(files[0])) {
return@setOnClickListener
}
activity.handleSAFDialog(files[0]) {
context.toast(R.string.moving)
val pair = Pair<ArrayList<File>, File>(files, destinationDir)
CopyMoveTask(context, true, context.config.treeUri, true, copyMoveListener).execute(pair)
CopyMoveTask(activity, true, context.config.treeUri, true, copyMoveListener).execute(pair)
dismiss()
}
} else {
val updatedFiles = ArrayList<File>(files.size * 2)
updatedFiles.addAll(files)
@ -86,6 +81,7 @@ class CopyDialog(val activity: SimpleActivity, val files: ArrayList<File>, val c
if (file.renameTo(destination))
updatedFiles.add(destination)
}
context.scanFiles(updatedFiles) {
activity.runOnUiThread {
copyMoveListener.copySucceeded(true, files.size * 2 == updatedFiles.size)
@ -94,6 +90,7 @@ class CopyDialog(val activity: SimpleActivity, val files: ArrayList<File>, val c
}
}
}
}
})
}

View file

@ -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
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()

View file

@ -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,9 +55,7 @@ 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)
@ -66,6 +64,7 @@ class RenameFileDialog(val activity: SimpleActivity, val file: File, val callbac
DocumentsContract.renameDocument(context.contentResolver, document!!.uri, newFile.name)
sendSuccess(file, newFile)
dismiss()
}
} else if (file.renameTo(newFile)) {
sendSuccess(file, newFile)
dismiss()

View file

@ -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()
}
}

View file

@ -70,6 +70,10 @@ fun Context.getParents(): ArrayList<String> {
val noMediaFolders = getNoMediaFolders()
val parents = ArrayList<String>()
if (config.showHiddenFolders) {
parentsSet.addAll(noMediaFolders)
}
parentsSet.filterTo(parents, {
if (File(it).isDirectory) {
if (!config.showHiddenFolders) {
@ -81,10 +85,6 @@ fun Context.getParents(): ArrayList<String> {
}
})
if (config.showHiddenFolders) {
parents.addAll(noMediaFolders)
}
return parents
}