From 5a76dd5db2a926d48243f001855d8fff09a9be91 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 20 Nov 2016 16:25:49 +0100 Subject: [PATCH] convert ItemsFragment to kotlin --- .../filemanager/fragments/ItemsFragment.java | 498 ------------------ .../filemanager/Constants.kt | 6 +- .../simplemobiletools/filemanager/Utils.kt | 24 - .../filemanager/activities/MainActivity.kt | 4 +- .../filemanager/fragments/ItemsFragment.kt | 400 ++++++++++++++ 5 files changed, 404 insertions(+), 528 deletions(-) delete mode 100644 app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java delete mode 100644 app/src/main/kotlin/com/simplemobiletools/filemanager/Utils.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt diff --git a/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java b/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java deleted file mode 100644 index 0ca03adf..00000000 --- a/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java +++ /dev/null @@ -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 mStates; - - private List mItems; - private ItemInteractionListener mListener; - private List 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 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 getItems(String path) { - final List 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 itemIndexes = getSelectedItemIndexes(); - if (itemIndexes.isEmpty()) - return; - - final ArrayList 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 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 itemIndexes) { - final List 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 fileIndexes = getSelectedItemIndexes(); - if (fileIndexes.isEmpty()) - return; - - final ArrayList 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 itemIndexes = getSelectedItemIndexes(); - if (itemIndexes.isEmpty()) - return null; - - final int itemIndex = itemIndexes.get(0); - return mItems.get(itemIndex); - } - - private List getSelectedItemIndexes() { - final List 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); - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/Constants.kt index 19e75328..7c7c638c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/Constants.kt @@ -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" -} diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/Utils.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/Utils.kt deleted file mode 100644 index bc332d7d..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/Utils.kt +++ /dev/null @@ -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) {} - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt index 61905910..35f86e3d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/activities/MainActivity.kt @@ -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 diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt new file mode 100644 index 00000000..221a41e9 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt @@ -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 + lateinit var mConfig: Config + lateinit var mToBeDeleted: MutableList + + 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() + mToBeDeleted = ArrayList() + 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 { + val items = ArrayList() + 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(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) { + val paths = ArrayList(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(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 { + 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) + } +}