Loading res/menu/context_menu.xml +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ <item android:id="@+id/menu_paste_from_clipboard" android:title="@string/menu_paste_from_clipboard" /> <item android:id="@+id/menu_paste_into_folder" android:title="@string/menu_paste_into_folder" /> </menu> res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ <string name="menu_copy_to_clipboard">Copy</string> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <string name="menu_paste_from_clipboard">Paste</string> <!-- Menu item title that pastes files into the selected folder [CHAR LIMIT=24] --> <string name="menu_paste_into_folder">Paste into folder</string> <!-- Translators asked for a length exemption for the show/hide internal storage strings. Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Loading src/com/android/documentsui/FilesMenuManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,11 @@ final class FilesMenuManager extends MenuManager { copyTo.setEnabled(!selectionDetails.containsPartialFiles()); } @Override void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(selectionDetails.canPasteInto()); } @Override void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { selectAll.setVisible(true); Loading src/com/android/documentsui/MenuManager.java +62 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui; import android.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.Menu; import android.view.MenuItem; Loading Loading @@ -59,39 +60,74 @@ public abstract class MenuManager { Menus.disableHiddenItems(menu); } /** @See DirectoryFragment.onCreateContextMenu */ public void updateContextMenu(Menu menu, @Nullable SelectionDetails selectionDetails, /** @See DirectoryFragment.onCreateContextMenu * * Called when user tries to generate a context menu anchored to a file. * */ public void updateContextMenuForFile( Menu menu, SelectionDetails selectionDetails, DirectoryDetails directoryDetails) { assert(selectionDetails != null); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); MenuItem createDir = menu.findItem(R.id.menu_create_dir); if (selectionDetails == null) { cut.setEnabled(false); copy.setEnabled(false); rename.setEnabled(false); delete.setEnabled(false); } else { copy.setEnabled(!selectionDetails.containsPartialFiles()); cut.setEnabled( !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); updatePasteInto(pasteInto, selectionDetails); updateRename(rename, selectionDetails); updateDelete(delete, selectionDetails); updateContextMenu(menu, directoryDetails); } menu.findItem(R.id.menu_paste_from_clipboard) .setEnabled(directoryDetails.hasItemsToPaste()); /** @See DirectoryFragment.onCreateContextMenu * * Called when user tries to generate a context menu anchored to an empty pane. * */ public void updateContextMenuForContainer(Menu menu, DirectoryDetails directoryDetails) { MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); cut.setEnabled(false); copy.setEnabled(false); pasteInto.setEnabled(false); rename.setEnabled(false); delete.setEnabled(false); updateContextMenu(menu, directoryDetails); } private void updateContextMenu(Menu menu, DirectoryDetails directoryDetails) { MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem createDir = menu.findItem(R.id.menu_create_dir); updateCreateDir(createDir, directoryDetails); paste.setEnabled(directoryDetails.hasItemsToPaste()); //Cut, Copy, Paste and Delete should always be visible //Cut, Copy and Delete should always be visible cut.setVisible(true); copy.setVisible(true); paste.setVisible(true); delete.setVisible(true); // PasteInto should only show if it is enabled. If it's not enabled, Paste shows (regardless // of whether it is enabled or not). // Paste then hides itself whenever PasteInto is enabled/visible pasteInto.setVisible(pasteInto.isEnabled()); paste.setVisible(!pasteInto.isVisible()); } public void updateRootContextMenu(Menu menu, RootInfo root) { Loading Loading @@ -159,6 +195,10 @@ public abstract class MenuManager { copyTo.setVisible(false); } void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(false); } abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); Loading @@ -175,6 +215,8 @@ public abstract class MenuManager { boolean canDelete(); boolean canRename(); boolean canPasteInto(); } public static class DirectoryDetails { Loading src/com/android/documentsui/dirlist/DirectoryFragment.java +36 −4 Original line number Diff line number Diff line Loading @@ -445,11 +445,13 @@ public class DirectoryFragment extends Fragment menu.add(Menu.NONE, R.id.menu_delete, Menu.NONE, R.string.menu_delete); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); if (v == mRecView || v == mEmptyView) { mMenuManager.updateContextMenu(menu, null, getBaseActivity().getDirectoryDetails()); boolean mouseOverFile = !(v == mRecView || v == mEmptyView); if (mouseOverFile) { mMenuManager.updateContextMenuForFile( menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); } else { mMenuManager.updateContextMenu(menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); mMenuManager.updateContextMenuForContainer( menu, getBaseActivity().getDirectoryDetails()); } } Loading Loading @@ -623,6 +625,7 @@ public class DirectoryFragment extends Fragment // Partial files are files that haven't been fully downloaded. private int mPartialCount = 0; private int mDirectoryCount = 0; private int mWritableDirectoryCount = 0; private int mNoDeleteCount = 0; private int mNoRenameCount = 0; Loading Loading @@ -668,6 +671,9 @@ public class DirectoryFragment extends Fragment if ((docFlags & Document.FLAG_PARTIAL) != 0) { mPartialCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0) { mWritableDirectoryCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { mNoDeleteCount += selected ? 1 : -1; } Loading Loading @@ -790,6 +796,12 @@ public class DirectoryFragment extends Fragment return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; } @Override public boolean canPasteInto() { return mDirectoryCount == 1 && mWritableDirectoryCount == 1 && mSelectionMgr.getSelection().size() == 1; } private void updateActionMenu() { assert(mMenu != null); mMenuManager.updateActionMenu(mMenu, this); Loading Loading @@ -848,6 +860,10 @@ public class DirectoryFragment extends Fragment pasteFromClipboard(); return true; case R.id.menu_paste_into_folder: pasteIntoFolder(); return true; case R.id.menu_select_all: selectAllFiles(); return true; Loading Loading @@ -1280,6 +1296,22 @@ public class DirectoryFragment extends Fragment getActivity().invalidateOptionsMenu(); } public void pasteIntoFolder() { assert (mSelectionMgr.getSelection().size() == 1); String modelId = mSelectionMgr.getSelection().iterator().next(); Cursor dstCursor = mModel.getItem(modelId); if (dstCursor == null) { Log.w(TAG, "Invalid destination. Can't obtain cursor for modelId: " + modelId); return; } BaseActivity activity = getBaseActivity(); DocumentInfo destination = DocumentInfo.fromDirectoryCursor(dstCursor); mClipper.copyFromClipboard( destination, activity.getDisplayState().stack, activity.fileOpCallback); getActivity().invalidateOptionsMenu(); } public void selectAllFiles() { Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Loading Loading
res/menu/context_menu.xml +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ <item android:id="@+id/menu_paste_from_clipboard" android:title="@string/menu_paste_from_clipboard" /> <item android:id="@+id/menu_paste_into_folder" android:title="@string/menu_paste_into_folder" /> </menu>
res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ <string name="menu_copy_to_clipboard">Copy</string> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <string name="menu_paste_from_clipboard">Paste</string> <!-- Menu item title that pastes files into the selected folder [CHAR LIMIT=24] --> <string name="menu_paste_into_folder">Paste into folder</string> <!-- Translators asked for a length exemption for the show/hide internal storage strings. Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Loading
src/com/android/documentsui/FilesMenuManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,11 @@ final class FilesMenuManager extends MenuManager { copyTo.setEnabled(!selectionDetails.containsPartialFiles()); } @Override void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(selectionDetails.canPasteInto()); } @Override void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { selectAll.setVisible(true); Loading
src/com/android/documentsui/MenuManager.java +62 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui; import android.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.Menu; import android.view.MenuItem; Loading Loading @@ -59,39 +60,74 @@ public abstract class MenuManager { Menus.disableHiddenItems(menu); } /** @See DirectoryFragment.onCreateContextMenu */ public void updateContextMenu(Menu menu, @Nullable SelectionDetails selectionDetails, /** @See DirectoryFragment.onCreateContextMenu * * Called when user tries to generate a context menu anchored to a file. * */ public void updateContextMenuForFile( Menu menu, SelectionDetails selectionDetails, DirectoryDetails directoryDetails) { assert(selectionDetails != null); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); MenuItem createDir = menu.findItem(R.id.menu_create_dir); if (selectionDetails == null) { cut.setEnabled(false); copy.setEnabled(false); rename.setEnabled(false); delete.setEnabled(false); } else { copy.setEnabled(!selectionDetails.containsPartialFiles()); cut.setEnabled( !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); updatePasteInto(pasteInto, selectionDetails); updateRename(rename, selectionDetails); updateDelete(delete, selectionDetails); updateContextMenu(menu, directoryDetails); } menu.findItem(R.id.menu_paste_from_clipboard) .setEnabled(directoryDetails.hasItemsToPaste()); /** @See DirectoryFragment.onCreateContextMenu * * Called when user tries to generate a context menu anchored to an empty pane. * */ public void updateContextMenuForContainer(Menu menu, DirectoryDetails directoryDetails) { MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); cut.setEnabled(false); copy.setEnabled(false); pasteInto.setEnabled(false); rename.setEnabled(false); delete.setEnabled(false); updateContextMenu(menu, directoryDetails); } private void updateContextMenu(Menu menu, DirectoryDetails directoryDetails) { MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard); MenuItem pasteInto = menu.findItem(R.id.menu_paste_into_folder); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem createDir = menu.findItem(R.id.menu_create_dir); updateCreateDir(createDir, directoryDetails); paste.setEnabled(directoryDetails.hasItemsToPaste()); //Cut, Copy, Paste and Delete should always be visible //Cut, Copy and Delete should always be visible cut.setVisible(true); copy.setVisible(true); paste.setVisible(true); delete.setVisible(true); // PasteInto should only show if it is enabled. If it's not enabled, Paste shows (regardless // of whether it is enabled or not). // Paste then hides itself whenever PasteInto is enabled/visible pasteInto.setVisible(pasteInto.isEnabled()); paste.setVisible(!pasteInto.isVisible()); } public void updateRootContextMenu(Menu menu, RootInfo root) { Loading Loading @@ -159,6 +195,10 @@ public abstract class MenuManager { copyTo.setVisible(false); } void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(false); } abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); Loading @@ -175,6 +215,8 @@ public abstract class MenuManager { boolean canDelete(); boolean canRename(); boolean canPasteInto(); } public static class DirectoryDetails { Loading
src/com/android/documentsui/dirlist/DirectoryFragment.java +36 −4 Original line number Diff line number Diff line Loading @@ -445,11 +445,13 @@ public class DirectoryFragment extends Fragment menu.add(Menu.NONE, R.id.menu_delete, Menu.NONE, R.string.menu_delete); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); if (v == mRecView || v == mEmptyView) { mMenuManager.updateContextMenu(menu, null, getBaseActivity().getDirectoryDetails()); boolean mouseOverFile = !(v == mRecView || v == mEmptyView); if (mouseOverFile) { mMenuManager.updateContextMenuForFile( menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); } else { mMenuManager.updateContextMenu(menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); mMenuManager.updateContextMenuForContainer( menu, getBaseActivity().getDirectoryDetails()); } } Loading Loading @@ -623,6 +625,7 @@ public class DirectoryFragment extends Fragment // Partial files are files that haven't been fully downloaded. private int mPartialCount = 0; private int mDirectoryCount = 0; private int mWritableDirectoryCount = 0; private int mNoDeleteCount = 0; private int mNoRenameCount = 0; Loading Loading @@ -668,6 +671,9 @@ public class DirectoryFragment extends Fragment if ((docFlags & Document.FLAG_PARTIAL) != 0) { mPartialCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0) { mWritableDirectoryCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { mNoDeleteCount += selected ? 1 : -1; } Loading Loading @@ -790,6 +796,12 @@ public class DirectoryFragment extends Fragment return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; } @Override public boolean canPasteInto() { return mDirectoryCount == 1 && mWritableDirectoryCount == 1 && mSelectionMgr.getSelection().size() == 1; } private void updateActionMenu() { assert(mMenu != null); mMenuManager.updateActionMenu(mMenu, this); Loading Loading @@ -848,6 +860,10 @@ public class DirectoryFragment extends Fragment pasteFromClipboard(); return true; case R.id.menu_paste_into_folder: pasteIntoFolder(); return true; case R.id.menu_select_all: selectAllFiles(); return true; Loading Loading @@ -1280,6 +1296,22 @@ public class DirectoryFragment extends Fragment getActivity().invalidateOptionsMenu(); } public void pasteIntoFolder() { assert (mSelectionMgr.getSelection().size() == 1); String modelId = mSelectionMgr.getSelection().iterator().next(); Cursor dstCursor = mModel.getItem(modelId); if (dstCursor == null) { Log.w(TAG, "Invalid destination. Can't obtain cursor for modelId: " + modelId); return; } BaseActivity activity = getBaseActivity(); DocumentInfo destination = DocumentInfo.fromDirectoryCursor(dstCursor); mClipper.copyFromClipboard( destination, activity.getDisplayState().stack, activity.fileOpCallback); getActivity().invalidateOptionsMenu(); } public void selectAllFiles() { Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Loading