Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3da8afcf authored by Steve McKay's avatar Steve McKay
Browse files

Add rudimentary keyboard operation support.

Currently only select-all/copy/paste of files is supported.
Note, I wasn't able to push all code into DirectoryFragment,
as Jeff Sharkey suggested, as it doesn't have direct access
to KeyEvents. Bridged this from StandaloneActivity.

Change-Id: I082c457c9c4372e689d3acbca9ae11cd5c554a63
parent bc7932ed
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -137,4 +137,11 @@
    <string name="retry">Retry</string>
    <!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
    <string name="copy_failure_alert_content">These files weren\'t copied: <xliff:g id="list">%1$s</xliff:g></string>
    <!-- Toast shown when a user copies files to clipboard. -->
    <plurals name="clipboard_files_clipped">
        <item quantity="one">Copied <xliff:g id="count" example="1">%1$d</xliff:g> file to clipboard.</item>
        <item quantity="other">Copied <xliff:g id="count" example="3">%1$d</xliff:g> files to clipboard.</item>
    </plurals>
    <!-- Toast shown when a user tries to paste files into an unsupported location. -->
    <string name="clipboard_files_cannot_paste">Cannot past the selected files in this location.</string>
</resources>
+70 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.android.documentsui.DocumentsActivity.TAG;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -35,6 +36,7 @@ import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -87,6 +89,7 @@ import com.android.documentsui.RecentsProvider.StateColumns;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;

import com.google.android.collect.Lists;

import java.util.ArrayList;
@@ -532,11 +535,7 @@ public class DirectoryFragment extends Fragment {
                return true;

            } else if (id == R.id.menu_select_all) {
                int count = mCurrentView.getCount();
                for (int i = 0; i < count; i++) {
                    mCurrentView.setItemChecked(i, true);
                }
                updateDisplayState();
                selectAllFiles();
                return true;

            } else {
@@ -1207,9 +1206,20 @@ public class DirectoryFragment extends Fragment {
        return docs;
    }

    private void copyFromClipData(ClipData clipData) {
        copyFromClipData(
                clipData,
                ((BaseActivity)getActivity()).getCurrentDirectory());
    }

    private void copyFromClipData(ClipData clipData, DocumentInfo dstDir) {
        final List<DocumentInfo> srcDocs = getDocumentsFromClipData(clipData);

        if (!canCopy(srcDocs, dstDir)) {
            Toast.makeText(getActivity(), R.string.clipboard_files_cannot_paste, Toast.LENGTH_SHORT).show();
            return;
        }

        if (srcDocs.isEmpty())
            return;

@@ -1265,6 +1275,61 @@ public class DirectoryFragment extends Fragment {
        return clipData;
    }

    void copyToClipboard() {
        ClipboardManager clipboard = getClipboardManager();
        List<DocumentInfo> docs = getSelectedDocuments();
        ClipData data = getClipDataFromDocuments(docs);
        clipboard.setPrimaryClip(data);

        Activity activity = getActivity();
        Toast.makeText(activity,
                activity.getResources().getQuantityString(
                        R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
                Toast.LENGTH_SHORT).show();
    }

    void pasteFromClipboard() {
        ClipboardManager clipboard = getClipboardManager();
        copyFromClipData(clipboard.getPrimaryClip());
    }

    private ClipboardManager getClipboardManager() {
        return (ClipboardManager)getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
    }

    /**
     * Returns true if the list of files can be copied to destination. Note that this
     * is a policy check only. Currently the method does not attempt to verify
     * available space or any other environmental aspects possibly resulting in
     * failure to copy.
     *
     * @return true if the list of files can be copied to destination.
     */
    boolean canCopy(List<DocumentInfo> files, DocumentInfo dest) {
        BaseActivity activity = (BaseActivity)getActivity();

        final RootInfo root = activity.getCurrentRoot();

        // Can't copy folders to Downloads.
        if (root.isDownloads()) {
            for (DocumentInfo docs : files) {
                if (docs.isDirectory()) {
                    return false;
                }
            }
        }

        return dest != null && dest.isDirectory() && dest.isCreateSupported();
    }

    void selectAllFiles() {
        int count = mCurrentView.getCount();
        for (int i = 0; i < count; i++) {
            mCurrentView.setItemChecked(i, true);
        }
        updateDisplayState();
    }

    private void setupDragAndDropOnDirectoryView(AbsListView view) {
        // Listen for drops on non-directory items and empty space.
        view.setOnDragListener(mOnDragListener);
+22 −2
Original line number Diff line number Diff line
@@ -27,16 +27,15 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Spinner;
import android.widget.Toast;
@@ -280,6 +279,27 @@ public class StandaloneActivity extends BaseActivity {
        // TODO
    }

    @Override
    public boolean onKeyShortcut(int keyCode, KeyEvent event) {
        DirectoryFragment dir;
        switch (keyCode) {
            case KeyEvent.KEYCODE_A:
                dir = DirectoryFragment.get(getFragmentManager());
                dir.selectAllFiles();
                return true;
            case KeyEvent.KEYCODE_C:
                dir = DirectoryFragment.get(getFragmentManager());
                dir.copyToClipboard();
                return true;
            case KeyEvent.KEYCODE_V:
                dir = DirectoryFragment.get(getFragmentManager());
                dir.pasteFromClipboard();
                return true;
            default:
                return super.onKeyUp(keyCode, event);
        }
    }

    @Override
    void saveStackBlocking() {
        final ContentResolver resolver = getContentResolver();