convert ItemsFragment to kotlin

This commit is contained in:
tibbi 2016-11-20 16:25:49 +01:00
parent f5257a0c8a
commit 5a76dd5db2
5 changed files with 404 additions and 528 deletions

View File

@ -1,498 +0,0 @@
package com.simplemobiletools.filemanager.fragments;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.provider.DocumentFile;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.AdapterView;
import android.widget.ListView;
import com.simplemobiletools.filemanager.Config;
import com.simplemobiletools.filemanager.Constants;
import com.simplemobiletools.filemanager.R;
import com.simplemobiletools.filemanager.Utils;
import com.simplemobiletools.filemanager.activities.SimpleActivity;
import com.simplemobiletools.filemanager.adapters.ItemsAdapter;
import com.simplemobiletools.filemanager.dialogs.CopyDialog;
import com.simplemobiletools.filemanager.dialogs.CreateNewItemDialog;
import com.simplemobiletools.filemanager.dialogs.RenameItemDialog;
import com.simplemobiletools.filepicker.asynctasks.CopyMoveTask;
import com.simplemobiletools.filepicker.models.FileDirItem;
import com.simplemobiletools.fileproperties.dialogs.PropertiesDialog;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class ItemsFragment extends android.support.v4.app.Fragment
implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener, ListView.MultiChoiceModeListener,
ListView.OnTouchListener {
@BindView(R.id.items_list) ListView mListView;
@BindView(R.id.items_swipe_refresh) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.items_holder) CoordinatorLayout mCoordinatorLayout;
private static Map<String, Parcelable> mStates;
private List<FileDirItem> mItems;
private ItemInteractionListener mListener;
private List<String> mToBeDeleted;
private String mPath;
private Snackbar mSnackbar;
private Config mConfig;
private boolean mShowHidden;
private int mSelectedItemsCnt;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.items_fragment, container, false);
ButterKnife.bind(this, view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mStates == null)
mStates = new HashMap<>();
mConfig = Config.Companion.newInstance(getContext());
mShowHidden = mConfig.getShowHidden();
mItems = new ArrayList<>();
mToBeDeleted = new ArrayList<>();
fillItems();
mSwipeRefreshLayout.setOnRefreshListener(this);
}
@Override
public void onResume() {
super.onResume();
if (mShowHidden != mConfig.getShowHidden()) {
mShowHidden = !mShowHidden;
mStates.remove(mPath);
fillItems();
}
}
@Override
public void onPause() {
super.onPause();
deleteItems();
mStates.put(mPath, mListView.onSaveInstanceState());
}
private void fillItems() {
mPath = getArguments().getString(Constants.INSTANCE.getPATH());
final List<FileDirItem> newItems = getItems(mPath);
Collections.sort(newItems);
if (mItems != null && newItems.toString().equals(mItems.toString())) {
return;
}
mItems = newItems;
final ItemsAdapter adapter = new ItemsAdapter(getContext(), mItems);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(this);
mListView.setMultiChoiceModeListener(this);
mListView.setOnTouchListener(this);
if (mStates != null && mStates.get(mPath) != null) {
mListView.onRestoreInstanceState(mStates.get(mPath));
}
}
public void setListener(ItemInteractionListener listener) {
mListener = listener;
}
private List<FileDirItem> getItems(String path) {
final List<FileDirItem> items = new ArrayList<>();
final File base = new File(path);
File[] files = base.listFiles();
if (files != null) {
for (File file : files) {
final String curPath = file.getAbsolutePath();
final String curName = Utils.Companion.getFilename(curPath);
if (!mShowHidden && curName.startsWith("."))
continue;
if (mToBeDeleted.contains(curPath))
continue;
int children = getChildren(file);
long size = file.length();
items.add(new FileDirItem(curPath, curName, file.isDirectory(), children, size));
}
}
return items;
}
private int getChildren(File file) {
if (file.listFiles() == null)
return 0;
if (file.isDirectory()) {
if (mShowHidden) {
return file.listFiles().length;
} else {
return file.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return !file.isHidden();
}
}).length;
}
}
return 0;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final FileDirItem item = mItems.get(position);
if (item.isDirectory()) {
if (mListener != null)
mListener.itemClicked(item);
} else {
final String path = item.getPath();
final File file = new File(path);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(Utils.Companion.getFileExtension(path));
if (mimeType == null)
mimeType = "text/plain";
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimeType);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
if (!tryGenericMimeType(intent, mimeType, file)) {
Utils.Companion.showToast(getContext(), R.string.no_app_found);
}
}
}
}
private boolean tryGenericMimeType(Intent intent, String mimeType, File file) {
final String genericMimeType = getGenericMimeType(mimeType);
intent.setDataAndType(Uri.fromFile(file), genericMimeType);
try {
startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
@OnClick(R.id.items_fab)
public void fabClicked(View view) {
new CreateNewItemDialog(getContext(), mPath, new CreateNewItemDialog.OnCreateNewItemListener() {
@Override
public void onSuccess() {
fillItems();
}
});
}
@Override
public void onRefresh() {
fillItems();
mSwipeRefreshLayout.setRefreshing(false);
}
private String getGenericMimeType(String mimeType) {
if (!mimeType.contains("/"))
return mimeType;
final String type = mimeType.substring(0, mimeType.indexOf("/"));
return type + "/*";
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (checked) {
mSelectedItemsCnt++;
} else {
mSelectedItemsCnt--;
}
if (mSelectedItemsCnt > 0) {
mode.setTitle(String.valueOf(mSelectedItemsCnt));
}
mode.invalidate();
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.cab, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
MenuItem menuItem = menu.findItem(R.id.cab_rename);
menuItem.setVisible(mSelectedItemsCnt == 1);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.cab_rename:
displayRenameDialog();
mode.finish();
break;
case R.id.cab_properties:
displayPropertiesDialog();
break;
case R.id.cab_share:
shareFiles();
break;
case R.id.cab_copy:
displayCopyDialog();
mode.finish();
break;
case R.id.cab_delete:
prepareForDeleting();
mode.finish();
break;
default:
return false;
}
return true;
}
private void shareFiles() {
final List<Integer> itemIndexes = getSelectedItemIndexes();
if (itemIndexes.isEmpty())
return;
final ArrayList<Uri> uris = new ArrayList<>(itemIndexes.size());
for (int i : itemIndexes) {
final File file = new File(mItems.get(i).getPath());
if (!file.isDirectory())
uris.add(Uri.fromFile(file));
}
if (uris.isEmpty()) {
Utils.Companion.showToast(getContext(), R.string.no_files_selected);
return;
}
final String shareTitle = getResources().getString(R.string.share_via);
final Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString(R.string.shared_files));
sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
sendIntent.setType("*/*");
startActivity(Intent.createChooser(sendIntent, shareTitle));
}
private void displayPropertiesDialog() {
final List<Integer> itemIndexes = getSelectedItemIndexes();
if (itemIndexes.isEmpty())
return;
if (itemIndexes.size() == 1) {
showOneItemProperties();
} else {
showMultipleItemProperties(itemIndexes);
}
}
private void showOneItemProperties() {
final FileDirItem item = getSelectedItem();
if (item == null)
return;
new PropertiesDialog(getActivity(), item.getPath(), mConfig.getShowHidden());
}
private void showMultipleItemProperties(List<Integer> itemIndexes) {
final List<String> paths = new ArrayList<>(itemIndexes.size());
for (int i : itemIndexes) {
paths.add(mItems.get(i).getPath());
}
new PropertiesDialog(getActivity(), paths, mConfig.getShowHidden());
}
private void displayRenameDialog() {
final FileDirItem item = getSelectedItem();
if (item == null)
return;
new RenameItemDialog(getContext(), mPath, item, new RenameItemDialog.OnRenameItemListener() {
@Override
public void onSuccess() {
fillItems();
}
});
}
private void displayCopyDialog() {
final List<Integer> fileIndexes = getSelectedItemIndexes();
if (fileIndexes.isEmpty())
return;
final ArrayList<File> files = new ArrayList<>(fileIndexes.size());
for (Integer i : fileIndexes) {
FileDirItem item = mItems.get(i);
files.add(new File(item.getPath()));
}
new CopyDialog((SimpleActivity) getActivity(), files, new CopyMoveTask.CopyMoveListener() {
@Override
public void copySucceeded(boolean deleted, boolean copiedAll) {
int msgId;
if (deleted) {
msgId = copiedAll ? R.string.moving_success : R.string.moving_success_partial;
} else {
msgId = copiedAll? R.string.copying_success : R.string.copying_success_partial;
}
fillItems();
Utils.Companion.showToast(getContext(), msgId);
}
@Override
public void copyFailed() {
Utils.Companion.showToast(getContext(), R.string.copy_move_failed);
}
});
}
private FileDirItem getSelectedItem() {
final List<Integer> itemIndexes = getSelectedItemIndexes();
if (itemIndexes.isEmpty())
return null;
final int itemIndex = itemIndexes.get(0);
return mItems.get(itemIndex);
}
private List<Integer> getSelectedItemIndexes() {
final List<Integer> selectedItems = new ArrayList<>();
final SparseBooleanArray items = mListView.getCheckedItemPositions();
int cnt = items.size();
for (int i = 0; i < cnt; i++) {
if (items.valueAt(i)) {
selectedItems.add(items.keyAt(i));
}
}
return selectedItems;
}
private void prepareForDeleting() {
mToBeDeleted.clear();
final SparseBooleanArray items = mListView.getCheckedItemPositions();
final int cnt = items.size();
int deletedCnt = 0;
for (int i = 0; i < cnt; i++) {
if (items.valueAt(i)) {
final int id = items.keyAt(i);
final String path = mItems.get(id).getPath();
mToBeDeleted.add(path);
deletedCnt++;
}
}
notifyDeletion(deletedCnt);
}
private void notifyDeletion(int cnt) {
final Resources res = getResources();
final String msg = res.getQuantityString(R.plurals.items_deleted, cnt, cnt);
mSnackbar = Snackbar.make(mCoordinatorLayout, msg, Snackbar.LENGTH_INDEFINITE);
mSnackbar.setAction(res.getString(R.string.undo), undoDeletion);
mSnackbar.setActionTextColor(Color.WHITE);
mSnackbar.show();
fillItems();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mSnackbar != null && mSnackbar.isShown()) {
deleteItems();
}
return false;
}
private void deleteItems() {
if (mToBeDeleted == null || mToBeDeleted.isEmpty())
return;
if (mSnackbar != null) {
mSnackbar.dismiss();
}
for (String delPath : mToBeDeleted) {
final File file = new File(delPath);
if (file.exists()) {
deleteItem(file);
}
}
mToBeDeleted.clear();
}
private void deleteItem(File item) {
if (item.isDirectory()) {
for (File child : item.listFiles()) {
deleteItem(child);
}
}
if (Utils.Companion.needsStupidWritePermissions(getContext(), item.getAbsolutePath())) {
final DocumentFile document = Utils.Companion.getFileDocument(getContext(), item.getAbsolutePath(), mConfig.getTreeUri());
document.delete();
} else {
item.delete();
}
}
private View.OnClickListener undoDeletion = new View.OnClickListener() {
@Override
public void onClick(View v) {
mToBeDeleted.clear();
mSnackbar.dismiss();
fillItems();
}
};
@Override
public void onDestroyActionMode(ActionMode mode) {
mSelectedItemsCnt = 0;
}
public interface ItemInteractionListener {
void itemClicked(FileDirItem item);
}
}

View File

@ -1,5 +1,7 @@
package com.simplemobiletools.filemanager
val PATH = "path"
// shared preferences
val PREFS_KEY = "File Manager"
val IS_FIRST_RUN = "is_first_run"
@ -9,7 +11,3 @@ val TREE_URI = "tree_uri"
// global intents
val OPEN_DOCUMENT_TREE = 1000
object Constants {
val PATH = "path"
}

View File

@ -1,24 +0,0 @@
package com.simplemobiletools.filemanager
import android.content.Context
import com.simplemobiletools.filepicker.extensions.getFileDocument
import com.simplemobiletools.filepicker.extensions.needsStupidWritePermissions
import com.simplemobiletools.filepicker.extensions.scanFile
import com.simplemobiletools.filepicker.extensions.toast
import java.io.File
class Utils {
companion object {
fun getFilename(path: String) = path.substring(path.lastIndexOf("/") + 1)
fun getFileExtension(fileName: String) = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase()
fun showToast(context: Context, resId: Int) = context.toast(resId)
fun needsStupidWritePermissions(context: Context, path: String) = context.needsStupidWritePermissions(path)
fun getFileDocument(context: Context, path: String, treeUri: String) = context.getFileDocument(path, treeUri)
fun scanFile(context: Context, file: File) = context.scanFile(file) {}
}
}

View File

@ -8,7 +8,7 @@ import android.os.Handler
import android.support.v4.app.ActivityCompat
import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.filemanager.Constants
import com.simplemobiletools.filemanager.PATH
import com.simplemobiletools.filemanager.R
import com.simplemobiletools.filemanager.fragments.ItemsFragment
import com.simplemobiletools.filepicker.dialogs.StoragePickerDialog
@ -50,7 +50,7 @@ class MainActivity : SimpleActivity(), ItemsFragment.ItemInteractionListener, Br
private fun openPath(path: String) {
breadcrumbs.setBreadcrumb(path)
val bundle = Bundle()
bundle.putString(Constants.PATH, path)
bundle.putString(PATH, path)
val fragment = ItemsFragment()
fragment.arguments = bundle

View File

@ -0,0 +1,400 @@
package com.simplemobiletools.filemanager.fragments
import android.content.ActivityNotFoundException
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.webkit.MimeTypeMap
import android.widget.AdapterView
import com.simplemobiletools.filemanager.Config
import com.simplemobiletools.filemanager.PATH
import com.simplemobiletools.filemanager.R
import com.simplemobiletools.filemanager.activities.SimpleActivity
import com.simplemobiletools.filemanager.adapters.ItemsAdapter
import com.simplemobiletools.filemanager.dialogs.CopyDialog
import com.simplemobiletools.filemanager.dialogs.CreateNewItemDialog
import com.simplemobiletools.filemanager.dialogs.RenameItemDialog
import com.simplemobiletools.filepicker.asynctasks.CopyMoveTask
import com.simplemobiletools.filepicker.extensions.*
import com.simplemobiletools.filepicker.models.FileDirItem
import com.simplemobiletools.fileproperties.dialogs.PropertiesDialog
import kotlinx.android.synthetic.main.items_fragment.*
import java.io.File
import java.util.*
class ItemsFragment : android.support.v4.app.Fragment(), AdapterView.OnItemClickListener, /*ListView.MultiChoiceModeListener, */View.OnTouchListener {
private var mListener: ItemInteractionListener? = null
private var mSnackbar: Snackbar? = null
lateinit var mItems: List<FileDirItem>
lateinit var mConfig: Config
lateinit var mToBeDeleted: MutableList<String>
private var mPath = ""
private var mShowHidden = false
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?) =
inflater!!.inflate(R.layout.items_fragment, container, false)
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mConfig = Config.newInstance(context)
mShowHidden = mConfig.showHidden
mItems = ArrayList<FileDirItem>()
mToBeDeleted = ArrayList<String>()
fillItems()
items_swipe_refresh.setOnRefreshListener({ fillItems() })
items_fab.setOnClickListener { createNewItem() }
}
override fun onResume() {
super.onResume()
if (mShowHidden != mConfig.showHidden) {
mShowHidden = !mShowHidden
fillItems()
}
}
override fun onPause() {
super.onPause()
deleteItems()
}
private fun fillItems() {
mPath = arguments.getString(PATH)
val newItems = getItems(mPath)
Collections.sort(newItems)
items_swipe_refresh.isRefreshing = false
if (newItems.toString() == mItems.toString()) {
return
}
mItems = newItems
val adapter = ItemsAdapter(context, mItems)
items_list.adapter = adapter
items_list.onItemClickListener = this
items_list.setOnTouchListener(this)
}
fun setListener(listener: ItemInteractionListener) {
mListener = listener
}
private fun getItems(path: String): List<FileDirItem> {
val items = ArrayList<FileDirItem>()
val files = File(path).listFiles()
if (files != null) {
for (file in files) {
val curPath = file.absolutePath
val curName = curPath.getFilenameFromPath()
if (!mShowHidden && curName.startsWith("."))
continue
if (mToBeDeleted.contains(curPath))
continue
val children = getChildren(file)
val size = file.length()
items.add(FileDirItem(curPath, curName, file.isDirectory, children, size))
}
}
return items
}
private fun getChildren(file: File): Int {
if (file.listFiles() == null)
return 0
if (file.isDirectory) {
return if (mShowHidden) {
file.listFiles().size
} else {
file.listFiles { file -> !file.isHidden }.size
}
}
return 0
}
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val item = mItems[position]
if (item.isDirectory) {
mListener?.itemClicked(item)
} else {
val path = item.path
val file = File(path)
var mimeType: String? = MimeTypeMap.getSingleton().getMimeTypeFromExtension(path.getFilenameExtension().toLowerCase())
if (mimeType == null)
mimeType = "text/plain"
Intent(Intent.ACTION_VIEW).apply {
setDataAndType(Uri.fromFile(file), mimeType)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
try {
startActivity(this)
} catch (e: ActivityNotFoundException) {
if (!tryGenericMimeType(this, mimeType!!, file)) {
context.toast(R.string.no_app_found)
}
}
}
}
}
private fun tryGenericMimeType(intent: Intent, mimeType: String, file: File): Boolean {
val genericMimeType = getGenericMimeType(mimeType)
intent.setDataAndType(Uri.fromFile(file), genericMimeType)
return try {
startActivity(intent)
true
} catch (e: ActivityNotFoundException) {
false
}
}
private fun createNewItem() {
CreateNewItemDialog(context, mPath, object : CreateNewItemDialog.OnCreateNewItemListener {
override fun onSuccess() {
fillItems()
}
})
}
private fun getGenericMimeType(mimeType: String): String {
if (!mimeType.contains("/"))
return mimeType
val type = mimeType.substring(0, mimeType.indexOf("/"))
return type + "/*"
}
/*override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long, checked: Boolean) {
if (checked) {
mSelectedItemsCnt++
} else {
mSelectedItemsCnt--
}
if (mSelectedItemsCnt > 0) {
mode.title = mSelectedItemsCnt.toString()
}
mode.invalidate()
}
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.cab, menu)
return true
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
val menuItem = menu.findItem(R.id.cab_rename)
menuItem.isVisible = mSelectedItemsCnt == 1
return true
}
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
when (item.itemId) {
R.id.cab_rename -> {
displayRenameDialog()
mode.finish()
}
R.id.cab_properties -> displayPropertiesDialog()
R.id.cab_share -> shareFiles()
R.id.cab_copy -> {
displayCopyDialog()
mode.finish()
}
R.id.cab_delete -> {
prepareForDeleting()
mode.finish()
}
else -> return false
}
return true
}*/
private fun shareFiles() {
val itemIndexes = getSelectedItemIndexes()
if (itemIndexes.isEmpty())
return
val uris = ArrayList<Uri>(itemIndexes.size)
itemIndexes.map { File(mItems[it].path) }
.filterNot { it.isDirectory }
.mapTo(uris) { Uri.fromFile(it) }
if (uris.isEmpty()) {
context.toast(R.string.no_files_selected)
return
}
val shareTitle = resources.getString(R.string.share_via)
Intent().apply {
action = Intent.ACTION_SEND_MULTIPLE
putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.shared_files))
putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
type = "*/*"
startActivity(Intent.createChooser(this, shareTitle))
}
}
private fun displayPropertiesDialog() {
val itemIndexes = getSelectedItemIndexes()
if (itemIndexes.isEmpty())
return
if (itemIndexes.size == 1) {
showOneItemProperties()
} else {
showMultipleItemProperties(itemIndexes)
}
}
private fun showOneItemProperties() {
val item = getSelectedItem() ?: return
PropertiesDialog(activity, item.path, mConfig.showHidden)
}
private fun showMultipleItemProperties(itemIndexes: List<Int>) {
val paths = ArrayList<String>(itemIndexes.size)
itemIndexes.mapTo(paths) { mItems[it].path }
PropertiesDialog(activity, paths, mConfig.showHidden)
}
private fun displayRenameDialog() {
val item = getSelectedItem() ?: return
RenameItemDialog(context, mPath, item, object : RenameItemDialog.OnRenameItemListener {
override fun onSuccess() {
fillItems()
}
})
}
private fun displayCopyDialog() {
val fileIndexes = getSelectedItemIndexes()
if (fileIndexes.isEmpty())
return
val files = ArrayList<File>(fileIndexes.size)
fileIndexes.mapTo(files) { File(mItems[it].path) }
CopyDialog(activity as SimpleActivity, files, object : CopyMoveTask.CopyMoveListener {
override fun copySucceeded(deleted: Boolean, copiedAll: Boolean) {
if (deleted) {
context.toast(if (copiedAll) R.string.moving_success else R.string.moving_success_partial)
} else {
context.toast(if (copiedAll) R.string.copying_success else R.string.copying_success_partial)
}
fillItems()
}
override fun copyFailed() {
context.toast(R.string.copy_move_failed)
}
})
}
private fun getSelectedItem(): FileDirItem? {
val itemIndexes = getSelectedItemIndexes()
if (itemIndexes.isEmpty())
return null
val itemIndex = itemIndexes[0]
return mItems[itemIndex]
}
private fun getSelectedItemIndexes(): List<Int> {
val items = items_list.checkedItemPositions
val cnt = items.size()
val selectedItems = (0..cnt - 1)
.filter { items.valueAt(it) }
.map { items.keyAt(it) }
return selectedItems
}
private fun prepareForDeleting() {
mToBeDeleted.clear()
val items = items_list.checkedItemPositions
val cnt = items.size()
var deletedCnt = 0
for (i in 0..cnt - 1) {
if (items.valueAt(i)) {
val id = items.keyAt(i)
val path = mItems[id].path
mToBeDeleted.add(path)
deletedCnt++
}
}
notifyDeletion(deletedCnt)
}
private fun notifyDeletion(cnt: Int) {
val res = resources
val msg = res.getQuantityString(R.plurals.items_deleted, cnt, cnt)
mSnackbar = Snackbar.make(items_holder, msg, Snackbar.LENGTH_INDEFINITE)
mSnackbar!!.apply {
setAction(res.getString(R.string.undo), undoDeletion)
setActionTextColor(Color.WHITE)
show()
}
fillItems()
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (mSnackbar != null && mSnackbar!!.isShown) {
deleteItems()
}
return false
}
private fun deleteItems() {
if (mToBeDeleted.isEmpty())
return
mSnackbar?.dismiss()
mToBeDeleted
.map(::File)
.filter(File::exists)
.forEach { deleteItem(it) }
mToBeDeleted.clear()
}
private fun deleteItem(item: File) {
if (item.isDirectory) {
for (child in item.listFiles()) {
deleteItem(child)
}
}
if (context.needsStupidWritePermissions(item.absolutePath)) {
val document = context.getFileDocument(item.absolutePath, mConfig.treeUri)
document.delete()
} else {
item.delete()
}
}
private val undoDeletion = View.OnClickListener {
mToBeDeleted.clear()
mSnackbar!!.dismiss()
fillItems()
}
interface ItemInteractionListener {
fun itemClicked(item: FileDirItem)
}
}