Loading res/menu/context_menu.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -24,4 +24,8 @@ <item <item android:id="@+id/menu_paste_from_clipboard" android:id="@+id/menu_paste_from_clipboard" android:title="@string/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> </menu> res/values/strings.xml +2 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ <string name="menu_copy_to_clipboard">Copy</string> <string name="menu_copy_to_clipboard">Copy</string> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <string name="menu_paste_from_clipboard">Paste</string> <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. <!-- Translators asked for a length exemption for the show/hide internal storage strings. Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Loading src/com/android/documentsui/FilesMenuManager.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,11 @@ final class FilesMenuManager extends MenuManager { copyTo.setEnabled(!selectionDetails.containsPartialFiles()); copyTo.setEnabled(!selectionDetails.containsPartialFiles()); } } @Override void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(selectionDetails.canPasteInto()); } @Override @Override void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { selectAll.setVisible(true); selectAll.setVisible(true); Loading src/com/android/documentsui/MenuManager.java +62 −20 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui; package com.android.documentsui; import android.annotation.Nullable; import android.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.Menu; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem; Loading Loading @@ -59,39 +60,74 @@ public abstract class MenuManager { Menus.disableHiddenItems(menu); Menus.disableHiddenItems(menu); } } /** @See DirectoryFragment.onCreateContextMenu */ /** @See DirectoryFragment.onCreateContextMenu public void updateContextMenu(Menu menu, * @Nullable SelectionDetails selectionDetails, * Called when user tries to generate a context menu anchored to a file. * */ public void updateContextMenuForFile( Menu menu, SelectionDetails selectionDetails, DirectoryDetails directoryDetails) { DirectoryDetails directoryDetails) { assert(selectionDetails != null); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_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 delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); 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()); copy.setEnabled(!selectionDetails.containsPartialFiles()); cut.setEnabled( cut.setEnabled( !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); updatePasteInto(pasteInto, selectionDetails); updateRename(rename, selectionDetails); updateRename(rename, selectionDetails); updateDelete(delete, 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); 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); cut.setVisible(true); copy.setVisible(true); copy.setVisible(true); paste.setVisible(true); delete.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) { public void updateRootContextMenu(Menu menu, RootInfo root) { Loading Loading @@ -159,6 +195,10 @@ public abstract class MenuManager { copyTo.setVisible(false); copyTo.setVisible(false); } } void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(false); } abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); Loading @@ -175,6 +215,8 @@ public abstract class MenuManager { boolean canDelete(); boolean canDelete(); boolean canRename(); boolean canRename(); boolean canPasteInto(); } } public static class DirectoryDetails { public static class DirectoryDetails { Loading src/com/android/documentsui/dirlist/DirectoryFragment.java +36 −4 Original line number Original line Diff line number Diff line Loading @@ -437,11 +437,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_delete, Menu.NONE, R.string.menu_delete); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); if (v == mRecView || v == mEmptyView) { boolean mouseOverFile = !(v == mRecView || v == mEmptyView); mMenuManager.updateContextMenu(menu, null, getBaseActivity().getDirectoryDetails()); if (mouseOverFile) { mMenuManager.updateContextMenuForFile( menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); } else { } else { mMenuManager.updateContextMenu(menu, mSelectionModeListener, mMenuManager.updateContextMenuForContainer( getBaseActivity().getDirectoryDetails()); menu, getBaseActivity().getDirectoryDetails()); } } } } Loading Loading @@ -615,6 +617,7 @@ public class DirectoryFragment extends Fragment // Partial files are files that haven't been fully downloaded. // Partial files are files that haven't been fully downloaded. private int mPartialCount = 0; private int mPartialCount = 0; private int mDirectoryCount = 0; private int mDirectoryCount = 0; private int mWritableDirectoryCount = 0; private int mNoDeleteCount = 0; private int mNoDeleteCount = 0; private int mNoRenameCount = 0; private int mNoRenameCount = 0; Loading Loading @@ -660,6 +663,9 @@ public class DirectoryFragment extends Fragment if ((docFlags & Document.FLAG_PARTIAL) != 0) { if ((docFlags & Document.FLAG_PARTIAL) != 0) { mPartialCount += selected ? 1 : -1; mPartialCount += selected ? 1 : -1; } } if ((docFlags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0) { mWritableDirectoryCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { mNoDeleteCount += selected ? 1 : -1; mNoDeleteCount += selected ? 1 : -1; } } Loading Loading @@ -782,6 +788,12 @@ public class DirectoryFragment extends Fragment return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; } } @Override public boolean canPasteInto() { return mDirectoryCount == 1 && mWritableDirectoryCount == 1 && mSelectionMgr.getSelection().size() == 1; } private void updateActionMenu() { private void updateActionMenu() { assert(mMenu != null); assert(mMenu != null); mMenuManager.updateActionMenu(mMenu, this); mMenuManager.updateActionMenu(mMenu, this); Loading Loading @@ -840,6 +852,10 @@ public class DirectoryFragment extends Fragment pasteFromClipboard(); pasteFromClipboard(); return true; return true; case R.id.menu_paste_into_folder: pasteIntoFolder(); return true; case R.id.menu_select_all: case R.id.menu_select_all: selectAllFiles(); selectAllFiles(); return true; return true; Loading Loading @@ -1272,6 +1288,22 @@ public class DirectoryFragment extends Fragment getActivity().invalidateOptionsMenu(); 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() { public void selectAllFiles() { Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Loading Loading
res/menu/context_menu.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -24,4 +24,8 @@ <item <item android:id="@+id/menu_paste_from_clipboard" android:id="@+id/menu_paste_from_clipboard" android:title="@string/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> </menu>
res/values/strings.xml +2 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ <string name="menu_copy_to_clipboard">Copy</string> <string name="menu_copy_to_clipboard">Copy</string> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] --> <string name="menu_paste_from_clipboard">Paste</string> <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. <!-- Translators asked for a length exemption for the show/hide internal storage strings. Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Thus the CHAR LIMIT=24/30 deviation is 'splained. --> Loading
src/com/android/documentsui/FilesMenuManager.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,11 @@ final class FilesMenuManager extends MenuManager { copyTo.setEnabled(!selectionDetails.containsPartialFiles()); copyTo.setEnabled(!selectionDetails.containsPartialFiles()); } } @Override void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(selectionDetails.canPasteInto()); } @Override @Override void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) { selectAll.setVisible(true); selectAll.setVisible(true); Loading
src/com/android/documentsui/MenuManager.java +62 −20 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.documentsui; package com.android.documentsui; import android.annotation.Nullable; import android.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.Menu; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem; Loading Loading @@ -59,39 +60,74 @@ public abstract class MenuManager { Menus.disableHiddenItems(menu); Menus.disableHiddenItems(menu); } } /** @See DirectoryFragment.onCreateContextMenu */ /** @See DirectoryFragment.onCreateContextMenu public void updateContextMenu(Menu menu, * @Nullable SelectionDetails selectionDetails, * Called when user tries to generate a context menu anchored to a file. * */ public void updateContextMenuForFile( Menu menu, SelectionDetails selectionDetails, DirectoryDetails directoryDetails) { DirectoryDetails directoryDetails) { assert(selectionDetails != null); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard); MenuItem copy = menu.findItem(R.id.menu_copy_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 delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); 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()); copy.setEnabled(!selectionDetails.containsPartialFiles()); cut.setEnabled( cut.setEnabled( !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); !selectionDetails.containsPartialFiles() && selectionDetails.canDelete()); updatePasteInto(pasteInto, selectionDetails); updateRename(rename, selectionDetails); updateRename(rename, selectionDetails); updateDelete(delete, 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); 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); cut.setVisible(true); copy.setVisible(true); copy.setVisible(true); paste.setVisible(true); delete.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) { public void updateRootContextMenu(Menu menu, RootInfo root) { Loading Loading @@ -159,6 +195,10 @@ public abstract class MenuManager { copyTo.setVisible(false); copyTo.setVisible(false); } } void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) { pasteInto.setEnabled(false); } abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails); Loading @@ -175,6 +215,8 @@ public abstract class MenuManager { boolean canDelete(); boolean canDelete(); boolean canRename(); boolean canRename(); boolean canPasteInto(); } } public static class DirectoryDetails { public static class DirectoryDetails { Loading
src/com/android/documentsui/dirlist/DirectoryFragment.java +36 −4 Original line number Original line Diff line number Diff line Loading @@ -437,11 +437,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_delete, Menu.NONE, R.string.menu_delete); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename); if (v == mRecView || v == mEmptyView) { boolean mouseOverFile = !(v == mRecView || v == mEmptyView); mMenuManager.updateContextMenu(menu, null, getBaseActivity().getDirectoryDetails()); if (mouseOverFile) { mMenuManager.updateContextMenuForFile( menu, mSelectionModeListener, getBaseActivity().getDirectoryDetails()); } else { } else { mMenuManager.updateContextMenu(menu, mSelectionModeListener, mMenuManager.updateContextMenuForContainer( getBaseActivity().getDirectoryDetails()); menu, getBaseActivity().getDirectoryDetails()); } } } } Loading Loading @@ -615,6 +617,7 @@ public class DirectoryFragment extends Fragment // Partial files are files that haven't been fully downloaded. // Partial files are files that haven't been fully downloaded. private int mPartialCount = 0; private int mPartialCount = 0; private int mDirectoryCount = 0; private int mDirectoryCount = 0; private int mWritableDirectoryCount = 0; private int mNoDeleteCount = 0; private int mNoDeleteCount = 0; private int mNoRenameCount = 0; private int mNoRenameCount = 0; Loading Loading @@ -660,6 +663,9 @@ public class DirectoryFragment extends Fragment if ((docFlags & Document.FLAG_PARTIAL) != 0) { if ((docFlags & Document.FLAG_PARTIAL) != 0) { mPartialCount += selected ? 1 : -1; mPartialCount += selected ? 1 : -1; } } if ((docFlags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0) { mWritableDirectoryCount += selected ? 1 : -1; } if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) { mNoDeleteCount += selected ? 1 : -1; mNoDeleteCount += selected ? 1 : -1; } } Loading Loading @@ -782,6 +788,12 @@ public class DirectoryFragment extends Fragment return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1; } } @Override public boolean canPasteInto() { return mDirectoryCount == 1 && mWritableDirectoryCount == 1 && mSelectionMgr.getSelection().size() == 1; } private void updateActionMenu() { private void updateActionMenu() { assert(mMenu != null); assert(mMenu != null); mMenuManager.updateActionMenu(mMenu, this); mMenuManager.updateActionMenu(mMenu, this); Loading Loading @@ -840,6 +852,10 @@ public class DirectoryFragment extends Fragment pasteFromClipboard(); pasteFromClipboard(); return true; return true; case R.id.menu_paste_into_folder: pasteIntoFolder(); return true; case R.id.menu_select_all: case R.id.menu_select_all: selectAllFiles(); selectAllFiles(); return true; return true; Loading Loading @@ -1272,6 +1288,22 @@ public class DirectoryFragment extends Fragment getActivity().invalidateOptionsMenu(); 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() { public void selectAllFiles() { Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL); Loading