1691 lines
67 KiB
Java
1691 lines
67 KiB
Java
/*
|
|
* ownCloud Android client application
|
|
*
|
|
* @author Bartek Przybylski
|
|
* @author masensio
|
|
* @author David A. Velasco
|
|
* Copyright (C) 2011 Bartek Przybylski
|
|
* Copyright (C) 2016 ownCloud Inc.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.ui.fragment;
|
|
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.accounts.AuthenticatorException;
|
|
import android.accounts.OperationCanceledException;
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.os.AsyncTask;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.annotation.StringRes;
|
|
import android.support.design.widget.BottomNavigationView;
|
|
import android.support.design.widget.Snackbar;
|
|
import android.support.v4.widget.DrawerLayout;
|
|
import android.support.v4.widget.SwipeRefreshLayout;
|
|
import android.text.TextUtils;
|
|
import android.util.SparseBooleanArray;
|
|
import android.view.ActionMode;
|
|
import android.view.LayoutInflater;
|
|
import android.view.Menu;
|
|
import android.view.MenuInflater;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.AbsListView;
|
|
import android.widget.AdapterView;
|
|
import android.widget.ListView;
|
|
import android.widget.PopupMenu;
|
|
import android.widget.RelativeLayout;
|
|
import android.widget.TextView;
|
|
|
|
import com.owncloud.android.MainApp;
|
|
import com.owncloud.android.R;
|
|
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.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;
|
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
import com.owncloud.android.lib.resources.files.SearchOperation;
|
|
import com.owncloud.android.lib.resources.files.ToggleEncryptionOperation;
|
|
import com.owncloud.android.lib.resources.files.ToggleFavoriteOperation;
|
|
import com.owncloud.android.lib.resources.shares.GetRemoteSharesOperation;
|
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
|
import com.owncloud.android.ui.activity.FileActivity;
|
|
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
|
import com.owncloud.android.ui.activity.FolderPickerActivity;
|
|
import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
|
|
import com.owncloud.android.ui.activity.UploadFilesActivity;
|
|
import com.owncloud.android.ui.adapter.FileListListAdapter;
|
|
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
|
|
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
|
|
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
|
|
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
|
import com.owncloud.android.ui.dialog.SetupEncryptionDialogFragment;
|
|
import com.owncloud.android.ui.events.ChangeMenuEvent;
|
|
import com.owncloud.android.ui.events.DummyDrawerEvent;
|
|
import com.owncloud.android.ui.events.EncryptionEvent;
|
|
import com.owncloud.android.ui.events.FavoriteEvent;
|
|
import com.owncloud.android.ui.events.SearchEvent;
|
|
import com.owncloud.android.ui.helpers.SparseBooleanArrayParcelable;
|
|
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
|
|
import com.owncloud.android.ui.preview.PreviewImageFragment;
|
|
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.EncryptionUtils;
|
|
import com.owncloud.android.utils.FileSortOrder;
|
|
import com.owncloud.android.utils.MimeTypeUtil;
|
|
import com.owncloud.android.utils.ThemeUtils;
|
|
|
|
import org.apache.commons.httpclient.HttpStatus;
|
|
import org.greenrobot.eventbus.EventBus;
|
|
import org.greenrobot.eventbus.Subscribe;
|
|
import org.greenrobot.eventbus.ThreadMode;
|
|
import org.parceler.Parcels;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* A Fragment that lists all files and folders in a given path.
|
|
*
|
|
* TODO refactor to get rid of direct dependency on FileDisplayActivity
|
|
*/
|
|
public class OCFileListFragment extends ExtendedListFragment implements OCFileListFragmentInterface {
|
|
|
|
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";
|
|
public final static String ARG_HIDE_FAB = MY_PACKAGE + ".HIDE_FAB";
|
|
public final static String ARG_HIDE_ITEM_OPTIONS = MY_PACKAGE + ".HIDE_ITEM_OPTIONS";
|
|
|
|
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_CURRENT_SEARCH_TYPE = "CURRENT_SEARCH_TYPE";
|
|
|
|
private static final String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
|
|
|
|
private static final String SCREEN_NAME = "Remote/Server file browser";
|
|
|
|
private FileFragment.ContainerActivity mContainerActivity;
|
|
|
|
private OCFile mFile = null;
|
|
private FileListListAdapter mAdapter;
|
|
private boolean mJustFolders;
|
|
|
|
private int mSystemBarActionModeColor;
|
|
private int mSystemBarColor;
|
|
private int mProgressBarActionModeColor;
|
|
private int mProgressBarColor;
|
|
|
|
private boolean mHideFab = true;
|
|
private boolean miniFabClicked = false;
|
|
private ActionMode mActiveActionMode;
|
|
private OCFileListFragment.MultiChoiceModeListener mMultiChoiceModeListener;
|
|
|
|
private BottomNavigationView bottomNavigationView;
|
|
|
|
private SearchType currentSearchType;
|
|
private boolean searchFragment = false;
|
|
private SearchEvent searchEvent;
|
|
private AsyncTask remoteOperationAsyncTask;
|
|
|
|
private enum MenuItemAddRemove {
|
|
DO_NOTHING, REMOVE_SORT, REMOVE_GRID_AND_SORT, ADD_SORT, ADD_GRID_AND_SORT, ADD_GRID_AND_SORT_WITH_SEARCH,
|
|
REMOVE_SEARCH
|
|
}
|
|
|
|
private MenuItemAddRemove menuItemAddRemoveValue = MenuItemAddRemove.DO_NOTHING;
|
|
|
|
private ArrayList<MenuItem> mOriginalMenuItems = new ArrayList<>();
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setHasOptionsMenu(true);
|
|
mSystemBarActionModeColor = getResources().getColor(R.color.action_mode_status_bar_background);
|
|
mSystemBarColor = ThemeUtils.primaryDarkColor();
|
|
mProgressBarActionModeColor = getResources().getColor(R.color.action_mode_background);
|
|
mProgressBarColor = ThemeUtils.primaryColor();
|
|
mMultiChoiceModeListener = new MultiChoiceModeListener();
|
|
|
|
if (savedInstanceState != null) {
|
|
currentSearchType = Parcels.unwrap(savedInstanceState.getParcelable(KEY_CURRENT_SEARCH_TYPE));
|
|
searchEvent = Parcels.unwrap(savedInstanceState.getParcelable(OCFileListFragment.SEARCH_EVENT));
|
|
}
|
|
|
|
searchFragment = currentSearchType != null;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void onAttach(Context context) {
|
|
super.onAttach(context);
|
|
Log_OC.i(TAG, "onAttach");
|
|
try {
|
|
mContainerActivity = (FileFragment.ContainerActivity) context;
|
|
|
|
} catch (ClassCastException e) {
|
|
throw new ClassCastException(context.toString() + " must implement " +
|
|
FileFragment.ContainerActivity.class.getSimpleName());
|
|
}
|
|
try {
|
|
setOnRefreshListener((OnEnforceableRefreshListener) context);
|
|
|
|
} catch (ClassCastException e) {
|
|
throw new ClassCastException(context.toString() + " must implement " +
|
|
SwipeRefreshLayout.OnRefreshListener.class.getSimpleName());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
Log_OC.i(TAG, "onCreateView() start");
|
|
View v = super.onCreateView(inflater, container, savedInstanceState);
|
|
bottomNavigationView = v.findViewById(R.id.bottom_navigation_view);
|
|
|
|
if (savedInstanceState != null) {
|
|
currentSearchType = Parcels.unwrap(savedInstanceState.getParcelable(KEY_CURRENT_SEARCH_TYPE));
|
|
} else {
|
|
currentSearchType = SearchType.NO_SEARCH;
|
|
}
|
|
|
|
searchFragment = savedInstanceState != null;
|
|
|
|
if (getResources().getBoolean(R.bool.bottom_toolbar_enabled)) {
|
|
bottomNavigationView.setVisibility(View.VISIBLE);
|
|
DisplayUtils.setupBottomBar(bottomNavigationView, getResources(), getActivity(), R.id.nav_bar_files);
|
|
}
|
|
|
|
if (!getResources().getBoolean(R.bool.bottom_toolbar_enabled) || savedInstanceState != null) {
|
|
|
|
final View fabView = v.findViewById(R.id.fab_main);
|
|
final RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
|
|
fabView.getLayoutParams();
|
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1);
|
|
Handler handler = new Handler();
|
|
handler.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
fabView.setLayoutParams(layoutParams);
|
|
fabView.invalidate();
|
|
}
|
|
});
|
|
}
|
|
|
|
Bundle args = getArguments();
|
|
boolean allowContextualActions = (args != null) && args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, false);
|
|
if (allowContextualActions) {
|
|
setChoiceModeAsMultipleModal(savedInstanceState);
|
|
}
|
|
Log_OC.i(TAG, "onCreateView() end");
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
|
|
if (getActivity() != null) {
|
|
AnalyticsUtils.setCurrentScreenName(getActivity(), SCREEN_NAME, TAG);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDetach() {
|
|
setOnRefreshListener(null);
|
|
mContainerActivity = null;
|
|
|
|
if (remoteOperationAsyncTask != null) {
|
|
remoteOperationAsyncTask.cancel(true);
|
|
}
|
|
super.onDetach();
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
mAdapter.cancelAllPendingTasks();
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void onActivityCreated(Bundle savedInstanceState) {
|
|
super.onActivityCreated(savedInstanceState);
|
|
Log_OC.i(TAG, "onActivityCreated() start");
|
|
|
|
|
|
if (savedInstanceState != null) {
|
|
mFile = savedInstanceState.getParcelable(KEY_FILE);
|
|
}
|
|
|
|
if (mJustFolders) {
|
|
setFooterEnabled(false);
|
|
} else {
|
|
setFooterEnabled(true);
|
|
}
|
|
|
|
Bundle args = getArguments();
|
|
mJustFolders = (args != null) && args.getBoolean(ARG_JUST_FOLDERS, false);
|
|
boolean hideItemOptions = (args != null) && args.getBoolean(ARG_HIDE_ITEM_OPTIONS, false);
|
|
|
|
mAdapter = new FileListListAdapter(mJustFolders, getActivity(), mContainerActivity, this, hideItemOptions);
|
|
setListAdapter(mAdapter);
|
|
|
|
mHideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false);
|
|
if (mHideFab) {
|
|
setFabEnabled(false);
|
|
} else {
|
|
setFabEnabled(true);
|
|
registerFabListeners();
|
|
|
|
// detect if a mini FAB has ever been clicked
|
|
if (PreferenceManager.getFABClicked(getActivity()) > 0) {
|
|
miniFabClicked = true;
|
|
}
|
|
|
|
// add labels to the min FABs when none of them has ever been clicked on
|
|
if (!miniFabClicked) {
|
|
setFabLabels();
|
|
} else {
|
|
removeFabLabels();
|
|
}
|
|
}
|
|
|
|
searchEvent = Parcels.unwrap(getArguments().getParcelable(OCFileListFragment.SEARCH_EVENT));
|
|
prepareCurrentSearch(searchEvent);
|
|
if (searchEvent != null && savedInstanceState == null) {
|
|
onMessageEvent(searchEvent);
|
|
}
|
|
|
|
setTitle();
|
|
|
|
}
|
|
|
|
private void prepareCurrentSearch(SearchEvent event) {
|
|
if (event != null) {
|
|
if (event.getSearchType().equals(SearchOperation.SearchType.FILE_SEARCH)) {
|
|
currentSearchType = SearchType.FILE_SEARCH;
|
|
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.CONTENT_TYPE_SEARCH)) {
|
|
if (event.getSearchQuery().equals("image/%")) {
|
|
currentSearchType = SearchType.PHOTO_SEARCH;
|
|
} else if (event.getSearchQuery().equals("video/%")) {
|
|
currentSearchType = SearchType.VIDEO_SEARCH;
|
|
}
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.FAVORITE_SEARCH)) {
|
|
currentSearchType = SearchType.FAVORITE_SEARCH;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_ADDED_SEARCH)) {
|
|
currentSearchType = SearchType.RECENTLY_ADDED_SEARCH;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_MODIFIED_SEARCH)) {
|
|
currentSearchType = SearchType.RECENTLY_MODIFIED_SEARCH;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.SHARED_SEARCH)) {
|
|
currentSearchType = SearchType.SHARED_FILTER;
|
|
}
|
|
|
|
prepareActionBarItems(event);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* adds labels to all mini FABs.
|
|
*/
|
|
private void setFabLabels() {
|
|
getFabUpload().setTitle(getResources().getString(R.string.actionbar_upload));
|
|
getFabMkdir().setTitle(getResources().getString(R.string.actionbar_mkdir));
|
|
getFabUploadFromApp().setTitle(getResources().getString(R.string.actionbar_upload_from_apps));
|
|
}
|
|
|
|
/**
|
|
* registers all listeners on all mini FABs.
|
|
*/
|
|
private void registerFabListeners() {
|
|
registerFabUploadListeners(getActivity());
|
|
registerFabMkDirListeners(getActivity());
|
|
registerFabUploadFromAppListeners(getActivity());
|
|
}
|
|
|
|
/**
|
|
* registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
|
|
* on the Upload mini FAB for the linked action and {@link Snackbar} showing the underlying action.
|
|
*
|
|
* @param activity the activity on which's content the {@link Snackbar} will be shown.
|
|
*/
|
|
private void registerFabUploadListeners(final Activity activity) {
|
|
getFabUpload().setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
UploadFilesActivity.startUploadActivityForResult(getActivity(), ((FileActivity) getActivity())
|
|
.getAccount(), FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM);
|
|
getFabMain().collapse();
|
|
recordMiniFabClick();
|
|
}
|
|
});
|
|
|
|
getFabUpload().setOnLongClickListener(new View.OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View v) {
|
|
DisplayUtils.showSnackMessage(activity, R.string.actionbar_upload);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
|
|
* on the 'Create Dir' mini FAB for the linked action and {@link Snackbar} showing the underlying action.
|
|
*
|
|
* @param activity the activity on which's content the {@link Snackbar} will be shown.
|
|
*/
|
|
private void registerFabMkDirListeners(final Activity activity) {
|
|
getFabMkdir().setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
CreateFolderDialogFragment dialog =
|
|
CreateFolderDialogFragment.newInstance(mFile);
|
|
dialog.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
|
|
getFabMain().collapse();
|
|
recordMiniFabClick();
|
|
}
|
|
});
|
|
|
|
getFabMkdir().setOnLongClickListener(new View.OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View v) {
|
|
DisplayUtils.showSnackMessage(activity, R.string.actionbar_mkdir);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
|
|
* on the Upload from App mini FAB for the linked action and {@link Snackbar} showing the underlying action.
|
|
*
|
|
* @param activity the activity on which's content the {@link Snackbar} will be shown.
|
|
*/
|
|
private void registerFabUploadFromAppListeners(final Activity activity) {
|
|
getFabUploadFromApp().setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
Intent action = new Intent(Intent.ACTION_GET_CONTENT);
|
|
action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
|
|
//Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
|
action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
|
}
|
|
getActivity().startActivityForResult(
|
|
Intent.createChooser(action, getString(R.string.upload_chooser_title)),
|
|
FileDisplayActivity.REQUEST_CODE__SELECT_CONTENT_FROM_APPS
|
|
);
|
|
getFabMain().collapse();
|
|
recordMiniFabClick();
|
|
}
|
|
});
|
|
|
|
getFabUploadFromApp().setOnLongClickListener(new View.OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View v) {
|
|
DisplayUtils.showSnackMessage(activity, R.string.actionbar_upload_from_apps);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* records a click on a mini FAB and thus:
|
|
* <ol>
|
|
* <li>persists the click fact</li>
|
|
* <li>removes the mini FAB labels</li>
|
|
* </ol>
|
|
*/
|
|
private void recordMiniFabClick() {
|
|
// only record if it hasn't been done already at some other time
|
|
if (!miniFabClicked) {
|
|
PreferenceManager.setFABClicked(getActivity());
|
|
miniFabClicked = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* removes the labels on all known min FABs.
|
|
*/
|
|
private void removeFabLabels() {
|
|
getFabUpload().setTitle(null);
|
|
getFabMkdir().setTitle(null);
|
|
getFabUploadFromApp().setTitle(null);
|
|
((TextView) getFabUpload().getTag(
|
|
com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
|
|
((TextView) getFabMkdir().getTag(
|
|
com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
|
|
((TextView) getFabUploadFromApp().getTag(
|
|
com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
|
|
}
|
|
|
|
@Override
|
|
public void finishedFiltering() {
|
|
updateFooter();
|
|
}
|
|
|
|
@Override
|
|
public void onShareIconClick(OCFile file) {
|
|
mContainerActivity.getFileOperationsHelper().sendShareFile(file);
|
|
}
|
|
|
|
@Override
|
|
public void onOverflowIconClick(View view, OCFile file) {
|
|
PopupMenu popup = new PopupMenu(getActivity(), view);
|
|
popup.inflate(R.menu.file_actions_menu);
|
|
FileMenuFilter mf = new FileMenuFilter(
|
|
mAdapter.getFiles().size(),
|
|
Collections.singleton(file),
|
|
((FileActivity) getActivity()).getAccount(),
|
|
mContainerActivity,
|
|
getActivity(),
|
|
true
|
|
);
|
|
mf.filter(popup.getMenu(), true);
|
|
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
@Override
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
ArrayList<OCFile> checkedFiles = new ArrayList<>(Collections.singletonList(file));
|
|
return onFileActionChosen(item.getItemId(), checkedFiles);
|
|
}
|
|
});
|
|
popup.show();
|
|
}
|
|
|
|
/**
|
|
* Handler for multiple selection mode.
|
|
*
|
|
* Manages input from the user when one or more files or folders are selected in the list.
|
|
*
|
|
* Also listens to changes in navigation drawer to hide and recover multiple selection when it's opened
|
|
* and closed.
|
|
*/
|
|
private class MultiChoiceModeListener
|
|
implements AbsListView.MultiChoiceModeListener, DrawerLayout.DrawerListener {
|
|
|
|
private static final String KEY_ACTION_MODE_CLOSED_BY_DRAWER = "KILLED_ACTION_MODE";
|
|
private static final String KEY_SELECTION_WHEN_CLOSED_BY_DRAWER = "CHECKED_ITEMS";
|
|
|
|
/**
|
|
* True when action mode is finished because the drawer was opened
|
|
*/
|
|
private boolean mActionModeClosedByDrawer = false;
|
|
|
|
/**
|
|
* Selected items in list when action mode is closed by drawer
|
|
*/
|
|
private SparseBooleanArray mSelectionWhenActionModeClosedByDrawer = null;
|
|
|
|
@Override
|
|
public void onDrawerSlide(View drawerView, float slideOffset) {
|
|
// nothing to do
|
|
}
|
|
|
|
@Override
|
|
public void onDrawerOpened(View drawerView) {
|
|
// nothing to do
|
|
}
|
|
|
|
/**
|
|
* When the navigation drawer is closed, action mode is recovered in the same state as was
|
|
* when the drawer was (started to be) opened.
|
|
*
|
|
* @param drawerView Navigation drawer just closed.
|
|
*/
|
|
@Override
|
|
public void onDrawerClosed(View drawerView) {
|
|
if (mSelectionWhenActionModeClosedByDrawer != null && mActionModeClosedByDrawer) {
|
|
for (int i = 0; i < mSelectionWhenActionModeClosedByDrawer.size(); i++) {
|
|
if (mSelectionWhenActionModeClosedByDrawer.valueAt(i)) {
|
|
getListView().setItemChecked(
|
|
mSelectionWhenActionModeClosedByDrawer.keyAt(i),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
}
|
|
mSelectionWhenActionModeClosedByDrawer = null;
|
|
}
|
|
|
|
/**
|
|
* If the action mode is active when the navigation drawer starts to move, the action
|
|
* mode is closed and the selection stored to be recovered when the drawer is closed.
|
|
*
|
|
* @param newState One of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
|
|
*/
|
|
@Override
|
|
public void onDrawerStateChanged(int newState) {
|
|
if (DrawerLayout.STATE_DRAGGING == newState && mActiveActionMode != null) {
|
|
mSelectionWhenActionModeClosedByDrawer = getListView().getCheckedItemPositions().clone();
|
|
mActiveActionMode.finish();
|
|
mActionModeClosedByDrawer = true;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Update action mode bar when an item is selected / unselected in the list
|
|
*/
|
|
@Override
|
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
|
getListView().invalidateViews();
|
|
mode.invalidate();
|
|
}
|
|
|
|
/**
|
|
* Load menu and customize UI when action mode is started.
|
|
*/
|
|
@Override
|
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
mActiveActionMode = mode;
|
|
|
|
MenuInflater inflater = getActivity().getMenuInflater();
|
|
inflater.inflate(R.menu.file_actions_menu, menu);
|
|
mode.invalidate();
|
|
|
|
//set gray color
|
|
ThemeUtils.colorStatusBar(getActivity(), mSystemBarActionModeColor);
|
|
ThemeUtils.colorToolbarProgressBar(getActivity(), mProgressBarActionModeColor);
|
|
|
|
// hide FAB in multi selection mode
|
|
setFabEnabled(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Updates available action in menu depending on current selection.
|
|
*/
|
|
@Override
|
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
|
List<OCFile> checkedFiles = mAdapter.getCheckedItems(getListView());
|
|
final int checkedCount = checkedFiles.size();
|
|
String title = getResources().getQuantityString(
|
|
R.plurals.items_selected_count,
|
|
checkedCount,
|
|
checkedCount
|
|
);
|
|
mode.setTitle(title);
|
|
FileMenuFilter mf = new FileMenuFilter(
|
|
mAdapter.getFiles().size(),
|
|
checkedFiles,
|
|
((FileActivity) getActivity()).getAccount(),
|
|
mContainerActivity,
|
|
getActivity(),
|
|
false
|
|
);
|
|
mf.filter(menu, false);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Starts the corresponding action when a menu item is tapped by the user.
|
|
*/
|
|
@Override
|
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
|
ArrayList<OCFile> checkedFiles = mAdapter.getCheckedItems(getListView());
|
|
return onFileActionChosen(item.getItemId(), checkedFiles);
|
|
}
|
|
|
|
/**
|
|
* Restores UI.
|
|
*/
|
|
@Override
|
|
public void onDestroyActionMode(ActionMode mode) {
|
|
mActiveActionMode = null;
|
|
|
|
// reset to previous color
|
|
ThemeUtils.colorStatusBar(getActivity(), mSystemBarColor);
|
|
ThemeUtils.colorToolbarProgressBar(getActivity(), mProgressBarColor);
|
|
|
|
// show FAB on multi selection mode exit
|
|
if (!mHideFab && !searchFragment) {
|
|
setFabEnabled(true);
|
|
}
|
|
}
|
|
|
|
|
|
public void storeStateIn(Bundle outState) {
|
|
outState.putBoolean(KEY_ACTION_MODE_CLOSED_BY_DRAWER, mActionModeClosedByDrawer);
|
|
if (mSelectionWhenActionModeClosedByDrawer != null) {
|
|
SparseBooleanArrayParcelable sbap = new SparseBooleanArrayParcelable(
|
|
mSelectionWhenActionModeClosedByDrawer
|
|
);
|
|
outState.putParcelable(KEY_SELECTION_WHEN_CLOSED_BY_DRAWER, sbap);
|
|
}
|
|
}
|
|
|
|
public void loadStateFrom(Bundle savedInstanceState) {
|
|
mActionModeClosedByDrawer = savedInstanceState.getBoolean(
|
|
KEY_ACTION_MODE_CLOSED_BY_DRAWER,
|
|
mActionModeClosedByDrawer
|
|
);
|
|
SparseBooleanArrayParcelable sbap = savedInstanceState.getParcelable(
|
|
KEY_SELECTION_WHEN_CLOSED_BY_DRAWER
|
|
);
|
|
if (sbap != null) {
|
|
mSelectionWhenActionModeClosedByDrawer = sbap.getSparseBooleanArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Init listener that will handle interactions in multiple selection mode.
|
|
*/
|
|
private void setChoiceModeAsMultipleModal(Bundle savedInstanceState) {
|
|
setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
|
if (savedInstanceState != null) {
|
|
mMultiChoiceModeListener.loadStateFrom(savedInstanceState);
|
|
}
|
|
setMultiChoiceModeListener(mMultiChoiceModeListener);
|
|
((FileActivity) getActivity()).addDrawerListener(mMultiChoiceModeListener);
|
|
}
|
|
|
|
@Override
|
|
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
|
|
super.onViewStateRestored(savedInstanceState);
|
|
|
|
if (savedInstanceState != null) {
|
|
searchEvent = Parcels.unwrap(savedInstanceState.getParcelable(SEARCH_EVENT));
|
|
}
|
|
|
|
if (searchEvent != null) {
|
|
onMessageEvent(searchEvent);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves the current listed folder.
|
|
*/
|
|
@Override
|
|
public void onSaveInstanceState(Bundle outState) {
|
|
super.onSaveInstanceState(outState);
|
|
outState.putParcelable(KEY_FILE, mFile);
|
|
if (searchFragment) {
|
|
outState.putParcelable(KEY_CURRENT_SEARCH_TYPE, Parcels.wrap(currentSearchType));
|
|
outState.putParcelable(OCFileListFragment.SEARCH_EVENT, Parcels.wrap(searchEvent));
|
|
}
|
|
mMultiChoiceModeListener.storeStateIn(outState);
|
|
}
|
|
|
|
@Override
|
|
public void onPrepareOptionsMenu(Menu menu) {
|
|
Menu mMenu = menu;
|
|
|
|
if (mOriginalMenuItems.size() == 0) {
|
|
mOriginalMenuItems.add(mMenu.findItem(R.id.action_switch_view));
|
|
mOriginalMenuItems.add(mMenu.findItem(R.id.action_sort));
|
|
mOriginalMenuItems.add(mMenu.findItem(R.id.action_search));
|
|
}
|
|
|
|
changeGridIcon(menu); // this is enough if the option stays out of the action bar
|
|
|
|
MenuItem menuItemOrig;
|
|
|
|
if (menuItemAddRemoveValue.equals(MenuItemAddRemove.ADD_SORT)) {
|
|
if (menu.findItem(R.id.action_sort) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(1);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
|
|
} else if (menuItemAddRemoveValue.equals(MenuItemAddRemove.ADD_GRID_AND_SORT))
|
|
|
|
{
|
|
if (menu.findItem(R.id.action_switch_view) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(0);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
|
|
if (menu.findItem(R.id.action_sort) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(1);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
} else if (menuItemAddRemoveValue.equals(MenuItemAddRemove.REMOVE_SEARCH)) {
|
|
menu.removeItem(R.id.action_search);
|
|
} else if (menuItemAddRemoveValue.equals(MenuItemAddRemove.ADD_GRID_AND_SORT_WITH_SEARCH)) {
|
|
if (menu.findItem(R.id.action_switch_view) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(0);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
|
|
if (menu.findItem(R.id.action_sort) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(1);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
|
|
if (menu.findItem(R.id.action_search) == null) {
|
|
menuItemOrig = mOriginalMenuItems.get(2);
|
|
menu.add(menuItemOrig.getGroupId(), menuItemOrig.getItemId(), menuItemOrig.getOrder(),
|
|
menuItemOrig.getTitle());
|
|
}
|
|
} else if (menuItemAddRemoveValue.equals(MenuItemAddRemove.REMOVE_SORT)) {
|
|
menu.removeItem(R.id.action_sort);
|
|
menu.removeItem(R.id.action_search);
|
|
} else if (menuItemAddRemoveValue.equals(MenuItemAddRemove.REMOVE_GRID_AND_SORT)) {
|
|
menu.removeItem(R.id.action_sort);
|
|
menu.removeItem(R.id.action_switch_view);
|
|
menu.removeItem(R.id.action_search);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
* <p/>
|
|
* return Count of folder levels browsed up.
|
|
*/
|
|
public int onBrowseUp() {
|
|
OCFile parentDir;
|
|
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, MainApp.isOnlyOnDevice(), false);
|
|
|
|
onRefresh(false);
|
|
|
|
// 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()) {
|
|
if (file.isEncrypted()) {
|
|
// check if API >= 19
|
|
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
|
|
Snackbar.make(mCurrentListView, R.string.end_to_end_encryption_not_supported,
|
|
Snackbar.LENGTH_LONG).show();
|
|
return;
|
|
}
|
|
|
|
// check if keys are stored
|
|
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(
|
|
getContext().getContentResolver());
|
|
|
|
Account account = ((FileActivity) mContainerActivity).getAccount();
|
|
String publicKey = arbitraryDataProvider.getValue(account, EncryptionUtils.PUBLIC_KEY);
|
|
String privateKey = arbitraryDataProvider.getValue(account, EncryptionUtils.PRIVATE_KEY);
|
|
|
|
if (publicKey.isEmpty() || privateKey.isEmpty()) {
|
|
Log_OC.d(TAG, "no public key for " + account.name);
|
|
|
|
SetupEncryptionDialogFragment dialog = SetupEncryptionDialogFragment.newInstance(account,
|
|
position);
|
|
dialog.setTargetFragment(this, SetupEncryptionDialogFragment.SETUP_ENCRYPTION_REQUEST_CODE);
|
|
dialog.show(getFragmentManager(), SetupEncryptionDialogFragment.SETUP_ENCRYPTION_DIALOG_TAG);
|
|
} else {
|
|
// update state and view of this fragment
|
|
searchFragment = false;
|
|
listDirectory(file, MainApp.isOnlyOnDevice(), false);
|
|
// then, notify parent activity to let it update its state and view
|
|
mContainerActivity.onBrowsedDownTo(file);
|
|
// save index and top position
|
|
saveIndexAndTopPosition(position);
|
|
}
|
|
} else {
|
|
// update state and view of this fragment
|
|
searchFragment = false;
|
|
listDirectory(file, MainApp.isOnlyOnDevice(), false);
|
|
// 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
|
|
if (searchFragment) {
|
|
VirtualFolderType type;
|
|
switch (currentSearchType) {
|
|
case FAVORITE_SEARCH:
|
|
type = VirtualFolderType.FAVORITE;
|
|
break;
|
|
case PHOTO_SEARCH:
|
|
type = VirtualFolderType.PHOTOS;
|
|
break;
|
|
default:
|
|
type = VirtualFolderType.NONE;
|
|
break;
|
|
}
|
|
((FileDisplayActivity) mContainerActivity).startImagePreview(file, type, !file.isDown());
|
|
} else {
|
|
((FileDisplayActivity) mContainerActivity).startImagePreview(file, !file.isDown());
|
|
}
|
|
} else if (file.isDown() && MimeTypeUtil.isVCard(file)) {
|
|
((FileDisplayActivity) mContainerActivity).startContactListFragment(file);
|
|
} else if (PreviewTextFragment.canBePreviewed(file)) {
|
|
((FileDisplayActivity) mContainerActivity).startTextPreview(file, false);
|
|
} else if (file.isDown()) {
|
|
if (PreviewMediaFragment.canBePreviewed(file)) {
|
|
// media preview
|
|
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0,
|
|
true, false);
|
|
} else {
|
|
mContainerActivity.getFileOperationsHelper().openFile(file);
|
|
}
|
|
|
|
} else {
|
|
// automatic download, preview on finish
|
|
((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file);
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
Log_OC.d(TAG, "Null object in ListAdapter!!");
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
if (requestCode == SetupEncryptionDialogFragment.SETUP_ENCRYPTION_REQUEST_CODE &&
|
|
resultCode == SetupEncryptionDialogFragment.SETUP_ENCRYPTION_RESULT_CODE &&
|
|
data.getBooleanExtra(SetupEncryptionDialogFragment.SUCCESS, false)) {
|
|
|
|
int position = data.getIntExtra(SetupEncryptionDialogFragment.ARG_POSITION, -1);
|
|
OCFile file = (OCFile) mAdapter.getItem(position);
|
|
|
|
// update state and view of this fragment
|
|
searchFragment = false;
|
|
listDirectory(file, MainApp.isOnlyOnDevice(), false);
|
|
// then, notify parent activity to let it update its state and view
|
|
mContainerActivity.onBrowsedDownTo(file);
|
|
// save index and top position
|
|
saveIndexAndTopPosition(position);
|
|
} else {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Start the appropriate action(s) on the currently selected files given menu selected by the user.
|
|
*
|
|
* @param menuId Identifier of the action menu selected by the user
|
|
* @param checkedFiles List of files selected by the user on which the action should be performed
|
|
* @return 'true' if the menu selection started any action, 'false' otherwise.
|
|
*/
|
|
public boolean onFileActionChosen(int menuId, ArrayList<OCFile> checkedFiles) {
|
|
if (checkedFiles.size() <= 0) {
|
|
return false;
|
|
}
|
|
|
|
if (checkedFiles.size() == 1) {
|
|
/// action only possible on a single file
|
|
OCFile singleFile = checkedFiles.get(0);
|
|
switch (menuId) {
|
|
case R.id.action_send_share_file: {
|
|
mContainerActivity.getFileOperationsHelper().sendShareFile(singleFile);
|
|
return true;
|
|
}
|
|
case R.id.action_open_file_with: {
|
|
mContainerActivity.getFileOperationsHelper().openFile(singleFile);
|
|
return true;
|
|
}
|
|
case R.id.action_rename_file: {
|
|
RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(singleFile);
|
|
dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
|
|
return true;
|
|
}
|
|
case R.id.action_see_details: {
|
|
if (mActiveActionMode != null) {
|
|
mActiveActionMode.finish();
|
|
}
|
|
mContainerActivity.showDetails(singleFile);
|
|
return true;
|
|
}
|
|
case R.id.action_set_as_wallpaper: {
|
|
mContainerActivity.getFileOperationsHelper().setPictureAs(singleFile, getView());
|
|
return true;
|
|
}
|
|
case R.id. action_encrypted: {
|
|
mContainerActivity.getFileOperationsHelper().toggleEncryption(singleFile, true);
|
|
return true;
|
|
}
|
|
case R.id. action_unset_encrypted: {
|
|
mContainerActivity.getFileOperationsHelper().toggleEncryption(singleFile, false);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// actions possible on a batch of files
|
|
switch (menuId) {
|
|
case R.id.action_remove_file: {
|
|
RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(checkedFiles);
|
|
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
|
|
return true;
|
|
}
|
|
case R.id.action_download_file:
|
|
case R.id.action_sync_file: {
|
|
mContainerActivity.getFileOperationsHelper().syncFiles(checkedFiles);
|
|
return true;
|
|
}
|
|
case R.id.action_cancel_sync: {
|
|
((FileDisplayActivity) mContainerActivity).cancelTransference(checkedFiles);
|
|
return true;
|
|
}
|
|
case R.id.action_keep_files_offline: {
|
|
mContainerActivity.getFileOperationsHelper().toggleOfflineFiles(checkedFiles, true);
|
|
return true;
|
|
}
|
|
case R.id.action_unset_keep_files_offline: {
|
|
mContainerActivity.getFileOperationsHelper().toggleOfflineFiles(checkedFiles, false);
|
|
return true;
|
|
}
|
|
case R.id.action_favorite: {
|
|
mContainerActivity.getFileOperationsHelper().toggleFavoriteFiles(checkedFiles, true);
|
|
return true;
|
|
}
|
|
case R.id.action_unset_favorite: {
|
|
mContainerActivity.getFileOperationsHelper().toggleFavoriteFiles(checkedFiles, false);
|
|
return true;
|
|
}
|
|
case R.id.action_move: {
|
|
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
|
|
action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, checkedFiles);
|
|
action.putExtra(FolderPickerActivity.EXTRA_ACTION, getResources().getText(R.string.move_to));
|
|
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES);
|
|
return true;
|
|
}
|
|
case R.id.action_copy: {
|
|
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
|
|
action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, checkedFiles);
|
|
action.putExtra(FolderPickerActivity.EXTRA_ACTION, getResources().getText(R.string.copy_to));
|
|
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES);
|
|
return true;
|
|
}
|
|
case R.id.action_select_all_action_menu: {
|
|
selectAllFiles(true);
|
|
return true;
|
|
}
|
|
case R.id.action_deselect_all_action_menu: {
|
|
selectAllFiles(false);
|
|
return true;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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, boolean, boolean)} with a null parameter
|
|
*/
|
|
public void listDirectory(boolean onlyOnDevice, boolean fromSearch) {
|
|
listDirectory(null, onlyOnDevice, fromSearch);
|
|
}
|
|
|
|
public void refreshDirectory() {
|
|
searchFragment = false;
|
|
|
|
setFabEnabled(true);
|
|
listDirectory(getCurrentFile(), MainApp.isOnlyOnDevice(), false);
|
|
}
|
|
|
|
/**
|
|
* 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, boolean onlyOnDevice, boolean fromSearch) {
|
|
if (!searchFragment) {
|
|
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());
|
|
}
|
|
|
|
|
|
if (searchView != null && !searchView.isIconified() && !fromSearch) {
|
|
|
|
searchView.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
searchView.setQuery("", false);
|
|
searchView.onActionViewCollapsed();
|
|
Activity activity;
|
|
if ((activity = getActivity()) != null && activity instanceof FileDisplayActivity) {
|
|
FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) activity;
|
|
if (getCurrentFile() != null) {
|
|
fileDisplayActivity.setDrawerIndicatorEnabled(
|
|
fileDisplayActivity.isRoot(getCurrentFile()));
|
|
}
|
|
}
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
mAdapter.swapDirectory(directory, storageManager, onlyOnDevice);
|
|
if (mFile == null || !mFile.equals(directory)) {
|
|
mCurrentListView.setSelection(0);
|
|
}
|
|
mFile = directory;
|
|
|
|
// hide create new folder within encrypted folders for now
|
|
if (mFile.isEncrypted()) {
|
|
getFabMkdir().setVisibility(View.GONE);
|
|
} else {
|
|
getFabMkdir().setVisibility(View.VISIBLE);
|
|
|
|
if (miniFabClicked) {
|
|
((TextView) getFabMkdir().getTag(com.getbase.floatingactionbutton.R.id.fab_label))
|
|
.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
|
|
updateLayout();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateFooter() {
|
|
if (!mJustFolders) {
|
|
int filesCount = 0;
|
|
int foldersCount = 0;
|
|
int count = mAdapter.getCount();
|
|
OCFile file;
|
|
for (int i = 0; i < count; i++) {
|
|
file = (OCFile) mAdapter.getItem(i);
|
|
if (file.isFolder()) {
|
|
foldersCount++;
|
|
} else {
|
|
if (!file.isHidden()) {
|
|
filesCount++;
|
|
}
|
|
}
|
|
}
|
|
// set footer text
|
|
setFooterText(generateFooterText(filesCount, foldersCount));
|
|
}
|
|
}
|
|
|
|
private void updateLayout() {
|
|
if (!mJustFolders) {
|
|
updateFooter();
|
|
// decide grid vs list view
|
|
OwnCloudVersion version = AccountUtils.getServerVersion(
|
|
((FileActivity) mContainerActivity).getAccount());
|
|
if (version != null && version.supportsRemoteThumbnails() &&
|
|
isGridViewPreferred(mFile)) {
|
|
switchToGridView();
|
|
} else {
|
|
switchToListView();
|
|
}
|
|
}
|
|
invalidateActionMode();
|
|
}
|
|
|
|
private void invalidateActionMode() {
|
|
if (mActiveActionMode != null) {
|
|
mActiveActionMode.invalidate();
|
|
}
|
|
}
|
|
|
|
private String generateFooterText(int filesCount, int foldersCount) {
|
|
String output = "";
|
|
|
|
if (getActivity() != null) {
|
|
if (filesCount + foldersCount <= 0) {
|
|
output = "";
|
|
} else if (foldersCount <= 0) {
|
|
output = getResources().getQuantityString(
|
|
R.plurals.file_list__footer__file,
|
|
filesCount,
|
|
filesCount
|
|
);
|
|
} else if (filesCount <= 0) {
|
|
output = getResources().getQuantityString(
|
|
R.plurals.file_list__footer__folder,
|
|
foldersCount,
|
|
foldersCount
|
|
);
|
|
} else {
|
|
output = getResources().getQuantityString(
|
|
R.plurals.file_list__footer__file,
|
|
filesCount,
|
|
filesCount)
|
|
+ ", "
|
|
+ getResources().getQuantityString(
|
|
R.plurals.file_list__footer__folder,
|
|
foldersCount,
|
|
foldersCount
|
|
);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
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 folder Folder to check.
|
|
* @return 'true' is folder should be shown in grid mode, 'false' if list mode is preferred.
|
|
*/
|
|
public boolean isGridViewPreferred(OCFile folder) {
|
|
return PreferenceManager.getFolderLayout(getActivity(), folder).equals(FOLDER_LAYOUT_GRID);
|
|
}
|
|
|
|
public void setListAsPreferred() {
|
|
PreferenceManager.setFolderLayout(getActivity(), mFile, FOLDER_LAYOUT_LIST);
|
|
switchToListView();
|
|
}
|
|
|
|
public void setGridAsPreferred() {
|
|
PreferenceManager.setFolderLayout(getActivity(), mFile, FOLDER_LAYOUT_GRID);
|
|
switchToGridView();
|
|
}
|
|
|
|
private void changeGridIcon(Menu menu) {
|
|
MenuItem menuItem = menu.findItem(R.id.action_switch_view);
|
|
if (menuItem != null) {
|
|
if (isGridViewPreferred(mFile)) {
|
|
menuItem.setTitle(getString(R.string.action_switch_list_view));
|
|
menuItem.setIcon(R.drawable.ic_view_list);
|
|
} else {
|
|
menuItem.setTitle(getString(R.string.action_switch_grid_view));
|
|
menuItem.setIcon(R.drawable.ic_view_module);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void unsetAllMenuItems(final boolean unsetDrawer) {
|
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (unsetDrawer) {
|
|
EventBus.getDefault().post(new DummyDrawerEvent());
|
|
} else {
|
|
if (bottomNavigationView != null) {
|
|
bottomNavigationView.getMenu().findItem(R.id.nav_bar_files).setChecked(true);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
public void setTitleFromSearchEvent(SearchEvent event) {
|
|
prepareCurrentSearch(event);
|
|
setTitle();
|
|
}
|
|
|
|
private void setTitle() {
|
|
// set title
|
|
|
|
if (getActivity() instanceof FileDisplayActivity && currentSearchType != null) {
|
|
switch (currentSearchType) {
|
|
case FAVORITE_SEARCH:
|
|
setTitle(R.string.drawer_item_favorites);
|
|
break;
|
|
case PHOTO_SEARCH:
|
|
setTitle(R.string.drawer_item_photos);
|
|
break;
|
|
case VIDEO_SEARCH:
|
|
setTitle(R.string.drawer_item_videos);
|
|
break;
|
|
case RECENTLY_ADDED_SEARCH:
|
|
setTitle(R.string.drawer_item_recently_added);
|
|
break;
|
|
case RECENTLY_MODIFIED_SEARCH:
|
|
setTitle(R.string.drawer_item_recently_modified);
|
|
break;
|
|
case SHARED_FILTER:
|
|
setTitle(R.string.drawer_item_shared);
|
|
break;
|
|
default:
|
|
setTitle(ThemeUtils.getDefaultDisplayNameForRootFolder());
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void prepareActionBarItems(SearchEvent event) {
|
|
if (event != null) {
|
|
if (event.getSearchType().equals(SearchOperation.SearchType.CONTENT_TYPE_SEARCH)) {
|
|
if (event.getSearchQuery().equals("image/%")) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_GRID_AND_SORT;
|
|
} else if (event.getSearchQuery().equals("video/%")) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SEARCH;
|
|
}
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.FAVORITE_SEARCH)) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_ADDED_SEARCH)) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_MODIFIED_SEARCH)) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.SHARED_SEARCH)) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SEARCH;
|
|
}
|
|
|
|
}
|
|
|
|
if (currentSearchType != null && !currentSearchType.equals(SearchType.FILE_SEARCH) && getActivity() != null) {
|
|
getActivity().invalidateOptionsMenu();
|
|
}
|
|
}
|
|
|
|
private void setEmptyView(SearchEvent event) {
|
|
|
|
if (event != null) {
|
|
if (event.getSearchType().equals(SearchOperation.SearchType.FILE_SEARCH)) {
|
|
setEmptyListMessage(SearchType.FILE_SEARCH);
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.CONTENT_TYPE_SEARCH)) {
|
|
if (event.getSearchQuery().equals("image/%")) {
|
|
setEmptyListMessage(SearchType.PHOTO_SEARCH);
|
|
} else if (event.getSearchQuery().equals("video/%")) {
|
|
setEmptyListMessage(SearchType.VIDEO_SEARCH);
|
|
}
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.FAVORITE_SEARCH)) {
|
|
setEmptyListMessage(SearchType.FAVORITE_SEARCH);
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_ADDED_SEARCH)) {
|
|
setEmptyListMessage(SearchType.RECENTLY_ADDED_SEARCH);
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.RECENTLY_MODIFIED_SEARCH)) {
|
|
setEmptyListMessage(SearchType.RECENTLY_MODIFIED_SEARCH);
|
|
} else if (event.getSearchType().equals(SearchOperation.SearchType.SHARED_SEARCH)) {
|
|
setEmptyListMessage(SearchType.SHARED_FILTER);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
public void onMessageEvent(ChangeMenuEvent changeMenuEvent) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.ADD_GRID_AND_SORT_WITH_SEARCH;
|
|
if (getActivity() != null) {
|
|
getActivity().invalidateOptionsMenu();
|
|
setTitle(ThemeUtils.getDefaultDisplayNameForRootFolder());
|
|
}
|
|
|
|
getActivity().getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT);
|
|
getArguments().putParcelable(OCFileListFragment.SEARCH_EVENT, null);
|
|
|
|
setFabEnabled(true);
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(FavoriteEvent event) {
|
|
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
|
|
|
OwnCloudAccount ocAccount = null;
|
|
AccountManager mAccountMgr = AccountManager.get(getActivity());
|
|
|
|
try {
|
|
ocAccount = new OwnCloudAccount(
|
|
currentAccount,
|
|
MainApp.getAppContext()
|
|
);
|
|
|
|
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
getClientFor(ocAccount, MainApp.getAppContext());
|
|
|
|
String userId = mAccountMgr.getUserData(currentAccount,
|
|
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
|
|
|
if (TextUtils.isEmpty(userId)) {
|
|
userId = mClient.getCredentials().getUsername();
|
|
}
|
|
|
|
ToggleFavoriteOperation toggleFavoriteOperation = new ToggleFavoriteOperation(event.shouldFavorite,
|
|
event.remotePath, userId);
|
|
RemoteOperationResult remoteOperationResult = toggleFavoriteOperation.execute(mClient);
|
|
|
|
if (remoteOperationResult.isSuccess()) {
|
|
mAdapter.setFavoriteAttributeForItemID(event.remoteId, event.shouldFavorite);
|
|
}
|
|
|
|
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
|
|
Log_OC.e(TAG, "Account not found", e);
|
|
} catch (AuthenticatorException e) {
|
|
Log_OC.e(TAG, "Authentication failed", e);
|
|
} catch (IOException e) {
|
|
Log_OC.e(TAG, "IO error", e);
|
|
} catch (OperationCanceledException e) {
|
|
Log_OC.e(TAG, "Operation has been canceled", e);
|
|
}
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(final SearchEvent event) {
|
|
searchFragment = true;
|
|
setEmptyListLoadingMessage();
|
|
mAdapter.setData(new ArrayList<>(), SearchType.NO_SEARCH, mContainerActivity.getStorageManager(), mFile);
|
|
|
|
setFabEnabled(false);
|
|
|
|
if (event.getUnsetType().equals(SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR)) {
|
|
unsetAllMenuItems(false);
|
|
} else if (event.getUnsetType().equals(SearchEvent.UnsetType.UNSET_DRAWER)) {
|
|
unsetAllMenuItems(true);
|
|
}
|
|
|
|
|
|
if (bottomNavigationView != null && searchEvent != null) {
|
|
switch (currentSearchType) {
|
|
case FAVORITE_SEARCH:
|
|
DisplayUtils.setBottomBarItem(bottomNavigationView, R.id.nav_bar_favorites);
|
|
break;
|
|
case PHOTO_SEARCH:
|
|
DisplayUtils.setBottomBarItem(bottomNavigationView, R.id.nav_bar_photos);
|
|
break;
|
|
|
|
default:
|
|
DisplayUtils.setBottomBarItem(bottomNavigationView, -1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
Runnable switchViewsRunnable = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (isGridViewPreferred(mFile) && !isGridEnabled()) {
|
|
switchToGridView();
|
|
} else if (!isGridViewPreferred(mFile) && isGridEnabled()) {
|
|
switchToListView();
|
|
}
|
|
}
|
|
};
|
|
|
|
if (currentSearchType.equals(SearchType.PHOTO_SEARCH)) {
|
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
switchToGridView();
|
|
}
|
|
});
|
|
} else if (currentSearchType.equals(SearchType.NO_SEARCH) || currentSearchType.equals(
|
|
SearchType.REGULAR_FILTER)) {
|
|
new Handler(Looper.getMainLooper()).post(switchViewsRunnable);
|
|
} else {
|
|
new Handler(Looper.getMainLooper()).post(switchViewsRunnable);
|
|
}
|
|
|
|
final RemoteOperation remoteOperation;
|
|
if (!currentSearchType.equals(SearchType.SHARED_FILTER)) {
|
|
remoteOperation = new SearchOperation(event.getSearchQuery(), event.getSearchType());
|
|
} else {
|
|
remoteOperation = new GetRemoteSharesOperation();
|
|
}
|
|
|
|
final Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
|
|
|
remoteOperationAsyncTask = new AsyncTask() {
|
|
@Override
|
|
protected Object doInBackground(Object[] params) {
|
|
if (getContext() != null && !isCancelled()) {
|
|
RemoteOperationResult remoteOperationResult = remoteOperation.execute(currentAccount, getContext());
|
|
|
|
FileDataStorageManager storageManager = null;
|
|
if (mContainerActivity != null && mContainerActivity.getStorageManager() != null) {
|
|
storageManager = mContainerActivity.getStorageManager();
|
|
}
|
|
|
|
if (remoteOperationResult.isSuccess() && remoteOperationResult.getData() != null
|
|
&& !isCancelled() && searchFragment) {
|
|
if (remoteOperationResult.getData() == null || remoteOperationResult.getData().size() == 0) {
|
|
setEmptyView(event);
|
|
} else {
|
|
mAdapter.setData(remoteOperationResult.getData(), currentSearchType, storageManager, mFile);
|
|
}
|
|
|
|
final FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity();
|
|
if (fileDisplayActivity != null) {
|
|
fileDisplayActivity.runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (fileDisplayActivity != null) {
|
|
fileDisplayActivity.setIndeterminate(false);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return remoteOperationResult.isSuccess();
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onPostExecute(Object o) {
|
|
if (!isCancelled()) {
|
|
mAdapter.notifyDataSetChanged();
|
|
}
|
|
}
|
|
};
|
|
|
|
remoteOperationAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(EncryptionEvent event) {
|
|
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
|
|
|
OwnCloudAccount ocAccount = null;
|
|
try {
|
|
ocAccount = new OwnCloudAccount(currentAccount, MainApp.getAppContext());
|
|
|
|
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
getClientFor(ocAccount, MainApp.getAppContext());
|
|
|
|
ToggleEncryptionOperation toggleEncryptionOperation = new ToggleEncryptionOperation(event.localId,
|
|
event.remotePath, event.shouldBeEncrypted);
|
|
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(mClient);
|
|
|
|
if (remoteOperationResult.isSuccess()) {
|
|
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
|
} else if (remoteOperationResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
|
Snackbar.make(mCurrentListView, R.string.end_to_end_encryption_folder_not_empty, Snackbar.LENGTH_LONG).show();
|
|
} else {
|
|
Snackbar.make(mCurrentListView, R.string.common_error_unknown, Snackbar.LENGTH_LONG).show();
|
|
}
|
|
|
|
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
|
|
Log_OC.e(TAG, "Account not found", e);
|
|
} catch (AuthenticatorException e) {
|
|
Log_OC.e(TAG, "Authentication failed", e);
|
|
} catch (IOException e) {
|
|
Log_OC.e(TAG, "IO error", e);
|
|
} catch (OperationCanceledException e) {
|
|
Log_OC.e(TAG, "Operation has been canceled", e);
|
|
}
|
|
}
|
|
|
|
private void setTitle(@StringRes final int title) {
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (getActivity() != null && ((FileDisplayActivity) getActivity()).getSupportActionBar() != null) {
|
|
ThemeUtils.setColoredTitle(((FileDisplayActivity) getActivity()).getSupportActionBar(),
|
|
title, getContext());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void setTitle(final String title) {
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (getActivity() != null && ((FileDisplayActivity) getActivity()).getSupportActionBar() != null) {
|
|
ThemeUtils.setColoredTitle(((FileDisplayActivity) getActivity()).getSupportActionBar(), title);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onStart() {
|
|
super.onStart();
|
|
EventBus.getDefault().register(this);
|
|
}
|
|
|
|
@Override
|
|
public void onStop() {
|
|
EventBus.getDefault().unregister(this);
|
|
super.onStop();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onRefresh() {
|
|
if (searchEvent != null && searchFragment) {
|
|
onMessageEvent(searchEvent);
|
|
|
|
mRefreshListLayout.setRefreshing(false);
|
|
mRefreshGridLayout.setRefreshing(false);
|
|
mRefreshEmptyLayout.setRefreshing(false);
|
|
} else {
|
|
super.onRefresh();
|
|
}
|
|
}
|
|
|
|
public void setSearchFragment(boolean searchFragment) {
|
|
this.searchFragment = searchFragment;
|
|
}
|
|
|
|
public boolean getIsSearchFragment() {
|
|
return searchFragment;
|
|
}
|
|
|
|
/**
|
|
* De-/select all elements in the current list view.
|
|
*
|
|
* @param select <code>true</code> to select all, <code>false</code> to deselect all
|
|
*/
|
|
public void selectAllFiles(boolean select) {
|
|
AbsListView listView = getListView();
|
|
for (int position = 0; position < listView.getCount(); position++) {
|
|
listView.setItemChecked(position, select);
|
|
}
|
|
}
|
|
}
|