Merge remote-tracking branch 'owncloud/multiSelect' into multiSelectOwncloud

# Conflicts:
#	res/drawable-hdpi/ic_checkbox_marked.png
#	res/drawable-mdpi/ic_checkbox_marked.png
#	res/drawable-xhdpi/ic_checkbox_marked.png
#	res/drawable-xxhdpi/ic_checkbox_marked.png
#	res/layout/grid_image.xml
#	res/values/strings.xml
#	src/com/owncloud/android/notifications/NotificationBuilderWithProgressBar.java
#	src/com/owncloud/android/ui/activity/FileDisplayActivity.java
#	src/com/owncloud/android/ui/adapter/FileListListAdapter.java
#	src/com/owncloud/android/ui/dialog/RemoveFileDialogFragment.java
#	src/com/owncloud/android/ui/fragment/OCFileListFragment.java
This commit is contained in:
tobiasKaminsky 2016-06-23 21:10:58 +02:00
Родитель f73f78fb28
Коммит 1183e51c19
21 изменённых файлов: 668 добавлений и 308 удалений

Просмотреть файл

@ -64,6 +64,16 @@
android:layout_marginBottom="4dp"
android:layout_marginRight="4dp"
android:src="@drawable/ic_available_offline" />
<ImageView
android:id="@+id/custom_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|top"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:gravity=""
android:src="@android:drawable/checkbox_off_background" />
</FrameLayout>
</LinearLayout>

Просмотреть файл

@ -65,7 +65,15 @@
android:layout_marginRight="2dp"
android:src="@drawable/ic_available_offline" />
<ImageView
android:id="@+id/custom_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|top"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:src="@android:drawable/checkbox_off_background"
android:elevation="30dp" />
</FrameLayout>

Просмотреть файл

@ -121,26 +121,35 @@
</LinearLayout>
<ImageView
android:id="@+id/sharedIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginBottom="4dp"
android:layout_marginRight="4dp"
android:src="@drawable/shared_via_link" />
<ImageView
android:id="@+id/custom_checkbox"
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="@dimen/standard_margin"
android:gravity=""
android:src="@drawable/ic_checkbox_blank_outline" />
android:paddingRight="@dimen/standard_padding">
<ImageView
android:id="@+id/sharedIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginBottom="4dp"
android:layout_marginRight="4dp"
android:src="@drawable/shared_via_link" />
<ImageView
android:id="@+id/custom_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:src="@drawable/ic_checkbox_blank_outline"
android:layout_toRightOf="@id/sharedIcon"/>
</RelativeLayout>
</LinearLayout>
<View

Просмотреть файл

@ -22,13 +22,13 @@
<item
android:id="@+id/action_share_file"
android:title="@string/action_share"
android:icon="@android:drawable/ic_menu_share"
android:icon="@drawable/ic_share"
android:orderInCategory="1" />
<item
android:id="@+id/action_open_file_with"
android:title="@string/actionbar_open_with"
android:icon="@android:drawable/ic_menu_set_as"
android:icon="@drawable/ic_export"
android:orderInCategory="1" />
<item
android:id="@+id/action_download_file"
@ -48,22 +48,22 @@
<item
android:id="@+id/action_rename_file"
android:title="@string/common_rename"
android:icon="@android:drawable/ic_menu_edit"
android:icon="@drawable/ic_pencil"
android:orderInCategory="1" />
<item
android:id="@+id/action_move"
android:title="@string/actionbar_move"
android:icon="@android:drawable/ic_menu_set_as"
android:icon="@drawable/ic_export"
android:orderInCategory="1" />
<item
android:id="@+id/action_copy"
android:title="@android:string/copy"
android:icon="@android:drawable/ic_menu_set_as"
android:icon="@drawable/ic_copy"
android:orderInCategory="1" />
<item
android:id="@+id/action_remove_file"
android:title="@string/common_remove"
android:icon="@android:drawable/ic_menu_delete"
android:icon="@drawable/ic_delete"
android:orderInCategory="1" />
<item
android:id="@+id/action_send_file"

Просмотреть файл

@ -46,7 +46,12 @@
<!-- Button -->
<color name="button_text_color">#000000</color>
<!-- Multiselect backgrounds -->
<color name="action_mode_background">#757575</color>
<color name="action_mode_status_bar_background">#616161</color>
<color name="selected_item_background">#ECECEC</color>
<!-- Multiaccount support -->
<bool name="multiaccount_support">true</bool>

Просмотреть файл

@ -234,7 +234,7 @@
<string name="unfavorite">Unset as available offline</string>
<string name="common_rename">Rename</string>
<string name="common_remove">Remove</string>
<string name="confirmation_remove_alert">"Do you really want to remove %1$s?"</string>
<string name="confirmation_remove_file_alert">"Do you really want to remove %1$s?"</string>
<string name="confirmation_remove_folder_alert">"Do you really want to remove %1$s and its contents?"</string>
<string name="confirmation_remove_local">Local only</string>
<string name="remove_success_msg">"Removal succeeded"</string>
@ -455,5 +455,8 @@
<string name="permission_storage_access">Additional permissions required to upload &amp; download files.</string>
<string name="local_file_not_found_toast">The file was not found in the local file system</string>
<string name="confirmation_remove_files_alert">Do you really want to remove the selected items?</string>
<string name="confirmation_remove_folders_alert">Do you really want to remove the selected items and their contents?</string>
<string name="confirmation_remove_files">selected items</string>
</resources>

Просмотреть файл

@ -24,6 +24,8 @@
<style name="Theme.ownCloud" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
<item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
<item name="actionModeBackground">@color/action_mode_background</item>
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/color_accent</item>

Просмотреть файл

@ -35,6 +35,7 @@ import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.activity.ComponentsGetter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -43,11 +44,30 @@ import java.util.List;
*/
public class FileMenuFilter {
private OCFile mFile;
private static final int SINGLE_SELECT_ITEMS = 1;
private List<OCFile> mFiles;
private ComponentsGetter mComponentsGetter;
private Account mAccount;
private Context mContext;
/**
* Constructor
*
* @param targetFiles List of {@link OCFile} file targets of the action to filter in the {@link Menu}.
* @param account ownCloud {@link Account} holding targetFile.
* @param cg Accessor to app components, needed to access the
* {@link FileUploader} and {@link FileDownloader} services
* @param context Android {@link Context}, needed to access build setup resources.
*/
public FileMenuFilter(List<OCFile> targetFiles, Account account, ComponentsGetter cg,
Context context) {
mFiles = targetFiles;
mAccount = account;
mComponentsGetter = cg;
mContext = context;
}
/**
* Constructor
*
@ -59,13 +79,9 @@ public class FileMenuFilter {
*/
public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg,
Context context) {
mFile = targetFile;
mAccount = account;
mComponentsGetter = cg;
mContext = context;
this(Arrays.asList(new OCFile[]{targetFile}), account, cg, context);
}
/**
* Filters out the file actions available in the passed {@link Menu} taken into account
* the state of the {@link OCFile} held by the filter.
@ -107,24 +123,24 @@ public class FileMenuFilter {
*/
private void filter(List<Integer> toShow, List <Integer> toHide) {
boolean synchronizing = false;
if (mComponentsGetter != null && mFile != null && mAccount != null) {
if (mComponentsGetter != null && !mFiles.isEmpty() && mAccount != null) {
OperationsServiceBinder opsBinder = mComponentsGetter.getOperationsServiceBinder();
FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
FileDownloaderBinder downloaderBinder = mComponentsGetter.getFileDownloaderBinder();
synchronizing = (
// comparing local and remote
(opsBinder != null && opsBinder.isSynchronizing(mAccount, mFile.getRemotePath())) ||
(opsBinder != null && opsBinder.isSynchronizing(mAccount, mFiles)) ||
// downloading
(downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) ||
(downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFiles)) ||
// uploading
(uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile))
(uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFiles))
);
}
/// decision is taken for each possible action on a file in the menu
// DOWNLOAD
if (mFile == null || mFile.isDown() || mFile.isFolder() || synchronizing) {
if (mFiles.isEmpty() || containsFolder() || anyFileDown() || synchronizing) {
toHide.add(R.id.action_download_file);
} else {
@ -132,7 +148,7 @@ public class FileMenuFilter {
}
// RENAME
if (mFile == null || synchronizing) {
if (!isSingleSelect() || synchronizing) {
toHide.add(R.id.action_rename_file);
} else {
@ -140,7 +156,7 @@ public class FileMenuFilter {
}
// MOVE & COPY
if (mFile == null || synchronizing) {
if (mFiles.isEmpty() || synchronizing) {
toHide.add(R.id.action_move);
toHide.add(R.id.action_copy);
} else {
@ -149,7 +165,7 @@ public class FileMenuFilter {
}
// REMOVE
if (mFile == null || synchronizing) {
if (mFiles.isEmpty() || synchronizing) {
toHide.add(R.id.action_remove_file);
} else {
@ -157,7 +173,7 @@ public class FileMenuFilter {
}
// OPEN WITH (different to preview!)
if (mFile == null || mFile.isFolder() || !mFile.isDown() || synchronizing) {
if (!isFile() || !anyFileDown() || synchronizing) {
toHide.add(R.id.action_open_file_with);
} else {
@ -165,7 +181,7 @@ public class FileMenuFilter {
}
// CANCEL SYNCHRONIZATION
if (mFile == null || !synchronizing) {
if (mFiles.isEmpty() || !synchronizing) {
toHide.add(R.id.action_cancel_sync);
} else {
@ -173,7 +189,7 @@ public class FileMenuFilter {
}
// SYNC CONTENTS (BOTH FILE AND FOLDER)
if (mFile == null || (!mFile.isFolder() && !mFile.isDown()) || synchronizing) {
if (mFiles.isEmpty() || (!anyFileDown() && !containsFolder()) || synchronizing) {
toHide.add(R.id.action_sync_file);
} else {
@ -191,14 +207,14 @@ public class FileMenuFilter {
(capability.getFilesSharingApiEnabled().isTrue() ||
capability.getFilesSharingApiEnabled().isUnknown()
);
if ((!shareViaLinkAllowed && !shareWithUsersAllowed) || mFile == null || !shareApiEnabled) {
if ((!shareViaLinkAllowed && !shareWithUsersAllowed) || !isSingleSelect() || !shareApiEnabled) {
toHide.add(R.id.action_share_file);
} else {
toShow.add(R.id.action_share_file);
}
// SEE DETAILS
if (mFile == null || mFile.isFolder()) {
if (!isFile()) {
toHide.add(R.id.action_see_details);
} else {
toShow.add(R.id.action_see_details);
@ -207,21 +223,21 @@ public class FileMenuFilter {
// SEND
boolean sendAllowed = (mContext != null &&
mContext.getString(R.string.send_files_to_other_apps).equalsIgnoreCase("on"));
if (mFile == null || !sendAllowed || mFile.isFolder() || synchronizing) {
if (!isFile() || !sendAllowed || synchronizing) {
toHide.add(R.id.action_send_file);
} else {
toShow.add(R.id.action_send_file);
}
// FAVORITES
if (mFile == null || synchronizing || mFile.isFolder() || mFile.isFavorite()) {
if (!isFile() || synchronizing || allFavorites()) {
toHide.add(R.id.action_favorite_file);
} else {
toShow.add(R.id.action_favorite_file);
}
// UNFAVORITES
if (mFile == null || synchronizing || mFile.isFolder() || !mFile.isFavorite()) {
if (!isFile() || synchronizing || allUnfavorites()) {
toHide.add(R.id.action_unfavorite_file);
} else {
toShow.add(R.id.action_unfavorite_file);
@ -229,4 +245,48 @@ public class FileMenuFilter {
}
private boolean isSingleSelect() {
return mFiles.size() == SINGLE_SELECT_ITEMS;
}
private boolean isFile() {
return isSingleSelect() && !mFiles.get(0).isFolder();
}
private boolean containsFolder() {
for(OCFile file: mFiles) {
if(file.isFolder()) {
return true;
}
}
return false;
}
private boolean anyFileDown() {
for(OCFile file: mFiles) {
if(file.isDown()) {
return true;
}
}
return false;
}
private boolean allFavorites() {
for(OCFile file: mFiles) {
if(!file.isFavorite()) {
return false;
}
}
return true;
}
private boolean allUnfavorites() {
for(OCFile file: mFiles) {
if(file.isFavorite()) {
return false;
}
}
return true;
}
}

Просмотреть файл

@ -53,8 +53,11 @@ import com.owncloud.android.ui.activity.ShareActivity;
import com.owncloud.android.ui.dialog.ShareLinkToDialog;
import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
/**
*
*/
@ -426,6 +429,12 @@ public class FileOperationsHelper {
}
}
public void syncFiles(Collection<OCFile> files) {
for (OCFile file: files) {
syncFile(file);
}
}
/**
* Request the synchronization of a file or folder with the OC server, including its contents.
*
@ -452,6 +461,12 @@ public class FileOperationsHelper {
}
}
public void toggleFavorites(Collection<OCFile> files, boolean isFavorite){
for (OCFile file: files) {
toggleFavorite(file, isFavorite);
}
}
public void toggleFavorite(OCFile file, boolean isFavorite) {
file.setFavorite(isFavorite);
mFileActivity.getStorageManager().saveFile(file);
@ -551,8 +566,6 @@ public class FileOperationsHelper {
service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
getString(R.string.wait_a_moment));
}
/**

Просмотреть файл

@ -62,6 +62,7 @@ import java.io.File;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
@ -301,6 +302,26 @@ public class FileDownloader extends Service
return (mPendingDownloads.contains(account.name, file.getRemotePath()));
}
/**
* Returns True when the file described by 'file' in the ownCloud account 'account'
* is downloading or waiting to download.
*
* If 'file' is a directory, returns 'true' if any of its descendant files is downloading or
* waiting to download.
*
* @param account ownCloud account where the remote file is stored.
* @param files A list of files that could contains someone in the queue of downloads.
*/
public boolean isDownloading(Account account, List<OCFile> files) {
if (account == null || files.isEmpty()) return false;
for(OCFile file: files) {
if(mPendingDownloads.contains(account.name, file.getRemotePath())) {
return true;
}
}
return false;
}
/**
* Adds a listener interested in the progress of the download for a concrete file.

Просмотреть файл

@ -70,6 +70,7 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
@ -734,6 +735,26 @@ public class FileUploader extends Service
);
}
/**
* Returns True when the file described by 'file' is being uploaded to
* the ownCloud account 'account' or waiting for it
*
* If 'file' is a directory, returns 'true' if some of its descendant files
* is uploading or waiting to upload.
*
* @param account ownCloud account where the remote file will be stored.
* @param files A list of files that could contains someone in the queue of pending uploads
*/
public boolean isUploading(Account account, List<OCFile> files) {
if (account == null || files.isEmpty()) return false;
for(OCFile file: files) {
if(mPendingUploads.contains(account.name, file.getRemotePath())) {
return true;
}
}
return false;
}
/**
* Adds a listener interested in the progress of the upload for a concrete file.

Просмотреть файл

@ -71,6 +71,7 @@ import com.owncloud.android.operations.common.SyncOperation;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
@ -379,11 +380,31 @@ public class OperationsService extends Service {
* or waiting to download.
*
* @param account ownCloud account where the remote file is stored.
* @param remotePath Path of the folder to check if something is synchronizing
* @param file File to check if something is synchronizing
* / downloading / uploading inside.
*/
public boolean isSynchronizing(Account account, String remotePath) {
return mSyncFolderHandler.isSynchronizing(account, remotePath);
public boolean isSynchronizing(Account account, OCFile file) {
return mSyncFolderHandler.isSynchronizing(account, file.getRemotePath());
}
/**
* Returns True when the file described by 'file' in the ownCloud account 'account' is
* downloading or waiting to download.
*
* If 'file' is a directory, returns 'true' if some of its descendant files is downloading
* or waiting to download.
*
* @param account ownCloud account where the remote file is stored.
* @param files List of files to check if something is synchronizing
* / downloading / uploading inside.
*/
public boolean isSynchronizing(Account account, List<OCFile> files) {
for(OCFile file: files) {
if(isSynchronizing(account, file)) {
return true;
}
}
return false;
}
}

Просмотреть файл

@ -912,11 +912,15 @@ public class FileActivity extends AppCompatActivity
// grant that only one waiting dialog is shown
dismissLoadingDialog();
// Construct dialog
LoadingDialog loading = new LoadingDialog(message);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
loading.show(ft, DIALOG_WAIT_TAG);
Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
if (frag == null) {
Log_OC.d(TAG, "show loading dialog");
LoadingDialog loading = new LoadingDialog(message);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
loading.show(ft, DIALOG_WAIT_TAG);
fm.executePendingTransactions();
}
}
@ -926,6 +930,7 @@ public class FileActivity extends AppCompatActivity
public void dismissLoadingDialog() {
Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
if (frag != null) {
Log_OC.d(TAG, "dismiss loading dialog");
LoadingDialog loading = (LoadingDialog) frag;
loading.dismiss();
}

Просмотреть файл

@ -58,7 +58,6 @@ import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.db.PreferenceManager;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader;
@ -93,6 +92,9 @@ import com.owncloud.android.utils.PermissionUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static com.owncloud.android.db.PreferenceManager.*;
/**
* Displays, what files the user has available in his ownCloud. This is the main view.
@ -562,7 +564,7 @@ public class FileDisplayActivity extends HookActivity
break;
}
case R.id.action_sort: {
Integer sortOrder = PreferenceManager.getSortOrder(this);
Integer sortOrder = getSortOrder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.actionbar_sort_title)
@ -764,8 +766,12 @@ public class FileDisplayActivity extends HookActivity
*/
private void requestMoveOperation(Intent data, int resultCode) {
OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
OCFile targetFile = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
getFileOperationsHelper().moveFile(folderToMoveAt, targetFile);
ArrayList<OCFile> files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
for (Parcelable file : files) {
getFileOperationsHelper().moveFile(folderToMoveAt, (OCFile) file);
}
}
/**
@ -776,8 +782,12 @@ public class FileDisplayActivity extends HookActivity
*/
private void requestCopyOperation(Intent data, int resultCode) {
OCFile folderToMoveAt = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
OCFile targetFile = data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
getFileOperationsHelper().copyFile(folderToMoveAt, targetFile);
ArrayList<OCFile> files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
for (Parcelable file : files) {
getFileOperationsHelper().copyFile(folderToMoveAt, (OCFile) file);
}
}
@Override
@ -975,22 +985,28 @@ public class FileDisplayActivity extends HookActivity
.equals(event));
if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
equals(event) &&/// TODO refactor and make common
equals(event)) {
synchResult != null && !synchResult.isSuccess()) {
if (synchResult != null && !synchResult.isSuccess()) {
/// TODO refactor and make common
if(ResultCode.UNAUTHORIZED.equals(synchResult.getCode()) ||
(synchResult.isException() && synchResult.getException()
instanceof AuthenticatorException)) {
if (ResultCode.UNAUTHORIZED.equals(synchResult.getCode()) ||
(synchResult.isException() && synchResult.getException()
instanceof AuthenticatorException)) {
requestCredentialsUpdate(context);
requestCredentialsUpdate(context);
} else if(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(
synchResult.getCode())) {
} else if (RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(
synchResult.getCode())) {
showUntrustedCertDialog(synchResult);
}
showUntrustedCertDialog(synchResult);
}
if (synchFolderRemotePath.equals(OCFile.ROOT_PATH)) {
setUsernameInDrawer(mDrawerLayout, getAccount());
}
}
}
@ -1734,6 +1750,11 @@ public class FileDisplayActivity extends HookActivity
}
/**
* Request stopping the upload/download operation in progress over the given {@link OCFile} file.
*
* @param file {@link OCFile} file which operation are wanted to be cancel
*/
public void cancelTransference(OCFile file) {
getFileOperationsHelper().cancelTransference(file);
if (mWaitingToPreview != null &&
@ -1747,6 +1768,17 @@ public class FileDisplayActivity extends HookActivity
onTransferStateChanged(file, false, false);
}
/**
* Request stopping all upload/download operations in progress over the given {@link OCFile} files.
*
* @param files list of {@link OCFile} files which operations are wanted to be cancel
*/
public void cancelTransference(List<OCFile> files) {
for(OCFile file: files) {
cancelTransference(file);
}
}
@Override
public void onRefresh(boolean ignoreETag) {
refreshList(ignoreETag);

Просмотреть файл

@ -55,13 +55,17 @@ import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.ui.fragment.OCFileListFragment;
import com.owncloud.android.utils.ErrorMessageAdapter;
public class FolderPickerActivity extends FileActivity implements FileFragment.ContainerActivity,
import java.util.ArrayList;
public class FolderPickerActivity extends FileActivity implements FileFragment.ContainerActivity,
OnClickListener, OnEnforceableRefreshListener {
public static final String EXTRA_FOLDER = UploadFilesActivity.class.getCanonicalName()
+ ".EXTRA_FOLDER";
public static final String EXTRA_FILE = UploadFilesActivity.class.getCanonicalName()
+ ".EXTRA_FILE";
public static final String EXTRA_FILES = UploadFilesActivity.class.getCanonicalName()
+ ".EXTRA_FILES";
//TODO: Think something better
private SyncBroadcastReceiver mSyncBroadcastReceiver;
@ -370,12 +374,16 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
} else if (v == mChooseBtn) {
Intent i = getIntent();
Parcelable targetFile = i.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
ArrayList<Parcelable> targetFiles = i.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
Intent data = new Intent();
data.putExtra(EXTRA_FOLDER, getCurrentFolder());
if (targetFile != null) {
data.putExtra(EXTRA_FILE, targetFile);
}
if (targetFiles != null){
data.putParcelableArrayListExtra(EXTRA_FILES, targetFiles);
}
setResult(RESULT_OK, data);
finish();

Просмотреть файл

@ -35,7 +35,6 @@ import android.content.IntentFilter;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources.NotFoundException;
import android.os.Bundle;
import android.os.Parcelable;
@ -59,6 +58,7 @@ import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.db.PreferenceManager;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
@ -315,7 +315,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
Log_OC.d(TAG, "on item click");
// TODO Enable when "On Device" is recovered ?
Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile /*, false*/);
sortFileList(tmpfiles);
tmpfiles = sortFileList(tmpfiles);
if (tmpfiles.size() <= 0) return;
// filter on dirtype
@ -404,7 +404,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
if (mFile != null) {
// TODO Enable when "On Device" is recovered ?
Vector<OCFile> files = getStorageManager().getFolderContent(mFile/*, false*/);
sortFileList(files);
files = sortFileList(files);
List<HashMap<String, Object>> data = new LinkedList<>();
for (OCFile f : files) {
@ -454,11 +454,13 @@ public class ReceiveExternalFilesActivity extends FileActivity
synchFolderOp.execute(getAccount(), this, null, null);
}
private void sortFileList(Vector<OCFile> files) {
private Vector<OCFile> sortFileList(Vector<OCFile> files) {
// Read sorting order, default to sort by name ascending
FileStorageUtils.mSortOrder = PreferenceManager.getSortOrder(this);
FileStorageUtils.mSortAscending = PreferenceManager.getSortAscending(this);
FileStorageUtils.sortFolder(files);
files = FileStorageUtils.sortFolder(files);
return files;
}
private String generatePath(Stack<String> dirs) {

Просмотреть файл

@ -24,15 +24,26 @@
package com.owncloud.android.ui.adapter;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Vector;
import android.accounts.Account;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.graphics.Color;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
@ -52,6 +63,9 @@ import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.MimetypeIconUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Vector;
@ -61,6 +75,8 @@ import java.util.Vector;
*/
public class FileListListAdapter extends BaseAdapter implements ListAdapter {
private static final String SELECTION_KEY = "multiFileSelectionsKey";
private Context mContext;
private OCFile mFile = null;
private Vector<OCFile> mFiles = null;
@ -71,21 +87,24 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
private Account mAccount;
private ComponentsGetter mTransferServiceGetter;
private boolean mGridMode;
private boolean isGridViewSelectionRestored = true;
private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM};
private HashSet<Long> mSelection = new LinkedHashSet<Long>();
private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM };
public FileListListAdapter(
boolean justFolders,
Context context,
ComponentsGetter transferServiceGetter
) {
) {
mJustFolders = justFolders;
mContext = context;
mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);
mTransferServiceGetter = transferServiceGetter;
// Read sorting order, default to sort by name ascending
FileStorageUtils.mSortOrder = PreferenceManager.getSortOrder(mContext);
FileStorageUtils.mSortAscending = PreferenceManager.getSortAscending(mContext);
@ -95,7 +114,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
mGridMode = false;
}
@Override
public boolean areAllItemsEnabled() {
return true;
@ -132,6 +151,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
restoreGridViewSelection((AbsListView) parent);
View view = convertView;
OCFile file = null;
@ -144,9 +164,9 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
// Find out which layout should be displayed
ViewType viewType;
if (!mGridMode){
if (!mGridMode) {
viewType = ViewType.LIST_ITEM;
} else if (file.isImage()){
} else if (file.isImage()) {
viewType = ViewType.GRID_IMAGE;
} else {
viewType = ViewType.GRID_ITEM;
@ -172,7 +192,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
view.invalidate();
if (file != null){
if (file != null) {
ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);
@ -183,40 +203,22 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.ListItemLayout);
linearLayout.setContentDescription("LinearLayout-" + name);
switch (viewType){
switch (viewType) {
case LIST_ITEM:
TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);
TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
lastModV.setVisibility(View.VISIBLE);
lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file.getModificationTimestamp()));
checkBoxV.setVisibility(View.GONE);
fileSizeSeparatorV.setVisibility(View.VISIBLE);
fileSizeV.setVisibility(View.VISIBLE);
fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));
if (!file.isFolder()) {
AbsListView parentList = (AbsListView)parent;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {
checkBoxV.setVisibility(View.GONE);
} else {
if (parentList.isItemChecked(position)) {
checkBoxV.setImageResource(
R.drawable.ic_checkbox_marked);
} else {
checkBoxV.setImageResource(
R.drawable.ic_checkbox_blank_outline);
}
checkBoxV.setVisibility(View.VISIBLE);
}
}
} else { //Folder
if (file.isFolder()) {
fileSizeSeparatorV.setVisibility(View.GONE);
fileSizeV.setVisibility(View.GONE);
}
@ -234,7 +236,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
sharedIconV.setImageResource(R.drawable.shared_via_link);
sharedIconV.setVisibility(View.VISIBLE);
sharedIconV.bringToFront();
} else if (file.isSharedWithSharee() || file.isSharedWithMe() ) {
} else if (file.isSharedWithSharee() || file.isSharedWithMe()) {
sharedIconV.setImageResource(R.drawable.shared_via_users);
sharedIconV.setVisibility(View.VISIBLE);
sharedIconV.bringToFront();
@ -258,22 +260,22 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
localStateView.setVisibility(View.INVISIBLE); // default first
if ( //synchronizing
opsBinder != null &&
opsBinder.isSynchronizing(mAccount, file.getRemotePath())
opsBinder != null &&
opsBinder.isSynchronizing(mAccount, file)
) {
localStateView.setImageResource(R.drawable.ic_synchronizing);
localStateView.setVisibility(View.VISIBLE);
} else if ( // downloading
downloaderBinder != null &&
downloaderBinder.isDownloading(mAccount, file)
downloaderBinder != null &&
downloaderBinder.isDownloading(mAccount, file)
) {
localStateView.setImageResource(R.drawable.ic_synchronizing);
localStateView.setVisibility(View.VISIBLE);
} else if ( //uploading
uploaderBinder != null &&
uploaderBinder.isUploading(mAccount, file)
uploaderBinder != null &&
uploaderBinder.isUploading(mAccount, file)
) {
localStateView.setImageResource(R.drawable.ic_synchronizing);
localStateView.setVisibility(View.VISIBLE);
@ -289,9 +291,29 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
break;
}
ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
checkBoxV.setVisibility(View.GONE);
view.setBackgroundColor(Color.WHITE);
AbsListView parentList = (AbsListView) parent;
if (parentList.getChoiceMode() != AbsListView.CHOICE_MODE_NONE
&& parentList.getCheckedItemCount() > 0) {
if (isItemSelected(position)) {
view.setBackgroundColor(mContext.getResources().getColor(
R.color.selected_item_background));
checkBoxV.setImageResource(
R.drawable.ic_checkbox_marked);
} else {
view.setBackgroundColor(Color.WHITE);
checkBoxV.setImageResource(
R.drawable.ic_checkbox_blank_outline);
}
checkBoxV.setVisibility(View.VISIBLE);
}
// For all Views
// this if-else is needed even though favorite icon is visible by default
// because android reuses views in listview
if (!file.isFavorite()) {
@ -299,15 +321,15 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
} else {
view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE);
}
// No Folder
if (!file.isFolder()) {
if (file.isImage() && file.getRemoteId() != null){
if (file.isImage() && file.getRemoteId() != null) {
// Thumbnail in Cache?
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
String.valueOf(file.getRemoteId())
);
if (thumbnail != null && !file.needsUpdateThumbnail()){
);
if (thumbnail != null && !file.needsUpdateThumbnail()) {
fileIcon.setImageBitmap(thumbnail);
} else {
// generate new Thumbnail
@ -315,15 +337,15 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
new ThumbnailsCacheManager.ThumbnailGenerationTask(
fileIcon, mStorageManager, mAccount
);
);
if (thumbnail == null) {
thumbnail = ThumbnailsCacheManager.mDefaultImg;
}
final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
new ThumbnailsCacheManager.AsyncDrawable(
mContext.getResources(),
thumbnail,
task
mContext.getResources(),
thumbnail,
task
);
fileIcon.setImageDrawable(asyncDrawable);
task.execute(file);
@ -352,10 +374,22 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
);
}
}
return view;
}
private void restoreGridViewSelection(AbsListView parent) {
if (parent instanceof GridView && !isGridViewSelectionRestored) {
isGridViewSelectionRestored = true;
parent.clearChoices();
final Vector<OCFile> files = mFiles;
for (int i = 0; i < files.size(); ++i) {
if(mSelection.contains(files.get(i).getFileId())){
parent.setItemChecked(i, true);
}
}
}
}
@Override
public int getViewTypeCount() {
return 1;
@ -390,7 +424,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
mFiles = mStorageManager.getFolderContent(mFile/*, onlyOnDevice*/);
mFilesOrig.clear();
mFilesOrig.addAll(mFiles);
if (mJustFolders) {
mFiles = getFolders(mFiles);
}
@ -401,17 +435,17 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
mFiles = FileStorageUtils.sortFolder(mFiles);
notifyDataSetChanged();
}
/**
* Filter for getting only the folders
*
* @param files
* @return Vector<OCFile>
*/
public Vector<OCFile> getFolders(Vector<OCFile> files) {
Vector<OCFile> ret = new Vector<OCFile>();
OCFile current = null;
for (int i=0; i<files.size(); i++) {
Vector<OCFile> ret = new Vector<OCFile>();
OCFile current = null;
for (int i = 0; i < files.size(); i++) {
current = files.get(i);
if (current.isFolder()) {
ret.add(current);
@ -419,9 +453,10 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
}
return ret;
}
public void setSortOrder(Integer order, boolean ascending) {
PreferenceManager.setSortOrder(mContext, order);
PreferenceManager.setSortAscending(mContext, ascending);
@ -432,10 +467,74 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
notifyDataSetChanged();
}
private CharSequence showRelativeTimestamp(OCFile file) {
return DisplayUtils.getRelativeDateTimeString(mContext, file.getModificationTimestamp(),
DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0);
}
public void setGridMode(boolean gridMode) {
mGridMode = gridMode;
}
public boolean isItemSelected(int position) {
return mSelection.contains(getItemId(position));
}
public void setNewSelection(int position, boolean checked) {
if (checked) {
mSelection.add(getItemId(position));
notifyDataSetChanged();
} else {
removeSelection(position);
}
}
public void removeSelection(int position) {
mSelection.remove(getItemId(position));
notifyDataSetChanged();
}
public void clearSelection() {
mSelection.clear();
notifyDataSetChanged();
}
public ArrayList<OCFile> getCheckedItems() {
ArrayList<OCFile> files = new ArrayList<OCFile>();
if (mFiles != null && mFiles.size() != 0) {
for (OCFile file : mFiles) {
if (mSelection.contains(file.getFileId())) {
files.add(file);
}
}
}
return files;
}
public void restoreSelectionState(Bundle savedInstanceState) {
if (savedInstanceState == null) {
return;
}
long[] selectionState = savedInstanceState.getLongArray(SELECTION_KEY);
mSelection.clear();
if (selectionState != null) {
for (long id : selectionState) {
mSelection.add(id);
}
}
isGridViewSelectionRestored = false;
}
public void saveSelectionState(Bundle outState) {
long[] selectionStatePrimitive = new long[mSelection.size()];
int i = 0;
for (Long id : mSelection) {
selectionStatePrimitive[i++] = id;
}
outState.putLongArray(SELECTION_KEY, selectionStatePrimitive);
}
public boolean isGridMode() {
return mGridMode;
}

Просмотреть файл

@ -52,14 +52,13 @@ implements ConfirmationDialogFragmentListener {
RemoveFileDialogFragment frag = new RemoveFileDialogFragment();
Bundle args = new Bundle();
int messageStringId = R.string.confirmation_remove_alert;
int messageStringId = (file.isFolder()) ?
R.string.confirmation_remove_folder_alert :
R.string.confirmation_remove_file_alert;
int localRemoveButton = (!file.isFavorite() && (file.isFolder() || file.isDown())) ?
R.string.confirmation_remove_local : -1;
if (file.isFolder()) {
messageStringId = R.string.confirmation_remove_folder_alert;
}
R.string.confirmation_remove_local :
-1;
args.putInt(ARG_MESSAGE_RESOURCE_ID, messageStringId);
args.putStringArray(ARG_MESSAGE_ARGUMENTS, new String[]{file.getFileName()});

Просмотреть файл

@ -165,11 +165,14 @@ public class ExtendedListFragment extends Fragment
mListView = (ExtendedListView)(v.findViewById(R.id.list_root));
mListView.setOnItemClickListener(this);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListFooterView = inflater.inflate(R.layout.list_footer, null, false);
mGridView = (GridViewWithHeaderAndFooter) (v.findViewById(R.id.grid_root));
mGridView.setNumColumns(GridView.AUTO_FIT);
mGridView.setOnItemClickListener(this);
mGridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mGridFooterView = inflater.inflate(R.layout.list_footer, null, false);
if (savedInstanceState != null) {
@ -404,19 +407,13 @@ public class ExtendedListFragment extends Fragment
}
protected void setChoiceMode(int choiceMode) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mListView.setChoiceMode(choiceMode);
mGridView.setChoiceMode(choiceMode);
} else {
((ListView)mListView).setChoiceMode(choiceMode);
}
mListView.setChoiceMode(choiceMode);
mGridView.setChoiceMode(choiceMode);
}
protected void registerForContextMenu() {
registerForContextMenu(mListView);
registerForContextMenu(mGridView);
mListView.setOnCreateContextMenuListener(this);
mGridView.setOnCreateContextMenuListener(this);
protected void setMultiChoiceModeListener(AbsListView.MultiChoiceModeListener listener) {
mListView.setMultiChoiceModeListener(listener);
mGridView.setMultiChoiceModeListener(listener);
}
/**

Просмотреть файл

@ -30,16 +30,17 @@ import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.ContextMenu;
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.AdapterView.AdapterContextMenuInfo;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
@ -60,6 +61,7 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
import com.owncloud.android.ui.dialog.FileActionsDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
@ -67,14 +69,15 @@ import com.owncloud.android.ui.preview.PreviewTextFragment;
import com.owncloud.android.utils.FileStorageUtils;
import java.io.File;
import java.util.ArrayList;
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 FileActionsDialogFragment.FileActionsDialogFragmentListener {
public class OCFileListFragment extends ExtendedListFragment {
private static final String TAG = OCFileListFragment.class.getSimpleName();
@ -98,14 +101,19 @@ public class OCFileListFragment extends ExtendedListFragment
private FileListListAdapter mAdapter;
private boolean mJustFolders;
private OCFile mTargetFile;
private int mStatusBarColorActionMode;
private int mStatusBarColor;
private boolean hideFab = true;
private boolean miniFabClicked = false;
private ActionMode mActiveActionMode;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mStatusBarColorActionMode = getResources().getColor(R.color.action_mode_status_bar_background);
mStatusBarColor = getResources().getColor(R.color.primary_dark);
}
/**
@ -176,11 +184,12 @@ public class OCFileListFragment extends ExtendedListFragment
getActivity(),
mContainerActivity
);
mAdapter.restoreSelectionState(savedInstanceState);
setListAdapter(mAdapter);
registerLongClickListener();
boolean hideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false);
hideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false);
if (hideFab) {
setFabEnabled(false);
} else {
@ -200,7 +209,7 @@ public class OCFileListFragment extends ExtendedListFragment
removeFabLabels();
}
}
}
}
/**
* adds labels to all mini FABs.
@ -228,7 +237,7 @@ public class OCFileListFragment extends ExtendedListFragment
getFabUpload().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UploadFilesActivity.startUploadActivityForResult(getActivity(), ((FileActivity)getActivity())
UploadFilesActivity.startUploadActivityForResult(getActivity(), ((FileActivity) getActivity())
.getAccount(), FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM);
getFabMain().collapse();
recordMiniFabClick();
@ -335,57 +344,76 @@ public class OCFileListFragment extends ExtendedListFragment
}
private void registerLongClickListener() {
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
showFileAction(index);
setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
mAdapter.setNewSelection(position, checked);
mode.invalidate();
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mActiveActionMode = mode;
createContextActionBar(menu);
mode.invalidate();
//set gray color
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(mStatusBarColorActionMode);
}
// hide FAB in multi selection mode
setFabEnabled(false);
return true;
}
});
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
private void showFileAction(int fileIndex) {
Bundle args = getArguments();
PopupMenu pm = new PopupMenu(getActivity(),null);
Menu menu = pm.getMenu();
final int checkedCount = getListView().getCheckedItemCount();
mode.setTitle(checkedCount + " selected");
boolean allowContextualActions =
(args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
if (checkedCount > 0) {
List<OCFile> targetFiles = mAdapter.getCheckedItems();
if (allowContextualActions) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.file_actions_menu, menu);
OCFile targetFile = (OCFile) mAdapter.getItem(fileIndex);
if (mContainerActivity.getStorageManager() != null) {
FileMenuFilter mf = new FileMenuFilter(
targetFile,
mContainerActivity.getStorageManager().getAccount(),
mContainerActivity,
getActivity()
);
mf.filter(menu);
if (mContainerActivity.getStorageManager() != null) {
FileMenuFilter mf = new FileMenuFilter(
targetFiles,
mContainerActivity.getStorageManager().getAccount(),
mContainerActivity,
getActivity()
);
mf.filter(menu);
}
}
return true;
}
/// TODO break this direct dependency on FileDisplayActivity... if possible
MenuItem item = menu.findItem(R.id.action_open_file_with);
FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment();
if (frag != null && frag instanceof FileDetailFragment &&
frag.getFile().getFileId() == targetFile.getFileId()) {
item = menu.findItem(R.id.action_see_details);
if (item != null) {
item.setVisible(false);
item.setEnabled(false);
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return onFileActionChosen(item.getItemId());
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActiveActionMode = null;
getListView().clearChoices();
mAdapter.clearSelection();
// reset to primary dark color
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(mStatusBarColor);
}
// show FAB on multi selection mode exit
if(!hideFab) {
setFabEnabled(true);
}
}
FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu,
fileIndex, targetFile.getFileName());
dialog.setTargetFragment(this, 0);
dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS);
}
});
}
/**
@ -395,6 +423,7 @@ public class OCFileListFragment extends ExtendedListFragment
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_FILE, mFile);
mAdapter.saveSelectionState(outState);
}
@Override
@ -490,123 +519,135 @@ public class OCFileListFragment extends ExtendedListFragment
}
/**
* {@inheritDoc}
* Create the context bar with the file actions
* @param menu
*/
@Override
public void onCreateContextMenu(
ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
public void createContextActionBar(Menu menu) {
Bundle args = getArguments();
boolean allowContextualActions =
(args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
if (allowContextualActions) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.file_actions_menu, menu);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
OCFile targetFile = (OCFile) mAdapter.getItem(info.position);
if (mContainerActivity.getStorageManager() != null) {
FileMenuFilter mf = new FileMenuFilter(
targetFile,
mContainerActivity.getStorageManager().getAccount(),
mContainerActivity,
getActivity()
);
mf.filter(menu);
}
/// TODO break this direct dependency on FileDisplayActivity... if possible
MenuItem item = menu.findItem(R.id.action_open_file_with);
FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment();
if (frag != null && frag instanceof FileDetailFragment &&
frag.getFile().getFileId() == targetFile.getFileId()) {
item = menu.findItem(R.id.action_see_details);
if (item != null) {
item.setVisible(false);
item.setEnabled(false);
}
}
// String.format(mContext.getString(R.string.subject_token),
// getClient().getCredentials().getUsername(), file.getFileName()));
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean onFileActionChosen(int menuId, int filePosition) {
mTargetFile = (OCFile) mAdapter.getItem(filePosition);
switch (menuId) {
case R.id.action_share_file: {
mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile);
return true;
}
case R.id.action_open_file_with: {
mContainerActivity.getFileOperationsHelper().openFile(mTargetFile);
return true;
}
case R.id.action_rename_file: {
RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
return true;
}
case R.id.action_remove_file: {
RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
return true;
}
case R.id.action_download_file:
case R.id.action_sync_file: {
mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
return true;
}
case R.id.action_cancel_sync: {
((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
return true;
}
case R.id.action_see_details: {
mContainerActivity.showDetails(mTargetFile);
return true;
}
case R.id.action_send_file: {
// Obtain the file
if (!mTargetFile.isDown()) { // Download the file
Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
public boolean onFileActionChosen(int menuId) {
final ArrayList<OCFile> checkedItems = mAdapter.getCheckedItems();
if (checkedItems.size() == 1){
OCFile mTargetFile = checkedItems.get(0);
} else {
mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
switch (menuId) {
case R.id.action_share_file: {
mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile);
return true;
}
return true;
}
case R.id.action_move: {
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
case R.id.action_open_file_with: {
mContainerActivity.getFileOperationsHelper().openFile(mTargetFile);
return true;
}
case R.id.action_rename_file: {
RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
return true;
}
case R.id.action_remove_file: {
RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
return true;
}
case R.id.action_download_file:
case R.id.action_sync_file: {
mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
return true;
}
case R.id.action_cancel_sync: {
((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
return true;
}
case R.id.action_see_details: {
mContainerActivity.showDetails(mTargetFile);
return true;
}
case R.id.action_send_file: {
// Obtain the file
if (!mTargetFile.isDown()) { // Download the file
Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
// Pass mTargetFile that contains info of selected file/folder
action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES);
return true;
} else {
mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
}
return true;
}
case R.id.action_move: {
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
ArrayList files = new ArrayList();
files.add(mTargetFile);
action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, files);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES);
return true;
}
case R.id.action_favorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
return true;
}
case R.id.action_unfavorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
return true;
}
case R.id.action_copy:
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
ArrayList files = new ArrayList();
files.add(mTargetFile);
action.putExtra(FolderPickerActivity.EXTRA_FILES, files);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES);
return true;
default:
return false;
}
case R.id.action_favorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
return true;
}
case R.id.action_unfavorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
return true;
}
case R.id.action_copy:
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
} else {
ArrayList<OCFile> mTargetFiles = checkedItems;
// Pass mTargetFile that contains info of selected file/folder
action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES);
return true;
default:
return false;
switch (menuId) {
case R.id.action_remove_file: {
RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(mTargetFiles);
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
return true;
}
case R.id.action_download_file:
case R.id.action_sync_file: {
mContainerActivity.getFileOperationsHelper().syncFiles(mTargetFiles);
return true;
}
case R.id.action_cancel_sync: {
((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFiles);
return true;
}
case R.id.action_move: {
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__MOVE_FILES);
return true;
}
case R.id.action_favorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, true);
return true;
}
case R.id.action_unfavorite_file: {
mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, false);
return true;
}
case R.id.action_copy:
Intent action = new Intent(getActivity(), FolderPickerActivity.class);
action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles);
getActivity().startActivityForResult(action, FileDisplayActivity.REQUEST_CODE__COPY_FILES);
return true;
default:
return false;
}
}
}
/**
@ -615,8 +656,7 @@ public class OCFileListFragment extends ExtendedListFragment
@Override
public boolean onContextItemSelected (MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
boolean matched = onFileActionChosen(item.getItemId(),
((AdapterContextMenuInfo) item.getMenuInfo()).position);
boolean matched = onFileActionChosen(item.getItemId());
if(!matched) {
return super.onContextItemSelected(item);
} else {
@ -624,7 +664,6 @@ public class OCFileListFragment extends ExtendedListFragment
}
}
/**
* Use this to query the {@link OCFile} that is currently
* being displayed by this fragment
@ -717,11 +756,17 @@ public class OCFileListFragment extends ExtendedListFragment
if (version != null && version.supportsRemoteThumbnails() &&
isGridViewPreferred(mFile)) {
switchToGridView();
registerLongClickListener();
} else {
switchToListView();
}
}
invalidateActionMode();
}
private void invalidateActionMode() {
if(mActiveActionMode != null){
mActiveActionMode.invalidate();
}
}
private String generateFooterText(int filesCount, int foldersCount) {

@ -1 +1 @@
Subproject commit a4dcad98f92eeb4caef89b4e860d4359385f0697
Subproject commit 343496c792616459e8204b6614fd42a1b16a6d68