Merge remote-tracking branch 'remotes/upstream/resizedImages' into beta
authortobiasKaminsky <tobias@kaminsky.me>
Sat, 31 Oct 2015 07:36:39 +0000 (08:36 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Sat, 31 Oct 2015 07:36:39 +0000 (08:36 +0100)
1  2 
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

@@@ -35,10 -35,8 +35,10 @@@ 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;
@@@ -81,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
              );
  
      
          return null;
      }
  
 +    /**
 +     * Sets max size of cache
 +     * @param maxSize in MB
 +     * @return
 +     */
 +    public static boolean setMaxSize(long maxSize){
 +        if (mThumbnailCache != null){
 +            mThumbnailCache.setMaxSize(maxSize * 1024 * 1024);
 +            return true;
 +        } else {
 +            return false;
 +        }
 +    }
 +
 +    public static long getMaxSize(){
 +        if (mThumbnailCache != null) {
 +            return mThumbnailCache.getMaxSize();
 +        } else {
 +            return -1l;
 +        }
 +    }
 +
      public static class ThumbnailGenerationTask extends AsyncTask<Object, Void, Bitmap> {
          private final WeakReference<ImageView> mImageViewReference;
          private WeakReference<ProgressBar> mProgressWheelRef;
          }
  
          protected void onPostExecute(Bitmap bitmap){
 -            if (isCancelled()) {
 -                bitmap = null;
 -            }
 -
              if (bitmap != null) {
                  final ImageView imageView = mImageViewReference.get();
                  final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
                  }
  
                  if (file.isDown()) {
 -                    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, pxW);
 +                        }
 +
 +                        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/" +
 -                                        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, pxW, pxH);
 -                                    byte[] bytes = get.getResponseBody();
 -
 -                                    if (mIsThumbnail) {
 +                                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 {
 -                                        thumbnail = bitmap;
 +                                        Log_OC.d(TAG, "Status: " + status);
 +                                    }
 +                                } else {
 +                                    String gallery = "";
 +                                    if (serverOCVersion.supportsNativeGallery()){
 +                                        gallery = "gallery";
 +                                    } else {
 +                                        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 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());
+             // distinguish between thumbnail and resized image
+             String temp = String.valueOf(file.hashCode());
+             if (mIsThumbnail){
+                 temp = "t" + temp;
+             } else {
+                 temp = "r" + temp;
+             }
+             final String imageKey = temp;
  
              // Check disk cache in background thread
-             thumbnail = getBitmapFromDiskCache(imageKey);
+             Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
  
              // Not found in disk cache
              if (thumbnail == null) {
              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;
@@@ -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
@@@ -25,16 -24,12 +25,16 @@@ package com.owncloud.android.ui.adapter
  \r
  \r
  import java.io.File;\r
 +import java.util.ArrayList;\r
 +import java.util.HashMap;\r
 +import java.util.Map;\r
  import java.util.Vector;\r
  \r
  import android.accounts.Account;\r
  import android.content.Context;\r
  import android.content.SharedPreferences;\r
  import android.graphics.Bitmap;\r
 +import android.graphics.Color;\r
  import android.os.Build;\r
  import android.preference.PreferenceManager;\r
  import android.text.format.DateUtils;\r
@@@ -59,7 -54,6 +59,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
@@@ -83,8 -77,6 +83,8 @@@ public class FileListListAdapter extend
      private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM };\r
  \r
      private SharedPreferences mAppPreferences;\r
 +\r
 +    private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();\r
      \r
      public FileListListAdapter(\r
              boolean justFolders, \r
          ViewType viewType;\r
          if (!mGridMode){\r
              viewType = ViewType.LIST_ITEM;\r
 -        } else if (file.isImage()){\r
 +        } else if (file.isImage() || file.isVideo()){\r
              viewType = ViewType.GRID_IMAGE;\r
          } else {\r
              viewType = ViewType.GRID_ITEM;\r
              switch (viewType){\r
                  case LIST_ITEM:\r
                      TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
 +                    TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);\r
                      TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
 -                    ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
 +\r
  \r
                      lastModV.setVisibility(View.VISIBLE);\r
                      lastModV.setText(showRelativeTimestamp(file));\r
  \r
 -                    checkBoxV.setVisibility(View.GONE);\r
  \r
 +                    fileSizeSeparatorV.setVisibility(View.VISIBLE);\r
                      fileSizeV.setVisibility(View.VISIBLE);\r
                      fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
  \r
 -                    if (!file.isFolder()) {\r
 -                        AbsListView parentList = (AbsListView)parent;\r
 -                        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {\r
 -                            if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {\r
 -                                checkBoxV.setVisibility(View.GONE);\r
 -                            } else {\r
 -                                if (parentList.isItemChecked(position)) {\r
 -                                    checkBoxV.setImageResource(\r
 -                                            android.R.drawable.checkbox_on_background);\r
 -                                } else {\r
 -                                    checkBoxV.setImageResource(\r
 -                                            android.R.drawable.checkbox_off_background);\r
 -                                }\r
 -                                checkBoxV.setVisibility(View.VISIBLE);\r
 -                            }\r
 -                        }\r
 -\r
 -                    } else { //Folder\r
 +//                    if (!file.isFolder()) {\r
 +//                        AbsListView parentList = (AbsListView)parent;\r
 +//                        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {\r
 +//                            if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {\r
 +//                                checkBoxV.setVisibility(View.GONE);\r
 +//                            } else {\r
 +//                                if (parentList.isItemChecked(position)) {\r
 +//                                    checkBoxV.setImageResource(\r
 +//                                            R.drawable.ic_checkbox_marked);\r
 +//                                } else {\r
 +//                                    checkBoxV.setImageResource(\r
 +//                                            R.drawable.ic_checkbox_blank_outline);\r
 +//                                }\r
 +//                                checkBoxV.setVisibility(View.VISIBLE);\r
 +//                            }\r
 +//                        }\r
 +\r
 +                    if (file.isFolder()) {\r
 +                        fileSizeSeparatorV.setVisibility(View.INVISIBLE);\r
                          fileSizeV.setVisibility(View.INVISIBLE);\r
                      }\r
  \r
                      }\r
  \r
                      // share with me icon\r
 -                    if (!file.isFolder()) {\r
 -                        ImageView sharedWithMeIconV = (ImageView)\r
 -                                view.findViewById(R.id.sharedWithMeIcon);\r
 -                        sharedWithMeIconV.bringToFront();\r
 -                        if (checkIfFileIsSharedWithMe(file)) {\r
 -                            sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 -                        } else {\r
 -                            sharedWithMeIconV.setVisibility(View.GONE);\r
 -                        }\r
 +                    ImageView sharedWithMeIconV = (ImageView)\r
 +                            view.findViewById(R.id.sharedWithMeIcon);\r
 +                    sharedWithMeIconV.bringToFront();\r
 +                    if (checkIfFileIsSharedWithMe(file) &&\r
 +                            (!file.isFolder() || !mGridMode)) {\r
 +                        sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                    } else {\r
 +                        sharedWithMeIconV.setVisibility(View.GONE);\r
                      }\r
  \r
                      break;\r
              }\r
 +\r
 +            ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
 +            checkBoxV.setVisibility(View.GONE);\r
 +\r
 +            AbsListView parentList = (AbsListView)parent;\r
 +            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {\r
 +                if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {\r
 +                    checkBoxV.setVisibility(View.GONE);\r
 +                } else if (parentList.getCheckedItemCount() > 0){\r
 +                    if (parentList.isItemChecked(position)) {\r
 +                        checkBoxV.setImageResource(\r
 +                                android.R.drawable.checkbox_on_background);\r
 +                    } else {\r
 +                        checkBoxV.setImageResource(\r
 +                                android.R.drawable.checkbox_off_background);\r
 +                    }\r
 +                    checkBoxV.setVisibility(View.VISIBLE);\r
 +                }\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
 +            if (!file.isFavorite()) {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);\r
              } else {\r
                  view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE);\r
                  if (file.isImage() && file.getRemoteId() != null){\r
                      // Thumbnail in Cache?\r
                      Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(\r
-                             String.valueOf(file.getRemoteId())\r
-                             );\r
+                             "t" + String.valueOf(file.getRemoteId()));\r
                      if (thumbnail != null && !file.needsUpdateThumbnail()){\r
                          fileIcon.setImageBitmap(thumbnail);\r
                      } else {\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
 +        if (mSelection.get(position) != null) {\r
 +            view.setBackgroundColor(Color.rgb(248, 248, 248));\r
 +        } else {\r
 +            view.setBackgroundColor(Color.WHITE);\r
 +        }\r
 +\r
          return view;\r
      }\r
  \r
       *                                  mStorageManager if is different (and not NULL)\r
       */\r
      public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager\r
 -            /*, boolean onlyOnDevice*/) {\r
 +            , boolean onlyOnDevice) {\r
          mFile = directory;\r
          if (updatedStorageManager != null && updatedStorageManager != mStorageManager) {\r
              mStorageManager = updatedStorageManager;\r
              mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
          }\r
          if (mStorageManager != null) {\r
 -            // TODO Enable when "On Device" is recovered ?\r
 -            mFiles = mStorageManager.getFolderContent(mFile/*, onlyOnDevice*/);\r
 +            mFiles = mStorageManager.getFolderContent(mFile, onlyOnDevice);\r
              mFilesOrig.clear();\r
              mFilesOrig.addAll(mFiles);\r
              \r
              mFiles = null;\r
          }\r
  \r
 -        mFiles = FileStorageUtils.sortFolder(mFiles);\r
 +        mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
          notifyDataSetChanged();\r
      }\r
      \r
          FileStorageUtils.mSortAscending = ascending;\r
          \r
  \r
 -        mFiles = FileStorageUtils.sortFolder(mFiles);\r
 +        mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
          notifyDataSetChanged();\r
  \r
      }\r
      public void setGridMode(boolean gridMode) {\r
          mGridMode = gridMode;\r
      }\r
 +\r
 +    public boolean isGridMode() {\r
 +        return mGridMode;\r
 +    }\r
 +\r
 +    public void setNewSelection(int position, boolean checked) {\r
 +        mSelection.put(position, checked);\r
 +        notifyDataSetChanged();\r
 +    }\r
 +\r
 +    public void removeSelection(int position) {\r
 +        mSelection.remove(position);\r
 +        notifyDataSetChanged();\r
 +    }\r
 +\r
 +    public void removeSelection(){\r
 +         mSelection.clear();\r
 +        notifyDataSetChanged();\r
 +    }\r
 +\r
 +    public ArrayList<Integer> getCheckedItemPositions() {\r
 +        ArrayList<Integer> ids = new ArrayList<Integer>();\r
 +\r
 +        for (Map.Entry<Integer, Boolean> entry : mSelection.entrySet()){\r
 +            if (entry.getValue()){\r
 +                ids.add(entry.getKey());\r
 +            }\r
 +        }\r
 +        return ids;\r
 +    }\r
 +\r
 +    public ArrayList<OCFile> getCheckedItems() {\r
 +        ArrayList<OCFile> files = new ArrayList<OCFile>();\r
 +\r
 +        for (Map.Entry<Integer, Boolean> entry : mSelection.entrySet()){\r
 +            if (entry.getValue()){\r
 +                files.add((OCFile) getItem(entry.getKey()));\r
 +            }\r
 +        }\r
 +        return files;\r
 +    }\r
  }\r