Merge remote-tracking branch 'remotes/upstream/resizedImages' into beta
authortobiasKaminsky <tobias@kaminsky.me>
Mon, 26 Oct 2015 21:49:00 +0000 (22:49 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Mon, 26 Oct 2015 21:49:00 +0000 (22:49 +0100)
1  2 
AndroidManifest.xml
owncloud-android-library
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/files/FileOperationsHelper.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/ui/preview/PreviewImageActivity.java
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

diff --combined AndroidManifest.xml
@@@ -1,4 -1,5 +1,4 @@@
 -<?xml version="1.0" encoding="utf-8"?>
 -<!-- 
 +<?xml version="1.0" encoding="utf-8"?><!--
    ownCloud Android client application
  
    Copyright (C) 2012  Bartek Przybylski
@@@ -17,8 -18,8 +17,8 @@@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   -->
  <manifest package="com.owncloud.android"
 -    android:versionCode="10700100"
 -    android:versionName="1.7.1" xmlns:android="http://schemas.android.com/apk/res/android">
 +    android:versionCode="10800000"
 +    android:versionName="1.8.0" xmlns:android="http://schemas.android.com/apk/res/android">
  
      <uses-permission android:name="android.permission.GET_ACCOUNTS" />
      <uses-permission android:name="android.permission.USE_CREDENTIALS" />
      <uses-permission android:name="android.permission.WAKE_LOCK"/>
      
      <uses-sdk
 -        android:minSdkVersion="8"
 -        android:targetSdkVersion="19" />
 +        android:minSdkVersion="14"
 +        android:targetSdkVersion="22" />
  
 -    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
 -    </uses-permission>
 +    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
  
      <application
          android:name=".MainApp"
          android:icon="@drawable/icon"
          android:label="@string/app_name"
 -        android:theme="@style/Theme.ownCloud"> 
 +        android:theme="@style/Theme.ownCloud">
          <activity
              android:name=".ui.activity.FileDisplayActivity"
 -            android:label="@string/app_name"
 -            >
 +            android:label="@string/app_name">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
 -        <activity android:name=".ui.activity.UploadFilesActivity">
 -        </activity>
 -        <activity android:name=".ui.activity.Uploader" >
 +        <activity android:name=".ui.activity.UploadFilesActivity"></activity>
 +        <activity android:name=".ui.activity.Uploader">
              <intent-filter>
 -                <action android:name="android.intent.action.SEND" >
 -                </action>
 +                <action android:name="android.intent.action.SEND"></action>
  
 -                <category android:name="android.intent.category.DEFAULT" >
 -                </category>
 +                <category android:name="android.intent.category.DEFAULT"></category>
  
 -                <data android:mimeType="*/*" >
 -                </data>
 +                <data android:mimeType="*/*"></data>
              </intent-filter>
              <intent-filter>
 -                <action android:name="android.intent.action.SEND_MULTIPLE" >
 -                </action>
 +                <action android:name="android.intent.action.SEND_MULTIPLE"></action>
  
 -                <category android:name="android.intent.category.DEFAULT" >
 -                </category>
 +                <category android:name="android.intent.category.DEFAULT"></category>
  
 -                <data android:mimeType="*/*" >
 -                </data>
 +                <data android:mimeType="*/*"></data>
  
 -                      </intent-filter>
 +            </intent-filter>
          </activity>
          <activity
              android:name=".ui.activity.Preferences"
              android:theme="@style/Theme.ownCloud" >
          </activity>
          <activity     
 -            android:name=".ui.preview.PreviewImageActivity" 
 +            android:name=".ui.preview.PreviewImageActivity"
 +            android:theme="@style/Theme.ownCloud.Overlay"
              />
                        
          <activity     
              android:name=".ui.preview.PreviewVideoActivity"
 -                      android:label="@string/app_name"
 -                      android:theme="@style/Theme.ownCloud.Fullscreen" 
 -                      >
 -              </activity>        
 +            android:label="@string/app_name"
 +            android:theme="@style/Theme.ownCloud.Fullscreen"></activity>
  
          <service
              android:name=".authentication.AccountAuthenticatorService"
              android:exported="true">
 -            <intent-filter  android:priority="100">
 +            <intent-filter android:priority="100">
                  <action android:name="android.accounts.AccountAuthenticator" />
              </intent-filter>
  
          </service>
          <service
              android:name=".syncadapter.FileSyncService"
 -            android:exported="true" 
 -            >
 +            android:exported="true">
              <intent-filter>
                  <action android:name="android.content.SyncAdapter" />
              </intent-filter>
              android:name=".providers.FileContentProvider"
              android:authorities="@string/authority"
              android:enabled="true"
-             android:exported="false"
+             android:exported="true"
              android:label="@string/sync_string_files"
 -            android:syncable="true" >
 -        </provider>
 +            android:syncable="true"></provider>
  
+         <provider
+             android:name=".ui.adapter.DiskLruImageCacheFileProvider"
+             android:authorities="com.owncloud.imageCache.provider">
+         </provider>
          <activity
              android:name=".authentication.AuthenticatorActivity"
              android:exported="true"
 -            android:theme="@style/Theme.ownCloud.noActionBar" 
 +            android:theme="@style/Theme.ownCloud.noActionBar"
              android:launchMode="singleTask">
              <intent-filter>
                  <action android:name="android.intent.action.VIEW" />
 +
                  <category android:name="android.intent.category.DEFAULT" />
                  <category android:name="android.intent.category.BROWSABLE" />
 +
                  <data android:scheme="@string/oauth2_redirect_scheme" />
              </intent-filter>
              <intent-filter>
          <service android:name=".files.services.FileDownloader" />
          <service android:name=".files.services.FileUploader" />
          <service android:name=".media.MediaService" />
 -        
 +
          <activity android:name=".ui.activity.PassCodeActivity" />
          <activity android:name=".ui.activity.ConflictsResolveActivity"/>
          <activity android:name=".ui.activity.GenericExplanationActivity"/>
              <intent-filter>
                  <!-- unofficially supported by many Android phones but not by HTC devices: -->
                  <action android:name="com.android.camera.NEW_PICTURE" />
 -                <!-- officially supported since Android 4.0 (SDK 14, works even for HTC devices): --> 
 +                <!-- officially supported since Android 4.0 (SDK 14, works even for HTC devices): -->
                  <action android:name="android.hardware.action.NEW_PICTURE" />
                  <data android:mimeType="image/*" />
              </intent-filter>
                  <data android:mimeType="video/*" />
              </intent-filter>
              <intent-filter>
 -                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
 +                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
              </intent-filter>
 +            <intent-filter>
 +                              <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
 +                          <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
 +                      </intent-filter>
          </receiver>
          <receiver android:name=".files.BootupBroadcastReceiver">
              <intent-filter>
 -                <action android:name="android.intent.action.BOOT_COMPLETED"/>
 +                <action android:name="android.intent.action.BOOT_COMPLETED" />
              </intent-filter>
          </receiver>
          <service android:name=".services.observer.FileObserverService"/>
                        android:label="@string/copy_link"
                        android:icon="@drawable/copy_link"/>
  
 -        <activity 
 +        <activity
                        android:name=".ui.activity.FolderPickerActivity"
                        android:label="@string/app_name"/>
  
 -        <activity 
 +        <activity
                        android:name=".ui.activity.UploadPathActivity"
                        android:label="@string/app_name"/>
          
diff --combined owncloud-android-library
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit ecc3415e3e3c13fa8f73fdd51a88c1ab7087b199
 -Subproject commit f5fbca24becbb01660abe2a7013c1b536ea8a301
++Subproject commit e7d9de771281ae673e1b1f64983c2d7eb7dada9b
@@@ -29,18 -29,23 +29,25 @@@ import org.apache.commons.httpclient.Ht
  import org.apache.commons.httpclient.methods.GetMethod;
  
  import android.accounts.Account;
+ import android.accounts.AccountManager;
+ import android.content.Context;
  import android.content.res.Resources;
  import android.graphics.Bitmap;
  import android.graphics.Bitmap.CompressFormat;
  import android.graphics.BitmapFactory;
 +import android.graphics.Canvas;
+ import android.graphics.Point;
  import android.graphics.drawable.BitmapDrawable;
 +import android.graphics.drawable.ColorDrawable;
  import android.graphics.drawable.Drawable;
  import android.media.ThumbnailUtils;
  import android.net.Uri;
  import android.os.AsyncTask;
+ import android.view.Display;
+ import android.view.View;
+ import android.view.WindowManager;
  import android.widget.ImageView;
+ import android.widget.ProgressBar;
  
  import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
@@@ -74,8 -79,8 +81,8 @@@ public class ThumbnailsCacheManager 
  
      public static Bitmap mDefaultImg = 
              BitmapFactory.decodeResource(
 -                    MainApp.getAppContext().getResources(), 
 -                    DisplayUtils.getFileTypeIconId("image/png", "default.png")
 +                    MainApp.getAppContext().getResources(),
 +                    R.drawable.file_image
              );
  
      
  
      public static class ThumbnailGenerationTask extends AsyncTask<Object, Void, Bitmap> {
          private final WeakReference<ImageView> mImageViewReference;
+         private WeakReference<ProgressBar> mProgressWheelRef;
          private static Account mAccount;
          private Object mFile;
+         private Boolean mIsThumbnail;
          private FileDataStorageManager mStorageManager;
  
          public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
                                         Account account) {
              // Use a WeakReference to ensure the ImageView can be garbage collected
              mAccount = account;
          }
  
+         public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
+                                        Account account, ProgressBar progressWheel) {
+         this(imageView, storageManager, account);
+         mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
+         }
          public ThumbnailGenerationTask(ImageView imageView) {
              // Use a WeakReference to ensure the ImageView can be garbage collected
              mImageViewReference = new WeakReference<ImageView>(imageView);
                  }
  
                  mFile = params[0];
+                 mIsThumbnail = (Boolean) params[1];
                  
                  if (mFile instanceof OCFile) {
-                     thumbnail = doOCFileInBackground();
+                     thumbnail = doOCFileInBackground(mIsThumbnail);
                  }  else if (mFile instanceof File) {
-                     thumbnail = doFileInBackground();
-                 //} else {  do nothing
+                     thumbnail = doFileInBackground(mIsThumbnail);
+                 } else {
+                     // do nothing
                  }
  
                  }catch(Throwable t){
          }
  
          protected void onPostExecute(Bitmap bitmap){
 -            if (isCancelled()) {
 -                bitmap = null;
 -            }
 -
              if (bitmap != null) {
                  final ImageView imageView = mImageViewReference.get();
                  final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
                          tagId = String.valueOf(mFile.hashCode());
                      }
                      if (String.valueOf(imageView.getTag()).equals(tagId)) {
+                         if (mProgressWheelRef != null) {
+                             final ProgressBar progressWheel = mProgressWheelRef.get();
+                             if (progressWheel != null) {
+                                 progressWheel.setVisibility(View.GONE);
+                             }
+                         }
                          imageView.setImageBitmap(bitmap);
+                         imageView.setVisibility(View.VISIBLE);
                      }
                  }
              }
           * @param imageKey: thumb key
           * @param bitmap:   image for extracting thumbnail
           * @param path:     image path
-          * @param px:       thumbnail dp
+          * @param pxW:       thumbnail width
+          * @param pxH:       thumbnail height
           * @return Bitmap
           */
-         private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){
+         private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int pxW, int pxH){
  
-             Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+             Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
  
              // Rotate image, obeying exif tag
              thumbnail = BitmapUtils.rotateImage(thumbnail,path);
              return Math.round(r.getDimension(R.dimen.file_icon_size_grid));
          }
  
-         private Bitmap doOCFileInBackground() {
+         private Point getScreenDimension(){
+             WindowManager wm = (WindowManager) MainApp.getAppContext().getSystemService(Context.WINDOW_SERVICE);
+             Display display = wm.getDefaultDisplay();
+             Point test = new Point();
+             display.getSize(test);
+             return test;
+         }
+         private Bitmap doOCFileInBackground(Boolean isThumbnail) {
+             Bitmap thumbnail = null;
              OCFile file = (OCFile)mFile;
  
-             final String imageKey = String.valueOf(file.getRemoteId());
+             // distinguish between thumbnail and resized image
+             String temp = String.valueOf(file.getRemoteId());
+             if (isThumbnail){
+                 temp = "t" + temp;
+             } else {
+                 temp = "r" + temp;
+             }
+             final String imageKey = temp;
  
              // Check disk cache in background thread
-             Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
+             thumbnail = getBitmapFromDiskCache(imageKey);
  
              // Not found in disk cache
              if (thumbnail == null || file.needsUpdateThumbnail()) {
-                 int px = getThumbnailDimension();
+                 int pxW = 0;
+                 int pxH = 0;
+                 if (mIsThumbnail) {
+                     pxW = pxH = getThumbnailDimension();
+                 } else {
+                     Point p = getScreenDimension();
+                     pxW = p.x;
+                     pxH = p.y;
+                 }
  
                  if (file.isDown()) {
-                     Bitmap temp = BitmapUtils.decodeSampledBitmapFromFile(
-                             file.getStoragePath(), px, px);
-                     Bitmap bitmap = ThumbnailUtils.extractThumbnail(temp, px, px);
 -                    Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
++                    Bitmap tempBitmap = BitmapUtils.decodeSampledBitmapFromFile(
+                             file.getStoragePath(), pxW, pxH);
++                    Bitmap bitmap = ThumbnailUtils.extractThumbnail(tempBitmap, pxW, pxH);
  
                      if (bitmap != null) {
 -                        thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), pxW, pxH);
 +                        // Handle PNG
 +                        if (file.getMimetype().equalsIgnoreCase("image/png")) {
-                             bitmap = handlePNG(bitmap, px);
++                            bitmap = handlePNG(bitmap, pxW);
 +                        }
 +
-                         thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px);
++                        thumbnail = addThumbnailToCache(imageKey, bitmap,
++                                                        file.getStoragePath(), pxW, pxH);
  
                          file.setNeedsUpdateThumbnail(false);
                          mStorageManager.saveFile(file);
                      if (mClient != null && serverOCVersion != null) {
                          if (serverOCVersion.supportsRemoteThumbnails()) {
                              try {
--                                String uri = mClient.getBaseUri() + "" +
--                                        "/index.php/apps/files/api/v1/thumbnail/" +
-                                         px + "/" + px + Uri.encode(file.getRemotePath(), "/");
 -                                        pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/");
--                                Log_OC.d("Thumbnail", "URI: " + uri);
--                                GetMethod get = new GetMethod(uri);
--                                int status = mClient.executeMethod(get);
--                                if (status == HttpStatus.SC_OK) {
 -//                                    byte[] bytes = get.getResponseBody();
 -//                                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
 -//                                            bytes.length);
--                                    InputStream inputStream = get.getResponseBodyAsStream();
--                                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
-                                     thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
 -                                    thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
 -                                    byte[] bytes = get.getResponseBody();
--
-                                     // Handle PNG
-                                     if (file.getMimetype().equalsIgnoreCase("image/png")) {
-                                         thumbnail = handlePNG(thumbnail, px);
 -                                    String type = "";
 -                                    if (mIsThumbnail){
 -                                        type = "Thumbnail";
++                                if (mIsThumbnail) {
++                                    String uri = mClient.getBaseUri() + "" +
++                                            "/index.php/apps/files/api/v1/thumbnail/" +
++                                            pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/");
++                                    Log_OC.d("Thumbnail", "Download URI: " + uri);
++                                    GetMethod get = new GetMethod(uri);
++                                    int status = mClient.executeMethod(get);
++                                    if (status == HttpStatus.SC_OK) {
++                                        InputStream inputStream = get.getResponseBodyAsStream();
++                                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
++                                        thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
+                                     } else {
 -                                        type = "Resized image";
++                                        Log_OC.d(TAG, "Status: " + status);
+                                     }
 -                                    Log_OC.d("Thumbnail",
 -                                            type + " size of " + file.getRemotePath()
 -                                                 + ": " + bytes.length);
 -
 -                                    // bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
 -
 -                                    if (mIsThumbnail) {
 -                                        thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
++                                } else {
++                                    String gallery = "";
++                                    if (serverOCVersion.supportsNativeGallery()){
++                                        gallery = "gallery";
+                                     } else {
 -                                        thumbnail = bitmap;
++                                        gallery = "galleryplus";
                                      }
  
--                                    // Add thumbnail to cache
--                                    if (thumbnail != null) {
--                                        addBitmapToCache(imageKey, thumbnail);
++                                    String uri = mClient.getBaseUri() +
++                                            "/index.php/apps/" + gallery + "/api/preview/" + Integer.parseInt(file.getRemoteId().substring(0,8)) +
++                                            "/" + pxW + "/" + pxH;
++                                    Log_OC.d("Thumbnail", "FileName: " + file.getFileName() + " Download URI: " + uri);
++                                    GetMethod get = new GetMethod(uri);
++                                    int status = mClient.executeMethod(get);
++                                    if (status == HttpStatus.SC_OK) {
++                                        InputStream inputStream = get.getResponseBodyAsStream();
++                                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
++                                        // Download via gallery app
++                                        thumbnail = bitmap;
                                      }
                                  }
++
++                                // Handle PNG
++                                if (thumbnail != null && file.getMimetype().equalsIgnoreCase("image/png")) {
++                                    thumbnail = handlePNG(thumbnail, pxW);
++                                }
++
++                                // Add thumbnail to cache
++                                if (thumbnail != null) {
++                                    addBitmapToCache(imageKey, thumbnail);
++                                }
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
  
          }
  
-         private Bitmap doFileInBackground() {
 +        private Bitmap handlePNG(Bitmap bitmap, int px){
 +            Bitmap resultBitmap = Bitmap.createBitmap(px,
 +                    px,
 +                    Bitmap.Config.ARGB_8888);
 +            Canvas c = new Canvas(resultBitmap);
 +
 +            c.drawColor(MainApp.getAppContext().getResources().
 +                    getColor(R.color.background_color));
 +            c.drawBitmap(bitmap, 0, 0, null);
 +
 +            return resultBitmap;
 +        }
 +
+         private Bitmap doFileInBackground(Boolean mIsThumbnail) {
+             Bitmap thumbnail = null;
              File file = (File)mFile;
  
              final String imageKey = String.valueOf(file.hashCode());
  
              // Check disk cache in background thread
-             Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
+             thumbnail = getBitmapFromDiskCache(imageKey);
  
              // Not found in disk cache
              if (thumbnail == null) {
-                 int px = getThumbnailDimension();
+                 int pxW = 0;
+                 int pxH = 0;
+                 if (mIsThumbnail) {
+                     pxW = pxH = getThumbnailDimension();
+                 } else {
+                     Point p = getScreenDimension();
+                     pxW = p.x;
+                     pxH = p.y;
+                 }
  
                  Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
-                         file.getAbsolutePath(), px, px);
+                         file.getAbsolutePath(), pxW, pxH);
  
                  if (bitmap != null) {
-                     thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px);
+                     thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), pxW, pxH);
                  }
              }
              return thumbnail;
              if (bitmapData == null || bitmapData != file) {
                  // Cancel previous task
                  bitmapWorkerTask.cancel(true);
 +                Log_OC.v(TAG, "Cancelled generation of thumbnail for a reused imageView");
              } else {
                  // The same work is already in progress
                  return false;
  
  package com.owncloud.android.files;
  
 -import org.apache.http.protocol.HTTP;
 -
  import android.accounts.Account;
 +import android.content.ActivityNotFoundException;
 +import android.content.Context;
  import android.content.Intent;
 +import android.content.pm.PackageManager;
 +import android.content.pm.ResolveInfo;
+ import android.graphics.Bitmap;
  import android.net.Uri;
  import android.support.v4.app.DialogFragment;
  import android.webkit.MimeTypeMap;
  import android.widget.Toast;
  
+ import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountUtils;
  import com.owncloud.android.datamodel.OCFile;
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 -
  import com.owncloud.android.lib.common.network.WebdavUtils;
  import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.lib.resources.status.OwnCloudVersion;
  import com.owncloud.android.services.OperationsService;
 +import com.owncloud.android.services.observer.FileObserverService;
  import com.owncloud.android.ui.activity.FileActivity;
+ import com.owncloud.android.ui.adapter.DiskLruImageCacheFileProvider;
  import com.owncloud.android.ui.dialog.ShareLinkToDialog;
  
 +import org.apache.http.protocol.HTTP;
 +
 +import java.util.List;
 +
+ import java.io.ByteArrayOutputStream;
+ import java.io.File;
+ import java.io.FileNotFoundException;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
  /**
   *
   */
  public class FileOperationsHelper {
  
      private static final String TAG = FileOperationsHelper.class.getName();
 -    
 -    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; 
 +
 +    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
  
      protected FileActivity mFileActivity = null;
  
      /// Identifier of operation in progress which result shouldn't be lost 
      private long mWaitingForOpId = Long.MAX_VALUE;
 -    
 +
      public FileOperationsHelper(FileActivity fileActivity) {
          mFileActivity = fileActivity;
      }
@@@ -72,7 -76,7 +82,7 @@@
          if (file != null) {
              String storagePath = file.getStoragePath();
              String encodedStoragePath = WebdavUtils.encodePath(storagePath);
 -            
 +
              Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
              intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
              intentForSavedMimeType.setFlags(
                      );
                  }
              }
 -            
 -            Intent chooserIntent;
 +
 +            Intent openFileWithIntent;
              if (intentForGuessedMimeType != null) {
 -                chooserIntent = Intent.createChooser(intentForGuessedMimeType, mFileActivity.getString(R.string.actionbar_open_with));
 +                openFileWithIntent = intentForGuessedMimeType;
              } else {
 -                chooserIntent = Intent.createChooser(intentForSavedMimeType, mFileActivity.getString(R.string.actionbar_open_with));
 +                openFileWithIntent = intentForSavedMimeType;
              }
 -            
 -            mFileActivity.startActivity(chooserIntent);
 -            
 +
 +            List<ResolveInfo> launchables = mFileActivity.getPackageManager().
 +                    queryIntentActivities(openFileWithIntent, PackageManager.GET_INTENT_FILTERS);
 +
 +            if(launchables != null && launchables.size() > 0) {
 +                try {
 +                    mFileActivity.startActivity(
 +                            Intent.createChooser(
 +                                    openFileWithIntent, mFileActivity.getString(R.string.actionbar_open_with)
 +                            )
 +                    );
 +                } catch (ActivityNotFoundException anfe) {
 +                    showNoAppForFileTypeToast(mFileActivity.getApplicationContext());
 +                }
 +            } else {
 +                showNoAppForFileTypeToast(mFileActivity.getApplicationContext());
 +            }
 +
          } else {
              Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
          }
      }
 -    
 -    
 +
 +    /**
 +     * Displays a toast stating that no application could be found to open the file.
 +     *
 +     * @param context the context to be able to show a toast.
 +     */
 +    private void showNoAppForFileTypeToast(Context context) {
 +        Toast.makeText(context,
 +                R.string.file_list_no_app_for_file_type, Toast.LENGTH_SHORT)
 +                .show();
 +    }
 +
      public void shareFileWithLink(OCFile file) {
 -        
 +
          if (isSharedSupported()) {
              if (file != null) {
                  String link = "https://fake.url";
                  Intent intent = createShareWithLinkIntent(link);
 -                String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
 +                String[] packagesToExclude = new String[]{mFileActivity.getPackageName()};
                  DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, packagesToExclude, file);
                  chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
 -                
 +
              } else {
                  Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
              }
 -            
 +
          } else {
              // Show a Message
              Toast t = Toast.makeText(
              t.show();
          }
      }
 -    
 -    
 +
 +
      public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) {
          
          if (file != null) {
              mFileActivity.showLoadingDialog();
 -            
 +
              Intent service = new Intent(mFileActivity, OperationsService.class);
              service.setAction(OperationsService.ACTION_CREATE_SHARE);
              service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
              Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
          }
      }
 -    
 -    
 +
 +
      private Intent createShareWithLinkIntent(String link) {
          Intent intentToShareLink = new Intent(Intent.ACTION_SEND);
          intentToShareLink.putExtra(Intent.EXTRA_TEXT, link);
          intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE);
 -        return intentToShareLink; 
 +        return intentToShareLink;
      }
 -    
 -    
 +
 +
      /**
 -     *  @return 'True' if the server supports the Share API
 +     * @return 'True' if the server supports the Share API
       */
      public boolean isSharedSupported() {
          if (mFileActivity.getAccount() != null) {
          }
          return false;
      }
 -    
 -    
 +
 +
      public void unshareFileWithLink(OCFile file) {
 -        
 +
          if (isSharedSupported()) {
              // Unshare the file
              Intent service = new Intent(mFileActivity, OperationsService.class);
              mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
              
              mFileActivity.showLoadingDialog();
 -            
 +
          } else {
              // Show a Message
              Toast t = Toast.makeText(mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG);
              t.show();
 -            
 +
          }
      }
 -    
 +
      public void sendDownloadedFile(OCFile file) {
          if (file != null) {
 +            String storagePath = file.getStoragePath();
 +            String encodedStoragePath = WebdavUtils.encodePath(storagePath);
              Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
              // set MimeType
              sendIntent.setType(file.getMimetype());
 -            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getStoragePath()));
 +            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + encodedStoragePath));
              sendIntent.putExtra(Intent.ACTION_SEND, true);      // Send Action
 -            
 +
              // Show dialog, without the own app
 -            String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
 +            String[] packagesToExclude = new String[]{mFileActivity.getPackageName()};
              DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file);
              chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
  
          }
      }
  
 -    
 -    
+     public void sendCachedImage(OCFile file) {
+         if (file != null) {
+             Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
+             // set MimeType
+             sendIntent.setType(file.getMimetype());
+ //            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName()));
+             sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath()));
+             sendIntent.putExtra(Intent.ACTION_SEND, true);      // Send Action
+             // Show dialog, without the own app
+             String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
+             DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file);
+             chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
+         } else {
+             Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
+         }
+     }
++
 +
      public void syncFile(OCFile file) {
 -        
 +
          if (!file.isFolder()){
              Intent intent = new Intent(mFileActivity, OperationsService.class);
              intent.setAction(OperationsService.ACTION_SYNC_FILE);
              mFileActivity.startService(intent);
          }
      }
 +
 +    public void toggleFavorite(OCFile file, boolean isFavorite) {
 +        file.setFavorite(isFavorite);
 +        mFileActivity.getStorageManager().saveFile(file);
 +
 +        /// register the OCFile instance in the observer service to monitor local updates
 +        Intent observedFileIntent = FileObserverService.makeObservedFileIntent(
 +                mFileActivity,
 +                file,
 +                mFileActivity.getAccount(),
 +                isFavorite);
 +        mFileActivity.startService(observedFileIntent);
 +
 +        /// immediate content synchronization
 +        if (file.isFavorite()) {
 +            syncFile(file);
 +        }
 +    }
      
      public void renameFile(OCFile file, String newFilename) {
          // RenameFile
          
          mFileActivity.showLoadingDialog();
      }
 -    
 -    
 +
 +
      public void createFolder(String remotePath, boolean createFullPath) {
          // Create Folder
          Intent service = new Intent(mFileActivity, OperationsService.class);
              downloaderBinder.cancel(account, file);
  
              // TODO - review why is this here, and solve in a better way
 -            // Remove etag for parent, if file is a keep_in_sync
 -            if (file.keepInSync()) {
 +            // Remove etag for parent, if file is a favorite
 +            if (file.isFavorite()) {
                  OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId());
                  parent.setEtag("");
                  mFileActivity.getStorageManager().saveFile(parent);
  
      /**
       * Start move file operation
 -     * @param newfile           File where it is going to be moved
 -     * @param currentFile       File with the previous info
 +     *
 +     * @param newfile     File where it is going to be moved
 +     * @param currentFile File with the previous info
       */
      public void moveFile(OCFile newfile, OCFile currentFile) {
          // Move files
          mFileActivity.showLoadingDialog();
      }
  
 +    /**
 +     * Start copy file operation
 +     *
 +     * @param newfile     File where it is going to be moved
 +     * @param currentFile File with the previous info
 +     */
 +    public void copyFile(OCFile newfile, OCFile currentFile) {
 +        // Copy files
 +        Intent service = new Intent(mFileActivity, OperationsService.class);
 +        service.setAction(OperationsService.ACTION_COPY_FILE);
 +        service.putExtra(OperationsService.EXTRA_NEW_PARENT_PATH, newfile.getRemotePath());
 +        service.putExtra(OperationsService.EXTRA_REMOTE_PATH, currentFile.getRemotePath());
 +        service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
 +        mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
 +
 +        mFileActivity.showLoadingDialog();
 +    }
  
      public long getOpIdWaitingFor() {
          return mWaitingForOpId;
      public void setOpIdWaitingFor(long waitingForOpId) {
          mWaitingForOpId = waitingForOpId;
      }
 -    
 +
      /**
       *  @return 'True' if the server doesn't need to check forbidden characters
       */
@@@ -4,7 -4,6 +4,7 @@@
   *   @author Bartek Przybylski\r
   *   @author Tobias Kaminsky\r
   *   @author David A. Velasco\r
 + *   @author masensio\r
   *   Copyright (C) 2011  Bartek Przybylski\r
   *   Copyright (C) 2015 ownCloud Inc.\r
   *\r
@@@ -55,7 -54,6 +55,7 @@@ import com.owncloud.android.services.Op
  import com.owncloud.android.ui.activity.ComponentsGetter;\r
  import com.owncloud.android.utils.DisplayUtils;\r
  import com.owncloud.android.utils.FileStorageUtils;\r
 +import com.owncloud.android.utils.MimetypeIconUtil;\r
  \r
  \r
  /**\r
@@@ -270,14 -268,15 +270,14 @@@ public class FileListListAdapter extend
                      }\r
  \r
                      // share with me icon\r
 -                    if (!file.isFolder()) {\r
 -                        ImageView sharedWithMeIconV = (ImageView)\r
 -                                view.findViewById(R.id.sharedWithMeIcon);\r
 -                        sharedWithMeIconV.bringToFront();\r
 -                        if (checkIfFileIsSharedWithMe(file)) {\r
 -                            sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 -                        } else {\r
 -                            sharedWithMeIconV.setVisibility(View.GONE);\r
 -                        }\r
 +                    ImageView sharedWithMeIconV = (ImageView)\r
 +                            view.findViewById(R.id.sharedWithMeIcon);\r
 +                    sharedWithMeIconV.bringToFront();\r
 +                    if (checkIfFileIsSharedWithMe(file) &&\r
 +                            (!file.isFolder() || !mGridMode)) {\r
 +                        sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                    } else {\r
 +                        sharedWithMeIconV.setVisibility(View.GONE);\r
                      }\r
  \r
                      break;\r
              \r
              // this if-else is needed even though favorite icon is visible by default\r
              // because android reuses views in listview\r
 -            if (!file.keepInSync()) {\r
 +            if (!file.isFavorite()) {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);\r
              } else {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE);\r
                                      task\r
                                      );\r
                              fileIcon.setImageDrawable(asyncDrawable);\r
-                             task.execute(file);\r
+                             task.execute(file, true);\r
                          }\r
                      }\r
 +\r
 +                    if (file.getMimetype().equalsIgnoreCase("image/png")) {\r
 +                        fileIcon.setBackgroundColor(mContext.getResources()\r
 +                                .getColor(R.color.background_color));\r
 +                    }\r
 +\r
 +\r
                  } else {\r
 -                    fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(),\r
 +                    fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(file.getMimetype(),\r
                              file.getFileName()));\r
                  }\r
  \r
              } else {\r
                  // Folder\r
 -                if (checkIfFileIsSharedWithMe(file)) {\r
 -                    fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
 -                } else if (file.isShareByLink()) {\r
 -                    // If folder is sharedByLink, icon folder must be changed to\r
 -                    // folder-public one\r
 -                    fileIcon.setImageResource(R.drawable.folder_public);\r
 -                } else {\r
 -                    fileIcon.setImageResource(\r
 -                            DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName())\r
 -                    );\r
 -                }\r
 +                fileIcon.setImageResource(\r
 +                        MimetypeIconUtil.getFolderTypeIconId(\r
 +                                checkIfFileIsSharedWithMe(file), file.isShareByLink()));\r
              }\r
          }\r
  \r
   */
  package com.owncloud.android.ui.fragment;
  
 -import java.io.File;
 -
  import android.app.Activity;
  import android.content.Intent;
  import android.os.Bundle;
  import android.support.v4.widget.SwipeRefreshLayout;
  import android.view.ContextMenu;
 +import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.AdapterView.AdapterContextMenuInfo;
 +import android.widget.PopupMenu;
  
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountUtils;
@@@ -48,35 -48,31 +48,35 @@@ import com.owncloud.android.ui.activity
  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.FileActionsDialogFragment;
  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.FileStorageUtils;
 +import com.owncloud.android.ui.preview.PreviewTextFragment;
 +
 +import java.io.File;
  
  /**
   * A Fragment that lists all files and folders in a given path.
 - * 
 + *
   * TODO refactor to get rid of direct dependency on FileDisplayActivity
   */
 -public class OCFileListFragment extends ExtendedListFragment {
 +public class OCFileListFragment extends ExtendedListFragment implements FileActionsDialogFragment.FileActionsDialogFragmentListener {
      
      private static final String TAG = OCFileListFragment.class.getSimpleName();
  
      private static final String MY_PACKAGE = OCFileListFragment.class.getPackage() != null ?
              OCFileListFragment.class.getPackage().getName() : "com.owncloud.android.ui.fragment";
 -            
 +
      public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS";
      public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL";
 -            
 +
      private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE";
  
      private FileFragment.ContainerActivity mContainerActivity;
 -   
 +
      private OCFile mFile = null;
      private FileListListAdapter mAdapter;
      private boolean mJustFolders;
          Log_OC.e(TAG, "onAttach");
          try {
              mContainerActivity = (FileFragment.ContainerActivity) activity;
 -            
 +
          } catch (ClassCastException e) {
 -            throw new ClassCastException(activity.toString() + " must implement " + 
 +            throw new ClassCastException(activity.toString() + " must implement " +
                      FileFragment.ContainerActivity.class.getSimpleName());
          }
          try {
              setOnRefreshListener((OnEnforceableRefreshListener) activity);
              
          } catch (ClassCastException e) {
 -            throw new ClassCastException(activity.toString() + " must implement " + 
 +            throw new ClassCastException(activity.toString() + " must implement " +
                      SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
          }
      }
  
 -    
 +
      @Override
      public void onDetach() {
          setOnRefreshListener(null);
                  mJustFolders,
                  getActivity(),
                  mContainerActivity
 -                );
 +        );
          setListAdapter(mAdapter);
  
 -        registerForContextMenu();
 +        registerLongClickListener();
    }
  
 +    private void registerLongClickListener() {
 +        getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
 +            public boolean onItemLongClick(AdapterView<?> arg0, View v,
 +                                           int index, long arg3) {
 +                showFileAction(index);
 +                return true;
 +            }
 +        });
 +    }
 +
 +
 +    private void showFileAction(int fileIndex) {
 +        Bundle args = getArguments();
 +        PopupMenu pm = new PopupMenu(getActivity(),null);
 +        Menu menu = pm.getMenu();
 +
 +        boolean allowContextualActions =
 +                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
 +
 +        if (allowContextualActions) {
 +            MenuInflater inflater = getActivity().getMenuInflater();
 +
 +            inflater.inflate(R.menu.file_actions_menu, menu);
 +            OCFile targetFile = (OCFile) mAdapter.getItem(fileIndex);
 +
 +            if (mContainerActivity.getStorageManager() != null) {
 +                FileMenuFilter mf = new FileMenuFilter(
 +                        targetFile,
 +                        mContainerActivity.getStorageManager().getAccount(),
 +                        mContainerActivity,
 +                        getActivity()
 +                );
 +                mf.filter(menu);
 +            }
 +
 +            /// TODO break this direct dependency on FileDisplayActivity... if possible
 +            MenuItem item = menu.findItem(R.id.action_open_file_with);
 +            FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment();
 +            if (frag != null && frag instanceof FileDetailFragment &&
 +                    frag.getFile().getFileId() == targetFile.getFileId()) {
 +                item = menu.findItem(R.id.action_see_details);
 +                if (item != null) {
 +                    item.setVisible(false);
 +                    item.setEnabled(false);
 +                }
 +            }
 +
 +            FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, fileIndex, targetFile.getFileName());
 +            dialog.setTargetFragment(this, 0);
 +            dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS);
 +        }
 +    }
 +
      /**
       * Saves the current listed folder.
       */
      @Override
 -    public void onSaveInstanceState (Bundle outState) {
 +    public void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
          outState.putParcelable(KEY_FILE, mFile);
      }
 -    
 +
      /**
       * Call this, when the user presses the up button.
 -     * 
 -     * Tries to move up the current folder one level. If the parent folder was removed from the 
 +     *
 +     * Tries to move up the current folder one level. If the parent folder was removed from the
       * database, it continues browsing up until finding an existing folders.
 -     * 
 +     * <p/>
       * return       Count of folder levels browsed up.
       */
      public int onBrowseUp() {
          OCFile parentDir = null;
          int moveCount = 0;
 -        
 -        if(mFile != null){
 +
 +        if (mFile != null) {
              FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
 -            
 +
              String parentPath = null;
              if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {
                  parentPath = new File(mFile.getRemotePath()).getParent();
 -                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : 
 -                      parentPath + OCFile.PATH_SEPARATOR;
 +                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
 +                        parentPath + OCFile.PATH_SEPARATOR;
                  parentDir = storageManager.getFileByPath(parentPath);
                  moveCount++;
              } else {
              }
              while (parentDir == null) {
                  parentPath = new File(parentPath).getParent();
 -                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : 
 -                      parentPath + OCFile.PATH_SEPARATOR;
 +                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
 +                        parentPath + OCFile.PATH_SEPARATOR;
                  parentDir = storageManager.getFileByPath(parentPath);
                  moveCount++;
              }   // exit is granted because storageManager.getFileByPath("/") never returns null
              listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/);
  
              onRefresh(false);
 -            
 +
              // restore index and top position
              restoreIndexAndTopPosition();
 -            
 +
          }   // else - should never happen now
 -   
 +
          return moveCount;
      }
 -    
 +
      @Override
      public void onItemClick(AdapterView<?> l, View v, int position, long id) {
          OCFile file = (OCFile) mAdapter.getItem(position);
          if (file != null) {
 -            if (file.isFolder()) { 
 +            if (file.isFolder()) {
                  // update state and view of this fragment
                  // TODO Enable when "On Device" is recovered ?
                  listDirectory(file/*, MainApp.getOnlyOnDevice()*/);
                  mContainerActivity.onBrowsedDownTo(file);
                  // save index and top position
                  saveIndexAndTopPosition(position);
 -                
 +
              } else { /// Click on a file
                  if (PreviewImageFragment.canBePreviewed(file)) {
                      // preview image - it handles the download, if needed
                      ((FileDisplayActivity)mContainerActivity).startImagePreview(file);
 -                    
 +                } else if (PreviewTextFragment.canBePreviewed(file)){
 +                    ((FileDisplayActivity)mContainerActivity).startTextPreview(file);
                  } else if (file.isDown()) {
                      if (PreviewMediaFragment.canBePreviewed(file)) {
                          // media preview
 -                        ((FileDisplayActivity)mContainerActivity).startMediaPreview(file, 0, true);
 +                        ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true);
                      } else {
                          mContainerActivity.getFileOperationsHelper().openFile(file);
                      }
-                 } else {
-                     // automatic download, preview on finish
-                     ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file);
+                     
                  }
              }
 -            
 +
          } else {
              Log_OC.d(TAG, "Null object in ListAdapter!!");
          }
 -        
 +
      }
 -    
 +
      /**
       * {@inheritDoc}
       */
      @Override
 -    public void onCreateContextMenu (
 +    public void onCreateContextMenu(
              ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
 -        super.onCreateContextMenu(menu, v, menuInfo);
          Bundle args = getArguments();
 -        boolean allowContextualActions = 
 -                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); 
 +        boolean allowContextualActions =
 +                (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
          if (allowContextualActions) {
              MenuInflater inflater = getActivity().getMenuInflater();
              inflater.inflate(R.menu.file_actions_menu, menu);
              AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
              OCFile targetFile = (OCFile) mAdapter.getItem(info.position);
 -            
 +
              if (mContainerActivity.getStorageManager() != null) {
                  FileMenuFilter mf = new FileMenuFilter(
                      targetFile,
              }
          }
      }
 -    
 -    
 +
      /**
 -     * {@inhericDoc}
 +     * {@inheritDoc}
       */
      @Override
 -    public boolean onContextItemSelected (MenuItem item) {
 -        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
 -        mTargetFile = (OCFile) mAdapter.getItem(info.position);
 -        switch (item.getItemId()) {                
 +    public boolean onFileActionChosen(int menuId, int filePosition) {
 +        mTargetFile = (OCFile) mAdapter.getItem(filePosition);
 +        switch (menuId) {
              case R.id.action_share_file: {
                  mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
                  return true;
                  dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
                  return true;
              }
 -            case R.id.action_download_file: 
 +            case R.id.action_download_file:
              case R.id.action_sync_file: {
                  mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
                  return true;
              }
              case R.id.action_cancel_download:
              case R.id.action_cancel_upload: {
 -                ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
 +                ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
                  return true;
              }
              case R.id.action_see_details: {
                  // Obtain the file
                  if (!mTargetFile.isDown()) {  // Download the file
                      Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
 -                    ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile);
 -                    
 +                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
 +
                  } else {
                      mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
                  }
                  getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
                  return true;
              }
 +            case R.id.action_favorite_file: {
 +                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
 +                return true;
 +            }
 +            case R.id.action_unfavorite_file: {
 +                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
 +                return true;
 +            }
 +            case R.id.action_copy:
 +                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
 +
 +                // Pass mTargetFile that contains info of selected file/folder
 +                action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
 +                getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
 +                return true;
              default:
 -                return super.onContextItemSelected(item); 
 +                return false;
 +        }
 +    }
 +    
 +    /**
 +     * {@inhericDoc}
 +     */
 +    @Override
 +    public boolean onContextItemSelected (MenuItem item) {
 +        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
 +        boolean matched = onFileActionChosen(item.getItemId(), ((AdapterContextMenuInfo) item.getMenuInfo()).position);
 +        if(!matched) {
 +            return super.onContextItemSelected(item);
 +        } else {
 +            return matched;
          }
      }
  
      /**
       * Use this to query the {@link OCFile} that is currently
       * being displayed by this fragment
 +     *
       * @return The currently viewed OCFile
       */
 -    public OCFile getCurrentFile(){
 +    public OCFile getCurrentFile() {
          return mFile;
      }
 -    
 +
      /**
       * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
       */
          // TODO Enable when "On Device" is recovered ?
          listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/);
      }
 -    
 +
      /**
       * Lists the given directory on the view. When the input parameter is null,
       * it will either refresh the last known directory. list the root
       * if there never was a directory.
 -     * 
 +     *
       * @param directory File to be listed
       */
      public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) {
          if (storageManager != null) {
  
              // Check input parameters for null
 -            if(directory == null){
 -                if(mFile != null){
 +            if (directory == null) {
 +                if (mFile != null) {
                      directory = mFile;
                  } else {
                      directory = storageManager.getFileByPath("/");
                      if (directory == null) return; // no files, wait for sync
                  }
              }
 -        
 -        
 +
 +
              // If that's not a directory -> List its parent
 -            if(!directory.isFolder()){
 +            if (!directory.isFolder()) {
                  Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
                  directory = storageManager.getFileById(directory.getParentId());
              }
                  if (file.isFolder()) {
                      foldersCount++;
                  } else {
 -                    filesCount++;
 -                    if (file.isImage()){
 -                        imagesCount++;
 +                    if (!file.isHidden()) {
 +                        filesCount++;
 +
 +                        if (file.isImage()) {
 +                            imagesCount++;
 +                        }
                      }
                  }
              }
              if (version != null && version.supportsRemoteThumbnails() &&
                  imagesCount > 0 && imagesCount == filesCount) {
                  switchToGridView();
 +                registerLongClickListener();
              } else {
                  switchToListView();
              }
      }
  
      private String generateFooterText(int filesCount, int foldersCount) {
 -        String output = "";
 -        if (filesCount > 0){
 -            if (filesCount == 1) {
 -                output = output + filesCount + " " + getResources().getString(R.string.file_list_file);
 -            } else {
 -                output = output + filesCount + " " + getResources().getString(R.string.file_list_files);
 +        String output;
 +        if (filesCount <= 0) {
 +            if (foldersCount <= 0) {
 +                output = "";
 +
 +            } else if (foldersCount == 1) {
 +                output = getResources().getString(R.string.file_list__footer__folder);
 +
 +            } else { // foldersCount > 1
 +                output = getResources().getString(R.string.file_list__footer__folders, foldersCount);
              }
 -        }
 -        if (foldersCount > 0 && filesCount > 0){
 -            output = output + ", ";
 -        }
 -        if (foldersCount == 1) {
 -            output = output + foldersCount + " " + getResources().getString(R.string.file_list_folder);
 -        } else if (foldersCount > 1) {
 -            output = output + foldersCount + " " + getResources().getString(R.string.file_list_folders);
 -        }
  
 +        } else if (filesCount == 1) {
 +            if (foldersCount <= 0) {
 +                output = getResources().getString(R.string.file_list__footer__file);
 +
 +            } else if (foldersCount == 1) {
 +                output = getResources().getString(R.string.file_list__footer__file_and_folder);
 +
 +            } else { // foldersCount > 1
 +                output = getResources().getString(R.string.file_list__footer__file_and_folders, foldersCount);
 +            }
 +        } else {    // filesCount > 1
 +            if (foldersCount <= 0) {
 +                output = getResources().getString(R.string.file_list__footer__files, filesCount);
 +
 +            } else if (foldersCount == 1) {
 +                output = getResources().getString(R.string.file_list__footer__files_and_folder, filesCount);
 +
 +            } else { // foldersCount > 1
 +                output = getResources().getString(
 +                        R.string.file_list__footer__files_and_folders, filesCount, foldersCount
 +                );
 +
 +            }
 +        }
          return output;
      }
  
 -
      public void sortByName(boolean descending) {
          mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
      }
  
      public void sortBySize(boolean descending) {
          mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
 -    }  
 -    
 -   
 -    
 +    }
  }
@@@ -26,7 -26,6 +26,7 @@@ import android.content.Context
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.content.ServiceConnection;
 +import android.graphics.drawable.ColorDrawable;
  import android.os.Build;
  import android.os.Bundle;
  import android.os.Handler;
@@@ -56,7 -55,6 +56,7 @@@ import com.owncloud.android.lib.common.
  import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.operations.CreateShareOperation;
  import com.owncloud.android.operations.RemoveFileOperation;
 +import com.owncloud.android.operations.SynchronizeFileOperation;
  import com.owncloud.android.operations.UnshareLinkOperation;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.activity.FileDisplayActivity;
@@@ -105,6 -103,7 +105,6 @@@ public class PreviewImageActivity exten
  
          // ActionBar
          ActionBar actionBar = getSupportActionBar();
 -        actionBar.setIcon(DisplayUtils.getSeasonalIconId());
          updateActionBarTitleAndHomeButton(null);
          actionBar.hide();
  
                  }
              });
  
 +            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 +                getWindow().setStatusBarColor(getResources().getColor(R.color.owncloud_blue_dark_transparent));
 +            }
          }
              
          if (savedInstanceState != null) {
              
          } else if (operation instanceof RemoveFileOperation) {
              finish();
 +        } else if (operation instanceof SynchronizeFileOperation) {
 +            onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result);
 +
          }
      }
      
          }
      }
  
 +    private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation,
 +                                                  RemoteOperationResult result) {
 +        if (result.isSuccess()) {
 +            invalidateOptionsMenu();
 +        }
 +
 +    }
 +
      @Override
      protected ServiceConnection newTransferenceServiceConnection() {
          return new PreviewImageServiceConnection();
              OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); 
              getSupportActionBar().setTitle(currentFile.getFileName());
              mDrawerToggle.setDrawerIndicatorEnabled(false);
-             if (!currentFile.isDown()) {
-                 if (!mPreviewImagePagerAdapter.pendingErrorAt(position)) {
-                     requestForDownload(currentFile);
-                 }
-             }
+             
              // Call to reset image zoom to initial state
              ((PreviewImagePagerAdapter) mViewPager.getAdapter()).resetZoom();
          }
  
      /**
       * Checks if OS version is Honeycomb one or higher
 -     * 
 +     *
       * @return boolean
       */
      private boolean isHoneycombOrHigher() {
@@@ -26,7 -26,6 +26,7 @@@ import android.annotation.SuppressLint
  import android.app.Activity;
  import android.graphics.Bitmap;
  import android.graphics.Point;
 +import android.graphics.drawable.Drawable;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.support.v4.app.FragmentStatePagerAdapter;
@@@ -41,8 -40,10 +41,10 @@@ import android.widget.ImageView
  import android.widget.ProgressBar;
  import android.widget.TextView;
  
+ import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
  import com.owncloud.android.datamodel.OCFile;
+ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
  import com.owncloud.android.files.FileMenuFilter;
  import com.owncloud.android.lib.common.utils.Log_OC;
  import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@@ -74,12 -75,14 +76,14 @@@ public class PreviewImageFragment exten
      private TextView mMessageView;
      private ProgressBar mProgressWheel;
  
+     private Boolean mShowResizedImage = false;
      public Bitmap mBitmap = null;
 -    
 +
      private static final String TAG = PreviewImageFragment.class.getSimpleName();
  
      private boolean mIgnoreFirstSavedState;
 -    
 +
      private LoadBitmapTask mLoadBitmapTask = null;
  
  
       *                                  {@link FragmentStatePagerAdapter}
       *                                  ; TODO better solution
       */
-     public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){
+     public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState,
+             boolean showResizedImage){
          PreviewImageFragment frag = new PreviewImageFragment();
+         frag.mShowResizedImage = showResizedImage;
          Bundle args = new Bundle();
          args.putParcelable(ARG_FILE, imageFile);
          args.putBoolean(ARG_IGNORE_FIRST, ignoreFirstSavedState);
          return frag;
      }
  
 -    
 +
      
      /**
       *  Creates an empty fragment for image previews.
      public PreviewImageFragment() {
          mIgnoreFirstSavedState = false;
      }
 -    
 -    
 +
 +
      /**
       * {@inheritDoc}
       */
          mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST);
          setHasOptionsMenu(true);
      }
 -    
 +
  
      /**
       * {@inheritDoc}
       */
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
 -            Bundle savedInstanceState) {
 +                             Bundle savedInstanceState) {
          super.onCreateView(inflater, container, savedInstanceState);
          View view = inflater.inflate(R.layout.preview_image_fragment, container, false);
          mImageView = (TouchImageViewCustom) view.findViewById(R.id.image);
          if (getFile() == null) {
              throw new IllegalStateException("Instanced with a NULL OCFile");
          }
-         if (!getFile().isDown()) {
-             throw new IllegalStateException("There is no local file to preview");
-         }
      }
 -        
 +
  
      /**
       * {@inheritDoc}
          super.onSaveInstanceState(outState);
          outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile());
      }
 -    
 +
  
      @Override
      public void onStart() {
          super.onStart();
          if (getFile() != null) {
-             mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
-             //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
- //            mLoadBitmapTask.execute(getFile().getStoragePath());
-             mLoadBitmapTask.execute(getFile());
+             mImageView.setTag(getFile().getFileId());
+             if (mShowResizedImage){
+                 Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                         String.valueOf("r" + getFile().getRemoteId())
+                 );
+                 if (thumbnail != null && !getFile().needsUpdateThumbnail()){
+                     mProgressWheel.setVisibility(View.GONE);
+                     mImageView.setImageBitmap(thumbnail);
+                     mImageView.setVisibility(View.VISIBLE);
+                     mBitmap  = thumbnail;
+                 } else {
+                 // generate new Thumbnail
+                     if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView)) {
+                         final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+                                 new ThumbnailsCacheManager.ThumbnailGenerationTask(
+                                         mImageView, mContainerActivity.getStorageManager(),
+                                         mContainerActivity.getStorageManager().getAccount(),
+                                         mProgressWheel);
+                         if (thumbnail == null) {
+                             thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                         }
+                         final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+                                 new ThumbnailsCacheManager.AsyncDrawable(
+                                         MainApp.getAppContext().getResources(),
+                                         thumbnail,
+                                         task
+                                 );
+                         mImageView.setImageDrawable(asyncDrawable);
+                         task.execute(getFile(), false);
+                     }
+             }
+             } else {
+                 mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
 -                mLoadBitmapTask.execute(getFile().getStoragePath());
++                mLoadBitmapTask.execute(getFile());
+             }
          }
      }
 -    
 -    
 +
 +
      @Override
      public void onStop() {
          Log_OC.d(TAG, "onStop starts");
          }
          super.onStop();
      }
 -    
 +
      /**
       * {@inheritDoc}
       */
      @Override
      public void onPrepareOptionsMenu(Menu menu) {
          super.onPrepareOptionsMenu(menu);
 -        
 +
          if (mContainerActivity.getStorageManager() != null) {
              // Update the file
              setFile(mContainerActivity.getStorageManager().getFileById(getFile().getFileId()));
 -            
 +
              FileMenuFilter mf = new FileMenuFilter(
                  getFile(),
                  mContainerActivity.getStorageManager().getAccount(),
              );
              mf.filter(menu);
          }
 -        
 +
          // additional restriction for this fragment 
          // TODO allow renaming in PreviewImageFragment
          MenuItem item = menu.findItem(R.id.action_rename_file);
              item.setVisible(false);
              item.setEnabled(false);
          }
 -        
 +
          // additional restriction for this fragment 
          // TODO allow refresh file in PreviewImageFragment
          item = menu.findItem(R.id.action_sync_file);
              item.setVisible(false);
              item.setEnabled(false);
          }
 -        
 +
 +        // additional restriction for this fragment
 +        item = menu.findItem(R.id.action_copy);
 +        if (item != null) {
 +            item.setVisible(false);
 +            item.setEnabled(false);
 +        }
 +
      }
  
 -    
 -    
 +
      /**
       * {@inheritDoc}
       */
                  return true;
              }
              case R.id.action_send_file: {
-                 mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
-                 return true;
+                 if (getFile().isImage() && !getFile().isDown()){
+                     mContainerActivity.getFileOperationsHelper().sendCachedImage(getFile());
+                     return true;
+                 } else {
+                     mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
+                     return true;
+                 }
              }
              case R.id.action_sync_file: {
                  mContainerActivity.getFileOperationsHelper().syncFile(getFile());
                  return true;
              }
 -            
 +            case R.id.action_favorite_file:{
 +                mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), true);
 +                return true;
 +            }
 +            case R.id.action_unfavorite_file:{
 +                mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false);
 +                return true;
 +            }
              default:
                  return false;
          }
      }
 -    
 +
  
      private void seeDetails() {
 -        mContainerActivity.showDetails(getFile());        
 +        mContainerActivity.showDetails(getFile());
      }
  
  
          super.onDestroy();
      }
  
 -    
 +
      /**
       * Opens the previewed image with an external application.
       */
          mContainerActivity.getFileOperationsHelper().openFile(getFile());
          finish();
      }
 +
      
 -    
 -    private class LoadBitmapTask extends AsyncTask<String, Void, Bitmap> {
 +    private class LoadBitmapTask extends AsyncTask<OCFile, Void, LoadImage> {
  
          /**
           * Weak reference to the target {@link ImageView} where the bitmap will be loaded into.
           */
          private final WeakReference<TextView> mMessageViewRef;
  
 -        
 +
          /**
           * Weak reference to the target {@link ProgressBar} shown while the load is in progress.
           * 
           */
          private final WeakReference<ProgressBar> mProgressWheelRef;
  
 -        
 +
          /**
 -         * Error message to show when a load fails 
 +         * Error message to show when a load fails
           */
          private int mErrorMessageId;
 -        
 -        
 +
 +
          /**
           * Constructor.
 -         * 
 -         * @param imageView     Target {@link ImageView} where the bitmap will be loaded into.
 +         *
 +         * @param imageView Target {@link ImageView} where the bitmap will be loaded into.
           */
          public LoadBitmapTask(ImageViewCustom imageView, TextView messageView,
                                ProgressBar progressWheel) {
              mMessageViewRef = new WeakReference<TextView>(messageView);
              mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
          }
 -        
 -        
 +
          @Override
 -        protected Bitmap doInBackground(String... params) {
 +        protected LoadImage doInBackground(OCFile... params) {
              Bitmap result = null;
              if (params.length != 1) return null;
 -            String storagePath = params[0];
 +            OCFile ocFile = params[0];
 +            String storagePath = ocFile.getStoragePath();
              try {
  
                  int maxDownScale = 3;   // could be a parameter passed to doInBackground(...)
                          result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth,
                                  minHeight);
  
 -                        if (isCancelled()) return result;
 +                        if (isCancelled()) return new LoadImage(result, ocFile);
  
                          if (result == null) {
                              mErrorMessageId = R.string.preview_image_error_unknown_format;
  
              } catch (NoSuchFieldError e) {
                  mErrorMessageId = R.string.common_error_unknown;
 -                Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " 
 -                                + storagePath, e);
 -                    
 +                Log_OC.e(TAG, "Error from access to unexisting field despite protection; file "
 +                        + storagePath, e);
 +
              } catch (Throwable t) {
                  mErrorMessageId = R.string.common_error_unknown;
                  Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t);
 -                
 +
              }
 -            
 -            return result;
 +
 +            return new LoadImage(result, ocFile);
          }
 -        
 +
          @Override
 -        protected void onCancelled(Bitmap result) {
 -            if (result != null) {
 -                result.recycle();
 +        protected void onCancelled(LoadImage result) {
 +            if (result != null && result.bitmap != null) {
 +                result.bitmap.recycle();
              }
          }
  
          @Override
 -        protected void onPostExecute(Bitmap result) {
 +        protected void onPostExecute(LoadImage result) {
              hideProgressWheel();
 -            if (result != null) {
 +            if (result.bitmap != null) {
                  showLoadedImage(result);
 -            } else {
 +            }
 +            else {
                  showErrorMessage();
              }
 -            if (result != null && mBitmap != result)  {
 +            if (result.bitmap != null && mBitmap != result.bitmap)  {
                  // unused bitmap, release it! (just in case)
 -                result.recycle();
 +                result.bitmap.recycle();
              }
          }
 -        
 +
          @SuppressLint("InlinedApi")
 -        private void showLoadedImage(Bitmap result) {
 +        private void showLoadedImage(LoadImage result) {
              final ImageViewCustom imageView = mImageViewRef.get();
 +            Bitmap bitmap = result.bitmap;
              if (imageView != null) {
 -                Log_OC.d(TAG, "Showing image with resolution " + result.getWidth() + "x" +
 -                        result.getHeight());
 -                imageView.setImageBitmap(result);
 +                Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" +
 +                        bitmap.getHeight());
 +
 +                if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")){
 +                    Drawable backrepeat = getResources().getDrawable(R.drawable.backrepeat);
 +                    imageView.setBackground(backrepeat);
 +                }
 +
 +                imageView.setImageBitmap(bitmap);
                  imageView.setVisibility(View.VISIBLE);
 -                mBitmap  = result;  // needs to be kept for recycling when not useful
 +                mBitmap  = bitmap;  // needs to be kept for recycling when not useful
              }
  
              final TextView messageView = mMessageViewRef.get();
                  messageView.setVisibility(View.GONE);
              } // else , silently finish, the fragment was destroyed
          }
 -        
 +
          private void showErrorMessage() {
              final ImageView imageView = mImageViewRef.get();
              if (imageView != null) {
                  messageView.setVisibility(View.VISIBLE);
              } // else , silently finish, the fragment was destroyed
          }
 -        
 +
          private void hideProgressWheel() {
              final ProgressBar progressWheel = mProgressWheelRef.get();
              if (progressWheel != null) {
                  progressWheel.setVisibility(View.GONE);
              }
          }
 -        
 +
      }
  
      /**
          return (file != null && file.isImage());
      }
  
 -    
 +
      /**
       * Finishes the preview
       */
          Activity container = getActivity();
          container.finish();
      }
 -    
 +
      public TouchImageViewCustom getImageView() {
          return mImageView;
      }
  
 +    private class LoadImage {
 +        private Bitmap bitmap;
 +        private OCFile ocFile;
 +
 +        public LoadImage(Bitmap bitmap, OCFile ocFile){
 +            this.bitmap = bitmap;
 +            this.ocFile = ocFile;
 +        }
 +
 +    }
 +
  }