From: tobiasKaminsky Date: Thu, 5 Nov 2015 21:26:56 +0000 (+0100) Subject: Merge remote-tracking branch 'remotes/upstream/resizedImages' into beta X-Git-Tag: beta-20151122~42 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/8e057b45041897e80e4cbfd44a14c515c0ef5605?ds=inline;hp=-c Merge remote-tracking branch 'remotes/upstream/resizedImages' into beta --- 8e057b45041897e80e4cbfd44a14c515c0ef5605 diff --combined AndroidManifest.xml index 240d73be,e1d21f3c..17945c85 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@@ -1,4 -1,5 +1,5 @@@ - - + --> + + + @@@ -30,64 -37,60 +35,60 @@@ - - - - + + + - + + + android:theme="@style/Theme.ownCloud" > + android:label="@string/app_name" > + - - + + - + - + - + - - - + - + + - - - + + android:theme="@style/Theme.ownCloud.Fullscreen" /> - + android:exported="true" > + @@@ -97,7 -100,7 +98,7 @@@ + android:exported="true" > @@@ -113,19 -116,26 +114,26 @@@ android:enabled="true" android:exported="true" android:label="@string/sync_string_files" - android:syncable="true"> + android:syncable="true" /> + + + android:launchMode="singleTask" + android:theme="@style/Theme.ownCloud.noActionBar" > @@@ -136,6 -146,7 +144,7 @@@ + @@@ -146,53 -157,60 +155,66 @@@ - - - - - - + + + + + + + + + + + + + + + - + - - - - + - + android:name=".ui.activity.CopyToClipboardActivity" + android:icon="@drawable/copy_link" + android:label="@string/copy_link" /> + + + + + + + + diff --combined build.gradle index d707b027,d96997a6..84807207 --- a/build.gradle +++ b/build.gradle @@@ -3,12 -3,13 +3,12 @@@ buildscript mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath 'com.android.tools.build:gradle:1.3.0' } } apply plugin: 'com.android.application' - repositories { mavenCentral() @@@ -19,22 -20,15 +19,22 @@@ dependencies { compile name: 'touch-image-view' - compile 'com.android.support:support-v4:22.2.1' compile project(':owncloud-android-library') + compile 'com.android.support:support-v4:22.2.1' compile 'com.jakewharton:disklrucache:2.0.2' compile 'com.android.support:appcompat-v7:22.2.1' + compile 'com.getbase:floatingactionbutton:1.10.1' } android { compileSdkVersion 22 buildToolsVersion "22.0.1" + + defaultConfig { + applicationId "com.owncloud.android.beta" + versionCode computeVersionCode() + } + sourceSets { main { manifest.srcFile 'AndroidManifest.xml' @@@ -64,7 -58,7 +64,7 @@@ abortOnError false } } - + productFlavors { } @@@ -73,8 -67,8 +73,12 @@@ } } + + + + - +def computeVersionCode() { + def date = new Date() + def formattedDate = date.format('yyyyMMdd').toInteger() + return formattedDate +} diff --combined owncloud-android-library index 59fb6160,32ab89fc..fff67c91 --- a/owncloud-android-library +++ b/owncloud-android-library @@@ -1,1 -1,1 +1,1 @@@ - Subproject commit 59fb61601de4dd8bfcab1afb619e016e1a7b904d -Subproject commit 32ab89fc308af2a51b9b7ded7fb40fc786dfd8a6 ++Subproject commit fff67c91f73532229cd678cbbee19b52b0852db5 diff --combined res/layout/grid_image.xml index b6580e9f,15a9baf0..9f93a3e8 --- a/res/layout/grid_image.xml +++ b/res/layout/grid_image.xml @@@ -38,30 -38,13 +38,13 @@@ android:scaleType="centerCrop" android:src="@drawable/ic_menu_archive"/> - - - - - - + android:layout_margin="4dp" + android:src="@drawable/shared_via_link" /> + + diff --combined res/layout/grid_item.xml index 23efe9a9,6bec5604..0f27f90d --- a/res/layout/grid_item.xml +++ b/res/layout/grid_item.xml @@@ -39,30 -39,13 +39,13 @@@ android:layout_marginRight="10dp" android:src="@drawable/ic_menu_archive" /> - - - - - - + android:src="@drawable/shared_via_link" /> - + diff --combined res/layout/list_item.xml index ee1f26a7,076ed7b7..cf09502e --- a/res/layout/list_item.xml +++ b/res/layout/list_item.xml @@@ -22,7 -22,7 +22,7 @@@ android:layout_width="match_parent" android:background="@drawable/list_selector" android:orientation="vertical" - android:layout_height="56dp"> + android:layout_height="72dp"> @@@ -43,15 -39,16 +43,15 @@@ android:id="@+id/localFileIndicator" android:layout_width="@dimen/file_icon_size" android:layout_height="@dimen/file_icon_size" - android:layout_gravity="center_vertical" - android:layout_marginLeft="22dp" + android:layout_gravity="top|right" + android:layout_marginRight="4dp" android:src="@drawable/local_file_indicator" /> @@@ -67,8 -65,7 +67,8 @@@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:gravity="center_vertical" + android:gravity="top" + android:paddingTop="@dimen/standard_padding" android:orientation="vertical" > + android:textSize="@dimen/two_line_primary_text_size" /> + android:orientation="horizontal"> + android:textSize="@dimen/two_line_secondary_text_size"/> + android:textSize="@dimen/two_line_secondary_text_size"/> + + - - - - - - - + + android:src="@drawable/ic_checkbox_blank_outline" /> All files - + On device Settings Logs Close @@@ -86,6 -87,7 +86,7 @@@ List Layout Share link Unshare link + Share with users Yes No OK @@@ -204,11 -206,11 +205,11 @@@ Unfavorite Rename Remove - "Do you really want to remove %1$s?" + "Do you really want to remove %1$s?" "Do you really want to remove %1$s and its contents?" Local only Local only - From server + From server Remote & local "Removal succeeded" "Removal failed" @@@ -261,11 -263,9 +262,11 @@@ 389 KB 2012/05/18 12:23 PM 12:23:45 - - Upload pictures via WiFi only - Upload videos via WiFi only + + Upload pictures via wifi only + Upload when charging only + Upload videos via wifi only + Upload when charging only /InstantUpload File conflict Which files do you want to keep? If you select both versions, the local file will have a number added to its name. @@@ -277,7 -277,7 +278,7 @@@ This image cannot be shown %1$s could not be copied to %2$s local folder - Upload Path + Upload path Sorry, sharing is not enabled on your server. Please contact your administrator. @@@ -342,15 -342,14 +343,15 @@@ Instant Uploads Security - Upload Video Path + Upload video path + Download of %1$s folder could not be completed Synchronization of %1$s folder could not be completed shared with you - %1$s shared \"%2$s\" with you - \"%1$s\" has been shared with you + %1$s shared \"%2$s\" with you + \"%1$s\" has been shared with you Refresh connection Server address @@@ -366,27 -365,17 +367,39 @@@ %1$d files %1$d files, 1 folder %1$d files, %2$d folders + Switch to grid view + Switch to list view + Common + Cache size + Upload file to server and ... + Behaviour + Copy file + Move file + + do nothing + copy file to OC folder + move file to OC folder + delete origin file + Do you really want to remove selected items? + Do you really want to remove a folder and its content? + selected items + Exit + Send Log + Error Log + Stream file with external player + Do you want to stream this file with an external app?\n\nCAUTION: This may expose your password! + Set picture as + Sharing + Share with Users and Groups + No data shared with users yet + Add User or Group + Search + + Search users and groups + %1$s (group) + + Sorry, your server version does not allow share with users within clients. + \nPlease contact your administrator + diff --combined res/values/styles.xml index 15b989ee,b7a64843..934b755c --- a/res/values/styles.xml +++ b/res/values/styles.xml @@@ -24,15 -24,20 +24,15 @@@ - @@@ -130,11 -135,6 +130,11 @@@ @style/Theme.ownCloud.Dialog.ButtonBar + + needs Password @@@ -795,34 -810,8 +819,8 @@@ } } - - private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, - RemoteOperationResult result) { - dismissLoadingDialog(); - - if (result.isSuccess()){ - updateFileFromDB(); - - } else { - Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, - operation, getResources()), Toast.LENGTH_LONG); - t.show(); - } - } - - private void onSynchronizeFolderOperationFinish( - SynchronizeFolderOperation operation, RemoteOperationResult result - ) { - if (!result.isSuccess() && result.getCode() != ResultCode.CANCELLED){ - Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, - operation, getResources()), Toast.LENGTH_LONG); - t.show(); - } - } - private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) { - dismissLoadingDialog(); OCFile syncedFile = operation.getLocalFile(); if (!result.isSuccess()) { if (result.getCode() == ResultCode.SYNC_CONFLICT) { @@@ -854,17 -843,13 +852,13 @@@ /** * Show loading dialog */ - public void showLoadingDialog() { + public void showLoadingDialog(String message) { // Construct dialog - Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG); - if (frag == null) { - Log_OC.d(TAG, "show loading dialog"); - LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment)); - FragmentManager fm = getSupportFragmentManager(); - FragmentTransaction ft = fm.beginTransaction(); - loading.show(ft, DIALOG_WAIT_TAG); - fm.executePendingTransactions(); - } + LoadingDialog loading = new LoadingDialog(message); + FragmentManager fm = getSupportFragmentManager(); + FragmentTransaction ft = fm.beginTransaction(); + loading.show(ft, DIALOG_WAIT_TAG); + } @@@ -874,7 -859,6 +868,7 @@@ 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(); } @@@ -944,12 -928,6 +938,12 @@@ startActivity(i); } + public void refresh(){ + Intent i = new Intent(this, FileDisplayActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + // TODO re-enable when "Accounts" is available in Navigation Drawer // public void closeDrawer() { // mDrawerLayout.closeDrawers(); @@@ -959,10 -937,6 +953,10 @@@ restart(); } + public void refreshDirectory(){ + // overridden by FileDisplayActivity + } + private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { @@@ -979,25 -953,24 +973,25 @@@ // break; case 0: // All Files - allFilesOption(); + MainApp.showOnlyFilesOnDevice(false); + refreshDirectory(); mDrawerLayout.closeDrawers(); break; - // TODO Enable when "On Device" is recovered ? -// case 2: -// MainApp.showOnlyFilesOnDevice(true); -// mDrawerLayout.closeDrawers(); -// break; + case 1: // On Device + MainApp.showOnlyFilesOnDevice(true); + refreshDirectory(); + mDrawerLayout.closeDrawers(); + break; - case 1: // Settings + case 2: // Settings Intent settingsIntent = new Intent(getApplicationContext(), Preferences.class); startActivity(settingsIntent); mDrawerLayout.closeDrawers(); break; - case 2: // Logs + case 3: // Logs Intent loggerIntent = new Intent(getApplicationContext(), LogHistoryActivity.class); startActivity(loggerIntent); diff --combined src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 5debcd43,e814c2d3..c19fb4a1 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@@ -26,7 -26,6 +26,7 @@@ import android.accounts.Account import android.accounts.AccountManager; import android.accounts.AuthenticatorException; import android.annotation.TargetApi; +import android.os.Parcelable; import android.support.v7.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; @@@ -80,13 -79,14 +80,14 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.operations.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; - import com.owncloud.android.operations.CreateShareOperation; + import com.owncloud.android.operations.CreateShareViaLinkOperation; + import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.MoveFileOperation; import com.owncloud.android.operations.RefreshFolderOperation; import com.owncloud.android.operations.RemoveFileOperation; import com.owncloud.android.operations.RenameFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; - import com.owncloud.android.operations.UnshareLinkOperation; + import com.owncloud.android.operations.UnshareOperation; import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.syncadapter.FileSyncAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@@ -108,8 -108,6 +109,8 @@@ import com.owncloud.android.utils.FileS import com.owncloud.android.utils.UriUtils; import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; /** * Displays, what files the user has available in his ownCloud. @@@ -119,8 -117,6 +120,6 @@@ public class FileDisplayActivity extend implements FileFragment.ContainerActivity, OnSslUntrustedCertListener, OnEnforceableRefreshListener { - - private SyncBroadcastReceiver mSyncBroadcastReceiver; private UploadFinishReceiver mUploadFinishReceiver; private DownloadFinishReceiver mDownloadFinishReceiver; @@@ -152,14 -148,13 +151,14 @@@ private boolean mSyncInProgress = false; private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT"; - private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; + public static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; private static String DIALOG_UPLOAD_SOURCE = "DIALOG_UPLOAD_SOURCE"; private static String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED"; private OCFile mWaitingToSend; + private Menu mOptionsMenu; + - @Override protected void onCreate(Bundle savedInstanceState) { Log_OC.v(TAG, "onCreate() start"); @@@ -231,6 -226,13 +230,13 @@@ } @Override + protected void onStop() { + Log_OC.v(TAG, "onStop() start"); + super.onStop(); + Log_OC.v(TAG, "onStop() end"); + } + + @Override protected void onDestroy() { Log_OC.v(TAG, "onDestroy() start"); super.onDestroy(); @@@ -269,7 -271,12 +275,7 @@@ setFile(file); if (mAccountWasSet) { - RelativeLayout navigationDrawerLayout = (RelativeLayout) findViewById(R.id.left_drawer); - if (navigationDrawerLayout != null && getAccount() != null) { - TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); - int lastAtPos = getAccount().name.lastIndexOf("@"); - username.setText(getAccount().name.substring(0, lastAtPos)); - } + setUsernameInDrawer((RelativeLayout) findViewById(R.id.left_drawer), getAccount()); } if (!stateWasRecovered) { @@@ -298,7 -305,10 +304,7 @@@ /// First fragment OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { - listOfFiles.listDirectory(getCurrentDir()); - // TODO Enable when "On Device" is recovered - // listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice()); - + listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice()); } else { Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >("); } @@@ -317,12 -327,6 +323,12 @@@ startTextPreview(file); } + if (DisplayUtils.isGridView(getFile(), getStorageManager())){ + switchToGridView(); + } else { + switchToListView(); + } + } else { Log_OC.wtf(TAG, "initFragments() called with invalid NULLs!"); if (getAccount() == null) { @@@ -433,7 -437,9 +439,7 @@@ protected void refreshListOfFilesFragment() { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(MainApp.getOnlyOnDevice()); + fileListFragment.listDirectory(MainApp.getOnlyOnDevice()); } } @@@ -485,9 -491,10 +491,9 @@@ @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean drawerOpen = mDrawerLayout.isDrawerOpen(GravityCompat.START); - menu.findItem(R.id.action_upload).setVisible(!drawerOpen); - menu.findItem(R.id.action_create_dir).setVisible(!drawerOpen); menu.findItem(R.id.action_sort).setVisible(!drawerOpen); menu.findItem(R.id.action_sync_account).setVisible(!drawerOpen); + menu.findItem(R.id.action_switch_view).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } @@@ -496,13 -503,6 +502,13 @@@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); + menu.findItem(R.id.action_create_dir).setVisible(false); + mOptionsMenu = menu; + + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + + changeGridIcon(); + return true; } @@@ -511,10 -511,23 +517,10 @@@ public boolean onOptionsItemSelected(MenuItem item) { boolean retval = true; switch (item.getItemId()) { - case R.id.action_create_dir: { - CreateFolderDialogFragment dialog = - CreateFolderDialogFragment.newInstance(getCurrentDir()); - dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER); - break; - } - case R.id.action_sync_account: { startSynchronization(); break; } - case R.id.action_upload: { - UploadSourceDialogFragment dialog = - UploadSourceDialogFragment.newInstance(getAccount()); - dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE); - break; - } case android.R.id.home: { FileFragment second = getSecondFragment(); OCFile currentDir = getCurrentDir(); @@@ -557,57 -570,12 +563,57 @@@ builder.create().show(); break; } + case R.id.action_switch_view:{ + if (isGridView()){ + item.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view)); + item.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_module)); + DisplayUtils.setViewMode(getFile(), false); + switchToListView(); + } else { + item.setTitle(getApplicationContext().getString(R.string.action_switch_list_view)); + item.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_list)); + DisplayUtils.setViewMode(getFile(), true); + switchToGridView(); + } + + return true; + } default: retval = super.onOptionsItemSelected(item); } return retval; } + public void createFolder() { + CreateFolderDialogFragment dialog = + CreateFolderDialogFragment.newInstance(getCurrentDir()); + dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER); + } + + public void uploadLocalFilesSelected() { + Intent action = new Intent(this, UploadFilesActivity.class); + action.putExtra( + UploadFilesActivity.EXTRA_ACCOUNT, + getAccount() + ); + startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES); + } + + public void uploadFromOtherAppsSelected() { + 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); + } + startActivityForResult( + Intent.createChooser(action, getString(R.string.upload_chooser_title)), + ACTION_SELECT_CONTENT_FROM_APPS + ); + } + private void startSynchronization() { Log_OC.d(TAG, "Got to start sync"); if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { @@@ -674,7 -642,7 +680,7 @@@ requestMoveOperation(fData, fResultCode); } }, - DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS + DELAY_TO_REQUEST_OPERATIONS_LATER ); } else if (requestCode == ACTION_COPY_FILES && resultCode == RESULT_OK) { @@@ -688,7 -656,7 +694,7 @@@ requestCopyOperation(fData, fResultCode); } }, - DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS + DELAY_TO_REQUEST_OPERATIONS_LATER ); } else { @@@ -802,12 -770,8 +808,12 @@@ */ 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 files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES); + + for (Parcelable file : files) { + getFileOperationsHelper().moveFile(folderToMoveAt, (OCFile) file); + } } /** @@@ -818,36 -782,13 +824,36 @@@ */ 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 files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES); + + for (Parcelable file : files) { + getFileOperationsHelper().copyFile(folderToMoveAt, (OCFile) file); + } } @Override public void onBackPressed() { - if (!isDrawerOpen()){ + boolean isFabOpen = isFabOpen(); + boolean isDrawerOpen = isDrawerOpen(); + + /* + * BackPressed priority/hierarchy: + * 1. close drawer if opened + * 2. close FAB if open (only if drawer isn't open) + * 3. navigate up (only if drawer and FAB aren't open) + */ + if(isDrawerOpen && isFabOpen) { + // close drawer first + super.onBackPressed(); + } else if(isDrawerOpen && !isFabOpen) { + // close drawer + super.onBackPressed(); + } else if (!isDrawerOpen && isFabOpen) { + // close fab + getListOfFilesFragment().getFabMain().collapse(); + } else { + // all closed OCFileListFragment listOfFiles = getListOfFilesFragment(); if (mDualPane || getSecondFragment() == null) { OCFile currentDir = getCurrentDir(); @@@ -863,20 -804,8 +869,20 @@@ setFile(listOfFiles.getCurrentFile()); } cleanSecondFragment(); + changeGridIcon(); + } + } + + private void changeGridIcon(){ + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + if (DisplayUtils.isGridView(getFile(), getStorageManager())){ + menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_list_view)); + menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_list)); } else { - super.onBackPressed(); + menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view)); + menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_module)); } } @@@ -955,14 -884,6 +961,14 @@@ Log_OC.v(TAG, "onPause() end"); } + public boolean isFabOpen() { + if(getListOfFilesFragment() != null && getListOfFilesFragment().getFabMain() != null && getListOfFilesFragment().getFabMain().isExpanded()) { + return true; + } else { + return false; + } + } + private class SyncBroadcastReceiver extends BroadcastReceiver { @@@ -1018,8 -939,10 +1024,8 @@@ currentDir.getRemotePath().equals(synchFolderRemotePath)) { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(currentDir, - // MainApp.getOnlyOnDevice()); + fileListFragment.listDirectory(currentDir, + MainApp.getOnlyOnDevice()); } } setFile(currentFile); @@@ -1066,6 -989,7 +1072,7 @@@ } } + } removeStickyBroadcast(intent); Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress); @@@ -1274,7 -1198,9 +1281,7 @@@ OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { // should never be null, indeed OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH); - listOfFiles.listDirectory(root); - // TODO Enable when "On Device" is recovered ? - // listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice()); + listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice()); setFile(listOfFiles.getCurrentFile()); startSyncFolderOperation(root, false); } @@@ -1293,15 -1219,6 +1300,15 @@@ cleanSecondFragment(); // Sync Folder startSyncFolderOperation(directory, false); + + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + + changeGridIcon(); + if (DisplayUtils.isGridView(directory, getStorageManager())){ + switchToGridView(); + } else { + switchToListView(); + } } /** @@@ -1368,7 -1285,9 +1375,7 @@@ // getFileDownloadBinder() - THIS IS A MESS OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { - listOfFiles.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // listOfFiles.listDirectory(MainApp.getOnlyOnDevice()); + listOfFiles.listDirectory(MainApp.getOnlyOnDevice()); } FileFragment secondFragment = getSecondFragment(); if (secondFragment != null && secondFragment instanceof FileDetailFragment) { @@@ -1434,11 -1353,14 +1441,14 @@@ } else if (operation instanceof CreateFolderOperation) { onCreateFolderOperationFinish((CreateFolderOperation) operation, result); - } else if (operation instanceof CreateShareOperation) { - onCreateShareOperationFinish((CreateShareOperation) operation, result); + } else if (operation instanceof CreateShareViaLinkOperation || + operation instanceof CreateShareWithShareeOperation ) { - } else if (operation instanceof UnshareLinkOperation) { - onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result); + refreshShowDetails(); + refreshListOfFilesFragment(); + + } else if (operation instanceof UnshareOperation) { + onUnshareLinkOperationFinish((UnshareOperation) operation, result); } else if (operation instanceof MoveFileOperation) { onMoveFileOperationFinish((MoveFileOperation) operation, result); @@@ -1448,15 -1370,8 +1458,8 @@@ } } - private void onCreateShareOperationFinish(CreateShareOperation operation, - RemoteOperationResult result) { - if (result.isSuccess()) { - refreshShowDetails(); - refreshListOfFilesFragment(); - } - } - private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, + private void onUnshareLinkOperationFinish(UnshareOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { refreshShowDetails(); @@@ -1497,8 -1412,6 +1500,6 @@@ */ private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) { - dismissLoadingDialog(); - Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); @@@ -1537,10 -1450,8 +1538,8 @@@ private void onMoveFileOperationFinish(MoveFileOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - dismissLoadingDialog(); refreshListOfFilesFragment(); } else { - dismissLoadingDialog(); try { Toast msg = Toast.makeText(FileDisplayActivity.this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), @@@ -1562,10 -1473,8 +1561,8 @@@ */ private void onCopyFileOperationFinish(CopyFileOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - dismissLoadingDialog(); refreshListOfFilesFragment(); } else { - dismissLoadingDialog(); try { Toast msg = Toast.makeText(FileDisplayActivity.this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), @@@ -1587,7 -1496,6 +1584,6 @@@ */ private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOperationResult result) { - dismissLoadingDialog(); OCFile renamedFile = operation.getFile(); if (result.isSuccess()) { FileFragment details = getSecondFragment(); @@@ -1656,10 -1564,8 +1652,8 @@@ private void onCreateFolderOperationFinish(CreateFolderOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - dismissLoadingDialog(); refreshListOfFilesFragment(); } else { - dismissLoadingDialog(); try { Toast msg = Toast.makeText(FileDisplayActivity.this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), @@@ -1722,26 -1628,60 +1716,60 @@@ return null; } - public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) { - long currentSyncTime = System.currentTimeMillis(); - - mSyncInProgress = true; - - // perform folder synchronization - RemoteOperation synchFolderOp = new RefreshFolderOperation( folder, - currentSyncTime, - false, - getFileOperationsHelper().isSharedSupported(), - ignoreETag, - getStorageManager(), - getAccount(), - getApplicationContext() + /** + * Starts an operation to refresh the requested folder. + * + * The operation is run in a new background thread created on the fly. + * + * The refresh updates is a "light sync": properties of regular files in folder are updated (including + * associated shares), but not their contents. Only the contents of files marked to be kept-in-sync are + * synchronized too. + * + * @param folder Folder to refresh. + * @param ignoreETag If 'true', the data from the server will be fetched and sync'ed even if the eTag + * didn't change. + */ + public void startSyncFolderOperation(final OCFile folder, final boolean ignoreETag) { + + // the execution is slightly delayed to allow the activity get the window focus if it's being started + // or if the method is called from a dialog that is being dismissed + getHandler().postDelayed( + new Runnable() { + @Override + public void run() { + if (hasWindowFocus()) { + long currentSyncTime = System.currentTimeMillis(); + mSyncInProgress = true; + + // perform folder synchronization + RemoteOperation synchFolderOp = new RefreshFolderOperation(folder, + currentSyncTime, + false, + getFileOperationsHelper().isSharedSupported(), + ignoreETag, + getStorageManager(), + getAccount(), + getApplicationContext() + ); + synchFolderOp.execute( + getAccount(), + MainApp.getAppContext(), + FileDisplayActivity.this, + null, + null + ); + + mProgressBar.setIndeterminate(true); + + setBackgroundText(); + + } // else: NOTHING ; lets' not refresh when the user rotates the device but there is + // another window floating over + } + }, + DELAY_TO_REQUEST_OPERATIONS_LATER ); - synchFolderOp.execute(getAccount(), MainApp.getAppContext(), this, null, null); - - mProgressBar.setIndeterminate(true); - setBackgroundText(); } /** @@@ -1897,19 -1837,8 +1925,19 @@@ private void sortByName(boolean ascending) { getListOfFilesFragment().sortByName(ascending); } + private boolean isGridView(){ return getListOfFilesFragment().isGridView(); } + private void switchToGridView() { + getListOfFilesFragment().switchToGridView(); + } + private void switchToListView() { + getListOfFilesFragment().switchToListView(); + } public void allFilesOption() { browseToRoot(); } + + public void refreshDirectory(){ + getListOfFilesFragment().refreshDirectory(); + } } diff --combined src/com/owncloud/android/ui/activity/FolderPickerActivity.java index ff12db6b,2f02dcd6..dc05de99 --- a/src/com/owncloud/android/ui/activity/FolderPickerActivity.java +++ b/src/com/owncloud/android/ui/activity/FolderPickerActivity.java @@@ -38,7 -38,6 +38,6 @@@ import android.view.MenuInflater import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; - import android.view.Window; import android.widget.Button; import android.widget.ProgressBar; import android.widget.Toast; @@@ -62,8 -61,6 +61,8 @@@ import com.owncloud.android.ui.fragment import com.owncloud.android.ui.fragment.OCFileListFragment; import com.owncloud.android.utils.ErrorMessageAdapter; +import java.util.ArrayList; + public class FolderPickerActivity extends FileActivity implements FileFragment.ContainerActivity, OnClickListener, OnEnforceableRefreshListener { @@@ -71,8 -68,6 +70,8 @@@ + ".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; @@@ -145,7 -140,7 +144,7 @@@ if (!stateWasRecovered) { OCFileListFragment listOfFolders = getListOfFilesFragment(); - listOfFolders.listDirectory(folder/*, false*/); + listOfFolders.listDirectory(folder, false); startSyncFolderOperation(folder, false); } @@@ -159,7 -154,6 +158,7 @@@ Bundle args = new Bundle(); args.putBoolean(OCFileListFragment.ARG_JUST_FOLDERS, true); args.putBoolean(OCFileListFragment.ARG_ALLOW_CONTEXTUAL_ACTIONS, false); + args.putBoolean(OCFileListFragment.ARG_HIDE_FAB, true); listOfFiles.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS); @@@ -268,6 -262,7 +267,6 @@@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); - menu.findItem(R.id.action_upload).setVisible(false); menu.findItem(R.id.action_sort).setVisible(false); return true; } @@@ -314,7 -309,9 +313,7 @@@ protected void refreshListOfFilesFragment() { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(false); + fileListFragment.listDirectory(false); } } @@@ -322,7 -319,9 +321,7 @@@ OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { // should never be null, indeed OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH); - listOfFiles.listDirectory(root); - // TODO Enable when "On Device" is recovered ? - // listOfFiles.listDirectory(root, false); + listOfFiles.listDirectory(root, false); setFile(listOfFiles.getCurrentFile()); updateNavigationElementsInActionBar(); startSyncFolderOperation(root, false); @@@ -350,9 -349,9 +349,9 @@@ actionBar.setDisplayHomeAsUpEnabled(!atRoot); actionBar.setHomeButtonEnabled(!atRoot); actionBar.setTitle( - atRoot - ? getString(R.string.default_display_name_for_root_folder) - : currentDir.getFileName() + atRoot + ? getString(R.string.default_display_name_for_root_folder) + : currentDir.getFileName() ); } @@@ -373,16 -372,12 +372,16 @@@ } else if (v == mChooseBtn) { Intent i = getIntent(); Parcelable targetFile = i.getParcelableExtra(FolderPickerActivity.EXTRA_FILE); + ArrayList 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(); } @@@ -394,7 -389,7 +393,7 @@@ super.onRemoteOperationFinish(operation, result); if (operation instanceof CreateFolderOperation) { - onCreateFolderOperationFinish((CreateFolderOperation)operation, result); + onCreateFolderOperationFinish((CreateFolderOperation) operation, result); } } @@@ -412,10 -407,8 +411,8 @@@ ) { if (result.isSuccess()) { - dismissLoadingDialog(); refreshListOfFilesFragment(); } else { - dismissLoadingDialog(); try { Toast msg = Toast.makeText(FolderPickerActivity.this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), @@@ -478,7 -471,9 +475,7 @@@ equals(synchFolderRemotePath)) { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(currentDir); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(currentDir, false); + fileListFragment.listDirectory(currentDir, false); } } setFile(currentFile); @@@ -544,9 -539,9 +541,9 @@@ /** - * Shows the information of the {@link OCFile} received as a + * Shows the information of the {@link OCFile} received as a * parameter in the second fragment. - * + * * @param file {@link OCFile} whose details will be shown */ @Override diff --combined src/com/owncloud/android/ui/activity/Uploader.java index 403d6bb7,0d1a8011..0194092d --- a/src/com/owncloud/android/ui/activity/Uploader.java +++ b/src/com/owncloud/android/ui/activity/Uploader.java @@@ -333,7 -333,8 +333,7 @@@ public class Uploader extends FileActiv public void onItemClick(AdapterView parent, View view, int position, long id) { // click on folder in the list Log_OC.d(TAG, "on item click"); - // TODO Enable when "On Device" is recovered ? - Vector tmpfiles = getStorageManager().getFolderContent(mFile /*, false*/); + Vector tmpfiles = getStorageManager().getFolderContent(mFile, false); if (tmpfiles.size() <= 0) return; // filter on dirtype Vector files = new Vector(); @@@ -417,7 -418,8 +417,7 @@@ mFile = getStorageManager().getFileByPath(full_path); if (mFile != null) { - // TODO Enable when "On Device" is recovered ? - Vector files = getStorageManager().getFolderContent(mFile/*, false*/); + Vector files = getStorageManager().getFolderContent(mFile, false); List> data = new LinkedList>(); for (OCFile f : files) { HashMap h = new HashMap(); @@@ -605,10 -607,8 +605,8 @@@ private void onCreateFolderOperationFinish(CreateFolderOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - dismissLoadingDialog(); populateDirectoryList(); } else { - dismissLoadingDialog(); try { Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), @@@ -656,6 -656,7 +654,6 @@@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); - menu.findItem(R.id.action_upload).setVisible(false); menu.findItem(R.id.action_sort).setVisible(false); menu.findItem(R.id.action_sync_account).setVisible(false); return true; diff --combined src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 78a66b31,2aa25eaf..48047547 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@@ -25,19 -25,12 +25,19 @@@ package com.owncloud.android.ui.adapter import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.Vector; import android.accounts.Account; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; import android.os.Build; import android.preference.PreferenceManager; import android.text.format.DateUtils; @@@ -70,7 -63,6 +70,6 @@@ import com.owncloud.android.utils.Mimet * instance. */ public class FileListListAdapter extends BaseAdapter implements ListAdapter { - private final static String PERMISSION_SHARED_WITH_ME = "S"; private Context mContext; private OCFile mFile = null; @@@ -86,8 -78,6 +85,8 @@@ private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM }; private SharedPreferences mAppPreferences; + + private HashMap mSelection = new HashMap(); public FileListListAdapter( boolean justFolders, @@@ -163,7 -153,7 +162,7 @@@ ViewType viewType; if (!mGridMode){ viewType = ViewType.LIST_ITEM; - } else if (file.isImage()){ + } else if (file.isImage() || file.isVideo()){ viewType = ViewType.GRID_IMAGE; } else { viewType = ViewType.GRID_ITEM; @@@ -203,38 -193,36 +202,38 @@@ 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(showRelativeTimestamp(file)); - 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( - android.R.drawable.checkbox_on_background); - } else { - checkBoxV.setImageResource( - android.R.drawable.checkbox_off_background); - } - checkBoxV.setVisibility(View.VISIBLE); - } - } - - } else { //Folder - fileSizeV.setVisibility(View.INVISIBLE); +// 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); +// } +// } + + if (file.isFolder()) { + fileSizeSeparatorV.setVisibility(View.GONE); + fileSizeV.setVisibility(View.GONE); } case GRID_ITEM: @@@ -246,13 -234,21 +245,21 @@@ case GRID_IMAGE: // sharedIcon ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); - if (file.isShareByLink()) { + if (file.isSharedViaLink()) { + sharedIconV.setImageResource(R.drawable.shared_via_link); + sharedIconV.setVisibility(View.VISIBLE); + sharedIconV.bringToFront(); + } else if (file.isSharedWithSharee() || file.isSharedWithMe() ) { + sharedIconV.setImageResource(R.drawable.shared_via_users); sharedIconV.setVisibility(View.VISIBLE); sharedIconV.bringToFront(); } else { sharedIconV.setVisibility(View.GONE); } + /*ImageView sharedWithMeIcon = (ImageView) view.findViewById(R.id.sharedWithMeIcon); + sharedWithMeIcon.bringToFront();*/ + // local state ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator); localStateView.bringToFront(); @@@ -303,38 -299,8 +310,27 @@@ localStateView.setVisibility(View.VISIBLE); } - // share with me icon - ImageView sharedWithMeIconV = (ImageView) - view.findViewById(R.id.sharedWithMeIcon); - sharedWithMeIconV.bringToFront(); - if (checkIfFileIsSharedWithMe(file) && - (!file.isFolder() || !mGridMode)) { - sharedWithMeIconV.setVisibility(View.VISIBLE); - } else { - sharedWithMeIconV.setVisibility(View.GONE); - } - break; } + + ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox); + checkBoxV.setVisibility(View.GONE); + + 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.getCheckedItemCount() > 0){ + if (parentList.isItemChecked(position)) { + checkBoxV.setImageResource( + android.R.drawable.checkbox_on_background); + } else { + checkBoxV.setImageResource( + android.R.drawable.checkbox_off_background); + } + checkBoxV.setVisibility(View.VISIBLE); + } + } // For all Views @@@ -348,18 -314,12 +344,18 @@@ // No Folder if (!file.isFolder()) { - if (file.isImage() && file.getRemoteId() != null){ + if ((file.isImage() || file.isVideo()) && file.getRemoteId() != null){ // Thumbnail in Cache? Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( "t" + String.valueOf(file.getRemoteId())); if (thumbnail != null && !file.needsUpdateThumbnail()){ - fileIcon.setImageBitmap(thumbnail); + + if (file.isVideo()) { + Bitmap withOverlay = ThumbnailsCacheManager.addVideoOverlay(thumbnail); + fileIcon.setImageBitmap(withOverlay); + } else { + fileIcon.setImageBitmap(thumbnail); + } } else { // generate new Thumbnail if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) { @@@ -396,16 -356,13 +392,19 @@@ // Folder fileIcon.setImageResource( MimetypeIconUtil.getFolderTypeIconId( - checkIfFileIsSharedWithMe(file), file.isShareByLink())); + file.isSharedWithMe() || file.isSharedWithSharee(), + file.isSharedViaLink() + ) + ); } } + if (mSelection.get(position) != null) { + view.setBackgroundColor(Color.rgb(248, 248, 248)); + } else { + view.setBackgroundColor(Color.WHITE); + } + return view; } @@@ -432,14 -389,15 +431,14 @@@ * mStorageManager if is different (and not NULL) */ public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager - /*, boolean onlyOnDevice*/) { + , boolean onlyOnDevice) { mFile = directory; if (updatedStorageManager != null && updatedStorageManager != mStorageManager) { mStorageManager = updatedStorageManager; mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); } if (mStorageManager != null) { - // TODO Enable when "On Device" is recovered ? - mFiles = mStorageManager.getFolderContent(mFile/*, onlyOnDevice*/); + mFiles = mStorageManager.getFolderContent(mFile, onlyOnDevice); mFilesOrig.clear(); mFilesOrig.addAll(mFiles); @@@ -450,7 -408,7 +449,7 @@@ mFiles = null; } - mFiles = FileStorageUtils.sortFolder(mFiles); + mFiles = FileStorageUtils.sortOcFolder(mFiles); notifyDataSetChanged(); } @@@ -473,20 -431,6 +472,6 @@@ } - /** - * Check if parent folder does not include 'S' permission and if file/folder - * is shared with me - * - * @param file: OCFile - * @return boolean: True if it is shared with me and false if it is not - */ - private boolean checkIfFileIsSharedWithMe(OCFile file) { - return (mFile.getPermissions() != null - && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) - && file.getPermissions() != null - && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); - } - public void setSortOrder(Integer order, boolean ascending) { SharedPreferences.Editor editor = mAppPreferences.edit(); editor.putInt("sortOrder", order); @@@ -497,7 -441,7 +482,7 @@@ FileStorageUtils.mSortAscending = ascending; - mFiles = FileStorageUtils.sortFolder(mFiles); + mFiles = FileStorageUtils.sortOcFolder(mFiles); notifyDataSetChanged(); } @@@ -510,45 -454,4 +495,45 @@@ public void setGridMode(boolean gridMode) { mGridMode = gridMode; } + + public boolean isGridMode() { + return mGridMode; + } + + public void setNewSelection(int position, boolean checked) { + mSelection.put(position, checked); + notifyDataSetChanged(); + } + + public void removeSelection(int position) { + mSelection.remove(position); + notifyDataSetChanged(); + } + + public void removeSelection(){ + mSelection.clear(); + notifyDataSetChanged(); + } + + public ArrayList getCheckedItemPositions() { + ArrayList ids = new ArrayList(); + + for (Map.Entry entry : mSelection.entrySet()){ + if (entry.getValue()){ + ids.add(entry.getKey()); + } + } + return ids; + } + + public ArrayList getCheckedItems() { + ArrayList files = new ArrayList(); + + for (Map.Entry entry : mSelection.entrySet()){ + if (entry.getValue()){ + files.add((OCFile) getItem(entry.getKey())); + } + } + return files; + } } diff --combined src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java index af3bdf0a,a339ed74..79bad6ad --- a/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java @@@ -25,9 -25,7 +25,9 @@@ import java.util.Arrays import java.util.Comparator; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@@ -43,7 -41,6 +43,7 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.utils.BitmapUtils; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.MimetypeIconUtil; +import com.owncloud.android.utils.FileStorageUtils; /** * This Adapter populates a ListView with all files and directories contained @@@ -56,18 -53,9 +56,18 @@@ public class LocalFileListAdapter exten private Context mContext; private File mDirectory; private File[] mFiles = null; + private SharedPreferences mAppPreferences; public LocalFileListAdapter(File directory, Context context) { mContext = context; + + mAppPreferences = PreferenceManager + .getDefaultSharedPreferences(mContext); + + // Read sorting order, default to sort by name ascending + FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0); + FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true); + swapDirectory(directory); } @@@ -133,11 -121,9 +133,11 @@@ fileIcon.setTag(file.hashCode()); 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); if (!file.isDirectory()) { + fileSizeSeparatorV.setVisibility(View.VISIBLE); fileSizeV.setVisibility(View.VISIBLE); fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length())); @@@ -148,9 -134,9 +148,9 @@@ checkBoxV.setVisibility(View.GONE); } else { if (parentList.isItemChecked(position)) { - checkBoxV.setImageResource(android.R.drawable.checkbox_on_background); + checkBoxV.setImageResource(R.drawable.ic_checkbox_marked); } else { - checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); + checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline); } checkBoxV.setVisibility(View.VISIBLE); } @@@ -189,7 -175,6 +189,7 @@@ } } else { + fileSizeSeparatorV.setVisibility(View.GONE); fileSizeV.setVisibility(View.GONE); lastModV.setVisibility(View.GONE); checkBoxV.setVisibility(View.GONE); @@@ -200,7 -185,6 +200,6 @@@ view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE); view.findViewById(R.id.sharedIcon).setVisibility(View.GONE); - view.findViewById(R.id.sharedWithMeIcon).setVisibility(View.GONE); } return view; @@@ -245,23 -229,7 +244,23 @@@ } }); + + mFiles = FileStorageUtils.sortLocalFolder(mFiles); } notifyDataSetChanged(); } + + public void setSortOrder(Integer order, boolean ascending) { + SharedPreferences.Editor editor = mAppPreferences.edit(); + editor.putInt("sortOrder", order); + editor.putBoolean("sortAscending", ascending); + editor.commit(); + + FileStorageUtils.mSortOrder = order; + FileStorageUtils.mSortAscending = ascending; + + mFiles = FileStorageUtils.sortLocalFolder(mFiles); + notifyDataSetChanged(); + + } } diff --combined src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 88b0dd16,44776368..2f59be46 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@@ -22,32 -22,19 +22,32 @@@ */ package com.owncloud.android.ui.fragment; +import android.accounts.Account; import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.net.Uri; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.widget.SwipeRefreshLayout; +import android.view.ActionMode; +import android.support.v7.app.AlertDialog; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +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; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; @@@ -55,37 -42,29 +55,37 @@@ import com.owncloud.android.datamodel.O import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import com.owncloud.android.media.MediaService; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.FolderPickerActivity; import com.owncloud.android.ui.activity.OnEnforceableRefreshListener; +import com.owncloud.android.ui.activity.UploadFilesActivity; import com.owncloud.android.ui.adapter.FileListListAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; +import com.owncloud.android.ui.dialog.CreateFolderDialogFragment; import com.owncloud.android.ui.dialog.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.dialog.UploadSourceDialogFragment; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; +import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.ExceptionHandler; +import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.ui.preview.PreviewTextFragment; import com.owncloud.android.utils.FileStorageUtils; import java.io.File; +import java.util.ArrayList; /** * 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(); @@@ -94,12 -73,8 +94,12 @@@ public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS"; public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL"; + public final static String ARG_HIDE_FAB = MY_PACKAGE + ".HIDE_FAB"; private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; + private static final String KEY_FAB_EVER_CLICKED = "FAB_EVER_CLICKED"; + + private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; private FileFragment.ContainerActivity mContainerActivity; @@@ -108,8 -83,8 +108,8 @@@ private boolean mJustFolders; private OCFile mTargetFile; - - + + private boolean miniFabClicked = false; /** * {@inheritDoc} @@@ -170,211 -145,15 +170,211 @@@ setListAdapter(mAdapter); registerLongClickListener(); + + boolean hideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false); + if (hideFab) { + setFabEnabled(false); + } else { + setFabEnabled(true); + registerFabListeners(); + + // detect if a mini FAB has ever been clicked + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + if(prefs.getLong(KEY_FAB_EVER_CLICKED, 0) > 0) { + miniFabClicked = true; + } + + // add labels to the min FABs when none of them has ever been clicked on + if(!miniFabClicked) { + setFabLabels(); + } else { + removeFabLabels(); + } + } } + /** + * adds labels to all mini FABs. + */ + private void setFabLabels() { + getFabUpload().setTitle(getResources().getString(R.string.actionbar_upload)); + getFabMkdir().setTitle(getResources().getString(R.string.actionbar_mkdir)); + getFabUploadFromApp().setTitle(getResources().getString(R.string.actionbar_upload_from_apps)); + } + + /** + * registers all listeners on all mini FABs. + */ + private void registerFabListeners() { + registerFabUploadListeners(); + registerFabMkDirListeners(); + registerFabUploadFromAppListeners(); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the Upload mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabUploadListeners() { + getFabUpload().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent action = new Intent(getActivity(), UploadFilesActivity.class); + action.putExtra( + UploadFilesActivity.EXTRA_ACCOUNT, + ((FileActivity) getActivity()).getAccount() + ); + getActivity().startActivityForResult(action, UploadSourceDialogFragment.ACTION_SELECT_MULTIPLE_FILES); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabUpload().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), R.string.actionbar_upload, Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the 'Create Dir' mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabMkDirListeners() { + getFabMkdir().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CreateFolderDialogFragment dialog = + CreateFolderDialogFragment.newInstance(mFile); + dialog.show(getActivity().getSupportFragmentManager(), FileDisplayActivity.DIALOG_CREATE_FOLDER); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabMkdir().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), R.string.actionbar_mkdir, Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the Upload from App mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabUploadFromAppListeners() { + getFabUploadFromApp().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent action = new Intent(Intent.ACTION_GET_CONTENT); + action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE); + + //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + } + + getActivity().startActivityForResult( + Intent.createChooser(action, getString(R.string.upload_chooser_title)), + UploadSourceDialogFragment.ACTION_SELECT_CONTENT_FROM_APPS + ); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabUploadFromApp().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), + R.string.actionbar_upload_from_apps, + Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * records a click on a mini FAB and thus: + *
    + *
  1. persists the click fact
  2. + *
  3. removes the mini FAB labels
  4. + *
+ */ + private void recordMiniFabClick() { + // only record if it hasn't been done already at some other time + if(!miniFabClicked) { + final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); + sp.edit().putLong(KEY_FAB_EVER_CLICKED, 1).commit(); + miniFabClicked = true; + } + } + + /** + * removes the labels on all known min FABs. + */ + private void removeFabLabels() { + getFabUpload().setTitle(null); + getFabMkdir().setTitle(null); + getFabUploadFromApp().setTitle(null); + ((TextView) getFabUpload().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + ((TextView) getFabMkdir().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + ((TextView) getFabUploadFromApp().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + } + private void registerLongClickListener() { - getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - public boolean onItemLongClick(AdapterView arg0, View v, - int index, long arg3) { - showFileAction(index); + getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { + private Menu menu; + + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + final int checkedCount = getListView().getCheckedItemCount(); + // TODO Tobi extract to values + mode.setTitle(checkedCount + " selected"); + + if (checked) { + mAdapter.setNewSelection(position, checked); + } else { + mAdapter.removeSelection(position); + } + + // TODO maybe change: only recreate menu if count changes + menu.clear(); + if (checkedCount == 1) { + createContextMenu(menu); + } else { + // download, move, copy, delete + getActivity().getMenuInflater().inflate(R.menu.multiple_file_actions_menu, menu); + } + + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + this.menu = menu; return true; } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return onFileActionChosen(item.getItemId()); + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mAdapter.removeSelection(); + } }); } @@@ -415,7 -194,8 +415,8 @@@ } } - FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, fileIndex, targetFile.getFileName()); + FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, + fileIndex, targetFile.getFileName()); dialog.setTargetFragment(this, 0); dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS); } @@@ -432,11 -212,11 +433,11 @@@ /** * 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. + *

+ * Tries to move up the current folder one level. If the parent folder was removed from the + * database, it continues browsing up until finding an existing folders. + *

+ * @return Count of folder levels browsed up. */ public int onBrowseUp() { OCFile parentDir = null; @@@ -464,7 -244,8 +465,7 @@@ } // exit is granted because storageManager.getFileByPath("/") never returns null mFile = parentDir; - // TODO Enable when "On Device" is recovered ? - listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/); + listDirectory(mFile, MainApp.getOnlyOnDevice()); onRefresh(false); @@@ -482,7 -263,8 +483,7 @@@ if (file != null) { if (file.isFolder()) { // update state and view of this fragment - // TODO Enable when "On Device" is recovered ? - listDirectory(file/*, MainApp.getOnlyOnDevice()*/); + listDirectory(file, MainApp.getOnlyOnDevice()); // then, notify parent activity to let it update its state and view mContainerActivity.onBrowsedDownTo(file); // save index and top position @@@ -494,36 -276,41 +495,36 @@@ ((FileDisplayActivity)mContainerActivity).startImagePreview(file); } else if (PreviewTextFragment.canBePreviewed(file)){ ((FileDisplayActivity)mContainerActivity).startTextPreview(file); - } else if (file.isDown()) { - if (PreviewMediaFragment.canBePreviewed(file)) { + } else if (PreviewMediaFragment.canBePreviewed(file)) { // media preview ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true); - } else { + } else if (file.isDown()) { mContainerActivity.getFileOperationsHelper().openFile(file); - } else { - } - + } else { // automatic download, preview on finish ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file); } - } - } else { Log_OC.d(TAG, "Null object in ListAdapter!!"); } - } /** * {@inheritDoc} */ - @Override - public void onCreateContextMenu( - ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + // TODO Tobi needed? + public void createContextMenu(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); + OCFile targetFile = null; + if (mAdapter.getCheckedItems().size() == 1){ + targetFile = mAdapter.getCheckedItems().get(0); + } if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( @@@ -546,133 -333,92 +547,132 @@@ 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().shareFileWithLink(mTargetFile); - return true; - } - case R.id.action_share_with_users: { - mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile); - return true; - } - case R.id.action_open_file_with: { - mContainerActivity.getFileOperationsHelper().openFile(mTargetFile); - return true; - } - case R.id.action_unshare_file: { - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile); - return true; - } - case R.id.action_rename_file: { - RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile); - dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE); - return true; - } - case R.id.action_remove_file: { - RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile); - dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); - return true; - } - case R.id.action_download_file: - case R.id.action_sync_file: { - mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile); - return true; - } - case R.id.action_cancel_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) { + if (mAdapter.getCheckedItems().size() == 1){ + OCFile mTargetFile = mAdapter.getCheckedItems().get(0); - } else { - mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile); + switch (menuId) { + case R.id.action_share_file: { + mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile); + return true; } - return true; + case R.id.action_open_file_with: { + mContainerActivity.getFileOperationsHelper().openFile(mTargetFile); + return true; + } + case R.id.action_unshare_file: { + mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile); + return true; + } + case R.id.action_rename_file: { + RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile); + dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE); + return true; + } + case R.id.action_remove_file: { + RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile); + dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); + return true; + } + case R.id.action_download_file: + case R.id.action_sync_file: { + mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile); + return true; + } + case R.id.action_cancel_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); + return true; + } else { + mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile); + } + } + case R.id.action_stream_file: { + Account account = ((FileActivity)mContainerActivity).getAccount(); + Context context = MainApp.getAppContext(); + String uri = PreviewMediaFragment.generateUrlWithCredentials(account, context, mTargetFile); + MediaService.streamWithExternalApp(uri, getActivity()).show(); + 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.ACTION_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); + + // Pass mTargetFile that contains info of selected file/folder + action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); + return true; + default: + return false; } - case R.id.action_move: { - Intent action = new Intent(getActivity(), FolderPickerActivity.class); + } else { + ArrayList mTargetFiles = mAdapter.getCheckedItems(); - // Pass mTargetFile that contains info of selected file/folder - action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); - getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_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; + 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_move: { + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_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.ACTION_COPY_FILES); + return true; + default: + return false; } - case R.id.action_copy: - Intent action = new Intent(getActivity(), FolderPickerActivity.class); - - // Pass mTargetFile that contains info of selected file/folder - action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); - getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); - return true; - default: - return false; } - } /** @@@ -681,7 -427,8 +681,7 @@@ @Override public boolean onContextItemSelected (MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); - boolean matched = onFileActionChosen(item.getItemId()); - boolean matched = onFileActionChosen(item.getItemId(), - ((AdapterContextMenuInfo) item.getMenuInfo()).position); ++ boolean matched = onFileActionChosen(item.getItemId()) ; if(!matched) { return super.onContextItemSelected(item); } else { @@@ -701,14 -448,17 +701,14 @@@ } /** - * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter + * Calls {@link OCFileListFragment#listDirectory(OCFile, boolean)} with a null parameter */ - public void listDirectory(/*boolean onlyOnDevice*/){ - listDirectory(null); - // TODO Enable when "On Device" is recovered ? - // listDirectory(null, onlyOnDevice); + public void listDirectory(boolean onlyOnDevice){ + listDirectory(null, onlyOnDevice); } public void refreshDirectory(){ - // TODO Enable when "On Device" is recovered ? - listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/); + listDirectory(getCurrentFile(), MainApp.getOnlyOnDevice()); } /** @@@ -718,7 -468,7 +718,7 @@@ * * @param directory File to be listed */ - public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) { + public void listDirectory(OCFile directory, boolean onlyOnDevice) { FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); if (storageManager != null) { @@@ -739,7 -489,8 +739,7 @@@ directory = storageManager.getFileById(directory.getParentId()); } - // TODO Enable when "On Device" is recovered ? - mAdapter.swapDirectory(directory, storageManager/*, onlyOnDevice*/); + mAdapter.swapDirectory(directory, storageManager, onlyOnDevice); if (mFile == null || !mFile.equals(directory)) { mCurrentListView.setSelection(0); } @@@ -763,7 -514,7 +763,7 @@@ if (!file.isHidden()) { filesCount++; - if (file.isImage()) { + if (file.isImage() || file.isVideo()) { imagesCount++; } } @@@ -776,12 -527,11 +776,12 @@@ OwnCloudVersion version = AccountUtils.getServerVersion( ((FileActivity)mContainerActivity).getAccount()); if (version != null && version.supportsRemoteThumbnails() && - imagesCount > 0 && imagesCount == filesCount) { + DisplayUtils.isGridView(mFile, mContainerActivity.getStorageManager())) { switchToGridView(); registerLongClickListener(); } else { switchToListView(); +// switchToGridView(); } } } diff --combined src/com/owncloud/android/ui/preview/PreviewImageActivity.java index c811de71,213fcd3a..f797fe2f --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@@ -26,7 -26,6 +26,6 @@@ import android.content.Context import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; - import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@@ -41,7 -40,6 +40,7 @@@ import android.view.View import android.view.Window; import com.ortiz.touch.ExtendedViewPager; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; @@@ -55,14 -53,15 +54,15 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; - import com.owncloud.android.operations.CreateShareOperation; + import com.owncloud.android.operations.CreateShareViaLinkOperation; + import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.RemoveFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; - import com.owncloud.android.operations.UnshareLinkOperation; + import com.owncloud.android.operations.UnshareOperation; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; + import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.fragment.FileFragment; - import com.owncloud.android.utils.DisplayUtils; /** @@@ -157,8 -156,9 +157,8 @@@ public class PreviewImageActivity exten parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH); } - // TODO Enable when "On Device" is recovered ? mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), - parentFolder, getAccount(), getStorageManager()/*, MainApp.getOnlyOnDevice()*/); + parentFolder, getAccount(), getStorageManager(), MainApp.getOnlyOnDevice()); mViewPager = (ExtendedViewPager) findViewById(R.id.fragmentPager); int position = mHasSavedPosition ? mSavedPosition : @@@ -230,11 -230,12 +230,12 @@@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { super.onRemoteOperationFinish(operation, result); - if (operation instanceof CreateShareOperation) { - onCreateShareOperationFinish((CreateShareOperation) operation, result); - - } else if (operation instanceof UnshareLinkOperation) { - onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result); + if (operation instanceof CreateShareViaLinkOperation || + operation instanceof CreateShareWithShareeOperation) { + onCreateShareOperationFinish(result); + + } else if (operation instanceof UnshareOperation) { + onUnshareLinkOperationFinish((UnshareOperation) operation, result); } else if (operation instanceof RemoveFileOperation) { finish(); @@@ -245,7 -246,7 +246,7 @@@ } - private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, + private void onUnshareLinkOperationFinish(UnshareOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); @@@ -259,8 -260,7 +260,7 @@@ } - private void onCreateShareOperationFinish(CreateShareOperation operation, - RemoteOperationResult result) { + private void onCreateShareOperationFinish(RemoteOperationResult result) { if (result.isSuccess()) { OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); if (file != null) { @@@ -400,7 -400,6 +400,6 @@@ } - private void requestForDownload(OCFile file) { if (mDownloaderBinder == null) { Log_OC.d(TAG, "requestForDownload called without binder to download service"); diff --combined src/com/owncloud/android/ui/preview/PreviewImageFragment.java index f01528a2,0166829b..b3aab453 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@@ -264,9 -264,6 +264,9 @@@ public class PreviewImageFragment exten public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.file_actions_menu, menu); + +// MenuItem item = menu.findItem(R.id.action_set_as_wallpaper); +// item.setVisible(getFile().isDown()); } /** @@@ -332,6 -329,10 +332,10 @@@ mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); return true; } + case R.id.action_share_with_users: { + mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); + return true; + } case R.id.action_unshare_file: { mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); return true; @@@ -358,6 -359,7 +362,7 @@@ return true; } } + case R.id.action_download_file: case R.id.action_sync_file: { mContainerActivity.getFileOperationsHelper().syncFile(getFile()); return true; @@@ -370,10 -372,6 +375,10 @@@ mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false); return true; } + case R.id.action_set_as_wallpaper:{ + mContainerActivity.getFileOperationsHelper().setPictureAs(getFile()); + return true; + } default: return false; } @@@ -384,7 -382,6 +389,6 @@@ mContainerActivity.showDetails(getFile()); } - @Override public void onResume() { super.onResume(); @@@ -561,12 -558,7 +565,12 @@@ imageView.setBackground(backrepeat); } - imageView.setImageBitmap(bitmap); + if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")){ + imageView.setGifImage(result.ocFile); + } else { + imageView.setImageBitmap(bitmap); + } + imageView.setVisibility(View.VISIBLE); mBitmap = bitmap; // needs to be kept for recycling when not useful } diff --combined src/com/owncloud/android/ui/preview/PreviewMediaFragment.java index 3f0ffc53,2c5527c0..a749b5ce --- a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@@ -20,14 -20,10 +20,14 @@@ package com.owncloud.android.ui.preview; import android.accounts.Account; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; +import android.os.AsyncTask; import android.support.v7.app.AlertDialog; import android.content.ComponentName; import android.content.Context; @@@ -56,16 -52,9 +56,16 @@@ import android.widget.ImageView import android.widget.Toast; import android.widget.VideoView; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; 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.OwnCloudCredentials; +import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.media.MediaControlView; import com.owncloud.android.media.MediaService; @@@ -75,9 -64,6 +75,9 @@@ import com.owncloud.android.ui.dialog.C import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.fragment.FileFragment; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + /** * This fragment shows a preview of a downloaded media file (audio or video). @@@ -101,7 -87,6 +101,7 @@@ public class PreviewMediaFragment exten private ImageView mImagePreview; private VideoView mVideoPreview; private int mSavedPlaybackPosition; + private String mUri; private MediaServiceBinder mMediaServiceBinder = null; private MediaControlView mMediaController = null; @@@ -199,6 -184,10 +199,6 @@@ if (mAccount == null) { throw new IllegalStateException("Instanced with a NULL ownCloud Account"); } - if (!file.isDown()) { - throw new IllegalStateException("There is no local file to preview"); - } - } else { file = (OCFile) savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE); @@@ -209,7 -198,7 +209,7 @@@ mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING); } - if (file != null && file.isDown()) { + if (file != null) { if (file.isVideo()) { mVideoPreview.setVisibility(View.VISIBLE); mImagePreview.setVisibility(View.GONE); @@@ -282,7 -271,7 +282,7 @@@ Log_OC.e(TAG, "onStart"); OCFile file = getFile(); - if (file != null && file.isDown()) { + if (file != null) { if (file.isAudio()) { bindMediaService(); @@@ -366,6 -355,10 +366,10 @@@ mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); return true; } + case R.id.action_share_with_users: { + seeShareFile(); + return true; + } case R.id.action_unshare_file: { stopPreview(false); mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); @@@ -426,6 -419,10 +430,10 @@@ mContainerActivity.showDetails(getFile()); } + private void seeShareFile() { + stopPreview(false); + mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); + } private void prepareVideo() { // create helper to get more control on the playback @@@ -442,65 -439,8 +450,65 @@@ // load the video file in the video player ; // when done, VideoHelper#onPrepared() will be called - Uri uri = Uri.parse(getFile().getStoragePath()); - mVideoPreview.setVideoPath(uri.encode(getFile().getStoragePath())); + if (getFile().isDown()) { + mUri = getFile().getStoragePath(); + } else { + Context context = MainApp.getAppContext(); + Account account = mContainerActivity.getStorageManager().getAccount(); + + mUri = generateUrlWithCredentials(account, context, getFile()); + } + + mVideoPreview.setVideoPath(mUri); + } + + public static String generateUrlWithCredentials(Account account, Context context, OCFile file){ + OwnCloudAccount ocAccount = null; + try { + ocAccount = new OwnCloudAccount(account, context); + + final ClientGenerationTask task = new ClientGenerationTask(); + task.execute(ocAccount); + + OwnCloudClient mClient = task.get(); + String url = AccountUtils.constructFullURLForAccount(context, account) + Uri.encode(file.getRemotePath(), "/"); + OwnCloudCredentials credentials = mClient.getCredentials(); + + return url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@"); + + } catch (AccountUtils.AccountNotFoundException e) { + e.printStackTrace(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + return ""; + } + + public static class ClientGenerationTask extends AsyncTask { + @Override + protected OwnCloudClient doInBackground(Object... params) { + Object account = params[0]; + if (account instanceof OwnCloudAccount){ + try { + OwnCloudAccount ocAccount = (OwnCloudAccount) account; + return OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, MainApp.getAppContext()); + } catch (AccountUtils.AccountNotFoundException e) { + e.printStackTrace(); + } catch (OperationCanceledException e) { + e.printStackTrace(); + } catch (AuthenticatorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + } } @@@ -568,11 -508,27 +576,11 @@@ */ @Override public boolean onError(MediaPlayer mp, int what, int extra) { - if (mVideoPreview.getWindowToken() != null) { - String message = MediaService.getMessageForMediaError( - getActivity(), what, extra); - new AlertDialog.Builder(getActivity()) - .setMessage(message) - .setPositiveButton(android.R.string.VideoView_error_button, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dialog.dismiss(); - VideoHelper.this.onCompletion(null); - } - }) - .setCancelable(false) - .show(); - } + MediaService.streamWithExternalApp(mUri, getActivity()).show(); return true; } - } - @Override public void onPause() { Log_OC.e(TAG, "onPause");