Merge remote-tracking branch 'upstream/develop' into imageGrid
authortobiasKaminsky <tobias@kaminsky.me>
Wed, 5 Nov 2014 21:07:11 +0000 (22:07 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Wed, 5 Nov 2014 21:07:11 +0000 (22:07 +0100)
Conflicts:
owncloud-android-library
res/layout/list_item.xml
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java

1  2 
owncloud-android-library
res/layout/list_item.xml
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

diff --combined owncloud-android-library
index 0000000,4f315c7..5bd0d73
mode 000000,160000..160000
--- /dev/null
@@@ -1,0 -1,1 +1,1 @@@
 -Subproject commit 4f315c7e06f6eef48df246be0ee9252fdfccdf00
++Subproject commit 5bd0d7387712ce3f53869294761ac4d8537841cd
diff --combined res/layout/list_item.xml
          android:focusableInTouchMode="false">\r
  \r
          <ImageView\r
 -            android:id="@+id/imageView2"\r
 +            android:id="@+id/localFileIndicator"\r
-             android:layout_width="32dp"\r
-             android:layout_height="32dp"\r
+             android:layout_width="@dimen/file_icon_size"\r
+             android:layout_height="@dimen/file_icon_size"\r
              android:layout_gravity="center_vertical"\r
              android:layout_marginLeft="22dp"\r
              android:src="@drawable/local_file_indicator" />\r
  \r
          <ImageView\r
 -            android:id="@+id/imageView1"\r
 +            android:id="@+id/thumbnail"\r
-             android:layout_width="32dp"\r
-             android:layout_height="32dp"\r
+             android:layout_width="@dimen/file_icon_size"\r
+             android:layout_height="@dimen/file_icon_size"\r
              android:layout_gravity="center_vertical"\r
              android:layout_marginLeft="9dp"\r
              android:src="@drawable/ic_menu_archive" />\r
  \r
          <ImageView\r
 -            android:id="@+id/imageView3"\r
 +            android:id="@+id/favoriteIcon"\r
              android:layout_width="wrap_content"\r
              android:layout_height="wrap_content"\r
              android:layout_gravity="bottom|right"\r
          android:layout_marginLeft="4dp"\r
          android:layout_marginRight="4dp"\r
          android:layout_marginTop="4dp"\r
 -        android:src="@drawable/shared_with_me" />\r
 +        android:src="@drawable/shared_with_me"\r
 +        android:visibility="invisible" />\r
  \r
      </LinearLayout>\r
  \r
   */
  package com.owncloud.android;
  
- import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
- import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
+ import android.app.Application;
+ import android.content.Context;
++import com.owncloud.android.authentication.AccountUtils;
++import com.owncloud.android.datamodel.ThumbnailsCacheManager;
++import android.app.Application;
++import android.content.Context;
++
++import com.owncloud.android.authentication.AccountUtils;
++import com.owncloud.android.datamodel.ThumbnailsCacheManager;
++import android.app.Application;
++import android.content.Context;
 +
++import com.owncloud.android.authentication.AccountUtils;
++import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 +import android.app.Application;
 +import android.content.Context;
++
++import com.owncloud.android.datamodel.ThumbnailsCacheManager;
++import android.app.Application;
++import android.content.Context;
++
++import com.owncloud.android.authentication.AccountUtils;
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
+ import com.owncloud.android.lib.common.utils.Log_OC;
  /**
   * Main Application of the project
   * 
@@@ -53,7 -55,20 +75,20 @@@ public class MainApp extends Applicatio
          } else {
              OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT);
          }
 -        new ThumbnailsCacheManager.InitDiskCacheTask().execute();
+         // initialise thumbnails cache on background thread
++        new ThumbnailsCacheManager.InitDiskCacheTask(mContext).execute();
          
+         if (BuildConfig.DEBUG) {
+             String dataFolder = getDataFolder();
+             // Set folder for store logs
+             Log_OC.setLogDataFolder(dataFolder);
+             Log_OC.startLogging();
+             Log_OC.d("Debug", "start logging");
+         }
      }
  
      public static Context getAppContext() {
      public static String getAccountType() {
          return getAppContext().getResources().getString(R.string.account_type);
      }
-     
      //  From AccountAuthenticator 
      //  public static final String AUTHORITY = "org.owncloud";
      public static String getAuthority() {
   */\r
  package com.owncloud.android.ui.adapter;\r
  \r
+ import java.io.File;\r
+ import java.util.Collections;\r
+ import java.util.Comparator;\r
  import java.util.Vector;\r
  \r
+ import third_parties.daveKoeller.AlphanumComparator;\r
  import android.accounts.Account;\r
  import android.content.Context;\r
++<<<<<<< HEAD
 +import android.graphics.Bitmap;\r
 +import android.graphics.BitmapFactory;\r
 +import android.media.ThumbnailUtils;\r
++=======
+ import android.content.SharedPreferences;\r
+ import android.graphics.Bitmap;\r
+ import android.preference.PreferenceManager;\r
++>>>>>>> upstream/develop
  import android.view.LayoutInflater;\r
  import android.view.View;\r
  import android.view.ViewGroup;\r
  import android.widget.BaseAdapter;\r
 +import android.widget.GridView;\r
  import android.widget.ImageView;\r
  import android.widget.ListAdapter;\r
  import android.widget.ListView;\r
@@@ -38,23 -42,26 +49,31 @@@ import com.owncloud.android.R
  import com.owncloud.android.authentication.AccountUtils;\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.ui.activity.ComponentsGetter;\r
  import com.owncloud.android.utils.DisplayUtils;\r
++<<<<<<< HEAD
 +import com.owncloud.android.utils.Log_OC;\r
 +\r
++=======
+ import com.owncloud.android.utils.FileStorageUtils;\r
++>>>>>>> upstream/develop
  \r
  /**\r
   * This Adapter populates a ListView with all files and folders in an ownCloud\r
   * instance.\r
   * \r
   * @author Bartek Przybylski\r
-  * \r
+  * @author Tobias Kaminsky\r
+  * @author David A. Velasco\r
   */\r
- public class FileListListAdapter extends BaseAdapter implements ListAdapter {\r
+ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
      private final static String PERMISSION_SHARED_WITH_ME = "S";\r
\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
++<<<<<<< HEAD
 +    private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM };\r
++=======
+     private Integer mSortOrder;\r
+     public static final Integer SORT_NAME = 0;\r
+     public static final Integer SORT_DATE = 1;\r
+     public static final Integer SORT_SIZE = 2;\r
+     private Boolean mSortAscending;\r
+     private SharedPreferences mAppPreferences;\r
++>>>>>>> upstream/develop
      \r
      public FileListListAdapter(\r
              boolean justFolders, \r
              Context context, \r
              ComponentsGetter transferServiceGetter\r
              ) {\r
\r
          mJustFolders = justFolders;\r
          mContext = context;\r
          mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
-         mTransferServiceGetter = transferServiceGetter;\r
-     }
+         mTransferServiceGetter = transferServiceGetter;
+         \r
+         mAppPreferences = PreferenceManager\r
+                 .getDefaultSharedPreferences(mContext);\r
+         \r
+         // Read sorting order, default to sort by name ascending\r
+         mSortOrder = mAppPreferences\r
+                 .getInt("sortOrder", 0);\r
+         mSortAscending = mAppPreferences.getBoolean("sortAscending", true);
+         \r
+         // initialise thumbnails cache on background thread\r
+         new ThumbnailsCacheManager.InitDiskCacheTask().execute();\r
  \r
+     }\r
+     
      @Override\r
      public boolean areAllItemsEnabled() {\r
          return true;\r
  \r
      @Override\r
      public View getView(int position, View convertView, ViewGroup parent) {\r
 +     // decide image vs. file view\r
 +        double count = 0;\r
 +        \r
 +        \r
 +        for (OCFile file : mFiles){\r
 +            if (file.isImage()){\r
 +                count++;\r
 +            }\r
 +        }\r
 +        \r
 +        // TODO threshold as constant in Preferences\r
 +        // > 50% Images --> image view\r
 +        boolean fileView = true;\r
 +        if ((count / mFiles.size()) >= 0.5){\r
 +            fileView = false;\r
 +        } else {\r
 +            fileView = true;\r
 +        }\r
 +        \r
          View view = convertView;\r
 -        if (view == null) {\r
 -            LayoutInflater inflator = (LayoutInflater) mContext\r
 -                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
 +        OCFile file = null;\r
 +        LayoutInflater inflator = (LayoutInflater) mContext\r
 +                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
 +        \r
 +        if (mFiles != null && mFiles.size() > position) {\r
 +            file = mFiles.get(position);\r
 +        }\r
 +        \r
 +        // Find out which layout should be displayed\r
 +        ViewType viewType;\r
 +        if (fileView){\r
 +            viewType = ViewType.LIST_ITEM;\r
 +        } else if (file.isImage()){\r
 +            viewType = ViewType.GRID_IMAGE;\r
 +        } else {\r
 +            viewType = ViewType.GRID_ITEM;\r
 +        }\r
 +\r
 +        // Create View\r
 +        switch (viewType){\r
 +        case GRID_IMAGE:\r
 +            view = inflator.inflate(R.layout.grid_image, null);\r
 +            break;\r
 +        case GRID_ITEM:\r
 +            view = inflator.inflate(R.layout.grid_item, null);\r
 +            break;\r
 +        case LIST_ITEM:\r
              view = inflator.inflate(R.layout.list_item, null);\r
 +            break;\r
          }\r
++<<<<<<< HEAD
 +\r
 +        view.invalidate();\r
 +\r
 +        if (file != null){\r
 +\r
 +            ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);\r
 +            TextView fileName;\r
 +            String name;\r
++=======
+          \r
+         if (mFiles != null && mFiles.size() > position) {\r
+             OCFile file = mFiles.get(position);\r
+             TextView fileName = (TextView) view.findViewById(R.id.Filename);           \r
+             String name = file.getFileName();\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
+             ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);\r
+             localStateView.bringToFront();\r
+             FileDownloaderBinder downloaderBinder = \r
+                     mTransferServiceGetter.getFileDownloaderBinder();\r
+             FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();\r
+             if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) {\r
+                 localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
+                 localStateView.setVisibility(View.VISIBLE);\r
+             } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {\r
+                 localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
+                 localStateView.setVisibility(View.VISIBLE);\r
+             } else if (file.isDown()) {\r
+                 localStateView.setImageResource(R.drawable.local_file_indicator);\r
+                 localStateView.setVisibility(View.VISIBLE);\r
+             } else {\r
+                 localStateView.setVisibility(View.INVISIBLE);\r
+             }\r
+             \r
+             TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
+             TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
+             ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
++>>>>>>> upstream/develop
              \r
 -            if (!file.isFolder()) {\r
 +            switch (viewType){\r
 +            case LIST_ITEM:\r
 +                fileName = (TextView) view.findViewById(R.id.Filename);\r
 +                name = file.getFileName();\r
 +                fileName.setText(name);\r
 +                \r
 +                TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
 +                TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
 +                ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
 +                \r
 +                lastModV.setVisibility(View.VISIBLE);\r
++<<<<<<< HEAD
 +                lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
 +                \r
 +                checkBoxV.setVisibility(View.GONE);\r
 +                \r
                  fileSizeV.setVisibility(View.VISIBLE);\r
                  fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
 -                lastModV.setVisibility(View.VISIBLE);\r
 +                \r
 +                ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon);\r
 +                \r
 +\r
 +                if (file.isShareByLink()) {\r
 +                    sharedIconV.setVisibility(View.VISIBLE);\r
++=======
+                 lastModV.setText(\r
+                         DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())\r
+                 );\r
+                 // this if-else is needed even thoe fav icon is visible by default\r
+                 // because android reuses views in listview\r
+                 if (!file.keepInSync()) {\r
+                     view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
++>>>>>>> upstream/develop
                  } else {\r
 -                    view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);\r
 +                    sharedIconV.setVisibility(View.GONE);\r
                  }\r
                  \r
 -                ListView parentList = (ListView)parent;\r
 -                if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { \r
 -                    checkBoxV.setVisibility(View.GONE);\r
 -                } else {\r
 -                    if (parentList.isItemChecked(position)) {\r
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);\r
 +                ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator);\r
 +                \r
 +                if (!file.isFolder()) {\r
 +                    GridView parentList = (GridView)parent;\r
 +                    if (parentList.getChoiceMode() == GridView.CHOICE_MODE_NONE) { \r
 +                        checkBoxV.setVisibility(View.GONE);\r
 +                    } else {\r
 +                        if (parentList.isItemChecked(position)) {\r
 +                            checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);\r
 +                        } else {\r
 +                            checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\r
 +                        }\r
 +                        checkBoxV.setVisibility(View.VISIBLE);\r
 +                    }\r
++<<<<<<< HEAD
 +                    \r
 +                    localStateView.bringToFront();\r
 +                    FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder();\r
 +                    FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();\r
 +                    if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) {\r
 +                        localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
 +                        localStateView.setVisibility(View.VISIBLE);\r
 +                    } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {\r
 +                        localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
 +                        localStateView.setVisibility(View.VISIBLE);\r
 +                    } else if (file.isDown()) {\r
 +                        localStateView.setImageResource(R.drawable.local_file_indicator);\r
 +                        localStateView.setVisibility(View.VISIBLE);\r
 +                    } else {\r
 +                        localStateView.setVisibility(View.INVISIBLE);\r
 +                    }\r
 +                    \r
 +                    ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon);\r
 +                    if (checkIfFileIsSharedWithMe(file)) {\r
 +                        sharedWithMeIconV.setVisibility(View.VISIBLE);\r
                      } else {\r
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\r
 +                        sharedWithMeIconV.setVisibility(View.GONE);\r
                      }\r
 +                } else {\r
 +                    localStateView.setVisibility(View.INVISIBLE);\r
 +                }\r
 +                break;\r
 +            case GRID_ITEM:\r
 +                fileName = (TextView) view.findViewById(R.id.Filename);\r
 +                name = file.getFileName();\r
 +                fileName.setText(name);\r
 +                break;\r
 +            case GRID_IMAGE:\r
 +                break;\r
 +            }\r
 +            \r
 +            // For all Views\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
 +                view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);\r
 +            } else {\r
 +                view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE);\r
 +            }\r
 +            \r
 +            // No Folder\r
 +            if (!file.isFolder()) {\r
 +                if (file.isImage() && file.isDown()){\r
 +                    Bitmap bitmap = BitmapFactory.decodeFile(file.getStoragePath());\r
 +                    fileIcon.setImageBitmap(ThumbnailUtils.extractThumbnail(bitmap, 200, 200));\r
 +                } else {\r
 +                    fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
 +                }\r
 +            } else {\r
 +                // Folder\r
++=======
+                     checkBoxV.setVisibility(View.VISIBLE);\r
+                 }               \r
+                 \r
+                 // get Thumbnail if file is image\r
+                 if (file.isImage() && file.getRemoteId() != null){\r
+                      // Thumbnail in Cache?\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 (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {\r
+                             final ThumbnailsCacheManager.ThumbnailGenerationTask task = \r
+                                     new ThumbnailsCacheManager.ThumbnailGenerationTask(\r
+                                             fileIcon, mStorageManager, mAccount\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
+                 } else {\r
+                     fileIcon.setImageResource(\r
+                             DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())\r
+                     );\r
+                 }\r
+                 if (checkIfFileIsSharedWithMe(file)) {\r
+                     sharedWithMeIconV.setVisibility(View.VISIBLE);\r
+                 }\r
+             } \r
+             else {\r
+                   // TODO Re-enable when server supports folder-size calculation\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
+                 checkBoxV.setVisibility(View.GONE);\r
+                 view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
\r
++>>>>>>> upstream/develop
                  if (checkIfFileIsSharedWithMe(file)) {\r
                      fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
 -                    sharedWithMeIconV.setVisibility(View.VISIBLE);\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(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
+                     fileIcon.setImageResource(\r
+                             DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())\r
+                     );\r
                  }\r
 -\r
 -                // If folder is sharedByLink, icon folder must be changed to\r
 -                // folder-public one\r
 -                if (file.isShareByLink()) {\r
 -                    fileIcon.setImageResource(R.drawable.folder_public);\r
 -                }\r
 -            }\r
 -\r
 -            if (file.isShareByLink()) {\r
 -                sharedIconV.setVisibility(View.VISIBLE);\r
 -            } else {\r
 -                sharedIconV.setVisibility(View.GONE);\r
 -            }\r
 +            }           \r
          }\r
  \r
          return view;\r
      }\r
+     /**\r
+      * Local Folder size in human readable format\r
+      * \r
+      * @param path\r
+      *            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
+             return DisplayUtils.bytesToHumanReadable(bytes);\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
+     } 
      @Override\r
      public int getViewTypeCount() {\r
          return 1;\r
  \r
      /**\r
       * Change the adapted directory for a new one\r
-      * @param directory                 New file to adapt. Can be NULL, meaning "no content to adapt".\r
-      * @param updatedStorageManager     Optional updated storage manager; used to replace mStorageManager if is different (and not NULL)\r
+      * @param directory                 New file to adapt. Can be NULL, meaning \r
+      *                                  "no content to adapt".\r
+      * @param updatedStorageManager     Optional updated storage manager; used to replace \r
+      *                                  mStorageManager if is different (and not NULL)\r
       */\r
      public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) {\r
          mFile = directory;\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 (mSortOrder){\r
+         case 0:\r
+             sortByName(mSortAscending);\r
+             break;\r
+         case 1:\r
+             sortByDate(mSortAscending);\r
+             break;\r
+         case 2: \r
+             sortBySize(mSortAscending);\r
+             break;\r
+         }\r
+         \r
          notifyDataSetChanged();\r
      }\r
      \r
       * @return boolean: True if it is shared with me and false if it is not\r
       */\r
      private boolean checkIfFileIsSharedWithMe(OCFile file) {\r
-         return (mFile.getPermissions() != null && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME)\r
-                 && file.getPermissions() != null && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
+         return (mFile.getPermissions() != null \r
+                 && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME)\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
+                     Long obj1 = o1.getModificationTimestamp();\r
+                     return val * obj1.compareTo(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
+                     Long obj1 = o1.getModificationTimestamp();\r
+                     return val * obj1.compareTo(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
+                     Long obj1 = getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1)));\r
+                     return val * obj1.compareTo(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
+                     Long obj1 = o1.getFileLength();\r
+                     return val * obj1.compareTo(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 = mAppPreferences.edit();\r
+         editor.putInt("sortOrder", order);\r
+         editor.putBoolean("sortAscending", ascending);\r
+         editor.commit();\r
+         \r
+         mSortOrder = order;\r
+         mSortAscending = ascending;\r
+         \r
+         sortDirectory();\r
+     }    
  }\r
@@@ -27,21 -27,21 +27,22 @@@ import android.view.View
  import android.view.ViewGroup;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
 +import android.widget.GridView;
  import android.widget.ListAdapter;
  import android.widget.ListView;
  import android.widget.TextView;
  
  import com.actionbarsherlock.app.SherlockFragment;
  import com.owncloud.android.R;
+ import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.ui.ExtendedListView;
- import com.owncloud.android.utils.Log_OC;
+ import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
  
  /**
   *  TODO extending SherlockListFragment instead of SherlockFragment 
   */
  public class ExtendedListFragment extends SherlockFragment 
- implements OnItemClickListener, SwipeRefreshLayout.OnRefreshListener {
+ implements OnItemClickListener, OnEnforceableRefreshListener {
      
      private static final String TAG = ExtendedListFragment.class.getSimpleName();
  
@@@ -52,7 -52,7 +53,7 @@@
      private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL";
      private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE";
  
 -    protected ExtendedListView mList;
 +    // protected ExtendedListView mList;
      
      private SwipeRefreshLayout mRefreshLayout;
      private SwipeRefreshLayout mRefreshEmptyLayout;
      private ArrayList<Integer> mTops;
      private int mHeightCell = 0;
  
-     private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = null;
+     private OnEnforceableRefreshListener mOnRefreshListener = null;
      
 -    
 +    protected GridView imageView;
 +       
      public void setListAdapter(ListAdapter listAdapter) {
 -        mList.setAdapter(listAdapter);
 -        mList.invalidate();
 +        imageView.setAdapter(listAdapter);
 +        imageView.invalidate();
      }
  
 -    public ListView getListView() {
 -        return mList;
 +    public GridView getGridView() {
 +        return imageView;
 +    }
 +    
 +    protected void switchImageView(){
 +       imageView.setNumColumns(GridView.AUTO_FIT);
 +       imageView.invalidate();
 +    }
 +    
 +    protected void switchFileView(){
 +       imageView.setNumColumns(1);
 +       imageView.invalidate();
      }
      
      
          Log_OC.e(TAG, "onCreateView");
          
          View v = inflater.inflate(R.layout.list_fragment, null);
 -        mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view);
 -        mList = (ExtendedListView)(v.findViewById(R.id.list_root));
 -        mList.setOnItemClickListener(this);
 +        
 +//        imageView = (GridView) v.findViewById(R.id.grid_list_view);
 +//        imageView.setOnItemClickListener(this);
 +        
 +       // mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view);
 +        imageView = (ExtendedListView)(v.findViewById(R.id.list_root));
 +        imageView.setOnItemClickListener(this);
  
 -        mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
 -        mList.setDividerHeight(1);
 +        //mList.set
 +        //mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
 +        //mList.setDividerHeight(1);
  
          if (savedInstanceState != null) {
              int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION);
          onCreateSwipeToRefresh(mRefreshLayout);
          onCreateSwipeToRefresh(mRefreshEmptyLayout);
          
 -        mList.setEmptyView(mRefreshEmptyLayout);
 +//        mList.setEmptyView(mRefreshEmptyLayout);
  
          return v;
      }
       * @return      The position in the list of the visible item in the center of the screen.
       */
      protected int getReferencePosition() {
 -        if (mList != null) {
 -            return (mList.getFirstVisiblePosition() + mList.getLastVisiblePosition()) / 2;
 +        if (imageView != null) {
 +            return (imageView.getFirstVisiblePosition() + imageView.getLastVisiblePosition()) / 2;
          } else {
              return 0;
          }
       * @param   position    Reference position previously returned by {@link LocalFileListFragment#getReferencePosition()}
       */
      protected void setReferencePosition(int position) {
 -        if (mList != null) {
 -            mList.setAndCenterSelection(position);
 +        if (imageView != null) {
 +            imageView.setSelection(position);
          }
      }
  
              
              int top = mTops.remove(mTops.size() - 1);
              
 -            mList.setSelectionFromTop(firstPosition, top);
 +            imageView.smoothScrollToPosition(firstPosition);
              
              // Move the scroll if the selection is not visible
              int indexPosition = mHeightCell*index;
 -            int height = mList.getHeight();
 +            int height = imageView.getHeight();
              
              if (indexPosition > height) {
 -                if (android.os.Build.VERSION.SDK_INT >= 11)
 -                {
 -                    mList.smoothScrollToPosition(index); 
 -                }
 -                else if (android.os.Build.VERSION.SDK_INT >= 8)
 -                {
 -                    mList.setSelectionFromTop(index, 0);
 -                }
 -                
 +                imageView.smoothScrollToPosition(index);
              }
          }
      }
          
          mIndexes.add(index);
          
 -        int firstPosition = mList.getFirstVisiblePosition();
 +        int firstPosition = imageView.getFirstVisiblePosition();
          mFirstPositions.add(firstPosition);
          
 -        View view = mList.getChildAt(0);
 +        View view = imageView.getChildAt(0);
          int top = (view == null) ? 0 : view.getTop() ;
  
          mTops.add(top);
          }
      }
      
-     public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) {
+     public void setOnRefreshListener(OnEnforceableRefreshListener listener) {
          mOnRefreshListener = listener;
      }
      
          refreshLayout.setOnRefreshListener(this);
      }
  
+     @Override
+     public void onRefresh(boolean ignoreETag) {
+         mRefreshLayout.setRefreshing(false);
+         mRefreshEmptyLayout.setRefreshing(false);
+         if (mOnRefreshListener != null) {
+             mOnRefreshListener.onRefresh(ignoreETag);
+         }
+     }
  }
@@@ -18,6 -18,7 +18,7 @@@
  package com.owncloud.android.ui.fragment;
  
  import java.io.File;
+ import java.util.ArrayList;
  
  import android.app.Activity;
  import android.os.Bundle;
@@@ -31,8 -32,8 +32,8 @@@ import android.widget.ImageView
  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.Log_OC;
  
  
  /**
@@@ -75,7 -76,7 +76,7 @@@ public class LocalFileListFragment exte
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          Log_OC.i(TAG, "onCreateView() start");
          View v = super.onCreateView(inflater, container, savedInstanceState);
 -        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
 +        getGridView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
          disableSwipe(); // Disable pull refresh
          setMessageForEmptyList(getString(R.string.local_file_list_empty));
          Log_OC.i(TAG, "onCreateView() end");
          Log_OC.i(TAG, "onActivityCreated() stop");
      }
      
+     public void selectAll(){
+         int numberOfFiles = mAdapter.getCount();
+         for(int i = 0; i < numberOfFiles; i++){
+             File file = (File) mAdapter.getItem(i);
+             if (file != null) {                
+                 if (!file.isDirectory()) {  
+                     /// Click on a file
+                     getListView().setItemChecked(i, true);                       
+                     // notify the change to the container Activity
+                     mContainerActivity.onFileClick(file);
+                 }
+             }
+         }
+     }
+     
+     public void deselectAll(){        
+         mAdapter = new LocalFileListAdapter(mContainerActivity.getInitialDirectory(), getActivity());
+         setListAdapter(mAdapter);
+     }
      
      /**
       * Checks the file clicked over. Browses inside if it is a directory. Notifies the container activity in any case.
       */
      @Override
      public void onItemClick(AdapterView<?> l, View v, int position, long id) {
-         File file = (File) mAdapter.getItem(position); 
+         File file = (File) mAdapter.getItem(position);
+         
          if (file != null) {
              /// Click on a directory
              if (file.isDirectory()) {
              } else {    /// Click on a file
                  ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox);
                  if (checkBoxV != null) {
 -                    if (getListView().isItemChecked(position)) {
 +                    if (getGridView().isItemChecked(position)) {
                          checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
                      } else {
                          checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
              directory = directory.getParentFile();
          }
  
 -        mList.clearChoices();   // by now, only files in the same directory will be kept as selected
 +        imageView.clearChoices();   // by now, only files in the same directory will be kept as selected
          mAdapter.swapDirectory(directory);
          if (mDirectory == null || !mDirectory.equals(directory)) {
 -            mList.setSelectionFromTop(0, 0);
 +            imageView.setSelection(0);
          }
          mDirectory = directory;
      }
       * @return      File paths to the files checked by the user.
       */
      public String[] getCheckedFilePaths() {
-         String [] result = null;
+         ArrayList<String> result = new ArrayList<String>();
 -        SparseBooleanArray positions = mList.getCheckedItemPositions();
 +        SparseBooleanArray positions = imageView.getCheckedItemPositions();
          if (positions.size() > 0) {
-             Log_OC.d(TAG, "Returning " + positions.size() + " selected files");
-             result = new String[positions.size()];
-             for (int i=0; i<positions.size(); i++) {
-                 result[i] = ((File) imageView.getItemAtPosition(positions.keyAt(i))).getAbsolutePath();
+             for (int i = 0; i < positions.size(); i++) {
+                 if (positions.get(positions.keyAt(i)) == true) {
+                     result.add(((File) mList.getItemAtPosition(positions.keyAt(i))).getAbsolutePath());
+                 }
              }
+             Log_OC.d(TAG, "Returning " + result.size() + " selected files");
          }
-         return result;
+         return result.toArray(new String[result.size()]);
      }
  
      
@@@ -18,7 -18,6 +18,7 @@@
  package com.owncloud.android.ui.fragment;
  
  import java.io.File;
 +import java.util.Vector;
  
  import android.app.Activity;
  import android.content.Intent;
@@@ -35,15 -34,16 +35,16 @@@ 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;
- import com.owncloud.android.utils.Log_OC;
  
  /**
   * A Fragment that lists all files and folders in a given path.
@@@ -89,7 -89,7 +90,7 @@@ public class OCFileListFragment extend
                      FileFragment.ContainerActivity.class.getSimpleName());
          }
          try {
-             setOnRefreshListener((SwipeRefreshLayout.OnRefreshListener) activity);
+             setOnRefreshListener((OnEnforceableRefreshListener) activity);
              
          } catch (ClassCastException e) {
              throw new ClassCastException(activity.toString() + " must implement " + 
          );
          setListAdapter(mAdapter);
          
 -        registerForContextMenu(getListView());
 -        getListView().setOnCreateContextMenuListener(this);
 +        registerForContextMenu(getGridView());
 +        getGridView().setOnCreateContextMenuListener(this);
    }
      
      /**
              
              listDirectory(mFile);
  
-             onRefresh();
+             onRefresh(false);
              
              // restore index and top position
              restoreIndexAndTopPosition();
  
              mAdapter.swapDirectory(directory, storageManager);
              if (mFile == null || !mFile.equals(directory)) {
 -                mList.setSelectionFromTop(0, 0);
 +                imageView.setSelection(0);
              }
              mFile = directory;
 +            
 +         // decide image vs. file view
 +            double count = 0;
 +            
 +            Vector<OCFile> files = storageManager.getFolderContent(directory);
 +            for (OCFile file : files){
 +                if (file.isImage()){
 +                    count++;
 +                }
 +            }
 +            
 +            // > 50% Images --> image view
 +            // TODO threshold as constant in Preferences
 +            if ((count / files.size()) >= 0.5){
 +                Log_OC.i(TAG, "Image View");
 +                switchImageView();
 +            } else {
 +                Log_OC.i(TAG, "Folder View");
 +                switchFileView();
 +            }
          }
      }
+     
+     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);
+     }  
  
  }