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

1  2 
res/layout/list_fragment.xml
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

          <com.owncloud.android.ui.ExtendedListView
              android:id="@+id/list_root"
              android:layout_width="match_parent"
 -            android:layout_height="match_parent" />
 -            
 +            android:layout_height="match_parent"
 +            android:columnWidth="100dp"
 +            android:gravity="center"
 +            android:horizontalSpacing="2dp"
 +            android:numColumns="auto_fit"
 +            android:stretchMode="columnWidth"
 +            android:verticalSpacing="2dp"
 +            android:visibility="visible" />
 +
      </android.support.v4.widget.SwipeRefreshLayout>
-     <android.support.v4.widget.SwipeRefreshLayout
+       
+       <android.support.v4.widget.SwipeRefreshLayout
          android:id="@+id/swipe_refresh_files_emptyView"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
@@@ -196,76 -171,28 +171,47 @@@ public class ThumbnailsCacheManager 
                      mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                              getClientFor(ocAccount, MainApp.getAppContext());
                  }
-                 
                  mFile = params[0];
 +                final String imageKey = String.valueOf(mFile.getRemoteId());
 +    
 +                // Check disk cache in background thread
 +                thumbnail = getBitmapFromDiskCache(imageKey);
 +    
 +                // Not found in disk cache
 +                if (thumbnail == null || mFile.needsUpdateThumbnail()) { 
 +                    // Use Width of imageView -> no blurry images on big screens
 +                    int px = mImageViewReference.get().getWidth();
 +                    
 +                    if (mFile.isDown()){
 +                        Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
 +                                mFile.getStoragePath(), px, px);
 +                        
 +                        if (bitmap != null) {
 +                            thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
 +    
 +                            // Add thumbnail to cache
 +                            addBitmapToCache(imageKey, thumbnail);
  
-                             mFile.setNeedsUpdateThumbnail(false);
-                             mStorageManager.saveFile(mFile);
-                         }
-     
-                     } else {
-                         // Download thumbnail from server
-                         if (mClient != null && mServerVersion != null) {
-                             OwnCloudVersion serverOCVersion = new OwnCloudVersion(mServerVersion);
-                             if (serverOCVersion.compareTo(new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) {
-                                 try {
-                                     int status = -1;
-                                     String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + 
-                                             px + "/" + px + Uri.encode(mFile.getRemotePath(), "/");
-                                     Log_OC.d("Thumbnail", "URI: " + uri);
-                                     GetMethod get = new GetMethod(uri);
-                                     status = mClient.executeMethod(get);
-                                     if (status == HttpStatus.SC_OK) {
-                                         byte[] bytes = get.getResponseBody();
-                                         Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
-                                         thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
-                                         // Add thumbnail to cache
-                                         if (thumbnail != null) {
-                                             addBitmapToCache(imageKey, thumbnail);
-                                         }
-                                     }
-                                 } catch (Exception e) {
-                                     e.printStackTrace();
-                                 }
-                             } else {
-                                 Log_OC.d(TAG, "Server too old");
-                             }
-                         }
-                     }
+                 if (mFile instanceof OCFile) {
+                     thumbnail = doOCFileInBackground();
+                 }  else if (mFile instanceof File) {
+                     thumbnail = doFileInBackground();
+                 } else {
+                     // do nothing
                  }
-                 
-             } catch (Throwable t) {
-                 // the app should never break due to a problem with thumbnails
-                 Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
-                 if (t instanceof OutOfMemoryError) {
-                     System.gc();
+                 }catch(Throwable t){
+                     // the app should never break due to a problem with thumbnails
+                     Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
+                     if (t instanceof OutOfMemoryError) {
+                         System.gc();
+                     }
                  }
-             }
-             
              return thumbnail;
          }
-         
          protected void onPostExecute(Bitmap bitmap){
              if (isCancelled()) {
                  bitmap = null;
@@@ -71,18 -65,12 +69,18 @@@ public class FileListListAdapter extend
      private Context mContext;\r
      private OCFile mFile = null;\r
      private Vector<OCFile> mFiles = null;\r
 +    private Vector<OCFile> mFilesOrig = new Vector<OCFile>();\r
      private boolean mJustFolders;\r
  \r
-     private FileDataStorageManager mStorageManager;
-     private Account mAccount;
+     private FileDataStorageManager mStorageManager;\r
+     private Account mAccount;\r
      private ComponentsGetter mTransferServiceGetter;\r
 -    \r
 +    private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM };\r
 +    private Integer mSortOrder;\r
 +    public static final Integer SORT_NAME = 0;\r
 +    public static final Integer SORT_DATE = 1;\r
 +    public static final Integer SORT_SIZE = 2;\r
 +    private Boolean mSortAscending;\r
      private SharedPreferences mAppPreferences;\r
      \r
      public FileListListAdapter(\r
@@@ -94,7 -82,8 +92,7 @@@
          mJustFolders = justFolders;\r
          mContext = context;\r
          mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
-         mTransferServiceGetter = transferServiceGetter;
 -\r
+         mTransferServiceGetter = transferServiceGetter;\r
          \r
          mAppPreferences = PreferenceManager\r
                  .getDefaultSharedPreferences(mContext);\r
          \r
          // initialise thumbnails cache on background thread\r
          new ThumbnailsCacheManager.InitDiskCacheTask().execute();\r
 -\r
      }\r
-     
+     \r
      @Override\r
      public boolean areAllItemsEnabled() {\r
          return true;\r
                              if (thumbnail == null) {\r
                                  thumbnail = ThumbnailsCacheManager.mDefaultImg;\r
                              }\r
-                             final AsyncDrawable asyncDrawable = new AsyncDrawable(\r
-                                     mContext.getResources(),\r
-                                     thumbnail,\r
+                             final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =\r
+                                     new ThumbnailsCacheManager.AsyncDrawable(\r
+                                     mContext.getResources(), \r
+                                     thumbnail, \r
                                      task\r
 -                            );\r
 +                                    );\r
                              fileIcon.setImageDrawable(asyncDrawable);\r
                              task.execute(file);\r
 +\r
                          }\r
                      }\r
+                 } else {\r
+                     fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName()));\r
                  }\r
 -\r
 -                if (checkIfFileIsSharedWithMe(file)) {\r
 -                    sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                else {\r
 +                    fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
                  }\r
 -            } \r
 -            else {\r
 -                  // TODO Re-enable when server supports folder-size calculation\r
 -//                if (FileStorageUtils.getDefaultSavePathFor(mAccount.name, file) != null){\r
 -//                    fileSizeV.setVisibility(View.VISIBLE);\r
 -//                    fileSizeV.setText(getFolderSizeHuman(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file)));\r
 -//                } else {\r
 -                    fileSizeV.setVisibility(View.INVISIBLE);\r
 -//                }\r
 -\r
 -                lastModV.setVisibility(View.VISIBLE);\r
 -                lastModV.setText(showRelativeTimestamp(file));\r
 -                checkBoxV.setVisibility(View.GONE);\r
 -                view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
 -\r
 +            } else {\r
 +                // Folder\r
                  if (checkIfFileIsSharedWithMe(file)) {\r
                      fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
 -                    sharedWithMeIconV.setVisibility(View.VISIBLE);\r
 +                } else if (file.isShareByLink()) {\r
 +                    // If folder is sharedByLink, icon folder must be changed to\r
 +                    // folder-public one\r
 +                    fileIcon.setImageResource(R.drawable.folder_public);\r
                  } else {\r
-                     fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
+                     fileIcon.setImageResource(\r
+                             DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName())\r
+                     );\r
                  }\r
 -\r
 -                // If folder is sharedByLink, icon folder must be changed to\r
 -                // folder-public one\r
 -                if (file.isShareByLink()) {\r
 -                    fileIcon.setImageResource(R.drawable.folder_public);\r
 -                }\r
 -            }\r
 -\r
 -            if (file.isShareByLink()) {\r
 -                sharedIconV.setVisibility(View.VISIBLE);\r
 -            } else {\r
 -                sharedIconV.setVisibility(View.GONE);\r
 -            }\r
 +            }           \r
          }\r
  \r
          return view;\r
                  && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
      }\r
  \r
-                     return val * obj1.compareTo(getFolderSize(\r
-                             new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));\r
 +    /**\r
 +     * Sorts list by Date\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortByDate(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +        \r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    Long obj1 = o1.getModificationTimestamp();\r
 +                    return val * obj1.compareTo(o2.getModificationTimestamp());\r
 +                }\r
 +                else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                } else if (o1.getModificationTimestamp() == 0 || o2.getModificationTimestamp() == 0){\r
 +                    return 0;\r
 +                } else {\r
 +                    Long obj1 = o1.getModificationTimestamp();\r
 +                    return val * obj1.compareTo(o2.getModificationTimestamp());\r
 +                }\r
 +            }\r
 +        });\r
 +    }\r
 +\r
 +    /**\r
 +     * Sorts list by Size\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortBySize(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +        \r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    Long obj1 = getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1)));\r
++                    return val * obj1.compareTo(getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));\r
 +                }\r
 +                else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                } else if (o1.getFileLength() == 0 || o2.getFileLength() == 0){\r
 +                    return 0;\r
 +                } else {\r
 +                    Long obj1 = o1.getFileLength();\r
 +                    return val * obj1.compareTo(o2.getFileLength());\r
 +                }\r
 +            }\r
 +        });\r
 +    }\r
 +\r
 +    /**\r
 +     * Sorts list by Name\r
 +     * @param sortAscending true: ascending, false: descending\r
 +     */\r
 +    private void sortByName(boolean sortAscending){\r
 +        final Integer val;\r
 +        if (sortAscending){\r
 +            val = 1;\r
 +        } else {\r
 +            val = -1;\r
 +        }\r
 +\r
 +        Collections.sort(mFiles, new Comparator<OCFile>() {\r
 +            public int compare(OCFile o1, OCFile o2) {\r
 +                if (o1.isFolder() && o2.isFolder()) {\r
 +                    return val * o1.getRemotePath().toLowerCase().compareTo(o2.getRemotePath().toLowerCase());\r
 +                } else if (o1.isFolder()) {\r
 +                    return -1;\r
 +                } else if (o2.isFolder()) {\r
 +                    return 1;\r
 +                }\r
 +                return val * new AlphanumComparator().compare(o1, o2);\r
 +            }\r
 +        });\r
 +    }\r
 +\r
      public void setSortOrder(Integer order, boolean ascending) {\r
          SharedPreferences.Editor editor = mAppPreferences.edit();\r
          editor.putInt("sortOrder", order);\r
          editor.putBoolean("sortAscending", ascending);\r
          editor.commit();\r
          \r
-         mSortOrder = order;\r
-         mSortAscending = ascending;\r
+         FileStorageUtils.mSortOrder = order;\r
+         FileStorageUtils.mSortAscending = ascending;\r
          \r
-     }
\r
+         mFiles = FileStorageUtils.sortFolder(mFiles);\r
+         notifyDataSetChanged();\r
\r
+     }    \r
 +        sortDirectory();\r
++    }\r
      \r
      private CharSequence showRelativeTimestamp(OCFile file){\r
          return DisplayUtils.getRelativeDateTimeString(mContext, file.getModificationTimestamp(),\r
@@@ -124,9 -129,40 +128,40 @@@ public class LocalFileListAdapter exten
                      }
                      checkBoxV.setVisibility(View.VISIBLE);
                  }
+                 
+              // get Thumbnail if file is image
+                 if (BitmapUtils.isImage(file)){
+                 // Thumbnail in Cache?
+                     Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                             String.valueOf(file.hashCode())
+                     );
+                     if (thumbnail != null){
+                         fileIcon.setImageBitmap(thumbnail);
+                     } else {
+                         // generate new Thumbnail
+                         if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
+                             final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+                                     new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon);
+                             if (thumbnail == null) {
+                                 thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                             }
+                             final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+                                       new ThumbnailsCacheManager.AsyncDrawable(
+                                     mContext.getResources(), 
+                                     thumbnail, 
+                                     task
+                                       );
+                             fileIcon.setImageDrawable(asyncDrawable);
+                             task.execute(file);
+                         }
+                     }
+                 } else {
+                     fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(null, file.getName()));
+                 }  
  
              } else {
 -                fileSizeV.setVisibility(View.GONE);
 +                //fileSizeV.setVisibility(View.GONE);
                  lastModV.setVisibility(View.GONE);
                  checkBoxV.setVisibility(View.GONE);
              }
@@@ -67,36 -66,32 +67,42 @@@ implements OnItemClickListener, OnEnfor
  
      private OnEnforceableRefreshListener mOnRefreshListener = null;
      
 -    
 +    protected GridView imageView;
 +       
      public void setListAdapter(ListAdapter listAdapter) {
 -        mList.setAdapter(listAdapter);
 -        mList.invalidate();
 +        imageView.setAdapter(listAdapter);
 +        imageView.invalidate();
      }
  
 -    public ListView getListView() {
 -        return mList;
 -    }
 +    public GridView getGridView() {
 +        return imageView;
 +    }
+     public void setFooterView(View footer) {
+         mList.addFooterView(footer, null, false);
+         mList.invalidate();
+     }
 +    
 +    protected void switchImageView(){
 +       imageView.setNumColumns(GridView.AUTO_FIT);
 +       imageView.invalidate();
 +    }
 +    
 +    protected void switchFileView(){
 +       imageView.setNumColumns(1);
 +       imageView.invalidate();
 +    }
 +    
 +    
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          Log_OC.e(TAG, "onCreateView");
-         
          View v = inflater.inflate(R.layout.list_fragment, null);
 -        mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view);
 -        mList = (ExtendedListView) (v.findViewById(R.id.list_root));
 -        mList.setOnItemClickListener(this);
 -
 -        mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
 -        mList.setDividerHeight(1);
 +        
 +        imageView = (ExtendedListView)(v.findViewById(R.id.list_root));
 +        imageView.setOnItemClickListener(this);
  
          if (savedInstanceState != null) {
              int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION);
          savedInstanceState.putString(KEY_EMPTY_LIST_MESSAGE, getEmptyViewText());
      }
  
-     
      /**
-      * Calculates the position of the item that will be used as a reference to reposition the visible items 
-      * in the list when the device is turned to other position. 
+      * Calculates the position of the item that will be used as a reference to
+      * reposition the visible items in the list when the device is turned to
+      * other position.
       * 
-      * THe current policy is take as a reference the visible item in the center of the screen.  
+      * THe current policy is take as a reference the visible item in the center
+      * of the screen.
       * 
-      * @return      The position in the list of the visible item in the center of the screen.
+      * @return The position in the list of the visible item in the center of the
+      *         screen.
       */
      protected int getReferencePosition() {
 -        if (mList != null) {
 -            return (mList.getFirstVisiblePosition() + mList.getLastVisiblePosition()) / 2;
 +        if (imageView != null) {
 +            return (imageView.getFirstVisiblePosition() + imageView.getLastVisiblePosition()) / 2;
          } else {
              return 0;
          }
      /**
       * Sets the visible part of the list from the reference position.
       * 
-      * @param   position    Reference position previously 
-      * returned by {@link LocalFileListFragment#getReferencePosition()}
+      * @param position Reference position previously returned by
+      *            {@link LocalFileListFragment#getReferencePosition()}
       */
      protected void setReferencePosition(int position) {
 -        if (mList != null) {
 -            mList.setAndCenterSelection(position);
 +        if (imageView != null) {
 +            imageView.setSelection(position);
          }
      }
  
@@@ -98,26 -98,7 +98,21 @@@ public class LocalFileListFragment exte
          Log_OC.i(TAG, "onActivityCreated() stop");
      }
      
 +    public void selectAll(){
 +        int numberOfFiles = mAdapter.getCount();
 +        for(int i = 0; i < numberOfFiles; i++){
 +            File file = (File) mAdapter.getItem(i);
 +            if (file != null) {                
 +                if (!file.isDirectory()) {  
 +                    /// Click on a file
 +                    getGridView().setItemChecked(i, true);                       
 +                    // notify the change to the container Activity
 +                    mContainerActivity.onFileClick(file);
 +                }
 +            }
 +        }
 +    }
      
-     public void deselectAll(){        
-         mAdapter = new LocalFileListAdapter(mContainerActivity.getInitialDirectory(), getActivity());
-         setListAdapter(mAdapter);
-     }
-     
      /**
       * Checks the file clicked over. Browses inside if it is a directory. Notifies the container activity in any case.
       */
@@@ -124,13 -133,13 +133,13 @@@ public class OCFileListFragment extend
                  justFolders,
                  getSherlockActivity(), 
                  mContainerActivity
-         );
+                 );
          setListAdapter(mAdapter);
 -
 -        registerForContextMenu(getListView());
 -        getListView().setOnCreateContextMenuListener(this);
 -    }
 -
 +        
 +        registerForContextMenu(getGridView());
 +        getGridView().setOnCreateContextMenuListener(this);
 +  }
 +    
      /**
       * Saves the current listed folder.
       */
              }
              mFile = directory;
              
+             // Update Footer
+             TextView footerText = (TextView) mFooterView.findViewById(R.id.footerText);
+             Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
+             footerText.setText(generateFooterText(directory));
+             Log_OC.d("footer", String.valueOf(System.currentTimeMillis()));
++            
 +         // decide image vs. file view
 +            double countImages = 0;
 +            double countFiles = 0;
 +            
 +            Vector<OCFile> files = storageManager.getFolderContent(directory);
 +            for (OCFile file : files){
 +                if (!file.isFolder()){
 +                    countFiles++;
 +                    
 +                    if (file.isImage()){
 +                        countImages++;
 +                    }
 +                }
 +            }
 +            
 +            // > 50% Images --> image view
 +            // TODO threshold as constant in Preferences
 +            if ((countImages / countFiles) >= 0.5){
 +                Log_OC.i(TAG, "Image View");
 +                switchImageView();
 +            } else {
 +                Log_OC.i(TAG, "Folder View");
 +                switchFileView();
 +            }
          }
      }