1704 lines
69 KiB
Java
1704 lines
69 KiB
Java
/*
|
|
* ownCloud Android client application
|
|
*
|
|
* @author Bartek Przybylski
|
|
* @author masensio
|
|
* @author David A. Velasco
|
|
* @author Andy Scherzinger
|
|
* @author Chris Narkiewicz
|
|
* Copyright (C) 2011 Bartek Przybylski
|
|
* Copyright (C) 2016 ownCloud Inc.
|
|
* Copyright (C) 2018 Andy Scherzinger
|
|
*
|
|
* 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.text.TextUtils;
|
|
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.PopupMenu;
|
|
import android.widget.RelativeLayout;
|
|
|
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|
import com.google.android.material.snackbar.Snackbar;
|
|
import com.nextcloud.client.account.UserAccountManager;
|
|
import com.nextcloud.client.di.Injectable;
|
|
import com.nextcloud.client.preferences.AppPreferences;
|
|
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.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.e2ee.ToggleEncryptionRemoteOperation;
|
|
import com.owncloud.android.lib.resources.files.SearchRemoteOperation;
|
|
import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation;
|
|
import com.owncloud.android.lib.resources.shares.GetRemoteSharesOperation;
|
|
import com.owncloud.android.lib.resources.status.OCCapability;
|
|
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.RichDocumentsWebView;
|
|
import com.owncloud.android.ui.activity.ToolbarActivity;
|
|
import com.owncloud.android.ui.activity.UploadFilesActivity;
|
|
import com.owncloud.android.ui.adapter.OCFileListAdapter;
|
|
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
|
|
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.CommentsEvent;
|
|
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.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.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.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.StringRes;
|
|
import androidx.appcompat.app.ActionBar;
|
|
import androidx.drawerlayout.widget.DrawerLayout;
|
|
import androidx.fragment.app.FragmentActivity;
|
|
import androidx.recyclerview.widget.GridLayoutManager;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|
|
|
/**
|
|
* 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,
|
|
OCFileListBottomSheetActions,
|
|
Injectable {
|
|
|
|
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_ONLY_FOLDERS_CLICKABLE = MY_PACKAGE + ".ONLY_FOLDERS_CLICKABLE";
|
|
public final static String ARG_FILE_SELECTABLE = MY_PACKAGE + ".FILE_SELECTABLE";
|
|
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 final static String ARG_SEARCH_ONLY_FOLDER = MY_PACKAGE + ".SEARCH_ONLY_FOLDER";
|
|
public final static String ARG_MIMETYPE = MY_PACKAGE + ".MIMETYPE";
|
|
|
|
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 DIALOG_CREATE_DOCUMENT = "DIALOG_CREATE_DOCUMENT";
|
|
|
|
private static final int SINGLE_SELECTION = 1;
|
|
|
|
@Inject AppPreferences preferences;
|
|
@Inject UserAccountManager accountManager;
|
|
private FileFragment.ContainerActivity mContainerActivity;
|
|
|
|
private OCFile mFile;
|
|
private OCFileListAdapter mAdapter;
|
|
private boolean mOnlyFoldersClickable;
|
|
private boolean mFileSelectable;
|
|
|
|
private int mSystemBarActionModeColor;
|
|
private int mSystemBarColor;
|
|
private int mProgressBarActionModeColor;
|
|
private int mProgressBarColor;
|
|
|
|
private boolean mHideFab = true;
|
|
private ActionMode mActiveActionMode;
|
|
private OCFileListFragment.MultiChoiceModeListener mMultiChoiceModeListener;
|
|
|
|
private BottomNavigationView bottomNavigationView;
|
|
|
|
private SearchType currentSearchType;
|
|
private boolean searchFragment;
|
|
private SearchEvent searchEvent;
|
|
private AsyncTask remoteOperationAsyncTask;
|
|
private String mLimitToMimeType;
|
|
|
|
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 List<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.primaryColor(getContext());
|
|
mProgressBarActionModeColor = getResources().getColor(R.color.action_mode_background);
|
|
mProgressBarColor = ThemeUtils.primaryColor(getContext());
|
|
mMultiChoiceModeListener = new MultiChoiceModeListener();
|
|
|
|
if (savedInstanceState != null) {
|
|
currentSearchType = Parcels.unwrap(savedInstanceState.getParcelable(KEY_CURRENT_SEARCH_TYPE));
|
|
searchEvent = Parcels.unwrap(savedInstanceState.getParcelable(OCFileListFragment.SEARCH_EVENT));
|
|
mFile = savedInstanceState.getParcelable(KEY_FILE);
|
|
}
|
|
|
|
searchFragment = currentSearchType != null && isSearchEventSet(searchEvent);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
if (getActivity() == null) {
|
|
return;
|
|
}
|
|
|
|
Intent intent = getActivity().getIntent();
|
|
|
|
if (intent.getParcelableExtra(OCFileListFragment.SEARCH_EVENT) != null) {
|
|
searchEvent = Parcels.unwrap(intent.getParcelableExtra(OCFileListFragment.SEARCH_EVENT));
|
|
onMessageEvent(searchEvent);
|
|
}
|
|
|
|
super.onResume();
|
|
}
|
|
|
|
/**
|
|
* {@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 IllegalArgumentException(context.toString() + " must implement " +
|
|
FileFragment.ContainerActivity.class.getSimpleName(), e);
|
|
}
|
|
try {
|
|
setOnRefreshListener((OnEnforceableRefreshListener) context);
|
|
|
|
} catch (ClassCastException e) {
|
|
throw new IllegalArgumentException(context.toString() + " must implement " +
|
|
SwipeRefreshLayout.OnRefreshListener.class.getSimpleName(), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public View onCreateView(@NonNull 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
|
|
&& Parcels.unwrap(savedInstanceState.getParcelable(KEY_CURRENT_SEARCH_TYPE)) != null &&
|
|
Parcels.unwrap(savedInstanceState.getParcelable(OCFileListFragment.SEARCH_EVENT)) != null) {
|
|
searchFragment = true;
|
|
currentSearchType = Parcels.unwrap(savedInstanceState.getParcelable(KEY_CURRENT_SEARCH_TYPE));
|
|
searchEvent = Parcels.unwrap(savedInstanceState.getParcelable(OCFileListFragment.SEARCH_EVENT));
|
|
} else {
|
|
currentSearchType = SearchType.NO_SEARCH;
|
|
}
|
|
|
|
if (getResources().getBoolean(R.bool.bottom_toolbar_enabled)) {
|
|
bottomNavigationView.setVisibility(View.VISIBLE);
|
|
DisplayUtils.setupBottomBar(
|
|
accountManager.getCurrentAccount(),
|
|
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 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);
|
|
}
|
|
|
|
Bundle args = getArguments();
|
|
mOnlyFoldersClickable = args != null && args.getBoolean(ARG_ONLY_FOLDERS_CLICKABLE, false);
|
|
mFileSelectable = args != null && args.getBoolean(ARG_FILE_SELECTABLE, false);
|
|
mLimitToMimeType = args != null ? args.getString(ARG_MIMETYPE, "") : "";
|
|
boolean hideItemOptions = args != null && args.getBoolean(ARG_HIDE_ITEM_OPTIONS, false);
|
|
|
|
mAdapter = new OCFileListAdapter(
|
|
getActivity(),
|
|
accountManager.getCurrentAccount(),
|
|
preferences,
|
|
mContainerActivity,
|
|
this,
|
|
hideItemOptions,
|
|
isGridViewPreferred(mFile)
|
|
);
|
|
setRecyclerViewAdapter(mAdapter);
|
|
|
|
mHideFab = args != null && args.getBoolean(ARG_HIDE_FAB, false);
|
|
|
|
if (mHideFab) {
|
|
setFabVisible(false);
|
|
} else {
|
|
setFabVisible(true);
|
|
registerFabListener();
|
|
}
|
|
|
|
searchEvent = Parcels.unwrap(getArguments().getParcelable(OCFileListFragment.SEARCH_EVENT));
|
|
prepareCurrentSearch(searchEvent);
|
|
|
|
if (isGridViewPreferred(getCurrentFile())) {
|
|
switchToGridView();
|
|
}
|
|
|
|
setTitle();
|
|
}
|
|
|
|
private void prepareCurrentSearch(SearchEvent event) {
|
|
if (isSearchEventSet(event)) {
|
|
if (SearchRemoteOperation.SearchType.FILE_SEARCH.equals(event.getSearchType())) {
|
|
currentSearchType = SearchType.FILE_SEARCH;
|
|
|
|
} else if (SearchRemoteOperation.SearchType.CONTENT_TYPE_SEARCH.equals(event.getSearchType())) {
|
|
if ("image/%".equals(event.getSearchQuery())) {
|
|
currentSearchType = SearchType.PHOTO_SEARCH;
|
|
} else if ("video/%".equals(event.getSearchQuery())) {
|
|
currentSearchType = SearchType.VIDEO_SEARCH;
|
|
}
|
|
} else if (SearchRemoteOperation.SearchType.FAVORITE_SEARCH.equals(event.getSearchType())) {
|
|
currentSearchType = SearchType.FAVORITE_SEARCH;
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_ADDED_SEARCH.equals(event.getSearchType())) {
|
|
currentSearchType = SearchType.RECENTLY_ADDED_SEARCH;
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_MODIFIED_SEARCH.equals(event.getSearchType())) {
|
|
currentSearchType = SearchType.RECENTLY_MODIFIED_SEARCH;
|
|
} else if (SearchRemoteOperation.SearchType.SHARED_SEARCH.equals(event.getSearchType())) {
|
|
currentSearchType = SearchType.SHARED_FILTER;
|
|
}
|
|
|
|
prepareActionBarItems(event);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* register listener on FAB.
|
|
*/
|
|
private void registerFabListener() {
|
|
FileActivity activity = (FileActivity) getActivity();
|
|
getFabMain().setOnClickListener(v -> {
|
|
new OCFileListBottomSheetDialog(activity, this).show();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void createFolder() {
|
|
CreateFolderDialogFragment.newInstance(mFile)
|
|
.show(getActivity().getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
|
|
}
|
|
|
|
@Override
|
|
public void uploadFromApp() {
|
|
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
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public void directCameraUpload() {
|
|
FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity();
|
|
|
|
if (fileDisplayActivity != null) {
|
|
fileDisplayActivity.getFileOperationsHelper()
|
|
.uploadFromCamera(fileDisplayActivity, FileDisplayActivity.REQUEST_CODE__UPLOAD_FROM_CAMERA);
|
|
} else {
|
|
DisplayUtils.showSnackMessage(getView(), getString(R.string.error_starting_direct_camera_upload));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void uploadFiles() {
|
|
UploadFilesActivity.startUploadActivityForResult(
|
|
getActivity(),
|
|
((FileActivity) getActivity()).getAccount(),
|
|
FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public void onShareIconClick(OCFile file) {
|
|
if (file.isFolder()) {
|
|
mContainerActivity.showDetails(file, 1);
|
|
} else {
|
|
mContainerActivity.getFileOperationsHelper().sendShareFile(file);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void showShareDetailView(OCFile file) {
|
|
mContainerActivity.showDetails(file, 1);
|
|
}
|
|
|
|
@Override
|
|
public void showActivityDetailView(OCFile file) {
|
|
mContainerActivity.showDetails(file, 0);
|
|
}
|
|
|
|
@Override
|
|
public void onOverflowIconClicked(OCFile file, View view) {
|
|
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(item -> {
|
|
Set<OCFile> checkedFiles = new HashSet<>();
|
|
checkedFiles.add(file);
|
|
return onFileActionChosen(item.getItemId(), checkedFiles);
|
|
});
|
|
popup.show();
|
|
}
|
|
|
|
@Override
|
|
public void newDocument() {
|
|
ChooseTemplateDialogFragment.newInstance(mFile, ChooseTemplateDialogFragment.Type.DOCUMENT)
|
|
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
|
}
|
|
|
|
@Override
|
|
public void newSpreadsheet() {
|
|
ChooseTemplateDialogFragment.newInstance(mFile, ChooseTemplateDialogFragment.Type.SPREADSHEET)
|
|
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
|
}
|
|
|
|
@Override
|
|
public void newPresentation() {
|
|
ChooseTemplateDialogFragment.newInstance(mFile, ChooseTemplateDialogFragment.Type.PRESENTATION)
|
|
.show(requireActivity().getSupportFragmentManager(), DIALOG_CREATE_DOCUMENT);
|
|
}
|
|
|
|
/**
|
|
* Handler for multiple selection mode.
|
|
* <p>
|
|
* Manages input from the user when one or more files or folders are selected in the list.
|
|
* <p>
|
|
* 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";
|
|
|
|
/**
|
|
* True when action mode is finished because the drawer was opened
|
|
*/
|
|
private boolean mActionModeClosedByDrawer;
|
|
|
|
/**
|
|
* Selected items in list when action mode is closed by drawer
|
|
*/
|
|
private Set<OCFile> mSelectionWhenActionModeClosedByDrawer = new HashSet<>();
|
|
|
|
@Override
|
|
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
|
|
// nothing to do
|
|
}
|
|
|
|
@Override
|
|
public void onDrawerOpened(@NonNull 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(@NonNull View drawerView) {
|
|
if (mActionModeClosedByDrawer && mSelectionWhenActionModeClosedByDrawer.size() > 0) {
|
|
FragmentActivity actionBarActivity = getActivity();
|
|
actionBarActivity.startActionMode(mMultiChoiceModeListener);
|
|
|
|
getAdapter().setCheckedItem(mSelectionWhenActionModeClosedByDrawer);
|
|
|
|
mActiveActionMode.invalidate();
|
|
|
|
mSelectionWhenActionModeClosedByDrawer.clear();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.addAll(((OCFileListAdapter) getRecyclerView().getAdapter())
|
|
.getCheckedItems());
|
|
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) {
|
|
// nothing to do here
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
setFabVisible(false);
|
|
|
|
mAdapter.setMultiSelect(true);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Updates available action in menu depending on current selection.
|
|
*/
|
|
@Override
|
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
|
Set<OCFile> checkedFiles = mAdapter.getCheckedItems();
|
|
final int checkedCount = mAdapter.getCheckedItems().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) {
|
|
Set<OCFile> checkedFiles = mAdapter.getCheckedItems();
|
|
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) {
|
|
setFabVisible(true);
|
|
}
|
|
|
|
mAdapter.setMultiSelect(false);
|
|
mAdapter.clearCheckedItems();
|
|
}
|
|
|
|
|
|
public void storeStateIn(Bundle outState) {
|
|
outState.putBoolean(KEY_ACTION_MODE_CLOSED_BY_DRAWER, mActionModeClosedByDrawer);
|
|
}
|
|
|
|
public void loadStateFrom(Bundle savedInstanceState) {
|
|
mActionModeClosedByDrawer = savedInstanceState.getBoolean(KEY_ACTION_MODE_CLOSED_BY_DRAWER,
|
|
mActionModeClosedByDrawer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Init listener that will handle interactions in multiple selection mode.
|
|
*/
|
|
private void setChoiceModeAsMultipleModal(Bundle savedInstanceState) {
|
|
if (savedInstanceState != null) {
|
|
mMultiChoiceModeListener.loadStateFrom(savedInstanceState);
|
|
}
|
|
((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 (isSearchEventSet(searchEvent)) {
|
|
onMessageEvent(searchEvent);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves the current listed folder.
|
|
*/
|
|
@Override
|
|
public void onSaveInstanceState(@NonNull Bundle outState) {
|
|
outState.putParcelable(KEY_FILE, mFile);
|
|
if (searchFragment) {
|
|
outState.putParcelable(KEY_CURRENT_SEARCH_TYPE, Parcels.wrap(currentSearchType));
|
|
if (isSearchEventSet(searchEvent)) {
|
|
outState.putParcelable(OCFileListFragment.SEARCH_EVENT, Parcels.wrap(searchEvent));
|
|
}
|
|
}
|
|
mMultiChoiceModeListener.storeStateIn(outState);
|
|
|
|
super.onSaveInstanceState(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 == 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 == 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 == MenuItemAddRemove.REMOVE_SEARCH) {
|
|
menu.removeItem(R.id.action_search);
|
|
} else if (menuItemAddRemoveValue == 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 == MenuItemAddRemove.REMOVE_SORT) {
|
|
menu.removeItem(R.id.action_sort);
|
|
menu.removeItem(R.id.action_search);
|
|
} else if (menuItemAddRemoveValue == 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.
|
|
*
|
|
* 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 boolean onLongItemClicked(OCFile file) {
|
|
FragmentActivity actionBarActivity = getActivity();
|
|
getAdapter().addCheckedFile(file);
|
|
actionBarActivity.startActionMode(mMultiChoiceModeListener);
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onItemClicked(OCFile file) {
|
|
if (getAdapter().isMultiSelect()) {
|
|
if (getAdapter().isCheckedFile(file)) {
|
|
getAdapter().removeCheckedFile(file);
|
|
} else {
|
|
getAdapter().addCheckedFile(file);
|
|
}
|
|
mActiveActionMode.invalidate();
|
|
mAdapter.notifyItemChanged(getAdapter().getItemPosition(file));
|
|
} else {
|
|
if (file != null) {
|
|
int position = mAdapter.getItemPosition(file);
|
|
|
|
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(getRecyclerView(), R.string.end_to_end_encryption_not_supported,
|
|
Snackbar.LENGTH_LONG).show();
|
|
return;
|
|
}
|
|
|
|
Account account = ((FileActivity) mContainerActivity).getAccount();
|
|
|
|
// check if e2e app is enabled
|
|
OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(account.name);
|
|
|
|
if (ocCapability.getEndToEndEncryption().isFalse() ||
|
|
ocCapability.getEndToEndEncryption().isUnknown()) {
|
|
Snackbar.make(getRecyclerView(), R.string.end_to_end_encryption_not_enabled,
|
|
Snackbar.LENGTH_LONG).show();
|
|
return;
|
|
}// check if keys are stored
|
|
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(
|
|
getContext().getContentResolver());
|
|
|
|
|
|
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;
|
|
|
|
if (mContainerActivity instanceof FolderPickerActivity &&
|
|
((FolderPickerActivity) mContainerActivity)
|
|
.isDoNotEnterEncryptedFolder()) {
|
|
Snackbar.make(getRecyclerView(),
|
|
R.string.copy_move_to_encrypted_folder_not_supported,
|
|
Snackbar.LENGTH_LONG).show();
|
|
} else {
|
|
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 if (mFileSelectable) {
|
|
Intent intent = new Intent();
|
|
intent.putExtra(FolderPickerActivity.EXTRA_FILES, file);
|
|
getActivity().setResult(Activity.RESULT_OK, intent);
|
|
getActivity().finish();
|
|
} else if (!mOnlyFoldersClickable) { // 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, true, false);
|
|
} else {
|
|
mContainerActivity.getFileOperationsHelper().openFile(file);
|
|
}
|
|
} else {
|
|
Account account = accountManager.getCurrentAccount();
|
|
OCCapability capability = mContainerActivity.getStorageManager().getCapability(account.name);
|
|
|
|
if (PreviewMediaFragment.canBePreviewed(file) && AccountUtils.getServerVersion(account)
|
|
.isMediaStreamingSupported()) {
|
|
// stream media preview on >= NC14
|
|
((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, true);
|
|
} else if (capability.getRichDocumentsMimeTypeList().contains(file.getMimeType()) &&
|
|
android.os.Build.VERSION.SDK_INT >= RichDocumentsWebView.MINIMUM_API &&
|
|
capability.getRichDocumentsDirectEditing().isTrue()) {
|
|
mContainerActivity.getFileOperationsHelper().openFileAsRichDocument(file, getContext());
|
|
} 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 = 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, Set<OCFile> checkedFiles) {
|
|
if (checkedFiles.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
if (checkedFiles.size() == SINGLE_SELECTION) {
|
|
/// action only possible on a single file
|
|
OCFile singleFile = checkedFiles.iterator().next();
|
|
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_stream_media: {
|
|
mContainerActivity.getFileOperationsHelper().streamMediaFile(singleFile);
|
|
return true;
|
|
}
|
|
case R.id.action_open_file_as_richdocument: {
|
|
mContainerActivity.getFileOperationsHelper().openFileAsRichDocument(singleFile, getContext());
|
|
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(new ArrayList<>(checkedFiles), mActiveActionMode);
|
|
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
|
|
return true;
|
|
}
|
|
case R.id.action_download_file:
|
|
case R.id.action_sync_file: {
|
|
mContainerActivity.getFileOperationsHelper().syncFiles(checkedFiles);
|
|
exitSelectionMode();
|
|
return true;
|
|
}
|
|
case R.id.action_cancel_sync: {
|
|
((FileDisplayActivity) mContainerActivity).cancelTransference(checkedFiles);
|
|
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, new ArrayList<>(checkedFiles));
|
|
action.putExtra(FolderPickerActivity.EXTRA_CURRENT_FOLDER, mFile);
|
|
action.putExtra(FolderPickerActivity.EXTRA_ACTION, FolderPickerActivity.MOVE);
|
|
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, new ArrayList<>(checkedFiles));
|
|
action.putExtra(FolderPickerActivity.EXTRA_CURRENT_FOLDER, mFile);
|
|
action.putExtra(FolderPickerActivity.EXTRA_ACTION, FolderPickerActivity.COPY);
|
|
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;
|
|
|
|
setFabVisible(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(
|
|
accountManager.getCurrentAccount(),
|
|
directory,
|
|
storageManager,
|
|
onlyOnDevice,
|
|
mLimitToMimeType
|
|
);
|
|
if (mFile == null || !mFile.equals(directory)) {
|
|
getRecyclerView().scrollToPosition(0);
|
|
}
|
|
mFile = directory;
|
|
|
|
updateLayout();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateLayout() {
|
|
// decide grid vs list view
|
|
if (isGridViewPreferred(mFile)) {
|
|
switchToGridView();
|
|
} else {
|
|
switchToListView();
|
|
}
|
|
|
|
// FAB
|
|
setFabEnabled(mFile.canWrite());
|
|
|
|
invalidateActionMode();
|
|
}
|
|
|
|
private void invalidateActionMode() {
|
|
if (mActiveActionMode != null) {
|
|
mActiveActionMode.invalidate();
|
|
}
|
|
}
|
|
|
|
|
|
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 FOLDER_LAYOUT_GRID.equals(preferences.getFolderLayout(folder));
|
|
}
|
|
|
|
public void setListAsPreferred() {
|
|
preferences.setFolderLayout(mFile, FOLDER_LAYOUT_LIST);
|
|
switchToListView();
|
|
}
|
|
|
|
public void switchToListView() {
|
|
if (isGridEnabled()) {
|
|
switchLayoutManager(false);
|
|
}
|
|
}
|
|
|
|
public void setGridAsPreferred() {
|
|
preferences.setFolderLayout(mFile, FOLDER_LAYOUT_GRID);
|
|
switchToGridView();
|
|
}
|
|
|
|
public void switchToGridView() {
|
|
if (!isGridEnabled()) {
|
|
switchLayoutManager(true);
|
|
}
|
|
}
|
|
|
|
public void switchLayoutManager(boolean grid) {
|
|
int position = 0;
|
|
|
|
if (getRecyclerView().getLayoutManager() != null) {
|
|
position = ((LinearLayoutManager) getRecyclerView().getLayoutManager())
|
|
.findFirstCompletelyVisibleItemPosition();
|
|
}
|
|
|
|
RecyclerView.LayoutManager layoutManager;
|
|
if (grid) {
|
|
layoutManager = new GridLayoutManager(getContext(), getColumnsCount());
|
|
((GridLayoutManager) layoutManager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
|
@Override
|
|
public int getSpanSize(int position) {
|
|
if (position == getAdapter().getItemCount() - 1) {
|
|
return ((GridLayoutManager) layoutManager).getSpanCount();
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
});
|
|
|
|
} else {
|
|
layoutManager = new LinearLayoutManager(getContext());
|
|
}
|
|
|
|
getRecyclerView().setLayoutManager(layoutManager);
|
|
getRecyclerView().scrollToPosition(position);
|
|
getAdapter().setGridView(grid);
|
|
getRecyclerView().setAdapter(getAdapter());
|
|
getAdapter().notifyDataSetChanged();
|
|
}
|
|
|
|
public OCFileListAdapter getAdapter() {
|
|
return mAdapter;
|
|
}
|
|
|
|
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(getContext()));
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void prepareActionBarItems(SearchEvent event) {
|
|
if (event != null) {
|
|
if (SearchRemoteOperation.SearchType.CONTENT_TYPE_SEARCH.equals(event.getSearchType())) {
|
|
if ("image/%".equals(event.getSearchQuery())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_GRID_AND_SORT;
|
|
} else if ("video/%".equals(event.getSearchQuery())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SEARCH;
|
|
}
|
|
} else if (SearchRemoteOperation.SearchType.FAVORITE_SEARCH.equals(event.getSearchType())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_ADDED_SEARCH.equals(event.getSearchType())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_MODIFIED_SEARCH.equals(event.getSearchType())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SORT;
|
|
} else if (SearchRemoteOperation.SearchType.SHARED_SEARCH.equals(event.getSearchType())) {
|
|
menuItemAddRemoveValue = MenuItemAddRemove.REMOVE_SEARCH;
|
|
}
|
|
}
|
|
|
|
if (SearchType.FILE_SEARCH != currentSearchType && getActivity() != null) {
|
|
getActivity().invalidateOptionsMenu();
|
|
}
|
|
}
|
|
|
|
private void setEmptyView(SearchEvent event) {
|
|
|
|
if (event != null) {
|
|
if (SearchRemoteOperation.SearchType.FILE_SEARCH == event.getSearchType()) {
|
|
setEmptyListMessage(SearchType.FILE_SEARCH);
|
|
} else if (event.getSearchType() == SearchRemoteOperation.SearchType.CONTENT_TYPE_SEARCH) {
|
|
if ("image/%".equals(event.getSearchQuery())) {
|
|
setEmptyListMessage(SearchType.PHOTO_SEARCH);
|
|
} else if ("video/%".equals(event.getSearchQuery())) {
|
|
setEmptyListMessage(SearchType.VIDEO_SEARCH);
|
|
}
|
|
} else if (SearchRemoteOperation.SearchType.FAVORITE_SEARCH == event.getSearchType()) {
|
|
setEmptyListMessage(SearchType.FAVORITE_SEARCH);
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_ADDED_SEARCH == event.getSearchType()) {
|
|
setEmptyListMessage(SearchType.RECENTLY_ADDED_SEARCH);
|
|
} else if (SearchRemoteOperation.SearchType.RECENTLY_MODIFIED_SEARCH == event.getSearchType()) {
|
|
setEmptyListMessage(SearchType.RECENTLY_MODIFIED_SEARCH);
|
|
} else if (SearchRemoteOperation.SearchType.SHARED_SEARCH == event.getSearchType()) {
|
|
setEmptyListMessage(SearchType.SHARED_FILTER);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
public void onMessageEvent(ChangeMenuEvent changeMenuEvent) {
|
|
searchFragment = false;
|
|
searchEvent = new SearchEvent();
|
|
|
|
menuItemAddRemoveValue = MenuItemAddRemove.ADD_GRID_AND_SORT_WITH_SEARCH;
|
|
if (getActivity() != null) {
|
|
getActivity().invalidateOptionsMenu();
|
|
setTitle(ThemeUtils.getDefaultDisplayNameForRootFolder(getContext()));
|
|
}
|
|
|
|
getActivity().getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT);
|
|
getArguments().putParcelable(OCFileListFragment.SEARCH_EVENT, null);
|
|
|
|
setFabVisible(true);
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(CommentsEvent event) {
|
|
mAdapter.refreshCommentsCount(event.remoteId);
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(FavoriteEvent event) {
|
|
Account currentAccount = accountManager.getCurrentAccount();
|
|
|
|
OwnCloudAccount ocAccount;
|
|
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();
|
|
}
|
|
|
|
ToggleFavoriteRemoteOperation toggleFavoriteOperation = new ToggleFavoriteRemoteOperation(
|
|
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 | AuthenticatorException
|
|
| IOException | OperationCanceledException e) {
|
|
Log_OC.e(TAG, "Error processing event", e);
|
|
}
|
|
}
|
|
|
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
|
public void onMessageEvent(final SearchEvent event) {
|
|
prepareCurrentSearch(event);
|
|
searchFragment = true;
|
|
setEmptyListLoadingMessage();
|
|
mAdapter.setData(new ArrayList<>(), SearchType.NO_SEARCH, mContainerActivity.getStorageManager(), mFile);
|
|
|
|
setFabVisible(false);
|
|
|
|
if (event.getUnsetType() == SearchEvent.UnsetType.UNSET_BOTTOM_NAV_BAR) {
|
|
unsetAllMenuItems(false);
|
|
} else if (event.getUnsetType() == SearchEvent.UnsetType.UNSET_DRAWER) {
|
|
unsetAllMenuItems(true);
|
|
}
|
|
|
|
|
|
if (bottomNavigationView != null && isSearchEventSet(searchEvent)) {
|
|
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 == SearchType.PHOTO_SEARCH) {
|
|
new Handler(Looper.getMainLooper()).post(this::switchToGridView);
|
|
} else {
|
|
new Handler(Looper.getMainLooper()).post(switchViewsRunnable);
|
|
}
|
|
|
|
final Account currentAccount = accountManager.getCurrentAccount();
|
|
|
|
final RemoteOperation remoteOperation;
|
|
if (currentSearchType != SearchType.SHARED_FILTER) {
|
|
boolean searchOnlyFolders = false;
|
|
if (getArguments() != null && getArguments().getBoolean(ARG_SEARCH_ONLY_FOLDER, false)) {
|
|
searchOnlyFolders = true;
|
|
}
|
|
|
|
String userId = AccountManager.get(MainApp.getAppContext()).getUserData(currentAccount,
|
|
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
|
|
|
remoteOperation = new SearchRemoteOperation(event.getSearchQuery(), event.getSearchType(),
|
|
searchOnlyFolders, userId);
|
|
} else {
|
|
remoteOperation = new GetRemoteSharesOperation();
|
|
}
|
|
|
|
remoteOperationAsyncTask = new AsyncTask() {
|
|
@Override
|
|
protected Object doInBackground(Object[] params) {
|
|
setTitle();
|
|
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);
|
|
searchEvent = event;
|
|
}
|
|
|
|
final ToolbarActivity fileDisplayActivity = (ToolbarActivity) 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 = accountManager.getCurrentAccount();
|
|
|
|
OwnCloudAccount ocAccount;
|
|
try {
|
|
ocAccount = new OwnCloudAccount(currentAccount, MainApp.getAppContext());
|
|
|
|
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
getClientFor(ocAccount, MainApp.getAppContext());
|
|
|
|
ToggleEncryptionRemoteOperation toggleEncryptionOperation = new ToggleEncryptionRemoteOperation(
|
|
event.localId, event.remotePath, event.shouldBeEncrypted);
|
|
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(mClient, true);
|
|
|
|
if (remoteOperationResult.isSuccess()) {
|
|
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
|
} else if (remoteOperationResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
|
Snackbar.make(getRecyclerView(), R.string.end_to_end_encryption_folder_not_empty, Snackbar.LENGTH_LONG).show();
|
|
} else {
|
|
Snackbar.make(getRecyclerView(), 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) {
|
|
ActionBar actionBar = ((FileDisplayActivity) getActivity()).getSupportActionBar();
|
|
|
|
if (actionBar != null) {
|
|
ThemeUtils.setColoredTitle(actionBar, title, getContext());
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@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 (isSearchEventSet(searchEvent) && searchFragment) {
|
|
onMessageEvent(searchEvent);
|
|
|
|
mRefreshListLayout.setRefreshing(false);
|
|
} else {
|
|
searchFragment = false;
|
|
super.onRefresh();
|
|
}
|
|
}
|
|
|
|
public void setSearchFragment(boolean searchFragment) {
|
|
this.searchFragment = searchFragment;
|
|
}
|
|
|
|
public boolean isSearchFragment() {
|
|
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) {
|
|
OCFileListAdapter ocFileListAdapter = (OCFileListAdapter) getRecyclerView().getAdapter();
|
|
|
|
if (select) {
|
|
ocFileListAdapter.addAllFilesToCheckedFiles();
|
|
} else {
|
|
ocFileListAdapter.removeAllFilesFromCheckedFiles();
|
|
}
|
|
|
|
for (int i = 0; i < mAdapter.getItemCount(); i++) {
|
|
mAdapter.notifyItemChanged(i);
|
|
}
|
|
|
|
mActiveActionMode.invalidate();
|
|
}
|
|
|
|
/**
|
|
* Exits the multi file selection mode.
|
|
*/
|
|
public void exitSelectionMode() {
|
|
if (mActiveActionMode != null) {
|
|
mActiveActionMode.finish();
|
|
}
|
|
}
|
|
|
|
private boolean isSearchEventSet(SearchEvent event) {
|
|
return event != null && !TextUtils.isEmpty(event.getSearchQuery()) && event.getSearchType() != null
|
|
&& event.getUnsetType() != null;
|
|
}
|
|
}
|