Merge remote-tracking branch 'remotes/upstream/sortInUploadFilesActivity' into beta
authortobiasKaminsky <tobias@kaminsky.me>
Thu, 29 Oct 2015 17:41:52 +0000 (18:41 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Thu, 29 Oct 2015 17:41:52 +0000 (18:41 +0100)
1  2 
CHANGELOG.md
src/com/owncloud/android/ui/activity/UploadFilesActivity.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java
src/com/owncloud/android/utils/FileStorageUtils.java
src/third_parties/daveKoeller/AlphanumComparator.java

diff --combined CHANGELOG.md
@@@ -1,14 -1,31 +1,15 @@@
 -
 -## 1.7.1 (April 2015)
 -
 -- Share link even with password enforced by server
 -- Get the app ready for oc 8.1 servers
 -- Added option to create new folder in uploads from external apps
 -- Improved management of deleted users
 -- Bugs fixed
 -  + Fixed crash on Android 2.x devices
 -  + Improvements on uploads
 -
 -## 1.7.0 (February 2015)
 -
 -- Download full folders
 -- Grid view for images
 -- Remote thumbnails (OC Server 8.0+)
 -- Added number of files and folders at the end of the list
 -- "Open with" in contextual menu
 -- Downloads added to Media Provider
 -- Uploads:
 -  + Local thumbnails in section "Files"
 -  + Multiple selection in "Content from other apps" (Android 4.3+)
 -- Gallery: 
 -  + proper handling of EXIF
 -  + obey sorting in the list of files
 -- Settings view updated
 -- Improved subjects in e-mails
 -- Bugs fixed
 -
 -
 -
 +# 2015-10-29
 +- PR [#1099](https://github.com/owncloud/android/pull/1099) "Switch list vs grid" merged
 +- PR [#1100](https://github.com/owncloud/android/pull/1100) "Material FAB with speed dial implementation" merged
 +- PR [#1209](https://github.com/owncloud/android/pull/1209) "Material buttons - before in #1090" merged
 +- PR [#1205](https://github.com/owncloud/android/pull/1205) "Switch between online and offline files" merged
 +- PR [#1195](https://github.com/owncloud/android/pull/1195) "Resize Cache" merged
 +- PR [#1187](https://github.com/owncloud/android/pull/1187) "Video: Big thumbnails" merged
++- PR [#1058](https://github.com/owncloud/android/pull/1058) "add sort to UploadFileActiviy" merged
 +
 +
 +# 2015-10-26
 +- start of branch
 +- PR [#745](https://github.com/owncloud/android/pull/745) merged
 +- PR [#1044](https://github.com/owncloud/android/pull/1044) merged: < 8.1: GalleryPlus app needed, >= 8.2 Gallery app needed
 +- PR [#1111](https://github.com/owncloud/android/pull/1111) merged
  
  package com.owncloud.android.ui.activity;
  
 -import java.io.File;
 -
  import android.accounts.Account;
+ import android.app.AlertDialog;
+ import android.content.DialogInterface;
  import android.content.Intent;
+ import android.content.SharedPreferences;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.os.Environment;
+ import android.preference.PreferenceManager;
  import android.support.v4.app.DialogFragment;
  import android.support.v7.app.ActionBar;
+ import android.view.Menu;
+ import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
@@@ -38,13 -46,12 +44,13 @@@ import android.widget.TextView
  import com.owncloud.android.R;
  import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 -import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
  import com.owncloud.android.ui.dialog.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
 +import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
  import com.owncloud.android.ui.fragment.LocalFileListFragment;
 -import com.owncloud.android.utils.DisplayUtils;
  import com.owncloud.android.utils.FileStorageUtils;
  
 +import java.io.File;
 +
  
  /**
   * Displays local files and let the user choose what of them wants to upload
@@@ -116,6 -123,7 +122,6 @@@ public class UploadFilesActivity extend
              
          // Action bar setup
          ActionBar actionBar = getSupportActionBar();
 -        actionBar.setIcon(DisplayUtils.getSeasonalIconId());
          actionBar.setHomeButtonEnabled(true);   // mandatory since Android ICS, according to the
                                                  // official documentation
          actionBar.setDisplayHomeAsUpEnabled(mCurrentDir != null && mCurrentDir.getName() != null);
          Log_OC.d(TAG, "onCreate() end");
      }
  
+     @Override
+     public boolean onCreateOptionsMenu(Menu menu) {
+         MenuInflater inflater = getMenuInflater();
+         inflater.inflate(R.menu.uploader_menu, menu);
+         return true;
+     }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
                  }
                  break;
              }
+             case R.id.action_sort: {
+                 SharedPreferences appPreferences = PreferenceManager
+                         .getDefaultSharedPreferences(this);
+                 // Read sorting order, default to sort by name ascending
+                 Integer sortOrder = appPreferences
+                         .getInt("sortOrder", FileStorageUtils.SORT_NAME);
+                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                 builder.setTitle(R.string.actionbar_sort_title)
+                         .setSingleChoiceItems(R.array.actionbar_sortby, sortOrder ,
+                                 new DialogInterface.OnClickListener() {
+                                     public void onClick(DialogInterface dialog, int which) {
+                                         switch (which){
+                                             case 0:
+                                                 mFileListFragment.sortByName(true);
+                                                 break;
+                                             case 1:
+                                                 mFileListFragment.sortByDate(false);
+                                                 break;
+                                         }
+                                         dialog.dismiss();
+                                     }
+                                 });
+                 builder.create().show();
+                 break;
+             }
              default:
                  retval = super.onOptionsItemSelected(item);
          }
@@@ -4,7 -4,6 +4,7 @@@
   *   @author Bartek Przybylski\r
   *   @author Tobias Kaminsky\r
   *   @author David A. Velasco\r
 + *   @author masensio\r
   *   Copyright (C) 2011  Bartek Przybylski\r
   *   Copyright (C) 2015 ownCloud Inc.\r
   *\r
@@@ -55,7 -54,6 +55,7 @@@ import com.owncloud.android.services.Op
  import com.owncloud.android.ui.activity.ComponentsGetter;\r
  import com.owncloud.android.utils.DisplayUtils;\r
  import com.owncloud.android.utils.FileStorageUtils;\r
 +import com.owncloud.android.utils.MimetypeIconUtil;\r
  \r
  \r
  /**\r
@@@ -154,7 -152,7 +154,7 @@@ public class FileListListAdapter extend
          ViewType viewType;\r
          if (!mGridMode){\r
              viewType = ViewType.LIST_ITEM;\r
 -        } else if (file.isImage()){\r
 +        } else if (file.isImage() || file.isVideo()){\r
              viewType = ViewType.GRID_IMAGE;\r
          } else {\r
              viewType = ViewType.GRID_ITEM;\r
              switch (viewType){\r
                  case LIST_ITEM:\r
                      TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
 +                    TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);\r
                      TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
                      ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
  \r
  \r
                      checkBoxV.setVisibility(View.GONE);\r
  \r
 +                    fileSizeSeparatorV.setVisibility(View.VISIBLE);\r
                      fileSizeV.setVisibility(View.VISIBLE);\r
                      fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
  \r
                              } else {\r
                                  if (parentList.isItemChecked(position)) {\r
                                      checkBoxV.setImageResource(\r
 -                                            android.R.drawable.checkbox_on_background);\r
 +                                            R.drawable.ic_checkbox_marked);\r
                                  } else {\r
                                      checkBoxV.setImageResource(\r
 -                                            android.R.drawable.checkbox_off_background);\r
 +                                            R.drawable.ic_checkbox_blank_outline);\r
                                  }\r
                                  checkBoxV.setVisibility(View.VISIBLE);\r
                              }\r
                          }\r
  \r
                      } else { //Folder\r
 +                        fileSizeSeparatorV.setVisibility(View.INVISIBLE);\r
                          fileSizeV.setVisibility(View.INVISIBLE);\r
                      }\r
  \r
                      }\r
  \r
                      // share with me icon\r
 -                    if (!file.isFolder()) {\r
 -                        ImageView sharedWithMeIconV = (ImageView)\r
 -                                view.findViewById(R.id.sharedWithMeIcon);\r
 -                        sharedWithMeIconV.bringToFront();\r
 -                        if (checkIfFileIsSharedWithMe(file)) {\r
 -                            sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 -                        } else {\r
 -                            sharedWithMeIconV.setVisibility(View.GONE);\r
 -                        }\r
 +                    ImageView sharedWithMeIconV = (ImageView)\r
 +                            view.findViewById(R.id.sharedWithMeIcon);\r
 +                    sharedWithMeIconV.bringToFront();\r
 +                    if (checkIfFileIsSharedWithMe(file) &&\r
 +                            (!file.isFolder() || !mGridMode)) {\r
 +                        sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                    } else {\r
 +                        sharedWithMeIconV.setVisibility(View.GONE);\r
                      }\r
  \r
                      break;\r
              \r
              // this if-else is needed even though favorite icon is visible by default\r
              // because android reuses views in listview\r
 -            if (!file.keepInSync()) {\r
 +            if (!file.isFavorite()) {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);\r
              } else {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE);\r
                                      task\r
                                      );\r
                              fileIcon.setImageDrawable(asyncDrawable);\r
 -                            task.execute(file);\r
 +                            task.execute(file, true);\r
                          }\r
                      }\r
 +\r
 +                    if (file.getMimetype().equalsIgnoreCase("image/png")) {\r
 +                        fileIcon.setBackgroundColor(mContext.getResources()\r
 +                                .getColor(R.color.background_color));\r
 +                    }\r
 +\r
 +\r
                  } else {\r
 -                    fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(),\r
 +                    fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(file.getMimetype(),\r
                              file.getFileName()));\r
                  }\r
  \r
              } else {\r
                  // Folder\r
 -                if (checkIfFileIsSharedWithMe(file)) {\r
 -                    fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
 -                } else if (file.isShareByLink()) {\r
 -                    // If folder is sharedByLink, icon folder must be changed to\r
 -                    // folder-public one\r
 -                    fileIcon.setImageResource(R.drawable.folder_public);\r
 -                } else {\r
 -                    fileIcon.setImageResource(\r
 -                            DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName())\r
 -                    );\r
 -                }\r
 +                fileIcon.setImageResource(\r
 +                        MimetypeIconUtil.getFolderTypeIconId(\r
 +                                checkIfFileIsSharedWithMe(file), file.isShareByLink()));\r
              }\r
          }\r
  \r
       *                                  mStorageManager if is different (and not NULL)\r
       */\r
      public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager\r
 -            /*, boolean onlyOnDevice*/) {\r
 +            , boolean onlyOnDevice) {\r
          mFile = directory;\r
          if (updatedStorageManager != null && updatedStorageManager != mStorageManager) {\r
              mStorageManager = updatedStorageManager;\r
              mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
          }\r
          if (mStorageManager != null) {\r
 -            // TODO Enable when "On Device" is recovered ?\r
 -            mFiles = mStorageManager.getFolderContent(mFile/*, onlyOnDevice*/);\r
 +            mFiles = mStorageManager.getFolderContent(mFile, onlyOnDevice);\r
              mFilesOrig.clear();\r
              mFilesOrig.addAll(mFiles);\r
              \r
              mFiles = null;\r
          }\r
  \r
-         mFiles = FileStorageUtils.sortFolder(mFiles);\r
+         mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
          notifyDataSetChanged();\r
      }\r
      \r
          FileStorageUtils.mSortAscending = ascending;\r
          \r
  \r
-         mFiles = FileStorageUtils.sortFolder(mFiles);\r
+         mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
          notifyDataSetChanged();\r
  \r
      }\r
      public void setGridMode(boolean gridMode) {\r
          mGridMode = gridMode;\r
      }\r
 +\r
 +    public boolean isGridMode() {\r
 +        return mGridMode;\r
 +    }\r
  }\r
@@@ -25,7 -25,9 +25,9 @@@ import java.util.Arrays
  import java.util.Comparator;
  
  import android.content.Context;
+ import android.content.SharedPreferences;
  import android.graphics.Bitmap;
+ import android.preference.PreferenceManager;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
@@@ -37,25 -39,31 +39,35 @@@ import android.widget.TextView
  
  import com.owncloud.android.R;
  import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 +import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.utils.BitmapUtils;
  import com.owncloud.android.utils.DisplayUtils;
 +import com.owncloud.android.utils.MimetypeIconUtil;
+ import com.owncloud.android.utils.FileStorageUtils;
  
  /**
   * This Adapter populates a ListView with all files and directories contained
   * in a local directory
   */
  public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
 -    
 +
 +    private static final String TAG = LocalFileListAdapter.class.getSimpleName();
 +
      private Context mContext;
      private File mDirectory;
      private File[] mFiles = null;
+     private SharedPreferences mAppPreferences;
      
      public LocalFileListAdapter(File directory, Context context) {
          mContext = context;
+         mAppPreferences = PreferenceManager
+                 .getDefaultSharedPreferences(mContext);
+         // Read sorting order, default to sort by name ascending
+         FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0);
+         FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true);
          swapDirectory(directory);
      }
  
              fileName.setText(name);
              
              ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);
 +
 +            /** Cancellation needs do be checked and done before changing the drawable in fileIcon, or
 +             * {@link ThumbnailsCacheManager#cancelPotentialWork} will NEVER cancel any task.
 +             **/
 +            boolean allowedToCreateNewThumbnail = (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon));
 +
              if (!file.isDirectory()) {
                  fileIcon.setImageResource(R.drawable.file);
              } else {
              fileIcon.setTag(file.hashCode());
  
              TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
 +            TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);
              TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
              ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
              if (!file.isDirectory()) {
 +                fileSizeSeparatorV.setVisibility(View.VISIBLE);
                  fileSizeV.setVisibility(View.VISIBLE);
                  fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
  
                      checkBoxV.setVisibility(View.GONE);
                  } else {
                      if (parentList.isItemChecked(position)) {
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
 +                        checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
                      } else {
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
 +                        checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
                      }
                      checkBoxV.setVisibility(View.VISIBLE);
                  }
                      } else {
  
                          // generate new Thumbnail
 -                        if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
 +                        if (allowedToCreateNewThumbnail) {
                              final ThumbnailsCacheManager.ThumbnailGenerationTask task =
                                      new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon);
                              if (thumbnail == null) {
                                        );
                              fileIcon.setImageDrawable(asyncDrawable);
                              task.execute(file);
 -                        }
 +                            Log_OC.v(TAG, "Executing task to generate a new thumbnail");
 +
 +                        } // else, already being generated, don't restart it
                      }
                  } else {
 -                    fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(null, file.getName()));
 +                    fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(null, file.getName()));
                  }  
  
              } else {
 +                fileSizeSeparatorV.setVisibility(View.GONE);
                  fileSizeV.setVisibility(View.GONE);
                  lastModV.setVisibility(View.GONE);
                  checkBoxV.setVisibility(View.GONE);
                  }
              
              });
+             mFiles = FileStorageUtils.sortLocalFolder(mFiles);
          }
          notifyDataSetChanged();
      }
+     public void setSortOrder(Integer order, boolean ascending) {
+         SharedPreferences.Editor editor = mAppPreferences.edit();
+         editor.putInt("sortOrder", order);
+         editor.putBoolean("sortAscending", ascending);
+         editor.commit();
+         FileStorageUtils.mSortOrder = order;
+         FileStorageUtils.mSortAscending = ascending;
+         mFiles = FileStorageUtils.sortLocalFolder(mFiles);
+         notifyDataSetChanged();
+     }
  }
@@@ -37,6 -37,7 +37,7 @@@ import android.widget.ListView
  import com.owncloud.android.R;
  import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.ui.adapter.LocalFileListAdapter;
+ import com.owncloud.android.utils.FileStorageUtils;
  
  
  /**
@@@ -54,6 -55,7 +55,6 @@@ public class LocalFileListFragment exte
      /** Adapter to connect the data from the directory with the View object */
      private LocalFileListAdapter mAdapter = null;
  
 -    
      /**
       * {@inheritDoc}
       */
@@@ -78,7 -80,6 +79,7 @@@
          View v = super.onCreateView(inflater, container, savedInstanceState);
          setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
          setSwipeEnabled(false); // Disable pull-to-refresh
 +        setFabEnabled(false); // Disable FAB
          setMessageForEmptyList(getString(R.string.local_file_list_empty));
          Log_OC.i(TAG, "onCreateView() end");
          return v;
                  ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox);
                  if (checkBoxV != null) {
                      if (((ListView)getListView()).isItemChecked(position)) {
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
 +                        checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
                      } else {
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
 +                        checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
                      }
                  }
                  // notify the change to the container Activity
          return result.toArray(new String[result.size()]);
      }
  
-     
+     public void sortByName(boolean descending) {
+         mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
+     }
+     public void sortByDate(boolean descending) {
+         mAdapter.setSortOrder(FileStorageUtils.SORT_DATE, descending);
+     }
+     public void sortBySize(boolean descending) {
+         mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
+     }
      /**
       * Interface to implement by any Activity that includes some instance of LocalFileListFragment
       */
@@@ -27,7 -27,6 +27,7 @@@ import java.util.Set
  import java.util.Vector;
  
  import android.accounts.Account;
 +import android.graphics.Bitmap;
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentManager;
  import android.support.v4.app.FragmentStatePagerAdapter;
@@@ -35,8 -34,6 +35,8 @@@ import android.view.ViewGroup
  
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
 +import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 +import com.owncloud.android.ui.adapter.FileListListAdapter;
  import com.owncloud.android.ui.fragment.FileFragment;
  import com.owncloud.android.utils.FileStorageUtils;
  
@@@ -64,8 -61,8 +64,8 @@@ public class PreviewImagePagerAdapter e
       * @param storageManager    Bridge to database.
       */
      public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder,
 -                                    Account account, FileDataStorageManager storageManager /*,
 -                                    boolean onlyOnDevice*/) {
 +                                    Account account, FileDataStorageManager storageManager,
 +                                    boolean onlyOnDevice) {
          super(fragmentManager);
          
          if (fragmentManager == null) {
  
          mAccount = account;
          mStorageManager = storageManager;
 -        // TODO Enable when "On Device" is recovered ?
 -        mImageFiles = mStorageManager.getFolderImages(parentFolder/*, false*/);
 +        mImageFiles = mStorageManager.getFolderImages(parentFolder, false);
          
-         mImageFiles = FileStorageUtils.sortFolder(mImageFiles);
+         mImageFiles = FileStorageUtils.sortOcFolder(mImageFiles);
          
          mObsoleteFragments = new HashSet<Object>();
          mObsoletePositions = new HashSet<Integer>();
          Fragment fragment = null;
          if (file.isDown()) {
              fragment = PreviewImageFragment.newInstance(file,
 -                    mObsoletePositions.contains(Integer.valueOf(i)));
 +                    mObsoletePositions.contains(Integer.valueOf(i)), false);
              
          } else if (mDownloadErrors.contains(Integer.valueOf(i))) {
              fragment = FileDownloadFragment.newInstance(file, mAccount, true);
              ((FileDownloadFragment)fragment).setError(true);
              mDownloadErrors.remove(Integer.valueOf(i));
 -            
          } else {
 -            fragment = FileDownloadFragment.newInstance(
 -                    file, mAccount, mObsoletePositions.contains(Integer.valueOf(i))
 -            );
 +            fragment = PreviewImageFragment.newInstance(file,
 +                    mObsoletePositions.contains(Integer.valueOf(i)), true);
          }
          mObsoletePositions.remove(Integer.valueOf(i));
          return fragment;
  package com.owncloud.android.utils;
  
  import java.io.File;
+ import java.util.ArrayList;
+ import java.util.Arrays;
  import java.util.Collections;
  import java.util.Comparator;
+ import java.util.List;
  import java.util.Vector;
  
  import third_parties.daveKoeller.AlphanumComparator;
@@@ -46,12 -49,12 +49,12 @@@ import android.webkit.MimeTypeMap
   * Static methods to help in access to local file system.
   */
  public class FileStorageUtils {
 -    public static Integer mSortOrder;
 -    public static Boolean mSortAscending;
      public static final Integer SORT_NAME = 0;
      public static final Integer SORT_DATE = 1;
      public static final Integer SORT_SIZE = 2;
 -  
 +    public static Integer mSortOrder = SORT_NAME;
 +    public static Boolean mSortAscending = true;
 +
      
      //private static final String LOG_TAG = "FileStorageUtils";
  
      /**
       * Sorts all filenames, regarding last user decision 
       */
-     public static Vector<OCFile> sortFolder(Vector<OCFile> files){
+     public static Vector<OCFile> sortOcFolder(Vector<OCFile> files){
          switch (mSortOrder){
          case 0:
-             files = FileStorageUtils.sortByName(files);
+             files = FileStorageUtils.sortOCFilesByName(files);
              break;
          case 1:
-             files = FileStorageUtils.sortByDate(files);
+             files = FileStorageUtils.sortOCFilesByDate(files);
              break;
          case 2: 
             // mFiles = FileStorageUtils.sortBySize(mSortAscending);
         
          return files;
      }
+     /**
+      * Sorts all filenames, regarding last user decision
+      */
+     public static File[] sortLocalFolder(File[] files){
+         switch (mSortOrder){
+             case 0:
+                 files = FileStorageUtils.sortLocalFilesByName(files);
+                 break;
+             case 1:
+                 files = FileStorageUtils.sortLocalFilesByDate(files);
+                 break;
+             case 2:
+                 // mFiles = FileStorageUtils.sortBySize(mSortAscending);
+                 break;
+         }
+         return files;
+     }
      
      /**
       * Sorts list by Date
       * @param files
       */
-     public static Vector<OCFile> sortByDate(Vector<OCFile> files){
+     public static Vector<OCFile> sortOCFilesByDate(Vector<OCFile> files){
          final Integer val;
          if (mSortAscending){
              val = 1;
          return files;
      }
  
+     /**
+      * Sorts list by Date
+      * @param filesArray
+      */
+     public static File[] sortLocalFilesByDate(File[] filesArray){
+         final Integer val;
+         if (mSortAscending){
+             val = 1;
+         } else {
+             val = -1;
+         }
+         List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+         Collections.sort(files, new Comparator<File>() {
+             public int compare(File o1, File o2) {
+                 if (o1.isDirectory() && o2.isDirectory()) {
+                     Long obj1 = o1.lastModified();
+                     return val * obj1.compareTo(o2.lastModified());
+                 }
+                 else if (o1.isDirectory()) {
+                     return -1;
+                 } else if (o2.isDirectory()) {
+                     return 1;
+                 } else if (o1.lastModified() == 0 || o2.lastModified() == 0){
+                     return 0;
+                 } else {
+                     Long obj1 = o1.lastModified();
+                     return val * obj1.compareTo(o2.lastModified());
+                 }
+             }
+         });
+         File[] returnArray = new File[1];
+         return files.toArray(returnArray);
+     }
  //    /**
  //     * Sorts list by Size
  //     * @param sortAscending true: ascending, false: descending
       * Sorts list by Name
       * @param files     files to sort
       */
-     public static Vector<OCFile> sortByName(Vector<OCFile> files){
+     public static Vector<OCFile> sortOCFilesByName(Vector<OCFile> files){
          final Integer val;
          if (mSortAscending){
              val = 1;
          Collections.sort(files, new Comparator<OCFile>() {
              public int compare(OCFile o1, OCFile o2) {
                  if (o1.isFolder() && o2.isFolder()) {
 -                    return val * o1.getRemotePath().toLowerCase().compareTo(o2.getRemotePath().toLowerCase());
 +                    return val * new AlphanumComparator().compare(o1, o2);
                  } else if (o1.isFolder()) {
                      return -1;
                  } else if (o2.isFolder()) {
          
          return files;
      }
+     /**
+      * Sorts list by Name
+      * @param filesArray    files to sort
+      */
+     public static File[] sortLocalFilesByName(File[] filesArray){
+         final Integer val;
+         if (mSortAscending){
+             val = 1;
+         } else {
+             val = -1;
+         }
+         List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+         Collections.sort(files, new Comparator<File>() {
+             public int compare(File o1, File o2) {
+                 if (o1.isDirectory() && o2.isDirectory()) {
+                     return val * o1.getPath().toLowerCase().compareTo(o2.getPath().toLowerCase());
+                 } else if (o1.isDirectory()) {
+                     return -1;
+                 } else if (o2.isDirectory()) {
+                     return 1;
+                 }
+                 return val * new AlphanumComparator().compare(o1.getPath().toLowerCase(),
+                                                               o2.getPath().toLowerCase());
+             }
+         });
+         File[] returnArray = new File[1];
+         return files.toArray(returnArray);
+     }
      
      /**
       * Local Folder size
@@@ -23,7 -23,7 +23,8 @@@
   */\r
  \r
  package third_parties.daveKoeller;\r
 +import java.text.Collator;\r
+ import java.io.File;\r
  import java.util.Comparator;\r
  \r
  import com.owncloud.android.datamodel.OCFile;\r
@@@ -49,12 -49,14 +50,12 @@@ public class AlphanumComparator impleme
      }\r
  \r
      /** Length of string is passed in for improved efficiency (only need to calculate it once) **/\r
 -    private final String getChunk(String s, int slength, int marker)\r
 -    {\r
 +    private final String getChunk(String s, int slength, int marker){\r
          StringBuilder chunk = new StringBuilder();\r
          char c = s.charAt(marker);\r
          chunk.append(c);\r
          marker++;\r
 -        if (isDigit(c))\r
 -        {\r
 +        if (isDigit(c)){\r
              while (marker < slength)\r
              {\r
                  c = s.charAt(marker);\r
@@@ -63,7 -65,8 +64,7 @@@
                  chunk.append(c);\r
                  marker++;\r
              }\r
 -        } else\r
 -        {\r
 +        } else {\r
              while (marker < slength)\r
              {\r
                  c = s.charAt(marker);\r
      }\r
  \r
      public int compare(OCFile o1, OCFile o2){\r
-         String s1 = (String)o1.getRemotePath().toLowerCase();\r
-         String s2 = (String)o2.getRemotePath().toLowerCase();\r
+         String s1 = o1.getRemotePath().toLowerCase();\r
+         String s2 = o2.getRemotePath().toLowerCase();\r
  \r
+         return compare(s1, s2);\r
+     }\r
\r
+     public int compare(File f1, File f2){\r
+         String s1 = f1.getPath().toLowerCase();\r
+         String s2 = f2.getPath().toLowerCase();\r
\r
+         return compare(s1, s2);\r
+     }\r
\r
+     public int compare(String s1, String s2) {\r
          int thisMarker = 0;\r
          int thatMarker = 0;\r
          int s1Length = s1.length();\r
          int s2Length = s2.length();\r
  \r
 -        while (thisMarker < s1Length && thatMarker < s2Length)\r
 -        {\r
 +        while (thisMarker < s1Length && thatMarker < s2Length) {\r
              String thisChunk = getChunk(s1, s1Length, thisMarker);\r
              thisMarker += thisChunk.length();\r
  \r
  \r
              // If both chunks contain numeric characters, sort them numerically\r
              int result = 0;\r
 -            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))\r
 -            {\r
 +            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {\r
                  // Simple chunk comparison by length.\r
                  int thisChunkLength = thisChunk.length();\r
                  result = thisChunkLength - thatChunk.length();\r
                  // If equal, the first different number counts\r
 -                if (result == 0)\r
 -                {\r
 -                    for (int i = 0; i < thisChunkLength; i++)\r
 -                    {\r
 +                if (result == 0) {\r
 +                    for (int i = 0; i < thisChunkLength; i++) {\r
                          result = thisChunk.charAt(i) - thatChunk.charAt(i);\r
 -                        if (result != 0)\r
 -                        {\r
 +                        if (result != 0) {\r
                              return result;\r
                          }\r
                      }\r
                  }\r
 -            } else\r
 -            {\r
 -                result = thisChunk.compareTo(thatChunk);\r
 +            } else {\r
 +                Collator collator = Collator.getInstance();\r
 +                collator.setStrength(Collator.PRIMARY);\r
 +                result = collator.compare(thisChunk, thatChunk);\r
              }\r
  \r
              if (result != 0)\r