Merge branch 'develop' into sorting_files_2
authorjabarros <jabarros@solidgear.es>
Thu, 23 Oct 2014 08:18:20 +0000 (10:18 +0200)
committerjabarros <jabarros@solidgear.es>
Thu, 23 Oct 2014 08:18:20 +0000 (10:18 +0200)
Conflicts:
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

1  2 
res/values-de/strings.xml
res/values/strings.xml
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

    <string name="actionbar_settings">Einstellungen</string>
    <string name="actionbar_see_details">Details</string>
    <string name="actionbar_send_file">Senden</string>
 +  <string name="actionbar_sort">Sortieren</string>
 +  <string name="actionbar_sort_title">Sortieren nach</string>
 +  <string-array name="actionbar_sortby">
 +      <item>A-Z</item>
 +      <item>Neu - Alt</item>
 +      <item>Groß - Klein</item>
 +  </string-array>
    <string name="prefs_category_general">Allgemein</string>
    <string name="prefs_category_more">Mehr</string>
    <string name="prefs_accounts">Konten</string>
    <string name="sync_fail_in_favourites_content">Inhalte von %1$d konnte nicht synchronisiert werden (%2$d Konflikte)</string>
    <string name="sync_foreign_files_forgotten_ticker">Einige lokale Dateien wurden vergessen</string>
    <string name="sync_foreign_files_forgotten_content">%1$d Dateien aus dem %2$s Verzeichnis konnten nicht kopiert werden nach</string>
-   <string name="sync_foreign_files_forgotten_explanation">Mit Version 1.3.16 werden Dateien die von diesem Gerät aus hochgeladen werden in den lokalen Ordner %1$s kopiert um Datenverlust zu vermeiden, wenn eine einzelne Datei mit mehreren Accounts synchronisiert wird.\n\nInfolge dieser Änderung wurden alle Dateien, die mit vorherigen Versionen dieser App hochgeladen wurden, in den Ordner %2$s verschoben. Jedoch ist während der Account-Synchronisation ein Fehler aufgetreten, der das Abschließen dieses Vorgangs verhindert. Du kannst die Datei(en) entweder wie sie sind belassen und den Link zu %3$s entfernen oder die Datei(en) in den %1$s Ordner verschieben und  den Link zu %4$s beibehalten.\n\nUnten befindet sich eine Liste der lokalen Datei(en) und der mit ihnen verbundenen Remote-Datei(en) in %5$s.</string>
+   <string name="sync_foreign_files_forgotten_explanation">Mit Version 1.3.16 werden Dateien die von diesem Gerät aus hochgeladen werden in den lokalen Ordner %1$s kopiert um Datenverlust zu vermeiden, wenn eine einzelne Datei mit mehreren Accounts synchronisiert wird.\n\nInfolge dieser Änderung wurden alle Dateien, die mit vorherigen Versionen dieser App hochgeladen wurden, in den Ordner %2$s verschoben. Jedoch ist während der Account-Synchronisation ein Fehler aufgetreten, der das Abschließen dieses Vorgangs verhindert. Du kannst die Datei(en) entweder wie sie sind belassen und den Link zu %3$s entfernen oder die Datei(en) in den Ordner %1$s verschieben und  den Link zu %4$s beibehalten.\n\nUnten befindet sich eine Liste der lokalen Datei(en) und der mit ihnen verbundenen Remote-Datei(en) in %5$s.</string>
    <string name="sync_current_folder_was_removed">Das Verzeichnis %1$s existiert nicht mehr</string>
    <string name="foreign_files_move">Verschiebe alle</string>
    <string name="foreign_files_success">Alle Dateien wurden verschoben</string>
    <string name="preview_image_description">Bildvorschau</string>
    <string name="preview_image_error_unknown_format">Dieses Bild kann nicht angezeigt werden</string>
    <string name="error__upload__local_file_not_copied">%1$s konnte nicht in den lokalen %2$s Ordner kopiert werden</string>
+   <string name="prefs_instant_upload_path_title">Pfad hochladen</string>
    <string name="share_link_no_support_share_api">Entschuldigung, Freigaben sind auf Deinem Server nicht aktiviert. Bitte kontaktiere Deinen
  ⇥⇥Administrator.</string>
    <string name="share_link_file_no_exist">Teilen nicht möglich. Prüfe, dass die Datei existiert</string>
    <string name="file_list_empty_moving">Nichts vorhanden. Du kannst einen Ordner hinzufügen!</string>
    <string name="move_choose_button_text">Auswählen</string>
    <string name="move_file_not_found">Verschieben nicht möglich. Prüfe, dass die Datei existiert</string>
-   <string name="move_file_invalid_into_descendent">Es ist nicht möglich einen Ordner eine Ebene tiefer zu verschieben</string>
+   <string name="move_file_invalid_into_descendent">Es ist nicht möglich, einen Ordner in einen seiner Unterordner zu verschieben</string>
    <string name="move_file_invalid_overwrite">Die Datei ist bereits im Zielordner vorhanden</string>
-   <string name="move_file_error">Es ist ein Fehler beim Verschieben dieser Datei oder Ordners aufgetreten.</string>
-   <string name="forbidden_permissions_move">zum Datei verschieben</string>
+   <string name="move_file_error">Es ist ein Fehler beim Verschieben der Datei oder des Ordners aufgetreten.</string>
+   <string name="forbidden_permissions_move">um diese Datei zu verschieben</string>
+   <string name="prefs_category_instant_uploading">Sofortiges Hochladen</string>
+   <string name="prefs_category_security">Sicherheit</string>
  </resources>
diff --combined res/values/strings.xml
      <string name="actionbar_settings">Settings</string>
      <string name="actionbar_see_details">Details</string>
      <string name="actionbar_send_file">Send</string>
 +    <string name="actionbar_sort">Sort</string>
 +    <string name="actionbar_sort_title">Sort by</string>
 +    <string-array name="actionbar_sortby">
 +      <item>A-Z</item>
 +      <item>Newest - Oldest</item>
 +      <item>Biggest - Smallest</item>
 +    </string-array>
      <string name="prefs_category_general">General</string>
      <string name="prefs_category_more">More</string>
      <string name="prefs_accounts">Accounts</string>
      <string name="preview_image_error_unknown_format">This image cannot be shown</string>
      
      <string name="error__upload__local_file_not_copied">%1$s could not be copied to %2$s local folder</string>
+     <string name="prefs_instant_upload_path_title">Upload Path</string>
  
        <string name="share_link_no_support_share_api">Sorry, sharing is not enabled on your server. Please contact your
                administrator.</string>
  
        <string name="prefs_category_accounts">Accounts</string>
        <string name="prefs_add_account">Add account</string>
-       <string name="auth_redirect_non_secure_connection_title">Secure connection is redirected through an unsecured route.</string>
+       <string name="auth_redirect_non_secure_connection_title">Secure connection is redirected to an unsecured route.</string>
  
        <string name="actionbar_logger">Logs</string>
        <string name="log_send_history_button">Send History</string>
        <string name="move_file_error">An error occurred while trying to move this file or folder</string>
        <string name="forbidden_permissions_move">to move this file</string>
  
+       <string name="prefs_category_instant_uploading">Instant Uploads</string>
+       <string name="prefs_category_security">Security</string>
  </resources>
   */\r
  package com.owncloud.android.ui.adapter;\r
  \r
- import java.lang.ref.WeakReference;\r
++
 +import java.io.File;\r
 +import java.util.Collections;\r
 +import java.util.Comparator;\r
  import java.util.Vector;\r
  \r
  import android.accounts.Account;\r
  import android.content.Context;\r
- import android.content.res.Resources;\r
 +import android.content.SharedPreferences;\r
  import android.graphics.Bitmap;\r
- import android.graphics.Bitmap.CompressFormat;\r
- import android.graphics.BitmapFactory;\r
- import android.graphics.drawable.BitmapDrawable;\r
- import android.graphics.drawable.Drawable;\r
- import android.media.ThumbnailUtils;\r
- import android.os.AsyncTask;\r
 +import android.preference.PreferenceManager;\r
- import android.util.TypedValue;\r
  import android.view.LayoutInflater;\r
  import android.view.View;\r
  import android.view.ViewGroup;\r
@@@ -47,17 -33,14 +39,17 @@@ import android.widget.TextView
  \r
  import com.owncloud.android.R;\r
  import com.owncloud.android.authentication.AccountUtils;\r
 +import com.owncloud.android.datamodel.AlphanumComparator;\r
  import com.owncloud.android.datamodel.FileDataStorageManager;\r
  import com.owncloud.android.datamodel.OCFile;\r
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager;\r
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable;\r
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;\r
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;\r
- import com.owncloud.android.lib.common.utils.Log_OC;\r
  import com.owncloud.android.ui.activity.ComponentsGetter;\r
- import com.owncloud.android.utils.BitmapUtils;\r
  import com.owncloud.android.utils.DisplayUtils;\r
 +import com.owncloud.android.utils.FileStorageUtils;\r
 +\r
  \r
  \r
  /**\r
@@@ -71,8 -54,6 +63,6 @@@
  public class FileListListAdapter extends BaseAdapter implements ListAdapter {\r
      private final static String PERMISSION_SHARED_WITH_ME = "S";\r
      \r
-     private static final String TAG = FileListListAdapter.class.getSimpleName();\r
\r
      private Context mContext;\r
      private OCFile mFile = null;\r
      private Vector<OCFile> mFiles = null;\r
      private FileDataStorageManager mStorageManager;
      private Account mAccount;
      private ComponentsGetter mTransferServiceGetter;\r
 +    private Integer sortOrder;\r
 +    private Boolean sortAscending;\r
 +    private SharedPreferences appPreferences;\r
      \r
-     private final Object thumbnailDiskCacheLock = new Object();\r
-     private DiskLruImageCache mThumbnailCache;\r
-     private boolean mThumbnailCacheStarting = true;\r
-     private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB\r
-     private static final CompressFormat mCompressFormat = CompressFormat.JPEG;\r
-     private static final int mCompressQuality = 70;\r
-     private Bitmap defaultImg;\r
-         \r
      public FileListListAdapter(\r
              boolean justFolders, \r
              Context context, \r
          mJustFolders = justFolders;\r
          mContext = context;\r
          mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
--        mTransferServiceGetter = transferServiceGetter;\r
++        mTransferServiceGetter = transferServiceGetter;
 +        \r
 +        appPreferences = PreferenceManager\r
 +                .getDefaultSharedPreferences(mContext);\r
 +        \r
 +        // Read sorting order, default to sort by name ascending\r
 +        sortOrder = appPreferences\r
 +                .getInt("sortOrder", 0);\r
-         sortAscending = appPreferences.getBoolean("sortAscending", true);\r
-         \r
-         defaultImg = BitmapFactory.decodeResource(mContext.getResources(), \r
-                     DisplayUtils.getResourceId("image/png", "default.png"));\r
-         \r
-         // Initialise disk cache on background thread\r
-         new InitDiskCacheTask().execute();\r
-     }\r
-     \r
-     class InitDiskCacheTask extends AsyncTask<File, Void, Void> {\r
-         @Override\r
-         protected Void doInBackground(File... params) {\r
-             synchronized (thumbnailDiskCacheLock) {\r
-                 try {\r
-                     mThumbnailCache = new DiskLruImageCache(mContext, "thumbnailCache", \r
-                                         DISK_CACHE_SIZE, mCompressFormat, mCompressQuality);\r
-                 } catch (Exception e) {\r
-                     Log_OC.d(TAG, "Thumbnail cache could not be opened ", e);\r
-                     mThumbnailCache = null;\r
-                 }\r
-                 mThumbnailCacheStarting = false; // Finished initialization\r
-                 thumbnailDiskCacheLock.notifyAll(); // Wake any waiting threads\r
-             }\r
-             return null;\r
-         }\r
-     }\r
-     \r
-     static class AsyncDrawable extends BitmapDrawable {\r
-         private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;\r
\r
-         public AsyncDrawable(Resources res, Bitmap bitmap,\r
-                 ThumbnailGenerationTask bitmapWorkerTask) {\r
-             super(res, bitmap);\r
-             bitmapWorkerTaskReference =\r
-                 new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);\r
-         }\r
\r
-         public ThumbnailGenerationTask getBitmapWorkerTask() {\r
-             return bitmapWorkerTaskReference.get();\r
-         }\r
-     }\r
\r
-     class ThumbnailGenerationTask extends AsyncTask<OCFile, Void, Bitmap> {\r
-         private final WeakReference<ImageView> imageViewReference;\r
-         private OCFile file;\r
\r
-         \r
-         public ThumbnailGenerationTask(ImageView imageView) {\r
-          // Use a WeakReference to ensure the ImageView can be garbage collected\r
-             imageViewReference = new WeakReference<ImageView>(imageView);\r
-         }\r
\r
-         // Decode image in background.\r
-         @Override\r
-         protected Bitmap doInBackground(OCFile... params) {\r
-             Bitmap thumbnail = null;\r
-             \r
-             try {\r
-                 file = params[0];\r
-                 final String imageKey = String.valueOf(file.getRemoteId());\r
-     \r
-                 // Check disk cache in background thread\r
-                 thumbnail = getBitmapFromDiskCache(imageKey);\r
-     \r
-                 // Not found in disk cache\r
-                 if (thumbnail == null || file.needsUpdateThumbnail()) { \r
-                     // Converts dp to pixel\r
-                     Resources r = mContext.getResources();\r
-                     int px = (int) Math.round(TypedValue.applyDimension(\r
-                             TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics()\r
-                     ));\r
-                     \r
-                     if (file.isDown()){\r
-                         Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(\r
-                                 file.getStoragePath(), px, px);\r
-                         \r
-                         if (bitmap != null) {\r
-                             thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);\r
-     \r
-                             // Add thumbnail to cache\r
-                             addBitmapToCache(imageKey, thumbnail);\r
\r
-                             file.setNeedsUpdateThumbnail(false);\r
-                             mStorageManager.saveFile(file);\r
-                         }\r
-     \r
-                     }\r
-                 }\r
-                 \r
-             } catch (Throwable t) {\r
-                 // the app should never break due to a problem with thumbnails\r
-                 Log_OC.e(TAG, "Generation of thumbnail for " + file + " failed", t);\r
-                 if (t instanceof OutOfMemoryError) {\r
-                     System.gc();\r
-                 }\r
-             }\r
-             \r
-             return thumbnail;\r
-         }\r
++        sortAscending = appPreferences.getBoolean("sortAscending", true);
          \r
-         protected void onPostExecute(Bitmap bitmap){\r
-             if (isCancelled()) {\r
-                 bitmap = null;\r
-             }\r
\r
-             if (imageViewReference != null && bitmap != null) {\r
-                 final ImageView imageView = imageViewReference.get();\r
-                 final ThumbnailGenerationTask bitmapWorkerTask =\r
-                         getBitmapWorkerTask(imageView);\r
-                 if (this == bitmapWorkerTask && imageView != null) {\r
-                     imageView.setImageBitmap(bitmap);\r
-                 }\r
-             }\r
-         }\r
-     }\r
-   \r
-     public void addBitmapToCache(String key, Bitmap bitmap) {\r
-         synchronized (thumbnailDiskCacheLock) {\r
-             if (mThumbnailCache != null) {\r
-                 mThumbnailCache.put(key, bitmap);\r
-             }\r
-         }\r
+         // initialise thumbnails cache on background thread\r
+         new ThumbnailsCacheManager.InitDiskCacheTask().execute();\r
      }\r
\r
-     public Bitmap getBitmapFromDiskCache(String key) {\r
-         synchronized (thumbnailDiskCacheLock) {\r
-             // Wait while disk cache is started from background thread\r
-             while (mThumbnailCacheStarting) {\r
-                 try {\r
-                     thumbnailDiskCacheLock.wait();\r
-                 } catch (InterruptedException e) {}\r
-             }\r
-             if (mThumbnailCache != null) {\r
-                 return (Bitmap) mThumbnailCache.getBitmap(key);\r
-             }\r
-         }\r
-         return null;
-     }
\r
 -    \r
++    
      @Override\r
      public boolean areAllItemsEnabled() {\r
          return true;\r
  \r
              fileName.setText(name);\r
              ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
+             fileIcon.setTag(file.getFileId());\r
              ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon);\r
              ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon);\r
              sharedWithMeIconV.setVisibility(View.GONE);\r
                  }               \r
                  \r
                  // get Thumbnail if file is image\r
-                 if (file.isImage()){\r
+                 if (file.isImage() && file.getRemoteId() != null){\r
                       // Thumbnail in Cache?\r
-                     Bitmap thumbnail = getBitmapFromDiskCache(String.valueOf(file.getRemoteId()));\r
+                     Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(\r
+                             String.valueOf(file.getRemoteId())\r
+                     );\r
                      if (thumbnail != null && !file.needsUpdateThumbnail()){\r
                          fileIcon.setImageBitmap(thumbnail);\r
                      } else {\r
                          // generate new Thumbnail\r
-                         if (cancelPotentialWork(file, fileIcon)) {\r
-                             final ThumbnailGenerationTask task = \r
-                                     new ThumbnailGenerationTask(fileIcon);\r
-                             final AsyncDrawable asyncDrawable =\r
-                                     new AsyncDrawable(mContext.getResources(), defaultImg, task);\r
+                         if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {\r
+                             final ThumbnailsCacheManager.ThumbnailGenerationTask task = \r
+                                     new ThumbnailsCacheManager.ThumbnailGenerationTask(\r
+                                             fileIcon, mStorageManager\r
+                                     );\r
+                             if (thumbnail == null) {\r
+                                 thumbnail = ThumbnailsCacheManager.mDefaultImg;\r
+                             }\r
+                             final AsyncDrawable asyncDrawable = new AsyncDrawable(\r
+                                     mContext.getResources(), \r
+                                     thumbnail, \r
+                                     task\r
+                             );\r
                              fileIcon.setImageDrawable(asyncDrawable);\r
                              task.execute(file);\r
                          }\r
                  }\r
              } \r
              else {\r
 -                fileSizeV.setVisibility(View.INVISIBLE);\r
 -                //fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
 +                if (FileStorageUtils.getDefaultSavePathFor(mAccount.name, file) != null){\r
 +                    fileSizeV.setVisibility(View.VISIBLE);\r
 +                    fileSizeV.setText(getFolderSizeHuman(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file)));\r
 +                } else {\r
 +                    fileSizeV.setVisibility(View.INVISIBLE);\r
 +                }\r
 +
                  lastModV.setVisibility(View.VISIBLE);\r
                  lastModV.setText(\r
                          DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())\r
  \r
          return view;\r
      }\r
 -    \r
 +
-     public static boolean cancelPotentialWork(OCFile file, ImageView imageView) {\r
-         final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);\r
\r
-         if (bitmapWorkerTask != null) {\r
-             final OCFile bitmapData = bitmapWorkerTask.file;\r
-             // If bitmapData is not yet set or it differs from the new data\r
-             if (bitmapData == null || bitmapData != file) {\r
-                 // Cancel previous task\r
-                 bitmapWorkerTask.cancel(true);\r
-             } else {\r
-                 // The same work is already in progress\r
-                 return false;\r
-             }\r
-         }\r
-         // No task associated with the ImageView, or an existing task was cancelled\r
-         return true;\r
-     }\r
-     \r
-     private static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {\r
-         if (imageView != null) {\r
-             final Drawable drawable = imageView.getDrawable();\r
-             if (drawable instanceof AsyncDrawable) {\r
-                 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;\r
-                 return asyncDrawable.getBitmapWorkerTask();\r
-             }\r
-          }\r
-          return null;\r
-      }\r
 +    /**\r
 +     * Local Folder size in human readable format\r
 +     * @param path String\r
 +     * @return Size in human readable format\r
 +     */\r
 +    private String getFolderSizeHuman(String path) {\r
 +\r
 +        File dir = new File(path);\r
 +\r
 +        if(dir.exists()) {\r
 +            long bytes = getFolderSize(dir);\r
 +            if (bytes < 1024) return bytes + " B";\r
 +            int exp = (int) (Math.log(bytes) / Math.log(1024));\r
 +            String pre = ("KMGTPE").charAt(exp-1) + "";\r
 +\r
 +            return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);\r
 +        }\r
 +\r
 +        return "0 B";\r
 +    }\r
 +\r
 +    /**\r
 +     * Local Folder size\r
 +     * @param dir File\r
 +     * @return Size in bytes\r
 +     */\r
 +    private long getFolderSize(File dir) {\r
 +        if (dir.exists()) {\r
 +            long result = 0;\r
 +            File[] fileList = dir.listFiles();\r
 +            for(int i = 0; i < fileList.length; i++) {\r
 +                if(fileList[i].isDirectory()) {\r
 +                    result += getFolderSize(fileList[i]);\r
 +                } else {\r
 +                    result += fileList[i].length();\r
 +                }\r
 +            }\r
 +            return result;\r
 +        }\r
 +        return 0;\r
 +    } 
\r
++
      @Override\r
      public int getViewTypeCount() {\r
          return 1;\r
          } else {\r
              mFiles = null;\r
          }\r
 +\r
 +        sortDirectory();\r
 +    }\r
 +    \r
 +    /**\r
 +     * Sorts all filenames, regarding last user decision \r
 +     */\r
 +    private void sortDirectory(){\r
 +        switch (sortOrder){\r
 +        case 0:\r
 +            sortByName(sortAscending);\r
 +            break;\r
 +        case 1:\r
 +            sortByDate(sortAscending);\r
 +            break;\r
 +        case 2: \r
 +            sortBySize(sortAscending);\r
 +            break;\r
 +        }\r
 +        \r
          notifyDataSetChanged();\r
      }\r
      \r
                  && file.getPermissions() != null \r
                  && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
      }\r
 +\r
 +    /**\r
 +     * Sorts list by Date\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortByDate(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +        \r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    return val * Long.compare(o1.getModificationTimestamp(), o2.getModificationTimestamp());\r
 +                }\r
 +                else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                } else if (o1.getModificationTimestamp() == 0 || o2.getModificationTimestamp() == 0){\r
 +                    return 0;\r
 +                } else {\r
 +                    return val * Long.compare(o1.getModificationTimestamp(), o2.getModificationTimestamp());\r
 +                }\r
 +            }\r
 +        });\r
 +    }\r
 +\r
 +    /**\r
 +     * Sorts list by Size\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortBySize(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +        \r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    return val * Long.compare(getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1))), \r
 +                                              getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));\r
 +                }\r
 +                else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                } else if (o1.getFileLength() == 0 || o2.getFileLength() == 0){\r
 +                    return 0;\r
 +                } else {\r
 +                    return val * Long.compare(o1.getFileLength(), o2.getFileLength());\r
 +                }\r
 +            }\r
 +        });\r
 +    }\r
 +\r
 +    /**\r
 +     * Sorts list by Name\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortByName(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +\r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    return val * o1.getRemotePath().toLowerCase().compareTo(o2.getRemotePath().toLowerCase());\r
 +                } else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                }\r
 +                return val * new AlphanumComparator().compare(o1, o2);\r
 +            }\r
 +        });\r
 +    }\r
 +\r
 +    public void setSortOrder(Integer order, boolean ascending) {\r
 +        SharedPreferences.Editor editor = appPreferences.edit();\r
 +        editor.putInt("sortOrder", order);\r
 +        editor.putBoolean("sortAscending", ascending);\r
 +        editor.commit();\r
 +        \r
 +        sortOrder = order;\r
 +        sortAscending = ascending;\r
 +        \r
 +        sortDirectory();\r
 +    }    \r
  }\r