From: Andy Scherzinger Date: Fri, 27 Nov 2015 20:40:01 +0000 (+0100) Subject: Merge branch 'master' of https://github.com/owncloud/android into target_marshmallow X-Git-Tag: beta-20151129~2^2~1^2~1 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/4d47f348c3cac7095ee341b8b33aac4ae3cc5320?ds=inline;hp=-c Merge branch 'master' of https://github.com/owncloud/android into target_marshmallow --- 4d47f348c3cac7095ee341b8b33aac4ae3cc5320 diff --combined src/com/owncloud/android/authentication/AuthenticatorActivity.java index 4173ca42,7b0398e8..418cdd5f --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@@ -176,6 -176,7 +176,6 @@@ public class AuthenticatorActivity exte private EditText mUsernameInput; private EditText mPasswordInput; private View mOkButton; - private View mCenteredRefreshButton; private TextView mAuthStatusView; private int mAuthStatusText = 0, mAuthStatusIcon = 0; @@@ -260,22 -261,16 +260,22 @@@ } }); - mCenteredRefreshButton = findViewById(R.id.centeredRefreshButton); - mCenteredRefreshButton.setOnClickListener(new View.OnClickListener() { + findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkOcServer(); } }); - - mOkButton = findViewById(R.id.buttonOK); + + findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + checkOcServer(); + } + }); + /// initialize block to be moved to single Fragment to check server and get info about it initServerPreFragment(savedInstanceState); @@@ -707,7 -702,7 +707,7 @@@ mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher); mHostUrlInput.setOnFocusChangeListener(null); - + super.onPause(); } @@@ -747,7 -742,7 +747,7 @@@ mOAuthTokenEndpointText.getText().toString().trim()); getServerInfoIntent.putExtra( - OperationsService.EXTRA_OAUTH2_QUERY_PARAMETERS, + OperationsService.EXTRA_OAUTH2_QUERY_PARAMETERS, queryParameters); if (mOperationsServiceBinder != null) { @@@ -806,6 -801,8 +806,8 @@@ showRefreshButton(false); if (uri.length() != 0) { + uri = stripIndexPhpOrAppsFiles(uri, mHostUrlInput); + // Handle internationalized domain names uri = DisplayUtils.convertIdn(uri, true); @@@ -816,8 -813,8 +818,8 @@@ Intent getServerInfoIntent = new Intent(); getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO); getServerInfoIntent.putExtra( - OperationsService.EXTRA_SERVER_URL, - normalizeUrlSuffix(uri) + OperationsService.EXTRA_SERVER_URL, + normalizeUrlSuffix(uri) ); if (mOperationsServiceBinder != null) { mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent); @@@ -1148,6 -1145,17 +1150,17 @@@ return url; } + private String stripIndexPhpOrAppsFiles(String url, EditText mHostUrlInput) { + if (url.endsWith("/index.php")) { + url = url.substring(0, url.lastIndexOf("/index.php")); + mHostUrlInput.setText(url); + } else if (url.contains("/index.php/apps/")) { + url = url.substring(0, url.lastIndexOf("/index.php/apps/")); + mHostUrlInput.setText(url); + } + + return url; + } // TODO remove, if possible private String trimUrlWebdav(String url){ @@@ -1630,6 -1638,18 +1643,6 @@@ } /** - * Called when the refresh button in the input field for ownCloud host is clicked. - * - * Performs a new check on the URL in the input field. - * - * @param view Refresh 'button' - */ - public void onRefreshClick(View view) { - checkOcServer(); - } - - - /** * Called when the eye icon in the password field is clicked. * * Toggles the visibility of the password in the field. diff --combined src/com/owncloud/android/ui/activity/FileActivity.java index 7dc13b9b,99e4c91f..571c90de --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@@ -67,12 -67,14 +67,14 @@@ 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.lib.resources.status.OCCapability; import com.owncloud.android.operations.CreateShareViaLinkOperation; import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.GetSharesForFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareOperation; + import com.owncloud.android.operations.UpdateShareViaLinkOperation; import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.ui.NavigationDrawerItem; @@@ -93,8 -95,6 +95,6 @@@ public class FileActivity extends AppCo public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE"; public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT"; - public static final String EXTRA_WAITING_TO_PREVIEW = - "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW"; public static final String EXTRA_FROM_NOTIFICATION = "com.owncloud.android.ui.activity.FROM_NOTIFICATION"; @@@ -113,9 -113,13 +113,13 @@@ /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located.*/ private Account mAccount; - /** Main {@link OCFile} handled by the activity.*/ + /** Capabilites of the server where {@link #mAccount} lives */ + private OCCapability mCapabilities; + + /** Main {@link OCFile} handled by the activity.*/ private OCFile mFile; + /** Flag to signal that the activity will is finishing to enforce the creation of an ownCloud * {@link Account} */ private boolean mRedirectingToSetupAccount = false; @@@ -141,12 -145,12 +145,12 @@@ private OperationsServiceBinder mOperationsServiceBinder = null; + private boolean mResumed = false; + protected FileDownloaderBinder mDownloaderBinder = null; protected FileUploaderBinder mUploaderBinder = null; private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null; - private boolean mTryShareAgain = false; - // Navigation Drawer protected DrawerLayout mDrawerLayout; protected ActionBarDrawerToggle mDrawerToggle; @@@ -161,6 -165,7 +165,7 @@@ protected NavigationDrawerListAdapter mNavigationDrawerAdapter = null; + // TODO re-enable when "Accounts" is available in Navigation Drawer // protected boolean mShowAccounts = false; @@@ -183,7 -188,6 +188,6 @@@ mFileOperationsHelper.setOpIdWaitingFor( savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID, Long.MAX_VALUE) ); - mTryShareAgain = savedInstanceState.getBoolean(KEY_TRY_SHARE_AGAIN); if (getSupportActionBar() != null) { getSupportActionBar().setTitle(savedInstanceState.getString(KEY_ACTION_BAR_TITLE)); } @@@ -255,7 -259,7 +259,7 @@@ @Override protected void onResume() { super.onResume(); - + mResumed = true; if (mOperationsServiceBinder != null) { doOnResumeAndBound(); } @@@ -266,7 -270,7 +270,7 @@@ if (mOperationsServiceBinder != null) { mOperationsServiceBinder.removeOperationListener(this); } - + mResumed = false; super.onPause(); } @@@ -367,7 -371,12 +371,7 @@@ // } // Display username in drawer - Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()); - if (account != null) { - TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); - int lastAtPos = account.name.lastIndexOf("@"); - username.setText(account.name.substring(0, lastAtPos)); - } + setUsernameInDrawer(navigationDrawerLayout, AccountUtils.getCurrentOwnCloudAccount(getApplicationContext())); // load slide menu items mDrawerTitles = getResources().getStringArray(R.array.drawer_items); @@@ -434,21 -443,6 +438,21 @@@ } /** + * sets the given account name in the drawer in case the drawer is available. The account name + * is shortened beginning from the @-sign in the username. + * + * @param navigationDrawerLayout the drawer layout to be used + * @param account the account to be set in the drawer + */ + protected void setUsernameInDrawer(RelativeLayout navigationDrawerLayout, Account account) { + if (navigationDrawerLayout != null && getAccount() != null) { + TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); + int lastAtPos = account.name.lastIndexOf("@"); + username.setText(account.name.substring(0, lastAtPos)); + } + } + + /** * Updates title bar and home buttons (state and icon). * * Assumes that navigation drawer is NOT visible. @@@ -564,7 -558,6 +568,6 @@@ outState.putParcelable(FileActivity.EXTRA_FILE, mFile); outState.putBoolean(FileActivity.EXTRA_FROM_NOTIFICATION, mFromNotification); outState.putLong(KEY_WAITING_FOR_OP_ID, mFileOperationsHelper.getOpIdWaitingFor()); - outState.putBoolean(KEY_TRY_SHARE_AGAIN, mTryShareAgain); if(getSupportActionBar() != null && getSupportActionBar().getTitle() != null) { // Null check in case the actionbar is used in ActionBar.NAVIGATION_MODE_LIST // since it doesn't have a title then @@@ -608,6 -601,18 +611,18 @@@ mAccount = account; } + + /** + * Getter for the capabilities of the server where the current OC account lives. + * + * @return Capabilities of the server where the current OC account lives. Null if the account is not + * set yet. + */ + public OCCapability getCapabilities() { + return mCapabilities; + } + + /** * @return Value of mFromNotification: True if the Activity is launched by a notification */ @@@ -622,14 -627,6 +637,6 @@@ return mRedirectingToSetupAccount; } - public boolean isTryShareAgain(){ - return mTryShareAgain; - } - - public void setTryShareAgain(boolean tryShareAgain) { - mTryShareAgain = tryShareAgain; - } - public OperationsServiceBinder getOperationsServiceBinder() { return mOperationsServiceBinder; } @@@ -686,6 -683,7 +693,7 @@@ protected void onAccountSet(boolean stateWasRecovered) { if (getAccount() != null) { mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); + mCapabilities = mStorageManager.getCapability(mAccount.name); } else { Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); @@@ -740,12 -738,12 +748,12 @@@ Toast.LENGTH_LONG); t.show(); } - mTryShareAgain = false; } else if (operation == null || operation instanceof CreateShareWithShareeOperation || operation instanceof UnshareOperation || - operation instanceof SynchronizeFolderOperation + operation instanceof SynchronizeFolderOperation || + operation instanceof UpdateShareViaLinkOperation ) { if (result.isSuccess()) { updateFileFromDB(); @@@ -764,10 -762,10 +772,10 @@@ onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result); } else if (operation instanceof GetSharesForFileOperation) { - if (result.isSuccess()) { + if (result.isSuccess() || result.getCode() == ResultCode.SHARE_NOT_FOUND) { updateFileFromDB(); - } else if (result.getCode() != ResultCode.SHARE_NOT_FOUND) { + } else { Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); @@@ -791,25 -789,31 +799,31 @@@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - mTryShareAgain = false; updateFileFromDB(); Intent sendIntent = operation.getSendIntentWithSubject(this); - startActivity(sendIntent); + if (sendIntent != null) { + startActivity(sendIntent); + } + } else { // Detect Failure (403) --> needs Password if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { - if (!isTryShareAgain()) { + String password = operation.getPassword(); + if ((password == null || password.length() == 0) && + getCapabilities().getFilesSharingPublicEnabled().isUnknown()) + { + // Was tried without password, but not sure that it's optional. Try with password. + // Try with password before giving up. + // See also ShareFileFragment#OnShareViaLinkListener SharePasswordDialogFragment dialog = - SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()), - operation.getSendIntent()); + SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()), true); dialog.show(getSupportFragmentManager(), DIALOG_SHARE_PASSWORD); } else { Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); t.show(); - mTryShareAgain = false; } } else { Toast t = Toast.makeText(this, @@@ -901,7 -905,9 +915,9 @@@ /*if (!mOperationsServiceBinder.isPerformingBlockingOperation()) { dismissLoadingDialog(); }*/ - doOnResumeAndBound(); + if (mResumed) { + doOnResumeAndBound(); + } } else { return; diff --combined src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 7a8f2a50,f09ed6c7..07b6541f --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@@ -26,7 -26,6 +26,6 @@@ import android.accounts.Account import android.accounts.AccountManager; import android.accounts.AuthenticatorException; import android.annotation.TargetApi; - import android.support.v7.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@@ -50,6 -49,7 +49,7 @@@ import android.support.v4.app.FragmentM import android.support.v4.app.FragmentTransaction; import android.support.v4.content.ContextCompat; import android.support.v4.view.GravityCompat; + import android.support.v7.app.AlertDialog; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@@ -79,14 -79,11 +79,11 @@@ 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.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.UnshareOperation; import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.syncadapter.FileSyncAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@@ -148,7 -145,7 +145,7 @@@ public class FileDisplayActivity extend 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"; @@@ -271,7 -268,12 +268,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) { @@@ -486,6 -488,8 +483,6 @@@ @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); @@@ -496,7 -500,6 +493,7 @@@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); + menu.findItem(R.id.action_create_dir).setVisible(false); return true; } @@@ -505,10 -508,23 +502,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,34 -573,6 +554,34 @@@ 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) { @@@ -797,26 -785,7 +794,26 @@@ @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(); @@@ -832,6 -801,8 +829,6 @@@ setFile(listOfFiles.getCurrentFile()); } cleanSecondFragment(); - } else { - super.onBackPressed(); } } @@@ -910,14 -881,6 +907,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 { @@@ -1387,15 -1350,6 +1384,6 @@@ } else if (operation instanceof CreateFolderOperation) { onCreateFolderOperationFinish((CreateFolderOperation) operation, result); - } else if (operation instanceof CreateShareViaLinkOperation || - operation instanceof CreateShareWithShareeOperation ) { - - refreshShowDetails(); - refreshListOfFilesFragment(); - - } else if (operation instanceof UnshareOperation) { - onUnshareLinkOperationFinish((UnshareOperation) operation, result); - } else if (operation instanceof MoveFileOperation) { onMoveFileOperationFinish((MoveFileOperation) operation, result); @@@ -1405,18 -1359,6 +1393,6 @@@ } - private void onUnshareLinkOperationFinish(UnshareOperation operation, - RemoteOperationResult result) { - if (result.isSuccess()) { - refreshShowDetails(); - refreshListOfFilesFragment(); - - } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { - cleanSecondFragment(); - refreshListOfFilesFragment(); - } - } - private void refreshShowDetails() { FileFragment details = getSecondFragment(); if (details != null) { diff --combined src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 036a0169,b47f648a..1be81679 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@@ -24,10 -24,7 +24,10 @@@ package com.owncloud.android.ui.fragmen import android.app.Activity; import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.widget.SwipeRefreshLayout; import android.view.ContextMenu; import android.view.Menu; @@@ -37,8 -34,6 +37,8 @@@ import android.view.View 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.R; import com.owncloud.android.authentication.AccountUtils; @@@ -51,14 -46,11 +51,14 @@@ import com.owncloud.android.ui.activity 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.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.ui.preview.PreviewTextFragment; @@@ -81,12 -73,8 +81,12 @@@ public class OCFileListFragment extend 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; @@@ -95,8 -83,8 +95,8 @@@ private boolean mJustFolders; private OCFile mTargetFile; - - + + private boolean miniFabClicked = false; /** * {@inheritDoc} @@@ -157,164 -145,8 +157,164 @@@ 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, @@@ -325,6 -157,7 +325,6 @@@ }); } - private void showFileAction(int fileIndex) { Bundle args = getArguments(); PopupMenu pm = new PopupMenu(getActivity(),null); @@@ -379,11 -212,11 +379,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; @@@ -511,10 -344,6 +511,6 @@@ 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; } @@@ -522,10 -351,6 +518,6 @@@ 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);