Merge remote-tracking branch 'remotes/upstream/resizedImages' into beta
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / fragment / OCFileListFragment.java
index 091549a..02105d9 100644 (file)
  */
 package com.owncloud.android.ui.fragment;
 
-import java.io.File;
-
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.ContextMenu;
+import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.PopupMenu;
 
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -48,31 +48,35 @@ import com.owncloud.android.ui.activity.FolderPickerActivity;
 import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
 import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
+import com.owncloud.android.ui.dialog.FileActionsDialogFragment;
 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
 import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.ui.preview.PreviewTextFragment;
+
+import java.io.File;
 
 /**
  * A Fragment that lists all files and folders in a given path.
- * 
+ *
  * TODO refactor to get rid of direct dependency on FileDisplayActivity
  */
-public class OCFileListFragment extends ExtendedListFragment {
+public class OCFileListFragment extends ExtendedListFragment implements FileActionsDialogFragment.FileActionsDialogFragmentListener {
     
     private static final String TAG = OCFileListFragment.class.getSimpleName();
 
     private static final String MY_PACKAGE = OCFileListFragment.class.getPackage() != null ?
             OCFileListFragment.class.getPackage().getName() : "com.owncloud.android.ui.fragment";
-            
+
     public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS";
     public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL";
-            
+
     private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE";
 
     private FileFragment.ContainerActivity mContainerActivity;
-   
+
     private OCFile mFile = null;
     private FileListListAdapter mAdapter;
     private boolean mJustFolders;
@@ -90,21 +94,21 @@ public class OCFileListFragment extends ExtendedListFragment {
         Log_OC.e(TAG, "onAttach");
         try {
             mContainerActivity = (FileFragment.ContainerActivity) activity;
-            
+
         } catch (ClassCastException e) {
-            throw new ClassCastException(activity.toString() + " must implement " + 
+            throw new ClassCastException(activity.toString() + " must implement " +
                     FileFragment.ContainerActivity.class.getSimpleName());
         }
         try {
             setOnRefreshListener((OnEnforceableRefreshListener) activity);
             
         } catch (ClassCastException e) {
-            throw new ClassCastException(activity.toString() + " must implement " + 
+            throw new ClassCastException(activity.toString() + " must implement " +
                     SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
         }
     }
 
-    
+
     @Override
     public void onDetach() {
         setOnRefreshListener(null);
@@ -136,41 +140,94 @@ public class OCFileListFragment extends ExtendedListFragment {
                 mJustFolders,
                 getActivity(),
                 mContainerActivity
-                );
+        );
         setListAdapter(mAdapter);
 
-        registerForContextMenu();
+        registerLongClickListener();
   }
 
+    private void registerLongClickListener() {
+        getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+            public boolean onItemLongClick(AdapterView<?> arg0, View v,
+                                           int index, long arg3) {
+                showFileAction(index);
+                return true;
+            }
+        });
+    }
+
+
+    private void showFileAction(int fileIndex) {
+        Bundle args = getArguments();
+        PopupMenu pm = new PopupMenu(getActivity(),null);
+        Menu menu = pm.getMenu();
+
+        boolean allowContextualActions =
+                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
+
+        if (allowContextualActions) {
+            MenuInflater inflater = getActivity().getMenuInflater();
+
+            inflater.inflate(R.menu.file_actions_menu, menu);
+            OCFile targetFile = (OCFile) mAdapter.getItem(fileIndex);
+
+            if (mContainerActivity.getStorageManager() != null) {
+                FileMenuFilter mf = new FileMenuFilter(
+                        targetFile,
+                        mContainerActivity.getStorageManager().getAccount(),
+                        mContainerActivity,
+                        getActivity()
+                );
+                mf.filter(menu);
+            }
+
+            /// TODO break this direct dependency on FileDisplayActivity... if possible
+            MenuItem item = menu.findItem(R.id.action_open_file_with);
+            FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment();
+            if (frag != null && frag instanceof FileDetailFragment &&
+                    frag.getFile().getFileId() == targetFile.getFileId()) {
+                item = menu.findItem(R.id.action_see_details);
+                if (item != null) {
+                    item.setVisible(false);
+                    item.setEnabled(false);
+                }
+            }
+
+            FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, fileIndex, targetFile.getFileName());
+            dialog.setTargetFragment(this, 0);
+            dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS);
+        }
+    }
+
     /**
      * Saves the current listed folder.
      */
     @Override
-    public void onSaveInstanceState (Bundle outState) {
+    public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putParcelable(KEY_FILE, mFile);
     }
-    
+
     /**
      * Call this, when the user presses the up button.
-     * 
-     * Tries to move up the current folder one level. If the parent folder was removed from the 
+     *
+     * Tries to move up the current folder one level. If the parent folder was removed from the
      * database, it continues browsing up until finding an existing folders.
-     * 
+     * <p/>
      * return       Count of folder levels browsed up.
      */
     public int onBrowseUp() {
         OCFile parentDir = null;
         int moveCount = 0;
-        
-        if(mFile != null){
+
+        if (mFile != null) {
             FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
-            
+
             String parentPath = null;
             if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {
                 parentPath = new File(mFile.getRemotePath()).getParent();
-                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : 
-                       parentPath + OCFile.PATH_SEPARATOR;
+                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
+                        parentPath + OCFile.PATH_SEPARATOR;
                 parentDir = storageManager.getFileByPath(parentPath);
                 moveCount++;
             } else {
@@ -178,8 +235,8 @@ public class OCFileListFragment extends ExtendedListFragment {
             }
             while (parentDir == null) {
                 parentPath = new File(parentPath).getParent();
-                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : 
-                       parentPath + OCFile.PATH_SEPARATOR;
+                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
+                        parentPath + OCFile.PATH_SEPARATOR;
                 parentDir = storageManager.getFileByPath(parentPath);
                 moveCount++;
             }   // exit is granted because storageManager.getFileByPath("/") never returns null
@@ -189,20 +246,20 @@ public class OCFileListFragment extends ExtendedListFragment {
             listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/);
 
             onRefresh(false);
-            
+
             // restore index and top position
             restoreIndexAndTopPosition();
-            
+
         }   // else - should never happen now
-   
+
         return moveCount;
     }
-    
+
     @Override
     public void onItemClick(AdapterView<?> l, View v, int position, long id) {
         OCFile file = (OCFile) mAdapter.getItem(position);
         if (file != null) {
-            if (file.isFolder()) { 
+            if (file.isFolder()) {
                 // update state and view of this fragment
                 // TODO Enable when "On Device" is recovered ?
                 listDirectory(file/*, MainApp.getOnlyOnDevice()*/);
@@ -210,45 +267,45 @@ public class OCFileListFragment extends ExtendedListFragment {
                 mContainerActivity.onBrowsedDownTo(file);
                 // save index and top position
                 saveIndexAndTopPosition(position);
-                
+
             } else { /// Click on a file
                 if (PreviewImageFragment.canBePreviewed(file)) {
                     // preview image - it handles the download, if needed
                     ((FileDisplayActivity)mContainerActivity).startImagePreview(file);
-                    
+                } else if (PreviewTextFragment.canBePreviewed(file)){
+                    ((FileDisplayActivity)mContainerActivity).startTextPreview(file);
                 } else if (file.isDown()) {
                     if (PreviewMediaFragment.canBePreviewed(file)) {
                         // media preview
-                        ((FileDisplayActivity)mContainerActivity).startMediaPreview(file, 0, true);
+                        ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true);
                     } else {
                         mContainerActivity.getFileOperationsHelper().openFile(file);
                     }
                     
                 }
             }
-            
+
         } else {
             Log_OC.d(TAG, "Null object in ListAdapter!!");
         }
-        
+
     }
-    
+
     /**
      * {@inheritDoc}
      */
     @Override
-    public void onCreateContextMenu (
+    public void onCreateContextMenu(
             ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu, v, menuInfo);
         Bundle args = getArguments();
-        boolean allowContextualActions = 
-                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); 
+        boolean allowContextualActions =
+                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
         if (allowContextualActions) {
             MenuInflater inflater = getActivity().getMenuInflater();
             inflater.inflate(R.menu.file_actions_menu, menu);
             AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
             OCFile targetFile = (OCFile) mAdapter.getItem(info.position);
-            
+
             if (mContainerActivity.getStorageManager() != null) {
                 FileMenuFilter mf = new FileMenuFilter(
                     targetFile,
@@ -272,16 +329,14 @@ public class OCFileListFragment extends ExtendedListFragment {
             }
         }
     }
-    
-    
+
     /**
-     * {@inhericDoc}
+     * {@inheritDoc}
      */
     @Override
-    public boolean onContextItemSelected (MenuItem item) {
-        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
-        mTargetFile = (OCFile) mAdapter.getItem(info.position);
-        switch (item.getItemId()) {                
+    public boolean onFileActionChosen(int menuId, int filePosition) {
+        mTargetFile = (OCFile) mAdapter.getItem(filePosition);
+        switch (menuId) {
             case R.id.action_share_file: {
                 mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
                 return true;
@@ -304,14 +359,14 @@ public class OCFileListFragment extends ExtendedListFragment {
                 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
                 return true;
             }
-            case R.id.action_download_file: 
+            case R.id.action_download_file:
             case R.id.action_sync_file: {
                 mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
                 return true;
             }
             case R.id.action_cancel_download:
             case R.id.action_cancel_upload: {
-                ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
+                ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
                 return true;
             }
             case R.id.action_see_details: {
@@ -322,8 +377,8 @@ public class OCFileListFragment extends ExtendedListFragment {
                 // Obtain the file
                 if (!mTargetFile.isDown()) {  // Download the file
                     Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
-                    ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile);
-                    
+                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
+
                 } else {
                     mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
                 }
@@ -337,8 +392,37 @@ public class OCFileListFragment extends ExtendedListFragment {
                 getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
                 return true;
             }
+            case R.id.action_favorite_file: {
+                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
+                return true;
+            }
+            case R.id.action_unfavorite_file: {
+                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
+                return true;
+            }
+            case R.id.action_copy:
+                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+
+                // Pass mTargetFile that contains info of selected file/folder
+                action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
+                getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
+                return true;
             default:
-                return super.onContextItemSelected(item); 
+                return false;
+        }
+    }
+    
+    /**
+     * {@inhericDoc}
+     */
+    @Override
+    public boolean onContextItemSelected (MenuItem item) {
+        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+        boolean matched = onFileActionChosen(item.getItemId(), ((AdapterContextMenuInfo) item.getMenuInfo()).position);
+        if(!matched) {
+            return super.onContextItemSelected(item);
+        } else {
+            return matched;
         }
     }
 
@@ -346,12 +430,13 @@ public class OCFileListFragment extends ExtendedListFragment {
     /**
      * Use this to query the {@link OCFile} that is currently
      * being displayed by this fragment
+     *
      * @return The currently viewed OCFile
      */
-    public OCFile getCurrentFile(){
+    public OCFile getCurrentFile() {
         return mFile;
     }
-    
+
     /**
      * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
      */
@@ -365,12 +450,12 @@ public class OCFileListFragment extends ExtendedListFragment {
         // TODO Enable when "On Device" is recovered ?
         listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/);
     }
-    
+
     /**
      * Lists the given directory on the view. When the input parameter is null,
      * it will either refresh the last known directory. list the root
      * if there never was a directory.
-     * 
+     *
      * @param directory File to be listed
      */
     public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) {
@@ -378,18 +463,18 @@ public class OCFileListFragment extends ExtendedListFragment {
         if (storageManager != null) {
 
             // Check input parameters for null
-            if(directory == null){
-                if(mFile != null){
+            if (directory == null) {
+                if (mFile != null) {
                     directory = mFile;
                 } else {
                     directory = storageManager.getFileByPath("/");
                     if (directory == null) return; // no files, wait for sync
                 }
             }
-        
-        
+
+
             // If that's not a directory -> List its parent
-            if(!directory.isFolder()){
+            if (!directory.isFolder()) {
                 Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
                 directory = storageManager.getFileById(directory.getParentId());
             }
@@ -416,9 +501,12 @@ public class OCFileListFragment extends ExtendedListFragment {
                 if (file.isFolder()) {
                     foldersCount++;
                 } else {
-                    filesCount++;
-                    if (file.isImage()){
-                        imagesCount++;
+                    if (!file.isHidden()) {
+                        filesCount++;
+
+                        if (file.isImage()) {
+                            imagesCount++;
+                        }
                     }
                 }
             }
@@ -431,6 +519,7 @@ public class OCFileListFragment extends ExtendedListFragment {
             if (version != null && version.supportsRemoteThumbnails() &&
                 imagesCount > 0 && imagesCount == filesCount) {
                 switchToGridView();
+                registerLongClickListener();
             } else {
                 switchToListView();
             }
@@ -438,27 +527,45 @@ public class OCFileListFragment extends ExtendedListFragment {
     }
 
     private String generateFooterText(int filesCount, int foldersCount) {
-        String output = "";
-        if (filesCount > 0){
-            if (filesCount == 1) {
-                output = output + filesCount + " " + getResources().getString(R.string.file_list_file);
-            } else {
-                output = output + filesCount + " " + getResources().getString(R.string.file_list_files);
+        String output;
+        if (filesCount <= 0) {
+            if (foldersCount <= 0) {
+                output = "";
+
+            } else if (foldersCount == 1) {
+                output = getResources().getString(R.string.file_list__footer__folder);
+
+            } else { // foldersCount > 1
+                output = getResources().getString(R.string.file_list__footer__folders, foldersCount);
             }
-        }
-        if (foldersCount > 0 && filesCount > 0){
-            output = output + ", ";
-        }
-        if (foldersCount == 1) {
-            output = output + foldersCount + " " + getResources().getString(R.string.file_list_folder);
-        } else if (foldersCount > 1) {
-            output = output + foldersCount + " " + getResources().getString(R.string.file_list_folders);
-        }
 
+        } else if (filesCount == 1) {
+            if (foldersCount <= 0) {
+                output = getResources().getString(R.string.file_list__footer__file);
+
+            } else if (foldersCount == 1) {
+                output = getResources().getString(R.string.file_list__footer__file_and_folder);
+
+            } else { // foldersCount > 1
+                output = getResources().getString(R.string.file_list__footer__file_and_folders, foldersCount);
+            }
+        } else {    // filesCount > 1
+            if (foldersCount <= 0) {
+                output = getResources().getString(R.string.file_list__footer__files, filesCount);
+
+            } else if (foldersCount == 1) {
+                output = getResources().getString(R.string.file_list__footer__files_and_folder, filesCount);
+
+            } else { // foldersCount > 1
+                output = getResources().getString(
+                        R.string.file_list__footer__files_and_folders, filesCount, foldersCount
+                );
+
+            }
+        }
         return output;
     }
 
-
     public void sortByName(boolean descending) {
         mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
     }
@@ -469,8 +576,5 @@ public class OCFileListFragment extends ExtendedListFragment {
 
     public void sortBySize(boolean descending) {
         mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
-    }  
-    
-   
-    
+    }
 }