Browse Source

Merge pull request #1571 from srkunze/issue-1508

Folder-Based Sort Order
Tobias Kaminsky 7 years ago
parent
commit
ae2ac1c26d

+ 93 - 26
src/main/java/com/owncloud/android/db/PreferenceManager.java

@@ -1,28 +1,36 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author David A. Velasco
  * Copyright (C) 2016 ownCloud Inc.
- * <p/>
+ * 
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
  * as published by the Free Software Foundation.
- * <p/>
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * <p/>
+ * 
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.owncloud.android.db;
 
+import android.accounts.Account;
 import android.content.Context;
 import android.content.SharedPreferences;
 
-import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.utils.FileSortOrder;
+
+import static com.owncloud.android.ui.fragment.OCFileListFragment.FOLDER_LAYOUT_LIST;
 
 /**
  * Helper to simplify reading of Preferences all around the app
@@ -33,8 +41,6 @@ public abstract class PreferenceManager {
      * Value handled by the app without direct access in the UI.
      */
     private static final String AUTO_PREF__LAST_UPLOAD_PATH = "last_upload_path";
-    private static final String AUTO_PREF__SORT_ORDER = "sort_order";
-    private static final String AUTO_PREF__SORT_ASCENDING = "sort_ascending";
     private static final String AUTO_PREF__UPLOAD_FILE_EXTENSION_MAP_URL = "prefs_upload_file_extension_map_url";
     private static final String AUTO_PREF__UPLOAD_FILE_EXTENSION_URL = "prefs_upload_file_extension_url";
     private static final String AUTO_PREF__UPLOADER_BEHAVIOR = "prefs_uploader_behaviour";
@@ -44,12 +50,16 @@ public abstract class PreferenceManager {
     private static final String PREF__INSTANT_UPLOAD_PATH_USE_SUBFOLDERS = "instant_upload_path_use_subfolders";
     private static final String PREF__INSTANT_UPLOAD_ON_WIFI = "instant_upload_on_wifi";
     private static final String PREF__INSTANT_VIDEO_UPLOAD_ON_WIFI = "instant_video_upload_on_wifi";
-    private static final String PREF__INSTANT_VIDEO_UPLOAD_PATH_USE_SUBFOLDERS = "instant_video_upload_path_use_subfolders";
+    private static final String PREF__INSTANT_VIDEO_UPLOAD_PATH_USE_SUBFOLDERS
+            = "instant_video_upload_path_use_subfolders";
     private static final String PREF__LEGACY_CLEAN = "legacyClean";
     private static final String PREF__AUTO_UPLOAD_UPDATE_PATH = "autoUploadPathUpdate";
     private static final String PREF__PUSH_TOKEN = "pushToken";
     private static final String PREF__AUTO_UPLOAD_SPLIT_OUT = "autoUploadEntriesSplitOut";
     private static final String PREF__AUTO_UPLOAD_INIT = "autoUploadInit";
+    private static final String PREF__FOLDER_SORT_ORDER = "folder_sort_order";
+    private static final String PREF__FOLDER_LAYOUT = "folder_layout";
+    private static final String KEY_FAB_EVER_CLICKED = "FAB_EVER_CLICKED";
 
     public static void setPushToken(Context context, String pushToken) {
         saveStringPreferenceNow(context, PREF__PUSH_TOKEN, pushToken);
@@ -88,13 +98,22 @@ public abstract class PreferenceManager {
     }
 
     public static boolean instantVideoUploadWhenChargingOnly(Context context) {
-        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_upload_on_charging", false);
+        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_upload_on_charging",
+                false);
     }
 
     public static boolean showHiddenFilesEnabled(Context context) {
         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("show_hidden_files_pref", false);
     }
 
+    public static long getFABClicked(Context context) {
+        return getDefaultSharedPreferences(context).getLong(KEY_FAB_EVER_CLICKED, 0);
+    }
+
+    public static void setFABClicked(Context context) {
+        getDefaultSharedPreferences(context).edit().putLong(KEY_FAB_EVER_CLICKED, 1).apply();
+    }
+
     /**
      * Gets the selected file extension position the user selected to do the last upload of a url file shared from other
      * app.
@@ -161,43 +180,91 @@ public abstract class PreferenceManager {
     }
 
     /**
-     * Gets the sort order which the user has set last.
+     * Get preferred folder display type.
+     *
+     * @param context Caller {@link Context}, used to access to preferences manager.
+     * @param folder Folder
+     * @return preference value, default is 
+     * {@link com.owncloud.android.ui.fragment.OCFileListFragment#FOLDER_LAYOUT_LIST}
+     */
+    public static String getFolderLayout(Context context, OCFile folder) {
+        return getFolderPreference(context, PREF__FOLDER_LAYOUT, folder, FOLDER_LAYOUT_LIST);
+    }
+
+    /**
+     * Set preferred folder display type.
      *
      * @param context Caller {@link Context}, used to access to shared preferences manager.
-     * @return sort order     the sort order, default is {@link FileStorageUtils#SORT_NAME} (sort by name)
+     * @param folder Folder
+     * @param layout_name preference value
      */
-    public static int getSortOrder(Context context) {
-        return getDefaultSharedPreferences(context).getInt(AUTO_PREF__SORT_ORDER, FileStorageUtils.SORT_NAME);
+    public static void setFolderLayout(Context context, OCFile folder, String layout_name) {
+        setFolderPreference(context, PREF__FOLDER_LAYOUT, folder, layout_name);
     }
 
     /**
-     * Save the sort order which the user has set last.
+     * Get preferred folder sort order.
      *
      * @param context Caller {@link Context}, used to access to shared preferences manager.
-     * @param order   the sort order
+     * @return sort order     the sort order, default is {@link FileSortOrder#sort_a_to_z} (sort by name)
      */
-    public static void setSortOrder(Context context, int order) {
-        saveIntPreference(context, AUTO_PREF__SORT_ORDER, order);
+    public static FileSortOrder getSortOrder(Context context, OCFile folder) {
+        return FileSortOrder.sortOrders.get(getFolderPreference(context, PREF__FOLDER_SORT_ORDER, folder,
+                FileSortOrder.sort_a_to_z.mName));
     }
 
     /**
-     * Gets the ascending order flag which the user has set last.
+     * Set preferred folder sort order.
      *
      * @param context Caller {@link Context}, used to access to shared preferences manager.
-     * @return ascending order     the ascending order, default is true
+     * @param sortOrder   the sort order
      */
-    public static boolean getSortAscending(Context context) {
-        return getDefaultSharedPreferences(context).getBoolean(AUTO_PREF__SORT_ASCENDING, true);
+    public static void setSortOrder(Context context, OCFile folder, FileSortOrder sortOrder) {
+        setFolderPreference(context, PREF__FOLDER_SORT_ORDER, folder, sortOrder.mName);
     }
 
     /**
-     * Saves the ascending order flag which the user has set last.
+     * Get preference value for a folder.
+     * If folder is not set itself, it finds an ancestor that is set.
      *
-     * @param context   Caller {@link Context}, used to access to shared preferences manager.
-     * @param ascending flag if sorting is ascending or descending
+     * @param context Context object.
+     * @param preferenceName Name of the preference to lookup.
+     * @param folder Folder.
+     * @param defaultValue Fallback value in case no ancestor is set.
+     * @return Preference value
      */
-    public static void setSortAscending(Context context, boolean ascending) {
-        saveBooleanPreference(context, AUTO_PREF__SORT_ASCENDING, ascending);
+    public static String getFolderPreference(Context context, String preferenceName, OCFile folder,
+                                             String defaultValue) {
+        Account account = AccountUtils.getCurrentOwnCloudAccount(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        FileDataStorageManager storageManager = ((ComponentsGetter)context).getStorageManager();
+        String value = dataProvider.getValue(account.name, getKeyFromFolder(preferenceName, folder));
+        while (folder != null && value.isEmpty()) {
+            folder = storageManager.getFileById(folder.getParentId());
+            value = dataProvider.getValue(account.name, getKeyFromFolder(preferenceName, folder));
+        }
+        return value.isEmpty() ? defaultValue : value;
+    }
+
+    /**
+     * Set preference value for a folder.
+     *
+     * @param context Context object.
+     * @param preferenceName Name of the preference to set.
+     * @param folder Folder.
+     * @param value Preference value to set.
+     */
+    public static void setFolderPreference(Context context, String preferenceName, OCFile folder, String value) {
+        Account account = AccountUtils.getCurrentOwnCloudAccount(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        dataProvider.storeOrUpdateKeyValue(account.name, getKeyFromFolder(preferenceName, folder), value);
+    }
+
+    private static String getKeyFromFolder(String preferenceName, OCFile folder) {
+        final String folderIdString = String.valueOf(folder != null ? folder.getFileId() :
+                FileDataStorageManager.ROOT_PARENT_ID);
+        
+        return preferenceName + "_" + folderIdString;
     }
 
     public static boolean getAutoUploadInit(Context context) {

+ 10 - 51
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -106,6 +106,7 @@ import com.owncloud.android.ui.preview.PreviewVideoActivity;
 import com.owncloud.android.utils.DataHolderUtil;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ErrorMessageAdapter;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.PermissionUtil;
 import com.owncloud.android.utils.PushUtils;
@@ -120,7 +121,6 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 
-import static com.owncloud.android.db.PreferenceManager.getSortAscending;
 import static com.owncloud.android.db.PreferenceManager.getSortOrder;
 
 /**
@@ -145,8 +145,6 @@ public class FileDisplayActivity extends HookActivity
     private static final String KEY_WAITING_TO_SEND = "WAITING_TO_SEND";
     private static final String KEY_SEARCH_QUERY = "KEY_SEARCH_QUERY";
 
-    private static final String SORT_ORDER_DIALOG_TAG = "SORT_ORDER_DIALOG";
-
     public static final String ACTION_DETAILS = "com.owncloud.android.ui.activity.action.DETAILS";
 
     public static final String DRAWER_MENU_ID = "DRAWER_MENU_ID";
@@ -678,10 +676,10 @@ public class FileDisplayActivity extends HookActivity
 
         // hacky as no default way is provided
         int fontColor = ThemeUtils.fontColor();
-        EditText editText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
+        EditText editText = searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
         editText.setHintTextColor(fontColor);
         editText.setTextColor(fontColor);
-        ImageView searchClose = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
+        ImageView searchClose = searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
         searchClose.setColorFilter(ThemeUtils.fontColor());
 
         // populate list of menu items to show/hide when drawer is opened/closed
@@ -778,23 +776,19 @@ public class FileDisplayActivity extends HookActivity
                 ft.addToBackStack(null);
 
                 SortingOrderDialogFragment mSortingOrderDialogFragment = SortingOrderDialogFragment.newInstance(
-                        getSortOrder(this),
-                        getSortAscending(this)
-                );
-                mSortingOrderDialogFragment.show(ft, SORT_ORDER_DIALOG_TAG);
+                        getSortOrder(this, getListOfFilesFragment().getCurrentFile()));
+                mSortingOrderDialogFragment.show(ft, SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
 
                 break;
             }
             case R.id.action_switch_view: {
                 if (isGridView()) {
                     item.setTitle(getString(R.string.action_switch_grid_view));
-                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(),
-                            R.drawable.ic_view_module));
+                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_view_module));
                     getListOfFilesFragment().setListAsPreferred();
                 } else {
                     item.setTitle(getApplicationContext().getString(R.string.action_switch_list_view));
-                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(),
-                            R.drawable.ic_view_list));
+                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_view_list));
                     getListOfFilesFragment().setGridAsPreferred();
                 }
                 break;
@@ -1006,7 +1000,7 @@ public class FileDisplayActivity extends HookActivity
 
     private void revertBottomNavigationBarToAllFiles() {
         if (getResources().getBoolean(R.bool.bottom_toolbar_enabled)) {
-            BottomNavigationView bottomNavigationView = (BottomNavigationView) getListOfFilesFragment().getView()
+            BottomNavigationView bottomNavigationView = getListOfFilesFragment().getView()
                     .findViewById(R.id.bottom_navigation_view);
             if (bottomNavigationView.getMenu().findItem(R.id.nav_bar_settings).isChecked()) {
                 bottomNavigationView.getMenu().findItem(R.id.nav_bar_files).setChecked(true);
@@ -1168,31 +1162,8 @@ public class FileDisplayActivity extends HookActivity
     }
 
     @Override
-    public void onSortingOrderChosen(int selection) {
-        switch (selection) {
-            case SortingOrderDialogFragment.BY_NAME_ASC:
-                sortByName(true);
-                break;
-            case SortingOrderDialogFragment.BY_NAME_DESC:
-                sortByName(false);
-                break;
-            case SortingOrderDialogFragment.BY_MODIFICATION_DATE_ASC:
-                sortByDate(true);
-                break;
-            case SortingOrderDialogFragment.BY_MODIFICATION_DATE_DESC:
-                sortByDate(false);
-                break;
-            case SortingOrderDialogFragment.BY_SIZE_ASC:
-                sortBySize(true);
-                break;
-            case SortingOrderDialogFragment.BY_SIZE_DESC:
-                sortBySize(false);
-                break;
-            default: // defaulting to alphabetical-ascending
-                Log_OC.w(TAG, "Unknown sort order, defaulting to alphabetical-ascending!");
-                sortByName(true);
-                break;
-        }
+    public void onSortingOrderChosen(FileSortOrder selection) {
+        getListOfFilesFragment().sortFiles(selection);
     }
 
     private class SyncBroadcastReceiver extends BroadcastReceiver {
@@ -2179,18 +2150,6 @@ public class FileDisplayActivity extends HookActivity
         }
     }
 
-    private void sortByDate(boolean ascending) {
-        getListOfFilesFragment().sortByDate(ascending);
-    }
-
-    private void sortBySize(boolean ascending) {
-        getListOfFilesFragment().sortBySize(ascending);
-    }
-
-    private void sortByName(boolean ascending) {
-        getListOfFilesFragment().sortByName(ascending);
-    }
-
     private boolean isGridView() {
         return getListOfFilesFragment().isGridEnabled();
     }

+ 22 - 11
src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java

@@ -89,12 +89,13 @@ import com.owncloud.android.ui.adapter.UploaderAdapter;
 import com.owncloud.android.ui.asynctasks.CopyAndUploadContentUrisTask;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
+import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
 import com.owncloud.android.ui.fragment.TaskRetainerFragment;
 import com.owncloud.android.ui.helpers.UriUploader;
 import com.owncloud.android.utils.DataHolderUtil;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ErrorMessageAdapter;
-import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
@@ -111,12 +112,15 @@ import java.util.List;
 import java.util.Stack;
 import java.util.Vector;
 
+import static com.owncloud.android.db.PreferenceManager.getSortOrder;
+
 
 /**
  * This can be used to upload things to an ownCloud instance.
  */
 public class ReceiveExternalFilesActivity extends FileActivity
-        implements OnItemClickListener, View.OnClickListener, CopyAndUploadContentUrisTask.OnCopyTmpFilesTaskListener {
+        implements OnItemClickListener, View.OnClickListener, CopyAndUploadContentUrisTask.OnCopyTmpFilesTaskListener,
+        SortingOrderDialogFragment.OnSortingOrderListener {
 
     private static final String TAG = ReceiveExternalFilesActivity.class.getSimpleName();
 
@@ -235,13 +239,19 @@ public class ReceiveExternalFilesActivity extends FileActivity
     }
 
     @Override
-    protected void onDestroy(){
+    protected void onDestroy() {
         if (mSyncBroadcastReceiver != null) {
             unregisterReceiver(mSyncBroadcastReceiver);
         }
         super.onDestroy();
     }
 
+    @Override
+    public void onSortingOrderChosen(FileSortOrder newSortOrder) {
+        PreferenceManager.setSortOrder(getBaseContext(), mFile, newSortOrder);
+        populateDirectoryList();
+    }
+
     public static class DialogNoAccount extends DialogFragment {
         @NonNull
         @Override
@@ -823,10 +833,8 @@ public class ReceiveExternalFilesActivity extends FileActivity
     }
 
     private Vector<OCFile> sortFileList(Vector<OCFile> files) {
-        // Read sorting order, default to sort by name ascending
-        FileStorageUtils.mSortOrder = PreferenceManager.getSortOrder(this);
-        FileStorageUtils.mSortAscending = PreferenceManager.getSortAscending(this);
-        return FileStorageUtils.sortOcFolder(files);
+        FileSortOrder sortOrder = getSortOrder(this, mFile);
+        return sortOrder.sortCloudFiles(files);
     }
 
     private String generatePath(Stack<String> dirs) {
@@ -1019,9 +1027,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
         switch (item.getItemId()) {
             case R.id.action_create_dir:
                 CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile);
-                dialog.show(
-                        getSupportFragmentManager(),
-                        CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT);
+                dialog.show(getSupportFragmentManager(), CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT);
                 break;
             case android.R.id.home:
                 if ((mParents.size() > 1)) {
@@ -1031,7 +1037,12 @@ public class ReceiveExternalFilesActivity extends FileActivity
             case R.id.action_switch_account:
                 showAccountChooserDialog();
                 break;
-
+            case R.id.action_sort:
+                SortingOrderDialogFragment mSortingOrderDialogFragment = SortingOrderDialogFragment.newInstance(
+                        getSortOrder(this, mFile));
+                mSortingOrderDialogFragment.show(getSupportFragmentManager(),
+                        SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT);
+                break;
             default:
                 retval = super.onOptionsItemSelected(item);
                 break;

+ 6 - 30
src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java

@@ -55,12 +55,12 @@ import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
 import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.fragment.LocalFileListFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
 
-import static com.owncloud.android.db.PreferenceManager.getSortAscending;
 import static com.owncloud.android.db.PreferenceManager.getSortOrder;
 
 
@@ -159,7 +159,7 @@ public class UploadFilesActivity extends FileActivity implements
         int localBehaviour = PreferenceManager.getUploaderBehaviour(this);
 
         // file upload spinner
-        mBehaviourSpinner = (Spinner) findViewById(R.id.upload_files_spinner_behaviour);
+        mBehaviourSpinner = findViewById(R.id.upload_files_spinner_behaviour);
         ArrayAdapter<CharSequence> behaviourAdapter = ArrayAdapter.createFromResource(this,
                 R.array.upload_files_behaviour, android.R.layout.simple_spinner_item);
         behaviourAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -241,9 +241,7 @@ public class UploadFilesActivity extends FileActivity implements
                 ft.addToBackStack(null);
 
                 SortingOrderDialogFragment mSortingOrderDialogFragment = SortingOrderDialogFragment.newInstance(
-                        getSortOrder(this),
-                        getSortAscending(this)
-                );
+                        getSortOrder(this, null));
                 mSortingOrderDialogFragment.show(ft, SORT_ORDER_DIALOG_TAG);
 
                 break;
@@ -258,6 +256,7 @@ public class UploadFilesActivity extends FileActivity implements
                     item.setIcon(R.drawable.ic_view_list);
                     mFileListFragment.switchToGridView();
                 }
+                break;
             }
             default:
                 retval = super.onOptionsItemSelected(item);
@@ -267,31 +266,8 @@ public class UploadFilesActivity extends FileActivity implements
     }
 
     @Override
-    public void onSortingOrderChosen(int selection) {
-        switch (selection) {
-            case SortingOrderDialogFragment.BY_NAME_ASC:
-                mFileListFragment.sortByName(true);
-                break;
-            case SortingOrderDialogFragment.BY_NAME_DESC:
-                mFileListFragment.sortByName(false);
-                break;
-            case SortingOrderDialogFragment.BY_MODIFICATION_DATE_ASC:
-                mFileListFragment.sortByDate(true);
-                break;
-            case SortingOrderDialogFragment.BY_MODIFICATION_DATE_DESC:
-                mFileListFragment.sortByDate(false);
-                break;
-            case SortingOrderDialogFragment.BY_SIZE_ASC:
-                mFileListFragment.sortBySize(true);
-                break;
-            case SortingOrderDialogFragment.BY_SIZE_DESC:
-                mFileListFragment.sortBySize(false);
-                break;
-            default: // defaulting to alphabetical-ascending
-                Log_OC.w(TAG, "Unknown sort order, defaulting to alphabetical-ascending!");
-                mFileListFragment.sortByName(true);
-                break;
-        }
+    public void onSortingOrderChosen(FileSortOrder selection) {
+        mFileListFragment.sortFiles(selection);
     }
     
     @Override

+ 12 - 17
src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java

@@ -64,6 +64,7 @@ import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.ThemeUtils;
@@ -108,10 +109,6 @@ public class FileListListAdapter extends BaseAdapter {
 
         mTransferServiceGetter = transferServiceGetter;
 
-        // Read sorting order, default to sort by name ascending
-        FileStorageUtils.mSortOrder = PreferenceManager.getSortOrder(mContext);
-        FileStorageUtils.mSortAscending = PreferenceManager.getSortAscending(mContext);
-
         // initialise thumbnails cache on background thread
         new ThumbnailsCacheManager.InitDiskCacheTask().execute();
     }
@@ -482,7 +479,8 @@ public class FileListListAdapter extends BaseAdapter {
             if (!PreferenceManager.showHiddenFilesEnabled(mContext)) {
                 mFiles = filterHiddenFiles(mFiles);
             }
-            mFiles = FileStorageUtils.sortOcFolder(mFiles);
+            FileSortOrder sortOrder = PreferenceManager.getSortOrder(mContext, directory);
+            mFiles = sortOrder.sortCloudFiles(mFiles);
             mFilesAll.clear();
             mFilesAll.addAll(mFiles);
 
@@ -505,7 +503,8 @@ public class FileListListAdapter extends BaseAdapter {
         }
     }
 
-    public void setData(ArrayList<Object> objects, ExtendedListFragment.SearchType searchType, FileDataStorageManager storageManager) {
+    public void setData(ArrayList<Object> objects, ExtendedListFragment.SearchType searchType,
+                        FileDataStorageManager storageManager, OCFile folder) {
         if (storageManager != null && mStorageManager == null) {
             mStorageManager = storageManager;
         }
@@ -524,7 +523,8 @@ public class FileListListAdapter extends BaseAdapter {
                 !searchType.equals(ExtendedListFragment.SearchType.PHOTOS_SEARCH_FILTER) &&
                 !searchType.equals(ExtendedListFragment.SearchType.RECENTLY_MODIFIED_SEARCH) &&
                 !searchType.equals(ExtendedListFragment.SearchType.RECENTLY_MODIFIED_SEARCH_FILTER)) {
-            mFiles = FileStorageUtils.sortOcFolder(mFiles);
+            FileSortOrder sortOrder = PreferenceManager.getSortOrder(mContext, folder);
+            mFiles = sortOrder.sortCloudFiles(mFiles);
         } else {
             mFiles = FileStorageUtils.sortOcFolderDescDateModified(mFiles);
         }
@@ -642,15 +642,9 @@ public class FileListListAdapter extends BaseAdapter {
     }
 
 
-    public void setSortOrder(Integer order, boolean ascending) {
-
-        PreferenceManager.setSortOrder(mContext, order);
-        PreferenceManager.setSortAscending(mContext, ascending);
-
-        FileStorageUtils.mSortOrder = order;
-        FileStorageUtils.mSortAscending = ascending;
-
-        mFiles = FileStorageUtils.sortOcFolder(mFiles);
+    public void setSortOrder(OCFile folder, FileSortOrder sortOrder) {
+        PreferenceManager.setSortOrder(mContext, folder, sortOrder);
+        mFiles = sortOrder.sortCloudFiles(mFiles);
         notifyDataSetChanged();
     }
 
@@ -714,7 +708,8 @@ public class FileListListAdapter extends BaseAdapter {
                 if (!PreferenceManager.showHiddenFilesEnabled(mContext)) {
                     mFiles = filterHiddenFiles(mFiles);
                 }
-                mFiles = FileStorageUtils.sortOcFolder(mFiles);
+                FileSortOrder sortOrder = PreferenceManager.getSortOrder(mContext, null);
+                mFiles = sortOrder.sortCloudFiles(mFiles);
             }
 
             notifyDataSetChanged();

+ 6 - 15
src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java

@@ -37,7 +37,7 @@ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.db.PreferenceManager;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.MimeTypeUtil;
 
 import java.io.File;
@@ -65,11 +65,6 @@ public class LocalFileListAdapter extends BaseAdapter implements FilterableListA
     public LocalFileListAdapter(boolean localFolderPickerMode, File directory, Context context) {
         mContext = context;
         mLocalFolderPicker = localFolderPickerMode;
-
-        // Read sorting order, default to sort by name ascending
-        FileStorageUtils.mSortOrder = PreferenceManager.getSortOrder(context);
-        FileStorageUtils.mSortAscending =PreferenceManager.getSortAscending(context);
-
         swapDirectory(directory);
     }
 
@@ -298,7 +293,8 @@ public class LocalFileListAdapter extends BaseAdapter implements FilterableListA
                 }
             });
 
-            mFiles = FileStorageUtils.sortLocalFolder(mFiles);
+            FileSortOrder sortOrder = PreferenceManager.getSortOrder(mContext, null);
+            mFiles = sortOrder.sortLocalFiles(mFiles);
 
             // Fetch preferences for showing hidden files
             boolean showHiddenFiles = PreferenceManager.showHiddenFilesEnabled(mContext);
@@ -313,14 +309,9 @@ public class LocalFileListAdapter extends BaseAdapter implements FilterableListA
         notifyDataSetChanged();
     }
 
-    public void setSortOrder(Integer order, boolean ascending) {
-        PreferenceManager.setSortOrder(mContext, order);
-        PreferenceManager.setSortAscending(mContext, ascending);
-
-        FileStorageUtils.mSortOrder = order;
-        FileStorageUtils.mSortAscending = ascending;
-
-        mFiles = FileStorageUtils.sortLocalFolder(mFiles);
+    public void setSortOrder(FileSortOrder sortOrder) {
+        PreferenceManager.setSortOrder(mContext, null, sortOrder);
+        mFiles = sortOrder.sortLocalFiles(mFiles);
         notifyDataSetChanged();
     }
 

+ 53 - 129
src/main/java/com/owncloud/android/ui/dialog/SortingOrderDialogFragment.java

@@ -1,4 +1,4 @@
-/**
+/*
  * Nextcloud Android client application
  *
  * @author Andy Scherzinger
@@ -35,6 +35,7 @@ import android.widget.TextView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.ThemeUtils;
 
 /**
@@ -44,41 +45,19 @@ public class SortingOrderDialogFragment extends DialogFragment {
 
     private final static String TAG = SortingOrderDialogFragment.class.getSimpleName();
 
+    public static final String SORTING_ORDER_FRAGMENT = "SORTING_ORDER_FRAGMENT";
     private static final String KEY_SORT_ORDER = "SORT_ORDER";
-    private static final String KEY_ASCENDING = "ASCENDING";
-
-    public static final int BY_NAME_ASC = 0;
-    public static final int BY_NAME_DESC = 1;
-    public static final int BY_MODIFICATION_DATE_ASC = 2;
-    public static final int BY_MODIFICATION_DATE_DESC = 3;
-    public static final int BY_SIZE_ASC = 4;
-    public static final int BY_SIZE_DESC = 5;
 
     private View mView = null;
-    private ImageButton mSortByNameAscendingButton = null;
-    private ImageButton mSortByNameDescendingButton = null;
-    private ImageButton mSortBySizeAscendingButton = null;
-    private ImageButton mSortBySizeDescendingButton = null;
-    private ImageButton mSortByModificationDateAscendingButton = null;
-    private ImageButton mSortByModificationDateDescendingButton = null;
-
-    private TextView mSortByNameAscendingText = null;
-    private TextView mSortByNameDescendingText = null;
-    private TextView mSortBySizeAscendingText = null;
-    private TextView mSortBySizeDescendingText = null;
-    private TextView mSortByModificationDateAscendingText = null;
-    private TextView mSortByModificationDateDescendingText = null;
-
-    private int mSortOrder;
-    private boolean mSortAscending;
+    private View[] mTaggedViews;
     private AppCompatButton mCancel;
+    private String mCurrentSortOrderName;
 
-    public static SortingOrderDialogFragment newInstance(int sortOrder, boolean ascending) {
+    public static SortingOrderDialogFragment newInstance(FileSortOrder sortOrder) {
         SortingOrderDialogFragment dialogFragment = new SortingOrderDialogFragment();
 
         Bundle args = new Bundle();
-        args.putInt(KEY_SORT_ORDER, sortOrder);
-        args.putBoolean(KEY_ASCENDING, ascending);
+        args.putString(KEY_SORT_ORDER, sortOrder.mName);
         dialogFragment.setArguments(args);
 
         dialogFragment.setStyle(STYLE_NORMAL, R.style.Theme_ownCloud_Dialog);
@@ -93,9 +72,7 @@ public class SortingOrderDialogFragment extends DialogFragment {
         setRetainInstance(true);
 
         mView = null;
-
-        mSortOrder = getArguments().getInt(KEY_SORT_ORDER, BY_NAME_ASC);
-        mSortAscending = getArguments().getBoolean(KEY_ASCENDING, true);
+        mCurrentSortOrderName = getArguments().getString(KEY_SORT_ORDER, FileSortOrder.sort_a_to_z.mName);
     }
 
     @Override
@@ -116,36 +93,34 @@ public class SortingOrderDialogFragment extends DialogFragment {
      * @param view the parent view
      */
     private void setupDialogElements(View view) {
-        // find/saves UI elements
-        mSortByNameAscendingButton = (ImageButton) view.findViewById(R.id.sortByNameAscending);
-        mSortByNameDescendingButton = (ImageButton) view.findViewById(R.id.sortByNameDescending);
-        mSortByModificationDateAscendingButton = (ImageButton) view.findViewById(R.id.sortByModificationDateAscending);
-        mSortByModificationDateDescendingButton = (ImageButton) view.findViewById(R.id.sortByModificationDateDescending);
-        mSortBySizeAscendingButton = (ImageButton) view.findViewById(R.id.sortBySizeAscending);
-        mSortBySizeDescendingButton = (ImageButton) view.findViewById(R.id.sortBySizeDescending);
-        mCancel = (AppCompatButton) view.findViewById(R.id.cancel);
+        mCancel = view.findViewById(R.id.cancel);
         mCancel.setTextColor(ThemeUtils.primaryAccentColor());
 
-        mSortByNameAscendingText = (TextView) view.findViewById(R.id.sortByNameAZText);
-        mSortByNameDescendingText = (TextView) view.findViewById(R.id.sortByNameZAText);
-        mSortByModificationDateAscendingText = (TextView) view.findViewById(R.id.sortByModificationDateOldestFirstText);
-        mSortByModificationDateDescendingText = (TextView) view.findViewById(R.id.sortByModificationDateNewestFirstText);
-        mSortBySizeAscendingText = (TextView) view.findViewById(R.id.sortBySizeSmallestFirstText);
-        mSortBySizeDescendingText = (TextView) view.findViewById(R.id.sortBySizeBiggestFirstText);
-
-        mSortByNameAscendingButton.setTag(BY_NAME_ASC);
-        mSortByNameDescendingButton.setTag(BY_NAME_DESC);
-        mSortByModificationDateAscendingButton.setTag(BY_MODIFICATION_DATE_ASC);
-        mSortByModificationDateDescendingButton.setTag(BY_MODIFICATION_DATE_DESC);
-        mSortBySizeAscendingButton.setTag(BY_SIZE_ASC);
-        mSortBySizeDescendingButton.setTag(BY_SIZE_DESC);
-
-        mSortByNameAscendingText.setTag(BY_NAME_ASC);
-        mSortByNameDescendingText.setTag(BY_NAME_DESC);
-        mSortByModificationDateAscendingText.setTag(BY_MODIFICATION_DATE_ASC);
-        mSortByModificationDateDescendingText.setTag(BY_MODIFICATION_DATE_DESC);
-        mSortBySizeAscendingText.setTag(BY_SIZE_ASC);
-        mSortBySizeDescendingText.setTag(BY_SIZE_DESC);
+        mTaggedViews = new View[12];
+        mTaggedViews[0] = view.findViewById(R.id.sortByNameAscending);
+        mTaggedViews[0].setTag(FileSortOrder.sort_a_to_z);
+        mTaggedViews[1] = view.findViewById(R.id.sortByNameAZText);
+        mTaggedViews[1].setTag(FileSortOrder.sort_a_to_z);
+        mTaggedViews[2] = view.findViewById(R.id.sortByNameDescending);
+        mTaggedViews[2].setTag(FileSortOrder.sort_z_to_a);
+        mTaggedViews[3] = view.findViewById(R.id.sortByNameZAText);
+        mTaggedViews[3].setTag(FileSortOrder.sort_z_to_a);
+        mTaggedViews[4] = view.findViewById(R.id.sortByModificationDateAscending);
+        mTaggedViews[4].setTag(FileSortOrder.sort_old_to_new);
+        mTaggedViews[5] = view.findViewById(R.id.sortByModificationDateOldestFirstText);
+        mTaggedViews[5].setTag(FileSortOrder.sort_old_to_new);
+        mTaggedViews[6] = view.findViewById(R.id.sortByModificationDateDescending);
+        mTaggedViews[6].setTag(FileSortOrder.sort_new_to_old);
+        mTaggedViews[7] = view.findViewById(R.id.sortByModificationDateNewestFirstText);
+        mTaggedViews[7].setTag(FileSortOrder.sort_new_to_old);
+        mTaggedViews[8] = view.findViewById(R.id.sortBySizeAscending);
+        mTaggedViews[8].setTag(FileSortOrder.sort_small_to_big);
+        mTaggedViews[9] = view.findViewById(R.id.sortBySizeSmallestFirstText);
+        mTaggedViews[9].setTag(FileSortOrder.sort_small_to_big);
+        mTaggedViews[10] = view.findViewById(R.id.sortBySizeDescending);
+        mTaggedViews[10].setTag(FileSortOrder.sort_big_to_small);
+        mTaggedViews[11] = view.findViewById(R.id.sortBySizeBiggestFirstText);
+        mTaggedViews[11].setTag(FileSortOrder.sort_big_to_small);
 
         setupActiveOrderSelection();
     }
@@ -154,84 +129,32 @@ public class SortingOrderDialogFragment extends DialogFragment {
      * tints the icon reflecting the actual sorting choice in the apps primary color.
      */
     private void setupActiveOrderSelection() {
-        if (mSortAscending) {
-            switch (mSortOrder) {
-                case 0:
-                    colorActiveSortingIconAndText(mSortByNameAscendingButton,
-                            mSortByNameAscendingText);
-                    break;
-                case 1:
-                    colorActiveSortingIconAndText(mSortByModificationDateAscendingButton,
-                            mSortByModificationDateAscendingText);
-                    break;
-                case 2:
-                    colorActiveSortingIconAndText(mSortBySizeAscendingButton,
-                            mSortBySizeAscendingText);
-                    break;
-                default: //do nothing
-                    Log_OC.w(TAG, "Unknown sort order " + mSortOrder);
-                    break;
+        final int color = ThemeUtils.primaryAccentColor();
+        for (View view: mTaggedViews) {
+            if (!((FileSortOrder)view.getTag()).mName.equals(mCurrentSortOrderName)) {
+                continue;
+            }
+            if (view instanceof ImageButton) {
+                ThemeUtils.colorImageButton((ImageButton)view, color);
             }
-        } else {
-            switch (mSortOrder) {
-                case 0:
-                    colorActiveSortingIconAndText(mSortByNameDescendingButton,
-                            mSortByNameDescendingText);
-                    break;
-                case 1:
-                    colorActiveSortingIconAndText(mSortByModificationDateDescendingButton,
-                            mSortByModificationDateDescendingText);
-                    break;
-                case 2:
-                    colorActiveSortingIconAndText(mSortBySizeDescendingButton,
-                            mSortBySizeDescendingText);
-                    break;
-                default: //do nothing
-                    Log_OC.w(TAG, "Unknown sort order " + mSortOrder);
-                    break;
+            if (view instanceof TextView) {
+                ((TextView)view).setTextColor(color);
+                ((TextView)view).setTypeface(Typeface.DEFAULT_BOLD);
             }
         }
     }
 
-    /**
-     * Sets the text color and tint the icon of given text view and image button.
-     *
-     * @param imageButton the image button, the icon to be tinted
-     * @param textView    the text view, the text color to be set
-     */
-    private void colorActiveSortingIconAndText(ImageButton imageButton, TextView textView) {
-        int color = ThemeUtils.primaryAccentColor();
-        ThemeUtils.colorImageButton(imageButton, color);
-        textView.setTextColor(color);
-        textView.setTypeface(Typeface.DEFAULT_BOLD);
-    }
-
     /**
      * setup all listeners.
      */
     private void setupListeners() {
-        mCancel.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                dismiss();
-            }
-        });
+        mCancel.setOnClickListener(view -> dismiss());
 
-        OnSortingOrderClickListener sortingClickListener = new OnSortingOrderClickListener();
+        OnSortOrderClickListener sortOrderClickListener = new OnSortOrderClickListener();
 
-        mSortByNameAscendingButton.setOnClickListener(sortingClickListener);
-        mSortByNameDescendingButton.setOnClickListener(sortingClickListener);
-        mSortByModificationDateAscendingButton.setOnClickListener(sortingClickListener);
-        mSortByModificationDateDescendingButton.setOnClickListener(sortingClickListener);
-        mSortBySizeAscendingButton.setOnClickListener(sortingClickListener);
-        mSortBySizeDescendingButton.setOnClickListener(sortingClickListener);
-
-        mSortByNameAscendingText.setOnClickListener(sortingClickListener);
-        mSortByNameDescendingText.setOnClickListener(sortingClickListener);
-        mSortByModificationDateAscendingText.setOnClickListener(sortingClickListener);
-        mSortByModificationDateDescendingText.setOnClickListener(sortingClickListener);
-        mSortBySizeAscendingText.setOnClickListener(sortingClickListener);
-        mSortBySizeDescendingText.setOnClickListener(sortingClickListener);
+        for (View view : mTaggedViews) {
+            view.setOnClickListener(sortOrderClickListener);
+        }
     }
 
     @Override
@@ -249,15 +172,16 @@ public class SortingOrderDialogFragment extends DialogFragment {
         super.onDestroyView();
     }
 
-    private class OnSortingOrderClickListener implements View.OnClickListener {
+    private class OnSortOrderClickListener implements View.OnClickListener {
         @Override
         public void onClick(View v) {
             dismissAllowingStateLoss();
-            ((SortingOrderDialogFragment.OnSortingOrderListener) getActivity()).onSortingOrderChosen((int) v.getTag());
+            ((SortingOrderDialogFragment.OnSortingOrderListener) getActivity())
+                    .onSortingOrderChosen((FileSortOrder) v.getTag());
         }
     }
 
     public interface OnSortingOrderListener {
-        void onSortingOrderChosen(int selection);
+        void onSortingOrderChosen(FileSortOrder selection);
     }
 }

+ 3 - 11
src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java

@@ -39,7 +39,7 @@ 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.AnalyticsUtils;
-import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.ThemeUtils;
 
 import java.io.File;
@@ -284,16 +284,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
         return result.toArray(new String[result.size()]);
     }
 
-    public void sortByName(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
-    }
-
-    public void sortByDate(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_DATE, descending);
-    }
-
-    public void sortBySize(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
+    public void sortFiles(FileSortOrder sortOrder) {
+        mAdapter.setSortOrder(sortOrder);
     }
 
     /**

+ 24 - 91
src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author Bartek Przybylski
@@ -28,13 +28,11 @@ import android.accounts.OperationCanceledException;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.preference.PreferenceManager;
 import android.support.annotation.Nullable;
 import android.support.annotation.StringRes;
 import android.support.design.widget.BottomNavigationView;
@@ -63,6 +61,7 @@ import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.VirtualFolderType;
+import com.owncloud.android.db.PreferenceManager;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudClient;
@@ -95,7 +94,7 @@ import com.owncloud.android.ui.preview.PreviewMediaFragment;
 import com.owncloud.android.ui.preview.PreviewTextFragment;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.ThemeUtils;
 
@@ -130,15 +129,15 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
     public static final String DOWNLOAD_BEHAVIOUR = "DOWNLOAD_BEHAVIOUR";
     public static final String DOWNLOAD_SEND = "DOWNLOAD_SEND";
 
+    public static final String FOLDER_LAYOUT_LIST = "LIST";
+    public static final String FOLDER_LAYOUT_GRID = "GRID";
+
     public static final String SEARCH_EVENT = "SEARCH_EVENT";
 
     private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE";
-    private static final String KEY_FAB_EVER_CLICKED = "FAB_EVER_CLICKED";
 
     private static final String KEY_CURRENT_SEARCH_TYPE = "CURRENT_SEARCH_TYPE";
 
-    private static final String GRID_IS_PREFERED_PREFERENCE = "gridIsPrefered";
-
     private static final String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
 
     private static final String SCREEN_NAME = "Remote/Server file browser";
@@ -325,8 +324,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
             registerFabListeners();
 
             // detect if a mini FAB has ever been clicked
-            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
-            if (prefs.getLong(KEY_FAB_EVER_CLICKED, 0) > 0) {
+            if (PreferenceManager.getFABClicked(getActivity()) > 0) {
                 miniFabClicked = true;
             }
 
@@ -488,8 +486,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
     private void recordMiniFabClick() {
         // only record if it hasn't been done already at some other time
         if (!miniFabClicked) {
-            final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
-            sp.edit().putLong(KEY_FAB_EVER_CLICKED, 1).apply();
+            PreferenceManager.setFABClicked(getActivity());
             miniFabClicked = true;
         }
     }
@@ -1100,7 +1097,8 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
                             if ((activity = getActivity()) != null && activity instanceof FileDisplayActivity) {
                                 FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) activity;
                                 if (getCurrentFile() != null) {
-                                    fileDisplayActivity.setDrawerIndicatorEnabled(fileDisplayActivity.isRoot(getCurrentFile()));
+                                    fileDisplayActivity.setDrawerIndicatorEnabled(
+                                            fileDisplayActivity.isRoot(getCurrentFile()));
                                 }
                             }
 
@@ -1198,71 +1196,29 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
         return output;
     }
 
-    public void sortByName(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
-    }
-
-    public void sortByDate(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_DATE, descending);
-    }
-
-    public void sortBySize(boolean descending) {
-        mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
+    public void sortFiles(FileSortOrder sortOrder) {
+        mAdapter.setSortOrder(mFile, sortOrder);
     }
 
     /**
      * Determines if user set folder to grid or list view. If folder is not set itself,
      * it finds a parent that is set (at least root is set).
      *
-     * @param file Folder to check.
+     * @param folder Folder to check.
      * @return 'true' is folder should be shown in grid mode, 'false' if list mode is preferred.
      */
-    public boolean isGridViewPreferred(OCFile file) {
-        if (file != null) {
-            OCFile fileToTest = file;
-            OCFile parentDir;
-            String parentPath = null;
-            FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
-
-            SharedPreferences setting =
-                    getActivity().getSharedPreferences(
-                            GRID_IS_PREFERED_PREFERENCE, Context.MODE_PRIVATE
-                    );
-
-            if (setting.contains(String.valueOf(fileToTest.getFileId()))) {
-                return setting.getBoolean(String.valueOf(fileToTest.getFileId()), false);
-            } else {
-                do {
-                    if (fileToTest.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {
-                        parentPath = new File(fileToTest.getRemotePath()).getParent();
-                        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
-                                parentPath + OCFile.PATH_SEPARATOR;
-                        parentDir = storageManager.getFileByPath(parentPath);
-                    } else {
-                        parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH);
-                    }
+    public boolean isGridViewPreferred(OCFile folder) {
+        return PreferenceManager.getFolderLayout(getActivity(), folder).equals(FOLDER_LAYOUT_GRID);
+    }
 
-                    while (parentDir == null) {
-                        parentPath = new File(parentPath).getParent();
-                        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
-                                parentPath + OCFile.PATH_SEPARATOR;
-                        parentDir = storageManager.getFileByPath(parentPath);
-                    }
-                    fileToTest = parentDir;
-                } while (endWhile(parentDir, setting));
-                return setting.getBoolean(String.valueOf(fileToTest.getFileId()), false);
-            }
-        } else {
-            return false;
-        }
+    public void setListAsPreferred() {
+        PreferenceManager.setFolderLayout(getActivity(), mFile, FOLDER_LAYOUT_LIST);
+        switchToListView();
     }
 
-    private boolean endWhile(OCFile parentDir, SharedPreferences setting) {
-        if (parentDir.getRemotePath().compareToIgnoreCase(OCFile.ROOT_PATH) == 0) {
-            return false;
-        } else {
-            return !setting.contains(String.valueOf(parentDir.getFileId()));
-        }
+    public void setGridAsPreferred() {
+        PreferenceManager.setFolderLayout(getActivity(), mFile, FOLDER_LAYOUT_GRID);
+        switchToGridView();
     }
 
     private void changeGridIcon(Menu menu) {
@@ -1278,29 +1234,6 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
         }
     }
 
-    public void setListAsPreferred() {
-        saveGridAsPreferred(false);
-        switchToListView();
-    }
-
-    public void setGridAsPreferred() {
-        saveGridAsPreferred(true);
-        switchToGridView();
-    }
-
-    private void saveGridAsPreferred(boolean setGrid) {
-        SharedPreferences setting = getActivity().getSharedPreferences(
-                GRID_IS_PREFERED_PREFERENCE, Context.MODE_PRIVATE
-        );
-
-        // can be in case of favorites, shared
-        if (mFile != null) {
-            SharedPreferences.Editor editor = setting.edit();
-            editor.putBoolean(String.valueOf(mFile.getFileId()), setGrid);
-            editor.apply();
-        }
-    }
-
     private void unsetAllMenuItems(final boolean unsetDrawer) {
         new Handler(Looper.getMainLooper()).post(new Runnable() {
             @Override
@@ -1463,7 +1396,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
     public void onMessageEvent(final SearchEvent event) {
         searchFragment = true;
         setEmptyListLoadingMessage();
-        mAdapter.setData(new ArrayList<>(), SearchType.NO_SEARCH, mContainerActivity.getStorageManager());
+        mAdapter.setData(new ArrayList<>(), SearchType.NO_SEARCH, mContainerActivity.getStorageManager(), mFile);
 
         setFabEnabled(false);
 
@@ -1539,7 +1472,7 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
                         if (remoteOperationResult.getData() == null || remoteOperationResult.getData().size() == 0) {
                             setEmptyView(event);
                         } else {
-                            mAdapter.setData(remoteOperationResult.getData(), currentSearchType, storageManager);
+                            mAdapter.setData(remoteOperationResult.getData(), currentSearchType, storageManager, mFile);
                         }
 
                         final FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity();

+ 2 - 3
src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java

@@ -29,6 +29,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.VirtualFolderType;
 import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.utils.FileSortOrderByName;
 import com.owncloud.android.utils.FileStorageUtils;
 
 import java.util.HashMap;
@@ -79,9 +80,7 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
         mAccount = account;
         mStorageManager = storageManager;
         mImageFiles = mStorageManager.getFolderImages(parentFolder, onlyOnDevice);
-        
-        mImageFiles = FileStorageUtils.sortOcFolder(mImageFiles);
-        
+        mImageFiles = FileSortOrderByName.sort_a_to_z.sortCloudFiles(mImageFiles);
         mObsoleteFragments = new HashSet<Object>();
         mObsoletePositions = new HashSet<Integer>();
         mDownloadErrors = new HashSet<Integer>();

+ 92 - 0
src/main/java/com/owncloud/android/utils/FileSortOrder.java

@@ -0,0 +1,92 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.utils;
+
+import com.owncloud.android.datamodel.OCFile;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * Sort order 
+ */
+
+public class FileSortOrder {
+    public static final FileSortOrder sort_a_to_z = new FileSortOrderByName("sort_a_to_z", true);
+    public static final FileSortOrder sort_z_to_a = new FileSortOrderByName("sort_z_to_a", false);
+    public static final FileSortOrder sort_old_to_new = new FileSortOrderByDate("sort_old_to_new", true);
+    public static final FileSortOrder sort_new_to_old = new FileSortOrderByDate("sort_new_to_old", false);
+    public static final FileSortOrder sort_small_to_big = new FileSortOrderBySize("sort_small_to_big", true);
+    public static final FileSortOrder sort_big_to_small = new FileSortOrderBySize("sort_big_to_small", false);
+
+    public static final Map<String, FileSortOrder> sortOrders;
+    static {
+        sortOrders = new HashMap<String, FileSortOrder>();
+        sortOrders.put(sort_a_to_z.mName, sort_a_to_z);
+        sortOrders.put(sort_z_to_a.mName, sort_z_to_a);
+        sortOrders.put(sort_old_to_new.mName, sort_old_to_new);
+        sortOrders.put(sort_new_to_old.mName, sort_new_to_old);
+        sortOrders.put(sort_small_to_big.mName, sort_small_to_big);
+        sortOrders.put(sort_big_to_small.mName, sort_big_to_small);
+    }
+
+    public String mName;
+    public boolean mAscending;
+
+    public FileSortOrder(String name, boolean ascending) {
+        mName = name;
+        mAscending = ascending;
+    }
+
+    public Vector<OCFile> sortCloudFiles(Vector<OCFile> files) {
+        return sortCloudFilesByFavourite(files);
+    }
+
+    public File[] sortLocalFiles(File[] files) {
+        return files;
+    }
+
+    /**
+     * Sorts list by Favourites.
+     *
+     * @param files files to sort
+     */
+    public static Vector<OCFile> sortCloudFilesByFavourite(Vector<OCFile> files) {
+        Collections.sort(files, new Comparator<OCFile>() {
+            public int compare(OCFile o1, OCFile o2) {
+                if (o1.getIsFavorite() && o2.getIsFavorite()) {
+                    return 0;
+                } else if (o1.getIsFavorite()) {
+                    return -1;
+                } else if (o2.getIsFavorite()) {
+                    return 1;
+                }
+                return 0;
+            }
+        });
+
+        return files;
+    }
+}

+ 85 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderByDate.java

@@ -0,0 +1,85 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.utils;
+
+import com.owncloud.android.datamodel.OCFile;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Vector;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Created by srkunze on 28.08.17.
+ */
+
+public class FileSortOrderByDate extends FileSortOrder {
+
+    public FileSortOrderByDate(String name, boolean ascending) {
+        super(name, ascending);
+    }
+
+    /**
+     * Sorts list by Date.
+     *
+     * @param files list of files to sort
+     */
+    public Vector<OCFile> sortCloudFiles(Vector<OCFile> files) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        Collections.sort(files, new Comparator<OCFile>() {
+            @SuppressFBWarnings(value = "Bx", justification = "Would require stepping up API level")
+            public int compare(OCFile o1, OCFile o2) {
+                Long obj1 = o1.getModificationTimestamp();
+                return multiplier * obj1.compareTo(o2.getModificationTimestamp());
+            }
+        });
+
+        return super.sortCloudFiles(files);
+    }
+
+    /**
+     * Sorts list by Date.
+     *
+     * @param filesArray list of files to sort
+     */
+    public File[] sortLocalFiles(File[] filesArray) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+
+        Collections.sort(files, new Comparator<File>() {
+            @SuppressFBWarnings(value = "Bx")
+            public int compare(File o1, File o2) {
+                Long obj1 = o1.lastModified();
+                return multiplier * obj1.compareTo(o2.lastModified());
+            }
+        });
+
+        File[] returnArray = new File[files.size()];
+        return files.toArray(returnArray);
+    }
+}

+ 98 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderByName.java

@@ -0,0 +1,98 @@
+/**
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.utils;
+
+import com.owncloud.android.datamodel.OCFile;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Vector;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import third_parties.daveKoeller.AlphanumComparator;
+
+/**
+ * Created by srkunze on 28.08.17.
+ */
+
+public class FileSortOrderByName extends FileSortOrder {
+
+    public FileSortOrderByName(String name, boolean ascending) {
+        super(name, ascending);
+    }
+
+    /**
+     * Sorts list by Name.
+     *
+     * @param files files to sort
+     */
+    @SuppressFBWarnings(value = "Bx")
+    public Vector<OCFile> sortCloudFiles(Vector<OCFile> files) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        Collections.sort(files, new Comparator<OCFile>() {
+            public int compare(OCFile o1, OCFile o2) {
+                if (o1.isFolder() && o2.isFolder()) {
+                    return multiplier * new AlphanumComparator().compare(o1, o2);
+                } else if (o1.isFolder()) {
+                    return -1;
+                } else if (o2.isFolder()) {
+                    return 1;
+                }
+                return multiplier * new AlphanumComparator().compare(o1, o2);
+            }
+        });
+
+        return super.sortCloudFiles(files);
+    }
+
+    /**
+     * Sorts list by Name.
+     *
+     * @param filesArray files to sort
+     */
+    public File[] sortLocalFiles(File[] filesArray) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+
+        Collections.sort(files, new Comparator<File>() {
+            public int compare(File o1, File o2) {
+                if (o1.isDirectory() && o2.isDirectory()) {
+                    return multiplier * o1.getPath().toLowerCase().compareTo(o2.getPath().toLowerCase());
+                } else if (o1.isDirectory()) {
+                    return -1;
+                } else if (o2.isDirectory()) {
+                    return 1;
+                }
+                return multiplier * new AlphanumComparator().compare(o1.getPath().toLowerCase(),
+                        o2.getPath().toLowerCase());
+            }
+        });
+
+        File[] returnArray = new File[files.size()];
+        return files.toArray(returnArray);
+    }
+}

+ 105 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderBySize.java

@@ -0,0 +1,105 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.utils;
+
+import com.owncloud.android.datamodel.OCFile;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Vector;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Sorts files by sizes
+ */
+
+public class FileSortOrderBySize extends FileSortOrder {
+
+    public FileSortOrderBySize(String name, boolean ascending) {
+        super(name, ascending);
+    }
+
+    /**
+     * Sorts list by Size.
+     *
+     * @param files list of files to sort
+     */
+    public Vector<OCFile> sortCloudFiles(Vector<OCFile> files) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        Collections.sort(files, new Comparator<OCFile>() {
+            @SuppressFBWarnings(value = "Bx")
+            public int compare(OCFile o1, OCFile o2) {
+                if (o1.isFolder() && o2.isFolder()) {
+                    Long obj1 = o1.getFileLength();
+                    return multiplier * obj1.compareTo(o2.getFileLength());
+                } else if (o1.isFolder()) {
+                    return -1;
+
+                } else if (o2.isFolder()) {
+                    return 1;
+                } else {
+                    Long obj1 = o1.getFileLength();
+                    return multiplier * obj1.compareTo(o2.getFileLength());
+                }
+            }
+        });
+
+        return super.sortCloudFiles(files);
+    }
+
+    /**
+     * Sorts list by Size.
+     *
+     * @param filesArray list of files to sort
+     */
+    public File[] sortLocalFiles(File[] filesArray) {
+        final int multiplier = mAscending ? 1 : -1;
+
+        List<File> files = new ArrayList<>(Arrays.asList(filesArray));
+
+        Collections.sort(files, new Comparator<File>() {
+            @SuppressFBWarnings(value = "Bx")
+            public int compare(File o1, File o2) {
+                if (o1.isDirectory() && o2.isDirectory()) {
+                    Long obj1 = FileStorageUtils.getFolderSize(o1);
+                    return multiplier * obj1.compareTo(FileStorageUtils.getFolderSize(o2));
+                } else if (o1.isDirectory()) {
+                    return -1;
+                } else if (o2.isDirectory()) {
+                    return 1;
+                } else {
+                    Long obj1 = o1.length();
+                    return multiplier * obj1.compareTo(o2.length());
+                }
+            }
+        });
+
+        File[] returnArray = new File[files.size()];
+        return files.toArray(returnArray);
+    }
+
+}

+ 1 - 228
src/main/java/com/owncloud/android/utils/FileStorageUtils.java

@@ -42,18 +42,14 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
-import java.util.List;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.Vector;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import third_parties.daveKoeller.AlphanumComparator;
 
 
 /**
@@ -62,12 +58,7 @@ import third_parties.daveKoeller.AlphanumComparator;
 public class FileStorageUtils {
     private static final String TAG = FileStorageUtils.class.getSimpleName();
 
-    public static final Integer SORT_NAME = 0;
-    public static final Integer SORT_DATE = 1;
-    public static final Integer SORT_SIZE = 2;
     public static final String PATTERN_YYYY_MM = "yyyy/MM/";
-    public static Integer mSortOrder = SORT_NAME;
-    public static Boolean mSortAscending = true;
 
     /**
      * Get local owncloud storage path for accountName.
@@ -258,227 +249,9 @@ public class FileStorageUtils {
             }
         });
 
-        return sortOCFilesByFavourite(files);
+        return FileSortOrder.sortCloudFilesByFavourite(files);
     }
 
-    /**
-     * Sorts all filenames, regarding last user decision 
-     */
-    public static Vector<OCFile> sortOcFolder(Vector<OCFile> files) {
-        switch (mSortOrder) {
-            case 0:
-                files = FileStorageUtils.sortOCFilesByName(files);
-                break;
-            case 1:
-                files = FileStorageUtils.sortOCFilesByDate(files);
-                break;
-            case 2:
-                files = FileStorageUtils.sortOCFilesBySize(files);
-                break;
-        }
-
-        files = FileStorageUtils.sortOCFilesByFavourite(files);
-
-        return files;
-    }
-
-    /**
-     * Sorts all filenames, regarding last user decision.
-     *
-     * @param files of files to sort
-     */
-    public static File[] sortLocalFolder(File[] files) {
-        switch (mSortOrder) {
-            case 0:
-                files = FileStorageUtils.sortLocalFilesByName(files);
-                break;
-            case 1:
-                files = FileStorageUtils.sortLocalFilesByDate(files);
-                break;
-            case 2:
-                files = FileStorageUtils.sortLocalFilesBySize(files);
-                break;
-        }
-
-        return files;
-    }
-
-    /**
-     * Sorts list by Date.
-     *
-     * @param files list of files to sort
-     */
-    public static Vector<OCFile> sortOCFilesByDate(Vector<OCFile> files) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        Collections.sort(files, new Comparator<OCFile>() {
-            @SuppressFBWarnings(value = "Bx", justification = "Would require stepping up API level")
-            public int compare(OCFile o1, OCFile o2) {
-                Long obj1 = o1.getModificationTimestamp();
-                return multiplier * obj1.compareTo(o2.getModificationTimestamp());
-            }
-        });
-
-        return files;
-    }
-
-    /**
-     * Sorts list by Date.
-     *
-     * @param filesArray list of files to sort
-     */
-    public static File[] sortLocalFilesByDate(File[] filesArray) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
-
-        Collections.sort(files, new Comparator<File>() {
-            @SuppressFBWarnings(value = "Bx")
-            public int compare(File o1, File o2) {
-                Long obj1 = o1.lastModified();
-                return multiplier * obj1.compareTo(o2.lastModified());
-            }
-        });
-
-        File[] returnArray = new File[files.size()];
-        return files.toArray(returnArray);
-    }
-
-    /**
-     * Sorts list by Size.
-     *
-     * @param files list of files to sort
-     */
-    public static Vector<OCFile> sortOCFilesBySize(Vector<OCFile> files) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        Collections.sort(files, new Comparator<OCFile>() {
-            @SuppressFBWarnings(value = "Bx")
-            public int compare(OCFile o1, OCFile o2) {
-                if (o1.isFolder() && o2.isFolder()) {
-                    Long obj1 = o1.getFileLength();
-                    return multiplier * obj1.compareTo(o2.getFileLength());
-                } else if (o1.isFolder()) {
-                    return -1;
-
-                } else if (o2.isFolder()) {
-                    return 1;
-                } else {
-                    Long obj1 = o1.getFileLength();
-                    return multiplier * obj1.compareTo(o2.getFileLength());
-                }
-            }
-        });
-
-        return files;
-    }
-
-    /**
-     * Sorts list by Size.
-     *
-     * @param filesArray list of files to sort
-     */
-    public static File[] sortLocalFilesBySize(File[] filesArray) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        List<File> files = new ArrayList<>(Arrays.asList(filesArray));
-
-        Collections.sort(files, new Comparator<File>() {
-            @SuppressFBWarnings(value = "Bx")
-            public int compare(File o1, File o2) {
-                if (o1.isDirectory() && o2.isDirectory()) {
-                    // Long obj1 = getFolderSize(o1);
-                    // return multiplier * obj1.compareTo(getFolderSize(o2));
-                    return o1.getPath().toLowerCase().compareTo(o2.getPath().toLowerCase());
-                } else if (o1.isDirectory()) {
-                    return -1;
-                } else if (o2.isDirectory()) {
-                    return 1;
-                } else {
-                    Long obj1 = o1.length();
-                    return multiplier * obj1.compareTo(o2.length());
-                }
-            }
-        });
-
-        File[] returnArray = new File[files.size()];
-        return files.toArray(returnArray);
-    }
-
-    /**
-     * Sorts list by Name.
-     *
-     * @param files files to sort
-     */
-    @SuppressFBWarnings(value = "Bx")
-    public static Vector<OCFile> sortOCFilesByName(Vector<OCFile> files) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        Collections.sort(files, new Comparator<OCFile>() {
-            public int compare(OCFile o1, OCFile o2) {
-                if (o1.isFolder() && o2.isFolder()) {
-                    return multiplier * new AlphanumComparator().compare(o1, o2);
-                } else if (o1.isFolder()) {
-                    return -1;
-                } else if (o2.isFolder()) {
-                    return 1;
-                }
-                return multiplier * new AlphanumComparator().compare(o1, o2);
-            }
-        });
-
-        return files;
-    }
-
-    /**
-     * Sorts list by Name.
-     *
-     * @param filesArray files to sort
-     */
-    public static File[] sortLocalFilesByName(File[] filesArray) {
-        final int multiplier = mSortAscending ? 1 : -1;
-
-        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
-
-        Collections.sort(files, new Comparator<File>() {
-            public int compare(File o1, File o2) {
-                if (o1.isDirectory() && o2.isDirectory()) {
-                    return multiplier * o1.getPath().toLowerCase().compareTo(o2.getPath().toLowerCase());
-                } else if (o1.isDirectory()) {
-                    return -1;
-                } else if (o2.isDirectory()) {
-                    return 1;
-                }
-                return multiplier * new AlphanumComparator().compare(o1.getPath().toLowerCase(),
-                        o2.getPath().toLowerCase());
-            }
-        });
-
-        File[] returnArray = new File[files.size()];
-        return files.toArray(returnArray);
-    }
-
-    /**
-     * Sorts list by Favourites.
-     *
-     * @param files files to sort
-     */
-    public static Vector<OCFile> sortOCFilesByFavourite(Vector<OCFile> files) {
-        Collections.sort(files, new Comparator<OCFile>() {
-            public int compare(OCFile o1, OCFile o2) {
-                if (o1.getIsFavorite() && o2.getIsFavorite()) {
-                    return 0;
-                } else if (o1.getIsFavorite()) {
-                    return -1;
-                } else if (o2.getIsFavorite()) {
-                    return 1;
-                }
-                return 0;
-            }
-        });
-
-        return files;
-    }
 
     /**
      * Local Folder size.

+ 7 - 0
src/main/res/menu/receive_file_menu.xml

@@ -40,6 +40,13 @@
         android:orderInCategory="1"
         android:title="@string/actionbar_mkdir"
         app:showAsAction="never"/>
+    <item
+        android:id="@+id/action_sort"
+        android:contentDescription="@string/actionbar_sort"
+        android:icon="@drawable/ic_sort_variant"
+        android:orderInCategory="1"
+        android:title="@string/actionbar_sort"
+        app:showAsAction="never"/>
     <item
         android:id="@+id/action_select_all"
         android:contentDescription="@string/select_all"