+++ /dev/null
-/*\r
- * The Alphanum Algorithm is an improved sorting algorithm for strings\r
- * containing numbers. Instead of sorting numbers in ASCII order like\r
- * a standard sort, this algorithm sorts numbers in numeric order.\r
- *\r
- * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com\r
- *\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
- *\r
- */\r
-\r
-package com.owncloud.android.datamodel;\r
-import java.util.Comparator;\r
-\r
-/**\r
- * This is an updated version with enhancements made by Daniel Migowski,\r
- * Andre Bogus, and David Koelle\r
- *\r
- * To convert to use Templates (Java 1.5+):\r
- * - Change "implements Comparator" to "implements Comparator<String>"\r
- * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"\r
- * - Remove the type checking and casting in compare().\r
- *\r
- * To use this class:\r
- * Use the static "sort" method from the java.util.Collections class:\r
- * Collections.sort(your list, new AlphanumComparator());\r
- */\r
-public class AlphanumComparator implements Comparator<OCFile>\r
-{\r
- private final boolean isDigit(char ch)\r
- {\r
- return ch >= 48 && ch <= 57;\r
- }\r
-\r
- /** Length of string is passed in for improved efficiency (only need to calculate it once) **/\r
- private final String getChunk(String s, int slength, int marker)\r
- {\r
- StringBuilder chunk = new StringBuilder();\r
- char c = s.charAt(marker);\r
- chunk.append(c);\r
- marker++;\r
- if (isDigit(c))\r
- {\r
- while (marker < slength)\r
- {\r
- c = s.charAt(marker);\r
- if (!isDigit(c))\r
- break;\r
- chunk.append(c);\r
- marker++;\r
- }\r
- } else\r
- {\r
- while (marker < slength)\r
- {\r
- c = s.charAt(marker);\r
- if (isDigit(c))\r
- break;\r
- chunk.append(c);\r
- marker++;\r
- }\r
- }\r
- return chunk.toString();\r
- }\r
-\r
- public int compare(OCFile o1, OCFile o2)\r
- {\r
- String s1 = (String)o1.getRemotePath().toLowerCase();\r
- String s2 = (String)o2.getRemotePath().toLowerCase();\r
-\r
- int thisMarker = 0;\r
- int thatMarker = 0;\r
- int s1Length = s1.length();\r
- int s2Length = s2.length();\r
-\r
- while (thisMarker < s1Length && thatMarker < s2Length)\r
- {\r
- String thisChunk = getChunk(s1, s1Length, thisMarker);\r
- thisMarker += thisChunk.length();\r
-\r
- String thatChunk = getChunk(s2, s2Length, thatMarker);\r
- thatMarker += thatChunk.length();\r
-\r
- // If both chunks contain numeric characters, sort them numerically\r
- int result = 0;\r
- if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))\r
- {\r
- // Simple chunk comparison by length.\r
- int thisChunkLength = thisChunk.length();\r
- result = thisChunkLength - thatChunk.length();\r
- // If equal, the first different number counts\r
- if (result == 0)\r
- {\r
- for (int i = 0; i < thisChunkLength; i++)\r
- {\r
- result = thisChunk.charAt(i) - thatChunk.charAt(i);\r
- if (result != 0)\r
- {\r
- return result;\r
- }\r
- }\r
- }\r
- } else\r
- {\r
- result = thisChunk.compareTo(thatChunk);\r
- }\r
-\r
- if (result != 0)\r
- return result;\r
- }\r
-\r
- return s1Length - s2Length;\r
- }\r
-}\r
import java.io.File;
-import com.owncloud.android.utils.Log_OC;
+import third_parties.daveKoeller.AlphanumComparator;
+import com.owncloud.android.utils.Log_OC;
import android.os.Parcel;
import android.os.Parcelable;
}
case R.id.action_sort: {
SharedPreferences appPreferences = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
+ .getDefaultSharedPreferences(this);
// Read sorting order, default to sort by name ascending
Integer sortOrder = appPreferences
import java.util.Comparator;\r
import java.util.Vector;\r
\r
+import third_parties.daveKoeller.AlphanumComparator;\r
import android.accounts.Account;\r
import android.content.Context;\r
import android.content.SharedPreferences;\r
\r
import com.owncloud.android.R;\r
import com.owncloud.android.authentication.AccountUtils;\r
-import com.owncloud.android.datamodel.AlphanumComparator;\r
import com.owncloud.android.datamodel.FileDataStorageManager;\r
import com.owncloud.android.datamodel.OCFile;\r
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;\r
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.Log_OC;\r
-\r
\r
/**\r
* This Adapter populates a ListView with all files and folders in an ownCloud\r
* \r
*/\r
public class FileListListAdapter extends BaseAdapter implements ListAdapter {\r
- private final static String PERMISSION_SHARED_WITH_ME = "S";\r
-\r
- private Context mContext;\r
- private OCFile mFile = null;\r
- private Vector<OCFile> mFiles = null;\r
- private boolean mJustFolders;\r
-\r
- private FileDataStorageManager mStorageManager;
- private Account mAccount;
- private ComponentsGetter mTransferServiceGetter;\r
- private Integer sortOrder;\r
- private Boolean sortAscending;\r
- private SharedPreferences appPreferences;\r
- \r
- public FileListListAdapter(\r
- boolean justFolders, \r
- Context context, \r
- ComponentsGetter transferServiceGetter\r
- ) {\r
- mJustFolders = justFolders;\r
- mContext = context;\r
- mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
- mTransferServiceGetter = transferServiceGetter;\r
- \r
- appPreferences = PreferenceManager\r
- .getDefaultSharedPreferences(mContext);\r
- \r
- // Read sorting order, default to sort by name ascending\r
- sortOrder = appPreferences\r
- .getInt("sortOrder", 0);\r
- sortAscending = appPreferences.getBoolean("sortAscending", true);\r
- \r
- }
-\r
- @Override\r
- public boolean areAllItemsEnabled() {\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean isEnabled(int position) {\r
- return true;\r
- }\r
-\r
- @Override\r
- public int getCount() {\r
- return mFiles != null ? mFiles.size() : 0;\r
- }\r
-\r
- @Override\r
- public Object getItem(int position) {\r
- if (mFiles == null || mFiles.size() <= position)\r
- return null;\r
- return mFiles.get(position);\r
- }\r
-\r
- @Override\r
- public long getItemId(int position) {\r
- if (mFiles == null || mFiles.size() <= position)\r
- return 0;\r
- return mFiles.get(position).getFileId();\r
- }\r
-\r
- @Override\r
- public int getItemViewType(int position) {\r
- return 0;\r
- }\r
-\r
- @Override\r
- public View getView(int position, View convertView, ViewGroup parent) {\r
- View view = convertView;\r
- if (view == null) {\r
- LayoutInflater inflator = (LayoutInflater) mContext\r
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
- view = inflator.inflate(R.layout.list_item, null);\r
- }\r
- \r
- if (mFiles != null && mFiles.size() > position) {\r
- OCFile file = mFiles.get(position);\r
- TextView fileName = (TextView) view.findViewById(R.id.Filename);\r
- String name = file.getFileName();\r
-\r
- fileName.setText(name);\r
- ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
- ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon);\r
- ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon);\r
- sharedWithMeIconV.setVisibility(View.GONE);\r
-\r
- ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);\r
- localStateView.bringToFront();\r
- FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder();\r
- FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();\r
- if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) {\r
- localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
- localStateView.setVisibility(View.VISIBLE);\r
- } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {\r
- localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
- localStateView.setVisibility(View.VISIBLE);\r
- } else if (file.isDown()) {\r
- localStateView.setImageResource(R.drawable.local_file_indicator);\r
- localStateView.setVisibility(View.VISIBLE);\r
- } else {\r
- localStateView.setVisibility(View.INVISIBLE);\r
- }\r
- \r
- TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
- TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
- ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
- \r
- if (!file.isFolder()) {\r
- fileSizeV.setVisibility(View.VISIBLE);\r
- fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
- lastModV.setVisibility(View.VISIBLE);\r
- lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
- // this if-else is needed even thoe fav icon is visible by default\r
- // because android reuses views in listview\r
- if (!file.keepInSync()) {\r
- view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
- } else {\r
- view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);\r
- }\r
- \r
- ListView parentList = (ListView)parent;\r
- if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { \r
- checkBoxV.setVisibility(View.GONE);\r
- } else {\r
- if (parentList.isItemChecked(position)) {\r
- checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);\r
- } else {\r
- checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\r
- }\r
- checkBoxV.setVisibility(View.VISIBLE);\r
- }\r
-\r
- fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
-\r
- if (checkIfFileIsSharedWithMe(file)) {\r
- sharedWithMeIconV.setVisibility(View.VISIBLE);\r
- }\r
- } \r
- else {\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(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
- checkBoxV.setVisibility(View.GONE);\r
- view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
-\r
- if (checkIfFileIsSharedWithMe(file)) {\r
- fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
- sharedWithMeIconV.setVisibility(View.VISIBLE);\r
- } else {\r
- fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\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
- return view;\r
- }\r
- \r
- /**\r
- * Local Folder size in human readable format\r
- * @param path String\r
- * @return Size in human readable format\r
- */\r
- private String getFolderSizeHuman(String path) {\r
-\r
- File dir = new File(path);\r
-\r
- if(dir.exists()) {\r
- long bytes = getFolderSize(dir);\r
- if (bytes < 1024) return bytes + " B";\r
- int exp = (int) (Math.log(bytes) / Math.log(1024));\r
- String pre = ("KMGTPE").charAt(exp-1) + "";\r
-\r
- return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);\r
- }\r
-\r
- return "0 B";\r
- }\r
-\r
- /**\r
- * Local Folder size\r
- * @param dir File\r
- * @return Size in bytes\r
- */\r
- private long getFolderSize(File dir) {\r
- if (dir.exists()) {\r
- long result = 0;\r
- File[] fileList = dir.listFiles();\r
- for(int i = 0; i < fileList.length; i++) {\r
- if(fileList[i].isDirectory()) {\r
- result += getFolderSize(fileList[i]);\r
- } else {\r
- result += fileList[i].length();\r
- }\r
- }\r
- return result;\r
- }\r
- return 0;\r
- } \r
-\r
- @Override\r
- public int getViewTypeCount() {\r
- return 1;\r
- }\r
-\r
- @Override\r
- public boolean hasStableIds() {\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean isEmpty() {\r
- return (mFiles == null || mFiles.isEmpty());\r
- }\r
-\r
- /**\r
- * Change the adapted directory for a new one\r
- * @param directory New file to adapt. Can be NULL, meaning "no content to adapt".\r
- * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL)\r
- */\r
- public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) {\r
- mFile = directory;\r
- if (updatedStorageManager != null && updatedStorageManager != mStorageManager) {\r
- mStorageManager = updatedStorageManager;\r
- mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
- }\r
- if (mStorageManager != null) {\r
- mFiles = mStorageManager.getFolderContent(mFile);\r
- if (mJustFolders) {\r
- mFiles = getFolders(mFiles);\r
- }\r
- } else {\r
- mFiles = null;\r
- }\r
-\r
- sortDirectory();\r
- }\r
- \r
- /**\r
- * Sorts all filenames, regarding last user decision \r
- */\r
- private void sortDirectory(){\r
- switch (sortOrder){\r
- case 0:\r
- sortByName(sortAscending);\r
- break;\r
- case 1:\r
- sortByDate(sortAscending);\r
- break;\r
- case 2: \r
- sortBySize(sortAscending);\r
- break;\r
- }\r
- \r
- notifyDataSetChanged();\r
- }\r
- \r
- \r
- /**\r
- * Filter for getting only the folders\r
- * @param files\r
- * @return Vector<OCFile>\r
- */\r
- public Vector<OCFile> getFolders(Vector<OCFile> files) {\r
- Vector<OCFile> ret = new Vector<OCFile>(); \r
- OCFile current = null; \r
- for (int i=0; i<files.size(); i++) {\r
- current = files.get(i);\r
- if (current.isFolder()) {\r
- ret.add(current);\r
- }\r
- }\r
- return ret;\r
- }\r
- \r
- \r
- /**\r
- * Check if parent folder does not include 'S' permission and if file/folder\r
- * is shared with me\r
- * \r
- * @param file: OCFile\r
- * @return boolean: True if it is shared with me and false if it is not\r
- */\r
- private boolean checkIfFileIsSharedWithMe(OCFile file) {\r
- return (mFile.getPermissions() != null && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME)\r
- && file.getPermissions() != null && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
- }\r
-\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
- return val * Long.compare(o1.getModificationTimestamp(), 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
- return val * Long.compare(o1.getModificationTimestamp(), 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
- return val * Long.compare(getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1))), \r
- 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
- return val * Long.compare(o1.getFileLength(), 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 = appPreferences.edit();\r
- editor.putInt("sortOrder", order);\r
- editor.putBoolean("sortAscending", ascending);\r
- editor.commit();\r
- \r
- sortOrder = order;\r
- sortAscending = ascending;\r
- \r
- sortDirectory();\r
- } \r
+ private final static String PERMISSION_SHARED_WITH_ME = "S";\r
+\r
+ private final Context mContext;\r
+ private OCFile mFile = null;\r
+ private Vector<OCFile> mFiles = null;\r
+ private final boolean mJustFolders;\r
+\r
+ private FileDataStorageManager mStorageManager;\r
+ private Account mAccount;\r
+ private final ComponentsGetter mTransferServiceGetter;\r
+ private Integer mSortOrder;\r
+ public static final Integer mSortName = 0;\r
+ public static final Integer mSortDate = 1;\r
+ public static final Integer mSortSize = 2;\r
+ private Boolean mSortAscending;\r
+ private final SharedPreferences mAppPreferences;\r
+\r
+ public FileListListAdapter(boolean justFolders, Context context, ComponentsGetter transferServiceGetter) {\r
+ mJustFolders = justFolders;\r
+ mContext = context;\r
+ mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
+ mTransferServiceGetter = transferServiceGetter;\r
+\r
+ mAppPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);\r
+\r
+ // Read sorting order, default to sort by name ascending\r
+ mSortOrder = mAppPreferences.getInt("sortOrder", mSortName);\r
+ mSortAscending = mAppPreferences.getBoolean("sortAscending", true);\r
+\r
+ }\r
+\r
+ @Override\r
+ public boolean areAllItemsEnabled() {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean isEnabled(int position) {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public int getCount() {\r
+ return mFiles != null ? mFiles.size() : 0;\r
+ }\r
+\r
+ @Override\r
+ public Object getItem(int position) {\r
+ if (mFiles == null || mFiles.size() <= position)\r
+ return null;\r
+ return mFiles.get(position);\r
+ }\r
+\r
+ @Override\r
+ public long getItemId(int position) {\r
+ if (mFiles == null || mFiles.size() <= position)\r
+ return 0;\r
+ return mFiles.get(position).getFileId();\r
+ }\r
+\r
+ @Override\r
+ public int getItemViewType(int position) {\r
+ return 0;\r
+ }\r
+\r
+ @Override\r
+ public View getView(int position, View convertView, ViewGroup parent) {\r
+ View view = convertView;\r
+ if (view == null) {\r
+ LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+ view = inflator.inflate(R.layout.list_item, null);\r
+ }\r
+\r
+ if (mFiles != null && mFiles.size() > position) {\r
+ OCFile file = mFiles.get(position);\r
+ TextView fileName = (TextView) view.findViewById(R.id.Filename);\r
+ String name = file.getFileName();\r
+\r
+ fileName.setText(name);\r
+ ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
+ ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon);\r
+ ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon);\r
+ sharedWithMeIconV.setVisibility(View.GONE);\r
+\r
+ ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);\r
+ localStateView.bringToFront();\r
+ FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder();\r
+ FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();\r
+ if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) {\r
+ localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
+ localStateView.setVisibility(View.VISIBLE);\r
+ } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {\r
+ localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
+ localStateView.setVisibility(View.VISIBLE);\r
+ } else if (file.isDown()) {\r
+ localStateView.setImageResource(R.drawable.local_file_indicator);\r
+ localStateView.setVisibility(View.VISIBLE);\r
+ } else {\r
+ localStateView.setVisibility(View.INVISIBLE);\r
+ }\r
+\r
+ TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
+ TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
+ ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
+\r
+ if (!file.isFolder()) {\r
+ fileSizeV.setVisibility(View.VISIBLE);\r
+ fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
+ lastModV.setVisibility(View.VISIBLE);\r
+ lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
+ // this if-else is needed even thoe fav icon is visible by\r
+ // default\r
+ // because android reuses views in listview\r
+ if (!file.keepInSync()) {\r
+ view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
+ } else {\r
+ view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);\r
+ }\r
+\r
+ ListView parentList = (ListView) parent;\r
+ if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) {\r
+ checkBoxV.setVisibility(View.GONE);\r
+ } else {\r
+ if (parentList.isItemChecked(position)) {\r
+ checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);\r
+ } else {\r
+ checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\r
+ }\r
+ checkBoxV.setVisibility(View.VISIBLE);\r
+ }\r
+\r
+ fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
+\r
+ if (checkIfFileIsSharedWithMe(file)) {\r
+ sharedWithMeIconV.setVisibility(View.VISIBLE);\r
+ }\r
+ } else {\r
+ // TODO Re-enable when server supports folder-size calculation\r
+ // if (FileStorageUtils.getDefaultSavePathFor(mAccount.name,\r
+ // file) != null) {\r
+ // fileSizeV.setVisibility(View.VISIBLE);\r
+ // fileSizeV\r
+ // .setText(getFolderSizeHuman(FileStorageUtils.getDefaultSavePathFor(mAccount.name,\r
+ // file)));\r
+ // } else {\r
+ fileSizeV.setVisibility(View.INVISIBLE);\r
+ // }\r
+\r
+ lastModV.setVisibility(View.VISIBLE);\r
+ lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
+ checkBoxV.setVisibility(View.GONE);\r
+ view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
+\r
+ if (checkIfFileIsSharedWithMe(file)) {\r
+ fileIcon.setImageResource(R.drawable.shared_with_me_folder);\r
+ sharedWithMeIconV.setVisibility(View.VISIBLE);\r
+ } else {\r
+ fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\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
+ return view;\r
+ }\r
+\r
+ /**\r
+ * Local Folder size in human readable format\r
+ * \r
+ * @param path\r
+ * String\r
+ * @return Size in human readable format\r
+ */\r
+ private String getFolderSizeHuman(String path) {\r
+\r
+ File dir = new File(path);\r
+\r
+ if (dir.exists()) {\r
+ long bytes = getFolderSize(dir);\r
+ return DisplayUtils.bytesToHumanReadable(bytes);\r
+ }\r
+\r
+ return "0 B";\r
+ }\r
+\r
+ /**\r
+ * Local Folder size\r
+ * \r
+ * @param dir\r
+ * File\r
+ * @return Size in bytes\r
+ */\r
+ private long getFolderSize(File dir) {\r
+ if (dir.exists()) {\r
+ long result = 0;\r
+ File[] fileList = dir.listFiles();\r
+ for (int i = 0; i < fileList.length; i++) {\r
+ if (fileList[i].isDirectory()) {\r
+ result += getFolderSize(fileList[i]);\r
+ } else {\r
+ result += fileList[i].length();\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ return 0;\r
+ }\r
+\r
+ @Override\r
+ public int getViewTypeCount() {\r
+ return 1;\r
+ }\r
+\r
+ @Override\r
+ public boolean hasStableIds() {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean isEmpty() {\r
+ return (mFiles == null || mFiles.isEmpty());\r
+ }\r
+\r
+ /**\r
+ * Change the adapted directory for a new one\r
+ * \r
+ * @param directory\r
+ * New file to adapt. Can be NULL, meaning "no content to adapt".\r
+ * @param updatedStorageManager\r
+ * Optional updated storage manager; used to replace\r
+ * mStorageManager if is different (and not NULL)\r
+ */\r
+ public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) {\r
+ mFile = directory;\r
+ if (updatedStorageManager != null && updatedStorageManager != mStorageManager) {\r
+ mStorageManager = updatedStorageManager;\r
+ mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
+ }\r
+ if (mStorageManager != null) {\r
+ mFiles = mStorageManager.getFolderContent(mFile);\r
+ if (mJustFolders) {\r
+ mFiles = getFolders(mFiles);\r
+ }\r
+ } else {\r
+ mFiles = null;\r
+ }\r
+\r
+ sortDirectory();\r
+ }\r
+\r
+ /**\r
+ * Sorts all filenames, regarding last user decision\r
+ */\r
+ private void sortDirectory() {\r
+ switch (mSortOrder) {\r
+ case 0:\r
+ sortByName(mSortAscending);\r
+ break;\r
+ case 1:\r
+ sortByDate(mSortAscending);\r
+ break;\r
+ case 2:\r
+ sortBySize(mSortAscending);\r
+ break;\r
+ }\r
+\r
+ notifyDataSetChanged();\r
+ }\r
+\r
+ /**\r
+ * Filter for getting only the folders\r
+ * \r
+ * @param files\r
+ * @return Vector<OCFile>\r
+ */\r
+ public Vector<OCFile> getFolders(Vector<OCFile> files) {\r
+ Vector<OCFile> ret = new Vector<OCFile>();\r
+ OCFile current = null;\r
+ for (int i = 0; i < files.size(); i++) {\r
+ current = files.get(i);\r
+ if (current.isFolder()) {\r
+ ret.add(current);\r
+ }\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ /**\r
+ * Check if parent folder does not include 'S' permission and if file/folder\r
+ * is shared with me\r
+ * \r
+ * @param file\r
+ * : OCFile\r
+ * @return boolean: True if it is shared with me and false if it is not\r
+ */\r
+ private boolean checkIfFileIsSharedWithMe(OCFile file) {\r
+ return (mFile.getPermissions() != null && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME)\r
+ && file.getPermissions() != null && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME));\r
+ }\r
+\r
+ /**\r
+ * Sorts list by Date\r
+ * \r
+ * @param sortAscending\r
+ * 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
+ @Override\r
+ public int compare(OCFile o1, OCFile o2) {\r
+ if (o1.isFolder() && o2.isFolder()) {\r
+ return val * Long.compare(o1.getModificationTimestamp(), o2.getModificationTimestamp());\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
+ return val * Long.compare(o1.getModificationTimestamp(), o2.getModificationTimestamp());\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ /**\r
+ * Sorts list by Size\r
+ * \r
+ * @param sortAscending\r
+ * 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
+ @Override\r
+ public int compare(OCFile o1, OCFile o2) {\r
+ if (o1.isFolder() && o2.isFolder()) {\r
+ return val\r
+ * Long.compare(\r
+ getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o1))),\r
+ getFolderSize(new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, o2))));\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
+ return val * Long.compare(o1.getFileLength(), o2.getFileLength());\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ /**\r
+ * Sorts list by Name\r
+ * \r
+ * @param sortAscending\r
+ * 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
+ @Override\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
+\r
+ sortDirectory();\r
+ }\r
}\r
* @author David A. Velasco
*/
public class OCFileListFragment extends ExtendedListFragment {
-
- 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 OCFile mTargetFile;
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- Log_OC.e(TAG, "onAttach");
- try {
- mContainerActivity = (FileFragment.ContainerActivity) activity;
-
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement " +
- FileFragment.ContainerActivity.class.getSimpleName());
- }
- try {
- setOnRefreshListener((SwipeRefreshLayout.OnRefreshListener) activity);
-
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement " +
- SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
- }
- }
-
-
- @Override
- public void onDetach() {
- setOnRefreshListener(null);
- mContainerActivity = null;
- super.onDetach();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Log_OC.e(TAG, "onActivityCreated() start");
-
- if (savedInstanceState != null) {
- mFile = savedInstanceState.getParcelable(KEY_FILE);
- }
-
- Bundle args = getArguments();
- boolean justFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false);
- mAdapter = new FileListListAdapter(
- justFolders,
- getSherlockActivity(),
- mContainerActivity
- );
- setListAdapter(mAdapter);
-
- registerForContextMenu(getListView());
- getListView().setOnCreateContextMenuListener(this);
- }
-
- /**
- * Saves the current listed folder.
- */
- @Override
- 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
- * database, it continues browsing up until finding an existing folders.
- *
- * return Count of folder levels browsed up.
- */
- public int onBrowseUp() {
- OCFile parentDir = null;
- int moveCount = 0;
-
- 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;
- parentDir = storageManager.getFileByPath(parentPath);
- moveCount++;
- } else {
- parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH);
- }
- while (parentDir == null) {
- parentPath = new File(parentPath).getParent();
- 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
- mFile = parentDir;
-
- listDirectory(mFile);
-
- onRefresh();
-
- // 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()) {
- // update state and view of this fragment
- listDirectory(file);
- // then, notify parent activity to let it update its state and view
- 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 (file.isDown()) {
- if (PreviewMediaFragment.canBePreviewed(file)) {
- // media preview
- ((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 (
- 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);
- if (allowContextualActions) {
- MenuInflater inflater = getSherlockActivity().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,
- mContainerActivity.getStorageManager().getAccount(),
- mContainerActivity,
- getSherlockActivity()
- );
- mf.filter(menu);
- }
-
- /// additional restrictions for this fragment
- // TODO allow in the future 'open with' for previewable files
- MenuItem item = menu.findItem(R.id.action_open_file_with);
- if (item != null) {
- item.setVisible(false);
- item.setEnabled(false);
- }
- /// TODO break this direct dependency on FileDisplayActivity... if possible
- FileFragment frag = ((FileDisplayActivity)getSherlockActivity()).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);
- }
- }
- }
- }
-
-
- /**
- * {@inhericDoc}
- */
- @Override
- public boolean onContextItemSelected (MenuItem item) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
- mTargetFile = (OCFile) mAdapter.getItem(info.position);
- switch (item.getItemId()) {
- case R.id.action_share_file: {
- mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
- return true;
- }
- case R.id.action_unshare_file: {
- mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile);
- return true;
- }
- case R.id.action_rename_file: {
- RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
- dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
- return true;
- }
- case R.id.action_remove_file: {
- RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
- dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
- return true;
- }
- 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);
- return true;
- }
- case R.id.action_see_details: {
- mContainerActivity.showDetails(mTargetFile);
- return true;
- }
- case R.id.action_send_file: {
- // Obtain the file
- if (!mTargetFile.isDown()) { // Download the file
- Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
- ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile);
-
- } else {
- mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
- }
- return true;
- }
- case R.id.action_move: {
- Intent action = new Intent(getActivity(), MoveActivity.class);
-
- // Pass mTargetFile that contains info of selected file/folder
- action.putExtra(MoveActivity.EXTRA_TARGET_FILE, mTargetFile);
- getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
- return true;
- }
- default:
- return super.onContextItemSelected(item);
- }
- }
-
-
- /**
- * Use this to query the {@link OCFile} that is currently
- * being displayed by this fragment
- * @return The currently viewed OCFile
- */
- public OCFile getCurrentFile(){
- return mFile;
- }
-
- /**
- * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
- */
- public void listDirectory(){
- listDirectory(null);
- }
-
- /**
- * 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) {
- FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
- if (storageManager != null) {
-
- // Check input parameters for 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()){
- Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
- directory = storageManager.getFileById(directory.getParentId());
- }
-
- mAdapter.swapDirectory(directory, storageManager);
- if (mFile == null || !mFile.equals(directory)) {
- mList.setSelectionFromTop(0, 0);
- }
- mFile = directory;
- }
- }
-
- public void sortByName(boolean descending){
- mAdapter.setSortOrder(0, descending);
- }
-
- public void sortByDate(boolean descending){
- mAdapter.setSortOrder(1, descending);
- }
-
- public void sortBySize(boolean descending){
- mAdapter.setSortOrder(2, descending);
- }
+
+ 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 OCFile mTargetFile;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ Log_OC.e(TAG, "onAttach");
+ try {
+ mContainerActivity = (FileFragment.ContainerActivity) activity;
+
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement "
+ + FileFragment.ContainerActivity.class.getSimpleName());
+ }
+ try {
+ setOnRefreshListener((SwipeRefreshLayout.OnRefreshListener) activity);
+
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement "
+ + SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ setOnRefreshListener(null);
+ mContainerActivity = null;
+ super.onDetach();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ Log_OC.e(TAG, "onActivityCreated() start");
+
+ if (savedInstanceState != null) {
+ mFile = savedInstanceState.getParcelable(KEY_FILE);
+ }
+
+ Bundle args = getArguments();
+ boolean justFolders = (args == null) ? false : args.getBoolean(ARG_JUST_FOLDERS, false);
+ mAdapter = new FileListListAdapter(justFolders, getSherlockActivity(), mContainerActivity);
+ setListAdapter(mAdapter);
+
+ registerForContextMenu(getListView());
+ getListView().setOnCreateContextMenuListener(this);
+ }
+
+ /**
+ * Saves the current listed folder.
+ */
+ @Override
+ 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 database, it continues browsing up until finding an
+ * existing folders.
+ *
+ * return Count of folder levels browsed up.
+ */
+ public int onBrowseUp() {
+ OCFile parentDir = null;
+ int moveCount = 0;
+
+ 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;
+ parentDir = storageManager.getFileByPath(parentPath);
+ moveCount++;
+ } else {
+ parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH);
+ }
+ while (parentDir == null) {
+ parentPath = new File(parentPath).getParent();
+ 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
+ mFile = parentDir;
+
+ listDirectory(mFile);
+
+ onRefresh();
+
+ // 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()) {
+ // update state and view of this fragment
+ listDirectory(file);
+ // then, notify parent activity to let it update its state and
+ // view
+ 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 (file.isDown()) {
+ if (PreviewMediaFragment.canBePreviewed(file)) {
+ // media preview
+ ((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(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);
+ if (allowContextualActions) {
+ MenuInflater inflater = getSherlockActivity().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, mContainerActivity.getStorageManager()
+ .getAccount(), mContainerActivity, getSherlockActivity());
+ mf.filter(menu);
+ }
+
+ // / additional restrictions for this fragment
+ // TODO allow in the future 'open with' for previewable files
+ MenuItem item = menu.findItem(R.id.action_open_file_with);
+ if (item != null) {
+ item.setVisible(false);
+ item.setEnabled(false);
+ }
+ // / TODO break this direct dependency on FileDisplayActivity... if
+ // possible
+ FileFragment frag = ((FileDisplayActivity) getSherlockActivity()).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);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inhericDoc}
+ */
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ mTargetFile = (OCFile) mAdapter.getItem(info.position);
+ switch (item.getItemId()) {
+ case R.id.action_share_file: {
+ mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
+ return true;
+ }
+ case R.id.action_unshare_file: {
+ mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile);
+ return true;
+ }
+ case R.id.action_rename_file: {
+ RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
+ dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
+ return true;
+ }
+ case R.id.action_remove_file: {
+ RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
+ dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
+ return true;
+ }
+ 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);
+ return true;
+ }
+ case R.id.action_see_details: {
+ mContainerActivity.showDetails(mTargetFile);
+ return true;
+ }
+ case R.id.action_send_file: {
+ // Obtain the file
+ if (!mTargetFile.isDown()) { // Download the file
+ Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
+ ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
+
+ } else {
+ mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+ }
+ return true;
+ }
+ case R.id.action_move: {
+ Intent action = new Intent(getActivity(), MoveActivity.class);
+
+ // Pass mTargetFile that contains info of selected file/folder
+ action.putExtra(MoveActivity.EXTRA_TARGET_FILE, mTargetFile);
+ getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
+ return true;
+ }
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ /**
+ * Use this to query the {@link OCFile} that is currently being displayed by
+ * this fragment
+ *
+ * @return The currently viewed OCFile
+ */
+ public OCFile getCurrentFile() {
+ return mFile;
+ }
+
+ /**
+ * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null
+ * parameter
+ */
+ public void listDirectory() {
+ listDirectory(null);
+ }
+
+ /**
+ * 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) {
+ FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+ if (storageManager != null) {
+
+ // Check input parameters for 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()) {
+ Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
+ directory = storageManager.getFileById(directory.getParentId());
+ }
+
+ mAdapter.swapDirectory(directory, storageManager);
+ if (mFile == null || !mFile.equals(directory)) {
+ mList.setSelectionFromTop(0, 0);
+ }
+ mFile = directory;
+ }
+ }
+
+ public void sortByName(boolean descending) {
+ mAdapter.setSortOrder(FileListListAdapter.mSortName, descending);
+ }
+
+ public void sortByDate(boolean descending) {
+ mAdapter.setSortOrder(FileListListAdapter.mSortDate, descending);
+ }
+
+ public void sortBySize(boolean descending) {
+ mAdapter.setSortOrder(FileListListAdapter.mSortSize, descending);
+ }
}
--- /dev/null
+/*\r
+ * The Alphanum Algorithm is an improved sorting algorithm for strings\r
+ * containing numbers. Instead of sorting numbers in ASCII order like\r
+ * a standard sort, this algorithm sorts numbers in numeric order.\r
+ *\r
+ * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com\r
+ *\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+ *\r
+ */\r
+\r
+package third_parties.daveKoeller;\r
+import java.util.Comparator;\r
+\r
+import com.owncloud.android.datamodel.OCFile;\r
+\r
+/**\r
+ * This is an updated version with enhancements made by Daniel Migowski,\r
+ * Andre Bogus, and David Koelle\r
+ *\r
+ * To convert to use Templates (Java 1.5+):\r
+ * - Change "implements Comparator" to "implements Comparator<String>"\r
+ * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"\r
+ * - Remove the type checking and casting in compare().\r
+ *\r
+ * To use this class:\r
+ * Use the static "sort" method from the java.util.Collections class:\r
+ * Collections.sort(your list, new AlphanumComparator());\r
+ */\r
+public class AlphanumComparator implements Comparator<OCFile>\r
+{\r
+ private final boolean isDigit(char ch)\r
+ {\r
+ return ch >= 48 && ch <= 57;\r
+ }\r
+\r
+ /** Length of string is passed in for improved efficiency (only need to calculate it once) **/\r
+ private final String getChunk(String s, int slength, int marker)\r
+ {\r
+ StringBuilder chunk = new StringBuilder();\r
+ char c = s.charAt(marker);\r
+ chunk.append(c);\r
+ marker++;\r
+ if (isDigit(c))\r
+ {\r
+ while (marker < slength)\r
+ {\r
+ c = s.charAt(marker);\r
+ if (!isDigit(c))\r
+ break;\r
+ chunk.append(c);\r
+ marker++;\r
+ }\r
+ } else\r
+ {\r
+ while (marker < slength)\r
+ {\r
+ c = s.charAt(marker);\r
+ if (isDigit(c))\r
+ break;\r
+ chunk.append(c);\r
+ marker++;\r
+ }\r
+ }\r
+ return chunk.toString();\r
+ }\r
+\r
+ public int compare(OCFile o1, OCFile o2)\r
+ {\r
+ String s1 = (String)o1.getRemotePath().toLowerCase();\r
+ String s2 = (String)o2.getRemotePath().toLowerCase();\r
+\r
+ int thisMarker = 0;\r
+ int thatMarker = 0;\r
+ int s1Length = s1.length();\r
+ int s2Length = s2.length();\r
+\r
+ while (thisMarker < s1Length && thatMarker < s2Length)\r
+ {\r
+ String thisChunk = getChunk(s1, s1Length, thisMarker);\r
+ thisMarker += thisChunk.length();\r
+\r
+ String thatChunk = getChunk(s2, s2Length, thatMarker);\r
+ thatMarker += thatChunk.length();\r
+\r
+ // If both chunks contain numeric characters, sort them numerically\r
+ int result = 0;\r
+ if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))\r
+ {\r
+ // Simple chunk comparison by length.\r
+ int thisChunkLength = thisChunk.length();\r
+ result = thisChunkLength - thatChunk.length();\r
+ // If equal, the first different number counts\r
+ if (result == 0)\r
+ {\r
+ for (int i = 0; i < thisChunkLength; i++)\r
+ {\r
+ result = thisChunk.charAt(i) - thatChunk.charAt(i);\r
+ if (result != 0)\r
+ {\r
+ return result;\r
+ }\r
+ }\r
+ }\r
+ } else\r
+ {\r
+ result = thisChunk.compareTo(thatChunk);\r
+ }\r
+\r
+ if (result != 0)\r
+ return result;\r
+ }\r
+\r
+ return s1Length - s2Length;\r
+ }\r
+}\r