From: tobiasKaminsky Date: Wed, 5 Nov 2014 21:07:11 +0000 (+0100) Subject: Merge remote-tracking branch 'upstream/develop' into imageGrid X-Git-Tag: oc-android-1.7.0_signed~16^2~28 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/f331120a147b95e7a27fb765de2e210d4af892ca?ds=inline;hp=-c Merge remote-tracking branch 'upstream/develop' into imageGrid Conflicts: owncloud-android-library res/layout/list_item.xml src/com/owncloud/android/ui/adapter/FileListListAdapter.java src/com/owncloud/android/ui/fragment/LocalFileListFragment.java --- f331120a147b95e7a27fb765de2e210d4af892ca diff --combined owncloud-android-library index 00000000,4f315c7e..5bd0d738 mode 000000,160000..160000 --- a/owncloud-android-library +++ b/owncloud-android-library @@@ -1,0 -1,1 +1,1 @@@ -Subproject commit 4f315c7e06f6eef48df246be0ee9252fdfccdf00 ++Subproject commit 5bd0d7387712ce3f53869294761ac4d8537841cd diff --combined res/layout/list_item.xml index 2d7ab87b,c6c7b92f..78c36cef --- a/res/layout/list_item.xml +++ b/res/layout/list_item.xml @@@ -31,23 -31,23 +31,23 @@@ android:focusableInTouchMode="false"> + android:src="@drawable/shared_with_me" + android:visibility="invisible" /> diff --combined src/com/owncloud/android/MainApp.java index 08efe342,c2a4c68b..4fdc5cb8 --- a/src/com/owncloud/android/MainApp.java +++ b/src/com/owncloud/android/MainApp.java @@@ -16,11 -16,13 +16,33 @@@ */ package com.owncloud.android; - import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; - import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; + import android.app.Application; + import android.content.Context; + ++import com.owncloud.android.authentication.AccountUtils; ++import com.owncloud.android.datamodel.ThumbnailsCacheManager; ++import android.app.Application; ++import android.content.Context; ++ ++import com.owncloud.android.authentication.AccountUtils; ++import com.owncloud.android.datamodel.ThumbnailsCacheManager; ++import android.app.Application; ++import android.content.Context; + ++import com.owncloud.android.authentication.AccountUtils; ++import com.owncloud.android.datamodel.ThumbnailsCacheManager; +import android.app.Application; +import android.content.Context; ++ ++import com.owncloud.android.datamodel.ThumbnailsCacheManager; ++import android.app.Application; ++import android.content.Context; ++ ++import com.owncloud.android.authentication.AccountUtils; + import com.owncloud.android.datamodel.ThumbnailsCacheManager; + import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; + import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; + import com.owncloud.android.lib.common.utils.Log_OC; /** * Main Application of the project * @@@ -53,7 -55,20 +75,20 @@@ public class MainApp extends Applicatio } else { OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT); } + + // initialise thumbnails cache on background thread - new ThumbnailsCacheManager.InitDiskCacheTask().execute(); ++ new ThumbnailsCacheManager.InitDiskCacheTask(mContext).execute(); + if (BuildConfig.DEBUG) { + + String dataFolder = getDataFolder(); + + // Set folder for store logs + Log_OC.setLogDataFolder(dataFolder); + + Log_OC.startLogging(); + Log_OC.d("Debug", "start logging"); + } } public static Context getAppContext() { @@@ -66,7 -81,7 +101,7 @@@ public static String getAccountType() { return getAppContext().getResources().getString(R.string.account_type); } - + // From AccountAuthenticator // public static final String AUTHORITY = "org.owncloud"; public static String getAuthority() { diff --combined src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 00d045a6,e002efb7..d2680fa5 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@@ -17,18 -17,22 +17,29 @@@ */ package com.owncloud.android.ui.adapter; + + import java.io.File; + import java.util.Collections; + import java.util.Comparator; import java.util.Vector; + import third_parties.daveKoeller.AlphanumComparator; import android.accounts.Account; import android.content.Context; ++<<<<<<< HEAD +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.ThumbnailUtils; ++======= + import android.content.SharedPreferences; + import android.graphics.Bitmap; + import android.preference.PreferenceManager; ++>>>>>>> upstream/develop import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; +import android.widget.GridView; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; @@@ -38,23 -42,26 +49,31 @@@ import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; + import com.owncloud.android.datamodel.ThumbnailsCacheManager; + import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.ui.activity.ComponentsGetter; import com.owncloud.android.utils.DisplayUtils; ++<<<<<<< HEAD +import com.owncloud.android.utils.Log_OC; + ++======= + import com.owncloud.android.utils.FileStorageUtils; + ++>>>>>>> upstream/develop /** * This Adapter populates a ListView with all files and folders in an ownCloud * instance. * * @author Bartek Przybylski - * + * @author Tobias Kaminsky + * @author David A. Velasco */ - public class FileListListAdapter extends BaseAdapter implements ListAdapter { + public class FileListListAdapter extends BaseAdapter implements ListAdapter { private final static String PERMISSION_SHARED_WITH_ME = "S"; - + private Context mContext; private OCFile mFile = null; private Vector mFiles = null; @@@ -63,19 -70,38 +82,42 @@@ private FileDataStorageManager mStorageManager; private Account mAccount; private ComponentsGetter mTransferServiceGetter; ++<<<<<<< HEAD + private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM }; ++======= + private Integer mSortOrder; + public static final Integer SORT_NAME = 0; + public static final Integer SORT_DATE = 1; + public static final Integer SORT_SIZE = 2; + private Boolean mSortAscending; + private SharedPreferences mAppPreferences; ++>>>>>>> upstream/develop public FileListListAdapter( boolean justFolders, Context context, ComponentsGetter transferServiceGetter ) { + mJustFolders = justFolders; mContext = context; mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); - mTransferServiceGetter = transferServiceGetter; - } + + mTransferServiceGetter = transferServiceGetter; + + mAppPreferences = PreferenceManager + .getDefaultSharedPreferences(mContext); + + // Read sorting order, default to sort by name ascending + mSortOrder = mAppPreferences + .getInt("sortOrder", 0); + mSortAscending = mAppPreferences.getBoolean("sortAscending", true); + + // initialise thumbnails cache on background thread + new ThumbnailsCacheManager.InitDiskCacheTask().execute(); + } + @Override public boolean areAllItemsEnabled() { return true; @@@ -112,177 -138,193 +154,325 @@@ @Override public View getView(int position, View convertView, ViewGroup parent) { + // decide image vs. file view + double count = 0; + + + for (OCFile file : mFiles){ + if (file.isImage()){ + count++; + } + } + + // TODO threshold as constant in Preferences + // > 50% Images --> image view + boolean fileView = true; + if ((count / mFiles.size()) >= 0.5){ + fileView = false; + } else { + fileView = true; + } + View view = convertView; - if (view == null) { - LayoutInflater inflator = (LayoutInflater) mContext - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + OCFile file = null; + LayoutInflater inflator = (LayoutInflater) mContext + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + if (mFiles != null && mFiles.size() > position) { + file = mFiles.get(position); + } + + // Find out which layout should be displayed + ViewType viewType; + if (fileView){ + viewType = ViewType.LIST_ITEM; + } else if (file.isImage()){ + viewType = ViewType.GRID_IMAGE; + } else { + viewType = ViewType.GRID_ITEM; + } + + // Create View + switch (viewType){ + case GRID_IMAGE: + view = inflator.inflate(R.layout.grid_image, null); + break; + case GRID_ITEM: + view = inflator.inflate(R.layout.grid_item, null); + break; + case LIST_ITEM: view = inflator.inflate(R.layout.list_item, null); + break; } ++<<<<<<< HEAD + + view.invalidate(); + + if (file != null){ + + ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail); + TextView fileName; + String name; ++======= + + if (mFiles != null && mFiles.size() > position) { + OCFile file = mFiles.get(position); + TextView fileName = (TextView) view.findViewById(R.id.Filename); + String name = file.getFileName(); + + fileName.setText(name); + ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1); + fileIcon.setTag(file.getFileId()); + ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); + ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon); + sharedWithMeIconV.setVisibility(View.GONE); + + ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2); + localStateView.bringToFront(); + FileDownloaderBinder downloaderBinder = + mTransferServiceGetter.getFileDownloaderBinder(); + FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); + if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) { + localStateView.setImageResource(R.drawable.downloading_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) { + localStateView.setImageResource(R.drawable.uploading_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else if (file.isDown()) { + localStateView.setImageResource(R.drawable.local_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else { + localStateView.setVisibility(View.INVISIBLE); + } + + TextView fileSizeV = (TextView) view.findViewById(R.id.file_size); + TextView lastModV = (TextView) view.findViewById(R.id.last_mod); + ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox); ++>>>>>>> upstream/develop - if (!file.isFolder()) { + switch (viewType){ + case LIST_ITEM: + fileName = (TextView) view.findViewById(R.id.Filename); + name = file.getFileName(); + fileName.setText(name); + + TextView fileSizeV = (TextView) view.findViewById(R.id.file_size); + TextView lastModV = (TextView) view.findViewById(R.id.last_mod); + ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox); + + lastModV.setVisibility(View.VISIBLE); ++<<<<<<< HEAD + lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())); + + checkBoxV.setVisibility(View.GONE); + fileSizeV.setVisibility(View.VISIBLE); fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); - lastModV.setVisibility(View.VISIBLE); + + ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); + + + if (file.isShareByLink()) { + sharedIconV.setVisibility(View.VISIBLE); ++======= + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); + // this if-else is needed even thoe fav icon is visible by default + // because android reuses views in listview + if (!file.keepInSync()) { + view.findViewById(R.id.imageView3).setVisibility(View.GONE); ++>>>>>>> upstream/develop } else { - view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE); + sharedIconV.setVisibility(View.GONE); } - ListView parentList = (ListView)parent; - if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { - checkBoxV.setVisibility(View.GONE); - } else { - if (parentList.isItemChecked(position)) { - checkBoxV.setImageResource(android.R.drawable.checkbox_on_background); + ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator); + + if (!file.isFolder()) { + GridView parentList = (GridView)parent; + if (parentList.getChoiceMode() == GridView.CHOICE_MODE_NONE) { + checkBoxV.setVisibility(View.GONE); + } else { + if (parentList.isItemChecked(position)) { + checkBoxV.setImageResource(android.R.drawable.checkbox_on_background); + } else { + checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); + } + checkBoxV.setVisibility(View.VISIBLE); + } ++<<<<<<< HEAD + + localStateView.bringToFront(); + FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder(); + FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); + if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) { + localStateView.setImageResource(R.drawable.downloading_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) { + localStateView.setImageResource(R.drawable.uploading_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else if (file.isDown()) { + localStateView.setImageResource(R.drawable.local_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else { + localStateView.setVisibility(View.INVISIBLE); + } + + ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon); + if (checkIfFileIsSharedWithMe(file)) { + sharedWithMeIconV.setVisibility(View.VISIBLE); } else { - checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); + sharedWithMeIconV.setVisibility(View.GONE); } + } else { + localStateView.setVisibility(View.INVISIBLE); + } + break; + case GRID_ITEM: + fileName = (TextView) view.findViewById(R.id.Filename); + name = file.getFileName(); + fileName.setText(name); + break; + case GRID_IMAGE: + break; + } + + // For all Views + + // this if-else is needed even though favorite icon is visible by default + // because android reuses views in listview + if (!file.keepInSync()) { + view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE); + } else { + view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE); + } + + // No Folder + if (!file.isFolder()) { + if (file.isImage() && file.isDown()){ + Bitmap bitmap = BitmapFactory.decodeFile(file.getStoragePath()); + fileIcon.setImageBitmap(ThumbnailUtils.extractThumbnail(bitmap, 200, 200)); + } else { + fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); + } + } else { + // Folder ++======= + checkBoxV.setVisibility(View.VISIBLE); + } + + // get Thumbnail if file is image + if (file.isImage() && file.getRemoteId() != null){ + // Thumbnail in Cache? + Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( + String.valueOf(file.getRemoteId()) + ); + if (thumbnail != null && !file.needsUpdateThumbnail()){ + fileIcon.setImageBitmap(thumbnail); + } else { + // generate new Thumbnail + if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) { + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask( + fileIcon, mStorageManager, mAccount + ); + if (thumbnail == null) { + thumbnail = ThumbnailsCacheManager.mDefaultImg; + } + final AsyncDrawable asyncDrawable = new AsyncDrawable( + mContext.getResources(), + thumbnail, + task + ); + fileIcon.setImageDrawable(asyncDrawable); + task.execute(file); + } + } + } else { + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); + } + + if (checkIfFileIsSharedWithMe(file)) { + sharedWithMeIconV.setVisibility(View.VISIBLE); + } + } + else { + // TODO Re-enable when server supports folder-size calculation + // if (FileStorageUtils.getDefaultSavePathFor(mAccount.name, file) != null){ + // fileSizeV.setVisibility(View.VISIBLE); + // fileSizeV.setText(getFolderSizeHuman(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file))); + // } else { + fileSizeV.setVisibility(View.INVISIBLE); + // } + + lastModV.setVisibility(View.VISIBLE); + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); + checkBoxV.setVisibility(View.GONE); + view.findViewById(R.id.imageView3).setVisibility(View.GONE); + ++>>>>>>> upstream/develop if (checkIfFileIsSharedWithMe(file)) { fileIcon.setImageResource(R.drawable.shared_with_me_folder); - sharedWithMeIconV.setVisibility(View.VISIBLE); + } else if (file.isShareByLink()) { + // If folder is sharedByLink, icon folder must be changed to + // folder-public one + fileIcon.setImageResource(R.drawable.folder_public); } else { - fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); } - - // If folder is sharedByLink, icon folder must be changed to - // folder-public one - if (file.isShareByLink()) { - fileIcon.setImageResource(R.drawable.folder_public); - } - } - - if (file.isShareByLink()) { - sharedIconV.setVisibility(View.VISIBLE); - } else { - sharedIconV.setVisibility(View.GONE); - } + } } return view; } + + /** + * Local Folder size in human readable format + * + * @param path + * String + * @return Size in human readable format + */ + private String getFolderSizeHuman(String path) { + + File dir = new File(path); + + if (dir.exists()) { + long bytes = getFolderSize(dir); + return DisplayUtils.bytesToHumanReadable(bytes); + } + return "0 B"; + } + + /** + * Local Folder size + * @param dir File + * @return Size in bytes + */ + private long getFolderSize(File dir) { + if (dir.exists()) { + long result = 0; + File[] fileList = dir.listFiles(); + for(int i = 0; i < fileList.length; i++) { + if(fileList[i].isDirectory()) { + result += getFolderSize(fileList[i]); + } else { + result += fileList[i].length(); + } + } + return result; + } + return 0; + } + @Override public int getViewTypeCount() { return 1; @@@ -300,8 -342,10 +490,10 @@@ /** * Change the adapted directory for a new one - * @param directory New file to adapt. Can be NULL, meaning "no content to adapt". - * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL) + * @param directory New file to adapt. Can be NULL, meaning + * "no content to adapt". + * @param updatedStorageManager Optional updated storage manager; used to replace + * mStorageManager if is different (and not NULL) */ public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) { mFile = directory; @@@ -317,6 -361,26 +509,26 @@@ } else { mFiles = null; } + + sortDirectory(); + } + + /** + * Sorts all filenames, regarding last user decision + */ + private void sortDirectory(){ + switch (mSortOrder){ + case 0: + sortByName(mSortAscending); + break; + case 1: + sortByDate(mSortAscending); + break; + case 2: + sortBySize(mSortAscending); + break; + } + notifyDataSetChanged(); } @@@ -347,7 -411,111 +559,111 @@@ * @return boolean: True if it is shared with me and false if it is not */ private boolean checkIfFileIsSharedWithMe(OCFile file) { - return (mFile.getPermissions() != null && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) - && file.getPermissions() != null && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); + return (mFile.getPermissions() != null + && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) + && file.getPermissions() != null + && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); + } + + /** + * Sorts list by Date + * @param sortAscending true: ascending, false: descending + */ + private void sortByDate(boolean sortAscending){ + final Integer val; + if (sortAscending){ + val = 1; + } else { + val = -1; + } + + Collections.sort(mFiles, new Comparator() { + public int compare(OCFile o1, OCFile o2) { + if (o1.isFolder() && o2.isFolder()) { + Long obj1 = o1.getModificationTimestamp(); + return val * obj1.compareTo(o2.getModificationTimestamp()); + } + else if (o1.isFolder()) { + return -1; + } else if (o2.isFolder()) { + return 1; + } else if (o1.getModificationTimestamp() == 0 || o2.getModificationTimestamp() == 0){ + return 0; + } else { + Long obj1 = o1.getModificationTimestamp(); + return val * obj1.compareTo(o2.getModificationTimestamp()); + } + } + }); } + + /** + * Sorts list by Size + * @param sortAscending true: ascending, false: descending + */ + private void sortBySize(boolean sortAscending){ + final Integer val; + if (sortAscending){ + val = 1; + } else { + val = -1; + } + + Collections.sort(mFiles, new Comparator() { + public int compare(OCFile o1, OCFile o2) { + if (o1.isFolder() && o2.isFolder()) { + Long obj1 = getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1))); + return val * obj1.compareTo(getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2)))); + } + else if (o1.isFolder()) { + return -1; + } else if (o2.isFolder()) { + return 1; + } else if (o1.getFileLength() == 0 || o2.getFileLength() == 0){ + return 0; + } else { + Long obj1 = o1.getFileLength(); + return val * obj1.compareTo(o2.getFileLength()); + } + } + }); + } + + /** + * Sorts list by Name + * @param sortAscending true: ascending, false: descending + */ + private void sortByName(boolean sortAscending){ + final Integer val; + if (sortAscending){ + val = 1; + } else { + val = -1; + } + + Collections.sort(mFiles, new Comparator() { + public int compare(OCFile o1, OCFile o2) { + if (o1.isFolder() && o2.isFolder()) { + return val * o1.getRemotePath().toLowerCase().compareTo(o2.getRemotePath().toLowerCase()); + } else if (o1.isFolder()) { + return -1; + } else if (o2.isFolder()) { + return 1; + } + return val * new AlphanumComparator().compare(o1, o2); + } + }); + } + + public void setSortOrder(Integer order, boolean ascending) { + SharedPreferences.Editor editor = mAppPreferences.edit(); + editor.putInt("sortOrder", order); + editor.putBoolean("sortAscending", ascending); + editor.commit(); + + mSortOrder = order; + mSortAscending = ascending; + + sortDirectory(); + } } diff --combined src/com/owncloud/android/ui/fragment/ExtendedListFragment.java index 17c3d010,5d3f7ace..c6123483 --- a/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java +++ b/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java @@@ -27,21 -27,21 +27,22 @@@ import android.view.View import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.GridView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragment; import com.owncloud.android.R; + import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.ui.ExtendedListView; - import com.owncloud.android.utils.Log_OC; + import com.owncloud.android.ui.activity.OnEnforceableRefreshListener; /** * TODO extending SherlockListFragment instead of SherlockFragment */ public class ExtendedListFragment extends SherlockFragment - implements OnItemClickListener, SwipeRefreshLayout.OnRefreshListener { + implements OnItemClickListener, OnEnforceableRefreshListener { private static final String TAG = ExtendedListFragment.class.getSimpleName(); @@@ -52,7 -52,7 +53,7 @@@ private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL"; private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE"; - protected ExtendedListView mList; + // protected ExtendedListView mList; private SwipeRefreshLayout mRefreshLayout; private SwipeRefreshLayout mRefreshEmptyLayout; @@@ -64,27 -64,16 +65,27 @@@ private ArrayList mTops; private int mHeightCell = 0; - private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = null; + private OnEnforceableRefreshListener mOnRefreshListener = null; - + protected GridView imageView; + public void setListAdapter(ListAdapter listAdapter) { - mList.setAdapter(listAdapter); - mList.invalidate(); + imageView.setAdapter(listAdapter); + imageView.invalidate(); } - public ListView getListView() { - return mList; + public GridView getGridView() { + return imageView; + } + + protected void switchImageView(){ + imageView.setNumColumns(GridView.AUTO_FIT); + imageView.invalidate(); + } + + protected void switchFileView(){ + imageView.setNumColumns(1); + imageView.invalidate(); } @@@ -93,17 -82,12 +94,17 @@@ Log_OC.e(TAG, "onCreateView"); View v = inflater.inflate(R.layout.list_fragment, null); - mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view); - mList = (ExtendedListView)(v.findViewById(R.id.list_root)); - mList.setOnItemClickListener(this); + +// imageView = (GridView) v.findViewById(R.id.grid_list_view); +// imageView.setOnItemClickListener(this); + + // mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view); + imageView = (ExtendedListView)(v.findViewById(R.id.list_root)); + imageView.setOnItemClickListener(this); - mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator)); - mList.setDividerHeight(1); + //mList.set + //mList.setDivider(getResources().getDrawable(R.drawable.uploader_list_separator)); + //mList.setDividerHeight(1); if (savedInstanceState != null) { int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION); @@@ -117,7 -101,7 +118,7 @@@ onCreateSwipeToRefresh(mRefreshLayout); onCreateSwipeToRefresh(mRefreshEmptyLayout); - mList.setEmptyView(mRefreshEmptyLayout); +// mList.setEmptyView(mRefreshEmptyLayout); return v; } @@@ -168,8 -152,8 +169,8 @@@ * @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; } @@@ -182,8 -166,8 +183,8 @@@ * @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); } } @@@ -201,14 -185,22 +202,14 @@@ int top = mTops.remove(mTops.size() - 1); - mList.setSelectionFromTop(firstPosition, top); + imageView.smoothScrollToPosition(firstPosition); // Move the scroll if the selection is not visible int indexPosition = mHeightCell*index; - int height = mList.getHeight(); + int height = imageView.getHeight(); if (indexPosition > height) { - if (android.os.Build.VERSION.SDK_INT >= 11) - { - mList.smoothScrollToPosition(index); - } - else if (android.os.Build.VERSION.SDK_INT >= 8) - { - mList.setSelectionFromTop(index, 0); - } - + imageView.smoothScrollToPosition(index); } } } @@@ -220,10 -212,10 +221,10 @@@ mIndexes.add(index); - int firstPosition = mList.getFirstVisiblePosition(); + int firstPosition = imageView.getFirstVisiblePosition(); mFirstPositions.add(firstPosition); - View view = mList.getChildAt(0); + View view = imageView.getChildAt(0); int top = (view == null) ? 0 : view.getTop() ; mTops.add(top); @@@ -249,7 -241,7 +250,7 @@@ } } - public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) { + public void setOnRefreshListener(OnEnforceableRefreshListener listener) { mOnRefreshListener = listener; } @@@ -309,4 -301,13 +310,13 @@@ refreshLayout.setOnRefreshListener(this); } + @Override + public void onRefresh(boolean ignoreETag) { + mRefreshLayout.setRefreshing(false); + mRefreshEmptyLayout.setRefreshing(false); + + if (mOnRefreshListener != null) { + mOnRefreshListener.onRefresh(ignoreETag); + } + } } diff --combined src/com/owncloud/android/ui/fragment/LocalFileListFragment.java index c695733d,62b41a3e..90af004c --- a/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/LocalFileListFragment.java @@@ -18,6 -18,7 +18,7 @@@ package com.owncloud.android.ui.fragment; import java.io.File; + import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; @@@ -31,8 -32,8 +32,8 @@@ import android.widget.ImageView import android.widget.ListView; import com.owncloud.android.R; + import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.ui.adapter.LocalFileListAdapter; - import com.owncloud.android.utils.Log_OC; /** @@@ -75,7 -76,7 +76,7 @@@ public class LocalFileListFragment exte public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log_OC.i(TAG, "onCreateView() start"); View v = super.onCreateView(inflater, container, savedInstanceState); - getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); + getGridView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); disableSwipe(); // Disable pull refresh setMessageForEmptyList(getString(R.string.local_file_list_empty)); Log_OC.i(TAG, "onCreateView() end"); @@@ -97,13 -98,33 +98,33 @@@ Log_OC.i(TAG, "onActivityCreated() stop"); } + public void selectAll(){ + int numberOfFiles = mAdapter.getCount(); + for(int i = 0; i < numberOfFiles; i++){ + File file = (File) mAdapter.getItem(i); + if (file != null) { + if (!file.isDirectory()) { + /// Click on a file + getListView().setItemChecked(i, true); + // notify the change to the container Activity + mContainerActivity.onFileClick(file); + } + } + } + } + + public void deselectAll(){ + mAdapter = new LocalFileListAdapter(mContainerActivity.getInitialDirectory(), getActivity()); + setListAdapter(mAdapter); + } /** * Checks the file clicked over. Browses inside if it is a directory. Notifies the container activity in any case. */ @Override public void onItemClick(AdapterView l, View v, int position, long id) { - File file = (File) mAdapter.getItem(position); + File file = (File) mAdapter.getItem(position); + if (file != null) { /// Click on a directory if (file.isDirectory()) { @@@ -117,7 -138,7 +138,7 @@@ } else { /// Click on a file ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox); if (checkBoxV != null) { - if (getListView().isItemChecked(position)) { + if (getGridView().isItemChecked(position)) { checkBoxV.setImageResource(android.R.drawable.checkbox_on_background); } else { checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); @@@ -194,10 -215,10 +215,10 @@@ directory = directory.getParentFile(); } - mList.clearChoices(); // by now, only files in the same directory will be kept as selected + imageView.clearChoices(); // by now, only files in the same directory will be kept as selected mAdapter.swapDirectory(directory); if (mDirectory == null || !mDirectory.equals(directory)) { - mList.setSelectionFromTop(0, 0); + imageView.setSelection(0); } mDirectory = directory; } @@@ -209,16 -230,18 +230,18 @@@ * @return File paths to the files checked by the user. */ public String[] getCheckedFilePaths() { - String [] result = null; + ArrayList result = new ArrayList(); - SparseBooleanArray positions = mList.getCheckedItemPositions(); + SparseBooleanArray positions = imageView.getCheckedItemPositions(); if (positions.size() > 0) { - Log_OC.d(TAG, "Returning " + positions.size() + " selected files"); - result = new String[positions.size()]; - for (int i=0; i files = storageManager.getFolderContent(directory); + for (OCFile file : files){ + if (file.isImage()){ + count++; + } + } + + // > 50% Images --> image view + // TODO threshold as constant in Preferences + if ((count / files.size()) >= 0.5){ + Log_OC.i(TAG, "Image View"); + switchImageView(); + } else { + Log_OC.i(TAG, "Folder View"); + switchFileView(); + } } } + + public void sortByName(boolean descending) { + mAdapter.setSortOrder(FileListListAdapter.SORT_NAME, descending); + } + + public void sortByDate(boolean descending) { + mAdapter.setSortOrder(FileListListAdapter.SORT_DATE, descending); + } + + public void sortBySize(boolean descending) { + mAdapter.setSortOrder(FileListListAdapter.SORT_SIZE, descending); + } }