-rebase on develop
authortobiasKaminsky <tobias@kaminsky.me>
Fri, 24 Oct 2014 16:34:39 +0000 (18:34 +0200)
committertobiasKaminsky <tobias@kaminsky.me>
Fri, 24 Oct 2014 16:34:39 +0000 (18:34 +0200)
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java [new file with mode: 0644]

index 5c66bfe..1b7a1dd 100644 (file)
@@ -18,6 +18,8 @@
 
 package com.owncloud.android.ui.fragment;
 
+import java.util.ArrayList;
+
 import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
@@ -30,9 +32,10 @@ import android.widget.ListView;
 import android.widget.TextView;
 
 import com.actionbarsherlock.app.SherlockFragment;
-import com.owncloud.android.Log_OC;
 import com.owncloud.android.R;
+import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.ExtendedListView;
+import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
 
 /**
  * TODO extending SherlockListFragment instead of SherlockFragment
@@ -70,7 +73,7 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
     }
 
     public void setFooterView(View footer) {
-        mList.addFooterView(footer);
+        mList.addFooterView(footer, null, false);
         mList.invalidate();
     }
 
diff --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java
new file mode 100644 (file)
index 0000000..34caa02
--- /dev/null
@@ -0,0 +1,447 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011  Bartek Przybylski
+ *   Copyright (C) 2012-2014 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package com.owncloud.android.ui.fragment;
+
+import java.io.File;
+import java.util.Vector;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.TextView;
+import android.view.LayoutInflater;
+
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.FileMenuFilter;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.ui.activity.MoveActivity;
+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.RemoveFileDialogFragment;
+import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
+import com.owncloud.android.ui.preview.PreviewImageFragment;
+import com.owncloud.android.ui.preview.PreviewMediaFragment;
+
+/**
+ * A Fragment that lists all files and folders in a given path.
+ * 
+ * TODO refactorize to get rid of direct dependency on FileDisplayActivity
+ * 
+ * @author Bartek Przybylski
+ * @author masensio
+ * @author David A. Velasco
+ */
+public class OCFileListFragment extends ExtendedListFragment {
+    
+    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 View mFooterView;
+    
+    private OCFile mTargetFile;
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        Log_OC.e(TAG, "onAttach");
+        try {
+            mContainerActivity = (FileFragment.ContainerActivity) activity;
+            
+        } catch (ClassCastException e) {
+            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 " + 
+                    SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
+        }
+    }
+
+    
+    @Override
+    public void onDetach() {
+        setOnRefreshListener(null);
+        mContainerActivity = null;
+        super.onDetach();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        Log_OC.e(TAG, "onActivityCreated() start");
+
+        if (savedInstanceState != null) {
+            mFile = savedInstanceState.getParcelable(KEY_FILE);
+        }
+
+        mFooterView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
+                        R.layout.list_footer, null, false);
+        setFooterView(mFooterView);
+
+        Bundle args = getArguments();
+        boolean justFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false); 
+        mAdapter = new FileListListAdapter(
+                justFolders,
+                getSherlockActivity(), 
+                mContainerActivity
+                );
+        setListAdapter(mAdapter);
+
+        registerForContextMenu(getListView());
+        getListView().setOnCreateContextMenuListener(this);
+    }
+
+    /**
+     * Saves the current listed folder.
+     */
+    @Override
+    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 
+     * database, it continues browsing up until finding an existing folders.
+     * 
+     * return       Count of folder levels browsed up.
+     */
+    public int onBrowseUp() {
+        OCFile parentDir = null;
+        int moveCount = 0;
+        
+        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;
+                parentDir = storageManager.getFileByPath(parentPath);
+                moveCount++;
+            } else {
+                parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH);
+            }
+            while (parentDir == null) {
+                parentPath = new File(parentPath).getParent();
+                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
+            mFile = parentDir;
+            
+            listDirectory(mFile);
+
+            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()) { 
+                // update state and view of this fragment
+                listDirectory(file);
+                // then, notify parent activity to let it update its state and view
+                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 (file.isDown()) {
+                    if (PreviewMediaFragment.canBePreviewed(file)) {
+                        // media preview
+                        ((FileDisplayActivity)mContainerActivity).startMediaPreview(file, 0, true);
+                    } else {
+                        mContainerActivity.getFileOperationsHelper().openFile(file);
+                    }
+                    
+                } else {
+                    // automatic download, preview on finish
+                    ((FileDisplayActivity)mContainerActivity).startDownloadForPreview(file);
+                }
+                    
+            }
+            
+        } else {
+            Log_OC.d(TAG, "Null object in ListAdapter!!");
+        }
+        
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    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); 
+        if (allowContextualActions) {
+            MenuInflater inflater = getSherlockActivity().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,
+                    mContainerActivity.getStorageManager().getAccount(),
+                    mContainerActivity,
+                    getSherlockActivity()
+                );
+                mf.filter(menu);
+            }
+            
+            /// additional restrictions for this fragment 
+            // TODO allow in the future 'open with' for previewable files
+            MenuItem item = menu.findItem(R.id.action_open_file_with);
+            if (item != null) {
+                item.setVisible(false);
+                item.setEnabled(false);
+            }
+            /// TODO break this direct dependency on FileDisplayActivity... if possible
+            FileFragment frag = ((FileDisplayActivity)getSherlockActivity()).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);
+                }
+            }
+        }
+    }
+    
+    
+    /**
+     * {@inhericDoc}
+     */
+    @Override
+    public boolean onContextItemSelected (MenuItem item) {
+        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
+        mTargetFile = (OCFile) mAdapter.getItem(info.position);
+        switch (item.getItemId()) {                
+            case R.id.action_share_file: {
+                mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
+                return true;
+            }
+            case R.id.action_unshare_file: {
+                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile);
+                return true;
+            }
+            case R.id.action_rename_file: {
+                RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
+                dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
+                return true;
+            }
+            case R.id.action_remove_file: {
+                RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
+                dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
+                return true;
+            }
+            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);
+                return true;
+            }
+            case R.id.action_see_details: {
+                mContainerActivity.showDetails(mTargetFile);
+                return true;
+            }
+            case R.id.action_send_file: {
+                // Obtain the file
+                if (!mTargetFile.isDown()) {  // Download the file
+                    Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
+                    ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile);
+                    
+                } else {
+                    mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+                }
+                return true;
+            }
+            case R.id.action_move: {
+                Intent action = new Intent(getActivity(), MoveActivity.class);
+
+                // Pass mTargetFile that contains info of selected file/folder
+                action.putExtra(MoveActivity.EXTRA_TARGET_FILE, mTargetFile);
+                getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
+                return true;
+            }
+            default:
+                return super.onContextItemSelected(item); 
+        }
+    }
+
+
+    /**
+     * Use this to query the {@link OCFile} that is currently
+     * being displayed by this fragment
+     * @return The currently viewed OCFile
+     */
+    public OCFile getCurrentFile(){
+        return mFile;
+    }
+    
+    /**
+     * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
+     */
+    public void listDirectory(){
+        listDirectory(null);
+    }
+    
+    /**
+     * 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) {
+        FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+        if (storageManager != null) {
+
+            // Check input parameters for 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()){
+                Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
+                directory = storageManager.getFileById(directory.getParentId());
+            }
+
+            mAdapter.swapDirectory(directory, storageManager);
+            if (mFile == null || !mFile.equals(directory)) {
+                mList.setSelectionFromTop(0, 0);
+            }
+            mFile = directory;
+            
+            // Update Footer
+            TextView footerText = (TextView) mFooterView.findViewById(R.id.footerText);
+            Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
+            footerText.setText(generateFooterText(directory));
+            Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
+        }
+    }
+    
+    private String generateFooterText(OCFile directory) {
+        Integer files = 0;
+        Integer folders = 0;
+
+        FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+        Vector<OCFile> mFiles = storageManager.getFolderContent(mFile);
+
+        for (OCFile ocFile : mFiles) {
+            if (ocFile.isFolder()) {
+                folders++;
+            } else {
+                files++;
+            }
+        }
+
+        String output = "";
+
+        if (folders == 1) {
+            output = folders.toString() + " " + getResources().getString(R.string.file_list_folder) + ", ";
+        } else if (folders > 1) {
+            output = folders.toString() + " " + getResources().getString(R.string.file_list_folders) + ", ";
+        }
+        if (files == 1) {
+            output = output + files.toString() + " " + getResources().getString(R.string.file_list_file);
+        } else {
+            output = output + files.toString() + " " + getResources().getString(R.string.file_list_files);
+        }
+        return output;
+    }
+    
+    public void sortByName(boolean descending) {
+        mAdapter.setSortOrder(FileListListAdapter.SORT_NAME, descending);
+    }
+
+    public void sortByDate(boolean descending) {
+        mAdapter.setSortOrder(FileListListAdapter.SORT_DATE, descending);
+    }
+
+    public void sortBySize(boolean descending) {
+        mAdapter.setSortOrder(FileListListAdapter.SORT_SIZE, descending);
+    }  
+
+}