Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +40 −49 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.FragmentTransaction; import android.app.LoaderManager.LoaderCallbacks; import android.app.LoaderManager.LoaderCallbacks; import android.content.ClipData; import android.content.ClipData; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface; import android.content.Intent; import android.content.Intent; Loading Loading @@ -103,7 +102,6 @@ import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService.OpType; import com.android.documentsui.services.FileOperationService.OpType; import com.android.documentsui.services.FileOperations; import com.android.documentsui.services.FileOperations; import com.google.common.collect.Lists; import com.google.common.collect.Lists; import java.lang.annotation.Retention; import java.lang.annotation.Retention; Loading @@ -111,6 +109,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Objects; /** /** * Display the documents inside a single directory. * Display the documents inside a single directory. Loading Loading @@ -147,8 +146,6 @@ public class DirectoryFragment extends Fragment public @interface RequestCode {} public @interface RequestCode {} public static final int REQUEST_COPY_DESTINATION = 1; public static final int REQUEST_COPY_DESTINATION = 1; static final boolean DEBUG_ENABLE_DND = true; private static final String TAG = "DirectoryFragment"; private static final String TAG = "DirectoryFragment"; private static final int LOADER_ID = 42; private static final int LOADER_ID = 42; Loading Loading @@ -205,10 +202,9 @@ public class DirectoryFragment extends Fragment mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity())); mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity())); // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration). // Make the recycler and the empty views responsive to drop events. if (DEBUG_ENABLE_DND) { mRecView.setOnDragListener(mOnDragListener); setupDragAndDropOnDirectoryView(mRecView); mEmptyView.setOnDragListener(mOnDragListener); } return view; return view; } } Loading Loading @@ -799,10 +795,8 @@ public class DirectoryFragment extends Fragment @Override @Override public void onBindDocumentHolder(DocumentHolder holder, Cursor cursor) { public void onBindDocumentHolder(DocumentHolder holder, Cursor cursor) { if (DEBUG_ENABLE_DND) { setupDragAndDropOnDocumentView(holder.itemView, cursor); setupDragAndDropOnDocumentView(holder.itemView, cursor); } } } @Override @Override public State getDisplayState() { public State getDisplayState() { Loading Loading @@ -938,25 +932,6 @@ public class DirectoryFragment extends Fragment FileOperations.copy(getActivity(), docs, tmpStack); FileOperations.copy(getActivity(), docs, tmpStack); } } private ClipData getClipDataFromDocuments(List<DocumentInfo> docs) { Context context = getActivity(); final ContentResolver resolver = context.getContentResolver(); ClipData clipData = null; for (DocumentInfo doc : docs) { final Uri uri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId); if (clipData == null) { // TODO: figure out what this string should be. // Currently it is not displayed anywhere in the UI, but this might change. final String label = ""; clipData = ClipData.newUri(resolver, label, uri); } else { // TODO: update list of mime types in ClipData. clipData.addItem(new ClipData.Item(uri)); } } return clipData; } public void copySelectedToClipboard() { public void copySelectedToClipboard() { Selection selection = mSelectionManager.getSelection(new Selection()); Selection selection = mSelectionManager.getSelection(new Selection()); if (!selection.isEmpty()) { if (!selection.isEmpty()) { Loading Loading @@ -1025,11 +1000,6 @@ public class DirectoryFragment extends Fragment mFocusManager.restoreLastFocus(); mFocusManager.restoreLastFocus(); } } private void setupDragAndDropOnDirectoryView(View view) { // Listen for drops on non-directory items and empty space. view.setOnDragListener(mOnDragListener); } private void setupDragAndDropOnDocumentView(View view, Cursor cursor) { private void setupDragAndDropOnDocumentView(View view, Cursor cursor) { final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); if (Document.MIME_TYPE_DIR.equals(docMimeType)) { if (Document.MIME_TYPE_DIR.equals(docMimeType)) { Loading @@ -1038,6 +1008,7 @@ public class DirectoryFragment extends Fragment view.setOnDragListener(mOnDragListener); view.setOnDragListener(mOnDragListener); } } // Make all items draggable. view.setOnLongClickListener(mDragHelper); view.setOnLongClickListener(mDragHelper); } } Loading @@ -1058,27 +1029,47 @@ public class DirectoryFragment extends Fragment return true; return true; case DragEvent.ACTION_DRAG_LOCATION: case DragEvent.ACTION_DRAG_LOCATION: return true; case DragEvent.ACTION_DRAG_ENDED: case DragEvent.ACTION_DRAG_ENDED: if (event.getResult()) { // Exit selection mode if the drop was handled. mSelectionManager.clearSelection(); } return true; return true; case DragEvent.ACTION_DROP: case DragEvent.ACTION_DROP: String dstId = getModelId(v); // After a drop event, always stop highlighting the target. DocumentInfo dstDir = null; if (dstId != null) { Cursor dstCursor = mModel.getItem(dstId); checkNotNull(dstCursor, "Cursor cannot be null."); dstDir = DocumentInfo.fromDirectoryCursor(dstCursor); // TODO: Do not drop into the directory where the documents came from. } copyFromClipData(event.getClipData(), dstDir); // Clean up the UI. setDropTargetHighlight(v, false); setDropTargetHighlight(v, false); mSelectionManager.clearSelection(); // Don't copy from the cwd into the cwd. Note: this currently doesn't work for // multi-window drag, because localState isn't carried over from one process to // another. Object src = event.getLocalState(); DocumentInfo dst = getDestination(v); if (Objects.equals(src, dst)) { return false; } copyFromClipData(event.getClipData(), dst); return true; return true; } } return false; return false; } } private DocumentInfo getDestination(View v) { String id = getModelId(v); if (id != null) { Cursor dstCursor = mModel.getItem(id); checkNotNull(dstCursor, "Cursor cannot be null."); return DocumentInfo.fromDirectoryCursor(dstCursor); } if (v == mRecView || v == mEmptyView) { return getDisplayState().stack.peek(); } return null; } private void setDropTargetHighlight(View v, boolean highlight) { private void setDropTargetHighlight(View v, boolean highlight) { // Note: use exact comparison - this code is searching for views which are children of // Note: use exact comparison - this code is searching for views which are children of // the RecyclerView instance in the UI. // the RecyclerView instance in the UI. Loading Loading @@ -1310,10 +1301,10 @@ public class DirectoryFragment extends Fragment if (docs.isEmpty()) { if (docs.isEmpty()) { return false; return false; } } v.startDrag( v.startDragAndDrop( getClipDataFromDocuments(docs), mClipper.getClipDataForDocuments(docs), new DrawableShadowBuilder(getDragShadowIcon(docs)), new DrawableShadowBuilder(getDragShadowIcon(docs)), null, getDisplayState().stack.peek(), View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | View.DRAG_FLAG_GLOBAL_URI_WRITE View.DRAG_FLAG_GLOBAL_URI_WRITE ); ); Loading Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +40 −49 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.FragmentTransaction; import android.app.LoaderManager.LoaderCallbacks; import android.app.LoaderManager.LoaderCallbacks; import android.content.ClipData; import android.content.ClipData; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface; import android.content.Intent; import android.content.Intent; Loading Loading @@ -103,7 +102,6 @@ import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService.OpType; import com.android.documentsui.services.FileOperationService.OpType; import com.android.documentsui.services.FileOperations; import com.android.documentsui.services.FileOperations; import com.google.common.collect.Lists; import com.google.common.collect.Lists; import java.lang.annotation.Retention; import java.lang.annotation.Retention; Loading @@ -111,6 +109,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Objects; /** /** * Display the documents inside a single directory. * Display the documents inside a single directory. Loading Loading @@ -147,8 +146,6 @@ public class DirectoryFragment extends Fragment public @interface RequestCode {} public @interface RequestCode {} public static final int REQUEST_COPY_DESTINATION = 1; public static final int REQUEST_COPY_DESTINATION = 1; static final boolean DEBUG_ENABLE_DND = true; private static final String TAG = "DirectoryFragment"; private static final String TAG = "DirectoryFragment"; private static final int LOADER_ID = 42; private static final int LOADER_ID = 42; Loading Loading @@ -205,10 +202,9 @@ public class DirectoryFragment extends Fragment mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity())); mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity())); // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration). // Make the recycler and the empty views responsive to drop events. if (DEBUG_ENABLE_DND) { mRecView.setOnDragListener(mOnDragListener); setupDragAndDropOnDirectoryView(mRecView); mEmptyView.setOnDragListener(mOnDragListener); } return view; return view; } } Loading Loading @@ -799,10 +795,8 @@ public class DirectoryFragment extends Fragment @Override @Override public void onBindDocumentHolder(DocumentHolder holder, Cursor cursor) { public void onBindDocumentHolder(DocumentHolder holder, Cursor cursor) { if (DEBUG_ENABLE_DND) { setupDragAndDropOnDocumentView(holder.itemView, cursor); setupDragAndDropOnDocumentView(holder.itemView, cursor); } } } @Override @Override public State getDisplayState() { public State getDisplayState() { Loading Loading @@ -938,25 +932,6 @@ public class DirectoryFragment extends Fragment FileOperations.copy(getActivity(), docs, tmpStack); FileOperations.copy(getActivity(), docs, tmpStack); } } private ClipData getClipDataFromDocuments(List<DocumentInfo> docs) { Context context = getActivity(); final ContentResolver resolver = context.getContentResolver(); ClipData clipData = null; for (DocumentInfo doc : docs) { final Uri uri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId); if (clipData == null) { // TODO: figure out what this string should be. // Currently it is not displayed anywhere in the UI, but this might change. final String label = ""; clipData = ClipData.newUri(resolver, label, uri); } else { // TODO: update list of mime types in ClipData. clipData.addItem(new ClipData.Item(uri)); } } return clipData; } public void copySelectedToClipboard() { public void copySelectedToClipboard() { Selection selection = mSelectionManager.getSelection(new Selection()); Selection selection = mSelectionManager.getSelection(new Selection()); if (!selection.isEmpty()) { if (!selection.isEmpty()) { Loading Loading @@ -1025,11 +1000,6 @@ public class DirectoryFragment extends Fragment mFocusManager.restoreLastFocus(); mFocusManager.restoreLastFocus(); } } private void setupDragAndDropOnDirectoryView(View view) { // Listen for drops on non-directory items and empty space. view.setOnDragListener(mOnDragListener); } private void setupDragAndDropOnDocumentView(View view, Cursor cursor) { private void setupDragAndDropOnDocumentView(View view, Cursor cursor) { final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); if (Document.MIME_TYPE_DIR.equals(docMimeType)) { if (Document.MIME_TYPE_DIR.equals(docMimeType)) { Loading @@ -1038,6 +1008,7 @@ public class DirectoryFragment extends Fragment view.setOnDragListener(mOnDragListener); view.setOnDragListener(mOnDragListener); } } // Make all items draggable. view.setOnLongClickListener(mDragHelper); view.setOnLongClickListener(mDragHelper); } } Loading @@ -1058,27 +1029,47 @@ public class DirectoryFragment extends Fragment return true; return true; case DragEvent.ACTION_DRAG_LOCATION: case DragEvent.ACTION_DRAG_LOCATION: return true; case DragEvent.ACTION_DRAG_ENDED: case DragEvent.ACTION_DRAG_ENDED: if (event.getResult()) { // Exit selection mode if the drop was handled. mSelectionManager.clearSelection(); } return true; return true; case DragEvent.ACTION_DROP: case DragEvent.ACTION_DROP: String dstId = getModelId(v); // After a drop event, always stop highlighting the target. DocumentInfo dstDir = null; if (dstId != null) { Cursor dstCursor = mModel.getItem(dstId); checkNotNull(dstCursor, "Cursor cannot be null."); dstDir = DocumentInfo.fromDirectoryCursor(dstCursor); // TODO: Do not drop into the directory where the documents came from. } copyFromClipData(event.getClipData(), dstDir); // Clean up the UI. setDropTargetHighlight(v, false); setDropTargetHighlight(v, false); mSelectionManager.clearSelection(); // Don't copy from the cwd into the cwd. Note: this currently doesn't work for // multi-window drag, because localState isn't carried over from one process to // another. Object src = event.getLocalState(); DocumentInfo dst = getDestination(v); if (Objects.equals(src, dst)) { return false; } copyFromClipData(event.getClipData(), dst); return true; return true; } } return false; return false; } } private DocumentInfo getDestination(View v) { String id = getModelId(v); if (id != null) { Cursor dstCursor = mModel.getItem(id); checkNotNull(dstCursor, "Cursor cannot be null."); return DocumentInfo.fromDirectoryCursor(dstCursor); } if (v == mRecView || v == mEmptyView) { return getDisplayState().stack.peek(); } return null; } private void setDropTargetHighlight(View v, boolean highlight) { private void setDropTargetHighlight(View v, boolean highlight) { // Note: use exact comparison - this code is searching for views which are children of // Note: use exact comparison - this code is searching for views which are children of // the RecyclerView instance in the UI. // the RecyclerView instance in the UI. Loading Loading @@ -1310,10 +1301,10 @@ public class DirectoryFragment extends Fragment if (docs.isEmpty()) { if (docs.isEmpty()) { return false; return false; } } v.startDrag( v.startDragAndDrop( getClipDataFromDocuments(docs), mClipper.getClipDataForDocuments(docs), new DrawableShadowBuilder(getDragShadowIcon(docs)), new DrawableShadowBuilder(getDragShadowIcon(docs)), null, getDisplayState().stack.peek(), View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | View.DRAG_FLAG_GLOBAL_URI_WRITE View.DRAG_FLAG_GLOBAL_URI_WRITE ); ); Loading