Merge branch 'develop2' into imageGrid2
authortobiasKaminsky <tobias@kaminsky.me>
Sun, 18 Jan 2015 16:00:29 +0000 (17:00 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Sun, 18 Jan 2015 16:00:29 +0000 (17:00 +0100)
Conflicts:
owncloud-android-library
res/layout/list_fragment.xml
res/values-fr/strings.xml
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.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

1  2 
res/layout/list_fragment.xml
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.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

@@@ -1,5 -1,5 +1,5 @@@
  <?xml version="1.0" encoding="utf-8"?>
 -<!-- 
 +<!--
    ownCloud Android client application
  
    Copyright (C) 2012  Bartek Przybylski
  
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 - -->
 +-->
  <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 -      android:layout_width="0dp"
 -      android:layout_height="match_parent"
 -      android:layout_weight="1" >
 +    xmlns:tools="http://schemas.android.com/tools"
 +    android:layout_width="match_parent"
 +    android:layout_height="match_parent"
 +    android:layout_weight="1" >
  
      <android.support.v4.widget.SwipeRefreshLayout
          android:id="@+id/swipe_refresh_files"
          android:layout_width="match_parent"
-         android:layout_height="match_parent" >
+         android:layout_height="match_parent" 
+         android:layout_weight="1"
+         android:footerDividersEnabled="false" > 
+         
          <com.owncloud.android.ui.ExtendedListView
              android:id="@+id/list_root"
              android:layout_width="match_parent"
 -            android:layout_height="match_parent" />
 -            
 +            android:layout_height="match_parent"
 +            android:columnWidth="100dp"
 +            android:gravity="center"
 +            android:horizontalSpacing="2dp"
 +            android:numColumns="auto_fit"
 +            android:stretchMode="columnWidth"
 +            android:verticalSpacing="2dp"
 +            android:visibility="visible" />
 +
      </android.support.v4.widget.SwipeRefreshLayout>
-     <android.support.v4.widget.SwipeRefreshLayout
+       
+       <android.support.v4.widget.SwipeRefreshLayout
          android:id="@+id/swipe_refresh_files_emptyView"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:visibility="gone" >
  
 -        <ScrollView
 +        <TextView
 +            android:id="@+id/empty_list_view"
              android:layout_width="match_parent"
 -            android:layout_height="match_parent" >
 -
 -                  <TextView
 -                              android:id="@+id/empty_list_view"
 -                              android:layout_width="match_parent"
 -                              android:layout_height="wrap_content"
 -                              android:gravity="center_vertical|center_horizontal"
 -                              android:text="@string/empty"
 -                                      android:layout_gravity="center"
 -                              android:visibility="visible" />
 -
 -        </ScrollView>
 +            android:layout_height="wrap_content"
 +            android:layout_gravity="center"
 +            android:gravity="center_vertical|center_horizontal"
 +            android:text="@string/empty"
 +            android:visibility="visible" />
      </android.support.v4.widget.SwipeRefreshLayout>
 -</FrameLayout>
 +
 +</FrameLayout>
@@@ -74,7 -74,7 +74,7 @@@ public class ThumbnailsCacheManager 
      public static Bitmap mDefaultImg = 
              BitmapFactory.decodeResource(
                      MainApp.getAppContext().getResources(), 
-                     DisplayUtils.getResourceId("image/png", "default.png")
+                     DisplayUtils.getFileTypeIconId("image/png", "default.png")
              );
  
      
          return null;
      }
  
-     
-     public static boolean cancelPotentialWork(OCFile file, ImageView imageView) {
-         final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
-         if (bitmapWorkerTask != null) {
-             final OCFile bitmapData = bitmapWorkerTask.mFile;
-             // If bitmapData is not yet set or it differs from the new data
-             if (bitmapData == null || bitmapData != file) {
-                 // Cancel previous task
-                 bitmapWorkerTask.cancel(true);
-             } else {
-                 // The same work is already in progress
-                 return false;
-             }
-         }
-         // No task associated with the ImageView, or an existing task was cancelled
-         return true;
-     }
-     
-     public static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {
-         if (imageView != null) {
-             final Drawable drawable = imageView.getDrawable();
-             if (drawable instanceof AsyncDrawable) {
-                 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
-                 return asyncDrawable.getBitmapWorkerTask();
-             }
-          }
-          return null;
-      }
-     public static class ThumbnailGenerationTask extends AsyncTask<OCFile, Void, Bitmap> {
+     public static class ThumbnailGenerationTask extends AsyncTask<Object, Void, Bitmap> {
          private final WeakReference<ImageView> mImageViewReference;
          private static Account mAccount;
-         private OCFile mFile;
+         private Object mFile;
          private FileDataStorageManager mStorageManager;
-         
          public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
-          // Use a WeakReference to ensure the ImageView can be garbage collected
+             // Use a WeakReference to ensure the ImageView can be garbage collected
              mImageViewReference = new WeakReference<ImageView>(imageView);
              if (storageManager == null)
                  throw new IllegalArgumentException("storageManager must not be NULL");
              mAccount = account;
          }
  
-         // Decode image in background.
+         public ThumbnailGenerationTask(ImageView imageView) {
+             // Use a WeakReference to ensure the ImageView can be garbage collected
+             mImageViewReference = new WeakReference<ImageView>(imageView);
+         }
          @Override
-         protected Bitmap doInBackground(OCFile... params) {
+         protected Bitmap doInBackground(Object... params) {
              Bitmap thumbnail = null;
-             
              try {
                  if (mAccount != null) {
                      AccountManager accountMgr = AccountManager.get(MainApp.getAppContext());
-                     
                      mServerVersion = accountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);
                      OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, MainApp.getAppContext());
                      mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                              getClientFor(ocAccount, MainApp.getAppContext());
                  }
-                 
                  mFile = params[0];
 +                final String imageKey = String.valueOf(mFile.getRemoteId());
 +    
 +                // Check disk cache in background thread
 +                thumbnail = getBitmapFromDiskCache(imageKey);
 +    
 +                // Not found in disk cache
 +                if (thumbnail == null || mFile.needsUpdateThumbnail()) { 
 +                    // Use Width of imageView -> no blurry images on big screens
 +                    int px = mImageViewReference.get().getWidth();
 +                    
 +                    if (mFile.isDown()){
 +                        Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
 +                                mFile.getStoragePath(), px, px);
 +                        
 +                        if (bitmap != null) {
 +                            thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
 +    
 +                            // Add thumbnail to cache
 +                            addBitmapToCache(imageKey, thumbnail);
  
-                             mFile.setNeedsUpdateThumbnail(false);
-                             mStorageManager.saveFile(mFile);
-                         }
-     
-                     } else {
-                         // Download thumbnail from server
-                         if (mClient != null && mServerVersion != null) {
-                             OwnCloudVersion serverOCVersion = new OwnCloudVersion(mServerVersion);
-                             if (serverOCVersion.compareTo(new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) {
-                                 try {
-                                     int status = -1;
-                                     String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + 
-                                             px + "/" + px + Uri.encode(mFile.getRemotePath(), "/");
-                                     Log_OC.d("Thumbnail", "URI: " + uri);
-                                     GetMethod get = new GetMethod(uri);
-                                     status = mClient.executeMethod(get);
-                                     if (status == HttpStatus.SC_OK) {
-                                         byte[] bytes = get.getResponseBody();
-                                         Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
-                                         thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
-                                         // Add thumbnail to cache
-                                         if (thumbnail != null) {
-                                             addBitmapToCache(imageKey, thumbnail);
-                                         }
-                                     }
-                                 } catch (Exception e) {
-                                     e.printStackTrace();
-                                 }
-                             } else {
-                                 Log_OC.d(TAG, "Server too old");
-                             }
-                         }
-                     }
+                 if (mFile instanceof OCFile) {
+                     thumbnail = doOCFileInBackground();
+                 }  else if (mFile instanceof File) {
+                     thumbnail = doFileInBackground();
+                 } else {
+                     // do nothing
                  }
-                 
-             } catch (Throwable t) {
-                 // the app should never break due to a problem with thumbnails
-                 Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
-                 if (t instanceof OutOfMemoryError) {
-                     System.gc();
+                 }catch(Throwable t){
+                     // the app should never break due to a problem with thumbnails
+                     Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
+                     if (t instanceof OutOfMemoryError) {
+                         System.gc();
+                     }
                  }
-             }
-             
              return thumbnail;
          }
-         
          protected void onPostExecute(Bitmap bitmap){
              if (isCancelled()) {
                  bitmap = null;
  
              if (mImageViewReference != null && bitmap != null) {
                  final ImageView imageView = mImageViewReference.get();
-                 final ThumbnailGenerationTask bitmapWorkerTask =
-                         getBitmapWorkerTask(imageView);
+                 final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
                  if (this == bitmapWorkerTask && imageView != null) {
-                     imageView.setImageBitmap(bitmap);
+                     String tagId = "";
+                     if (mFile instanceof OCFile){
+                         tagId = String.valueOf(((OCFile)mFile).getFileId());
+                     } else if (mFile instanceof File){
+                         tagId = String.valueOf(((File)mFile).hashCode());
+                     }
+                     if (String.valueOf(imageView.getTag()).equals(tagId)) {
+                         imageView.setImageBitmap(bitmap);
+                     }
+                 }
+             }
+         }
+         /**
+          * Add thumbnail to cache
+          * @param imageKey: thumb key
+          * @param bitmap:   image for extracting thumbnail
+          * @param path:     image path
+          * @param px:       thumbnail dp
+          * @return Bitmap
+          */
+         private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){
+             Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+             // Rotate image, obeying exif tag
+             thumbnail = BitmapUtils.rotateImage(thumbnail,path);
+             // Add thumbnail to cache
+             addBitmapToCache(imageKey, thumbnail);
+             return thumbnail;
+         }
+         /**
+          * Converts size of file icon from dp to pixel
+          * @return int
+          */
+         private int getThumbnailDimension(){
+             // Converts dp to pixel
+             Resources r = MainApp.getAppContext().getResources();
+             return (int) Math.round(r.getDimension(R.dimen.file_icon_size));
+         }
+         private Bitmap doOCFileInBackground() {
+             Bitmap thumbnail = null;
+             OCFile file = (OCFile)mFile;
+             final String imageKey = String.valueOf(file.getRemoteId());
+             // Check disk cache in background thread
+             thumbnail = getBitmapFromDiskCache(imageKey);
+             // Not found in disk cache
+             if (thumbnail == null || file.needsUpdateThumbnail()) {
+                 int px = getThumbnailDimension();
+                 if (file.isDown()) {
+                     Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+                             file.getStoragePath(), px, px);
+                     if (bitmap != null) {
+                         thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px);
+                         file.setNeedsUpdateThumbnail(false);
+                         mStorageManager.saveFile(file);
+                     }
+                 } else {
+                     // Download thumbnail from server
+                     if (mClient != null && mServerVersion != null) {
+                         OwnCloudVersion serverOCVersion = new OwnCloudVersion(mServerVersion);
+                         if (serverOCVersion.compareTo(new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) {
+                             try {
+                                 int status = -1;
+                                 String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" +
+                                         px + "/" + px + Uri.encode(file.getRemotePath(), "/");
+                                 Log_OC.d("Thumbnail", "URI: " + uri);
+                                 GetMethod get = new GetMethod(uri);
+                                 status = mClient.executeMethod(get);
+                                 if (status == HttpStatus.SC_OK) {
+                                     byte[] bytes = get.getResponseBody();
+                                     Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
+                                     thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+                                     // Add thumbnail to cache
+                                     if (thumbnail != null) {
+                                         addBitmapToCache(imageKey, thumbnail);
+                                     }
+                                 }
+                             } catch (Exception e) {
+                                 e.printStackTrace();
+                             }
+                         } else {
+                             Log_OC.d(TAG, "Server too old");
+                         }
+                     }
                  }
              }
+             return thumbnail;
          }
+         private Bitmap doFileInBackground() {
+             Bitmap thumbnail = null;
+             File file = (File)mFile;
+             final String imageKey = String.valueOf(file.hashCode());
+             // Check disk cache in background thread
+             thumbnail = getBitmapFromDiskCache(imageKey);
+             // Not found in disk cache
+             if (thumbnail == null) {
+                 int px = getThumbnailDimension();
+                 Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+                         file.getAbsolutePath(), px, px);
+                 if (bitmap != null) {
+                     thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px);
+                 }
+             }
+             return thumbnail;
+         }
      }
-   
-     
+     public static boolean cancelPotentialWork(Object file, ImageView imageView) {
+         final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+         if (bitmapWorkerTask != null) {
+             final Object bitmapData = bitmapWorkerTask.mFile;
+             // If bitmapData is not yet set or it differs from the new data
+             if (bitmapData == null || bitmapData != file) {
+                 // Cancel previous task
+                 bitmapWorkerTask.cancel(true);
+             } else {
+                 // The same work is already in progress
+                 return false;
+             }
+         }
+         // No task associated with the ImageView, or an existing task was cancelled
+         return true;
+     }
+     public static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {
+         if (imageView != null) {
+             final Drawable drawable = imageView.getDrawable();
+             if (drawable instanceof AsyncDrawable) {
+                 final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+                 return asyncDrawable.getBitmapWorkerTask();
+             }
+         }
+         return null;
+     }
      public static class AsyncDrawable extends BitmapDrawable {
          private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
  
          public AsyncDrawable(
                  Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask
-             ) {
-             
+         ) {
              super(res, bitmap);
              bitmapWorkerTaskReference =
-                 new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
+                     new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
          }
  
          public ThumbnailGenerationTask getBitmapWorkerTask() {
              return bitmapWorkerTaskReference.get();
          }
      }
-     
-     /**
-      * Remove from cache the remoteId passed
-      * @param fileRemoteId: remote id of mFile passed
-      */
-     public static void removeFileFromCache(String fileRemoteId){
-         synchronized (mThumbnailsDiskCacheLock) {
-             if (mThumbnailCache != null) {
-                 mThumbnailCache.removeKey(fileRemoteId);
-             }
-             mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
-         }
-     }
  }
@@@ -17,7 -17,7 +17,7 @@@
   */\r
  package com.owncloud.android.ui.adapter;\r
  \r
\r
  import java.io.File;\r
  import java.util.Collections;\r
  import java.util.Comparator;\r
@@@ -28,19 -28,15 +28,19 @@@ import android.accounts.Account
  import android.content.Context;\r
  import android.content.SharedPreferences;\r
  import android.graphics.Bitmap;\r
 +import android.graphics.BitmapFactory;\r
 +import android.media.ThumbnailUtils;\r
  import android.preference.PreferenceManager;\r
  import android.text.format.DateUtils;\r
  import android.view.LayoutInflater;\r
  import android.view.View;\r
  import android.view.ViewGroup;\r
  import android.widget.BaseAdapter;\r
 +import android.widget.Filter;\r
 +import android.widget.Filterable;\r
 +import android.widget.GridView;\r
  import android.widget.ImageView;\r
  import android.widget.ListAdapter;\r
 -import android.widget.ListView;\r
  import android.widget.TextView;\r
  \r
  import com.owncloud.android.R;\r
@@@ -48,14 -44,12 +48,12 @@@ import com.owncloud.android.authenticat
  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.DisplayUtils;\r
  import com.owncloud.android.utils.FileStorageUtils;\r
\r
  \r
  /**\r
   * This Adapter populates a ListView with all files and folders in an ownCloud\r
   * @author Tobias Kaminsky\r
   * @author David A. Velasco\r
   */\r
- public class FileListListAdapter extends BaseAdapter implements ListAdapter {
+ public class FileListListAdapter extends BaseAdapter implements ListAdapter {\r
      private final static String PERMISSION_SHARED_WITH_ME = "S";\r
      \r
      private Context mContext;\r
      private OCFile mFile = null;\r
      private Vector<OCFile> mFiles = null;\r
 +    private Vector<OCFile> mFilesOrig = new Vector<OCFile>();\r
      private boolean mJustFolders;\r
  \r
-     private FileDataStorageManager mStorageManager;
-     private Account mAccount;
+     private FileDataStorageManager mStorageManager;\r
+     private Account mAccount;\r
      private ComponentsGetter mTransferServiceGetter;\r
 -    \r
 +    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
      \r
      public FileListListAdapter(\r
              Context context, \r
              ComponentsGetter transferServiceGetter\r
              ) {\r
 -\r
 +        \r
          mJustFolders = justFolders;\r
          mContext = context;\r
          mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
-         mTransferServiceGetter = transferServiceGetter;
 -\r
+         mTransferServiceGetter = transferServiceGetter;\r
          \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);
+         FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0);\r
+         FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true);\r
\r
          \r
          // initialise thumbnails cache on background thread\r
          new ThumbnailsCacheManager.InitDiskCacheTask().execute();\r
 -\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 countImages = 0;\r
 +        double countFiles = 0;\r
 +        \r
 +        for (OCFile file : mFiles){\r
 +            if (!file.isFolder()){\r
 +                countFiles++;\r
 +                \r
 +                if (file.isImage()){\r
 +                    countImages++;\r
 +                }\r
 +            }\r
 +        }\r
 +        \r
 +        // TODO threshold as constant in Preferences\r
 +        // > 50% Images --> image view\r
 +        boolean fileView = true;\r
 +        if ((countImages / countFiles) >= 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
 -         \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
 +\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 (!file.isFolder()) {\r
 -                fileSizeV.setVisibility(View.VISIBLE);\r
 -                fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\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
                  lastModV.setText(showRelativeTimestamp(file));\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
 +                \r
 +                checkBoxV.setVisibility(View.GONE);\r
 +                \r
 +                fileSizeV.setVisibility(View.VISIBLE);\r
 +                fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
 +                \r
 +                ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon);\r
 +                \r
 +\r
 +                if (file.isShareByLink()) {\r
 +                    sharedIconV.setVisibility(View.VISIBLE);\r
                  } 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
 -                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\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
 -                    checkBoxV.setVisibility(View.VISIBLE);\r
 -                }               \r
 -                \r
 -                // get Thumbnail if file is image\r
 +                    \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
 +                        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.getRemoteId() != null){\r
 -                     // Thumbnail in Cache?\r
 +                    // Thumbnail in Cache?\r
                      Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(\r
                              String.valueOf(file.getRemoteId())\r
 -                    );\r
 +                            );\r
                      if (thumbnail != null && !file.needsUpdateThumbnail()){\r
                          fileIcon.setImageBitmap(thumbnail);\r
                      } else {\r
\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
 +                                            );\r
                              if (thumbnail == null) {\r
                                  thumbnail = ThumbnailsCacheManager.mDefaultImg;\r
                              }\r
-                             final AsyncDrawable asyncDrawable = new AsyncDrawable(\r
-                                     mContext.getResources(),\r
-                                     thumbnail,\r
+                             final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =\r
+                                     new ThumbnailsCacheManager.AsyncDrawable(\r
+                                     mContext.getResources(), \r
+                                     thumbnail, \r
                                      task\r
 -                            );\r
 +                                    );\r
                              fileIcon.setImageDrawable(asyncDrawable);\r
                              task.execute(file);\r
 +\r
                          }\r
                      }\r
+                 } else {\r
+                     fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName()));\r
                  }\r
 -\r
 -                if (checkIfFileIsSharedWithMe(file)) {\r
 -                    sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                else {\r
 +                    fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\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
 -\r
 -                lastModV.setVisibility(View.VISIBLE);\r
 -                lastModV.setText(showRelativeTimestamp(file));\r
 -                checkBoxV.setVisibility(View.GONE);\r
 -                view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
 -\r
 +            } else {\r
 +                // Folder\r
                  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.getFileTypeIconId(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
      /**\r
       * Local Folder size in human readable format\r
       * \r
          File dir = new File(path);\r
  \r
          if (dir.exists()) {\r
-             long bytes = getFolderSize(dir);\r
+             long bytes = FileStorageUtils.getFolderSize(dir);\r
              return DisplayUtils.bytesToHumanReadable(bytes);\r
          }\r
  \r
              return result;\r
          }\r
          return 0;\r
-     } 
+     } \r
\r
      @Override\r
      public int getViewTypeCount() {\r
          return 1;\r
          }\r
          if (mStorageManager != null) {\r
              mFiles = mStorageManager.getFolderContent(mFile);\r
 +            mFilesOrig.clear();\r
 +            mFilesOrig.addAll(mFiles);\r
 +            \r
              if (mJustFolders) {\r
                  mFiles = getFolders(mFiles);\r
              }\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
+         mFiles = FileStorageUtils.sortFolder(mFiles);\r
          notifyDataSetChanged();\r
      }\r
      \r
-     \r
\r
      /**\r
       * Filter for getting only the folders\r
       * @param files\r
                  && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
      }\r
  \r
-                     return val * obj1.compareTo(getFolderSize(\r
-                             new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));\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
+         FileStorageUtils.mSortOrder = order;\r
+         FileStorageUtils.mSortAscending = ascending;\r
          \r
-     }
\r
+         mFiles = FileStorageUtils.sortFolder(mFiles);\r
+         notifyDataSetChanged();\r
\r
+     }    \r
 +        sortDirectory();\r
++    }\r
      \r
      private CharSequence showRelativeTimestamp(OCFile file){\r
          return DisplayUtils.getRelativeDateTimeString(mContext, file.getModificationTimestamp(),\r
                  DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0);\r
-     }
+     }\r
  }\r
@@@ -22,6 -22,7 +22,7 @@@ import java.util.Arrays
  import java.util.Comparator;
  
  import android.content.Context;
+ import android.graphics.Bitmap;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
@@@ -32,6 -33,8 +33,8 @@@ import android.widget.ListView
  import android.widget.TextView;
  
  import com.owncloud.android.R;
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+ import com.owncloud.android.utils.BitmapUtils;
  import com.owncloud.android.utils.DisplayUtils;
  
  /**
@@@ -46,7 -49,7 +49,7 @@@ public class LocalFileListAdapter exten
      private Context mContext;
      private File mDirectory;
      private File[] mFiles = null;
+     
      public LocalFileListAdapter(File directory, Context context) {
          mContext = context;
          swapDirectory(directory);
              String name = file.getName();
              fileName.setText(name);
              
 -            ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
 +            ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);
              if (!file.isDirectory()) {
                  fileIcon.setImageResource(R.drawable.file);
              } else {
                  fileIcon.setImageResource(R.drawable.ic_menu_archive);
              }
+             fileIcon.setTag(file.hashCode());
  
              TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
              TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
              ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
              if (!file.isDirectory()) {
 -                fileSizeV.setVisibility(View.VISIBLE);
 -                fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
 +                
                  lastModV.setVisibility(View.VISIBLE);
                  lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.lastModified()));
                  ListView parentList = (ListView)parent;
                      }
                      checkBoxV.setVisibility(View.VISIBLE);
                  }
+                 
+              // get Thumbnail if file is image
+                 if (BitmapUtils.isImage(file)){
+                 // Thumbnail in Cache?
+                     Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                             String.valueOf(file.hashCode())
+                     );
+                     if (thumbnail != null){
+                         fileIcon.setImageBitmap(thumbnail);
+                     } else {
+                         // generate new Thumbnail
+                         if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
+                             final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+                                     new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon);
+                             if (thumbnail == null) {
+                                 thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                             }
+                             final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+                                       new ThumbnailsCacheManager.AsyncDrawable(
+                                     mContext.getResources(), 
+                                     thumbnail, 
+                                     task
+                                       );
+                             fileIcon.setImageDrawable(asyncDrawable);
+                             task.execute(file);
+                         }
+                     }
+                 } else {
+                     fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(null, file.getName()));
+                 }  
  
              } else {
 -                fileSizeV.setVisibility(View.GONE);
 +                //fileSizeV.setVisibility(View.GONE);
                  lastModV.setVisibility(View.GONE);
                  checkBoxV.setVisibility(View.GONE);
              }
 +            fileSizeV.setVisibility(View.VISIBLE);
 +            fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
              
 -            view.findViewById(R.id.imageView2).setVisibility(View.INVISIBLE);   // not GONE; the alignment would change
 -            view.findViewById(R.id.imageView3).setVisibility(View.GONE);
 +            // not GONE; the alignment changes; ugly way to keep it
 +            view.findViewById(R.id.localFileIndicator).setVisibility(View.INVISIBLE);   
 +            view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);
              
              view.findViewById(R.id.sharedIcon).setVisibility(View.GONE);
              view.findViewById(R.id.sharedWithMeIcon).setVisibility(View.GONE);
@@@ -27,7 -27,6 +27,7 @@@ 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;
@@@ -39,14 -38,14 +39,14 @@@ import com.owncloud.android.ui.Extended
  import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
  
  /**
-  *  TODO extending SherlockListFragment instead of SherlockFragment 
+  * TODO extending SherlockListFragment instead of SherlockFragment
   */
  public class ExtendedListFragment extends SherlockFragment 
  implements OnItemClickListener, OnEnforceableRefreshListener {
-     
      private static final String TAG = ExtendedListFragment.class.getSimpleName();
  
-     private static final String KEY_SAVED_LIST_POSITION = "SAVED_LIST_POSITION"; 
+     private static final String KEY_SAVED_LIST_POSITION = "SAVED_LIST_POSITION";
      private static final String KEY_INDEXES = "INDEXES";
      private static final String KEY_FIRST_POSITIONS= "FIRST_POSITIONS";
      private static final String KEY_TOPS = "TOPS";
@@@ -54,7 -53,7 +54,7 @@@
      private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE";
  
      protected ExtendedListView mList;
-     
      private SwipeRefreshLayout mRefreshLayout;
      private SwipeRefreshLayout mRefreshEmptyLayout;
      private TextView mEmptyListMessage;
  
      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;
 +    }
+     public void setFooterView(View footer) {
+         mList.addFooterView(footer, null, false);
+         mList.invalidate();
+     }
 +    
 +    protected void switchImageView(){
 +       imageView.setNumColumns(GridView.AUTO_FIT);
 +       imageView.invalidate();
 +    }
 +    
 +    protected void switchFileView(){
 +       imageView.setNumColumns(1);
 +       imageView.invalidate();
 +    }
 +    
 +    
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          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);
 -
 -        mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
 -        mList.setDividerHeight(1);
 +        
 +        imageView = (ExtendedListView)(v.findViewById(R.id.list_root));
 +        imageView.setOnItemClickListener(this);
  
          if (savedInstanceState != null) {
              int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION);
              setReferencePosition(referencePosition);
          }
-         
          // Pull down refresh
          mRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files);
          mRefreshEmptyLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files_emptyView);
          onCreateSwipeToRefresh(mRefreshLayout);
          onCreateSwipeToRefresh(mRefreshEmptyLayout);
          
 -        mList.setEmptyView(mRefreshEmptyLayout);
 -
          return v;
      }
  
-     
      /**
       * {@inheritDoc}
       */
          savedInstanceState.putString(KEY_EMPTY_LIST_MESSAGE, getEmptyViewText());
      }
  
-     
      /**
-      * Calculates the position of the item that will be used as a reference to reposition the visible items 
-      * in the list when the device is turned to other position. 
+      * Calculates the position of the item that will be used as a reference to
+      * reposition the visible items in the list when the device is turned to
+      * other position.
       * 
-      * THe current policy is take as a reference the visible item in the center of the screen.  
+      * THe current policy is take as a reference the visible item in the center
+      * of the screen.
       * 
-      * @return      The position in the list of the visible item in the center of the screen.
+      * @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;
          }
      }
  
-     
      /**
       * Sets the visible part of the list from the reference position.
       * 
-      * @param   position    Reference position previously 
-      * returned by {@link LocalFileListFragment#getReferencePosition()}
+      * @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);
      
      @Override
      public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
-         // to be @overriden  
+         // to be @overriden
      }
  
      @Override
              mOnRefreshListener.onRefresh();
          }
      }
-     
      public void setOnRefreshListener(OnEnforceableRefreshListener listener) {
          mOnRefreshListener = listener;
      }
@@@ -76,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
 +                    getGridView().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;
      }
@@@ -21,6 -21,7 +21,7 @@@ import java.io.File
  import java.util.Vector;
  
  import android.app.Activity;
+ import android.content.Context;
  import android.content.Intent;
  import android.os.Bundle;
  import android.support.v4.widget.SwipeRefreshLayout;
@@@ -30,6 -31,8 +31,8 @@@ import android.view.MenuItem
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.AdapterView.AdapterContextMenuInfo;
+ import android.widget.TextView;
+ import android.view.LayoutInflater;
  
  import com.owncloud.android.R;
  import com.owncloud.android.datamodel.FileDataStorageManager;
@@@ -37,7 -40,7 +40,7 @@@ import com.owncloud.android.datamodel.O
  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.FolderPickerActivity;
  import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
  import com.owncloud.android.ui.adapter.FileListListAdapter;
  import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@@ -45,6 -48,7 +48,7 @@@ import com.owncloud.android.ui.dialog.R
  import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
  import com.owncloud.android.ui.preview.PreviewImageFragment;
  import com.owncloud.android.ui.preview.PreviewMediaFragment;
+ import com.owncloud.android.utils.FileStorageUtils;
  
  /**
   * A Fragment that lists all files and folders in a given path.
@@@ -71,6 -75,7 +75,7 @@@ public class OCFileListFragment extend
     
      private OCFile mFile = null;
      private FileListListAdapter mAdapter;
+     private View mFooterView;
      
      private OCFile mTargetFile;
  
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          Log_OC.e(TAG, "onActivityCreated() start");
-         
          if (savedInstanceState != null) {
              mFile = savedInstanceState.getParcelable(KEY_FILE);
          }
-         
+         mFooterView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
+                         R.layout.list_footer, null, false);
+         setFooterView(mFooterView);
          Bundle args = getArguments();
          boolean justFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false); 
          mAdapter = new FileListListAdapter(
                  justFolders,
                  getSherlockActivity(), 
                  mContainerActivity
-         );
+                 );
          setListAdapter(mAdapter);
 -
 -        registerForContextMenu(getListView());
 -        getListView().setOnCreateContextMenuListener(this);
 -    }
 -
 +        
 +        registerForContextMenu(getGridView());
 +        getGridView().setOnCreateContextMenuListener(this);
 +  }
 +    
      /**
       * Saves the current listed folder.
       */
                  );
                  mf.filter(menu);
              }
-             
-             /// additional restrictions for this fragment 
-             // TODO allow in the future 'open with' for previewable files
-             MenuItem item = menu.findItem(R.id.action_open_file_with);
-             if (item != null) {
-                 item.setVisible(false);
-                 item.setEnabled(false);
-             }
+                  
              /// TODO break this direct dependency on FileDisplayActivity... if possible
+             MenuItem item = menu.findItem(R.id.action_open_file_with);
              FileFragment frag = ((FileDisplayActivity)getSherlockActivity()).getSecondFragment();
              if (frag != null && frag instanceof FileDetailFragment && 
                      frag.getFile().getFileId() == targetFile.getFileId()) {
                  mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
                  return true;
              }
+             case R.id.action_open_file_with: {
+                 mContainerActivity.getFileOperationsHelper().openFile(mTargetFile);
+                 return true;
+             }
              case R.id.action_unshare_file: {
                  mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile);
                  return true;
                  return true;
              }
              case R.id.action_move: {
-                 Intent action = new Intent(getActivity(), MoveActivity.class);
+                 Intent action = new Intent(getActivity(), FolderPickerActivity.class);
  
                  // Pass mTargetFile that contains info of selected file/folder
-                 action.putExtra(MoveActivity.EXTRA_TARGET_FILE, mTargetFile);
+                 action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
                  getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
                  return true;
              }
  
              mAdapter.swapDirectory(directory, storageManager);
              if (mFile == null || !mFile.equals(directory)) {
 -                mList.setSelectionFromTop(0, 0);
 +                imageView.setSelection(0);
              }
              mFile = directory;
              
+             // Update Footer
+             TextView footerText = (TextView) mFooterView.findViewById(R.id.footerText);
+             Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
+             footerText.setText(generateFooterText(directory));
+             Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
++            
 +         // decide image vs. file view
 +            double countImages = 0;
 +            double countFiles = 0;
 +            
 +            Vector<OCFile> files = storageManager.getFolderContent(directory);
 +            for (OCFile file : files){
 +                if (!file.isFolder()){
 +                    countFiles++;
 +                    
 +                    if (file.isImage()){
 +                        countImages++;
 +                    }
 +                }
 +            }
 +            
 +            // > 50% Images --> image view
 +            // TODO threshold as constant in Preferences
 +            if ((countImages / countFiles) >= 0.5){
 +                Log_OC.i(TAG, "Image View");
 +                switchImageView();
 +            } else {
 +                Log_OC.i(TAG, "Folder View");
 +                switchFileView();
 +            }
          }
      }
      
+     private String generateFooterText(OCFile directory) {
+         Integer files = 0;
+         Integer folders = 0;
+         FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+         Vector<OCFile> mFiles = storageManager.getFolderContent(mFile);
+         for (OCFile ocFile : mFiles) {
+             if (ocFile.isFolder()) {
+                 folders++;
+             } else {
+                 files++;
+             }
+         }
+         String output = "";
+        
+         if (files > 0){
+             if (files == 1) {
+                 output = output + files.toString() + " " + getResources().getString(R.string.file_list_file);
+             } else {
+                 output = output + files.toString() + " " + getResources().getString(R.string.file_list_files);
+             }
+         }
+         if (folders > 0 && files > 0){
+             output = output + ", ";
+         }
+         if (folders == 1) {
+             output = output + folders.toString() + " " + getResources().getString(R.string.file_list_folder);
+         } else if (folders > 1) {
+             output = output + folders.toString() + " " + getResources().getString(R.string.file_list_folders);
+         }
+         
+         return output;
+     }
+     
      public void sortByName(boolean descending) {
-         mAdapter.setSortOrder(FileListListAdapter.SORT_NAME, descending);
+         mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
      }
  
      public void sortByDate(boolean descending) {
-         mAdapter.setSortOrder(FileListListAdapter.SORT_DATE, descending);
+         mAdapter.setSortOrder(FileStorageUtils.SORT_DATE, descending);
      }
  
      public void sortBySize(boolean descending) {
-         mAdapter.setSortOrder(FileListListAdapter.SORT_SIZE, descending);
+         mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
      }  
  
  }